Unable to use TubeFilter with multiple CellData for coloring.

We are currently working on implementing an interactive visualization of a set of boreholes within a React framework using vtk.js. Our approach involves parsing boreholes using the XMLPolyDataReader to process an XML string labeled lineSetXML in the below code snippet. The ultimate goal is to visualize several scalar features of these boreholes using color maps.

However, we’ve encountered an issue when attempting to color the tubes based on cell data arrays other than the last one in the XML. It appears that the values become incorrect, displaying as constant values (potentially dependent on the first value in the array).

Here’s a simplified version of our loading code:

const tubeActor = vtkActor.newInstance()
renderer.addActor(tubeActor);
const boreholeMapper = vtkMapper.newInstance();
tubeActor.setMapper(boreholeMapper);
const tubeFilter = vtkTubeFilter.newInstance();
tubeFilter.setCapping(true);
tubeFilter.setNumberOfSides(10);
tubeFilter.setRadius(2.);

// Load lineSetXML
const boreholeReader = vtkXMLPolyDataReader.newInstance();
boreholeReader.parseAsArrayBuffer(encoder.encode(lineSetXML).buffer);
const boreholePolydata = boreholeReader.getOutputData();
console.log(boreholePolydata.getCellData().toJSON()); // log to console first time

tubeFilter.setInputData(boreholePolydata);
boreholeMapper.setInputData(tubeFilter.getOutputData())

When I inspect the cell data at this stage, it seems to be correct. Next we set the colour dynamically based on selectedArrayName.

boreholeMapper.setScalarModeToUseCellData();
let boreholePolydata = boreholeMapper.getInputData() //vtkClass: vtkPolyData
boreholePolydata.getCellData().setActiveScalars(selectedArrayName);

console.log(boreholePolydata.getCellData().toJSON()); // log to console second time

let range = boreholePolydata.getCellData().getArrayByName(selectedArrayName).getRange();
boreholeMapper.setScalarRange(range);
boreholeMapper.setColorByArrayName(selectedArrayName);

// Set color
let boreholeLut = vtkColorTransferFunction.newInstance();
boreholeLut.applyColorMap(vtkColorMaps.getPresetByName('Black, Orange and White'));
boreholeMapper.setLookupTable(boreholeLut); 

When I inspect the log at this time, the order of the CellData arrays has changed. Length of the arrays are no longer the same, and values are usually constants.

We’d appreciate any insights or suggestions on how to resolve this behavior.

Hello,

Here’s how a setup a tube filter in C++ to display oil wells:


    vtkSmartPointer<vtkPolyData> poly = vtkSmartPointer<vtkPolyData>::New();
    poly->SetPints(...    
 
    // build a tube around the polygonal line
    vtkSmartPointer<vtkTubeFilter> tubeFilter =
      vtkSmartPointer<vtkTubeFilter>::New();
    tubeFilter->SetInputData( poly );
    tubeFilter->SetRadius(10); //default is .5
    tubeFilter->SetNumberOfSides(50);
    tubeFilter->Update();

    vtkSmartPointer<vtkLookupTable> lut = ...

    // Create a VTK mapper and actor to enable its visualization
    vtkSmartPointer<vtkPolyDataMapper> tubeMapper =
      vtkSmartPointer<vtkPolyDataMapper>::New();
    tubeMapper->SetInputConnection(tubeFilter->GetOutputPort());
    tubeMapper->SetLookupTable(lut);
    tubeMapper->SetScalarModeToUseCellData();
    tubeMapper->SetColorModeToMapScalars();
    tubeMapper->SelectColorArray("values");
    tubeMapper->SetScalarRange(min, max);

    vtkSmartPointer<vtkActor> tubeActor =
      vtkSmartPointer<vtkActor>::New();
    tubeActor->GetProperty()->SetOpacity(1.0); //Make the tube have some transparency.
    tubeActor->SetMapper(tubeMapper);

I think the key missing call in your case is:

boreholeMapper.setColorModeToMapScalars();

Also, you instantiate tubeMapper as const and call clearly state-changing methods on it (e.g. setScalarRange()). I don’t know how that works in Javascript (does it make copies?), but in C++ that definitely would not work.

I know VTK API varies a bit between languages, but another point of attention is that you use setColorByArrayName() whereas I use SelectColorArray() to select the array of scalars to use in painting the tubes.

regards,

PC

Hi Paulo,

Thanks allot for the reply and the code snippet! Nice to know that such a similar code works in C++. I am definitively not an expert in javascript, but I believe the use of const in javascript only applies to the reference and not the object itself.

I’ll look into the setColorModeToMapScalars. I see that there is also such a method associated with the mappers in vtk.js.

Regarding the code as it is now, it works fine if I skip the filter and pass the poltydata directly to the mapper. It also works if there is only a single array associated with the CellData.

Regards,
Erlend.

1 Like

I tested adding a call to setColorModeToMapScalars. Unfortunatly it does not appear to have any effect on the current problem. Anyway - thanks for the suggestion!