ColoredAnnotatedCube
VTKExamples/Cxx/VisualizationAlgorithms/ColoredAnnotatedCube
Description¶
This example demonstrates how to color the individual faces of an annotated cube.
This is based on a very nice example by Rodrigo Figueiredo in this discussion.
The process is:
- Create the annotated cube actor using vtkAnnotatedCubeActor.
- Select the names on the faces, text colors and, if needed, any rotations of the text.
- Make the annotated cube transparent.
- Create a cube actor with colored faces.
- Combine the annotated cube actor and cube actor into a prop assembly using vtkPropAssembly. Since the annotated cube and the cube are the same size you get an assembly with colored cube faces and the requisite text.
- Create a vtkOrientationMarkerWidget and set the set the orientation marker to be the prop assembly.
The function MakeAnnotatedCubeActor generates the annotated cube with different colored faces which is then added to a vtkOrientationMarkerWidget.
The colored annotated cube is then placed in the lower left of the view (default). Additionally, a vtkOrientationMarkerWidget containing an axes actor has been added to the lower right of the view.
Other Languages
See (Python)
Code¶
ColoredAnnotatedCube.cxx
#include <vtkAnnotatedCubeActor.h> #include <vtkAxesActor.h> #include <vtkBandedPolyDataContourFilter.h> #include <vtkCamera.h> #include <vtkCaptionActor2D.h> #include <vtkCellData.h> #include <vtkColorSeries.h> #include <vtkColorTransferFunction.h> #include <vtkConeSource.h> #include <vtkCubeSource.h> #include <vtkElevationFilter.h> #include <vtkLookupTable.h> #include <vtkNamedColors.h> #include <vtkOrientationMarkerWidget.h> #include <vtkPolyDataMapper.h> #include <vtkPropAssembly.h> #include <vtkProperty.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> #include <vtkSmartPointer.h> #include <vtkTextProperty.h> #include <vtkTransform.h> #include <vtkTransformPolyDataFilter.h> #include <array> namespace { /** * Nake the annotated cube actor with different colored faces. * * @param colors: Used to set the colors of the cube faces. * @return The annotated cube actor. */ vtkSmartPointer<vtkPropAssembly> MakeAnnotatedCubeActor(vtkNamedColors* colors); /** * Make an axes actor. * * @param scale: Sets the scale and direction of the axes. * @param xyzLabels: Labels for the axes. * @return The axes actor. */ vtkSmartPointer<vtkAxesActor> MakeAxesActor(std::array<double, 3>& scale, std::array<std::string, 3>& xyzLabels); } // namespace int main(int, char*[]) { // Basic stuff setup // Set up the renderer, window, and interactor auto colors = vtkSmartPointer<vtkNamedColors>::New(); auto ren = vtkSmartPointer<vtkRenderer>::New(); auto renWin = vtkSmartPointer<vtkRenderWindow>::New(); renWin->AddRenderer(ren); renWin->SetSize(640, 480); auto iRen = vtkSmartPointer<vtkRenderWindowInteractor>::New(); iRen->SetRenderWindow(renWin); // Create a cone with an elliptical base whose major axis is in the // X-direction. auto coneSource = vtkSmartPointer<vtkConeSource>::New(); coneSource->SetCenter(0.0, 0.0, 0.0); coneSource->SetRadius(5.0); coneSource->SetHeight(15.0); coneSource->SetDirection(0, 1, 0); coneSource->SetResolution(60); coneSource->Update(); auto transform = vtkSmartPointer<vtkTransform>::New(); transform->Scale(1.0, 1.0, 0.75); auto transF = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); transF->SetInputConnection(coneSource->GetOutputPort()); transF->SetTransform(transform); double bounds[6]; transF->GetOutput()->GetBounds(bounds); auto elevation = vtkSmartPointer<vtkElevationFilter>::New(); elevation->SetInputConnection(transF->GetOutputPort()); elevation->SetLowPoint(0, bounds[2], 0); elevation->SetHighPoint(0, bounds[3], 0); auto bandedContours = vtkSmartPointer<vtkBandedPolyDataContourFilter>::New(); bandedContours->SetInputConnection(elevation->GetOutputPort()); bandedContours->SetScalarModeToValue(); bandedContours->GenerateContourEdgesOn(); bandedContours->GenerateValues(11, elevation->GetScalarRange()); // Make a lookup table using a color series. auto colorSeries = vtkSmartPointer<vtkColorSeries>::New(); colorSeries->SetColorScheme(vtkColorSeries::BREWER_DIVERGING_SPECTRAL_11); auto lut = vtkSmartPointer<vtkLookupTable>::New(); colorSeries->BuildLookupTable(lut, vtkColorSeries::ORDINAL); auto coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); coneMapper->SetInputConnection(bandedContours->GetOutputPort()); coneMapper->SetScalarRange(elevation->GetScalarRange()); coneMapper->SetLookupTable(lut); auto coneActor = vtkSmartPointer<vtkActor>::New(); coneActor->SetMapper(coneMapper); // Contouring auto contourLineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); contourLineMapper->SetInputData(bandedContours->GetContourEdgesOutput()); contourLineMapper->SetScalarRange(elevation->GetScalarRange()); contourLineMapper->SetResolveCoincidentTopologyToPolygonOffset(); auto contourLineActor = vtkSmartPointer<vtkActor>::New(); contourLineActor->SetMapper(contourLineMapper); contourLineActor->GetProperty()->SetColor( colors->GetColor3d("DimGray").GetData()); // Set up the Orientation Marker Widget. auto prop_assembly = MakeAnnotatedCubeActor(colors); auto om1 = vtkSmartPointer<vtkOrientationMarkerWidget>::New(); om1->SetOrientationMarker(prop_assembly); om1->SetInteractor(iRen); om1->SetDefaultRenderer(ren); om1->On(); om1->InteractiveOn(); std::array<std::string, 3> xyzLabels{{"X", "Y", "Z"}}; std::array<double, 3> scale{{1.0, 1.0, 1.0}}; auto axes = MakeAxesActor(scale, xyzLabels); auto om2 = vtkSmartPointer<vtkOrientationMarkerWidget>::New(); om2->SetOrientationMarker(axes); // Position lower right in the viewport. om2->SetViewport(0.8, 0, 1.0, 0.2); om2->SetInteractor(iRen); om2->EnabledOn(); om2->InteractiveOn(); ren->AddActor(coneActor); ren->AddActor(contourLineActor); ren->SetBackground2(colors->GetColor3d("RoyalBlue").GetData()); ren->SetBackground(colors->GetColor3d("MistyRose").GetData()); ren->GradientBackgroundOn(); ren->GetActiveCamera()->Azimuth(45); ren->GetActiveCamera()->Pitch(-22.5); ren->ResetCamera(); renWin->SetSize(600, 600); renWin->Render(); renWin->SetWindowName("ColoredAnnotatedCube"); renWin->Render(); iRen->Start(); return EXIT_SUCCESS; } namespace { vtkSmartPointer<vtkPropAssembly> MakeAnnotatedCubeActor(vtkNamedColors* colors) { // Annotated Cube setup auto annotated_cube = vtkSmartPointer<vtkAnnotatedCubeActor>::New(); annotated_cube->SetFaceTextScale(0.366667); // Anatomic labeling annotated_cube->SetXPlusFaceText("X+"); annotated_cube->SetXMinusFaceText("X-"); annotated_cube->SetYPlusFaceText("Y+"); annotated_cube->SetYMinusFaceText("Y-"); annotated_cube->SetZPlusFaceText("Z+"); annotated_cube->SetZMinusFaceText("Z-"); // Change the vector text colors annotated_cube->GetTextEdgesProperty()->SetColor( colors->GetColor3d("Black").GetData()); annotated_cube->GetTextEdgesProperty()->SetLineWidth(1); annotated_cube->GetXPlusFaceProperty()->SetColor( colors->GetColor3d("Turquoise").GetData()); annotated_cube->GetXMinusFaceProperty()->SetColor( colors->GetColor3d("Turquoise").GetData()); annotated_cube->GetYPlusFaceProperty()->SetColor( colors->GetColor3d("Mint").GetData()); annotated_cube->GetYMinusFaceProperty()->SetColor( colors->GetColor3d("Mint").GetData()); annotated_cube->GetZPlusFaceProperty()->SetColor( colors->GetColor3d("Tomato").GetData()); annotated_cube->GetZMinusFaceProperty()->SetColor( colors->GetColor3d("Tomato").GetData()); annotated_cube->SetXFaceTextRotation(90); annotated_cube->SetYFaceTextRotation(180); annotated_cube->SetZFaceTextRotation(-90); // Make the annotated cube transparent annotated_cube->GetCubeProperty()->SetOpacity(0); // Colored faces cube setup auto cube_source = vtkSmartPointer<vtkCubeSource>::New(); cube_source->Update(); auto face_colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); face_colors->SetNumberOfComponents(3); auto face_x_plus = colors->GetColor3ub("Red").GetData(); auto face_x_minus = colors->GetColor3ub("Green").GetData(); auto face_y_plus = colors->GetColor3ub("Blue").GetData(); auto face_y_minus = colors->GetColor3ub("Yellow").GetData(); auto face_z_plus = colors->GetColor3ub("Cyan").GetData(); auto face_z_minus = colors->GetColor3ub("Magenta").GetData(); face_colors->InsertNextTypedTuple(face_x_minus); face_colors->InsertNextTypedTuple(face_x_plus); face_colors->InsertNextTypedTuple(face_y_minus); face_colors->InsertNextTypedTuple(face_y_plus); face_colors->InsertNextTypedTuple(face_z_minus); face_colors->InsertNextTypedTuple(face_z_plus); cube_source->GetOutput()->GetCellData()->SetScalars(face_colors); cube_source->Update(); auto cube_mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); cube_mapper->SetInputData(cube_source->GetOutput()); cube_mapper->Update(); auto cube_actor = vtkSmartPointer<vtkActor>::New(); cube_actor->SetMapper(cube_mapper); // Assemble the colored cube and annotated cube texts into a composite prop. auto prop_assembly = vtkSmartPointer<vtkPropAssembly>::New(); prop_assembly->AddPart(annotated_cube); prop_assembly->AddPart(cube_actor); return prop_assembly; } vtkSmartPointer<vtkAxesActor> MakeAxesActor(std::array<double, 3>& scale, std::array<std::string, 3>& xyzLabels) { auto axes = vtkSmartPointer<vtkAxesActor>::New(); axes->SetScale(scale[0], scale[1], scale[2]); axes->SetShaftTypeToCylinder(); axes->SetXAxisLabelText(xyzLabels[0].c_str()); axes->SetYAxisLabelText(xyzLabels[1].c_str()); axes->SetZAxisLabelText(xyzLabels[2].c_str()); axes->SetCylinderRadius(0.5 * axes->GetCylinderRadius()); axes->SetConeRadius(1.025 * axes->GetConeRadius()); axes->SetSphereRadius(1.5 * axes->GetSphereRadius()); vtkTextProperty* tprop = axes->GetXAxisCaptionActor2D()->GetCaptionTextProperty(); tprop->ItalicOn(); tprop->ShadowOn(); tprop->SetFontFamilyToTimes(); // Use the same text properties on the other two axes. axes->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy(tprop); axes->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->ShallowCopy(tprop); return axes; } } // namespace
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(ColoredAnnotatedCube) find_package(VTK COMPONENTS vtkCommonColor vtkCommonCore vtkCommonDataModel vtkCommonTransforms vtkFiltersCore vtkFiltersGeneral vtkFiltersModeling vtkFiltersSources vtkInteractionStyle vtkInteractionWidgets vtkRenderingAnnotation vtkRenderingContextOpenGL2 vtkRenderingCore vtkRenderingFreeType vtkRenderingGL2PSOpenGL2 vtkRenderingOpenGL2 QUIET) if (NOT VTK_FOUND) message("Skipping ColoredAnnotatedCube: ${VTK_NOT_FOUND_MESSAGE}") return () endif() message (STATUS "VTK_VERSION: ${VTK_VERSION}") if (VTK_VERSION VERSION_LESS "8.90.0") # old system include(${VTK_USE_FILE}) add_executable(ColoredAnnotatedCube MACOSX_BUNDLE ColoredAnnotatedCube.cxx ) target_link_libraries(ColoredAnnotatedCube PRIVATE ${VTK_LIBRARIES}) else () # include all components add_executable(ColoredAnnotatedCube MACOSX_BUNDLE ColoredAnnotatedCube.cxx ) target_link_libraries(ColoredAnnotatedCube PRIVATE ${VTK_LIBRARIES}) # vtk_module_autoinit is needed vtk_module_autoinit( TARGETS ColoredAnnotatedCube MODULES ${VTK_LIBRARIES} ) endif ()
Download and Build ColoredAnnotatedCube¶
Click here to download ColoredAnnotatedCube and its CMakeLists.txt file. Once the tarball ColoredAnnotatedCube.tar has been downloaded and extracted,
cd ColoredAnnotatedCube/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:
./ColoredAnnotatedCube
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.