ExtrudePolyDataAlongLine
VTKExamples/Cxx/Visualization/ExtrudePolyDataAlongLine
Code¶
ExtrudePolyDataAlongLine.cxx
#include <vtkFrenetSerretFrame.h> #include <vtkSmartPointer.h> #include <vtkParametricSpline.h> #include <vtkParametricFunctionSource.h> #include <vtkAppendPolyData.h> #include <vtkRuledSurfaceFilter.h> #include <vtkCleanPolyData.h> #include <vtkLineSource.h> #include <vtkFeatureEdges.h> #include <vtkStripper.h> #include <vtkPolyDataConnectivityFilter.h> #include <vtkTransform.h> #include <vtkTransformPolyDataFilter.h> #include <vtkMatrix4x4.h> #include <vtkDiskSource.h> #include <vtkPointSource.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPointData.h> #include <vtkProperty.h> #include <vtkPolyDataMapper.h> #include <vtkCamera.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkPLYReader.h> #include <vtkSTLReader.h> #include <vtkXMLPolyDataReader.h> #include <vtkOBJReader.h> #include <vtksys/SystemTools.hxx> static vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName); int main(int argc, char *argv[]) { // Read a polydata vtkSmartPointer<vtkPolyData> polyData = ReadPolyData(argc > 1 ? argv[1] : "");; int numberOfContours = polyData->GetNumberOfLines(); std::cout << "Number of contours: " << numberOfContours << std::endl; // Generate some random points int numberOfPoints = 3; vtkSmartPointer<vtkPointSource> pointSource = vtkSmartPointer<vtkPointSource>::New(); pointSource->SetNumberOfPoints(numberOfPoints); pointSource->Update(); vtkPoints* points = pointSource->GetOutput()->GetPoints(); vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New(); spline->SetPoints(points); vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(1 * numberOfPoints); functionSource->SetVResolution(1 * numberOfPoints); functionSource->SetWResolution(1 * numberOfPoints); // Create the frame vtkSmartPointer<vtkFrenetSerretFrame> frame = vtkSmartPointer<vtkFrenetSerretFrame>::New(); 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) { vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); // 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 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New(); 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); vtkSmartPointer<vtkTransformPolyDataFilter> transformPD = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); vtkSmartPointer<vtkPolyData> polyDataCopy = vtkSmartPointer<vtkPolyData>::New(); polyDataCopy->DeepCopy(polyData); transformPD->SetTransform(transform); transformPD->SetInputData(polyDataCopy); transformPD->Update(); vtkSmartPointer<vtkPolyDataConnectivityFilter> contours = vtkSmartPointer<vtkPolyDataConnectivityFilter>::New(); contours->SetInputConnection(transformPD->GetOutputPort()); contours->Update(); for (int r = 0; r < contours->GetNumberOfExtractedRegions(); ++r) { contours->SetExtractionModeToSpecifiedRegions(); contours->InitializeSpecifiedRegionList(); contours->AddSpecifiedRegion(r); contours->Update(); vtkSmartPointer<vtkPolyData> skeleton = vtkSmartPointer<vtkPolyData>::New(); skeleton->DeepCopy(contours->GetOutput()); skeletons[r]->AddInputData(skeleton); } } vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); for (int i = 0; i < numberOfContours; ++i) { vtkSmartPointer<vtkRuledSurfaceFilter> ruled = vtkSmartPointer<vtkRuledSurfaceFilter>::New(); ruled->SetRuledModeToPointWalk(); ruled->CloseSurfaceOff(); ruled->SetDistanceFactor(10000000); ruled->SetInputConnection(skeletons[i]->GetOutputPort()); vtkSmartPointer<vtkCleanPolyData> clean = vtkSmartPointer<vtkCleanPolyData>::New(); clean->SetInputConnection(ruled->GetOutputPort()); vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(clean->GetOutputPort()); vtkSmartPointer<vtkProperty> backProp = vtkSmartPointer<vtkProperty>::New(); backProp->SetColor(1,0,0); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetBackfaceProperty(backProp); actor->SetMapper(mapper); renderer->AddActor(actor); } vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); lineMapper->SetInputConnection(functionSource->GetOutputPort()); vtkSmartPointer<vtkActor> lineActor = vtkSmartPointer<vtkActor>::New(); lineActor->SetMapper(lineMapper); // Setup render window, renderer, and interactor vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow(renderWindow); renderer->AddActor(lineActor); renderer->SetBackground(.4, .5, .7); // Pick a good view renderer->ResetCamera(); renderer->GetActiveCamera()->Azimuth(120); renderer->GetActiveCamera()->Elevation(30); renderer->GetActiveCamera()->Dolly(1.8); renderer->ResetCameraClippingRange(); renderWindow->SetSize(640, 480); renderWindow->Render(); renderWindowInteractor->Start(); return EXIT_SUCCESS; } static vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName) { vtkSmartPointer<vtkPolyData> polyData; std::string extension = vtksys::SystemTools::GetFilenameExtension(std::string(fileName)); if (extension == ".ply") { vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".vtp") { vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".obj") { vtkSmartPointer<vtkOBJReader> reader = vtkSmartPointer<vtkOBJReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".stl") { vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else { vtkSmartPointer<vtkDiskSource> diskSource = vtkSmartPointer<vtkDiskSource>::New(); diskSource->SetCircumferentialResolution(3); vtkSmartPointer<vtkCleanPolyData> clean = vtkSmartPointer<vtkCleanPolyData>::New(); clean->SetInputConnection(diskSource->GetOutputPort()); vtkSmartPointer<vtkFeatureEdges> edges = vtkSmartPointer<vtkFeatureEdges>::New(); edges->SetInputConnection(clean->GetOutputPort()); edges->NonManifoldEdgesOff(); edges->ManifoldEdgesOff(); edges->BoundaryEdgesOn(); edges->FeatureEdgesOff(); vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New(); stripper->SetInputConnection(edges->GetOutputPort()); stripper->Update(); polyData = stripper->GetOutput(); #if 0 vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New(); lineSource->SetResolution(10); lineSource->Update(); polyData = lineSource->GetOutput(); #endif } return polyData; }
CMakeLists.txt¶
cmake_minimum_required(VERSION 2.8) PROJECT(ExtrudePolyDataAlongLine) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) add_executable(ExtrudePolyDataAlongLine MACOSX_BUNDLE ExtrudePolyDataAlongLine.cxx) target_link_libraries(ExtrudePolyDataAlongLine ${VTK_LIBRARIES})
Download and Build ExtrudePolyDataAlongLine¶
Danger
The generation of tar files has not been ported to the new VTKExamples. Some tarballs may be missing or out-of-date.
Click here to download ExtrudePolyDataAlongLine and its CMakeLists.txt file. Once the tarball ExtrudePolyDataAlongLine.tar has been downloaded and extracted,
cd ExtrudePolyDataAlongLine/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./ExtrudePolyDataAlongLine
WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.