def setPointHeights( self, ptheights ): try: if self.topo == PlotType.Planar: self.np_points_data[2::3] = ptheights vtk_points_data = numpy_support.numpy_to_vtk( self.np_points_data ) vtk_points_data.SetNumberOfComponents( 3 ) vtk_points_data.SetNumberOfTuples( len( self.np_points_data ) / 3 ) self.vtk_planar_points.SetData( vtk_points_data ) self.polydata.SetPoints( self.vtk_planar_points ) self.vtk_planar_points.Modified() elif self.topo == PlotType.Spherical: self.np_sp_grid_data[0::3] = self.spherical_scaling * ptheights + self.earth_radius vtk_sp_grid_data = numpy_support.numpy_to_vtk( self.np_sp_grid_data ) size = vtk_sp_grid_data.GetSize() vtk_sp_grid_data.SetNumberOfComponents( 3 ) vtk_sp_grid_data.SetNumberOfTuples( size/3 ) vtk_sp_grid_points = vtk.vtkPoints() vtk_sp_grid_points.SetData( vtk_sp_grid_data ) self.vtk_spherical_points = vtk.vtkPoints() self.shperical_to_xyz_trans.TransformPoints( vtk_sp_grid_points, self.vtk_spherical_points ) # pt0 = self.vtk_spherical_points.GetPoint(0) # print "VTK Set point Heights, samples: %s %s %s " % ( str( ptheights[0] ), str( self.np_sp_grid_data[0] ), str( pt0 ) ) self.polydata.SetPoints( self.vtk_spherical_points ) self.vtk_spherical_points.Modified() self.polydata.Modified() except Exception, err: self.printLogMessage( "Processing point heights: %s " % str( err ), error=True )
def makeEdgeVTKObject(mesh,model): """ Make and return a edge based VTK object for a simpeg mesh and model. Input: :param mesh, SimPEG TensorMesh object - mesh to be transfer to VTK :param model, dictionary of numpy.array - Name('s) and array('s). Property array must be order hstack(Ex,Ey,Ez) Output: :rtype: vtkUnstructuredGrid object :return: vtkObj """ ## Convert simpeg mesh to VTK properties # Convert mesh nodes to vtkPoints vtkPts = vtk.vtkPoints() vtkPts.SetData(npsup.numpy_to_vtk(mesh.gridN,deep=1)) # Define the face "cells" # Using VTK_QUAD cell for faces (see VTK file format) nodeMat = mesh.r(np.arange(mesh.nN,dtype='int64'),'N','N','M') def edgeR(mat,length): return mat.T.reshape((length,1)) # First direction nTEx = np.prod(mesh.nEx) ExCellBlock = np.hstack([ 2*np.ones((nTEx,1),dtype='int64'),edgeR(nodeMat[:-1,:,:],nTEx),edgeR(nodeMat[1:,:,:],nTEx)]) # Second direction if mesh.dim >= 2: nTEy = np.prod(mesh.nEy) EyCellBlock = np.hstack([ 2*np.ones((nTEy,1),dtype='int64'),edgeR(nodeMat[:,:-1,:],nTEy),edgeR(nodeMat[:,1:,:],nTEy)]) # Third direction if mesh.dim == 3: nTEz = np.prod(mesh.nEz) EzCellBlock = np.hstack([ 2*np.ones((nTEz,1),dtype='int64'),edgeR(nodeMat[:,:,:-1],nTEz),edgeR(nodeMat[:,:,1:],nTEz)]) # Cells -cell array ECellArr = vtk.vtkCellArray() ECellArr.SetNumberOfCells(mesh.nE) ECellArr.SetCells(mesh.nE,npsup.numpy_to_vtkIdTypeArray(np.vstack([ExCellBlock,EyCellBlock,EzCellBlock]),deep=1)) # Cell type ECellType = npsup.numpy_to_vtk(vtk.VTK_LINE*np.ones(mesh.nE,dtype='uint8'),deep=1) # Cell location ECellLoc = npsup.numpy_to_vtkIdTypeArray(np.arange(0,mesh.nE*3,3,dtype='int64'),deep=1) ## Make the object vtkObj = vtk.vtkUnstructuredGrid() # Set the objects properties vtkObj.SetPoints(vtkPts) vtkObj.SetCells(ECellType,ECellLoc,ECellArr) # Assign the model('s) to the object for item in model.iteritems(): # Convert numpy array vtkDoubleArr = npsup.numpy_to_vtk(item[1],deep=1) vtkDoubleArr.SetName(item[0]) vtkObj.GetCellData().AddArray(vtkDoubleArr) vtkObj.GetCellData().SetActiveScalars(model.keys()[0]) vtkObj.Update() return vtkObj
def render(self, **kwargs): """ Plots the volume and the control points. """ # Calling parent function super(VisVolume, self).render(**kwargs) # Initialize a list to store VTK actors vtk_actors = [] # Start plotting for plot in self._plots: # Plot control points if plot['type'] == 'ctrlpts' and self.vconf.display_ctrlpts: # Points as spheres pts = np.array(plot['ptsarr'], dtype=np.float) vtkpts = numpy_to_vtk(pts, deep=False, array_type=VTK_FLOAT) vtkpts.SetName(plot['name']) temp_actor = vtkh.create_actor_pts(pts=vtkpts, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx']) vtk_actors.append(temp_actor) # Plot evaluated points if plot['type'] == 'evalpts' and self.vconf.display_evalpts: pts = np.array(plot['ptsarr'], dtype=np.float) vtkpts = numpy_to_vtk(pts, deep=False, array_type=VTK_FLOAT) vtkpts.SetName(plot['name']) temp_actor = vtkh.create_actor_pts(pts=vtkpts, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx']) vtk_actors.append(temp_actor) # Render actors return vtkh.create_render_window(vtk_actors, dict(KeyPressEvent=(self.vconf.keypress_callback, 1.0)), figure_size=self.vconf.figure_size)
def Gen_uGrid(new_pt, new_fc): """ Generates a vtk unstructured grid given points and triangular faces""" ints = np.ones(len(new_fc), 'int')*3 cells = np.hstack((ints.reshape(-1, 1), np.vstack(new_fc))) # Generate vtk mesh # Convert points to vtkfloat object points = np.vstack(new_pt) vtkArray = VN.numpy_to_vtk(np.ascontiguousarray(points), deep=True)#, deep=True) points = vtk.vtkPoints() points.SetData(vtkArray) # Convert to vtk arrays tritype = vtk.vtkTriangle().GetCellType()*np.ones(len(new_fc), 'int') cell_type = np.ascontiguousarray(tritype).astype('uint8') cell_type = VN.numpy_to_vtk(cell_type, deep=True) offset = np.cumsum(np.hstack(ints + 1)) offset = np.ascontiguousarray(np.delete(np.insert(offset, 0, 0), -1)).astype('int64') # shift offset = VN.numpy_to_vtkIdTypeArray(offset, deep=True) cells = np.ascontiguousarray(np.hstack(cells).astype('int64')) vtkcells = vtk.vtkCellArray() vtkcells.SetCells(cells.shape[0], VN.numpy_to_vtkIdTypeArray(cells, deep=True)) # Create unstructured grid uGrid = vtk.vtkUnstructuredGrid() uGrid.SetPoints(points) uGrid.SetCells(cell_type, offset, vtkcells) return uGrid
def makeVTK(self, filename): nelements = len(self.data[filename]['elements']) n = np.array(self.data[filename]['nodes']) arr = numpy_support.numpy_to_vtk( n.ravel(), deep=True, array_type=vtk.VTK_DOUBLE) arr.SetNumberOfComponents(3) tetraPoints = vtk.vtkPoints() tetraPoints.SetData(arr) vtkMesh = vtk.vtkUnstructuredGrid() vtkMesh.Allocate(nelements, nelements) vtkMesh.SetPoints(tetraPoints) e = np.array(self.data[filename]['elements'], np.uint32) - 1 e = np.hstack((np.ones((e.shape[0], 1), np.uint32) * 4, e)) arr = numpy_support.numpy_to_vtk(e.ravel(), deep=True, array_type=vtk.VTK_ID_TYPE) tet = vtk.vtkCellArray() tet.SetCells(old_div(e.size, 5), arr) vtkMesh.SetCells(10, tet) centroids = (n[e[:, 1]] + n[e[:, 2]] + n[e[:, 3]] + n[e[:, 4]]) centroids /= 4.0 arr = numpy_support.numpy_to_vtk( centroids.ravel(), deep=True, array_type=vtk.VTK_FLOAT) arr.SetName("Centroids") arr.SetNumberOfComponents(3) vtkMesh.GetCellData().AddArray(arr) self.vtkMeshes[filename] = vtkMesh
def as_vtkarray(a): if isinstance(a, npy.ndarray): return vnp.numpy_to_vtk(a) elif isinstance(a, rpy2.rinterface.SexpVector): return vnp.numpy_to_vtk(npy.asarray(a)) else: return None
def putMaskOnVTKGrid(data,grid,actorColor=None,deep=True): #Ok now looking msk = data.mask imsk = VN.numpy_to_vtk(msk.astype(numpy.int).flat,deep=deep) mapper = None if msk is not numpy.ma.nomask: msk = VN.numpy_to_vtk(numpy.logical_not(msk).astype(numpy.uint8).flat,deep=deep) if actorColor is not None: grid2 = vtk.vtkStructuredGrid() grid2.CopyStructure(grid) geoFilter = vtk.vtkDataSetSurfaceFilter() if grid.IsA("vtkStructuredGrid"): grid2.GetPointData().SetScalars(imsk) #grid2.SetCellVisibilityArray(imsk) p2c = vtk.vtkPointDataToCellData() p2c.SetInputData(grid2) geoFilter.SetInputConnection(p2c.GetOutputPort()) else: grid2.GetCellData().SetScalars(imsk) geoFilter.SetInputData(grid) geoFilter.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(geoFilter.GetOutput()) lut = vtk.vtkLookupTable() lut.SetNumberOfTableValues(1) r,g,b = actorColor lut.SetNumberOfTableValues(2) lut.SetTableValue(0,r/100.,g/100.,b/100.) lut.SetTableValue(1,r/100.,g/100.,b/100.) mapper.SetLookupTable(lut) mapper.SetScalarRange(1,1) if grid.IsA("vtkStructuredGrid"): grid.SetPointVisibilityArray(msk) #grid.SetCellVisibilityArray(msk) return mapper
def writeVTK(mesh, fileName, models=None): """ Makes and saves a VTK rectilinear file (vtr) for a simpeg Tensor mesh and model. Input: :param str, path to the output vtk file :param mesh, SimPEG TensorMesh object - mesh to be transfer to VTK :param models, dictionary of numpy.array - Name('s) and array('s). Match number of cells """ # Import from vtk import vtkRectilinearGrid as rectGrid, vtkXMLRectilinearGridWriter as rectWriter, VTK_VERSION from vtk.util.numpy_support import numpy_to_vtk # Deal with dimensionalities if mesh.dim >= 1: vX = mesh.vectorNx xD = mesh.nNx yD,zD = 1,1 vY, vZ = np.array([0,0]) if mesh.dim >= 2: vY = mesh.vectorNy yD = mesh.nNy if mesh.dim == 3: vZ = mesh.vectorNz zD = mesh.nNz # Use rectilinear VTK grid. # Assign the spatial information. vtkObj = rectGrid() vtkObj.SetDimensions(xD,yD,zD) vtkObj.SetXCoordinates(numpy_to_vtk(vX,deep=1)) vtkObj.SetYCoordinates(numpy_to_vtk(vY,deep=1)) vtkObj.SetZCoordinates(numpy_to_vtk(vZ,deep=1)) # Assign the model('s) to the object if models is not None: for item in models.iteritems(): # Convert numpy array vtkDoubleArr = numpy_to_vtk(item[1],deep=1) vtkDoubleArr.SetName(item[0]) vtkObj.GetCellData().AddArray(vtkDoubleArr) # Set the active scalar vtkObj.GetCellData().SetActiveScalars(models.keys()[0]) # vtkObj.Update() # Check the extension of the fileName ext = os.path.splitext(fileName)[1] if ext is '': fileName = fileName + '.vtr' elif ext not in '.vtr': raise IOError('{:s} is an incorrect extension, has to be .vtr') # Write the file. vtrWriteFilter = rectWriter() if float(VTK_VERSION.split('.')[0]) >=6: vtrWriteFilter.SetInputData(vtkObj) else: vtuWriteFilter.SetInput(vtuObj) vtrWriteFilter.SetFileName(fileName) vtrWriteFilter.Update()
def execute(self): res = self.input("in") #get primary variable.. #need to ensure that results that go back to VisIt #are at least correct size.. varr = self.context.mesh.GetCellData().GetArray(self.context.primary_var) if varr is None: varr = self.context.mesh.GetPointData().GetArray(self.context.primary_var) if res is None: return self.context.mesh if isinstance(res,vtk.vtkDataSet): return res if isinstance(res,npy.ndarray): res = npy.ascontiguousarray(res) res = vnp.numpy_to_vtk(res) if not isinstance(res, vtk.vtkDataArray): if isinstance(res,npy.ndarray) or isinstance(res, (list,tuple)): np_tmp = npy.ascontiguousarray(res) else: np_tmp = npy.ascontiguousarray([res]) #ensure 1 dimension before putting it in vtk.. np_tmp = npy.ravel(np_tmp) #pad with zeros if incorrect size.. if varr is not None and varr.GetDataSize() > len(np_tmp): np_tmp = npy.pad(np_tmp,(0,len(np_tmp)-var.GetDataSize()),'constant') res = vnp.numpy_to_vtk(np_tmp) #if isinstance(res,npy.ndarray): # # create # vdata = vtk.vtkFloatArray() # vdata.SetNumberOfComponents(1) # vdata.SetNumberOfTuples(res.shape[0]) # npo = vnp.vtk_to_numpy(vdata) # npo[:] = res # res = vdata if isinstance(res,vtk.vtkDataArray): res.SetName(self.context.primary_var) rset = self.context.mesh.NewInstance() rset.ShallowCopy(self.context.mesh) #only handles scalar data right now. TODO: add more support vtk_data = rset.GetCellData().GetScalars(self.context.primary_var) if vtk_data : rset.GetCellData().RemoveArray(self.context.primary_var) rset.GetCellData().AddArray(res) rset.GetCellData().SetScalars(res) else: rset.GetPointData().RemoveArray(self.context.primary_var) rset.GetPointData().AddArray(res) rset.GetPointData().SetScalars(res) else: #should not get here.. rset = res return rset
def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_L: self.basis_idx += 1 coeffs = VN.numpy_to_vtk(self.WavBases[self.basis_idx][::-1,0]*100, deep=True) coeffs.SetName('coefficient') c_sign = VN.numpy_to_vtk(N.sign(self.WavBases[self.basis_idx][::-1,0]), deep=True) c_sign.SetName('sign') self.table.RemoveColumn(2) self.table.RemoveColumn(1) self.table.AddColumn(coeffs) self.table.AddColumn(c_sign) self.WordleView.RemoveAllRepresentations() self.WordleView.AddRepresentationFromInput(self.table) self.table.Modified() self.WordleView.Update() if event.key() == QtCore.Qt.Key_Space: if event.modifiers() == QtCore.Qt.NoModifier: self.WordleView.Modified() self.WordleView.Update() elif event.modifiers() == QtCore.Qt.ShiftModifier: self.table.Modified() self.WordleView.Update() # Write PNG (n) # Trying to use a integer-based QImage if event.key() == QtCore.Qt.Key_N: scene = self.WordleView.GetScene() image = QtGui.QImage(256,256,QtGui.QImage.Format_ARGB32) painter = QtGui.QPainter(image) painter.setRenderHint(QtGui.QPainter.Antialiasing) scene.render(painter) painter.end() image.save("out.png") # Write PDF (p) if event.key() == QtCore.Qt.Key_P: scene = self.WordleView.GetScene() printer = QtGui.QPrinter() printer.setOutputFormat(QtGui.QPrinter.PdfFormat) printer.setOutputFileName("out.pdf") pdfPainter = QtGui.QPainter(printer) scene.render(pdfPainter) pdfPainter.end() # Write SVG (s) if event.key() == QtCore.Qt.Key_S: scene = self.WordleView.GetScene() svggen = QtSvg.QSvgGenerator() svggen.setFileName("out.svg") svggen.setSize(QtCore.QSize(600, 600)) svggen.setViewBox(QtCore.QRect(0, 0, 600, 600)) svggen.setTitle("SVG Generator Example Drawing") svggen.setDescription("An SVG drawing created by the SVG Generator") svgPainter = QtGui.QPainter(svggen) scene.render(svgPainter) svgPainter.end()
def method(self): # multiblock += contact points output_a = self._contact_source_a.GetPolyDataOutput() output_b = self._contact_source_b.GetPolyDataOutput() id_f = numpy.where( abs(self._data[:, 0] - self._time) < 1e-15)[0] self.cpa_export = self._data[ id_f, 2:5].copy() self.cpb_export = self._data[ id_f, 5:8].copy() self.cn_export = self._data[ id_f, 8:11].copy() self.cf_export = self._data[ id_f, 11:14].copy() self.cpa_ = numpy_support.numpy_to_vtk( self.cpa_export) self.cpa_.SetName('contact_positions_A') self.cpb_ = numpy_support.numpy_to_vtk( self.cpb_export) self.cpb_.SetName('contact_positions_B') self.cn_ = numpy_support.numpy_to_vtk( self.cn_export) self.cn_.SetName('contact_normals') self.cf_ = numpy_support.numpy_to_vtk( self.cf_export) self.cf_.SetName('contact_forces') output_a.Allocate(len(self.cpa_export), 1) cpa_points = vtk.vtkPoints() cpa_points.SetNumberOfPoints(len(self.cpa_export)) cpa_points.SetData(self.cpa_) output_a.SetPoints(cpa_points) # normal and forces are attached to A points output_a.GetPointData().AddArray(self.cn_) output_a.GetPointData().AddArray(self.cf_) output_b.Allocate(len(self.cpb_export), 1) cpb_points = vtk.vtkPoints() cpb_points.SetNumberOfPoints(len(self.cpb_export)) cpb_points.SetData(self.cpb_) output_b.SetPoints(cpb_points)
def write_vtu(filename, atoms, data=None): from vtk import VTK_MAJOR_VERSION, vtkUnstructuredGrid, vtkPoints, vtkXMLUnstructuredGridWriter from vtk.util.numpy_support import numpy_to_vtk if isinstance(atoms, list): if len(atoms) > 1: raise ValueError('Can only write one configuration to a VTI file!') atoms = atoms[0] # Create a VTK grid of structured points ugd = vtkUnstructuredGrid() # add atoms as vtk Points p = vtkPoints() p.SetNumberOfPoints(len(atoms)) p.SetDataTypeToDouble() for i,pos in enumerate(atoms.get_positions()): p.InsertPoint(i,pos[0],pos[1],pos[2]) ugd.SetPoints(p) # add atomic numbers numbers = numpy_to_vtk(atoms.get_atomic_numbers(), deep=1) ugd.GetPointData().AddArray(numbers) numbers.SetName("atomic numbers") # add tags tags = numpy_to_vtk(atoms.get_tags(), deep=1) ugd.GetPointData().AddArray(tags) tags.SetName("tags") # add covalent radii from ase.data import covalent_radii radii = numpy_to_vtk(np.array([covalent_radii[i] for i in atoms.get_atomic_numbers()]), deep=1) ugd.GetPointData().AddArray(radii) radii.SetName("radii") # Save the UnstructuredGrid dataset to a VTK XML file. w = vtkXMLUnstructuredGridWriter() if fast: w.SetDataModeToAppend() w.EncodeAppendedDataOff() else: w.GetCompressor().SetCompressionLevel(0) w.SetDataModeToAscii() if isinstance(filename, str): w.SetFileName(filename) else: w.SetFileName(filename.name) if VTK_MAJOR_VERSION <= 5: w.SetInput(ugd) else: w.SetInputData(ugd) w.Write()
def attach_pos(self): pos = self._pos rad = self._rad if pos is not None and rad is not None: positions_vtk = numpy_support.numpy_to_vtk(num_array=pos.ravel(), deep=True, array_type=vtk.VTK_FLOAT) positions_vtk.SetName("positions") radius_vtk = numpy_support.numpy_to_vtk(num_array=rad.ravel(), deep=True, array_type=vtk.VTK_FLOAT) radius_vtk.SetName("radius") sphere = vtk.vtkSphereSource() sphere.SetRadius(1.0) ballGlyph = vtk.vtkGlyph3D() if vtk.VTK_MAJOR_VERSION <= 5: ballGlyph.SetSource(sphere.GetOutput()) else: ballGlyph.SetSourceConnection(sphere.GetOutputPort()) polydata = vtk.vtkPolyData() polydata.SetPoints(self._points) polydata.GetPointData().AddArray(radius_vtk) polydata.GetPointData().SetActiveScalars("radius") # this scales the source (sphere) radius (1.0) ballGlyph.SetInputData(polydata) #ballGlyph.SetScaleModeToDataScalingOn() mapper = vtk.vtkPolyDataMapper() if vtk.VTK_MAJOR_VERSION <= 5: mapper.SetInput(ballGlyph.GetOutput()) else: mapper.SetInputConnection(ballGlyph.GetOutputPort()) # Set colors depending on the color transfer functions # mapper.SetLookupTable(self.colorTransferFunction) # actor ballActor = vtk.vtkActor() ballActor.GetProperty().SetColor(0,0,1) ballActor.SetMapper(mapper) #self._ren.AddActor(ballActor) self._marker2 = vtk.vtkOrientationMarkerWidget() self._marker2.SetInteractor( self.widget._Iren ) self._marker2.SetOrientationMarker( ballActor ) self._marker2.SetViewport(0.75,0,1,0.25) self._marker2.SetEnabled(1) else: print("No particles found. Make sure the particles loaded have positions and radii.")
def writeVTK(mesh, fileName, models=None): """ Function to write a VTU file from a SimPEG TreeMesh and model. """ import vtk from vtk import vtkXMLUnstructuredGridWriter as Writer, VTK_VERSION from vtk.util.numpy_support import numpy_to_vtk, numpy_to_vtkIdTypeArray if str(type(mesh)).split()[-1][1:-2] not in 'SimPEG.Mesh.TreeMesh.TreeMesh': raise IOError('mesh is not a SimPEG TreeMesh.') # Make the data parts for the vtu object # Points mesh.number() ptsMat = mesh._gridN + mesh.x0 vtkPts = vtk.vtkPoints() vtkPts.SetData(numpy_to_vtk(ptsMat,deep=True)) # Cells cellConn = np.array([c.nodes for c in mesh],dtype=np.int64) cellsMat = np.concatenate((np.ones((cellConn.shape[0],1),dtype=np.int64)*cellConn.shape[1],cellConn),axis=1).ravel() cellsArr = vtk.vtkCellArray() cellsArr.SetNumberOfCells(cellConn.shape[0]) cellsArr.SetCells(cellConn.shape[0],numpy_to_vtkIdTypeArray(cellsMat,deep=True)) # Make the object vtuObj = vtk.vtkUnstructuredGrid() vtuObj.SetPoints(vtkPts) vtuObj.SetCells(vtk.VTK_VOXEL,cellsArr) # Add the level of refinement as a cell array cellSides = np.array([np.array(vtuObj.GetCell(i).GetBounds()).reshape((3,2)).dot(np.array([-1, 1])) for i in np.arange(vtuObj.GetNumberOfCells())]) uniqueLevel, indLevel = np.unique(np.prod(cellSides,axis=1),return_inverse=True) refineLevelArr = numpy_to_vtk(indLevel.max() - indLevel,deep=1) refineLevelArr.SetName('octreeLevel') vtuObj.GetCellData().AddArray(refineLevelArr) # Assign the model('s) to the object if models is not None: for item in models.iteritems(): # Convert numpy array vtkDoubleArr = numpy_to_vtk(item[1],deep=1) vtkDoubleArr.SetName(item[0]) vtuObj.GetCellData().AddArray(vtkDoubleArr) # Make the writer vtuWriteFilter = Writer() if float(VTK_VERSION.split('.')[0]) >=6: vtuWriteFilter.SetInputData(vtuObj) else: vtuWriteFilter.SetInput(vtuObj) vtuWriteFilter.SetFileName(fileName) # Write the file vtuWriteFilter.Update()
def polydata_from_numpy(coords): """ Converts Numpy Array to vtkPolyData Parameters ---------- coords: array, shape= [number of points, point features] array containing the point cloud in which each point has three coordinares [x, y, z] and none, one or three values corresponding to colors. Returns: -------- PolyData: vtkPolyData concrete dataset represents vertices, lines, polygons, and triangle strips """ Npts, Ndim = np.shape(coords) Points = vtkPoints() ntype = get_numpy_array_type(Points.GetDataType()) coords_vtk = numpy_to_vtk(np.asarray(coords[:,0:3], order='C',dtype=ntype), deep=1) Points.SetNumberOfPoints(Npts) Points.SetData(coords_vtk) Cells = vtkCellArray() ids = np.arange(0,Npts, dtype=np.int64).reshape(-1,1) IDS = np.concatenate([np.ones(Npts, dtype=np.int64).reshape(-1,1), ids],axis=1) ids_vtk = numpy_to_vtkIdTypeArray(IDS, deep=True) Cells.SetNumberOfCells(Npts) Cells.SetCells(Npts,ids_vtk) if Ndim == 4: color = [128]*len(coords) color = np.c_[color, color, color] elif Ndim == 6: color = coords[:,3:] else: color = [[128, 128, 128]]*len(coords) color_vtk = numpy_to_vtk( np.ascontiguousarray(color, dtype=get_vtk_to_numpy_typemap()[VTK_UNSIGNED_CHAR]), deep=True) color_vtk.SetName("colors") PolyData = vtkPolyData() PolyData.SetPoints(Points) PolyData.SetVerts(Cells) PolyData.GetPointData().SetScalars(color_vtk) return PolyData
def extract_particles(self,ids): data=vtk.vtkPolyData() points=vtk_to_numpy(self._in_vtk.GetPoints().GetData()) s_points=vtk.vtkPoints() cell_arr=vtk.vtkCellArray() #s_points.SetData(numpy_to_vtk(points[ids,:])) #s_points.SetNumberOfPoints(s_points.GetData().GetNumberOfTuples()) s_p = points[ids,:] s_points.SetNumberOfPoints(s_p.shape[0]) cell_arr.SetNumberOfCells(s_p.shape[0]) for kk in xrange(s_p.shape[0]): s_points.SetPoint(kk,s_p[kk,0],s_p[kk,1],s_p[kk,2]) cell_arr.InsertNextCell(1) cell_arr.InsertCellPoint(kk) data.SetPoints(s_points) data.SetVerts(cell_arr) #Transfer point data and field data for pd,out_pd in zip([self._in_vtk.GetPointData(),self._in_vtk.GetFieldData()],[data.GetPointData(),data.GetFieldData()]): for k in xrange(pd.GetNumberOfArrays()): arr=vtk_to_numpy(pd.GetArray(pd.GetArrayName(k))) if len(arr.shape) == 1: s_vtk_arr=numpy_to_vtk(arr[ids],1) else: s_vtk_arr=numpy_to_vtk(arr[ids,:],1) s_vtk_arr.SetName(pd.GetArrayName(k)) out_pd.AddArray(s_vtk_arr) return data #Method to do the extraction using a vtk pipeline (experimental with seg fault) def extract_using_vtk(self,ids): node=vtk.vtkSelectionNode() sel = vtk.vtkSelection() node.GetProperties().Set(vtk.vtkSelectionNode.CONTENT_TYPE(),\ vtk.vtkSelectionNode.INDICES) node.GetProperties().Set(vtk.vtkSelectionNode.FIELD_TYPE(),\ vtk.vtkSelectionNode.POINT) #Create Id Array with point Ids for each cluster vtk_ids=numpy_to_vtkIdTypeArray(ids) node.SetSelectionList(vtk_ids) #sel_filter = vtk.vtkExtractSelectedPolyDataIds() sel_filter = vtk.vtkExtractSelection() sel_filter.SetInput(0,self._in_vtk) sel_filter.SetInput(1,sel) sel_filter.Update() return sel_filter.GetOutput()
def GetNodeOneScaleCoeffTable(self, node_id): """Returns a table of the wavelet coefficients at a single node at a single scale for plotting on a scatter plot. Relying on icicle_view already having called GetWaveletCoeffImages() with correct positions of leaf nodes in view, otherwise just using original Matlab-saved LeafNodes ordering. This version supports category labels.""" if self.data_loaded: # For a given node_id, concatenate wavelet coeffs in proper order # (according to leaf node positions in icicle view if it was set already) # Columns of table will be rows of the wavelet coeffs image scale = self.Scales[node_id] leaf_offspring = N.array(list(self.get_leaf_children(self.cp, node_id))) offspring_idxs = self.LeafNodesImap[leaf_offspring] offspring_pos = self.mapped_leaf_pos[offspring_idxs] sorted_offspring_pos_idxs = N.argsort(offspring_pos) sorted_offspring_idxs = offspring_idxs[sorted_offspring_pos_idxs] img_tuple = tuple(pp for pp in self.CelCoeffs[sorted_offspring_idxs, scale]) # The image comes out with shape (npts, ndims) # May need to reorder (reverse) this...? img = N.concatenate(img_tuple, axis=0) table = vtk.vtkTable() for ii in range(img.shape[1]): column = VN.numpy_to_vtk(img[:,ii].copy(), deep=True) column.SetName(str(scale) + '.' + str(ii)) table.AddColumn(column) IDtuple = tuple(self.PointsInNet[xx] for xx in self.LeafNodes[sorted_offspring_idxs]) IDarray = N.concatenate(IDtuple) # Trying to set PedigreeIds to that parallel coords selections have correct IDs IDvtk = VN.numpy_to_vtk(IDarray, deep=True) IDvtk.SetName('pedigree_ids') table.AddColumn(IDvtk) table.GetRowData().SetActivePedigreeIds('pedigree_ids') # Adding in category labels # Name needs to end in _ids so plots will ignore it if self.hasLabels: for ii in range(self.cat_labels.shape[0]): CATvtk = VN.numpy_to_vtk(self.cat_labels[ii,IDarray], deep=True) CATvtk.SetName(self.label_names[ii]) table.AddColumn(CATvtk) return table else: raise IOError, "Can't get image until data is loaded successfully"
def gocad2simpegMeshIndex(gcFile,mesh,extractBoundaryCells=True,extractInside=True): """" Function to read gocad polystructure file and output indexes of mesh with in the structure. """ # Make the polydata polyData = gocad2vtp(gcFile) # Make implicit func ImpDistFunc = vtk.vtkImplicitPolyDataDistance() ImpDistFunc.SetInput(polyData) # Convert the mesh vtkMesh = vtk.vtkRectilinearGrid() vtkMesh.SetDimensions(mesh.nNx,mesh.nNy,mesh.nNz) vtkMesh.SetXCoordinates(npsup.numpy_to_vtk(mesh.vectorNx,deep=1)) vtkMesh.SetYCoordinates(npsup.numpy_to_vtk(mesh.vectorNy,deep=1)) vtkMesh.SetZCoordinates(npsup.numpy_to_vtk(mesh.vectorNz,deep=1)) # Add indexes cell data to the object vtkInd = npsup.numpy_to_vtk(np.arange(mesh.nC),deep=1) vtkInd.SetName('Index') vtkMesh.GetCellData().AddArray(vtkInd) # Define the extractGeometry extractImpDistRectGridFilt = vtk.vtkExtractGeometry() # Object constructor extractImpDistRectGridFilt.SetImplicitFunction(ImpDistFunc) # extractImpDistRectGridFilt.SetInputData(vtkMesh) # Set extraction type if extractBoundaryCells is True: extractImpDistRectGridFilt.ExtractBoundaryCellsOn() else: extractImpDistRectGridFilt.ExtractBoundaryCellsOff() if extractInside is True: extractImpDistRectGridFilt.ExtractInsideOn() else: extractImpDistRectGridFilt.ExtractInsideOff() print "Extracting indices from grid..." # Executing the pipe extractImpDistRectGridFilt.Update() # Get index inside insideGrid = extractImpDistRectGridFilt.GetOutput() insideGrid = npsup.vtk_to_numpy(insideGrid.GetCellData().GetArray('Index')) # Return the indexes inside return insideGrid
def render(self, **kwargs): """ Plots the surface and the control points grid. """ # Calling parent function super(VisSurface, self).render(**kwargs) # Initialize a list to store VTK actors vtk_actors = [] # Start plotting for plot in self._plots: # Plot control points if plot['type'] == 'ctrlpts' and self.vconf.display_ctrlpts: vertices = [v.data for v in plot['ptsarr'][0]] faces = [q.data for q in plot['ptsarr'][1]] # Points as spheres pts = np.array(vertices, dtype=np.float) vtkpts = numpy_to_vtk(pts, deep=False, array_type=VTK_FLOAT) vtkpts.SetName(plot['name']) actor1 = vtkh.create_actor_pts(pts=vtkpts, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx']) vtk_actors.append(actor1) # Quad mesh lines = np.array(faces, dtype=np.int) actor2 = vtkh.create_actor_mesh(pts=vtkpts, lines=lines, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx'], size=self.vconf.line_width) vtk_actors.append(actor2) # Plot evaluated points if plot['type'] == 'evalpts' and self.vconf.display_evalpts: vertices = [v.data for v in plot['ptsarr'][0]] vtkpts = numpy_to_vtk(vertices, deep=False, array_type=VTK_FLOAT) vtkpts.SetName(plot['name']) faces = [t.data for t in plot['ptsarr'][1]] tris = np.array(faces, dtype=np.int) actor1 = vtkh.create_actor_tri(pts=vtkpts, tris=tris, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx']) vtk_actors.append(actor1) # Plot trim curves if self.vconf.display_trims: if plot['type'] == 'trimcurve': pts = np.array(plot['ptsarr'], dtype=np.float) vtkpts = numpy_to_vtk(pts, deep=False, array_type=VTK_FLOAT) vtkpts.SetName(plot['name']) actor1 = vtkh.create_actor_polygon(pts=vtkpts, color=vtkh.create_color(plot['color']), name=plot['name'], index=plot['idx'], size=self.vconf.trim_size) vtk_actors.append(actor1) # Render actors return vtkh.create_render_window(vtk_actors, dict(KeyPressEvent=(self.vconf.keypress_callback, 1.0)), figure_size=self.vconf.figure_size)
def ply_exporter(mesh, file_path, binary=False, **kwargs): r""" Given a file path to write in to write out the mesh data. No value is returned. Only file paths are supported and if a file handle is passed it will be ignored and a warning will be raised. Note that this does not save out textures of textured images, and so should not be used in isolation. Parameters ---------- file_path : `str` The full path where the obj will be saved out. mesh : :map:`TriMesh` Any subclass of :map:`TriMesh`. If :map:`TexturedTriMesh` texture coordinates will be saved out. Note that :map:`ColouredTriMesh` will only have shape data saved out, as .PLY doesn't robustly support per-vertex colour information. binary: `bool`, optional Specify whether to format output in binary or ascii, defaults to False """ import vtk from vtk.util.numpy_support import numpy_to_vtk, numpy_to_vtkIdTypeArray file_path = _enforce_only_paths_supported(file_path, 'PLY') polydata = vtk.vtkPolyData() points = vtk.vtkPoints() points.SetData(numpy_to_vtk(mesh.points)) polydata.SetPoints(points) cells = vtk.vtkCellArray() counts = np.empty((mesh.trilist.shape[0], 1), dtype=np.int) counts.fill(3) tris = np.concatenate((counts, mesh.trilist), axis=1) cells.SetCells(mesh.trilist.shape[0], numpy_to_vtkIdTypeArray(tris)) polydata.SetPolys(cells) if isinstance(mesh, TexturedTriMesh): pointdata = polydata.GetPointData() pointdata.SetTCoords(numpy_to_vtk(mesh.tcoords.points)) ply_writer = vtk.vtkPLYWriter() ply_writer.SetFileName(str(file_path)) ply_writer.SetInputData(polydata) if not binary: ply_writer.SetFileTypeToASCII() else: ply_writer.SetFileTypeToBinary() ply_writer.Update() ply_writer.Write()
def GetTree(self): """Returns a full vtkTree based on data loaded in LoadData().""" if self.data_loaded: vertex_id = vtk.vtkIdTypeArray() vertex_id.SetName('vertex_ids') for ii in range(len(self.cp)): vertex_id.InsertNextValue(ii) NINvtk = VN.numpy_to_vtk(self.NumberInNet, deep=True) NINvtk.SetName('num_in_vertex') SCALESvtk = VN.numpy_to_vtk(self.Scales, deep=True) SCALESvtk.SetName('scale') # This array will default to empty strings BLANKvtk = vtk.vtkStringArray() BLANKvtk.SetNumberOfComponents(1) BLANKvtk.SetNumberOfTuples(self.NumberInNet.shape[0]) BLANKvtk.SetName('blank') # Build tree out of CP list of "is a child of" # remembering that Matlab indices are 1-based and numpy/VTK 0-based print 'Building graph' dg = vtk.vtkMutableDirectedGraph() edge_id = vtk.vtkIdTypeArray() edge_id.SetName('edge_ids') for ii in range(self.cp.size): dg.AddVertex() for ii in range(self.cp.size): if self.cp[ii] > 0: # CP already zero-based dg.AddGraphEdge(self.cp[ii],ii) # Method for use with wrappers -- AddEdge() in C++ edge_id.InsertNextValue(ii) dg.GetVertexData().AddArray(NINvtk) dg.GetVertexData().AddArray(SCALESvtk) dg.GetVertexData().AddArray(vertex_id) dg.GetVertexData().SetActiveScalars('scale') dg.GetVertexData().SetActivePedigreeIds('vertex_ids') dg.GetEdgeData().AddArray(edge_id) dg.GetEdgeData().SetActivePedigreeIds('edge_ids') tree = vtk.vtkTree() tree.CheckedShallowCopy(dg) return tree else: raise IOError, "Can't get tree until data is loaded successfully"
def VertFacetoPoly(new_pt, new_fc): """ Creates a vtk polydata object given points and triangular faces """ # Convert points to vtkfloat object points = np.vstack(new_pt) vtkArray = VN.numpy_to_vtk(np.ascontiguousarray(points), deep=True)#, deep=True) points = vtk.vtkPoints() points.SetData(vtkArray) # Convert faces to vtk cells object ints = np.ones(len(new_fc), 'int')*3 cells = np.hstack((ints.reshape(-1, 1), np.vstack(new_fc))) cells = np.ascontiguousarray(np.hstack(cells).astype('int64')) vtkcells = vtk.vtkCellArray() vtkcells.SetCells(cells.shape[0], VN.numpy_to_vtkIdTypeArray(cells, deep=True)) # Create polydata object pdata = vtk.vtkPolyData() pdata.SetPoints(points) pdata.SetPolys(vtkcells) # Remove duplicate verticies clean = vtk.vtkCleanPolyData() clean.ConvertPolysToLinesOff() clean.ConvertLinesToPointsOff() clean.ConvertStripsToPolysOff() if vtk.vtkVersion().GetVTKMajorVersion() > 5: clean.SetInputData(pdata) else: clean.SetInput(pdata) clean.Update() return clean.GetOutput()
def add_lines(self, points, lines, colors=(255, 0, 0)): line_collection = vtk.vtkCellArray() line_collection.Allocate(len(lines)) for line in lines: line_collection.InsertNextCell(len(line), line) poly_data = vtk.vtkPolyData() poly_data.SetPoints(self._convert_points_array(points)) poly_data.SetLines(line_collection) actor = self._actor_from_poly_data(poly_data) colors = np.asarray(colors) if colors.size == 3: # only one color given colors = colors.ravel() actor.GetProperty().SetColor(colors[0], colors[1], colors[2]) elif colors.shape[0] == len(lines): # array of line colors colors = np.ascontiguousarray( colors.astype(np.uint8, subok=True, copy=False)) colors_array = numpy_to_vtk(colors) colors_array.SetName("Colors") # to avoid the colors array going out of scope setattr(colors_array, '_np_color_array', colors) poly_data.GetCellData().SetScalars(colors_array) else: # array of vertex colors self._add_color_to_actor(actor, colors) return self._add_mesh_actor(actor)
def __loadVTKImageDataFromNumpyFormat(self, scores): num_patients = scores.shape[1] self.pat_poly_data = vtk.vtkPolyData() self.pat_data_img_data_list = list() self.pat_data_pandas_scores = dict() for pat in range(0, num_patients): data_matrix = scores[:,pat] data_matrix = data_matrix.astype(float) #arr = vtk.vtkFloatArray() # there is too much data to display efficiently # with 120 x 120 x 120 voxels # todo: need to narrow down data points...stepping by arb. 1000 for now... dmat_contig = np.copy(a=data_matrix[0:-1:100], order='C') arr = numpy_to_vtk(num_array=dmat_contig, \ deep=True, array_type=vtk.VTK_FLOAT) arr.SetName('pat'+str(pat)) self.pat_poly_data.GetPointData().AddArray(arr) # store outcomes for cross-patient parallel coordinates outcomes = dmat_contig[np.where(dmat_contig > NAN)] outcome = np.NaN if len(outcomes) > 0: outcome = outcomes[0] #self.pat_data_pandas_scores['pat'+str(pat)] = [outcome] self.pat_data_pandas_scores[pat] = [outcome] idata = self.__getVTKImgDataForNumpyArray(data_matrix) self.pat_data_img_data_list.append( idata )
def to_vtk(n_array, spacing, slice_number, orientation): try: dz, dy, dx = n_array.shape except ValueError: dy, dx = n_array.shape dz = 1 v_image = numpy_support.numpy_to_vtk(n_array.flat) if orientation == 'AXIAL': extent = (0, dx -1, 0, dy -1, slice_number, slice_number + dz - 1) elif orientation == 'SAGITAL': dx, dy, dz = dz, dx, dy extent = (slice_number, slice_number + dx - 1, 0, dy - 1, 0, dz - 1) elif orientation == 'CORONAL': dx, dy, dz = dx, dz, dy extent = (0, dx - 1, slice_number, slice_number + dy - 1, 0, dz - 1) # Generating the vtkImageData image = vtk.vtkImageData() image.SetOrigin(0, 0, 0) image.SetSpacing(spacing) image.SetDimensions(dx, dy, dz) # SetNumberOfScalarComponents and SetScalrType were replaced by # AllocateScalars # image.SetNumberOfScalarComponents(1) # image.SetScalarType(numpy_support.get_vtk_array_type(n_array.dtype)) image.AllocateScalars(numpy_support.get_vtk_array_type(n_array.dtype), 1) image.SetExtent(extent) image.GetPointData().SetScalars(v_image) image_copy = vtk.vtkImageData() image_copy.DeepCopy(image) return image_copy
def get_vtk_cloud(self, zMin=-10.0,zMax=10.0): assert( len(self.intensity.shape) == 1) (vtkPolyData, vtkPoints, vtkCells) = self.build_vtk_polydata() self.intensity == self.intensity.astype(np.float32) vtk_intensity_data = converter.numpy_to_vtk(self.intensity) vtk_intensity_data.SetName('DepthArray') vtkPolyData.GetPointData().SetScalars(vtk_intensity_data) num_points = self.xyz.shape[0] #vtkDepth = vtk.vtkFloatArray() #vtkDepth.SetName('DepthArray') #vtkPolyData.GetPointData().SetScalars(vtkDepth) #vtkDepth.SetVoidArray(self.intensity, num_points, 1) vtkPolyData.GetPointData().SetActiveScalars('DepthArray') mapper = vtk.vtkPolyDataMapper() mapper.SetInput(vtkPolyData) mapper.SetColorModeToDefault() mapper.SetScalarRange(zMin, zMax) mapper.SetScalarVisibility(1) vtkActor = vtk.vtkActor() vtkActor.SetMapper(mapper) return vtkActor
def ndarray2vtkImageData(ndarray, cast_type=11, spacing=[1, 1, 1]): """ Convert a NumPy array to a vtkImageData, with a default casting type VTK_DOUBLE :param ndarray: input NumPy array, can be 3D array :param cast_type: 11 means VTK_DOUBLE :return: a vtkImageData """ # Convert numpy array to VTK array (vtkDoubleArray) vtk_data_array = numpy_support.numpy_to_vtk( num_array=ndarray.transpose(2, 1, 0).ravel(), deep=True, array_type=vtk.VTK_DOUBLE) # Convert the VTK array to vtkImageData img_vtk = vtk.vtkImageData() img_vtk.SetDimensions(ndarray.shape) img_vtk.SetSpacing(spacing[::-1]) # Note the order should be reversed! img_vtk.GetPointData().SetScalars(vtk_data_array) # is a vtkImageData # casting cast = vtk.vtkImageCast() cast.SetInputData(img_vtk) cast.SetOutputScalarType(cast_type) cast.Update() return cast.GetOutput() # vtkImageData
def computeSphericalPoints( self, **args ): lon_data = self.np_points_data[0::3] lat_data = self.np_points_data[1::3] z_data = self.np_points_data[2::3] radian_scaling = math.pi / 180.0 theta = ( 90.0 - lat_data ) * radian_scaling phi = lon_data * radian_scaling r = z_data * self.spherical_scaling + self.earth_radius self.np_sp_grid_data = numpy.dstack( ( r, theta, phi ) ).flatten() vtk_sp_grid_data = numpy_support.numpy_to_vtk( self.np_sp_grid_data ) # if self.grid == PlotType.List: # # r = numpy.empty( lon_data.shape, lon_data.dtype ) # # r.fill( self.earth_radius ) # r = z_data * self.spherical_scaling + self.earth_radius # self.np_sp_grid_data = numpy.dstack( ( r, theta, phi ) ).flatten() # vtk_sp_grid_data = numpy_support.numpy_to_vtk( self.np_sp_grid_data ) # elif self.grid == PlotType.Grid: # thetaB = theta.reshape( [ theta.shape[0], 1 ] ) # phiB = phi.reshape( [ 1, phi.shape[0] ] ) # grid_data = numpy.array( [ ( self.earth_radius, t, p ) for (t,p) in numpy.broadcast(thetaB,phiB) ] ) # self.np_sp_grid_data = grid_data.flatten() # vtk_sp_grid_data = numpy_support.numpy_to_vtk( self.np_sp_grid_data ) # else: # print>>sys.stderr, "Unrecognized grid type: %s " % str( self.grid ) # return size = vtk_sp_grid_data.GetSize() vtk_sp_grid_data.SetNumberOfComponents( 3 ) vtk_sp_grid_data.SetNumberOfTuples( size/3 ) vtk_sp_grid_points = vtk.vtkPoints() vtk_sp_grid_points.SetData( vtk_sp_grid_data ) self.vtk_spherical_points = vtk.vtkPoints() self.shperical_to_xyz_trans.TransformPoints( vtk_sp_grid_points, self.vtk_spherical_points )
def set_array(dataobject, newarray): # Ensure we have Fortran ordered flat array to assign to image data. This # is ideally done without additional copies, but if C order we must copy. if np.isfortran(newarray): arr = newarray.reshape(-1, order='F') else: print 'Warning, array does not have Fortran order, making deep copy and fixing...' tmp = np.asfortranarray(newarray) arr = tmp.reshape(-1, order='F') print '...done.' # Set the extents (they may have changed). dataobject.SetExtent(0, newarray.shape[0] - 1, 0, newarray.shape[1] - 1, 0, newarray.shape[2] - 1) # Now replace the scalars array with the new array. vtkarray = np_s.numpy_to_vtk(arr) vtkarray.Association = dsa.ArrayAssociation.POINT do = dsa.WrapDataObject(dataobject) oldscalars = do.PointData.GetScalars() name = oldscalars.GetName() del oldscalars do.PointData.append(arr, name) do.PointData.SetActiveScalars(name)
def progress_renwin(renWin): fname = next(renWin.fnames) dyn = np.load(fname.strip()) rp = butils.pad_to_3d(np.array([dyn['rp']])) renWin.points.SetData(numpy_support.numpy_to_vtk(rp)) keys = ['vp', 'vh', 've'] # Something to do with VTK messing up Python's garbage collection # not sure why this is needed but it works anyway vs = [None for i in range(len(keys))] for i in range(len(renWin.point_sets)): vs[i] = butils.pad_to_3d(np.array([dyn[keys[i]]])) renWin.point_sets[i].SetVectors(numpy_support.numpy_to_vtk(vs[i])) renWin.Render() return fname
def numpy_to_vtk_colors(colors): vtk_colors = ns.numpy_to_vtk( np.asarray(colors), deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) return vtk_colors
def _generate_vtk_mesh(points, cells): import vtk from vtk.util import numpy_support mesh = vtk.vtkUnstructuredGrid() # set points vtk_points = vtk.vtkPoints() # Not using a deep copy here results in a segfault. vtk_array = numpy_support.numpy_to_vtk(points, deep=True) vtk_points.SetData(vtk_array) mesh.SetPoints(vtk_points) # Set cells. meshio_to_vtk_type = { 'vertex': vtk.VTK_VERTEX, 'line': vtk.VTK_LINE, 'triangle': vtk.VTK_TRIANGLE, 'quad': vtk.VTK_QUAD, 'tetra': vtk.VTK_TETRA, 'hexahedron': vtk.VTK_HEXAHEDRON, 'wedge': vtk.VTK_WEDGE, 'pyramid': vtk.VTK_PYRAMID } # create cell_array. It's a one-dimensional vector with # (num_points2, p0, p1, ... ,pk, numpoints1, p10, p11, ..., p1k, ... cell_types = [] cell_offsets = [] cell_connectivity = [] len_array = 0 for meshio_type, data in cells.items(): numcells, num_local_nodes = data.shape vtk_type = meshio_to_vtk_type[meshio_type] # add cell types cell_types.append(numpy.empty(numcells, dtype=numpy.ubyte)) cell_types[-1].fill(vtk_type) # add cell offsets cell_offsets.append( numpy.arange(len_array, len_array + numcells * (num_local_nodes + 1), num_local_nodes + 1, dtype=numpy.int64)) cell_connectivity.append( numpy.c_[num_local_nodes * numpy.ones(numcells, dtype=data.dtype), data].flatten()) len_array += len(cell_connectivity[-1]) cell_types = numpy.concatenate(cell_types) cell_offsets = numpy.concatenate(cell_offsets) cell_connectivity = numpy.concatenate(cell_connectivity) connectivity = vtk.util.numpy_support.numpy_to_vtkIdTypeArray( cell_connectivity.astype(numpy.int64), deep=1) # wrap the data into a vtkCellArray cell_array = vtk.vtkCellArray() cell_array.SetCells(len(cell_types), connectivity) # Add cell data to the mesh mesh.SetCells( numpy_support.numpy_to_vtk( cell_types, deep=1, array_type=vtk.vtkUnsignedCharArray().GetDataType()), numpy_support.numpy_to_vtk( cell_offsets, deep=1, array_type=vtk.vtkIdTypeArray().GetDataType()), cell_array) return mesh
meanMFArray.InsertNextValue(meanMFValue) # Add Dach1 Array to point data maxMFArray.SetName('Max ' + factors[molecularFactor] + ' (' + str(INTERPOLATING_RADIUS) + ')') mesh.GetPointData().AddArray(maxMFArray) meanMFArray.SetName('Mean ' + factors[molecularFactor] + ' (' + str(INTERPOLATING_RADIUS) + ')') mesh.GetPointData().AddArray(meanMFArray) thresholdMFArray.SetName('Threshold ' + factors[molecularFactor] + ' (' + str(CX40THRESHOLD) + ')') mesh.GetPointData().AddArray(thresholdMFArray) # Convert TA_WSS and Pressure to micron units and new arrays to point data TA_WSS = VN.vtk_to_numpy(mesh.GetPointData().GetArray('vWSS')) TA_WSS_numpy = WSS_CONV_FACTOR * TA_WSS TA_WSS_vtk = VN.numpy_to_vtk(TA_WSS_numpy) TA_WSS_vtk.SetName('vTAWSS (dynes/cm^2)') mesh.GetPointData().AddArray(TA_WSS_vtk) pressure_avg = VN.vtk_to_numpy(mesh.GetPointData().GetArray('pressure')) pressure_numpy = pressure_avg / P_CONV_FACTOR pressure_vtk = VN.numpy_to_vtk(pressure_numpy) pressure_vtk.SetName('pressure_avg (mmHg)') mesh.GetPointData().AddArray(pressure_vtk) # Write a new .vtp file that has all converted values and mapped values. w = vtk.vtkXMLPolyDataWriter() w.SetInputData(mesh) w.SetFileName('all_results_mapped_interpolated_threshold.vtp') w.Write()
# Example of NumPy to VTK array import vtk from vtk.util.numpy_support import numpy_to_vtk import numpy numpyarray = numpy.zeros(5) vtkarray = numpy_to_vtk(numpyarray)
def to_vtk(self, file_name, data=None, binary=True): """ Export the fracture network to vtk. The fractures are treated as lines, with no special treatment of intersections. Fracture numbers are always exported (1-offset). In addition, it is possible to export additional data, as specified by the keyword-argument data. Parameters: file_name (str): Name of the target file. data (dictionary, optional): Data associated with the fractures. The values in the dictionary should be numpy arrays. 1d and 3d data is supported. Fracture numbers are always exported. binary (boolean, optional): Use binary export format. Defaults to True. """ network_vtk = vtk.vtkUnstructuredGrid() point_counter = 0 pts_vtk = vtk.vtkPoints() pts = self.pts # make points 3d if pts.shape[0] == 2: pts = np.vstack((pts, np.zeros(pts.shape[1]))) for edge in self.edges.T: # Add local points pts_vtk.InsertNextPoint(*pts[:, edge[0]]) pts_vtk.InsertNextPoint(*pts[:, edge[1]]) # Indices of local points loc_pt_id = point_counter + np.arange(2) # Update offset point_counter += 2 # Add bounding polygon frac_vtk = vtk.vtkIdList() [frac_vtk.InsertNextId(p) for p in loc_pt_id] # Close polygon frac_vtk.InsertNextId(loc_pt_id[0]) network_vtk.InsertNextCell(vtk.VTK_POLYGON, frac_vtk) # Add the points network_vtk.SetPoints(pts_vtk) writer = vtk.vtkXMLUnstructuredGridWriter() writer.SetInputData(network_vtk) writer.SetFileName(file_name) if not binary: writer.SetDataModeToAscii() # Cell-data to be exported is at least the fracture numbers if data is None: data = {} # Use offset 1 for fracture numbers (should we rather do 0?) data["Fracture_Number"] = 1 + np.arange(self.edges.shape[1]) for name, data in data.items(): data_vtk = vtk_np.numpy_to_vtk(data.ravel(order="F"), deep=True, array_type=vtk.VTK_DOUBLE) data_vtk.SetName(name) data_vtk.SetNumberOfComponents(1 if data.ndim == 1 else 3) network_vtk.GetCellData().AddArray(data_vtk) writer.Update()
def z(self, coords): """Set the coordinates along the Z-direction.""" self.SetZCoordinates(numpy_to_vtk(coords)) self._update_dimensions() self.Modified()
def strain_tensor_on_surface(pd, M, C, sigma, cl=None): """ normal and shear strain at each cell of polydata pd deformation given by momenta M, control points C and kernel width sigma cl is a centerline polydata used to define surface coord sys ## Notes: a good measure could be 'strain energy density function' that is also quite simple for hyperelastic material (https://en.wikipedia.org/wiki/Hyperelastic_material) and I can probably derive something for a fine surface W(E) = ... tr(E)**2 + ... tr(E**2) avec E Lagrangian Green strain (symetric strain) For now, I use strain/geometric changes - normal_strain = n^T . S . n (S strain tensor) - shear_strain = trace(S) - normal_stress more or less dx and dy+dz... (if x along normal) ## Inputs pd P cells M (N, D) C (N, D) sigma kernel width cl centerline polydata (use to define coord sys) ## Return pd, with new cell arrays normal_stress (P, ) shear_stress (P, ) """ # cell centers cx, cnx, cny, cnz = surface_coordinate_systems(pd, cl) # P, D # Gradient of infinitesimal displacement S = gradU_from_momenta(cx, M, C, sigma) # P, D, D # Metrics divergence = np.trace(S, axis1=1, axis2=2) cncn = np.expand_dims(cnx, 1) * np.expand_dims(cnx, 2) normal_strain = np.sum(S * cncn, axis=(1,2)) # sum( ci * cj * sij) #shear_stress = divergence - normal_stress # vtk arrays stressArray = nps.numpy_to_vtk(divergence) stressArray.SetName("Trace") pd.GetCellData().AddArray(stressArray) stressArray = nps.numpy_to_vtk(normal_strain) stressArray.SetName("NormalStrain") pd.GetCellData().AddArray(stressArray) # base change if cny is not None and cnz is not None: R = np.zeros((S.shape[0], 9)) for i in range(S.shape[0]): B = np.stack((cnx[i, :], cny[i, :], cnz[i, :]), axis=1) R[i, :] = (B.T @ S[i, :, :] @ B).flatten() strainArray = nps.numpy_to_vtk(R) strainArray.SetName("Strain") pd.GetCellData().AddArray(strainArray) else: R = None return pd, S, R
def _query_mesh(self, xlim, ylim, zlim, xtire, ytire, rtire): """Use VTK structured grid to generate query mesh. This is also the mesh of final superposition results. Args: *lim: [min, max] range for xyz directions *tire [n x 1 vec]: unique tire coordinates in x & y directions rtire [num]: tire radius to be densified Note: query mesh will include the grid points & evaluation points at all depth In VTK there are 3 types of "structured" grids: - vtkImageData (vtkUniformGrid): constant spacing & axis aligned - vtkRectilinearGrid: axis aligned & vary spacing - vtkStructuredGrid: arbitrarily located points (cells may not be valid). """ # 1. Generate densified XYZ axis coordinates spacing_sparse = rtire * cfg.SPACING_SPARSE_3D spacing_dense = rtire * cfg.SPACING_DENSE_3D xranges = np.hstack([(xtire - rtire).reshape(-1, 1), (xtire + rtire).reshape(-1, 1)]) yranges = np.hstack([(ytire - rtire).reshape(-1, 1), (ytire + rtire).reshape(-1, 1)]) xcoords = self._nonlinear_spacing(xlim, xranges, spacing_dense, spacing_sparse) ycoords = self._nonlinear_spacing(ylim, yranges, spacing_dense, spacing_sparse) # Single-layer depth points # zcoords = - (np.logspace(np.log10(-zlim[0]+1), np.log10(-zlim[1]+1), num=cfg.DEPTH_POINTS, base=10) - 1) # logspace # zcoords = np.linspace(*zlim, num=cfg.DEPTH_POINTS) # linspace # Multi-layer depth points num_layers = len(zlim) - 1 zcoord = [] self.interface = np.zeros(num_layers - 1) for l in range(num_layers - 1): zcoord.append( np.linspace(zlim[l], zlim[l + 1], num=cfg.DEPTH_LINSPACE_3D, endpoint=False)) self.interface[l] = cfg.DEPTH_LINSPACE_3D * (l + 1) zcoord.append(-np.logspace(np.log10(-zlim[-2]), np.log10(-zlim[-1]), num=cfg.DEPTH_LOGSPACE_3D, base=10, endpoint=True)) zcoords = np.concatenate(zcoord, axis=0) # 2. Generate VTK rectilinear grid grid = vtk.vtkRectilinearGrid() grid.SetDimensions(len(xcoords), len(ycoords), len(zcoords)) # initialize mesh space print("> Generating 3D mesh with {} rectilinear points".format( grid.GetNumberOfPoints())) grid.SetXCoordinates(numpy_to_vtk(xcoords)) grid.SetYCoordinates(numpy_to_vtk(ycoords)) grid.SetZCoordinates(numpy_to_vtk(zcoords)) coord = vtk.vtkPoints() grid.GetPoints(coord) self.queryMesh = grid # self.queryPoints = vtk_to_numpy(coord.GetData()) # N x 3 self.queryPoints = np.array([0, 0, 0]).reshape(-1, 3) # don't query point # query depths self.depths = np.linspace(*cfg.DEPTH, num=cfg.DEPTH_POINTS) # linspace
def __init__(self, model, T0=0, T1=200 * 3600 * 24, NS=14, NT=20 * 60 * 24): self.model = model self.mesh = model.space_mesh(n=NS) self.timeline = model.time_mesh(T0=T0, T1=T1, n=NT) self.GD = model.GD if self.GD == 2: self.vspace = RaviartThomasFiniteElementSpace2d(self.mesh, p=0) # 速度空间 elif self.GD == 3: self.vspace = RaviartThomasFiniteElementSpace3d(self.mesh, p=0) self.pspace = self.vspace.smspace # 压强和饱和度所属的空间, 分片常数 self.cspace = LagrangeFiniteElementSpace(self.mesh, p=1) # 位移空间 # 上一时刻物理量的值 self.v = self.vspace.function() # 速度函数 self.p = self.pspace.function() # 压强函数 self.s = self.pspace.function() # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0 self.u = self.cspace.function(dim=self.GD) # 位移函数 self.phi = self.pspace.function() # 孔隙度函数, 分片常数 # 当前时刻物理量的值, 用于保存临时计算出的值, 模型中系数的计算由当前时刻 # 的物理量的值决定 self.cv = self.vspace.function() # 速度函数 self.cp = self.pspace.function() # 压强函数 self.cs = self.pspace.function() # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0 self.cu = self.cspace.function(dim=self.GD) # 位移函数 self.cphi = self.pspace.function() # 孔隙度函数, 分片常数 # 初值 self.p[:] = model.rock['initial pressure'] # MPa self.phi[:] = model.rock['porosity'] # 初始孔隙度 self.cp[:] = model.rock['initial pressure'] # 初始地层压强 self.cphi[:] = model.rock['porosity'] # 当前孔隙度系数 # 源项, TODO: 注意这里假设用的是结构网格, 换其它的网格需要修改代码 self.fo = self.cspace.function() self.fo[3] = -self.model.oil['production rate'] # 产出 self.fw = self.cspace.function() self.fw[0] = self.model.water['injection rate'] # 注入 # 一些常数矩阵和向量 # 速度散度矩阵, 速度方程对应的散度矩阵, (\nabla\cdot v, w) self.B = self.vspace.div_matrix() # 压强方程对应的位移散度矩阵, (\nabla\cdot u, w) 位移散度矩阵 # * 注意这里利用了压强空间分片常数, 线性函数导数也是分片常数的事实 c = self.mesh.entity_measure('cell') c *= self.model.rock['biot'] val = self.mesh.grad_lambda() # (NC, TD+1, GD) val *= c[:, None, None] pc2d = self.pspace.cell_to_dof() cc2d = self.cspace.cell_to_dof() pgdof = self.pspace.number_of_global_dofs() cgdof = self.cspace.number_of_global_dofs() I = np.broadcast_to(pc2d, shape=cc2d.shape) J = cc2d self.PU0 = csr_matrix((val[..., 0].flat, (I.flat, J.flat)), shape=(pgdof, cgdof)) self.PU1 = csr_matrix((val[..., 1].flat, (I.flat, J.flat)), shape=(pgdof, cgdof)) if self.GD == 3: self.PU2 = csr_matrix((val[..., 2].flat, (I.flat, J.flat)), shape=(pgdof, cgdof)) # 线弹性矩阵的右端向量 sigma0 = self.pspace.function() sigma0[:] = self.model.rock['initial stress'] self.FU = np.zeros(self.GD * cgdof, dtype=np.float64) self.FU[0 * cgdof:1 * cgdof] -= self.p @ self.PU0 self.FU[1 * cgdof:2 * cgdof] -= self.p @ self.PU1 if self.GD == 3: self.FU[2 * cgdof:3 * cgdof] -= self.p @ self.PU2 # 初始应力和等效应力项 self.FU[0 * cgdof:1 * cgdof] -= sigma0 @ self.PU0 self.FU[1 * cgdof:2 * cgdof] -= sigma0 @ self.PU1 if self.GD == 3: self.FU[2 * cgdof:3 * cgdof] -= sigma0 @ self.PU2 self.isFCell = model.is_fracture_cell(self.mesh) # vtk 文件输出 node, cell, cellType, NC = self.mesh.to_vtk() self.points = vtk.vtkPoints() self.points.SetData(vnp.numpy_to_vtk(node)) self.cells = vtk.vtkCellArray() self.cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell)) self.cellType = cellType
def save_vtk_streamlines(streamlines, filename, to_lps=True, binary=False): """Save streamlines as vtk polydata to a supported format file. File formats can be VTK, FIB Parameters ---------- streamlines : list list of 2D arrays or ArraySequence filename : string output filename (.vtk or .fib) to_lps : bool Default to True, will follow the vtk file convention for streamlines Will be supported by MITKDiffusion and MI-Brain binary : bool save the file as binary """ if to_lps: # ras (mm) to lps (mm) to_lps = np.eye(4) to_lps[0, 0] = -1 to_lps[1, 1] = -1 streamlines = transform_streamlines(streamlines, to_lps) # Get the 3d points_array nb_lines = len(streamlines) points_array = np.vstack(streamlines) # Get lines_array in vtk input format lines_array = [] current_position = 0 for i in range(nb_lines): current_len = len(streamlines[i]) end_position = current_position + current_len lines_array.append(current_len) lines_array.extend(range(current_position, end_position)) current_position = end_position # Set Points to vtk array format vtk_points = vtk.vtkPoints() vtk_points.SetData( ns.numpy_to_vtk(points_array.astype(np.float32), deep=True)) # Set Lines to vtk array format vtk_lines = vtk.vtkCellArray() vtk_lines.SetNumberOfCells(nb_lines) vtk_lines.GetData().DeepCopy( ns.numpy_to_vtk(np.array(lines_array), deep=True)) # Create the poly_data polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetLines(vtk_lines) writer = vtk.vtkPolyDataWriter() writer.SetFileName(filename) writer = utils.set_input(writer, polydata) if binary: writer.SetFileTypeToBinary() writer.Update() writer.Write()
if norm_value == 0: case2 = full((nvalues), 1.0 - min_value, dtype='float32') else: case2 = 1.0 - (case - min_value) / norm_value else: if norm_value == 0: case2 = full((nvalues), min_value, dtype='float32') else: case2 = (case - min_value) / norm_value if case.flags.contiguous: case2 = case else: case2 = deepcopy(case) grid_result = numpy_to_vtk(num_array=case2, deep=True, array_type=data_type) #print('grid_result = %s' % grid_result) #print('max2 =', grid_result.GetRange()) else: # vector_size=3 if case.flags.contiguous: case2 = case else: case2 = deepcopy(case) grid_result = numpy_to_vtk(num_array=case2, deep=True, array_type=data_type) return grid_result def update_grid_by_icase_scale_phase(self, icase, scale, phase=0.0):
def SET_LINE_DATA(self, Surface, Line_avg): Surface_avg = numpy_to_vtk(Line_avg, deep=True) Surface_avg.SetName("%s_Projected" % self.Args.ArrayName) Surface.GetPointData().AddArray(Surface_avg) Surface.Modified() return Surface
def execute(self): res = self.input("in") #get primary variable.. #need to ensure that results that go back to VisIt #are at least correct size.. varr = self.context.mesh.GetCellData().GetArray( self.context.primary_var) if varr is None: varr = self.context.mesh.GetPointData().GetArray( self.context.primary_var) if res is None: return self.context.mesh if isinstance(res, vtk.vtkDataSet): return res if isinstance(res, npy.ndarray): res = npy.ascontiguousarray(res) res = vnp.numpy_to_vtk(res) if not isinstance(res, vtk.vtkDataArray): if isinstance(res, npy.ndarray) or isinstance(res, (list, tuple)): np_tmp = npy.ascontiguousarray(res) else: np_tmp = npy.ascontiguousarray([res]) #ensure 1 dimension before putting it in vtk.. np_tmp = npy.ravel(np_tmp) #pad with zeros if incorrect size.. if varr is not None and varr.GetDataSize() > len(np_tmp): np_tmp = npy.pad(np_tmp, (0, len(np_tmp) - var.GetDataSize()), 'constant') res = vnp.numpy_to_vtk(np_tmp) #if isinstance(res,npy.ndarray): # # create # vdata = vtk.vtkFloatArray() # vdata.SetNumberOfComponents(1) # vdata.SetNumberOfTuples(res.shape[0]) # npo = vnp.vtk_to_numpy(vdata) # npo[:] = res # res = vdata if isinstance(res, vtk.vtkDataArray): res.SetName(self.context.primary_var) rset = self.context.mesh.NewInstance() rset.ShallowCopy(self.context.mesh) #only handles scalar data right now. TODO: add more support vtk_data = rset.GetCellData().GetScalars(self.context.primary_var) if vtk_data: rset.GetCellData().RemoveArray(self.context.primary_var) rset.GetCellData().AddArray(res) rset.GetCellData().SetScalars(res) else: rset.GetPointData().RemoveArray(self.context.primary_var) rset.GetPointData().AddArray(res) rset.GetPointData().SetScalars(res) else: #should not get here.. rset = res return rset
def to_vtk(bdf): # type: (BDF) -> VTKData import vtk # TODO: use pynastran numpy_to_vtk from vtk.util.numpy_support import numpy_to_vtk if bdf: nid_list = [] nid_dict = {} node_pos = np.empty((len(bdf.nodes), 3), dtype=np.float64) i = 0 for node in itervalues(bdf.nodes): node_pos[i] = node.get_position() nid = node.nid nid_list.append(nid) nid_dict[nid] = i i += 1 _points = vtk.vtkPoints() _points.SetData(numpy_to_vtk(node_pos)) points = vtk.vtkPoints() points.DeepCopy(_points) cells = [] cell_types = [] cell_count = 0 elem_types = [] eid_list = [] eid_dict = {} _nastran_to_vtk = nastran_to_vtk bdf_data_to_plot = chain(itervalues(bdf.nodes), itervalues(bdf.elements), itervalues(bdf.rigid_elements)) category_list = [] for elem in bdf_data_to_plot: elem_type = elem.type cell_type, add_method, category = _nastran_to_vtk.get( elem_type, (None, None, None)) if cell_type is None: continue cell_types.append(cell_type) elem_types.append(elem_type) eid = add_method(elem, cells, nid_dict) # returns element/grid id eid_list.append(eid) eid_dict[eid] = cell_count category_list.append(categories[category]) cell_count += 1 cells = np.array(cells, dtype=np.int64) id_array = vtk.vtkIdTypeArray() id_array.SetVoidArray(cells, len(cells), 1) vtk_cells = vtk.vtkCellArray() vtk_cells.SetCells(cell_count, id_array) cell_types = np.array(cell_types, 'B') vtk_cell_types = numpy_to_vtk(cell_types) cell_locations = np.array([i for i in range(cell_count)]) vtk_cell_locations = numpy_to_vtk(cell_locations, deep=1, array_type=vtk.VTK_ID_TYPE) ugrid = vtk.vtkUnstructuredGrid() ugrid.SetPoints(points) ugrid.SetCells(vtk_cell_types, vtk_cell_locations, vtk_cells) vtk_cell_locations.SetName('index') ugrid.GetCellData().AddArray(vtk_cell_locations) _elem_types = vtk.vtkStringArray() _elem_types.SetName('element_type') _elem_types.SetNumberOfValues(len(elem_types)) for i in range(len(elem_types)): _elem_types.SetValue(i, elem_types[i]) ugrid.GetCellData().AddArray(_elem_types) _cat_arr = np.array(category_list, dtype=np.int64) _cat = vtk.vtkIdTypeArray() _cat.SetNumberOfValues(len(category_list)) _cat.SetVoidArray(_cat_arr, len(_cat_arr), 1) _cat.SetName('category') ugrid.GetCellData().AddArray(_cat) id_array = numpy_to_vtk(np.array(eid_list), deep=1, array_type=vtk.VTK_ID_TYPE) # id_array = vtk.vtkIdTypeArray() # id_array.SetVoidArray(eid_list, len(eid_list), 1) id_array.SetName('element_id') ugrid.GetCellData().AddArray(id_array) copy = vtk.vtkUnstructuredGrid() copy.DeepCopy(ugrid) vtk_data = VTKData(copy, nid_list, nid_dict, eid_list, eid_dict) return vtk_data
def numpy_to_vtk_cells(data, is_coords=True): """Convert numpy array to a vtk cell array. Parameters ---------- data : ndarray points coordinate or connectivity array (e.g triangles). is_coords : ndarray Select the type of array. default: True. Returns ------- vtk_cell : vtkCellArray connectivity + offset information """ data = np.array(data, dtype=object) nb_cells = len(data) # Get lines_array in vtk input format connectivity = data.flatten() if not is_coords else [] offset = [ 0, ] current_position = 0 cell_array = vtk.vtkCellArray() if vtk.vtkVersion.GetVTKMajorVersion() >= 9: for i in range(nb_cells): current_len = len(data[i]) offset.append(offset[-1] + current_len) if is_coords: end_position = current_position + current_len connectivity += list(range(current_position, end_position)) current_position = end_position connectivity = np.array(connectivity, np.intp) offset = np.array(offset, dtype=connectivity.dtype) vtk_array_type = numpy_support.get_vtk_array_type(connectivity.dtype) cell_array.SetData( numpy_support.numpy_to_vtk(offset, deep=True, array_type=vtk_array_type), numpy_support.numpy_to_vtk(connectivity, deep=True, array_type=vtk_array_type)) else: for i in range(nb_cells): current_len = len(data[i]) end_position = current_position + current_len connectivity += [current_len] connectivity += list(range(current_position, end_position)) current_position = end_position connectivity = np.array(connectivity) cell_array.GetData().DeepCopy(numpy_support.numpy_to_vtk(connectivity)) cell_array.SetNumberOfCells(nb_cells) return cell_array
dims = textImage.GetDimensions() print(dims) nxy = max(dims) if 0: arr = np.zeros((nxy, nxy, 4), dtype=np.uint8) arr0 = numpy_support.vtk_to_numpy( textImage.GetPointData().GetScalars()) arr0 = arr0.reshape(dims[1], dims[0], -1) offset0 = (nxy - dims[1]) // 2 offset1 = (nxy - dims[0]) // 2 arr[offset0:nxy - offset0, offset1:nxy - offset1, :] = arr0 colors = numpy_support.numpy_to_vtk( arr.ravel(), deep=False, array_type=vtk.VTK_UNSIGNED_CHAR) newImage = vtk.vtkImageData() newImage.SetDimensions(nxy, nxy, 1) colors.SetNumberOfComponents(4) colors.SetNumberOfTuples(newImage.GetNumberOfPoints()) newImage.GetPointData().SetScalars(colors) else: padFilter = vtk.vtkImageConstantPad() curExtent = textImage.GetExtent() curDims = textImage.GetDimensions() padExtent = np.r_[nxy, nxy, 1] - np.array(curDims) newExtent = (curExtent[0] - (padExtent[0] + 1) // 2, curExtent[1] + padExtent[0] // 2, curExtent[2] - (padExtent[1] + 1) // 2,
def AppendScalarData(self,name,numpy_array): #* Append scalar cell data (numpy array) into vtk object data = ns.numpy_to_vtk(numpy_array.ravel(order='F'),deep=True, array_type=vtk.VTK_FLOAT) data.SetName(str(name)) data.SetNumberOfComponents(1) self.VTK_Grids.GetCellData().AddArray(data)
def lines_to_vtk_polydata(lines, colors=None): """Create a vtkPolyData with lines and colors. Parameters ---------- lines : list list of N curves represented as 2D ndarrays colors : array (N, 3), list of arrays, tuple (3,), array (K,) If None or False, a standard orientation colormap is used for every line. If one tuple of color is used. Then all streamlines will have the same colour. If an array (N, 3) is given, where N is equal to the number of lines. Then every line is coloured with a different RGB color. If a list of RGB arrays is given then every point of every line takes a different color. If an array (K, 3) is given, where K is the number of points of all lines then every point is colored with a different RGB color. If an array (K,) is given, where K is the number of points of all lines then these are considered as the values to be used by the colormap. If an array (L,) is given, where L is the number of streamlines then these are considered as the values to be used by the colormap per streamline. If an array (X, Y, Z) or (X, Y, Z, 3) is given then the values for the colormap are interpolated automatically using trilinear interpolation. Returns ------- poly_data : vtkPolyData color_is_scalar : bool, true if the color array is a single scalar Scalar array could be used with a colormap lut None if no color was used """ # Get the 3d points_array points_array = np.vstack(lines) # Set Points to vtk array format vtk_points = numpy_to_vtk_points(points_array) # Set Lines to vtk array format vtk_cell_array = numpy_to_vtk_cells(lines) # Create the poly_data poly_data = vtk.vtkPolyData() poly_data.SetPoints(vtk_points) poly_data.SetLines(vtk_cell_array) # Get colors_array (reformat to have colors for each points) # - if/else tested and work in normal simple case nb_points = len(points_array) nb_lines = len(lines) lines_range = range(nb_lines) points_per_line = [len(lines[i]) for i in lines_range] points_per_line = np.array(points_per_line, np.intp) color_is_scalar = False if colors is None or colors is False: # set automatic rgb colors cols_arr = line_colors(lines) colors_mapper = np.repeat(lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors(255 * cols_arr[colors_mapper]) else: cols_arr = np.asarray(colors) if cols_arr.dtype == object: # colors is a list of colors vtk_colors = numpy_to_vtk_colors(255 * np.vstack(colors)) else: if len(cols_arr) == nb_points: if cols_arr.ndim == 1: # values for every point vtk_colors = numpy_support.numpy_to_vtk(cols_arr, deep=True) color_is_scalar = True elif cols_arr.ndim == 2: # map color to each point vtk_colors = numpy_to_vtk_colors(255 * cols_arr) elif cols_arr.ndim == 1: if len(cols_arr) == nb_lines: # values for every streamline cols_arrx = [] for (i, value) in enumerate(colors): cols_arrx += lines[i].shape[0] * [value] cols_arrx = np.array(cols_arrx) vtk_colors = numpy_support.numpy_to_vtk(cols_arrx, deep=True) color_is_scalar = True else: # the same colors for all points vtk_colors = numpy_to_vtk_colors( np.tile(255 * cols_arr, (nb_points, 1))) elif cols_arr.ndim == 2: # map color to each line colors_mapper = np.repeat(lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors(255 * cols_arr[colors_mapper]) else: # colormap # get colors for each vertex cols_arr = map_coordinates_3d_4d(cols_arr, points_array) vtk_colors = numpy_support.numpy_to_vtk(cols_arr, deep=True) color_is_scalar = True vtk_colors.SetName("colors") poly_data.GetPointData().SetScalars(vtk_colors) return poly_data, color_is_scalar
def _cell_derivatives(narray, dataset, attribute_type, filter): if not dataset: raise RuntimeError, 'Need a dataset to compute _cell_derivatives.' # Reshape n dimensional vector to n by 1 matrix if len(narray.shape) == 1: narray = narray.reshape((narray.shape[0], 1)) ncomp = narray.shape[1] if attribute_type == 'scalars' and ncomp != 1: raise RuntimeError, 'This function expects scalars.'\ 'Input shape ' + narray.shape if attribute_type == 'vectors' and ncomp != 3: raise RuntimeError, 'This function expects vectors.'\ 'Input shape ' + narray.shape # numpy_to_vtk converts only contiguous arrays if not narray.flags.contiguous: narray = narray.copy() varray = numpy_support.numpy_to_vtk(narray) if attribute_type == 'scalars': varray.SetName('scalars') else: varray.SetName('vectors') # create a dataset with only our array but the same geometry/topology ds = dataset.NewInstance() ds.UnRegister(None) ds.CopyStructure(dataset.VTKObject) if dsa.ArrayAssociation.FIELD == narray.Association: raise RuntimeError, 'Unknown data association. Data should be associated with points or cells.' if dsa.ArrayAssociation.POINT == narray.Association: # Work on point data if narray.shape[0] != dataset.GetNumberOfPoints(): raise RuntimeError, 'The number of points does not match the number of tuples in the array' if attribute_type == 'scalars': ds.GetPointData().SetScalars(varray) else: ds.GetPointData().SetVectors(varray) elif dsa.ArrayAssociation.CELL == narray.Association: # Work on cell data if narray.shape[0] != dataset.GetNumberOfCells(): raise RuntimeError, 'The number of does not match the number of tuples in the array' # Since vtkCellDerivatives only works with point data, we need to convert # the cell data to point data first. ds2 = dataset.NewInstance() ds2.UnRegister(None) ds2.CopyStructure(dataset.VTKObject) if attribute_type == 'scalars': ds2.GetCellData().SetScalars(varray) else: ds2.GetCellData().SetVectors(varray) c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(ds2) c2p.Update() # Set the output to the ds dataset if attribute_type == 'scalars': ds.GetPointData().SetScalars( c2p.GetOutput().GetPointData().GetScalars()) else: ds.GetPointData().SetVectors( c2p.GetOutput().GetPointData().GetVectors()) filter.SetInputData(ds) if dsa.ArrayAssociation.POINT == narray.Association: # Since the data is associated with cell and the query is on points # we have to convert to point data before returning c2p = vtk.vtkCellDataToPointData() c2p.SetInputConnection(filter.GetOutputPort()) c2p.Update() return c2p.GetOutput().GetPointData() elif dsa.ArrayAssociation.CELL == narray.Association: filter.Update() return filter.GetOutput().GetCellData() else: # We shall never reach here raise RuntimeError, 'Unknown data association. Data should be associated with points or cells.'
def _from_arrays(self, offset, cells, cell_type, points, deep=True): """Create VTK unstructured grid from numpy arrays. Parameters ---------- offset : np.ndarray dtype=np.int64 Array indicating the start location of each cell in the cells array. Set to ``None`` when using VTK 9+. cells : np.ndarray dtype=np.int64 Array of cells. Each cell contains the number of points in the cell and the node numbers of the cell. cell_type : np.uint8 Cell types of each cell. Each cell type numbers can be found from vtk documentation. See example below. points : np.ndarray Numpy array containing point locations. Examples -------- >>> import numpy >>> import vtk >>> import pyvista >>> offset = np.array([0, 9]) >>> cells = np.array([8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15]) >>> cell_type = np.array([vtk.VTK_HEXAHEDRON, vtk.VTK_HEXAHEDRON], np.int8) >>> cell1 = np.array([[0, 0, 0], ... [1, 0, 0], ... [1, 1, 0], ... [0, 1, 0], ... [0, 0, 1], ... [1, 0, 1], ... [1, 1, 1], ... [0, 1, 1]]) >>> cell2 = np.array([[0, 0, 2], ... [1, 0, 2], ... [1, 1, 2], ... [0, 1, 2], ... [0, 0, 3], ... [1, 0, 3], ... [1, 1, 3], ... [0, 1, 3]]) >>> points = np.vstack((cell1, cell2)) >>> grid = pyvista.UnstructuredGrid(offset, cells, cell_type, points) """ # Convert to vtk arrays vtkcells = CellArray(cells, cell_type.size, deep) if cell_type.dtype != np.uint8: cell_type = cell_type.astype(np.uint8) cell_type_np = cell_type cell_type = numpy_to_vtk(cell_type, deep=deep) # Convert points to vtkPoints object points = pyvista.vtk_points(points, deep=deep) self.SetPoints(points) # vtk9 does not require an offset array if VTK9: if offset is not None: warnings.warn('VTK 9 no longer accepts an offset array', stacklevel=3) self.SetCells(cell_type, vtkcells) else: if offset is None: offset = generate_cell_offsets(cells, cell_type_np) self.SetCells(cell_type, numpy_to_idarr(offset), vtkcells)
def repeat_sources(centers, colors, active_scalars=1., directions=None, source=None, vertices=None, faces=None): """Transform a vtksource to glyph. """ if source is None and faces is None: raise IOError("A source or faces should be defined") if np.array(colors).ndim == 1: colors = np.tile(colors, (len(centers), 1)) pts = numpy_to_vtk_points(np.ascontiguousarray(centers)) cols = numpy_to_vtk_colors(255 * np.ascontiguousarray(colors)) cols.SetName('colors') if isinstance(active_scalars, (float, int)): active_scalars = np.tile(active_scalars, (len(centers), 1)) if isinstance(active_scalars, np.ndarray): ascalars = numpy_support.numpy_to_vtk(np.asarray(active_scalars), deep=True, array_type=vtk.VTK_DOUBLE) ascalars.SetName('active_scalars') if directions is not None: directions_fa = numpy_support.numpy_to_vtk(np.asarray(directions), deep=True, array_type=vtk.VTK_DOUBLE) directions_fa.SetName('directions') polydata_centers = vtk.vtkPolyData() polydata_geom = vtk.vtkPolyData() if faces is not None: set_polydata_vertices(polydata_geom, vertices.astype(np.int8)) set_polydata_triangles(polydata_geom, faces) polydata_centers.SetPoints(pts) polydata_centers.GetPointData().AddArray(cols) if directions is not None: polydata_centers.GetPointData().AddArray(directions_fa) polydata_centers.GetPointData().SetActiveVectors('directions') if isinstance(active_scalars, np.ndarray): polydata_centers.GetPointData().AddArray(ascalars) polydata_centers.GetPointData().SetActiveScalars('active_scalars') glyph = vtk.vtkGlyph3D() if faces is None: glyph.SetSourceConnection(source.GetOutputPort()) else: glyph.SetSourceData(polydata_geom) glyph.SetInputData(polydata_centers) glyph.SetOrient(True) glyph.SetScaleModeToScaleByScalar() glyph.SetVectorModeToUseVector() glyph.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(glyph.GetOutput()) mapper.SetScalarModeToUsePointFieldData() mapper.SelectColorArray('colors') actor = vtk.vtkActor() actor.SetMapper(mapper) return actor
def numpy_to_vtk_points(points): vtk_points = vtk.vtkPoints() vtk_points.SetData(ns.numpy_to_vtk(np.asarray(points), deep=True)) return vtk_points
def linear_copy(self, deep=False): """Return a copy of the unstructured grid containing only linear cells. Converts the following cell types to their linear equivalents. - VTK_QUADRATIC_TETRA --> VTK_TETRA - VTK_QUADRATIC_PYRAMID --> VTK_PYRAMID - VTK_QUADRATIC_WEDGE --> VTK_WEDGE - VTK_QUADRATIC_HEXAHEDRON --> VTK_HEXAHEDRON Parameters ---------- deep : bool When True, makes a copy of the points array. Default False. Cells and cell types are always copied. Return ------ grid : pyvista.UnstructuredGrid UnstructuredGrid containing only linear cells. """ lgrid = self.copy(deep) # grab the vtk object vtk_cell_type = numpy_to_vtk(self.GetCellTypesArray(), deep=True) celltype = vtk_to_numpy(vtk_cell_type) celltype[celltype == VTK_QUADRATIC_TETRA] = VTK_TETRA celltype[celltype == VTK_QUADRATIC_PYRAMID] = VTK_PYRAMID celltype[celltype == VTK_QUADRATIC_WEDGE] = VTK_WEDGE celltype[celltype == VTK_QUADRATIC_HEXAHEDRON] = VTK_HEXAHEDRON # track quad mask for later quad_quad_mask = celltype == VTK_QUADRATIC_QUAD celltype[quad_quad_mask] = VTK_QUAD quad_tri_mask = celltype == VTK_QUADRATIC_TRIANGLE celltype[quad_tri_mask] = VTK_TRIANGLE vtk_offset = self.GetCellLocationsArray() cells = vtk.vtkCellArray() cells.DeepCopy(self.GetCells()) lgrid.SetCells(vtk_cell_type, vtk_offset, cells) # fixing bug with display of quad cells if np.any(quad_quad_mask): if VTK9: quad_offset = lgrid.offset[:-1][quad_quad_mask] base_point = lgrid.cell_connectivity[quad_offset] lgrid.cell_connectivity[quad_offset + 4] = base_point lgrid.cell_connectivity[quad_offset + 5] = base_point lgrid.cell_connectivity[quad_offset + 6] = base_point lgrid.cell_connectivity[quad_offset + 7] = base_point else: quad_offset = lgrid.offset[quad_quad_mask] base_point = lgrid.cells[quad_offset + 1] lgrid.cells[quad_offset + 5] = base_point lgrid.cells[quad_offset + 6] = base_point lgrid.cells[quad_offset + 7] = base_point lgrid.cells[quad_offset + 8] = base_point if np.any(quad_tri_mask): if VTK9: tri_offset = lgrid.offset[:-1][quad_tri_mask] base_point = lgrid.cell_connectivity[tri_offset] lgrid.cell_connectivity[tri_offset + 3] = base_point lgrid.cell_connectivity[tri_offset + 4] = base_point lgrid.cell_connectivity[tri_offset + 5] = base_point else: tri_offset = lgrid.offset[quad_tri_mask] base_point = lgrid.cells[tri_offset + 1] lgrid.cells[tri_offset + 4] = base_point lgrid.cells[tri_offset + 5] = base_point lgrid.cells[tri_offset + 6] = base_point return lgrid
def __init__( self, inputobj=None, c=('r', 'y', 'lg', 'lb', 'b'), #('b','lb','lg','y','r') alpha=(0.0, 0.0, 0.5, 0.8, 1.0), alphaGradient=None, alphaUnit=1, mode=0, spacing=None, dims=None, origin=None, mapper='smart', ): vtk.vtkVolume.__init__(self) BaseGrid.__init__(self) ################### if isinstance(inputobj, str): if "https://" in inputobj: from vedo.io import download inputobj = download(inputobj) # fpath else: inputobj = sorted(glob.glob(inputobj)) ################### inputtype = str(type(inputobj)) #colors.printc('Volume inputtype', inputtype) if inputobj is None: img = vtk.vtkImageData() elif utils.isSequence(inputobj): if isinstance(inputobj[0], str): # scan sequence of BMP files ima = vtk.vtkImageAppend() ima.SetAppendAxis(2) pb = utils.ProgressBar(0, len(inputobj)) for i in pb.range(): f = inputobj[i] picr = vtk.vtkBMPReader() picr.SetFileName(f) picr.Update() mgf = vtk.vtkImageMagnitude() mgf.SetInputData(picr.GetOutput()) mgf.Update() ima.AddInputData(mgf.GetOutput()) pb.print('loading...') ima.Update() img = ima.GetOutput() else: if "ndarray" not in inputtype: inputobj = np.array(inputobj) if len(inputobj.shape) == 1: varr = numpy_to_vtk(inputobj, deep=True, array_type=vtk.VTK_FLOAT) else: if len(inputobj.shape) > 2: inputobj = np.transpose(inputobj, axes=[2, 1, 0]) varr = numpy_to_vtk(inputobj.ravel(order='F'), deep=True, array_type=vtk.VTK_FLOAT) varr.SetName('input_scalars') img = vtk.vtkImageData() if dims is not None: img.SetDimensions(dims) else: if len(inputobj.shape) == 1: colors.printc( "Error: must set dimensions (dims keyword) in Volume.", c=1) raise RuntimeError() img.SetDimensions(inputobj.shape) img.GetPointData().SetScalars(varr) #to convert rgb to numpy # img_scalar = data.GetPointData().GetScalars() # dims = data.GetDimensions() # n_comp = img_scalar.GetNumberOfComponents() # temp = numpy_support.vtk_to_numpy(img_scalar) # numpy_data = temp.reshape(dims[1],dims[0],n_comp) # numpy_data = numpy_data.transpose(0,1,2) # numpy_data = np.flipud(numpy_data) elif "ImageData" in inputtype: img = inputobj elif "UniformGrid" in inputtype: img = inputobj elif hasattr( inputobj, "GetOutput"): # passing vtk object, try extract imagdedata if hasattr(inputobj, "Update"): inputobj.Update() img = inputobj.GetOutput() elif isinstance(inputobj, str): from vedo.io import loadImageData img = loadImageData(inputobj) else: colors.printc("Volume(): cannot understand input type:\n", inputtype, c=1) return ################### if 'gpu' in mapper: self._mapper = vtk.vtkGPUVolumeRayCastMapper() elif 'opengl_gpu' in mapper: self._mapper = vtk.vtkOpenGLGPUVolumeRayCastMapper() elif 'smart' in mapper: self._mapper = vtk.vtkSmartVolumeMapper() elif 'fixed' in mapper: self._mapper = vtk.vtkFixedPointVolumeRayCastMapper() elif isinstance(mapper, vtk.vtkMapper): self._mapper = mapper else: print("Error unknown mapper type", [mapper]) raise RuntimeError() if dims is not None: img.SetDimensions(dims) if origin is not None: img.SetOrigin(origin) ### DIFFERENT from volume.origin()! if spacing is not None: img.SetSpacing(spacing) self._data = img self._mapper.SetInputData(img) self.SetMapper(self._mapper) self.mode(mode).color(c).alpha(alpha).alphaGradient(alphaGradient) self.GetProperty().SetInterpolationType(1) self.GetProperty().SetScalarOpacityUnitDistance(alphaUnit) # remember stuff: self._mode = mode self._color = c self._alpha = alpha self._alphaGrad = alphaGradient self._alphaUnit = alphaUnit
def buildPolyData(vertices, faces=None, lines=None, indexOffset=0, fast=True): """ Build a ``vtkPolyData`` object from a list of vertices where faces represents the connectivity of the polygonal mesh. E.g. : - ``vertices=[[x1,y1,z1],[x2,y2,z2], ...]`` - ``faces=[[0,1,2], [1,2,3], ...]`` Use ``indexOffset=1`` if face numbering starts from 1 instead of 0. if fast=False the mesh is built "manually" by setting polygons and triangles one by one. This is the fallback case when a mesh contains faces of different number of vertices. """ if len(vertices[0]) < 3: # make sure it is 3d vertices = np.c_[np.array(vertices), np.zeros(len(vertices))] if len(vertices[0]) == 2: vertices = np.c_[np.array(vertices), np.zeros(len(vertices))] poly = vtk.vtkPolyData() sourcePoints = vtk.vtkPoints() sourcePoints.SetData( numpy_to_vtk(np.ascontiguousarray(vertices), deep=True)) poly.SetPoints(sourcePoints) if lines is not None: # Create a cell array to store the lines in and add the lines to it linesarr = vtk.vtkCellArray() for i in range(1, len(lines) - 1): vline = vtk.vtkLine() vline.GetPointIds().SetId(0, lines[i]) vline.GetPointIds().SetId(1, lines[i + 1]) linesarr.InsertNextCell(vline) poly.SetLines(linesarr) if faces is None: sourceVertices = vtk.vtkCellArray() for i in range(len(vertices)): sourceVertices.InsertNextCell(1) sourceVertices.InsertCellPoint(i) poly.SetVerts(sourceVertices) return poly ################### # faces exist sourcePolygons = vtk.vtkCellArray() faces = np.array(faces) if len(faces.shape) == 2 and indexOffset == 0 and fast: #################### all faces are composed of equal nr of vtxs, FAST ast = np.int32 if vtk.vtkIdTypeArray().GetDataTypeSize() != 4: ast = np.int64 nf, nc = faces.shape hs = np.hstack((np.zeros(nf)[:, None] + nc, faces)).astype(ast).ravel() arr = numpy_to_vtkIdTypeArray(hs, deep=True) sourcePolygons.SetCells(nf, arr) else: ########################################## manually add faces, SLOW showbar = False if len(faces) > 25000: showbar = True pb = ProgressBar(0, len(faces), ETA=False) for f in faces: n = len(f) if n == 3: ele = vtk.vtkTriangle() pids = ele.GetPointIds() for i in range(3): pids.SetId(i, f[i] - indexOffset) sourcePolygons.InsertNextCell(ele) elif n == 4: # do not use vtkTetra() because it fails # with dolfin faces orientation ele0 = vtk.vtkTriangle() ele1 = vtk.vtkTriangle() ele2 = vtk.vtkTriangle() ele3 = vtk.vtkTriangle() if indexOffset: for i in [0, 1, 2, 3]: f[i] -= indexOffset f0, f1, f2, f3 = f pid0 = ele0.GetPointIds() pid1 = ele1.GetPointIds() pid2 = ele2.GetPointIds() pid3 = ele3.GetPointIds() pid0.SetId(0, f0) pid0.SetId(1, f1) pid0.SetId(2, f2) pid1.SetId(0, f0) pid1.SetId(1, f1) pid1.SetId(2, f3) pid2.SetId(0, f1) pid2.SetId(1, f2) pid2.SetId(2, f3) pid3.SetId(0, f2) pid3.SetId(1, f3) pid3.SetId(2, f0) sourcePolygons.InsertNextCell(ele0) sourcePolygons.InsertNextCell(ele1) sourcePolygons.InsertNextCell(ele2) sourcePolygons.InsertNextCell(ele3) else: ele = vtk.vtkPolygon() pids = ele.GetPointIds() pids.SetNumberOfIds(n) for i in range(n): pids.SetId(i, f[i] - indexOffset) sourcePolygons.InsertNextCell(ele) if showbar: pb.print("converting mesh... ") poly.SetPolys(sourcePolygons) return poly
def __init__(self, data_numpy, name=None): self._numpy = data_numpy self._vtk = numpy_support.numpy_to_vtk(data_numpy) if name is not None: self._vtk.SetName(name)
def processPartition(idx, iterator): print('==============> processPartition %d' % idx) import os os.environ["PMI_PORT"] = pmi_port os.environ["PMI_ID"] = str(idx) os.environ["PV_ALLOW_BATCH_INTERACTION"] = "1" os.environ["DISPLAY"] = ":0" import paraview paraview.options.batch = True from vtk.vtkCommonExecutionModel import vtkTrivialProducer from vtk.vtkPVVTKExtensionsCore import vtkDistributedTrivialProducer from vtk.vtkCommonCore import vtkIntArray, vtkUnsignedCharArray from vtk.vtkCommonDataModel import vtkImageData, vtkPointData, vtkCellData iOffset = 0 for i in range(idx): iOffset += xSizes[i] size = xSizes[idx] * sizeY * sizeZ # ------------------------------------------------------------------------- # Gather data chunk # ------------------------------------------------------------------------- dataChunk = vtkIntArray() dataChunk.SetName('scalar') dataChunk.SetNumberOfTuples(size) dataChunk.Fill(0) print('%d # Reserve chunk size (%d, %d, %d) - size: %d ' % (idx, xSizes[idx], sizeY, sizeZ, size)) count = 0 for row in iterator: count += 1 coords = idxToCoord(row[0]) originCoords = '[%d, %d, %d]' % (coords[0], coords[1], coords[2]) coords[0] -= iOffset destIdx = coords[0] + (coords[1] * xSizes[idx]) + (coords[2] * xSizes[idx] * sizeY) if destIdx < 0 or destIdx > size: print('(%d) %d => %s | (%d, %d, %d) => %d | [%d, %d, %d]' % (idx, row[0], originCoords, coords[0], coords[1], coords[2], destIdx, xSizes[idx], sizeY, sizeZ)) else: dataChunk.SetValue(destIdx, row[1]) print('%d # Data chunk filled (%d, %d, %d) - size: %d - filled: %d' % (idx, xSizes[idx], sizeY, sizeZ, size, count)) # ------------------------------------------------------------------------- # Reshape data into 3D Fortran array ordering # ------------------------------------------------------------------------- npDataChunk = numpy_support.vtk_to_numpy(dataChunk) scalars_array3d = np.reshape(npDataChunk, (xSizes[idx], sizeY, sizeZ), order='F') print('%d # Data chunk reshaped' % idx) # ------------------------------------------------------------------------- # Reconstruction helper # ------------------------------------------------------------------------- def parallelRay(Nside, pixelWidth, angles, Nray, rayWidth): # Suppress warning messages that pops up when dividing zeros np.seterr(all='ignore') Nproj = len(angles) # Number of projections # Ray coordinates at 0 degrees. offsets = np.linspace(-(Nray * 1.0 - 1) / 2, (Nray * 1.0 - 1) / 2, Nray) * rayWidth # Intersection lines/grid Coordinates xgrid = np.linspace(-Nside * 0.5, Nside * 0.5, Nside + 1) * pixelWidth ygrid = np.linspace(-Nside * 0.5, Nside * 0.5, Nside + 1) * pixelWidth # Initialize vectors that contain matrix elements and corresponding # row/column numbers rows = np.zeros(2 * Nside * Nproj * Nray) cols = np.zeros(2 * Nside * Nproj * Nray) vals = np.zeros(2 * Nside * Nproj * Nray) idxend = 0 for i in range(0, Nproj): # Loop over projection angles ang = angles[i] * np.pi / 180. # Points passed by rays at current angles xrayRotated = np.cos(ang) * offsets yrayRotated = np.sin(ang) * offsets xrayRotated[np.abs(xrayRotated) < 1e-8] = 0 yrayRotated[np.abs(yrayRotated) < 1e-8] = 0 a = -np.sin(ang) a = rmepsilon(a) b = np.cos(ang) b = rmepsilon(b) for j in range(0, Nray): # Loop rays in current projection #Ray: y = tx * x + intercept t_xgrid = (xgrid - xrayRotated[j]) / a y_xgrid = b * t_xgrid + yrayRotated[j] t_ygrid = (ygrid - yrayRotated[j]) / b x_ygrid = a * t_ygrid + xrayRotated[j] # Collect all points t_grid = np.append(t_xgrid, t_ygrid) xx = np.append(xgrid, x_ygrid) yy = np.append(y_xgrid, ygrid) # Sort the coordinates according to intersection time I = np.argsort(t_grid) xx = xx[I] yy = yy[I] # Get rid of points that are outside the image grid Ix = np.logical_and(xx >= -Nside / 2.0 * pixelWidth, xx <= Nside / 2.0 * pixelWidth) Iy = np.logical_and(yy >= -Nside / 2.0 * pixelWidth, yy <= Nside / 2.0 * pixelWidth) I = np.logical_and(Ix, Iy) xx = xx[I] yy = yy[I] # If the ray pass through the image grid if (xx.size != 0 and yy.size != 0): # Get rid of double counted points I = np.logical_and( np.abs(np.diff(xx)) <= 1e-8, np.abs(np.diff(yy)) <= 1e-8) I2 = np.zeros(I.size + 1) I2[0:-1] = I xx = xx[np.logical_not(I2)] yy = yy[np.logical_not(I2)] # Calculate the length within the cell length = np.sqrt(np.diff(xx)**2 + np.diff(yy)**2) #Count number of cells the ray passes through numvals = length.size # Remove the rays that are on the boundary of the box in the # top or to the right of the image grid check1 = np.logical_and( b == 0, np.absolute(yrayRotated[j] - Nside / 2 * pixelWidth) < 1e-15) check2 = np.logical_and( a == 0, np.absolute(xrayRotated[j] - Nside / 2 * pixelWidth) < 1e-15) check = np.logical_not(np.logical_or(check1, check2)) if np.logical_and(numvals > 0, check): # Calculate corresponding indices in measurement matrix # First, calculate the mid points coord. between two # adjacent grid points midpoints_x = rmepsilon(0.5 * (xx[0:-1] + xx[1:])) midpoints_y = rmepsilon(0.5 * (yy[0:-1] + yy[1:])) #Calculate the pixel index for mid points pixelIndicex = \ (np.floor(Nside / 2.0 - midpoints_y / pixelWidth)) * \ Nside + (np.floor(midpoints_x / pixelWidth + Nside / 2.0)) # Create the indices to store the values to the measurement # matrix idxstart = idxend idxend = idxstart + numvals idx = np.arange(idxstart, idxend) # Store row numbers, column numbers and values rows[idx] = i * Nray + j cols[idx] = pixelIndicex vals[idx] = length else: print("Ray No. %d at %f degree is out of image grid!" % (j + 1, angles[i])) # Truncate excess zeros. rows = rows[:idxend] cols = cols[:idxend] vals = vals[:idxend] A = ss.coo_matrix((vals, (rows, cols)), shape=(Nray * Nproj, Nside**2)) return A def rmepsilon(input): if (input.size > 1): input[np.abs(input) < 1e-10] = 0 else: if np.abs(input) < 1e-10: input = 0 return input # ------------------------------------------------------------------------- # Reconstruction # ------------------------------------------------------------------------- print('%d # Start reconstruction' % idx) tiltSeries = scalars_array3d tiltAngles = range(-sizeZ + 1, sizeZ, 2) # Delta angle of 2 (Nslice, Nray, Nproj) = tiltSeries.shape Niter = 1 A = parallelRay(Nray, 1.0, tiltAngles, Nray, 1.0) # A is a sparse matrix recon = np.empty([Nslice, Nray, Nray], dtype=float, order='F') A = A.todense() (Nrow, Ncol) = A.shape rowInnerProduct = np.zeros(Nrow) row = np.zeros(Ncol) f = np.zeros(Ncol) # Placeholder for 2d image beta = 1.0 # Calculate row inner product for j in range(Nrow): row[:] = A[j, ].copy() rowInnerProduct[j] = np.dot(row, row) for s in range(Nslice): f[:] = 0 b = tiltSeries[s, :, :].transpose().flatten() for i in range(Niter): for j in range(Nrow): row[:] = A[j, ].copy() row_f_product = np.dot(row, f) a = (b[j] - row_f_product) / rowInnerProduct[j] f = f + row * a * beta recon[s, :, :] = f.reshape((Nray, Nray)) (iSize, jSize, kSize) = recon.shape print('%d # End reconstruction - Dimensions (%d, %d, %d)' % (idx, iSize, jSize, kSize)) # ------------------------------------------------------------------------- # Convert reconstruction array into VTK format # ------------------------------------------------------------------------- print('%d # Reshape reconstruction' % idx) arr = recon.ravel(order='A') vtkarray = numpy_support.numpy_to_vtk(arr) vtkarray.SetName('Scalars') print('%d # Array size %d' % (idx, vtkarray.GetNumberOfTuples())) # ------------------------------------------------------------------------- # Share boundary # ------------------------------------------------------------------------- # pure python with mpi to share bounds # ------------------------------------------------------------------------- print('%d # Create new image data from reconstruction' % idx) dataset = vtkImageData() minX = 0 maxX = 0 for i in range(idx + 1): minX = maxX maxX += xSizes[i] print('%d # extent [%d, %d, %d, %d, %d, %d]' % (idx, minX, maxX - 1, 0, sizeY - 1, 0, sizeY - 1)) dataset.SetExtent(minX, maxX - 1, 0, sizeY - 1, 0, sizeY - 1) dataset.GetPointData().SetScalars(vtkarray) vtkDistributedTrivialProducer.SetGlobalOutput('Spark', dataset) from vtk.vtkPVClientServerCoreCore import vtkProcessModule from paraview import simple from paraview.web import wamp as pv_wamp from paraview.web import protocols as pv_protocols from vtk.web import server pm = vtkProcessModule.GetProcessModule() class Options(object): debug = False nosignalhandlers = True host = 'localhost' port = 9753 timeout = 300 content = '/data/scott/SparkMPI/runtime/visualizer-2.1.4/dist' forceFlush = False sslKey = '' sslCert = '' ws = 'ws' lp = 'lp' hp = 'hp' nows = False nobws = False nolp = False fsEndpoints = '' uploadPath = None testScriptPath = '' baselineImgDir = '' useBrowser = 'nobrowser' tmpDirectory = '.' testImgFile = '' class _VisualizerServer(pv_wamp.PVServerProtocol): dataDir = '/data' groupRegex = "[0-9]+\\.[0-9]+\\.|[0-9]+\\." excludeRegex = "^\\.|~$|^\\$" allReaders = True viewportScale = 1.0 viewportMaxWidth = 2560 viewportMaxHeight = 1440 def initialize(self): # Bring used components self.registerVtkWebProtocol( pv_protocols.ParaViewWebFileListing( _VisualizerServer.dataDir, "Home", _VisualizerServer.excludeRegex, _VisualizerServer.groupRegex)) self.registerVtkWebProtocol( pv_protocols.ParaViewWebProxyManager( baseDir=_VisualizerServer.dataDir, allowUnconfiguredReaders=_VisualizerServer.allReaders)) self.registerVtkWebProtocol(pv_protocols.ParaViewWebColorManager()) self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebViewPort( _VisualizerServer.viewportScale, _VisualizerServer.viewportMaxWidth, _VisualizerServer.viewportMaxHeight)) self.registerVtkWebProtocol( pv_protocols.ParaViewWebViewPortImageDelivery()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebViewPortGeometryDelivery()) self.registerVtkWebProtocol(pv_protocols.ParaViewWebTimeHandler()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebSelectionHandler()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebWidgetManager()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebKeyValuePairStore()) self.registerVtkWebProtocol( pv_protocols.ParaViewWebSaveData( baseSavePath=_VisualizerServer.dataDir)) # Disable interactor-based render calls simple.GetRenderView().EnableRenderOnInteraction = 0 simple.GetRenderView().Background = [0, 0, 0] # Update interaction mode pxm = simple.servermanager.ProxyManager() interactionProxy = pxm.GetProxy('settings', 'RenderViewInteractionSettings') interactionProxy.Camera3DManipulators = [ 'Rotate', 'Pan', 'Zoom', 'Pan', 'Roll', 'Pan', 'Zoom', 'Rotate', 'Zoom' ] # ------------------------------------------------------------------------- print('%d # Start visualization' % idx) # ------------------------------------------------------------------------- args = Options() if pm.GetPartitionId() == 0: producer = simple.DistributedTrivialProducer() producer.UpdateDataset = '' producer.UpdateDataset = 'Spark' print('Whole extent [%d, %d, %d, %d, %d, %d]' % (0, sizeX - 1, 0, sizeY - 1, 0, sizeY - 1)) producer.WholeExtent = [0, sizeX - 1, 0, sizeY - 1, 0, sizeY - 1] server.start_webserver(options=args, protocol=_VisualizerServer) pm.GetGlobalController().TriggerBreakRMIs() yield (idx, targetPartition)
def _from_arrays(self, offset, cells, cell_type, points, deep=True): """Create VTK unstructured grid from numpy arrays. Parameters ---------- offset : np.ndarray dtype=np.int64 Array indicating the start location of each cell in the cells array. cells : np.ndarray dtype=np.int64 Array of cells. Each cell contains the number of points in the cell and the node numbers of the cell. cell_type : np.uint8 Cell types of each cell. Each cell type numbers can be found from vtk documentation. See example below. points : np.ndarray Numpy array containing point locations. Examples -------- >>> import numpy >>> import vtk >>> import pyvista >>> offset = np.array([0, 9]) >>> cells = np.array([8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15]) >>> cell_type = np.array([vtk.VTK_HEXAHEDRON, vtk.VTK_HEXAHEDRON], np.int8) >>> cell1 = np.array([[0, 0, 0], ... [1, 0, 0], ... [1, 1, 0], ... [0, 1, 0], ... [0, 0, 1], ... [1, 0, 1], ... [1, 1, 1], ... [0, 1, 1]]) >>> cell2 = np.array([[0, 0, 2], ... [1, 0, 2], ... [1, 1, 2], ... [0, 1, 2], ... [0, 0, 3], ... [1, 0, 3], ... [1, 1, 3], ... [0, 1, 3]]) >>> points = np.vstack((cell1, cell2)) >>> grid = pyvista.UnstructuredGrid(offset, cells, cell_type, points) """ if offset.dtype != pyvista.ID_TYPE: offset = offset.astype(pyvista.ID_TYPE) if cells.dtype != pyvista.ID_TYPE: cells = cells.astype(pyvista.ID_TYPE) if not cells.flags['C_CONTIGUOUS']: cells = np.ascontiguousarray(cells) # if cells.ndim != 1: # cells = cells.ravel() if cell_type.dtype != np.uint8: cell_type = cell_type.astype(np.uint8) # Get number of cells ncells = cell_type.size # Convert to vtk arrays cell_type = numpy_to_vtk(cell_type, deep=deep) offset = numpy_to_vtkIdTypeArray(offset, deep=deep) vtkcells = vtk.vtkCellArray() vtkcells.SetCells(ncells, numpy_to_vtkIdTypeArray(cells.ravel(), deep=deep)) # Convert points to vtkPoints object points = pyvista.vtk_points(points, deep=deep) # Create unstructured grid self.SetPoints(points) self.SetCells(cell_type, offset, vtkcells)
def initializeLesion(self): self.reader.Update() self.lesion.CopyStructure(self.reader.GetOutput()) self.lesion.GetPointData().SetScalars(numpy_to_vtk(num_array= self.imageArray.ravel(order='F'), deep=True))
def lines_to_vtk_polydata(lines, colors="RGB", dtype=None): # Get the 3d points_array points_array = np.vstack(lines) nb_lines = len(lines) nb_points = len(points_array) lines_range = range(nb_lines) # Get lines_array in vtk input format # todo put from array lines_array = [] points_per_line = np.zeros([nb_lines], np.int64) current_position = 0 for i in lines_range: current_len = len(lines[i]) points_per_line[i] = current_len end_position = current_position + current_len lines_array += [current_len] lines_array += range(current_position, end_position) current_position = end_position if dtype is None: lines_array = np.array(lines_array) else: lines_array = np.array(lines_array) # Set Points to vtk array format vtk_points = numpy_to_vtk_points(points_array.astype(dtype)) # Set Lines to vtk array format vtk_lines = vtk.vtkCellArray() vtk_lines.GetData().DeepCopy(ns.numpy_to_vtk(lines_array)) vtk_lines.SetNumberOfCells(len(lines)) # colors test, todo improve if colors is not None: if colors == "RGB": # set automatic rgb colors colors = np.abs(lines[:, -1] - lines[:, 0]) colors = 0.8 * colors / \ np.sqrt(np.sum(colors ** 2, axis=1, keepdims=True)) colors_mapper = np.repeat(lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors(255 * colors[colors_mapper]) else: colors = np.array(colors) if colors.dtype == np.object: # colors is a list of colors vtk_colors = numpy_to_vtk_colors(255 * np.vstack(colors)) else: # one colors per points / colormap way if len(colors) == nb_points: vtk_colors = ns.numpy_to_vtk(colors, deep=True) raise NotImplementedError() elif colors.ndim == 1: # the same colors for all points vtk_colors = numpy_to_vtk_colors( np.tile(255 * colors, (nb_points, 1))) elif colors.ndim == 2: # map color to each line colors_mapper = np.repeat( lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors( 255 * colors[colors_mapper]) vtk_colors.SetName("Colors") # Create the poly_data poly_data = vtk.vtkPolyData() poly_data.SetPoints(vtk_points) poly_data.SetLines(vtk_lines) if colors is not None: poly_data.GetPointData().SetScalars(vtk_colors) return poly_data