def test_init_bad_input(): with pytest.raises(Exception): unstruct_grid = vtki.UnstructuredGrid(np.array(1)) with pytest.raises(Exception): unstruct_grid = vtki.UnstructuredGrid(np.array(1), np.array(1), np.array(1), 'woa')
def test_init_bad_filename(): filename = os.path.join(test_path, 'test_grid.py') with pytest.raises(Exception): grid = vtki.UnstructuredGrid(filename) with pytest.raises(Exception): grid = vtki.UnstructuredGrid('not a file')
def beam_example(off_screen=False, notebook=None): # Load module and example file hexfile = hexbeamfile # Load Grid grid = vtki.UnstructuredGrid(hexfile) # Create fiticious displacements as a function of Z location d = grid.points[:, 2]**3 / 250 grid.points[:, 1] += d # Camera position cpos = [(11.915126303095157, 6.11392754955802, 3.6124956735471914), (0.0, 0.375, 2.0), (-0.42546442225230097, 0.9024244135964158, -0.06789847673314177)] try: import matplotlib cmap = 'bwr' except ImportError: cmap = None # plot this displaced beam plotter = vtki.Plotter(off_screen=off_screen, notebook=notebook) plotter.add_mesh(grid, scalars=d, stitle='Y Displacement', rng=[-d.max(), d.max()], cmap=cmap) plotter.camera_position = cpos plotter.add_text('Static Beam Example') cpos = plotter.plot(auto_close=False) # store camera position # plotter.TakeScreenShot('beam.png') plotter.close()
def grid(self): """ Returns a vtkInterface unstructured grid """ if not hasattr(self, 'node'): raise Exception('Run Tetrahedralize first') if hasattr(self, '_grid') and not self._updated: return self._grid buf = np.empty((self.elem.shape[0], 1), np.int64) cell_type = np.empty(self.elem.shape[0], dtype='uint8') if self.elem.shape[1] == 4: # linear buf[:] = 4 cell_type[:] = 10 elif self.elem.shape[1] == 10: # quadradic buf[:] = 10 cell_type[:] = 24 else: raise Exception('Invalid element array shape %s' % str(self.elem.shape)) offset = np.cumsum(buf + 1) - (buf[0] + 1) cells = np.hstack((buf, self.elem)) self._grid = vtki.UnstructuredGrid(offset, cells, cell_type, self.node) self._updated = False return self._grid
def test_save(extension, binary, tmpdir): filename = str(tmpdir.mkdir("tmpdir").join('tmp.%s' % extension)) beam.save(filename, binary) grid = vtki.UnstructuredGrid(filename) assert grid.cells.shape == beam.cells.shape assert grid.points.shape == beam.points.shape
def getDdnMeansOfAllTimeResultsForASimuFromWatertables(repo): os.chdir(repo) taille = len(glob.glob("VTU_WaterTable_*.vtu")) #Numpy Array to store the mean of ddn data for every stress period means_alongTheTime = np.ones(taille) * np.nan # One file stores a watertable (ddn data) of the geographical zone (matrix) for a stress period for file in glob.glob("VTU_WaterTable_*.vtu"): #Retrieving the number of the stress period from the filename m = re.search(r'VTU_WaterTable_(?P<num>\d+).vtu', file) if m is not None: ind = int(m.group('num')) #Retrieving the data from the file #Thanks to the vtki library gridcolor = vtki.UnstructuredGrid(repo + file) nbPointsColor = gridcolor.GetNumberOfCells() pointsColor = gridcolor.GetPoints() # Retrieving the ddn data for every cell of the geographical zone # With the vtki library, it means retreiving the data from the points ddn = [] for i in range(0, nbPointsColor): ptcol = pointsColor.GetPoint(i) ddn.append(ptcol[2]) #Transforming the list into a numpy array #It will be easier to calculate the means with this type of data structure ddn_np = np.array(ddn) #Storing the mean for the stress period number 'ind' means_alongTheTime[ind] = ddn_np.mean() return means_alongTheTime
def test_init_from_arrays(): offset = np.array([0, 9], np.int8) 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.int32) 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)).astype(np.int32) grid = vtki.UnstructuredGrid(offset, cells, cell_type, points) assert grid.n_cells == 2 assert np.allclose(grid.offset, offset)
def read(filename): """This will read any VTK file! It will figure out what reader to use then wrap the VTK object for use in ``vtki`` """ def legacy(filename): reader = vtk.vtkDataSetReader() reader.SetFileName(filename) reader.Update() return reader.GetOutputDataObject(0) ext = os.path.splitext(filename)[1] if ext.lower() in '.vtk': # Use a legacy reader and wrap the result return wrap(legacy(filename)) else: # From the extension, decide which reader to use if ext.lower() in '.vti': # ImageData return vtki.UniformGrid(filename) elif ext.lower() in '.vtr': # RectilinearGrid return vtki.RectilinearGrid(filename) elif ext.lower() in '.vtu': # UnstructuredGrid return vtki.UnstructuredGrid(filename) elif ext.lower() in '.ply': # PolyData return vtki.PolyData(filename) elif ext.lower() in '.vts': # UnstructuredGrid return vtki.StructuredGrid(filename) else: # Attempt to use the legacy reader... try: return wrap(legacy(filename)) except: pass raise IOError("This file was not able to be automatically read by vtki.")
def test_write_non_ansys_grid(tmpdir): grid = vtki.UnstructuredGrid(vtki_examples.hexbeamfile) del grid.point_arrays['ANSYSnodenum'] del grid.cell_arrays['ANSYSelemnum'] try: archive_file = str(tmpdir.mkdir("tmpdir").join('tmp.cdb')) except: archive_file = '/tmp/nblock.cdb' pyansys.save_as_archive(archive_file, grid)
def test_rotate_z(): angle = 30 trans = vtk.vtkTransform() trans.RotateZ(angle) trans.Update() trans_filter = vtk.vtkTransformFilter() trans_filter.SetTransform(trans) trans_filter.SetInputData(grid) trans_filter.Update() grid_a = vtki.UnstructuredGrid(trans_filter.GetOutput()) grid_b = grid.copy() grid_b.rotate_z(angle) assert np.allclose(grid_a.points, grid_b.points)
def test_get_scalar(): grid = vtki.UnstructuredGrid(ex.hexbeamfile) # add array to both point/cell data with same name carr = np.random.rand(grid.n_cells) grid._add_cell_scalar(carr, 'test_data') parr = np.random.rand(grid.n_points) grid._add_point_scalar(parr, 'test_data') oarr = np.random.rand(grid.n_points) grid._add_point_scalar(oarr, 'other') assert np.allclose( carr, utilities.get_scalar(grid, 'test_data', preference='cell')) assert np.allclose( parr, utilities.get_scalar(grid, 'test_data', preference='point')) assert np.allclose(oarr, utilities.get_scalar(grid, 'other')) assert None == utilities.get_scalar(grid, 'foo')
def test_save_as_vtk(tmpdir): filename = str(tmpdir.mkdir("tmpdir").join('tmp.vtk')) result = pyansys.open_result(examples.rstfile) result.save_as_vtk(filename) grid = vtki.UnstructuredGrid(filename) for i in range(result.nsets): assert 'nodal_solution%03d' % i in grid.point_arrays arr = grid.point_arrays['nodal_solution%03d' % i] assert np.allclose(arr, result.nodal_solution(i)[1], atol=1E-5) assert 'nodal_stress%03d' % i in grid.point_arrays arr = grid.point_arrays['nodal_stress%03d' % i] assert np.allclose(arr, result.nodal_stress(i)[1], atol=1E-5, equal_nan=True)
def read(filename, attrs=None): """This will read any VTK file! It will figure out what reader to use then wrap the VTK object for use in ``vtki``. Parameters ---------- attrs : dict, optional A dictionary of attributes to call on the reader. Keys of dictionary are the attribute/method names and values are the arguments passed to those calls. If you do not have any attributes to call, pass ``None`` as the value. """ filename = os.path.abspath(os.path.expanduser(filename)) ext = get_ext(filename) # From the extension, decide which reader to use if attrs is not None: reader = get_reader(filename) return standard_reader_routine(reader, filename, attrs=attrs) elif ext in '.vti': # ImageData return vtki.UniformGrid(filename) elif ext in '.vtr': # RectilinearGrid return vtki.RectilinearGrid(filename) elif ext in '.vtu': # UnstructuredGrid return vtki.UnstructuredGrid(filename) elif ext in ['.ply', '.obj', '.stl']: # PolyData return vtki.PolyData(filename) elif ext in '.vts': # StructuredGrid return vtki.StructuredGrid(filename) elif ext in ['.vtm', '.vtmb']: return vtki.MultiBlock(filename) elif ext in ['.e', '.exo']: return read_exodus(filename) elif ext in ['.vtk']: # Attempt to use the legacy reader... return read_legacy(filename) else: # Attempt find a reader in the readers mapping try: reader = get_reader(filename) return standard_reader_routine(reader, filename) except KeyError: pass raise IOError("This file was not able to be automatically read by vtki.")
def AddCyclicProperties(self, tol=1E-5): """ Adds cyclic properties to result object Makes the assumption that all the cyclic nodes are within tol """ if self.resultheader['csCord'] != 1: warnings.warn('Cyclic coordinate system %d' % self.resultheader['csCord']) # idenfity the sector based on number of elements in master sector cs_els = self.resultheader['csEls'] mask = self.quadgrid.cell_arrays['ansys_elem_num'] <= cs_els # node_mask = self.geometry['nnum'] <= self.resultheader['csNds'] node_mask = self.nnum <= self.resultheader['csNds'] self.master_cell_mask = mask self.grid = self.grid.extract_cells(mask) # number of nodes in sector may not match number of nodes in geometry self.mas_ind = np.nonzero(node_mask)[0] # duplicate sector may not exist if not np.any(self.geometry['nnum'] > self.resultheader['csNds']): self.dup_ind = None else: shift = (self.geometry['nnum'] < self.resultheader['csNds']).sum() self.dup_ind = self.mas_ind + shift + 1 # create full rotor self.nsector = self.resultheader['nSector'] # Create rotor of sectors vtkappend = vtk.vtkAppendFilter() rang = 360.0 / self.nsector for i in range(self.nsector): # Transform mesh sector = self.grid.copy() sector.rotate_z(rang * i) vtkappend.AddInputData(sector) vtkappend.Update() self.rotor = vtki.UnstructuredGrid(vtkappend.GetOutput())
def getDdnMeansOfAllTimeResultsForASimuFromWatertablesForRiskZonesWithoutSea( repo, averageSeaLevel, upperLimitForRiskZone): os.chdir(repo) taille = len(glob.glob("VTU_WaterTable_*.vtu")) # Numpy Array to store the mean of ddn data for every stress period means_alongTheTime = np.ones(taille) * np.nan # One file stores a watertable (ddn data) of the geographical zone (matrix) for a stress period for file in glob.glob("VTU_WaterTable_*.vtu"): # Retrieving the number of the stress period from the filename m = re.search(r'VTU_WaterTable_(?P<num>\d+).vtu', file) if m is not None: ind = int(m.group('num')) # Retrieving the ddn data from the file # Thanks to the vtki library gridcolor = vtki.UnstructuredGrid(repo + file) nbPointsColor = gridcolor.GetNumberOfCells() pointsColor = gridcolor.GetPoints() # Retrieving the ddn data for every cell of the geographical zone # With the vtki library, it means retreiving the data from the points ddn = [] for i in range(0, nbPointsColor): ptcol = pointsColor.GetPoint(i) # Storing the ddn values only if they are below 1m and not equal to the default average sea level if (ptcol[2] < upperLimitForRiskZone) and (ptcol[2] != averageSeaLevel): ddn.append(ptcol[2]) # Transforming the list into a numpy array # It will be easier to calculate the means with this type of data structure ddn_np = np.array(ddn) if (ddn_np.size == 0): means_alongTheTime[ind] = np.NaN else: means_alongTheTime[ind] = ddn_np.mean() return means_alongTheTime
import sys import numpy as np import pytest import vtk import vtki from vtki import examples grid = vtki.UnstructuredGrid(examples.hexbeamfile) py2 = sys.version_info.major == 2 def test_point_arrays(): key = 'test_array' grid.point_arrays[key] = np.arange(grid.n_points) assert key in grid.point_arrays orig_value = grid.point_arrays[key][0] / 1.0 grid.point_arrays[key][0] += 1 assert orig_value == grid._point_scalar(key)[0] - 1 del grid.point_arrays[key] assert key not in grid.point_arrays grid.point_arrays[key] = np.arange(grid.n_points) assert key in grid.point_arrays def test_point_arrays_bad_value():
def load_hexbeam(): """ Loads a sample UnstructuredGrid """ return vtki.UnstructuredGrid(hexbeamfile)
def quiver3d(self, x, y, z, u, v, w, color, scale, mode, resolution=8, glyph_height=None, glyph_center=None, glyph_resolution=None, opacity=1.0, scale_mode='none', scalars=None, backface_culling=False): factor = scale vectors = np.c_[u, v, w] points = np.vstack(np.c_[x, y, z]) n_points = len(points) offset = np.arange(n_points) * 3 cell_type = np.full(n_points, vtk.VTK_VERTEX) cells = np.c_[np.full(n_points, 1), range(n_points)] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=FutureWarning) grid = vtki.UnstructuredGrid(offset, cells, cell_type, points) grid.point_arrays['vec'] = vectors if scale_mode == "scalar": grid.point_arrays['mag'] = np.array(scalars) scale = 'mag' else: scale = False if mode == "arrow": self.plotter.add_mesh(grid.glyph(orient='vec', scale=scale, factor=factor), color=color, opacity=opacity, backface_culling=backface_culling) elif mode == "cone": cone = vtk.vtkConeSource() if glyph_height is not None: cone.SetHeight(glyph_height) if glyph_center is not None: cone.SetCenter(glyph_center) if glyph_resolution is not None: cone.SetResolution(glyph_resolution) cone.Update() geom = cone.GetOutput() self.plotter.add_mesh(grid.glyph(orient='vec', scale=scale, factor=factor, geom=geom), color=color, opacity=opacity, backface_culling=backface_culling) elif mode == "cylinder": cylinder = vtk.vtkCylinderSource() cylinder.SetHeight(glyph_height) cylinder.SetCenter(glyph_center) cylinder.SetResolution(glyph_resolution) cylinder.Update() # fix orientation tr = vtk.vtkTransform() tr.RotateWXYZ(90, 0, 0, 1) trp = vtk.vtkTransformPolyDataFilter() trp.SetInputData(cylinder.GetOutput()) trp.SetTransform(tr) trp.Update() geom = trp.GetOutput() self.plotter.add_mesh(grid.glyph(orient='vec', scale=scale, factor=factor, geom=geom), color=color, opacity=opacity, backface_culling=backface_culling)
def test_save_bad_extension(): with pytest.raises(Exception): grid = vtki.UnstructuredGrid('file.abc')
def parse_vtk(self, force_linear=False, allowable_types=None, null_unallowed=False): """ Parses raw data from cdb file to VTK format. Parameters ---------- force_linear : bool, optional This parser creates quadradic elements if available. Set this to True to always create linear elements. Defaults to False. allowable_types : list, optional Allowable element types. Defaults to: ['45', '95', '185', '186', '92', '187'] See help(pyansys.elements) for available element types. null_unallowed : bool, optional Elements types not matching element types will be stored as empty (null) elements. Useful for debug or tracking element numbers. Default False. Returns ------- uGrid : vtk.vtkUnstructuredGrid VTK unstructured grid from archive file. """ if self.check_raw(): raise Exception( 'Missing key data. Cannot parse into unstructured grid') # Convert to vtk style arrays if allowable_types is None: allowable_types = ['45', '95', '185', '186', '92', '187'] else: assert isinstance(allowable_types, list), \ 'allowable_types must be a list' for eletype in allowable_types: if str(eletype) not in valid_types: raise Exception('Element type "%s" ' % eletype + 'cannot be parsed in pyansys') # parse raw output parsed = _parser.Parse(self.raw, force_linear, allowable_types, null_unallowed) cells = parsed['cells'] offset = parsed['offset'] cell_type = parsed['cell_type'] numref = parsed['numref'] enum = parsed['enum'] # catch bug # if np.any(cells > numref.max()): # import pdb; pdb.set_trace() # cells[cells > numref.max()] == 0 # Check for missing midside nodes if force_linear or np.all(cells != -1): nodes = self.raw['nodes'][:, :3].copy() nnum = self.raw['nnum'] else: mask = cells == -1 nextra = mask.sum() maxnum = numref.max() + 1 cells[mask] = np.arange(maxnum, maxnum + nextra) nnodes = self.raw['nodes'].shape[0] nodes = np.zeros((nnodes + nextra, 3)) nodes[:nnodes] = self.raw['nodes'][:, :3] # Set new midside nodes directly between their edge nodes temp_nodes = nodes.copy() _relaxmidside.ResetMidside(cells, temp_nodes) nodes[nnodes:] = temp_nodes[nnodes:] # merge nodes new_nodes = temp_nodes[nnodes:] unique_nodes, idxA, idxB = unique_rows(new_nodes) # rewrite node numbers cells[mask] = idxB + maxnum nextra = idxA.shape[0] nodes = np.zeros((nnodes + nextra, 3)) nodes[:nnodes] = self.raw['nodes'][:, :3] nodes[nnodes:] = unique_nodes # Add extra node numbers nnum = np.hstack( (self.raw['nnum'], np.ones(nextra, np.int32) * -1)) # Create unstructured grid grid = vtki.UnstructuredGrid(offset, cells, cell_type, nodes) # Store original ANSYS element and cell information grid.point_arrays['ansys_node_num'] = nnum grid.cell_arrays['ansys_elem_num'] = enum grid.cell_arrays['ansys_elem_type_num'] = parsed['etype'] grid.cell_arrays['ansys_real_constant'] = parsed['rcon'] grid.cell_arrays['ansys_material_type'] = parsed['mtype'] grid.cell_arrays['ansys_etype'] = parsed['ansys_etype'] # Add element components to unstructured grid for comp in self.raw['elem_comps']: mask = np.in1d(enum, self.raw['elem_comps'][comp], assume_unique=True) grid.cell_arrays[comp.strip()] = mask # Add node components to unstructured grid for comp in self.raw['node_comps']: mask = np.in1d(nnum, self.raw['node_comps'][comp], assume_unique=True) grid.point_arrays[comp.strip()] = mask # Add tracker for original node numbering ind = np.arange(grid.number_of_points) grid.point_arrays['origid'] = ind grid.point_arrays['VTKorigID'] = ind self.vtkuGrid = grid return grid
def create_surface(points, z_range): """From the sorted x, y, and z station locations, create a surface to display a seismic recording/migration on in space. The result is defined in the X,Y,Z-z_range 3D space. The z_range should be treated as relative coordinates to the values given on the third column of the points array. If you want the values in the z_range to be treated as the absolute coordinates, simply do not pass any Z values in the points array - if points is N by 2, then the values in z_range will be inferred as absolute. Args: points (np.ndarray): array-like of the station x and y locations (npts by 2-3) z_range (np.ndarray): The linear space of the z dimension. This will be filled out for every station location. Return: vtki.UnstructuredGrid """ if hasattr(points, 'values'): # This will extract data from pandas dataframes if those are given points = points.values points = np.array(points) z_range = np.array(z_range) xloc = points[:, 0] yloc = points[:, 1] if points.shape[1] > 2: zloc = points[:, 2] else: val = np.nanmax(z_range) z_range = val - np.flip(z_range) zloc = np.full(xloc.shape, val) if not len(xloc) == len(yloc) == len(zloc): raise AssertionError('Coordinate shapes do not match.') nt = len(xloc) ns = len(z_range) # Extrapolate points to a 2D surface # repeat the XY locations across points = np.repeat(np.c_[xloc, yloc, zloc], ns, axis=0) # repeat the Z locations across tp = np.repeat(z_range.reshape((-1, len(z_range))), nt, axis=0) tp = zloc[:, None] - tp points[:, -1] = tp.ravel() # Create cell indices for that surface indexes = np.array(range(0, (nt * ns))) indexes = np.reshape(indexes, (nt, ns)) # Define the cell connectivity on the surface cellConn = np.zeros((nt - 1, ns - 1, 4), dtype=np.int) cellConn[:, :, 0] = indexes[:-1, :-1] cellConn[:, :, 1] = indexes[1:, :-1] cellConn[:, :, 2] = indexes[1:, 1:] cellConn[:, :, 3] = indexes[:-1, 1:] cellConn = cellConn.reshape((ns - 1) * (nt - 1), 4) cells = vtk.vtkCellArray() cells.SetNumberOfCells(cellConn.shape[0]) cells.SetCells(cellConn.shape[0], interface.convertCellConn(cellConn)) # Produce the output output = vtki.UnstructuredGrid() output.points = points output.SetCells(vtk.VTK_QUAD, cells) return output
def test_init_from_structured(): unstruct_grid = vtki.UnstructuredGrid(sgrid) assert unstruct_grid.points.shape[0] == x.size assert np.all(unstruct_grid.celltypes == 12)
def test_merge(): beamA = vtki.UnstructuredGrid(examples.hexbeamfile) beamB = beamA.copy() beamB.points[:, 1] += 1 beamA.Merge(beamB)
def test_init_from_unstructured(): grid = vtki.UnstructuredGrid(beam, deep=True) grid.points += 1 assert not np.any(grid.points == beam.points)