vedo.ugrid
Work with unstructured grid datasets
1import numpy as np 2 3try: 4 import vedo.vtkclasses as vtk 5except ImportError: 6 import vtkmodules.all as vtk 7 8import vedo 9from vedo import settings 10from vedo import colors 11from vedo import utils 12from vedo.base import BaseGrid 13from vedo.file_io import download, loadUnStructuredGrid 14 15 16__docformat__ = "google" 17 18__doc__ = """ 19Work with unstructured grid datasets 20""" 21 22__all__ = ["UGrid"] 23 24######################################################################### 25class UGrid(BaseGrid, vtk.vtkActor): 26 """Support for UnstructuredGrid objects.""" 27 28 def __init__(self, inputobj=None): 29 """ 30 Support for UnstructuredGrid objects. 31 32 Arguments: 33 inputobj : (list, vtkUnstructuredGrid, str) 34 A list in the form `[points, cells, celltypes]`, 35 or a vtkUnstructuredGrid object, or a filename 36 37 Celltypes are identified by the following convention: 38 - VTK_TETRA = 10 39 - VTK_VOXEL = 11 40 - VTK_HEXAHEDRON = 12 41 - VTK_WEDGE = 13 42 - VTK_PYRAMID = 14 43 - VTK_HEXAGONAL_PRISM = 15 44 - VTK_PENTAGONAL_PRISM = 16 45 """ 46 47 vtk.vtkActor.__init__(self) 48 BaseGrid.__init__(self) 49 50 inputtype = str(type(inputobj)) 51 self._data = None 52 self._polydata = None 53 self._bfprop = None 54 self.name = "UGrid" 55 56 ################### 57 if inputobj is None: 58 self._data = vtk.vtkUnstructuredGrid() 59 60 elif utils.is_sequence(inputobj): 61 62 pts, cells, celltypes = inputobj 63 64 self._data = vtk.vtkUnstructuredGrid() 65 66 if not utils.is_sequence(cells[0]): 67 tets = [] 68 nf = cells[0] + 1 69 for i, cl in enumerate(cells): 70 if i in (nf, 0): 71 k = i + 1 72 nf = cl + k 73 cell = [cells[j + k] for j in range(cl)] 74 tets.append(cell) 75 cells = tets 76 77 # This would fill the points and use those to define orientation 78 vpts = utils.numpy2vtk(pts, dtype=np.float32) 79 points = vtk.vtkPoints() 80 points.SetData(vpts) 81 self._data.SetPoints(points) 82 83 # This fill the points and use cells to define orientation 84 # points = vtk.vtkPoints() 85 # for c in cells: 86 # for pid in c: 87 # points.InsertNextPoint(pts[pid]) 88 # self._data.SetPoints(points) 89 90 # Fill cells 91 # https://vtk.org/doc/nightly/html/vtkCellType_8h_source.html 92 for i, ct in enumerate(celltypes): 93 cell_conn = cells[i] 94 if ct == vtk.VTK_HEXAHEDRON: 95 cell = vtk.vtkHexahedron() 96 elif ct == vtk.VTK_TETRA: 97 cell = vtk.vtkTetra() 98 elif ct == vtk.VTK_VOXEL: 99 cell = vtk.vtkVoxel() 100 elif ct == vtk.VTK_WEDGE: 101 cell = vtk.vtkWedge() 102 elif ct == vtk.VTK_PYRAMID: 103 cell = vtk.vtkPyramid() 104 elif ct == vtk.VTK_HEXAGONAL_PRISM: 105 cell = vtk.vtkHexagonalPrism() 106 elif ct == vtk.VTK_PENTAGONAL_PRISM: 107 cell = vtk.vtkPentagonalPrism() 108 else: 109 print("UGrid: cell type", ct, "not implemented. Skip.") 110 continue 111 cpids = cell.GetPointIds() 112 for j, pid in enumerate(cell_conn): 113 cpids.SetId(j, pid) 114 self._data.InsertNextCell(ct, cpids) 115 116 elif "UnstructuredGrid" in inputtype: 117 self._data = inputobj 118 119 elif isinstance(inputobj, str): 120 if "https://" in inputobj: 121 inputobj = download(inputobj, verbose=False) 122 self._data = loadUnStructuredGrid(inputobj) 123 self.filename = inputobj 124 125 else: 126 vedo.logger.error(f"cannot understand input type {inputtype}") 127 return 128 129 # self._mapper = vtk.vtkDataSetMapper() 130 self._mapper = vtk.vtkPolyDataMapper() 131 self._mapper.SetInterpolateScalarsBeforeMapping(settings.interpolate_scalars_before_mapping) 132 133 if settings.use_polygon_offset: 134 self._mapper.SetResolveCoincidentTopologyToPolygonOffset() 135 pof, pou = settings.polygon_offset_factor, settings.polygon_offset_units 136 self._mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(pof, pou) 137 self.GetProperty().SetInterpolationToFlat() 138 139 if not self._data: 140 return 141 142 # now fill the representation of the vtk unstr grid 143 sf = vtk.vtkShrinkFilter() 144 sf.SetInputData(self._data) 145 sf.SetShrinkFactor(1.0) 146 sf.Update() 147 gf = vtk.vtkGeometryFilter() 148 gf.SetInputData(sf.GetOutput()) 149 gf.Update() 150 self._polydata = gf.GetOutput() 151 152 self._mapper.SetInputData(self._polydata) 153 sc = None 154 if self.useCells: 155 sc = self._polydata.GetCellData().GetScalars() 156 else: 157 sc = self._polydata.GetPointData().GetScalars() 158 if sc: 159 self._mapper.SetScalarRange(sc.GetRange()) 160 161 self.SetMapper(self._mapper) 162 self.property = self.GetProperty() 163 164 self.pipeline = utils.OperationNode( 165 self, comment=f"#cells {self._data.GetNumberOfCells()}", 166 c="#4cc9f0", 167 ) 168 # ------------------------------------------------------------------ 169 170 def _repr_html_(self): 171 """ 172 HTML representation of the UGrid object for Jupyter Notebooks. 173 174 Returns: 175 HTML text with the image and some properties. 176 """ 177 import io 178 import base64 179 from PIL import Image 180 181 library_name = "vedo.ugrid.UGrid" 182 help_url = "https://vedo.embl.es/docs/vedo/ugrid.html" 183 184 arr = self.thumbnail() 185 im = Image.fromarray(arr) 186 buffered = io.BytesIO() 187 im.save(buffered, format="PNG", quality=100) 188 encoded = base64.b64encode(buffered.getvalue()).decode("utf-8") 189 url = "data:image/png;base64," + encoded 190 image = f"<img src='{url}'></img>" 191 192 bounds = "<br/>".join( 193 [ 194 utils.precision(min_x,4) + " ... " + utils.precision(max_x,4) 195 for min_x, max_x in zip(self.bounds()[::2], self.bounds()[1::2]) 196 ] 197 ) 198 199 help_text = "" 200 if self.name: 201 help_text += f"<b> {self.name}:   </b>" 202 help_text += '<b><a href="' + help_url + '" target="_blank">' + library_name + "</a></b>" 203 if self.filename: 204 dots = "" 205 if len(self.filename) > 30: 206 dots = "..." 207 help_text += f"<br/><code><i>({dots}{self.filename[-30:]})</i></code>" 208 209 pdata = "" 210 if self._data.GetPointData().GetScalars(): 211 if self._data.GetPointData().GetScalars().GetName(): 212 name = self._data.GetPointData().GetScalars().GetName() 213 pdata = "<tr><td><b> point data array </b></td><td>" + name + "</td></tr>" 214 215 cdata = "" 216 if self._data.GetCellData().GetScalars(): 217 if self._data.GetCellData().GetScalars().GetName(): 218 name = self._data.GetCellData().GetScalars().GetName() 219 cdata = "<tr><td><b> cell data array </b></td><td>" + name + "</td></tr>" 220 221 pts = self.points() 222 cm = np.mean(pts, axis=0) 223 224 all = [ 225 "<table>", 226 "<tr>", 227 "<td>", image, "</td>", 228 "<td style='text-align: center; vertical-align: center;'><br/>", help_text, 229 "<table>", 230 "<tr><td><b> bounds </b> <br/> (x/y/z) </td><td>" + str(bounds) + "</td></tr>", 231 "<tr><td><b> center of mass </b></td><td>" + utils.precision(cm,3) + "</td></tr>", 232 # "<tr><td><b> average size </b></td><td>" + str(average_size) + "</td></tr>", 233 "<tr><td><b> nr. points / cells </b></td><td>" 234 + str(self.npoints) + " / " + str(self.ncells) + "</td></tr>", 235 pdata, 236 cdata, 237 "</table>", 238 "</table>", 239 ] 240 return "\n".join(all) 241 242 def clone(self): 243 """Clone the UGrid object to yield an exact copy.""" 244 ugCopy = vtk.vtkUnstructuredGrid() 245 ugCopy.DeepCopy(self._data) 246 247 cloned = UGrid(ugCopy) 248 pr = self.GetProperty() 249 if isinstance(pr, vtk.vtkVolumeProperty): 250 prv = vtk.vtkVolumeProperty() 251 else: 252 prv = vtk.vtkProperty() 253 prv.DeepCopy(pr) 254 cloned.SetProperty(prv) 255 cloned.property = prv 256 257 # assign the same transformation to the copy 258 cloned.SetOrigin(self.GetOrigin()) 259 cloned.SetScale(self.GetScale()) 260 cloned.SetOrientation(self.GetOrientation()) 261 cloned.SetPosition(self.GetPosition()) 262 cloned.name = self.name 263 264 cloned.pipeline = utils.OperationNode( 265 "clone", parents=[self], shape='diamond', c='#bbe1ed', 266 ) 267 return cloned 268 269 def color(self, c=False, alpha=None): 270 """ 271 Set/get UGrid color. 272 If None is passed as input, will use colors from active scalars. 273 Same as `ugrid.c()`. 274 """ 275 if c is False: 276 return np.array(self.GetProperty().GetColor()) 277 if c is None: 278 self._mapper.ScalarVisibilityOn() 279 return self 280 self._mapper.ScalarVisibilityOff() 281 cc = colors.get_color(c) 282 self.property.SetColor(cc) 283 if self.trail: 284 self.trail.GetProperty().SetColor(cc) 285 if alpha is not None: 286 self.alpha(alpha) 287 return self 288 289 def alpha(self, opacity=None): 290 """Set/get mesh's transparency. Same as `mesh.opacity()`.""" 291 if opacity is None: 292 return self.property.GetOpacity() 293 294 self.property.SetOpacity(opacity) 295 bfp = self.GetBackfaceProperty() 296 if bfp: 297 if opacity < 1: 298 self._bfprop = bfp 299 self.SetBackfaceProperty(None) 300 else: 301 self.SetBackfaceProperty(self._bfprop) 302 return self 303 304 def opacity(self, alpha=None): 305 """Set/get mesh's transparency. Same as `mesh.alpha()`.""" 306 return self.alpha(alpha) 307 308 def wireframe(self, value=True): 309 """Set mesh's representation as wireframe or solid surface. 310 Same as `mesh.wireframe()`.""" 311 if value: 312 self.property.SetRepresentationToWireframe() 313 else: 314 self.property.SetRepresentationToSurface() 315 return self 316 317 def linewidth(self, lw=None): 318 """Set/get width of mesh edges. Same as `lw()`.""" 319 if lw is not None: 320 if lw == 0: 321 self.property.EdgeVisibilityOff() 322 self.property.SetRepresentationToSurface() 323 return self 324 self.property.EdgeVisibilityOn() 325 self.property.SetLineWidth(lw) 326 else: 327 return self.property.GetLineWidth() 328 return self 329 330 def lw(self, linewidth=None): 331 """Set/get width of mesh edges. Same as `linewidth()`.""" 332 return self.linewidth(linewidth) 333 334 def linecolor(self, lc=None): 335 """Set/get color of mesh edges. Same as `lc()`.""" 336 if lc is not None: 337 if "ireframe" in self.property.GetRepresentationAsString(): 338 self.property.EdgeVisibilityOff() 339 self.color(lc) 340 return self 341 self.property.EdgeVisibilityOn() 342 self.property.SetEdgeColor(colors.get_color(lc)) 343 else: 344 return self.property.GetEdgeColor() 345 return self 346 347 def lc(self, linecolor=None): 348 """Set/get color of mesh edges. Same as `linecolor()`.""" 349 return self.linecolor(linecolor) 350 351 def extract_cell_type(self, ctype): 352 """Extract a specific cell type and return a new `UGrid`.""" 353 uarr = self._data.GetCellTypesArray() 354 ctarrtyp = np.where(utils.vtk2numpy(uarr) == ctype)[0] 355 uarrtyp = utils.numpy2vtk(ctarrtyp, deep=False, dtype="id") 356 selection_node = vtk.vtkSelectionNode() 357 selection_node.SetFieldType(vtk.vtkSelectionNode.CELL) 358 selection_node.SetContentType(vtk.vtkSelectionNode.INDICES) 359 selection_node.SetSelectionList(uarrtyp) 360 selection = vtk.vtkSelection() 361 selection.AddNode(selection_node) 362 es = vtk.vtkExtractSelection() 363 es.SetInputData(0, self._data) 364 es.SetInputData(1, selection) 365 es.Update() 366 ug = UGrid(es.GetOutput()) 367 368 ug.pipeline = utils.OperationNode( 369 "extract_cell_type", comment=f"type {ctype}", 370 c="#edabab", parents=[self], 371 ) 372 return ug
26class UGrid(BaseGrid, vtk.vtkActor): 27 """Support for UnstructuredGrid objects.""" 28 29 def __init__(self, inputobj=None): 30 """ 31 Support for UnstructuredGrid objects. 32 33 Arguments: 34 inputobj : (list, vtkUnstructuredGrid, str) 35 A list in the form `[points, cells, celltypes]`, 36 or a vtkUnstructuredGrid object, or a filename 37 38 Celltypes are identified by the following convention: 39 - VTK_TETRA = 10 40 - VTK_VOXEL = 11 41 - VTK_HEXAHEDRON = 12 42 - VTK_WEDGE = 13 43 - VTK_PYRAMID = 14 44 - VTK_HEXAGONAL_PRISM = 15 45 - VTK_PENTAGONAL_PRISM = 16 46 """ 47 48 vtk.vtkActor.__init__(self) 49 BaseGrid.__init__(self) 50 51 inputtype = str(type(inputobj)) 52 self._data = None 53 self._polydata = None 54 self._bfprop = None 55 self.name = "UGrid" 56 57 ################### 58 if inputobj is None: 59 self._data = vtk.vtkUnstructuredGrid() 60 61 elif utils.is_sequence(inputobj): 62 63 pts, cells, celltypes = inputobj 64 65 self._data = vtk.vtkUnstructuredGrid() 66 67 if not utils.is_sequence(cells[0]): 68 tets = [] 69 nf = cells[0] + 1 70 for i, cl in enumerate(cells): 71 if i in (nf, 0): 72 k = i + 1 73 nf = cl + k 74 cell = [cells[j + k] for j in range(cl)] 75 tets.append(cell) 76 cells = tets 77 78 # This would fill the points and use those to define orientation 79 vpts = utils.numpy2vtk(pts, dtype=np.float32) 80 points = vtk.vtkPoints() 81 points.SetData(vpts) 82 self._data.SetPoints(points) 83 84 # This fill the points and use cells to define orientation 85 # points = vtk.vtkPoints() 86 # for c in cells: 87 # for pid in c: 88 # points.InsertNextPoint(pts[pid]) 89 # self._data.SetPoints(points) 90 91 # Fill cells 92 # https://vtk.org/doc/nightly/html/vtkCellType_8h_source.html 93 for i, ct in enumerate(celltypes): 94 cell_conn = cells[i] 95 if ct == vtk.VTK_HEXAHEDRON: 96 cell = vtk.vtkHexahedron() 97 elif ct == vtk.VTK_TETRA: 98 cell = vtk.vtkTetra() 99 elif ct == vtk.VTK_VOXEL: 100 cell = vtk.vtkVoxel() 101 elif ct == vtk.VTK_WEDGE: 102 cell = vtk.vtkWedge() 103 elif ct == vtk.VTK_PYRAMID: 104 cell = vtk.vtkPyramid() 105 elif ct == vtk.VTK_HEXAGONAL_PRISM: 106 cell = vtk.vtkHexagonalPrism() 107 elif ct == vtk.VTK_PENTAGONAL_PRISM: 108 cell = vtk.vtkPentagonalPrism() 109 else: 110 print("UGrid: cell type", ct, "not implemented. Skip.") 111 continue 112 cpids = cell.GetPointIds() 113 for j, pid in enumerate(cell_conn): 114 cpids.SetId(j, pid) 115 self._data.InsertNextCell(ct, cpids) 116 117 elif "UnstructuredGrid" in inputtype: 118 self._data = inputobj 119 120 elif isinstance(inputobj, str): 121 if "https://" in inputobj: 122 inputobj = download(inputobj, verbose=False) 123 self._data = loadUnStructuredGrid(inputobj) 124 self.filename = inputobj 125 126 else: 127 vedo.logger.error(f"cannot understand input type {inputtype}") 128 return 129 130 # self._mapper = vtk.vtkDataSetMapper() 131 self._mapper = vtk.vtkPolyDataMapper() 132 self._mapper.SetInterpolateScalarsBeforeMapping(settings.interpolate_scalars_before_mapping) 133 134 if settings.use_polygon_offset: 135 self._mapper.SetResolveCoincidentTopologyToPolygonOffset() 136 pof, pou = settings.polygon_offset_factor, settings.polygon_offset_units 137 self._mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(pof, pou) 138 self.GetProperty().SetInterpolationToFlat() 139 140 if not self._data: 141 return 142 143 # now fill the representation of the vtk unstr grid 144 sf = vtk.vtkShrinkFilter() 145 sf.SetInputData(self._data) 146 sf.SetShrinkFactor(1.0) 147 sf.Update() 148 gf = vtk.vtkGeometryFilter() 149 gf.SetInputData(sf.GetOutput()) 150 gf.Update() 151 self._polydata = gf.GetOutput() 152 153 self._mapper.SetInputData(self._polydata) 154 sc = None 155 if self.useCells: 156 sc = self._polydata.GetCellData().GetScalars() 157 else: 158 sc = self._polydata.GetPointData().GetScalars() 159 if sc: 160 self._mapper.SetScalarRange(sc.GetRange()) 161 162 self.SetMapper(self._mapper) 163 self.property = self.GetProperty() 164 165 self.pipeline = utils.OperationNode( 166 self, comment=f"#cells {self._data.GetNumberOfCells()}", 167 c="#4cc9f0", 168 ) 169 # ------------------------------------------------------------------ 170 171 def _repr_html_(self): 172 """ 173 HTML representation of the UGrid object for Jupyter Notebooks. 174 175 Returns: 176 HTML text with the image and some properties. 177 """ 178 import io 179 import base64 180 from PIL import Image 181 182 library_name = "vedo.ugrid.UGrid" 183 help_url = "https://vedo.embl.es/docs/vedo/ugrid.html" 184 185 arr = self.thumbnail() 186 im = Image.fromarray(arr) 187 buffered = io.BytesIO() 188 im.save(buffered, format="PNG", quality=100) 189 encoded = base64.b64encode(buffered.getvalue()).decode("utf-8") 190 url = "data:image/png;base64," + encoded 191 image = f"<img src='{url}'></img>" 192 193 bounds = "<br/>".join( 194 [ 195 utils.precision(min_x,4) + " ... " + utils.precision(max_x,4) 196 for min_x, max_x in zip(self.bounds()[::2], self.bounds()[1::2]) 197 ] 198 ) 199 200 help_text = "" 201 if self.name: 202 help_text += f"<b> {self.name}:   </b>" 203 help_text += '<b><a href="' + help_url + '" target="_blank">' + library_name + "</a></b>" 204 if self.filename: 205 dots = "" 206 if len(self.filename) > 30: 207 dots = "..." 208 help_text += f"<br/><code><i>({dots}{self.filename[-30:]})</i></code>" 209 210 pdata = "" 211 if self._data.GetPointData().GetScalars(): 212 if self._data.GetPointData().GetScalars().GetName(): 213 name = self._data.GetPointData().GetScalars().GetName() 214 pdata = "<tr><td><b> point data array </b></td><td>" + name + "</td></tr>" 215 216 cdata = "" 217 if self._data.GetCellData().GetScalars(): 218 if self._data.GetCellData().GetScalars().GetName(): 219 name = self._data.GetCellData().GetScalars().GetName() 220 cdata = "<tr><td><b> cell data array </b></td><td>" + name + "</td></tr>" 221 222 pts = self.points() 223 cm = np.mean(pts, axis=0) 224 225 all = [ 226 "<table>", 227 "<tr>", 228 "<td>", image, "</td>", 229 "<td style='text-align: center; vertical-align: center;'><br/>", help_text, 230 "<table>", 231 "<tr><td><b> bounds </b> <br/> (x/y/z) </td><td>" + str(bounds) + "</td></tr>", 232 "<tr><td><b> center of mass </b></td><td>" + utils.precision(cm,3) + "</td></tr>", 233 # "<tr><td><b> average size </b></td><td>" + str(average_size) + "</td></tr>", 234 "<tr><td><b> nr. points / cells </b></td><td>" 235 + str(self.npoints) + " / " + str(self.ncells) + "</td></tr>", 236 pdata, 237 cdata, 238 "</table>", 239 "</table>", 240 ] 241 return "\n".join(all) 242 243 def clone(self): 244 """Clone the UGrid object to yield an exact copy.""" 245 ugCopy = vtk.vtkUnstructuredGrid() 246 ugCopy.DeepCopy(self._data) 247 248 cloned = UGrid(ugCopy) 249 pr = self.GetProperty() 250 if isinstance(pr, vtk.vtkVolumeProperty): 251 prv = vtk.vtkVolumeProperty() 252 else: 253 prv = vtk.vtkProperty() 254 prv.DeepCopy(pr) 255 cloned.SetProperty(prv) 256 cloned.property = prv 257 258 # assign the same transformation to the copy 259 cloned.SetOrigin(self.GetOrigin()) 260 cloned.SetScale(self.GetScale()) 261 cloned.SetOrientation(self.GetOrientation()) 262 cloned.SetPosition(self.GetPosition()) 263 cloned.name = self.name 264 265 cloned.pipeline = utils.OperationNode( 266 "clone", parents=[self], shape='diamond', c='#bbe1ed', 267 ) 268 return cloned 269 270 def color(self, c=False, alpha=None): 271 """ 272 Set/get UGrid color. 273 If None is passed as input, will use colors from active scalars. 274 Same as `ugrid.c()`. 275 """ 276 if c is False: 277 return np.array(self.GetProperty().GetColor()) 278 if c is None: 279 self._mapper.ScalarVisibilityOn() 280 return self 281 self._mapper.ScalarVisibilityOff() 282 cc = colors.get_color(c) 283 self.property.SetColor(cc) 284 if self.trail: 285 self.trail.GetProperty().SetColor(cc) 286 if alpha is not None: 287 self.alpha(alpha) 288 return self 289 290 def alpha(self, opacity=None): 291 """Set/get mesh's transparency. Same as `mesh.opacity()`.""" 292 if opacity is None: 293 return self.property.GetOpacity() 294 295 self.property.SetOpacity(opacity) 296 bfp = self.GetBackfaceProperty() 297 if bfp: 298 if opacity < 1: 299 self._bfprop = bfp 300 self.SetBackfaceProperty(None) 301 else: 302 self.SetBackfaceProperty(self._bfprop) 303 return self 304 305 def opacity(self, alpha=None): 306 """Set/get mesh's transparency. Same as `mesh.alpha()`.""" 307 return self.alpha(alpha) 308 309 def wireframe(self, value=True): 310 """Set mesh's representation as wireframe or solid surface. 311 Same as `mesh.wireframe()`.""" 312 if value: 313 self.property.SetRepresentationToWireframe() 314 else: 315 self.property.SetRepresentationToSurface() 316 return self 317 318 def linewidth(self, lw=None): 319 """Set/get width of mesh edges. Same as `lw()`.""" 320 if lw is not None: 321 if lw == 0: 322 self.property.EdgeVisibilityOff() 323 self.property.SetRepresentationToSurface() 324 return self 325 self.property.EdgeVisibilityOn() 326 self.property.SetLineWidth(lw) 327 else: 328 return self.property.GetLineWidth() 329 return self 330 331 def lw(self, linewidth=None): 332 """Set/get width of mesh edges. Same as `linewidth()`.""" 333 return self.linewidth(linewidth) 334 335 def linecolor(self, lc=None): 336 """Set/get color of mesh edges. Same as `lc()`.""" 337 if lc is not None: 338 if "ireframe" in self.property.GetRepresentationAsString(): 339 self.property.EdgeVisibilityOff() 340 self.color(lc) 341 return self 342 self.property.EdgeVisibilityOn() 343 self.property.SetEdgeColor(colors.get_color(lc)) 344 else: 345 return self.property.GetEdgeColor() 346 return self 347 348 def lc(self, linecolor=None): 349 """Set/get color of mesh edges. Same as `linecolor()`.""" 350 return self.linecolor(linecolor) 351 352 def extract_cell_type(self, ctype): 353 """Extract a specific cell type and return a new `UGrid`.""" 354 uarr = self._data.GetCellTypesArray() 355 ctarrtyp = np.where(utils.vtk2numpy(uarr) == ctype)[0] 356 uarrtyp = utils.numpy2vtk(ctarrtyp, deep=False, dtype="id") 357 selection_node = vtk.vtkSelectionNode() 358 selection_node.SetFieldType(vtk.vtkSelectionNode.CELL) 359 selection_node.SetContentType(vtk.vtkSelectionNode.INDICES) 360 selection_node.SetSelectionList(uarrtyp) 361 selection = vtk.vtkSelection() 362 selection.AddNode(selection_node) 363 es = vtk.vtkExtractSelection() 364 es.SetInputData(0, self._data) 365 es.SetInputData(1, selection) 366 es.Update() 367 ug = UGrid(es.GetOutput()) 368 369 ug.pipeline = utils.OperationNode( 370 "extract_cell_type", comment=f"type {ctype}", 371 c="#edabab", parents=[self], 372 ) 373 return ug
Support for UnstructuredGrid objects.
UGrid(inputobj=None)
29 def __init__(self, inputobj=None): 30 """ 31 Support for UnstructuredGrid objects. 32 33 Arguments: 34 inputobj : (list, vtkUnstructuredGrid, str) 35 A list in the form `[points, cells, celltypes]`, 36 or a vtkUnstructuredGrid object, or a filename 37 38 Celltypes are identified by the following convention: 39 - VTK_TETRA = 10 40 - VTK_VOXEL = 11 41 - VTK_HEXAHEDRON = 12 42 - VTK_WEDGE = 13 43 - VTK_PYRAMID = 14 44 - VTK_HEXAGONAL_PRISM = 15 45 - VTK_PENTAGONAL_PRISM = 16 46 """ 47 48 vtk.vtkActor.__init__(self) 49 BaseGrid.__init__(self) 50 51 inputtype = str(type(inputobj)) 52 self._data = None 53 self._polydata = None 54 self._bfprop = None 55 self.name = "UGrid" 56 57 ################### 58 if inputobj is None: 59 self._data = vtk.vtkUnstructuredGrid() 60 61 elif utils.is_sequence(inputobj): 62 63 pts, cells, celltypes = inputobj 64 65 self._data = vtk.vtkUnstructuredGrid() 66 67 if not utils.is_sequence(cells[0]): 68 tets = [] 69 nf = cells[0] + 1 70 for i, cl in enumerate(cells): 71 if i in (nf, 0): 72 k = i + 1 73 nf = cl + k 74 cell = [cells[j + k] for j in range(cl)] 75 tets.append(cell) 76 cells = tets 77 78 # This would fill the points and use those to define orientation 79 vpts = utils.numpy2vtk(pts, dtype=np.float32) 80 points = vtk.vtkPoints() 81 points.SetData(vpts) 82 self._data.SetPoints(points) 83 84 # This fill the points and use cells to define orientation 85 # points = vtk.vtkPoints() 86 # for c in cells: 87 # for pid in c: 88 # points.InsertNextPoint(pts[pid]) 89 # self._data.SetPoints(points) 90 91 # Fill cells 92 # https://vtk.org/doc/nightly/html/vtkCellType_8h_source.html 93 for i, ct in enumerate(celltypes): 94 cell_conn = cells[i] 95 if ct == vtk.VTK_HEXAHEDRON: 96 cell = vtk.vtkHexahedron() 97 elif ct == vtk.VTK_TETRA: 98 cell = vtk.vtkTetra() 99 elif ct == vtk.VTK_VOXEL: 100 cell = vtk.vtkVoxel() 101 elif ct == vtk.VTK_WEDGE: 102 cell = vtk.vtkWedge() 103 elif ct == vtk.VTK_PYRAMID: 104 cell = vtk.vtkPyramid() 105 elif ct == vtk.VTK_HEXAGONAL_PRISM: 106 cell = vtk.vtkHexagonalPrism() 107 elif ct == vtk.VTK_PENTAGONAL_PRISM: 108 cell = vtk.vtkPentagonalPrism() 109 else: 110 print("UGrid: cell type", ct, "not implemented. Skip.") 111 continue 112 cpids = cell.GetPointIds() 113 for j, pid in enumerate(cell_conn): 114 cpids.SetId(j, pid) 115 self._data.InsertNextCell(ct, cpids) 116 117 elif "UnstructuredGrid" in inputtype: 118 self._data = inputobj 119 120 elif isinstance(inputobj, str): 121 if "https://" in inputobj: 122 inputobj = download(inputobj, verbose=False) 123 self._data = loadUnStructuredGrid(inputobj) 124 self.filename = inputobj 125 126 else: 127 vedo.logger.error(f"cannot understand input type {inputtype}") 128 return 129 130 # self._mapper = vtk.vtkDataSetMapper() 131 self._mapper = vtk.vtkPolyDataMapper() 132 self._mapper.SetInterpolateScalarsBeforeMapping(settings.interpolate_scalars_before_mapping) 133 134 if settings.use_polygon_offset: 135 self._mapper.SetResolveCoincidentTopologyToPolygonOffset() 136 pof, pou = settings.polygon_offset_factor, settings.polygon_offset_units 137 self._mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(pof, pou) 138 self.GetProperty().SetInterpolationToFlat() 139 140 if not self._data: 141 return 142 143 # now fill the representation of the vtk unstr grid 144 sf = vtk.vtkShrinkFilter() 145 sf.SetInputData(self._data) 146 sf.SetShrinkFactor(1.0) 147 sf.Update() 148 gf = vtk.vtkGeometryFilter() 149 gf.SetInputData(sf.GetOutput()) 150 gf.Update() 151 self._polydata = gf.GetOutput() 152 153 self._mapper.SetInputData(self._polydata) 154 sc = None 155 if self.useCells: 156 sc = self._polydata.GetCellData().GetScalars() 157 else: 158 sc = self._polydata.GetPointData().GetScalars() 159 if sc: 160 self._mapper.SetScalarRange(sc.GetRange()) 161 162 self.SetMapper(self._mapper) 163 self.property = self.GetProperty() 164 165 self.pipeline = utils.OperationNode( 166 self, comment=f"#cells {self._data.GetNumberOfCells()}", 167 c="#4cc9f0", 168 )
Support for UnstructuredGrid objects.
Arguments:
- inputobj : (list, vtkUnstructuredGrid, str)
A list in the form
[points, cells, celltypes]
, or a vtkUnstructuredGrid object, or a filename
Celltypes are identified by the following convention:
- VTK_TETRA = 10
- VTK_VOXEL = 11
- VTK_HEXAHEDRON = 12
- VTK_WEDGE = 13
- VTK_PYRAMID = 14
- VTK_HEXAGONAL_PRISM = 15
- VTK_PENTAGONAL_PRISM = 16
def
clone(self):
243 def clone(self): 244 """Clone the UGrid object to yield an exact copy.""" 245 ugCopy = vtk.vtkUnstructuredGrid() 246 ugCopy.DeepCopy(self._data) 247 248 cloned = UGrid(ugCopy) 249 pr = self.GetProperty() 250 if isinstance(pr, vtk.vtkVolumeProperty): 251 prv = vtk.vtkVolumeProperty() 252 else: 253 prv = vtk.vtkProperty() 254 prv.DeepCopy(pr) 255 cloned.SetProperty(prv) 256 cloned.property = prv 257 258 # assign the same transformation to the copy 259 cloned.SetOrigin(self.GetOrigin()) 260 cloned.SetScale(self.GetScale()) 261 cloned.SetOrientation(self.GetOrientation()) 262 cloned.SetPosition(self.GetPosition()) 263 cloned.name = self.name 264 265 cloned.pipeline = utils.OperationNode( 266 "clone", parents=[self], shape='diamond', c='#bbe1ed', 267 ) 268 return cloned
Clone the UGrid object to yield an exact copy.
def
color(self, c=False, alpha=None):
270 def color(self, c=False, alpha=None): 271 """ 272 Set/get UGrid color. 273 If None is passed as input, will use colors from active scalars. 274 Same as `ugrid.c()`. 275 """ 276 if c is False: 277 return np.array(self.GetProperty().GetColor()) 278 if c is None: 279 self._mapper.ScalarVisibilityOn() 280 return self 281 self._mapper.ScalarVisibilityOff() 282 cc = colors.get_color(c) 283 self.property.SetColor(cc) 284 if self.trail: 285 self.trail.GetProperty().SetColor(cc) 286 if alpha is not None: 287 self.alpha(alpha) 288 return self
Set/get UGrid color.
If None is passed as input, will use colors from active scalars.
Same as ugrid.c()
.
def
alpha(self, opacity=None):
290 def alpha(self, opacity=None): 291 """Set/get mesh's transparency. Same as `mesh.opacity()`.""" 292 if opacity is None: 293 return self.property.GetOpacity() 294 295 self.property.SetOpacity(opacity) 296 bfp = self.GetBackfaceProperty() 297 if bfp: 298 if opacity < 1: 299 self._bfprop = bfp 300 self.SetBackfaceProperty(None) 301 else: 302 self.SetBackfaceProperty(self._bfprop) 303 return self
Set/get mesh's transparency. Same as mesh.opacity()
.
def
opacity(self, alpha=None):
305 def opacity(self, alpha=None): 306 """Set/get mesh's transparency. Same as `mesh.alpha()`.""" 307 return self.alpha(alpha)
Set/get mesh's transparency. Same as mesh.alpha()
.
def
wireframe(self, value=True):
309 def wireframe(self, value=True): 310 """Set mesh's representation as wireframe or solid surface. 311 Same as `mesh.wireframe()`.""" 312 if value: 313 self.property.SetRepresentationToWireframe() 314 else: 315 self.property.SetRepresentationToSurface() 316 return self
Set mesh's representation as wireframe or solid surface.
Same as mesh.wireframe()
.
def
linewidth(self, lw=None):
318 def linewidth(self, lw=None): 319 """Set/get width of mesh edges. Same as `lw()`.""" 320 if lw is not None: 321 if lw == 0: 322 self.property.EdgeVisibilityOff() 323 self.property.SetRepresentationToSurface() 324 return self 325 self.property.EdgeVisibilityOn() 326 self.property.SetLineWidth(lw) 327 else: 328 return self.property.GetLineWidth() 329 return self
Set/get width of mesh edges. Same as lw()
.
def
lw(self, linewidth=None):
331 def lw(self, linewidth=None): 332 """Set/get width of mesh edges. Same as `linewidth()`.""" 333 return self.linewidth(linewidth)
Set/get width of mesh edges. Same as linewidth()
.
def
linecolor(self, lc=None):
335 def linecolor(self, lc=None): 336 """Set/get color of mesh edges. Same as `lc()`.""" 337 if lc is not None: 338 if "ireframe" in self.property.GetRepresentationAsString(): 339 self.property.EdgeVisibilityOff() 340 self.color(lc) 341 return self 342 self.property.EdgeVisibilityOn() 343 self.property.SetEdgeColor(colors.get_color(lc)) 344 else: 345 return self.property.GetEdgeColor() 346 return self
Set/get color of mesh edges. Same as lc()
.
def
lc(self, linecolor=None):
348 def lc(self, linecolor=None): 349 """Set/get color of mesh edges. Same as `linecolor()`.""" 350 return self.linecolor(linecolor)
Set/get color of mesh edges. Same as linecolor()
.
def
extract_cell_type(self, ctype):
352 def extract_cell_type(self, ctype): 353 """Extract a specific cell type and return a new `UGrid`.""" 354 uarr = self._data.GetCellTypesArray() 355 ctarrtyp = np.where(utils.vtk2numpy(uarr) == ctype)[0] 356 uarrtyp = utils.numpy2vtk(ctarrtyp, deep=False, dtype="id") 357 selection_node = vtk.vtkSelectionNode() 358 selection_node.SetFieldType(vtk.vtkSelectionNode.CELL) 359 selection_node.SetContentType(vtk.vtkSelectionNode.INDICES) 360 selection_node.SetSelectionList(uarrtyp) 361 selection = vtk.vtkSelection() 362 selection.AddNode(selection_node) 363 es = vtk.vtkExtractSelection() 364 es.SetInputData(0, self._data) 365 es.SetInputData(1, selection) 366 es.Update() 367 ug = UGrid(es.GetOutput()) 368 369 ug.pipeline = utils.OperationNode( 370 "extract_cell_type", comment=f"type {ctype}", 371 c="#edabab", parents=[self], 372 ) 373 return ug
Extract a specific cell type and return a new UGrid
.
Inherited Members
- vedo.base.BaseGrid
- tomesh
- cells
- alpha_unit
- shrink
- isosurface
- legosurface
- cut_with_plane
- cut_with_box
- cut_with_mesh
- extract_cells_on_plane
- extract_cells_on_sphere
- extract_cells_on_cylinder
- clean
- find_cell
- extract_cells_by_id
- vedo.base.BaseActor
- mapper
- inputdata
- modified
- npoints
- ncells
- points
- cell_centers
- delete_cells
- mark_boundaries
- find_cells_in
- count_vertices
- lighting
- print_histogram
- c
- pointdata
- celldata
- metadata
- map_cells_to_points
- map_points_to_cells
- resample_data_from
- add_ids
- gradient
- divergence
- vorticity
- add_scalarbar
- add_scalarbar3d
- write