Add temperature attribute using vtkDoubleArray->SetArray is not effect the result color

Hi,
I am a beginner, when I my vtkUnstructuredGrid object have a attribute temperature, there are 2 methods to put it into vtkUnstructuredGrid object, one is that put 1 by 1 using InsertNextTuple1() , this method work well. the other is that put all at once using SetArray, all work well , but the result color is shown according to the input temperature?
this is my code:
void MainWindow::showCyScene()
{

double xyz[][3]={{0, 0 ,2 },
                 {1, 0 ,2 },
                 {1, 1 ,2 },
                 {0, 1 ,2 },
                 {2, 0 ,2 },
                 {3, 0 ,2 },
                 {3, 1 ,2 },
                 {2, 1 ,2 }};

vtkIdType cells[][3]={{0 ,1,2 },
                {0 ,2,3 },
                {1 ,4,2 },
                {4 ,7,2 },
                {4 ,5,7 },
                {5 ,6,7 }};

double temperature[8]={1.0 ,2.0 ,2.0 ,1.0,3.0, 4.0 ,4.0, 3.0};

vtkSmartPointer<vtkPoints> pts=vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkUnstructuredGrid> ug=vtkSmartPointer<vtkUnstructuredGrid>::New();

for(int i=0;i<8;i++)
    pts->InsertNextPoint(xyz[i]);
for (int i = 0; i < 6; ++i) {
    ug->InsertNextCell(VTK_TRIANGLE,3,cells[i]);
}

ug->SetPoints(pts);

vtkSmartPointer<vtkDoubleArray> da=vtkSmartPointer<vtkDoubleArray>::New();
da->SetName("temp");
da->SetArray(temperature,8,1);   //Method 1: using SetArray() add temperature at once is not effective. 

// for(int i=0;i<8;i++)
// da->InsertNextTuple1(temperature[i]); //Method 2: using InsertNextTuple() add temperature 1 by 1 is effective.

ug->GetPointData()->SetScalars(da);
qDebug()<<ug->GetPointData()->GetArrayName(0);
ug->GetPointData()->SetActiveScalars("temp");


vtkSmartPointer<vtkLookupTable> lut=vtkSmartPointer<vtkLookupTable>::New();
lut->SetNumberOfColors(3);
lut->SetTableValue(0,1,1,1);
lut->SetTableValue(1,0,1,0);
lut->SetTableValue(2,0,0,1);
lut->Build();

vtkSmartPointer<vtkDataSetMapper> mapper=vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInputData(ug);

mapper->SetScalarRange(1.0,5.0);
mapper->SetLookupTable(lut);
mapper->ScalarVisibilityOn();
mapper->SetScalarModeToUsePointData();

vtkSmartPointer<vtkActor> actor= vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);

vtkSmartPointer<vtkRenderer> renderer=
        vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(1,1,1);

renderer->AddActor(actor);

vtkSmartPointer<vtkAxesActor> actor2 = 	vtkSmartPointer<vtkAxesActor>::New();
actor2->SetPosition(0, 0, 0);
actor2->SetTotalLength(2,2,2);
actor2->SetShaftType(0);
actor2->SetAxisLabels(0);
actor2->SetCylinderRadius(0.02);
renderer->AddActor(actor2);

renderer->SetBackground(0.1,0.2,0.4);
renderer->ResetCamera();

this->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);

}

Thank you for your help

Leo

After bulk operations on an array, you need to indicate that you have finished the updates by calling its Modified() method.

Andras Lasso, Thanks for your quickly reply, I have tried adding da->Modified() aft da->SetArray(temperature,8,1), but it not work yet.

I don’t have any other idea, but you can easily see what goes wrong if you go execute your code in a debugger - stepping into VTK methods, to see if they do what you expect.

Hi, friend,

I think you need to set a transfer function for your LUT object. I set my color mapping with this:

vtkSmartPointer<vtkLookupTable> getClassicRainbow(double min, double max)
{
    size_t tableSize = 32;

    //create a color interpolator object
    vtkSmartPointer<vtkColorTransferFunction> ctf =
            vtkSmartPointer<vtkColorTransferFunction>::New();
    ctf->SetColorSpaceToRGB();
    ctf->AddRGBPoint(0.00, 0.000, 0.000, 1.000);
    ctf->AddRGBPoint(0.25, 0.000, 1.000, 1.000);
    ctf->AddRGBPoint(0.50, 0.000, 1.000, 0.000);
    ctf->AddRGBPoint(0.75, 1.000, 1.000, 0.000);
    ctf->AddRGBPoint(1.00, 1.000, 0.000, 0.000);

    //create the color table object
    vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetTableRange(min, max);
    lut->SetNumberOfTableValues(tableSize);
    for(size_t i = 0; i < tableSize; ++i)
    {
        double *rgb;
        rgb = ctf->GetColor(static_cast<double>(i)/tableSize);
        lut->SetTableValue(i, rgb[0], rgb[1], rgb[2]);
    }
    lut->SetRampToLinear();
    lut->Build();

    return lut;
}

I hope this helps,

Paulo

Paulo, Thank you for suggestion , But maybe it is not the problem, because I have tried the commentted codes replace the SetArray():
// for(int i=0;i<8;i++)
// da->InsertNextTuple1(temperature[i]); //Method 2: using InsertNextTuple() add temperature 1 by 1 is effective.

it works well,the result color is mapping successfully, so I think the problem is logically I input temperature array at once using SetArray(), actually it is not completed, I miss some key commands,but I don’t know which is missed, There are few detailed VTk documents online and it is difficult to find relevant examplest。

Ok… I just do like you: I set the values array at once, but I use unstructuredGrid->GetCellData()->SetScalars( values ); instead. I never used SetArray(). You can take a look at how I use it to assign values to the different VTK data structures here (search for SetScalars): https://github.com/PauloCarvalhoRJ/gammaray/blob/master/viewer3d/view3dbuilders.cpp .

I hope this cast light onto your problem.

regards,

Paulo

Hi, Paulo Carvalho,Thank you for your patient reply,however I already used the setscalars(), please see the following code snip:
ug->GetPointData()->SetScalars(da);
qDebug()<GetPointData()->GetArrayName(0);
ug->GetPointData()->SetActiveScalars(“temp”);

because SetScalars()'s parameter is vtkDoubleArray, before you use SetScalars(), you have to fill the vtkDoubleArray, one method is insert 1 by 1, the other is fill all value at once using SetArray(),The former is more robust and work well, but I think the latter is more efficiency, now the problem is I can not make it work good?

In your example , you use the former method , not use SetArray() method.
image

anyway, thank you all the same!

Well, SetScalars() works just fine for me. No 1 by 1 here. I don’t use SetArray() in any of my numerous VTK pipelines. If you want to stick to SetArray() then I can’t help you, sorry. Good luck.

Ah… I see what you need. But, anyway, I don’t have any code ready by now using SetArray(). Sorry.

In such cases, the easiest is to step through the code using a debugger - stepping into VTK methods, too. It makes it obvious what happens, why, and what needs to be changed in your code or fixed/documented better in VTK.