python-3.xvtkvtk.js

vtkOBJReader import OBJ as individual vtkPolyData objects


My intention is to get the vtkPolyData(ideally colored/textured via the vtk OBJ import) to pass to k3d viewer using;

k3d.vtk_poly_data(<vtkPolyData>)

vtkGLTFReader gives a vtkMultiBlock that which can be easily iterated over to get access to multiple vtkPolyData objects as shown here?

vtkOBJReader on the other hand returns a vtkPolyData object that encompasses all the objects in one obj. So I have lost my reference to individual objects and their guids/ids;

reader = vtk.vtkOBJReader() 
reader.SetFileName('Sample.obj')
reader.Update() 
vtkPolyData = reader.GetOutput() #Problem! all .OBJ elements in one vtkPolyData instance
  1. Is it possible to get access to the individual vtkPolyData objects from the .OBJ without splitting the .OBJ in multiple files?
  2. Is a vtkMultiBlock version of the data accessible from the vtk python module? Or is this only possible via js version of vtk as described here

Since the vtkImporter class supersedes vtkReader class and already correctly displays objects with material (.mtl) I suspect there is a way to get access the geometry through the Render_Window object, but I could not manage this.

SOLUTION;

importer = vtk.vtkOBJImporter()
importer.SetFileName('Sample.obj')
importer.SetFileNameMTL('Sample.mtl')

#preview with material using the importer
importer.Read()
importer.InitializeObjectBase()
importer.GetRenderer()
vtkRenderWindowInteractor = vtk.vtkRenderWindowInteractor()
Render_Window = importer.GetRenderWindow()
vtkRenderWindowInteractor.SetRenderWindow(Render_Window)

actors = Renderer.GetActors()
actors.InitTraversal() #Unpacks OBJ !

#Iterate over actors to get PolyData!
pds = []
for a in range(actors.GetNumberOfItems()):
    actor = actors.GetNextActor()

    # OBJImporter turns texture interpolation off
    if actor.GetTexture():
        actor.GetTexture().InterpolateOn()

    pd = actor.GetMapper().GetInput()
    
    #mapper = vtk.vtkPolyDataMapper(actor.GetMapper()) #Throws TypeError: Method requires a string argument!
    mapper = actor.GetMapper() #use this in python
    mapper.SetInputData(pd)
    pds.append(pd)

vtkRenderWindowInteractor.Start() 

Solution

  • You are looking in the right direction wiht the importer and the renderer. The renderer object contains actors, each one has a mapper that contains a polydata as input.

    See this cxx example (python API is the same, except you can directly iterate through renderer.GetActors()): https://lorensen.github.io/VTKExamples/site/Cxx/IO/OBJImporter/