I tried to use vtkRuledSurfaceFilter to extrude a circle along a spline curve, but some error unexpected happened as shown in the figure below.Some triangle cells are just missed after this option and I have tried all the parametres but got nothing.After looking up the source code, I thought that should be a bug in the code that miss the cell that connects the last and the first point in a loop.
And I beg for some solutions to help solve this.
Can you please send some data and a simple program?
the code:
vtkNew<vtkNamedColors> colors;
vtkNew<vtkRegularPolygonSource> polygonSource;
polygonSource->GeneratePolygonOff();
polygonSource->SetNumberOfSides(50);
polygonSource->SetRadius(2);
polygonSource->SetCenter(0, 0, 0);
polygonSource->Update();
vtkSmartPointer<vtkPolyData> polyData = polygonSource->GetOutput();
int numberOfContours = polyData->GetNumberOfLines();
std::cout << "Number of contours: " << numberOfContours << std::endl;
// Generate some random points
double start[3] = {-1.2, 0.0, 0.2};
double p0[3] = {-1.0, 0.0, 0.0};
double p1[3] = {0.0, 0.0, 0.0};
// Create a vtkPoints object and store the points in it
vtkNew<vtkPoints> points;
points->InsertNextPoint(start);
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
vtkNew<vtkParametricSpline> spline;
spline->SetPoints(points);
vtkNew<vtkParametricFunctionSource> functionSource;
functionSource->SetParametricFunction(spline);
functionSource->SetUResolution(100);
functionSource->SetVResolution(100);
functionSource->SetWResolution(100);
functionSource->Update();
// Create the frame
vtkNew<vtkFrenetSerretFrame> frame;
frame->SetInputConnection(functionSource->GetOutputPort());
frame->ConsistentNormalsOn();
frame->Update();
frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals");
frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents");
frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals");
vtkPoints* linePoints = frame->GetOutput()->GetPoints();
std::vector<vtkSmartPointer<vtkAppendPolyData>> skeletons;
for (int i = 0; i < numberOfContours; ++i) {
skeletons.push_back(vtkSmartPointer<vtkAppendPolyData>::New());
}
for (int i = 0; i < linePoints->GetNumberOfPoints(); ++i) {
vtkNew<vtkTransform> transform;
// Compute a basis
double normalizedX[3];
frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals");
frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedX);
double normalizedY[3];
frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals");
frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedY);
double normalizedZ[3];
frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents");
frame->GetOutput()->GetPointData()->GetVectors()->GetTuple(i, normalizedZ);
// Create the direction cosine matrix
vtkNew<vtkMatrix4x4> matrix;
matrix->Identity();
for (unsigned int j = 0; j < 3; ++j) {
matrix->SetElement(j, 0, normalizedX[j]);
matrix->SetElement(j, 1, normalizedY[j]);
matrix->SetElement(j, 2, normalizedZ[j]);
}
transform->Translate(linePoints->GetPoint(i)[0], linePoints->GetPoint(i)[1],
linePoints->GetPoint(i)[2]);
transform->Scale(.02, .02, .02);
transform->Concatenate(matrix);
vtkNew<vtkTransformPolyDataFilter> transformPD;
vtkNew<vtkPolyData> polyDataCopy;
polyDataCopy->DeepCopy(polyData);
transformPD->SetTransform(transform);
transformPD->SetInputData(polyDataCopy);
transformPD->Update();
vtkNew<vtkPolyDataConnectivityFilter> contours;
contours->SetInputConnection(transformPD->GetOutputPort());
contours->Update();
for (int r = 0; r < contours->GetNumberOfExtractedRegions(); ++r)
{
contours->SetExtractionModeToSpecifiedRegions();
contours->InitializeSpecifiedRegionList();
contours->AddSpecifiedRegion(r);
contours->Update();
vtkNew<vtkPolyData> skeleton;
skeleton->DeepCopy(contours->GetOutput());
skeletons[r]->AddInputData(skeleton);
}
}
for (int i = 0; i < numberOfContours; ++i) {
vtkNew<vtkRuledSurfaceFilter> ruled;
ruled->SetRuledModeToPointWalk();
ruled->CloseSurfaceOff();
ruled->SetOnRatio(0);
ruled->SetOffset(10);
ruled->OrientLoopsOn();
ruled->SetDistanceFactor(10000000);
ruled->SetInputConnection(skeletons[i]->GetOutputPort());
std::cout << ruled->GetOffset() << endl;
vtkNew<vtkPolyDataNormals> normals;
normals->SetInputConnection(ruled->GetOutputPort());
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(normals->GetOutputPort());
vtkNew<vtkActor> actor;
actor->GetProperty()->SetColor(colors->GetColor3d("Snow").GetData());
actor->SetMapper(mapper);
modelStore.renderer->AddActor(actor);
}
modelStore.renderer->SetBackground(.4, .5, .7);
modelStore.renderWindow->AddRenderer(modelStore.renderer);
ui.openGLWidget->setRenderWindow(modelStore.renderWindow);
ui.openGLWidget->setVisible(true);
Hi 段凡,
I am having some problems when applying the vtkFrenetSerretFrame class in a qt c++ vtk program. Do you have any tips when you implemented your codes?
Kind regards,
Yuxuan