def initMixedTvtk2D(self): """ Initialise the actual 2 dimensional tvtk object This is for a mixed data type """ poly_type = tvtk.Polygon().cell_type #poly_type = tvtk.Polyhedron().cell_type self.ug = tvtk.UnstructuredGrid(points=self.points) cells = np.array(self.cells[self.cells.mask==False]) cell_array = tvtk.CellArray() cell_array.set_cells(self.Nc,cells) offsets = np.cumsum(self.nfaces) offsets = offsets - offsets[0] poly_types = [poly_type for ii in range(self.Nc)] pdb.set_trace() self.ug.set_cells(np.array(poly_types),offsets, cell_array) self.ug.cell_data.scalars = self.data self.ug.cell_data.scalars.name = 'suntans_scalar'
def initMixedTvtk2D(self): """ Initialise the actual 2 dimensional tvtk object This is for a mixed data type """ poly_type = tvtk.Polygon().cell_type ug = tvtk.UnstructuredGrid(points=self.points) # Fill all of the cells with the first points # this is a bit of a hack but works... cells = self.cells for ii in range(self.Nc): nf = self.nfaces[ii] cells[ii, nf::] = cells[ii, 0] #offsets, cells = self.to_metismesh() ##cells = np.array(self.cells[self.cells.mask==False]) #cell_array = tvtk.CellArray() #cell_array.set_cells(self.Nc,cells) ##offsets = np.cumsum(self.nfaces) ##offsets = offsets - offsets[0] #poly_types = [poly_type for ii in range(self.Nc)] ## ##self.ug.set_cells(np.array(poly_types),offsets, cell_array) ## For a single cell type ug.set_cells(poly_type, self.cells) ug.cell_data.scalars = self.data ug.cell_data.scalars.name = 'suntans_scalar' return ug
def vtk_cell_types(self): cell_types = np.empty(self.get_cell_count(), dtype=int) for (id, n_nodes) in enumerate(self.nodes_per_cell()): try: cell_types[id] = self._EDGE_COUNT_TO_TYPE[n_nodes] except KeyError: cell_types[id] = tvtk.Polygon().cell_type return cell_types
def write_vtk_mesh(mesh, fileName): node = mesh.entity('node') GD = mesh.geo_dimension() if GD == 2: node = np.concatenate( (node, np.zeros((node.shape[0], 1), dtype=mesh.ftype)), axis=1) ug = tvtk.UnstructuredGrid(points=node) if mesh.meshtype is 'hex': cell_type = tvtk.Hexahedron().cell_type cell = mesh.ds.cell elif mesh.meshtype is 'tri': cell_type = tvtk.Triangle().cell_type cell = mesh.ds.cell for key, value in mesh.cellData.items(): i = ug.cell_data.add_array(value) ug.cell_data.get_array(i).name = key for key, value in mesh.pointData.items(): i = ug.point_data.add_array(value) ug.point_data.get_array(i).name = key elif mesh.meshtype is 'polyhedron': cell_type = tvtk.Polygon().cell_type NF, faces = mesh.to_vtk() cell = tvtk.CellArray() cell.set_cells(NF, faces) elif mesh.meshtype is 'polygon': cell_type = tvtk.Polygon().cell_type NC, cells = mesh.to_vtk() cell = tvtk.CellArray() cell.set_cells(NC, cells) elif mesh.meshtype is 'tet': cell_type = tvtk.Tetra().cell_type cell = mesh.ds.cell for key, value in mesh.cellData.items(): i = ug.cell_data.add_array(value) ug.cell_data.get_array(i).name = key for key, value in mesh.pointData.items(): i = ug.point_data.add_array(value) ug.point_data.get_array(i).name = key ug.set_cells(cell_type, cell) write_data(ug, fileName)
def write_vtk_mesh(mesh, fileName): point = mesh.point if point.shape[1] == 2: point = np.concatenate( (point, np.zeros((point.shape[0], 1), dtype=np.float)), axis=1) ug = tvtk.UnstructuredGrid(points=point) if mesh.meshtype is 'hex': cell_type = tvtk.Hexahedron().cell_type cell = mesh.ds.cell elif mesh.meshtype is 'tri': cell_type = tvtk.Triangle().cell_type cell = mesh.ds.cell for key, value in mesh.cellData.items(): i = ug.cell_data.add_array(value) ug.cell_data.get_array(i).name = key for key, value in mesh.pointData.items(): i = ug.point_data.add_array(value) ug.point_data.get_array(i).name = key elif mesh.meshtype is 'polyhedron': cell_type = tvtk.Polygon().cell_type NF, faces = mesh.to_vtk() cell = tvtk.CellArray() cell.set_cells(NF, faces) ug.cell_data.scalars = mesh.cellData['flag'] elif mesh.meshtype is 'polygon': cell_type = tvtk.Polygon().cell_type NC, cells = mesh.to_vtk() cell = tvtk.CellArray() cell.set_cells(NC, cells) elif mesh.meshtype is 'tet': cell_type = tvtk.Tetra().cell_type cell = mesh.ds.cell for key, value in mesh.cellData.items(): i = ug.cell_data.add_array(value) ug.cell_data.get_array(i).name = key for key, value in mesh.pointData.items(): i = ug.point_data.add_array(value) ug.point_data.get_array(i).name = key ug.set_cells(cell_type, cell) write_data(ug, fileName)
def generate_unstrgrid_mesh(self, filter=0): points = global_variable.NODE_COORDINATES self.index = where(self.density >= (1.0 - filter))[0].tolist() cells = (global_variable.ELEMENT_ATTRIBUTES[self.index, :] - 1) if global_variable.GRID_TYPE == 'Polygon': cell_tpye = tvtk.Polygon().cell_type if global_variable.GRID_TYPE == 'Hexahedron': cell_tpye = tvtk.Hexahedron().cell_type grid = tvtk.UnstructuredGrid(points=points) grid.set_cells(cell_tpye, cells) return grid
def plotbathy3d(self, clims=None, zscale=None, **kwargs): """ Adds 3D plot of the bathymetry to the current scene """ # Create a new scene if there isn't one if 'fig' not in self.__dict__: self.newscene() if zscale is None: zscale = self.zscale depth = -self.dv if clims == None: clims = [depth.min(), depth.max()] # Create an unstructured grid object to interpolate cells onto points points = np.column_stack((self.xp, self.yp, 0.0 * self.xp)) tri_type = tvtk.Polygon().cell_type cells = self.cells for ii in range(self.Nc): nf = self.nfaces[ii] cells[ii, nf::] = cells[ii, 0] ug = tvtk.UnstructuredGrid(points=points) ug.set_cells(tri_type, cells) ug.cell_data.scalars = depth ug.cell_data.scalars.name = 'suntans_depth' # Interpolate the cell data onto the points F = mlab.pipeline.cell_to_point_data(ug) dp = mlab.pipeline.probe_data(F, self.xp, self.yp, 0.0 * self.xp) # Now set up a new object with the 3D points points = np.column_stack((self.xp, self.yp, dp * zscale)) ug = tvtk.UnstructuredGrid(points=points) ug.set_cells(tri_type, self.cells) ug.cell_data.scalars = depth ug.cell_data.scalars.name = 'suntans_depth' #ug.point_data.scalars = dp*self.zscale #ug.point_data.scalars.name = 'suntans_depth_nodes' # Plot as a 3D surface src = mlab.pipeline.add_dataset(ug) h = mlab.pipeline.surface(src, vmin=clims[0], vmax=clims[1], **kwargs) return h
def _build_triangle(self, cell, points): faces = tvtk.CellArray() polygon = tvtk.Polygon() polygon.point_ids.number_of_ids = 3 polygon.point_ids.set_id(0, 0) polygon.point_ids.set_id(1, 1) polygon.point_ids.set_id(2, 2) faces.insert_next_cell(polygon) cell_points = self._get_cell_points(cell, points) poly = Polyhedron(cell_points, faces) name = 'Triang-{}-{}-{}'.format(*cell) return poly, name
def _build_quadrilateral(self, cell, points): faces = tvtk.CellArray() polygon = tvtk.Polygon() polygon.point_ids.number_of_ids = 4 polygon.point_ids.set_id(0, 0) polygon.point_ids.set_id(1, 1) polygon.point_ids.set_id(2, 2) polygon.point_ids.set_id(3, 3) faces.insert_next_cell(polygon) cell_points = self._get_cell_points(cell, points) poly = Polyhedron(cell_points, faces) name = 'Quad-{}-{}-{}-{}'.format(*cell) return poly, name
def _build_tetrahedron(self, cell, points): faces = tvtk.CellArray() for i0,i1,i2 in [(0,1,2), (0,3,1), (0,2,3), (1,3,2)]: polygon = tvtk.Polygon() polygon.point_ids.number_of_ids = 3 polygon.point_ids.set_id(0, i0) polygon.point_ids.set_id(1, i1) polygon.point_ids.set_id(2, i2) faces.insert_next_cell(polygon) cell_points = self._get_cell_points(cell, points) poly = Polyhedron(cell_points, faces) name = 'Tetra-{}-{}-{}-{}'.format(*cell) return poly, name
def _build_voxel(self, cell, points): faces = tvtk.CellArray() for i0,i1,i2,i3 in [(0,1,3,2), (1,3,7,5), (5,7,6,4), (4,0,2,6), (6,2,3,7), (0,1,5,4)]: polygon = tvtk.Polygon() polygon.point_ids.number_of_ids = 4 polygon.point_ids.set_id(0, i0) polygon.point_ids.set_id(1, i1) polygon.point_ids.set_id(2, i2) polygon.point_ids.set_id(3, i3) faces.insert_next_cell(polygon) cell_points = self._get_cell_points(cell, points) poly = Polyhedron(cell_points, faces) name = 'Voxel-{}-{}-{}-{}-{}-{}-{}-{}'.format(*cell) return poly, name
def _VTKCellType(self): try: from tvtk.api import tvtk except ImportError as e: from enthought.tvtk.api import tvtk return tvtk.Polygon().cell_type
class Mesh2D(Mesh): def __init__(self, vertexCoords, faceVertexIDs, cellFaceIDs, communicator=serialComm, _RepresentationClass=_MeshRepresentation, _TopologyClass=_Mesh2DTopology): super(Mesh2D, self).__init__(vertexCoords=vertexCoords, faceVertexIDs=faceVertexIDs, cellFaceIDs=cellFaceIDs, communicator=communicator, _RepresentationClass=_RepresentationClass, _TopologyClass=_TopologyClass) def _calcScaleArea(self): return self.scale['length'] def _calcScaleVolume(self): return self.scale['length']**2 def _calcFaceAreas(self): faceVertexCoords = numerix.take(self.vertexCoords, self.faceVertexIDs, axis=1) tangent = faceVertexCoords[:, 1] - faceVertexCoords[:, 0] return numerix.sqrtDot(tangent, tangent) def _calcFaceNormals(self): faceVertexCoords = numerix.take(self.vertexCoords, self.faceVertexIDs, axis=1) t1 = faceVertexCoords[:, 1, :] - faceVertexCoords[:, 0, :] faceNormals = t1.copy() mag = numerix.sqrt(t1[1]**2 + t1[0]**2) faceNormals[0] = -t1[1] / mag faceNormals[1] = t1[0] / mag orientation = 1 - 2 * (numerix.dot(faceNormals, self.cellDistanceVectors) < 0) return faceNormals * orientation def _calcFaceTangents(self): # copy required to get internal memory ordering correct for inlining. faceTangents1 = numerix.array( (-self.faceNormals[1], self.faceNormals[0])).copy() faceTangents2 = numerix.zeros(faceTangents1.shape, 'd') return faceTangents1, faceTangents2 def _translate(self, vector): newCoords = self.vertexCoords + vector newmesh = Mesh2D(newCoords, self.faceVertexIDs, self.cellFaceIDs) return newmesh def __mul__(self, factor): newCoords = self.vertexCoords * factor newmesh = Mesh2D(newCoords, self.faceVertexIDs, self.cellFaceIDs) return newmesh def _calcOrderedCellVertexIDs(self): from fipy.tools.numerix import take NFac = self._maxFacesPerCell # numpy 1.1's MA.take doesn't like FlatIter. Call ravel() instead. cellVertexIDs0 = take(self.faceVertexIDs[0], self.cellFaceIDs.ravel()) cellVertexIDs1 = take(self.faceVertexIDs[1], self.cellFaceIDs.ravel()) cellVertexIDs = MA.where(self._cellToFaceOrientations.ravel() > 0, cellVertexIDs0, cellVertexIDs1) cellVertexIDs = numerix.reshape(cellVertexIDs, (NFac, -1)) return cellVertexIDs @getsetDeprecated def _getNonOrthogonality(self): return self._nonOrthogonality @property def _nonOrthogonality(self): exteriorFaceArray = numerix.zeros((self.faceCellIDs.shape[1], ), 'l') numerix.put(exteriorFaceArray, numerix.nonzero(self.exteriorFaces), 1) unmaskedFaceCellIDs = MA.filled(self.faceCellIDs, 0) # what we put in for the "fill" doesn't matter because only exterior # faces have anything masked, and exterior faces have their displacement # vectors set to zero. # # if it's an exterior face, make the "displacement vector" equal to zero # so the cross product will be zero. faceDisplacementVectors = \ numerix.where(numerix.array(zip(exteriorFaceArray, exteriorFaceArray)), 0.0, numerix.take(self._scaledCellCenters.swapaxes(0,1), unmaskedFaceCellIDs[1, :]) \ - numerix.take(self._scaledCellCenters.swapaxes(0,1), unmaskedFaceCellIDs[0, :])) faceDisplacementVectors = faceDisplacementVectors.swapaxes(0, 1) faceCrossProducts = (faceDisplacementVectors[0, :] * self.faceNormals[1,:]) \ - (faceDisplacementVectors[1, :] * self.faceNormals[0, :]) faceDisplacementVectorLengths = numerix.maximum(((faceDisplacementVectors[0, :] ** 2) \ + (faceDisplacementVectors[1, :] ** 2)) ** 0.5, 1.e-100) faceWeightedNonOrthogonalities = abs( faceCrossProducts / faceDisplacementVectorLengths) * self._faceAreas cellFaceWeightedNonOrthogonalities = numerix.take( faceWeightedNonOrthogonalities, self.cellFaceIDs) cellFaceAreas = numerix.take(self._faceAreas, self.cellFaceIDs) cellTotalWeightedValues = numerix.add.reduce( cellFaceWeightedNonOrthogonalities, axis=0) cellTotalFaceAreas = numerix.add.reduce(cellFaceAreas, axis=0) return (cellTotalWeightedValues / cellTotalFaceAreas) def extrude(self, extrudeFunc=lambda x: x + numerix.array( (0, 0, 1))[:, numerix.newaxis], layers=1): """ This function returns a new 3D mesh. The 2D mesh is extruded using the extrudeFunc and the number of layers. :Parameters: - `extrudeFunc`: function that takes the vertex coordinates and returns the displaced values - `layers`: the number of layers in the extruded mesh (number of times extrudeFunc will be called) >>> from fipy.meshes.nonUniformGrid2D import NonUniformGrid2D >>> print NonUniformGrid2D(nx=2,ny=2).extrude(layers=2).cellCenters [[ 0.5 1.5 0.5 1.5 0.5 1.5 0.5 1.5] [ 0.5 0.5 1.5 1.5 0.5 0.5 1.5 1.5] [ 0.5 0.5 0.5 0.5 1.5 1.5 1.5 1.5]] >>> from fipy.meshes.tri2D import Tri2D >>> print Tri2D().extrude(layers=2).cellCenters [[ 0.83333333 0.5 0.16666667 0.5 0.83333333 0.5 0.16666667 0.5 ] [ 0.5 0.83333333 0.5 0.16666667 0.5 0.83333333 0.5 0.16666667] [ 0.5 0.5 0.5 0.5 1.5 1.5 1.5 1.5 ]] """ return self._extrude(self, extrudeFunc, layers) def _extrude(self, mesh, extrudeFunc, layers): ## should extrude cnahe self rather than creating a new mesh? ## the following allows the 2D mesh to be in 3D space, this can be the case for a ## Gmsh2DIn3DSpace which would then be extruded. oldVertices = mesh.vertexCoords if oldVertices.shape[0] == 2: oldVertices = numerix.resize(oldVertices, (3, len(oldVertices[0]))) oldVertices[2] = 0 NCells = mesh.numberOfCells NFac = mesh.numberOfFaces NFacPerCell = mesh._maxFacesPerCell ## set up the initial data arrays new_shape = (max(NFacPerCell, 4), (1 + layers) * NCells + layers * NFac) faces = numerix.MA.masked_values(-numerix.ones(new_shape, 'l'), value=-1) orderedVertices = mesh._orderedCellVertexIDs faces[:NFacPerCell, :NCells] = orderedVertices vertices = oldVertices vert0 = mesh.faceVertexIDs faceCount = NCells for layer in range(layers): ## need this later initialFaceCount = faceCount ## build the vertices newVertices = extrudeFunc(oldVertices) vertices = numerix.concatenate((vertices, newVertices), axis=1) ## build the faces along the layers faces[:NFacPerCell, faceCount:faceCount + NCells] = orderedVertices + len(oldVertices[0]) * (layer + 1) try: # numpy 1.1 doesn't copy right side before assigning slice # See: http://www.mail-archive.com/[email protected]/msg09843.html faces[:NFacPerCell, faceCount:faceCount + NCells] = faces[:NFacPerCell, faceCount:faceCount + NCells][::-1, :].copy() except: faces[:NFacPerCell, faceCount:faceCount + NCells] = faces[:NFacPerCell, faceCount:faceCount + NCells][::-1, :] faceCount = faceCount + NCells vert1 = (vert0 + len(oldVertices[0]))[::-1, :] ## build the faces between the layers faces[:4, faceCount:faceCount + NFac] = numerix.concatenate( (vert0, vert1), axis=0)[::-1, :] vert0 = vert0 + len(oldVertices[0]) NCells = mesh.numberOfCells ## build the cells, the first layer has slightly different ordering if layer == 0: c0 = numerix.reshape(numerix.arange(NCells), (1, NCells)) cells = numerix.concatenate( (c0, c0 + NCells, mesh.cellFaceIDs + 2 * NCells), axis=0) else: newCells = numerix.concatenate( (c0, c0 + initialFaceCount, mesh.cellFaceIDs + faceCount), axis=0) newCells[0] = cells[1, -NCells:] cells = numerix.concatenate((cells, newCells), axis=1) ## keep a count of things for the next layer faceCount = faceCount + NFac oldVertices = newVertices ## return a new mesh, extrude could just as easily act on self return Mesh(vertices, faces, cells, communicator=mesh.communicator) @property def _VTKCellType(self): try: from tvtk.api import tvtk except ImportError, e: from enthought.tvtk.api import tvtk return tvtk.Polygon().cell_type
def _parse_OFF(cls, filename): points = tvtk.Points() faces = tvtk.CellArray() n_read = False vertices_read = faces_read = 0 fp_regexp = '(-?)(0[\.\d*]?|([1-9]\d*\.?\d*)|(\.\d+))([Ee][+-]?\d+)?' with open(filename, 'r') as _file: lines = _file.readlines() for i, line in enumerate(lines): line = line.strip() if i == 0 and line != 'OFF': raise Exception('Wrong format!') elif i == 0: continue if not line or line[0] == '#': continue if n_read is False: match = re.match('(\d+)\s+(\d+)\s+(\d+).*', line) if match is None: raise Exception('Wrong format!') n_verts = int(match.groups()[0]) n_faces = int(match.groups()[1]) n_read = True continue if vertices_read < n_verts: match = re.findall(fp_regexp, line) if not match: raise Exception('Wrong format!') x = float(match[0][1]) if match[0][0] == '-': x = -x y = float(match[1][1]) if match[1][0] == '-': y = -y z = float(match[2][1]) if match[2][0] == '-': z = -z points.insert_next_point((x, y, z)) vertices_read += 1 continue if faces_read < n_faces: # TODO: add support for non-triangular faces. match = re.match( '(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*(\d+)?.*', line) if match is None: raise Exception('Wrong format!') f_verts = int(match.groups()[0]) if f_verts not in [3, 4]: raise Exception( 'Faces should have three or four vertices!') vert0 = int(match.groups()[1]) vert1 = int(match.groups()[2]) vert2 = int(match.groups()[3]) polygon = tvtk.Polygon() polygon.point_ids.number_of_ids = f_verts polygon.point_ids.set_id(0, vert0) polygon.point_ids.set_id(1, vert1) polygon.point_ids.set_id(2, vert2) if f_verts == 4: vert3 = int(match.groups()[4]) polygon.point_ids.set_id(3, vert3) faces.insert_next_cell(polygon) faces_read += 1 continue return faces, points