Colors of vtkAnnotatedCubeActor faces (with vtkOrientationMarkerWidget)

(Marco Sambin) #1

Hi all.
In my VTK 3D scene, I am using a vtkOrientationMarkerWidget which in turn uses a vtkAnnotatedCubeActor as the widget’s vtkProp.

I have an apparently-trivial question: how to customize the colors of this cube’s faces?

I am easily able to customize the texts appearing on each cube’s face, but I could not find an easy way to customize faces colors.

Any hint?

Thanks in advance and best regards,

Marco Sambin

(Andrew Maclean) #2

This example may help AnatomicalOrientation. Actually it may not help as only the text color is changed.

(Marco Sambin) #3

Hi Andrew,

thanks for taking the time to share this example with me.

Actually, as you guessed in your message, I was already able to change the text color. What I would like to achieve is changing the color of the “faces” of the cube, and I didn’t find an easy way to do this.

What I imagined to do was to associate cell data to the cube source, and then maybe apply a LUT on cell data on the mapper. In addition to being complex, this doesn’t even seem to be possible, as the cubeSource is not accessible on my vtkAnnotatedCubeActor instance…
Moreover, setting this LUT on my mapper could even have other side-effects…

Anything simpler?

Any further hint would be greatly appreciated.
Best regards,

Marco Sambin

(Rodrigo Figueiredo) #4

Hi Marco!

The best solution I could think of is to compose the letters from the vtkAnnotatedCubeActor with a basic cube actor of the same size with colored faces. In order to do that, you should:

  1. Hide the annotated cube faces by setting it’s opacity property to 0
  2. Create an array to hold the six colors for the faces
  3. Create a actor based on the vtkCubeSource setting its CellData Scalars to use the color array
  4. Merge the vtkAnnotatedCubeActor and colored actor using vtkPropAssembly
  5. Use the vtkPropAssembly output as your marker for the vtkOrientationMarkerWidget

I tried to simplify the coloring part, to avoid difficulties for you to choose what colors go in what faces:

  vtkSmartPointer<vtkUnsignedCharArray> face_colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
  face_colors->SetNumberOfComponents(3);
  unsigned char face_x_plus[3]  = { 255,0,0 };
  unsigned char face_x_minus[3] = { 0,255,0 };
  unsigned char face_y_plus[3]  = { 0,0,255 };
  unsigned char face_y_minus[3] = { 255,255,0 };
  unsigned char face_z_plus[3]  = { 0,255,255 };
  unsigned char face_z_minus[3] = { 255,0,255 };
  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);

Anyways, follow attached the modified example I made to test it. main.cpp (4.6 KB)

Hope this is useful.
Have a fruitful week!

Rodrigo Figueiredo.

1 Like
(Andrew Maclean) #5

That is a really nice approach and very ingenious. Would you like to contribute it to VTKExamples? I would be glad to help or add it for you.

(Marco Sambin) #6

Dear Rodrigo,

I would like to really thank you very much for taking the time to provide such a complete reply to my post: your suggestion is very smart, and it works indeed!

For those working with Java (like me), I would just like to mention that some of the methods that you used on vtkUnsignedCharArray are not available, hence here is the Java equivalent of that portion:

======

  vtkCubeSource cubeSource = new vtkCubeSource();
  cubeSource.Update();
  
  vtkUnsignedCharArray faceColors = new vtkUnsignedCharArray();
  faceColors.SetNumberOfComponents(3);
  faceColors.InsertNextTuple3(255, 0, 0);
  faceColors.InsertNextTuple3(255, 0, 0);
  faceColors.InsertNextTuple3(0, 255, 0);
  faceColors.InsertNextTuple3(0, 255, 0);
  faceColors.InsertNextTuple3(0, 0, 255);
  faceColors.InsertNextTuple3(0, 0, 255);
  
  cubeSource.GetOutput().GetCellData().SetScalars(faceColors);
  cubeSource.Update();
  
  vtkPolyDataMapper cubeMapper = new vtkPolyDataMapper();
  cubeMapper.SetInputData(cubeSource.GetOutput());
  cubeMapper.Update();
  
  vtkActor cubeActor = new vtkActor();
  cubeActor.SetMapper(cubeMapper);
  
  vtkPropAssembly propAssembly = new vtkPropAssembly();
  propAssembly.AddPart(orientMarkerCubeProp);
  propAssembly.AddPart(cubeActor);

======

Once again, thanks a lot, you solved my problem man!

Best regards,

Marco Sambin

1 Like
(Rodrigo Figueiredo) #7

Thanks!
If you consider that this would be a useful contribution, I would be interested in seeing how you did it afterwards, since I don’t know how to do it.

And @Marco, I’m glad it helped :wink:

All the best,
Rodrigo Figueiredo.

(Andrew Maclean) #8

@figueiredo I’ll do a C++ and Python version for the VTK Examples.

1 Like
(Andrew Maclean) #9

The examples are here (C++) and here (Python).

Thanks once again @figueiredo for the idea.

1 Like