Display model with scalars

I have a model created with Slicer’s ‘Probe volume with model’. I can display the scalars, and edit the color table, etc., but I can only edit the scalar range up to the maximum (but not exceeding it).

I want to make the maximum value (red in the currently displayed surface) appear yellow. Why can I not arbitrarily set the maximum value of the color table?

THanks!

Manual range setting is limited to the model’s scalar range by default but you can change it by clicking on the triple-dot button right next to it.

I can click the triple dot button and manually enter the intensity range I want, but it doesn’t properly update the range, and when I readjust it with the slider it resets the range I entered manually.

Can I send a video capture?

I’m using Slicer 4.11.0-2019-6-24.

Indeed, there is a glitch that if you change the displayed range values then the maximum range is automatically reset. We’ll fix this, but in the meantime you should still achieve what you need.

There are two main use cases, and both should work well:

  • A. Shared scalar range: when you want to use the same color mapping across several models. Set “Scalar range mode” to “Color table (LUT)” and set range in Colors module.
  • B. Set color mapping to an individual segment: When you just want to colorize a model, you can choose an existing color map and tune what range is emphasized (for this you don’t need to set values outside the scalar range of the volume). Or, if you want specific values to have specific colors then edit the colormap using Colors module (for example, make a copy of PET-Heat color table and edit the colors).

If you want to create a sparse color table with randomly distributed colors then you can write a few lines of Python script for that:

colorTableNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLProceduralColorNode", "MyColors")
colorTableNode.SetType(slicer.vtkMRMLColorTableNode.User)
colorTransferFunction = vtk.vtkDiscretizableColorTransferFunction()
colorTransferFunction.AddRGBPoint(-1000.0, 1.0, 0.0, 0.0)
colorTransferFunction.AddRGBPoint(0.0, 0.0, 1.0, 0.0)
colorTransferFunction.AddRGBPoint(500.0, 0.6, 0.0, 1.0)
colorTransferFunction.AddRGBPoint(1500.0, 1.0, 1.0, 1.0)
colorTableNode.SetAndObserveColorTransferFunction(colorTransferFunction) 
1 Like

Slider range reset is now fixed in r28421. Will be available in tomorrow’s Preview Release.

1 Like

A related question, I tried the above code but the color of the model does not change and it is still gray

    colorTableNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLProceduralColorNode", "MyColors")
    colorTableNode.SetType(slicer.vtkMRMLColorTableNode.User)
    colorTransferFunction = vtk.vtkDiscretizableColorTransferFunction()
    colorTransferFunction.AddRGBPoint(-1000.0, 1.0, 0.0, 0.0)
    colorTransferFunction.AddRGBPoint(0.0, 0.0, 1.0, 0.0)
    colorTransferFunction.AddRGBPoint(500.0, 0.6, 0.0, 1.0)
    colorTransferFunction.AddRGBPoint(1500.0, 1.0, 1.0, 1.0)
    colorTableNode.SetAndObserveColorTransferFunction(colorTransferFunction) 
    modelNode.GetDisplayNode().SetAndObserveColorNodeID(colorTableNode.GetID())

What I am missing?

This code snippet just sets a color look-up table. You also need to select an active scalar and enable scalar display, as shown in this example.

1 Like

Thanks, it seems to work (I only see one color)

    colorTableNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLProceduralColorNode", "MyColors")
    colorTableNode.SetType(slicer.vtkMRMLColorTableNode.User)
    colorTransferFunction = vtk.vtkDiscretizableColorTransferFunction()
    colorTransferFunction.AddRGBPoint(-1000.0, 1.0, 0.0, 0.0)
    colorTransferFunction.AddRGBPoint(0.0, 0.0, 1.0, 0.0)
    colorTransferFunction.AddRGBPoint(500.0, 0.6, 0.0, 1.0)
    colorTransferFunction.AddRGBPoint(1500.0, 1.0, 1.0, 1.0)
    colorTableNode.SetAndObserveColorTransferFunction(colorTransferFunction) 
    cellScalars = modelNode.GetMesh().GetCellData()
    selectionArray = cellScalars.GetArray('selection')
    if not selectionArray:
        selectionArray = vtk.vtkIntArray()
        selectionArray.SetName('selection')
        selectionArray.SetNumberOfValues(modelNode.GetMesh().GetNumberOfCells())
        selectionArray.Fill(0)
        cellScalars.AddArray(selectionArray)
    # Set up coloring by selection array
    modelNode.GetDisplayNode().SetActiveScalar("selection", vtk.vtkAssignAttribute.CELL_DATA)
    modelNode.GetDisplayNode().SetAndObserveColorNodeID(colorTableNode.GetID())
    modelNode.GetDisplayNode().SetScalarVisibility(True)

How to set RGB colors to the modelNode according to its surface normals, for example: RBGColor = RAS_To_RGBMatrix * normalVector

And see with the 3D camera something that looks like like when you define a 2D normals texture (but only on the 3D model’s surface):

Screenshot from 2024-01-15 17-41-04

Would that be possible to implement? Would someone like this coloring according to normals as a new feature?