CombineImportedActors
Repository source: CombineImportedActors
Other languages
See (Cxx)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
CombineImportedActors.py
#!/usr/bin/env python3
from dataclasses import dataclass
from pathlib import Path
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkUnsignedCharArray
from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkCommonTransforms import vtkTransform
from vtkmodules.vtkFiltersCore import vtkAppendPolyData
from vtkmodules.vtkFiltersGeneral import vtkTransformPolyDataFilter
from vtkmodules.vtkIOImport import (
vtk3DSImporter,
vtkGLTFImporter,
vtkOBJImporter,
vtkVRMLImporter,
)
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkLight,
vtkPolyDataMapper,
vtkRenderWindowInteractor,
vtkRenderWindow,
vtkRenderer
)
def get_program_parameters():
import argparse
description = 'Combining imported actors.'
epilogue = '''
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('in_fn', help='iflamingo.3ds.')
# Optional additional input file and folder for the OBJ reader.
parser.add_argument('-m', '--mtl_fn', default=None, help='Optional OBJ MTL file name e.g. iflamingo.obj')
parser.add_argument('-t', '--texture_dir', default=None, help='Optional OBJ texture folder.')
args = parser.parse_args()
return args.in_fn, args.mtl_fn, args.texture_dir
def main():
ifn, mtl_fn, texture_dir = get_program_parameters()
input_suffixes = ('.3ds', '.glb', '.gltf', '.obj', '.wrl')
output_suffixes = ('.glb', '.gltf', '.obj', '.wrl', '.x3d')
def sorted_suffixes(suffixes):
s = ', '.join(sorted(list(suffixes)))
return f'{s}'
# Check the files exist and have correct suffixes.
ifp = Path(ifn)
if not ifp.is_file():
print(f'Nonexistent source: {ifp}')
return
if not ifp.suffix.lower() in input_suffixes:
print(f'Available input file suffixes are: {sorted_suffixes(input_suffixes)}')
return
mtlp = None
if mtl_fn:
mtlp = Path(mtl_fn)
if not mtlp.is_file():
print(f'Nonexistent MTL path: {mtlp}')
return
if not mtlp.suffix.lower() == '.mtl':
print(f'Bad mtl file suffix: {mtlp}')
return
texd = None
if texture_dir:
texd = Path(texture_dir)
if not texd.is_dir():
print(f'Nonexistent directory: {texd}')
return
colors = vtkNamedColors()
ren = vtkRenderer(background=colors.GetColor3d('SlateGray'), background2=colors.GetColor3d('LightSkyBlue'),
gradient_background=True)
ren_win = vtkRenderWindow(size=(640, 480), window_name='CombineImportedActors')
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.render_window = ren_win
# Read the file(s).
import_ren = vtkRenderer()
import_ren_win = vtkRenderWindow()
import_ren_win.AddRenderer(import_ren)
importer = get_importer(ifp, mtlp, texd, import_ren_win)
if not importer:
print(f'No suitable reader found for {ifp}')
return
importer.active_renderer = import_ren
importer.Update()
actors = import_ren.actors
actors.InitTraversal()
actors_sz = actors.number_of_items
if actors_sz == 1:
print(f'There is {actors_sz} actors')
else:
print(f'There are {actors_sz} actors')
for a in range(0, actors_sz):
if ifp.suffix.lower() == '.obj':
# OBJImporter turns texture interpolation off.
actor = actors.next_actor
if actor.texture:
# print('Has texture')
# print(importer.GetOutputDescription(a))
actor.texture.interpolate = True
append = vtkAppendPolyData()
for a in range(0, actors_sz):
append_pd = vtkPolyData()
actor = actors.next_actor
actor.mapper.update()
if actor.user_matrix:
transform = vtkTransform(matrix=actor.user_matrix)
transform_pd = vtkTransformPolyDataFilter(transform=transform)
(actor.mapper >> transform_pd).update()
append_pd.DeepCopy(transform_pd)
else:
append_pd.DeepCopy(actor.mapper.input)
cell_data = vtkUnsignedCharArray(number_of_components=3, number_of_tuples=append_pd.number_of_cells)
for i in range(0, append_pd.number_of_cells):
# rgb = [0]*4
rgb = actor.property.GetDiffuseColor()
rgb = list(map(lambda x: int(x * 255.0), rgb))
cell_data.InsertTuple(i, rgb)
append_pd.cell_data.SetScalars(cell_data)
append.AddInputData(append_pd)
append.update()
mapper = vtkPolyDataMapper(scalar_mode=Mapper.ScalarMode.VTK_SCALAR_MODE_USE_CELL_DATA)
append >> mapper
actor = vtkActor(mapper=mapper)
actor.property.diffuse_color = colors.GetColor3d('Banana')
ren.AddActor(actor)
name = ifp.name
camera = ren.active_camera
if name == 'iflamingo.3ds':
camera.position = (0, -1, 0)
camera.focal_point = (0, 0, 0)
camera.view_up = (0, 0, 1)
camera.Azimuth(150)
camera.Elevation(30)
ren.ResetCamera()
if name == 'FlightHelmet.gltf':
head_light = vtkLight(switch=True)
head_light.SetLightTypeToHeadlight()
ren.AddLight(head_light)
if name == 'trumpet.obj':
camera.Azimuth(30)
camera.Elevation(30)
camera.Dolly(1.5)
ren.ResetCameraClippingRange()
ren_win.Render()
iren.Start()
def get_importer(ifp, mtlp, texd, ren_win):
importer = None
if ifp.suffix.lower() == '.wrl':
importer = vtkVRMLImporter(file_name=ifp, render_window=ren_win)
if ifp.suffix.lower() == '.3ds':
importer = vtk3DSImporter(file_name=ifp, render_window=ren_win, compute_normals=True)
if ifp.suffix.lower() in ('.gltf', 'glb'):
importer = vtkGLTFImporter(file_name=ifp, render_window=ren_win)
if ifp.suffix.lower() == '.obj':
importer = vtkOBJImporter(file_name=ifp, render_window=ren_win)
if mtlp:
importer.file_name_mtl = mtlp
if texd:
importer.texture_path = texd
return importer
@dataclass(frozen=True)
class Mapper:
@dataclass(frozen=True)
class ColorMode:
VTK_COLOR_MODE_DEFAULT: int = 0
VTK_COLOR_MODE_MAP_SCALARS: int = 1
VTK_COLOR_MODE_DIRECT_SCALARS: int = 2
@dataclass(frozen=True)
class ResolveCoincidentTopology:
VTK_RESOLVE_OFF: int = 0
VTK_RESOLVE_POLYGON_OFFSET: int = 1
VTK_RESOLVE_SHIFT_ZBUFFER: int = 2
@dataclass(frozen=True)
class ScalarMode:
VTK_SCALAR_MODE_DEFAULT: int = 0
VTK_SCALAR_MODE_USE_POINT_DATA: int = 1
VTK_SCALAR_MODE_USE_CELL_DATA: int = 2
VTK_SCALAR_MODE_USE_POINT_FIELD_DATA: int = 3
VTK_SCALAR_MODE_USE_CELL_FIELD_DATA: int = 4
VTK_SCALAR_MODE_USE_FIELD_DATA: int = 5
if __name__ == '__main__':
main()