Volume rendering Error

Hi all,
I have a Problem with the volume rendering. If I try to use the vtkSmartVolumeMapper i get the following Error:

ERROR: vtkSmartVolumeMapper (000002A431C3C1B0): Could not find the requested vtkDataArray! 0, 0, -1, 

My File: https://drive.google.com/open?id=1bXapjrNTirGECwRymt9SNChx2lyIpaV8
My Code is as follows:

 #include <vtkRenderWindow.h>
 #include <vtkRenderWindowInteractor.h>
 #include <vtkRenderer.h>
 #include <vtkSmartPointer.h>
 #include <vtkStructuredPointsReader.h>
 #include <vtkPiecewiseFunction.h>
 #include <vtkSmartVolumeMapper.h>
 #include <vtkColorTransferFunction.h>
 #include <vtkVolume.h>
 #include <vtkVolumeProperty.h>
 #include <vtkRectilinearGridReader.h>
 #include <vtkSmartPointer.h>
 #include <vtkNetCDFReader.h>

 int main()
 {

     // Add named color library
     vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

     // Create renderer
     vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();

     // Create a new render window
     vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
     renWin->AddRenderer(renderer);

     // Make the render window interacting
     vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
     iren->SetRenderWindow(renWin);

     vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
     
     string filenameNC = "C:\\snapshot_ql_00081.nc";
     vtkSmartPointer<vtkNetCDFReader> cdfReader = vtkSmartPointer<vtkNetCDFReader>::New();
     cdfReader->SetFileName(filenameNC.c_str());
     cdfReader->UpdateInformation();
     cdfReader->SetDimensions("z,y,x");
     cdfReader->SetVariableArrayStatus("ql_3D", 1);
  
     // Add a piece-wise function for color transfer functions. Piece-wise means 
     // adding control (interpolation) points.
     vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
     opacityTransferFunction->AddPoint(0, 0.0);
     opacityTransferFunction->AddPoint(0.342, 1.0);

     // Piece-wise function cannot be used for colors because colors are vectors
     vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction> ::New();
     colorTransferFunction->AddRGBPoint(0, 0.23, 0.29, 0.75);
     colorTransferFunction->AddRGBPoint(0.171, 0.860, 0.860, 0.860);
     colorTransferFunction->AddRGBPoint(0.342, 0.70, 0.010, 0.140);


     // Set volume rendering properties
     vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
     volumeProperty->SetColor(colorTransferFunction);
     volumeProperty->SetScalarOpacity(opacityTransferFunction);
     volumeProperty->ShadeOn();
     volumeProperty->SetInterpolationTypeToLinear();

     // Add a mapper to create graphic primitives from the data
     vtkSmartPointer<vtkSmartVolumeMapper> mapper = vtkSmartPointer<vtkSmartVolumeMapper>:New();
     mapper->SetBlendModeToComposite();
     mapper->SetInputConnection(cdfReader->GetOutputPort());

     // Create a new actor(the actual graphics object) and add the mapped data to 
     // it
     vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
     volume->SetMapper(mapper);
     volume->SetProperty(volumeProperty);

     // Add the volume actor to the renderer
     renderer->AddVolume(volume);

     // Set the background color

     renderer->SetBackground(colors->GetColor3d("Black").GetData());

     // Set the size of the render window
     renWin->SetSize(512, 512);

     // Render the data 
     renWin->Render();

     // Start the interactor
     iren->Start();

     return 0;
 }

Thanks for your help in advance :slight_smile:

Hi, Alex!
That error is thrown by https://github.com/Kitware/VTK/blob/master/Rendering/VolumeOpenGL2/vtkSmartVolumeMapper.cxx here:

    vtkDataArray* scalars = this->GetScalars(input, this->ScalarMode, this->ArrayAccessMode,
    this->ArrayId, this->ArrayName, usingCellColors);

  if (!scalars)
  {
    vtkErrorMacro("Could not find the requested vtkDataArray! "
      << this->ScalarMode << ", " << this->ArrayAccessMode << ", " << this->ArrayId << ", "
      << this->ArrayName);
    this->Initialized = 0;
    return;
  }

This implies that the call to GetScalars() is returning a null pointer. So, I guess you have to do a mapper->SelectScalarArray([id of array goes here]).

regards,

Paulo

Hi Paulo,
i tried mapper->SelectScalarArray([id of array goes here]) an get the same error.

Best regards,
Alex

Hi. Which value did you use for id?

I tried 0,1,2,3 … but nothing happend. I also tried to use mapper->SelectScalarArray("ql_3D")
the same Array I use with cdfReader->SetVariableArrayStatus("ql_3D") but again I get the error:
vtkSmartVolumeMapper (000002AF1B0803C0): Could not find the requested vtkDataArray! 0, 1, -1, ql_3D

I have a solution for my Problem. I need to use vtkAssignAttribute to assign an array which I want to use and change the reader from vtkNetCDFReader to vtkNetCDFCFReader

    // Create renderer
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();

    // Create a new render window
    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(renderer);

    // Make the render window interacting
    vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetRenderWindow(renWin);


    string filenameNC = "C:\\snapshot_ql_00081.nc";
    
    vtkSmartPointer<vtkNetCDFCFReader> cdfCFReader = vtkSmartPointer<vtkNetCDFCFReader>::New();
    cdfCFReader->SetFileName(filenameNC.c_str());
    //cdfCFReader->SetDimensions("z,y,x");
    cdfCFReader->SetVariableArrayStatus("ql_3D", 1);
    cdfCFReader->Update();

	// Assign an Array which we well use 
    vtkSmartPointer<vtkAssignAttribute> assignAttribute = vtkSmartPointer<vtkAssignAttribute>::New();
    assignAttribute->SetInputConnection(cdfCFReader->GetOutputPort());
    assignAttribute->Assign("ql_3D", "SCALARS", "POINT_DATA");
	
 // Piece-wise function cannot be used for colors because colors are vectors
    vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
    opacityTransferFunction->AddPoint(0, 0.0);
    opacityTransferFunction->AddPoint(0.342, 1.0);
	
	// Set volume rendering properties
    vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
    volumeProperty->SetColor(colorTransferFunction);
    volumeProperty->SetScalarOpacity(opacityTransferFunction);
    volumeProperty->ShadeOn();
    volumeProperty->SetInterpolationTypeToLinear();
	
	// Add a mapper to create graphic primitives from the data
    vtkSmartPointer<vtkSmartVolumeMapper> mapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
	mapper->SetBlendModeToComposite();
    mapper->SetInputConnection(assignAttribute->GetOutputPort());
	
	// Create a new actor(the actual graphics object) and add the mapped data to it
    vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(mapper);
    volume->SetProperty(volumeProperty);
    
    // Add the volume actor to the renderer
    renderer->AddVolume(volume);
	
	// Render the data 
    renWin->Render();
	
	// Start the interactor
    iren->Start(); ```
1 Like