vtkMarchingCubes is a filter that takes as input a volume (e.g., 3D structured point set) and generates on output one or more isosurfaces. One or more contour values must be specified to generate the isosurfaces. Alternatively, you can specify a min/max scalar range and the number of contours to generate a series of evenly spaced contour values.
vtkContourFilter is a filter that takes as input any dataset and generates on output isosurfaces and/or isolines. The exact form of the output depends upon the dimensionality of the input data. Data consisting of 3D cells will generate isosurfaces, data consisting of 2D cells will generate isolines, and data with 1D or 0D cells will generate isopoints. Combinations of output type are possible if the input dimension is mixed.
To use this filter you must specify one or more contour values. You can either use the method SetValue() to specify each contour value, or use GenerateValues() to generate a series of evenly spaced contours. It is also possible to accelerate the operation of this filter (at the cost of extra memory) by using a vtkScalarTree. A scalar tree is used to quickly locate cells that contain a contour surface. This is especially effective if multiple contours are being extracted. If you want to use a scalar tree, invoke the method UseScalarTreeOn().
auto reader = vtkSmartPointer<vtkMetaImageReader>::New(); reader->SetFileName(argv[1]);
#if 0 // An isosurface, or contour value of 500 is known to correspond to the // skin of the patient. auto skinExtractor = vtkSmartPointer<vtkMarchingCubes>::New(); skinExtractor->SetInputConnection(reader->GetOutputPort()); skinExtractor->SetValue(0, 500);
// An isosurface, or contour value of 1150 is known to correspond to the // bone of the patient. auto boneExtractor = vtkSmartPointer<vtkMarchingCubes>::New(); boneExtractor->SetInputConnection(reader->GetOutputPort()); boneExtractor->SetValue(0, 1150);
// The triangle stripper is used to create triangle strips from the // isosurface; these render much faster on may systems. auto skinStripper = vtkSmartPointer<vtkStripper>::New(); skinStripper->SetInputConnection(skinExtractor->GetOutputPort());
auto boneStripper = vtkSmartPointer<vtkStripper>::New(); boneStripper->SetInputConnection(boneExtractor->GetOutputPort()); #else // An isosurface, or contour value of 500 is known to correspond to the // skin of the patient. auto skinExtractor = vtkSmartPointer<vtkContourFilter>::New(); skinExtractor->SetInputConnection(reader->GetOutputPort()); skinExtractor->SetValue(0, 500);
// An isosurface, or contour value of 1150 is known to correspond to the // bone of the patient. auto boneExtractor = vtkSmartPointer<vtkContourFilter>::New(); boneExtractor->SetInputConnection(reader->GetOutputPort()); boneExtractor->SetValue(0, 1150);
auto skinNormals = vtkSmartPointer<vtkPolyDataNormals>::New(); skinNormals->SetInputConnection(skinExtractor->GetOutputPort()); skinNormals->SetFeatureAngle(60.0);
auto boneNormals = vtkSmartPointer<vtkPolyDataNormals>::New(); boneNormals->SetInputConnection(boneExtractor->GetOutputPort()); boneNormals->SetFeatureAngle(60.0);
// The triangle stripper is used to create triangle strips from the // isosurface; these render much faster on may systems. auto skinStripper = vtkSmartPointer<vtkStripper>::New(); skinStripper->SetInputConnection(skinNormals->GetOutputPort());
auto boneStripper = vtkSmartPointer<vtkStripper>::New(); boneStripper->SetInputConnection(boneNormals->GetOutputPort()); #endif
auto skinMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); skinMapper->SetInputConnection(skinStripper->GetOutputPort()); skinMapper->ScalarVisibilityOff(); auto boneMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); boneMapper->SetInputConnection(boneStripper->GetOutputPort()); boneMapper->ScalarVisibilityOff();
auto skin = vtkSmartPointer<vtkActor>::New(); skin->SetMapper(skinMapper); skin->GetProperty()->SetDiffuseColor(colors->GetColor3d("SkinColor").GetData()); skin->GetProperty()->SetSpecular(.3); skin->GetProperty()->SetSpecularPower(20); skin->GetProperty()->SetOpacity(.5);
auto bone = vtkSmartPointer<vtkActor>::New(); bone->SetMapper(boneMapper); bone->GetProperty()->SetDiffuseColor(colors->GetColor3d("Ivory").GetData());
// An outline provides context around the data. auto outlineData = vtkSmartPointer<vtkOutlineFilter>::New(); outlineData->SetInputConnection(reader->GetOutputPort());
auto outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); outlineMapper->SetInputConnection(outlineData->GetOutputPort());
auto outline = vtkSmartPointer<vtkActor>::New(); outline->SetMapper(outlineMapper); outline->GetProperty()->SetColor(1, 0, 0);
auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(skin); renderer->AddActor(bone); renderer->AddActor(outline);
auto renWindow = vtkSmartPointer<vtkRenderWindow>::New(); renWindow->SetSize(640, 480); renWindow->AddRenderer(renderer);
auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renWindow);