# ExportPolyDataScene

VTKExamples/Cxx/IO/ExportPolyDataScene

Danger

This example is a work in progress.

The example exports the vtkPolyData used by vtkActor's. The example stores the vtkMapper, vtkCamera, vtkActor and vtkProperty parameters as vtkFieldData in the vtkActor's vtkPolyData.

### Code

ExportPolyDataScene.cxx

    #include <vtkSmartPointer.h>
    #include <vtkMultiBlockDataSet.h>
    #include <vtkActorCollection.h>
    #include <vtkXMLMultiBlockDataWriter.h>
    #include <vtkActorCollection.h>
    #include <vtkPolyData.h>

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

    #include <vtkFieldData.h>
    #include <vtkDoubleArray.h>
    #include <vtkStringArray.h>
    #include <vtkIntArray.h>
    #include <vtkIdTypeArray.h>
    #include <vtkLookupTable.h>
    #include <vtkScalarsToColors.h>
    #include <vtkLinearTransform.h>
    #include <vtkTransform.h>

    #include <vtksys/SystemTools.hxx>
    #include <vtkNamedColors.h>

    #include <vtkBYUReader.h>
    #include <vtkOBJReader.h>
    #include <vtkPLYReader.h>
    #include <vtkPolyDataReader.h>
    #include <vtkSTLReader.h>
    #include <vtkXMLPolyDataReader.h>
    #include <vtkSphereSource.h>

    namespace
    {
    vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName);
    void ExportMultiBlockScene(vtkRenderer *renderer, std::string fileName, bool binary = false);
    void SaveCameraAsFieldData(std::string, vtkCamera *, vtkPolyData *);
    void SavePropertyAsFieldData(std::string, vtkProperty *, vtkPolyData *);
    void SaveMapperAsFieldData(std::string, vtkPolyDataMapper *, vtkPolyData *);
    void SaveActorAsFieldData(std::string, vtkActor *, vtkPolyData *);
    void SaveLookupTableAsFieldData(std::string, vtkScalarsToColors *, vtkPolyData *);
    }

    int main (int argc, char *argv[])
    {
      vtkSmartPointer<vtkPolyData> polyData =
        ReadPolyData(argc > 1 ? argv[1] : "");

      // Visualize
      vtkSmartPointer<vtkNamedColors> colors =
        vtkSmartPointer<vtkNamedColors>::New();

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

      double bounds[6];
      polyData->GetBounds(bounds);
      double delta[3];
      delta[0] = bounds[1] - bounds[0];
      delta[1] = bounds[3] - bounds[2];
      delta[2] = bounds[5] - bounds[4];
      for (int c = 0; c < 4; ++c)
      {
        for (int b = 0; b < 4; ++b)
        {
          for (int a = 0; a < 4; ++a)
          {
            vtkSmartPointer<vtkPolyDataMapper> mapper =
              vtkSmartPointer<vtkPolyDataMapper>::New();
            mapper->SetInputData(polyData);

            vtkSmartPointer<vtkProperty> backProperty =
              vtkSmartPointer<vtkProperty>::New();
            backProperty->SetColor(colors->GetColor3d("peacock").GetData());

            vtkSmartPointer<vtkActor> actor =
              vtkSmartPointer<vtkActor>::New();
            actor->SetMapper(mapper);
            actor->SetBackfaceProperty(backProperty);
            if (b == 1)
            {
            actor->GetProperty()->
              SetDiffuseColor(colors->GetColor3d("Orchid").GetData());
            }
            else if (b == 2)
            {
            actor->GetProperty()->
              SetDiffuseColor(colors->GetColor3d("Salmon").GetData());
            }
            else if (b == 3)
            {
            actor->GetProperty()->
              SetDiffuseColor(colors->GetColor3d("SandyBrown").GetData());
            }
            else
            {
              actor->GetProperty()->
                SetDiffuseColor(colors->GetColor3d("Crimson").GetData());
            }
            actor->GetProperty()->SetSpecular(.5);
            actor->GetProperty()->SetDiffuse(.5);
            actor->GetProperty()->SetSpecularPower(a * b * c);
            if ((a % 3) == 0)
            {
              actor->GetProperty()->EdgeVisibilityOn();
              actor->GetProperty()->SetEdgeColor(colors->GetColor3d("SlateGray").GetData());
              actor->GetProperty()->SetLineWidth(1.0);
            }
            else
            {
              actor->GetProperty()->EdgeVisibilityOff();
            }
            if ((a % 4) == 0)
            {
              actor->GetProperty()->FrontfaceCullingOn();
            }
            if ((a % 3) == 0 && (c & 3) == 0)
            {
              actor->GetProperty()->SetRepresentationToWireframe();
            }
            else
            {
              actor->GetProperty()->SetRepresentationToSurface();
            }
            if (c == 3)
            {
              vtkSmartPointer<vtkTransform> rotateTransform =
                vtkSmartPointer<vtkTransform>::New();
              rotateTransform->RotateZ(30.0);
              actor->GetProperty()->SetInterpolationToGouraud();
              actor->SetUserTransform(rotateTransform);
            }
            else
            {
              actor->GetProperty()->SetInterpolationToFlat();
            }
            actor->AddPosition(1.5 * a * delta[0],
                               1.5 * b * delta[1],
                               1.5 * c * delta[2]);
            actor->SetScale((a + 1) * .5, (b + 1) * .5, (c + 1) * .5);

            renderer->AddActor(actor);
          }
        }
      }
      renderer->GetActiveCamera()->Azimuth(30);
      renderer->GetActiveCamera()->Elevation(30);
      renderer->GetActiveCamera()->Yaw(10);
      renderer->ResetCamera();
      renderer->SetBackground(colors->GetColor3d("Silver").GetData());
      renderWindow->SetSize(640, 480);
      renderWindow->Render();
      renderWindowInteractor->Start();

      std::string prefix;
      if (argc < 2)
      {
        prefix = "Sphere";
      }
      else
      {
        prefix = "Export" +
          vtksys::SystemTools::GetFilenameWithoutExtension(argv[1]) +
          ".vtp";
      }
      std::cout << "Scene is exported to " << vtksys::SystemTools::GetCurrentWorkingDirectory() + "/" + prefix << std::endl;
      ExportMultiBlockScene (renderer.GetPointer(), prefix, false);

      return EXIT_SUCCESS;
    }

    namespace
    {
    void ExportMultiBlockScene (vtkRenderer *renderer,
                                std::string fileName,
                                bool binary)
    {
      // Iterate over all actors in the renderer
      vtkSmartPointer<vtkActorCollection> actors =
        vtkSmartPointer<vtkActorCollection>::New();
      actors = renderer->GetActors();
      std::cout << "There are " << actors->GetNumberOfItems() << " actors" << std::endl;
      actors->InitTraversal();
      // Initialize dataset to write
      vtkSmartPointer<vtkMultiBlockDataSet> multiBlockDataset =
        vtkSmartPointer<vtkMultiBlockDataSet>::New();
      multiBlockDataset->SetNumberOfBlocks(actors->GetNumberOfItems());

      for (vtkIdType a = 0; a < actors->GetNumberOfItems(); ++a)
      {
        vtkActor * actor = actors->GetNextActor();

        // Deep copy the polydata because it may be shared with other actors
        vtkSmartPointer<vtkPolyData> pd =
          vtkSmartPointer<vtkPolyData>::New();
        pd->DeepCopy(vtkPolyData::SafeDownCast(actor->GetMapper()->GetInput()));

        // Set metadata for block
        multiBlockDataset->SetBlock(a, pd);

        // Save Camera
        SaveCameraAsFieldData("Camera",
                              renderer->GetActiveCamera(),
                              pd);

        // Save Property
        SavePropertyAsFieldData("Property",
                                actor->GetProperty(),
                                pd);
        SavePropertyAsFieldData("BackfaceProperty",
                                actor->GetBackfaceProperty(),
                                pd);
        // Save Mapper
        SaveMapperAsFieldData("PolyDataMapper",
                              vtkPolyDataMapper::SafeDownCast(actor->GetMapper()),
                              pd);
        // Save Actor
        SaveActorAsFieldData("Actor",
                              actor,
                              pd);
      }

      // Write multiblock dataset to disk
      vtkSmartPointer<vtkXMLMultiBlockDataWriter> writer =
        vtkSmartPointer<vtkXMLMultiBlockDataWriter>::New();
      if (binary)
      {
        writer->SetDataModeToBinary();
        writer->SetCompressorTypeToZLib();
      }
      else
      {
        writer->SetDataModeToAscii();
      }
      writer->SetInputData(multiBlockDataset);
      writer->SetFileName(fileName.c_str());
      writer->Update();
      return;
    }

    #define SAVE_SCALAR(arrayPrefix,instance,pd,name,T)      \
      vtkSmartPointer<T> name = \
        vtkSmartPointer<T>::New(); \
      name->SetNumberOfComponents(1); \
      name->SetNumberOfTuples(1); \
      name->SetValue(0, instance->Get##name()); \
      name->SetName(std::string(arrayPrefix + ":" + "#name").c_str()); \
      pd->GetFieldData()->AddArray(name)

    #define SAVE_VECTOR(arrayPrefix,instance,pd,name,T,components,tuples) \
      vtkSmartPointer<T> name = \
        vtkSmartPointer<T>::New(); \
      name->SetNumberOfComponents(components); \
      name->SetNumberOfTuples(tuples); \
      name->SetTuple(0, instance->Get##name()); \
      name->SetName(std::string(arrayPrefix + ":" + "#name").c_str()); \
      pd->GetFieldData()->AddArray(name)

    void SaveCameraAsFieldData(std::string arrayPrefix,
                               vtkCamera *camera,
                               vtkPolyData *pd)
    {
      SAVE_VECTOR(arrayPrefix, camera, pd, ViewUp, vtkDoubleArray, 3, 1);
      SAVE_VECTOR(arrayPrefix, camera, pd, Position, vtkDoubleArray, 3, 1);
      SAVE_VECTOR(arrayPrefix, camera, pd, FocalPoint, vtkDoubleArray, 3, 1);
      SAVE_VECTOR(arrayPrefix, camera, pd, ClippingRange, vtkDoubleArray, 2, 1);
      SAVE_SCALAR(arrayPrefix, camera, pd, ViewAngle, vtkDoubleArray);
    }
    void SavePropertyAsFieldData(std::string arrayPrefix,
                                 vtkProperty * property,
                                 vtkPolyData *pd)
    {
      if (property)
      {
        SAVE_SCALAR(arrayPrefix, property, pd, Ambient, vtkDoubleArray);
        SAVE_VECTOR(arrayPrefix, property, pd, AmbientColor, vtkDoubleArray,3, 1);
        SAVE_SCALAR(arrayPrefix, property, pd, Diffuse, vtkDoubleArray);
        SAVE_VECTOR(arrayPrefix, property, pd, DiffuseColor, vtkDoubleArray,3, 1);
        SAVE_SCALAR(arrayPrefix, property, pd, Specular, vtkDoubleArray);
        SAVE_VECTOR(arrayPrefix, property, pd, SpecularColor, vtkDoubleArray,3, 1);
        SAVE_SCALAR(arrayPrefix, property, pd, SpecularPower, vtkDoubleArray);
        SAVE_VECTOR(arrayPrefix, property, pd, EdgeColor, vtkDoubleArray,3, 1);
        SAVE_SCALAR(arrayPrefix, property, pd, EdgeVisibility, vtkIntArray);
        SAVE_VECTOR(arrayPrefix, property, pd, VertexColor, vtkDoubleArray,3, 1);
        SAVE_SCALAR(arrayPrefix, property, pd, Interpolation, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, Opacity, vtkDoubleArray);
        SAVE_SCALAR(arrayPrefix, property, pd, Representation, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, BackfaceCulling, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, FrontfaceCulling, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, PointSize, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, LineWidth, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, LineStipplePattern, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, LineStippleRepeatFactor, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, Lighting, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, RenderPointsAsSpheres, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, property, pd, Shading, vtkIntArray);

        if (property->GetMaterialName())
        {
          SAVE_SCALAR(arrayPrefix, property, pd, MaterialName, vtkStringArray);
        }
      }
    }
    void SaveMapperAsFieldData(std::string arrayPrefix,
                               vtkPolyDataMapper *mapper,
                               vtkPolyData *pd)
    {
      if (mapper->GetLookupTable())
      {
        std::string prefix = arrayPrefix + "LookupTable:";
        vtkScalarsToColors *scalarsToColors = mapper->GetLookupTable();

        SAVE_SCALAR(prefix, scalarsToColors, pd, Alpha, vtkDoubleArray);
        SAVE_SCALAR(prefix, scalarsToColors, pd, VectorMode, vtkIntArray);
        SAVE_SCALAR(prefix, scalarsToColors, pd, VectorComponent, vtkIntArray);
        SAVE_SCALAR(prefix, scalarsToColors, pd, VectorSize, vtkIntArray);
        SAVE_SCALAR(prefix, scalarsToColors, pd, IndexedLookup, vtkIntArray);

        vtkLookupTable *lut = vtkLookupTable::SafeDownCast(mapper->GetLookupTable());
        SAVE_VECTOR(prefix, lut, pd, TableRange, vtkDoubleArray, 2, 1);
        SAVE_SCALAR(prefix, lut, pd, Scale, vtkIntArray);
        SAVE_VECTOR(prefix, lut, pd, HueRange, vtkDoubleArray, 2, 1);
        SAVE_VECTOR(prefix, lut, pd, SaturationRange, vtkDoubleArray, 2, 1);
        SAVE_VECTOR(prefix, lut, pd, ValueRange, vtkDoubleArray, 2, 1);
        SAVE_VECTOR(prefix, lut, pd, AlphaRange, vtkDoubleArray, 2, 1);
        SAVE_VECTOR(prefix, lut, pd, NanColor, vtkDoubleArray, 4, 1);
        SAVE_VECTOR(prefix, lut, pd, BelowRangeColor, vtkDoubleArray, 4, 1);
        SAVE_SCALAR(prefix, lut, pd, UseBelowRangeColor, vtkIntArray);
        SAVE_VECTOR(prefix, lut, pd, AboveRangeColor, vtkDoubleArray, 4, 1);
        SAVE_SCALAR(prefix, lut, pd, UseAboveRangeColor, vtkIntArray);
        SAVE_SCALAR(prefix, lut, pd, NumberOfTableValues, vtkIntArray);
        SAVE_SCALAR(prefix, lut, pd, Ramp, vtkIntArray);
        SAVE_SCALAR(prefix, lut, pd, NumberOfColors, vtkIntArray);

        vtkSmartPointer<vtkUnsignedCharArray> Table =
          vtkSmartPointer<vtkUnsignedCharArray>::New();
    //    Table->SetNumberOfComponents(4);
    //    Table->SetNumberOfTuples(vtkLookupTable::SafeDownCast(lut)->GetTable()->GetNumberOfTuples());
        Table->DeepCopy(vtkLookupTable::SafeDownCast(lut)->GetTable());
        Table->SetName(std::string(arrayPrefix + ":LookupTable:" + "Table").c_str());
        pd->GetFieldData()->AddArray(Table);

        SAVE_SCALAR(arrayPrefix, mapper, pd, ScalarVisibility, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, mapper, pd, Static, vtkIntArray);
        SAVE_VECTOR(arrayPrefix, mapper, pd, ScalarRange, vtkDoubleArray, 2, 1);
        SAVE_SCALAR(arrayPrefix, mapper, pd, UseLookupTableScalarRange, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, mapper, pd, ColorMode, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, mapper, pd, InterpolateScalarsBeforeMapping, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, mapper, pd, ScalarMode, vtkIntArray);
        SAVE_SCALAR(arrayPrefix, mapper, pd, ResolveCoincidentTopology, vtkIntArray);
      }
    }

    void SaveActorAsFieldData(std::string arrayPrefix,
                              vtkActor *actor,
                              vtkPolyData *pd)
    {
      SAVE_SCALAR(arrayPrefix, actor, pd, Dragable, vtkIntArray);
      SAVE_SCALAR(arrayPrefix, actor, pd, Pickable, vtkIntArray);
      SAVE_SCALAR(arrayPrefix, actor, pd, Visibility, vtkIntArray);
      SAVE_VECTOR(arrayPrefix, actor, pd, Orientation, vtkDoubleArray, 3, 1);
      SAVE_VECTOR(arrayPrefix, actor, pd, Origin, vtkDoubleArray, 3, 1);
      SAVE_VECTOR(arrayPrefix, actor, pd, Scale, vtkDoubleArray, 3, 1);
      SAVE_SCALAR(arrayPrefix, actor, pd, ForceOpaque, vtkIntArray);
      SAVE_SCALAR(arrayPrefix, actor, pd, ForceTranslucent, vtkIntArray);

      if (actor->GetUserTransform())
      {
        vtkLinearTransform *userTransform = actor->GetUserTransform();
        userTransform->Print(std::cout);
      }

    #if 0
    UserTransform
    UserMatrix
    Texture
    #endif
    }
    vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName)
    {
      vtkSmartPointer<vtkPolyData> polyData;
      std::string extension = vtksys::SystemTools::GetFilenameExtension(std::string(fileName));
      if (extension == ".ply")
      {
        vtkSmartPointer<vtkPLYReader> reader =
          vtkSmartPointer<vtkPLYReader>::New();
        reader->SetFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else if (extension == ".vtp")
      {
        vtkSmartPointer<vtkXMLPolyDataReader> reader =
          vtkSmartPointer<vtkXMLPolyDataReader>::New();
        reader->SetFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else if (extension == ".obj")
      {
        vtkSmartPointer<vtkOBJReader> reader =
          vtkSmartPointer<vtkOBJReader>::New();
        reader->SetFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else if (extension == ".stl")
      {
        vtkSmartPointer<vtkSTLReader> reader =
          vtkSmartPointer<vtkSTLReader>::New();
        reader->SetFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else if (extension == ".vtk")
      {
        vtkSmartPointer<vtkPolyDataReader> reader =
          vtkSmartPointer<vtkPolyDataReader>::New();
        reader->SetFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else if (extension == ".g")
      {
        vtkSmartPointer<vtkBYUReader> reader =
          vtkSmartPointer<vtkBYUReader>::New();
        reader->SetGeometryFileName (fileName);
        reader->Update();
        polyData = reader->GetOutput();
      }
      else
      {
        vtkSmartPointer<vtkSphereSource> source =
          vtkSmartPointer<vtkSphereSource>::New();
        source->Update();
        polyData = source->GetOutput();
      }
      return polyData;
    }
    }

### CMakeLists.txt

    cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

    project(ExportPolyDataScene)

    find_package(VTK COMPONENTS
      vtkCommonColor
      vtkCommonCore
      vtkCommonDataModel
      vtkCommonTransforms
      vtkFiltersSources
      vtkIOGeometry
      vtkIOLegacy
      vtkIOPLY
      vtkIOXML
      vtkInteractionStyle
      vtkRenderingCore
      vtkRenderingFreeType
      vtkRenderingOpenGL2 QUIET)
    if (NOT VTK_FOUND)
      message("Skipping ExportPolyDataScene: ${VTK_NOT_FOUND_MESSAGE}")
      return ()
    endif()
    message (STATUS "VTK_VERSION: ${VTK_VERSION}")
    if (VTK_VERSION VERSION_LESS "8.90.0")
      # old system
      include(${VTK_USE_FILE})
      add_executable(ExportPolyDataScene MACOSX_BUNDLE ExportPolyDataScene.cxx )
      target_link_libraries(ExportPolyDataScene PRIVATE ${VTK_LIBRARIES})
    else ()
      # include all components
      add_executable(ExportPolyDataScene MACOSX_BUNDLE ExportPolyDataScene.cxx )
      target_link_libraries(ExportPolyDataScene PRIVATE ${VTK_LIBRARIES})
      # vtk_module_autoinit is needed
      vtk_module_autoinit(
        TARGETS ExportPolyDataScene
        MODULES ${VTK_LIBRARIES}
        )
    endif ()

### Download and Build ExportPolyDataScene

Click here to download ExportPolyDataScene and its CMakeLists.txt file. Once the tarball ExportPolyDataScene.tar has been downloaded and extracted,

    cd ExportPolyDataScene/build

If VTK is installed:

    cmake ..

If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:

    cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

    make

and run it:

    ./ExportPolyDataScene

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.