diff --git a/processing/post/vtk_addPointcloudData.py b/processing/post/vtk_addPointcloudData.py index 95b91d8ee..602e69307 100755 --- a/processing/post/vtk_addPointcloudData.py +++ b/processing/post/vtk_addPointcloudData.py @@ -1,8 +1,9 @@ #!/usr/bin/env python # -*- coding: UTF-8 no BOM -*- -import os,sys,vtk +import os,vtk import damask +from collections import defaultdict from optparse import OptionParser scriptName = os.path.splitext(os.path.basename(__file__))[0] @@ -17,125 +18,163 @@ Add scalar and RGB tuples from ASCIItable to existing VTK point cloud (.vtp). """, version = scriptID) -parser.add_option('-v', '--vtk', dest='vtk', \ +parser.add_option( '--vtk', + dest = 'vtk', + type = 'string', metavar = 'string', help = 'VTK file name') +parser.add_option( '--inplace', + dest = 'inplace', + action = 'store_true', + help = 'modify VTK file in-place') +parser.add_option('-r', '--render', + dest = 'render', + action = 'store_true', + help = 'open output in VTK render window') parser.add_option('-s', '--scalar', dest='scalar', action='extend', \ help = 'scalar values') +parser.add_option('-v', '--vector', + dest = 'vector', + action = 'extend', metavar = '', + help = 'vector value label(s)') parser.add_option('-c', '--color', dest='color', action='extend', \ help = 'RGB color tuples') -parser.set_defaults(scalar = []) -parser.set_defaults(color = []) +parser.set_defaults(scalar = [], + vector = [], + color = [], + inplace = False, + render = False, +) (options, filenames) = parser.parse_args() -datainfo = { # list of requested labels per datatype - 'scalar': {'len':1, - 'label':[]}, - 'color': {'len':3, - 'label':[]}, - } - -if not os.path.exists(options.vtk): - parser.error('VTK file does not exist'); sys.exit() +if not options.vtk: parser.error('No VTK file specified.') +if not os.path.exists(options.vtk): parser.error('VTK file does not exist.') reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(options.vtk) reader.Update() -Npoints = reader.GetNumberOfPoints() -Ncells = reader.GetNumberOfCells() +Npoints = reader.GetNumberOfPoints() +Ncells = reader.GetNumberOfCells() Nvertices = reader.GetNumberOfVerts() -Polydata = reader.GetOutput() +Polydata = reader.GetOutput() if Npoints != Ncells or Npoints != Nvertices: - parser.error('Number of points, cells, and vertices in VTK differ from each other'); sys.exit() -if options.scalar is not None: datainfo['scalar']['label'] += options.scalar -if options.color is not None: datainfo['color']['label'] += options.color + parser.error('Number of points, cells, and vertices in VTK differ from each other.') -# ------------------------------------------ setup file handles --------------------------------------- +damask.util.croak('{}: {} points, {} vertices, and {} cells...'.format(options.vtk,Npoints,Nvertices,Ncells)) -files = [] -if filenames == []: - files.append({'name':'STDIN', 'input':sys.stdin, 'output':sys.stdout, 'croak':sys.stderr}) -else: - for name in filenames: - if os.path.exists(name): - files.append({'name':name, 'input':open(name), 'output':sys.stderr, 'croak':sys.stderr}) +# --- loop over input files ------------------------------------------------------------------------- -#--- loop over input files ------------------------------------------------------------------------ -for file in files: - if file['name'] != 'STDIN': file['croak'].write('\033[1m'+scriptName+'\033[0m: '+file['name']+'\n') - else: file['croak'].write('\033[1m'+scriptName+'\033[0m\n') +if filenames == []: filenames = [None] - table = damask.ASCIItable(file['input'],file['output'],False) # make unbuffered ASCII_table - table.head_read() # read ASCII header info +for name in filenames: + try: table = damask.ASCIItable(name = name, + buffered = False, + readonly = True) + except: continue + damask.util.report(scriptName, name) -# --------------- figure out columns to process - active = {} - column = {} +# --- interpret header ---------------------------------------------------------------------------- - array = {} + table.head_read() + + remarks = [] + errors = [] + VTKarray = {} + active = defaultdict(list) - for datatype,info in datainfo.items(): - for label in info['label']: - foundIt = False - for key in ['1_'+label,label]: - if key in table.labels: - foundIt = True - if datatype not in active: active[datatype] = [] - if datatype not in column: column[datatype] = {} - if datatype not in array: array[datatype] = {} - active[datatype].append(label) - column[datatype][label] = table.labels.index(key) # remember columns of requested data - if datatype == 'scalar': - array[datatype][label] = vtk.vtkDoubleArray() - array[datatype][label].SetNumberOfComponents(1) - array[datatype][label].SetName(label) - elif datatype == 'color': - array[datatype][label] = vtk.vtkUnsignedCharArray() - array[datatype][label].SetNumberOfComponents(3) - array[datatype][label].SetName(label) - if not foundIt: - file['croak'].write('column %s not found...\n'%label) - + for datatype,dimension,label in [['scalar',1,options.scalar], + ['vector',3,options.vector], + ['color',3,options.color], + ]: + for i,dim in enumerate(table.label_dimension(label)): + me = label[i] + if dim == -1: remarks.append('{} "{}" not found...'.format(datatype,me)) + elif dim > dimension: remarks.append('"{}" not of dimension {}...'.format(me,dimension)) + else: + remarks.append('adding {} "{}"...'.format(datatype,me)) + active[datatype].append(me) + + if datatype in ['scalar','vector']: VTKarray[me] = vtk.vtkDoubleArray() + elif datatype == 'color': VTKarray[me] = vtk.vtkUnsignedCharArray() + + VTKarray[me].SetNumberOfComponents(dimension) + VTKarray[me].SetName(label[i]) + + if remarks != []: damask.util.croak(remarks) + if errors != []: + damask.util.croak(errors) + table.close(dismiss = True) + continue + # ------------------------------------------ process data --------------------------------------- - while table.data_read(): # read next data line of ASCII table + while table.data_read(): # read next data line of ASCII table - for datatype,labels in active.items(): # loop over scalar,color - for label in labels: # loop over all requested items - theData = table.data[column[datatype][label]:\ - column[datatype][label]+datainfo[datatype]['len']] # read strings - if datatype == 'color': - theData = map(lambda x: int(255.*float(x)),theData) - array[datatype][label].InsertNextTuple3(theData[0],theData[1],theData[2],) - elif datatype == 'scalar': - array[datatype][label].InsertNextValue(float(theData[0])) + for datatype,labels in active.items(): # loop over scalar,color + for me in labels: # loop over all requested items + theData = [table.data[i] for i in table.label_indexrange(me)] # read strings + if datatype == 'color': VTKarray[me].InsertNextTuple3(*map(lambda x: int(255.*float(x)),theData)) + elif datatype == 'vector': VTKarray[me].InsertNextTuple3(*map(float,theData)) + elif datatype == 'scalar': VTKarray[me].InsertNextValue(float(theData[0])) table.input_close() # close input ASCII table # ------------------------------------------ add data --------------------------------------- - for datatype,labels in active.items(): # loop over scalar,color + damask.util.croak('adding now...') + for datatype,labels in active.items(): # loop over scalar,color + damask.util.croak('type {}'.format(datatype)) + if datatype == 'color': - Polydata.GetPointData().SetScalars(array[datatype][labels[0]]) - Polydata.GetCellData().SetScalars(array[datatype][labels[0]]) - for label in labels: # loop over all requested items - Polydata.GetPointData().AddArray(array[datatype][label]) - Polydata.GetCellData().AddArray(array[datatype][label]) + Polydata.GetPointData().SetScalars(VTKarray[active['color'][0]]) + Polydata.GetCellData().SetScalars(VTKarray[active['color'][0]]) + for me in labels: # loop over all requested items + damask.util.croak('label {}'.format(me)) + Polydata.GetPointData().AddArray(VTKarray[me]) + Polydata.GetCellData().AddArray(VTKarray[me]) + + damask.util.croak('...done.') Polydata.Modified() - if vtk.VTK_MAJOR_VERSION <= 5: - Polydata.Update() + if vtk.VTK_MAJOR_VERSION <= 5: Polydata.Update() # ------------------------------------------ output result --------------------------------------- -writer = vtk.vtkXMLPolyDataWriter() -writer.SetDataModeToBinary() -writer.SetCompressorTypeToZLib() -writer.SetFileName(os.path.splitext(options.vtk)[0]+'_added.vtp') -if vtk.VTK_MAJOR_VERSION <= 5: - writer.SetInput(Polydata) -else: - writer.SetInputData(Polydata) -writer.Write() + writer = vtk.vtkXMLPolyDataWriter() + writer.SetDataModeToBinary() + writer.SetCompressorTypeToZLib() + writer.SetFileName(os.path.splitext(options.vtk)[0]+('.vtp' if options.inplace else '_added.vtp')) + if vtk.VTK_MAJOR_VERSION <= 5: writer.SetInput(Polydata) + else: writer.SetInputData(Polydata) + writer.Write() + +# ------------------------------------------ render result --------------------------------------- + +if options.render: + mapper = vtk.vtkDataSetMapper() + mapper.SetInputData(Polydata) + actor = vtk.vtkActor() + actor.SetMapper(mapper) + +# Create the graphics structure. The renderer renders into the +# render window. The render window interactor captures mouse events +# and will perform appropriate camera or actor manipulation +# depending on the nature of the events. + + ren = vtk.vtkRenderer() + + renWin = vtk.vtkRenderWindow() + renWin.AddRenderer(ren) + + ren.AddActor(actor) + ren.SetBackground(1, 1, 1) + renWin.SetSize(200, 200) + + iren = vtk.vtkRenderWindowInteractor() + iren.SetRenderWindow(renWin) + + iren.Initialize() + renWin.Render() + iren.Start()