how to write .xml .vtk or vtp with color?

I’m trying to save a polyData mesh with color.

I set the color like this:

		// Generate the colors for each point based on the color map
		vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
		colors->SetNumberOfComponents(3);

colorLookupTable->GetColor(val[i], dcolor);

colors->InsertNextTupleValue(color);

registeredMesh->GetPointData()->SetScalars(colors);

I know this is working because I can view the result and it looks colored.

I go to save the mesh like this:

			vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkSmartPointer<vtkXMLPolyDataWriter>::New();
			writer->SetFileName(filename.c_str());
			writer->SetInputData(mesh);
			writer->Update();
			writer->Write();

and it is not written correctly. When I don’t add color it writes the mesh fine but I need the color in my file.
Any thoughts or ideas on what to do?
Thanks,
~Shane

Can you share the outputed file ?

phase_2.xml (1.7 MB)

This is not a .vtp file.

yes, sorry I put the wrong file there initially.

Are mesh and registeredMesh the same var ?

We can try to guess from these code snippets - for example you have not set a name for the array, which makes the data set invalid - but we don’t know if you set the name somewhere just did not include that part in the post or you have actually did not set the name.

If you provide a minimal reproducible example then we would see what’s happening and give informed advice. There is also a high chance that as you are creating the example, you find the root cause of the problem by yourself.

Another good strategy is to check out VTK examples. From the hundreds of examples you can almost always find code snippets that do exactly what you need. Download the entire VTK source tree and the whole VTKExamples repository and search for SetScalars in all text. I’m sure you’ll find dozens of complete, working examples and tests.

1 Like

@lassoan, @mwestphal Here is an example, it is a modified version of the triangleColorPoints example.
However, as you suspected I found the issue; thanks for the advice

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkCellArray.h>
#include <vtkTriangle.h>
#include <vtkUnsignedCharArray.h>

#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

// For compatibility with new VTK generic data arrays
#ifdef vtkGenericDataArray_h
#define InsertNextTupleValue InsertNextTypedTuple
#endif
#include <vtkGLTFExporter.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkNamedColors.h>

int writeGLTF(std::string filename);

int main(int, char *[])
{
  // Setup points
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  points->InsertNextPoint(1.0, 0.0, 0.0);
  points->InsertNextPoint(0.0, 0.0, 0.0);
  points->InsertNextPoint(0.0, 1.0, 0.0);

  points->InsertNextPoint(1.0, 0.0, 0.0);
  points->InsertNextPoint(1.0, 1.0, 0.0);
  points->InsertNextPoint(0.0, 1.0, 0.0);
  
  // Define some colors
  unsigned char red[3] = {255, 0, 0};
  unsigned char green[3] = {0, 255, 0};
  unsigned char blue[3] = {0, 0, 255};

  unsigned char other[3] = { 255, 0, 255 };

  // Setup the colors array
  vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
  colors->SetNumberOfComponents(3);
  colors->SetName("Colors");

  // Add the three colors we have created to the array
  colors->InsertNextTupleValue(green); 
  colors->InsertNextTupleValue(blue);
  colors->InsertNextTupleValue(red);
  
  colors->InsertNextTupleValue(red);
  colors->InsertNextTupleValue(blue);
  colors->InsertNextTupleValue(green);
  
  // Create a triangle
  vtkSmartPointer<vtkCellArray> triangles =   vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkTriangle> triangle1 = vtkSmartPointer<vtkTriangle>::New();
  triangle1->GetPointIds()->SetId(0, 0);
  triangle1->GetPointIds()->SetId(1, 1);
  triangle1->GetPointIds()->SetId(2, 2);
  triangles->InsertNextCell(triangle1);

  vtkSmartPointer<vtkTriangle> triangle2 = vtkSmartPointer<vtkTriangle>::New();
  triangle2->GetPointIds()->SetId(0, 3);
  triangle2->GetPointIds()->SetId(1, 4);
  triangle2->GetPointIds()->SetId(2, 5);
  triangles->InsertNextCell(triangle2);

  // Create a polydata object and add everything to it
  vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
  polydata->SetPoints(points);
  polydata->SetPolys(triangles);
  polydata->GetPointData()->SetScalars(colors);
  
  std::string filename = "outputFile.xml";
  vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkSmartPointer<vtkXMLPolyDataWriter>::New();
  writer->SetFileName(filename.c_str());
  writer->SetInputData(polydata);
  writer->Update();
  writer->Write();

  writeGLTF(filename);

  // Visualize
  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(polydata);

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

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);

  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}


int writeGLTF(std::string filename) {

    vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();
    vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    auto renderer = vtkSmartPointer<vtkRenderer>::New();
    auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();

    std::string inputFileName = filename; //phase_1.xml";

        // Read all the data from the file
        reader->SetFileName(inputFileName.c_str());
        reader->Update();
        mapper->SetInputConnection(reader->GetOutputPort());
        actor->SetMapper(mapper);

        renderer->AddActor(actor);
        renderer->SetBackground(colors->GetColor3d("Teal").GetData());
        renderer->ResetCamera();
        renderWindow->AddRenderer(renderer);
        renderWindow->SetSize(600, 600);
        renderWindow->Render();
        renderWindow->SetWindowName("ReadPolyData");

        //**Don't Delete use this if ever .obj is needed.
        //auto exporter =  vtkSmartPointer<vtkOBJExporter>::New();
        //std::stringstream comment;
        //comment << "Converted by ImportExport from " << FileName;
        //exporter->SetOBJFileComment(comment.str().c_str());
        //exporter->SetMTLFileComment(comment.str().c_str());
        //exporter->SetActiveRenderer(renderer);
        //exporter->SetRenderWindow(renderWindow);
        //exporter->SetFilePrefix("0_");
        //exporter->Update();
        //exporter->Write();

        std::string exportFileName;
        int check;

        exportFileName = std::string("outputGLTFFile") + "." + "gltf";
        auto exporter = vtkSmartPointer<vtkGLTFExporter>::New();
        exporter->SetFileName(exportFileName.c_str());
        exporter->SetActiveRenderer(renderer);
        exporter->SetRenderWindow(renderWindow);
        std::cout << "Writing " << exportFileName << std::endl;
        exporter->Update();
        exporter->Write();


    return EXIT_SUCCESS;
}

Thanks for the update. What was the issue in your original code?

I was not referencing the mesh correctly face-palm

1 Like

Hi All,

I am interested in writing vtkActors to a file. I found this post to be related. Is it possible to write vtkActors to a file?

I am interested in changing colors and visual styles (wireframe, surface, etc.) before I write them. I apply such effect to vtkActors.

You can use one of VTK exporter classes.

Note that you will have a much higher chance that your question will be answered (and faster) if you create a new topic instead of adding extra questions to an old, somewhat related topic. Having shorter, more focused topics is also better for everyone who reads discussions. You can of course link add links to relevant earlier discussions in your topic if you think that those are useful.