def main(): # Create a square in the x-y plane. points = vtkPoints() points.InsertNextPoint(0.0, 0.0, 0.0) points.InsertNextPoint(1.0, 0.0, 0.0) points.InsertNextPoint(1.0, 1.0, 0.0) points.InsertNextPoint(0.0, 1.0, 0.0) # Create the polygon polygon = vtkPolygon() polygon.GetPoints().DeepCopy(points) polygon.GetPointIds().SetNumberOfIds(4) # The 4 corners of the square for i in range(4): polygon.GetPointIds().SetId(i, i) # Inputs p1 = [0.1, 0, -1.0] p2 = [0.1, 0, 1.0] tolerance = 0.001 # Outputs t = mutable(0) # Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) x = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] subId = mutable(0) iD = polygon.IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId) print('intersected? ', 'Yes' if iD == 1 else 'No') print('intersection: ', x)
def update_geometry(self, geometry: Field, patch: Patch, data: Array2D): super().update_geometry(geometry, patch, data) if not isinstance(patch.topology, StructuredTopology) and self.require_structured: raise TypeError( f"{self.writer_name} does not support unstructured grids") if isinstance(patch.topology, StructuredTopology) and self.allow_structured: if not isinstance(self.grid, vtkStructuredGrid): self.grid = vtkStructuredGrid() shape = patch.topology.shape while len(shape) < 3: shape = (*shape, 0) if not config.fix_orientation: shape = shape[::-1] self.grid.SetDimensions(*(s + 1 for s in shape)) elif not self.grid: self.grid = vtkUnstructuredGrid() data = ensure_ncomps(self.nan_filter(data), 3, allow_scalar=False) if config.fix_orientation: data = transpose(data, self.grid) points = vtkPoints() points.SetData(numpy_to_vtk(data)) self.grid.SetPoints(points) if isinstance(self.grid, vtkUnstructuredGrid): if patch.topology.celltype not in [Line(), Quad(), Hex()]: raise TypeError( f"Unexpected cell type found: needed line, quad or hex") cells = patch.topology.cells cells = np.hstack( [cells.shape[-1] * np.ones((len(cells), 1), dtype=int), cells]).ravel() cells = cells.astype('i8') cellarray = vtkCellArray() cellarray.SetCells(len(cells), numpy_to_vtkIdTypeArray(cells)) if patch.topology.celltype == Hex(): celltype = VTK_HEXAHEDRON elif patch.topology.celltype == Quad(): celltype = VTK_QUAD else: celltype = VTK_LINE self.grid.SetCells(celltype, cellarray)
def writepolydata(filename, points, normals, cells): polydata = vtkPolyData() vtkpoints = vtkPoints() vtkpoints.SetData(numpy_to_vtk(points)) polydata.SetPoints(vtkpoints) polydata.GetPointData().SetNormals(numpy_to_vtk(normals)) triangles = vtkCellArray() for i, j, k in cells: triangles.InsertNextCell(3) triangles.InsertCellPoint(i) triangles.InsertCellPoint(j) triangles.InsertCellPoint(k) polydata.SetPolys(triangles) wr = vtkPolyDataWriter() wr.SetFileName(filename) wr.SetInputData(polydata) wr.Write()
def write_poly_data(cls, var, filename: str, attr_names: str) -> None: vol = vtkPolyData() verts = vtkPoints() # noinspection PyArgumentList lines = vtkCellArray() # Retained, but not used. 'Fungus' is current, not 'Afumigatus' # if isinstance(var, AfumigatusCellTreeList): # adjacency = var.adjacency # # for i, j in adjacency.keys(): # if i != j: # line = vtkLine() # line.GetPointIds().SetId(0, i) # line.GetPointIds().SetId(1, j) # lines.InsertNextCell(line) # # el if not isinstance(var, CellList): raise NotImplementedError( f'Only supported CellTree or CellList for POLY_DATA. \ Got {type(var)}' ) for index in var.alive(): cell = var[index] # noinspection PyArgumentList verts.InsertNextPoint(cell['point'][2], cell['point'][1], cell['point'][0]) alive_cells = np.take(var.cell_data, var.alive()) for attr_name in attr_names: cell_attr = alive_cells[attr_name] scalars = numpy_to_vtk(num_array=cell_attr) scalars.SetName(attr_name) vol.GetPointData().AddArray(scalars) vol.SetPoints(verts) vol.SetLines(lines) writer = vtkPolyDataWriter() writer.SetFileName(filename) writer.SetInputData(vol) writer.Write()
def compute_tubes(trk, direction): """Compute and assign colors to a vtkTube for visualization of a single tract :param trk: nx3 array of doubles (x, y, z) point coordinates composing the tract :type trk: numpy.ndarray :param direction: nx3 array of int (x, y, z) RGB colors in the range 0 - 255 :type direction: numpy.ndarray :return: a vtkTubeFilter instance :rtype: vtkTubeFilter """ numb_points = trk.shape[0] points = vtkPoints() lines = vtkCellArray() colors = vtkUnsignedCharArray() colors.SetNumberOfComponents(4) k = 0 lines.InsertNextCell(numb_points) for j in range(numb_points): points.InsertNextPoint(trk[j, :]) colors.InsertNextTuple(direction[j, :]) lines.InsertCellPoint(k) k += 1 trk_data = vtkPolyData() trk_data.SetPoints(points) trk_data.SetLines(lines) trk_data.GetPointData().SetScalars(colors) # make it a tube trk_tube = vtkTubeFilter() trk_tube.SetRadius(0.5) trk_tube.SetNumberOfSides(4) trk_tube.SetInputData(trk_data) trk_tube.Update() return trk_tube
def convert_cells_to_vtk(cells: CellList) -> vtkPolyData: cell_data: CellData = cells.cell_data live_cells = cells.alive() cell_data = cell_data[live_cells] fields = dict(cell_data.dtype.fields) # type: ignore fields.pop('point') points = vtkPoints() poly = vtkPolyData() poly.SetPoints(points) if not len(cell_data): return poly # vtk uses coordinate ordering x, y, z while we use z, y, x. points.SetData(numpy_to_vtk(np.flip(cell_data['point'], axis=1))) point_data = poly.GetPointData() for field, (dtype, *_) in fields.items(): data = cell_data[field] # numpy_to_vtk doesn't handle bool for some reason if dtype == np.dtype('bool'): data = data.astype(np.dtype('uint8')) # noinspection PyBroadException try: scalar = numpy_to_vtk(data) except Exception: print(f'Unhandled data type in field {field}') continue scalar.SetName(field) point_data.AddArray(scalar) return poly
def RequestData(self, request, inInfoVec, outInfoVec): from vtkmodules.vtkCommonCore import vtkFloatArray, vtkPoints from vtkmodules.vtkCommonDataModel import ( vtkCellArray, vtkCompositeDataSet, vtkPartitionedDataSet, vtkPartitionedDataSetCollection, vtkPolyData) output = vtkPartitionedDataSetCollection.GetData(outInfoVec) partitioned_datasets = [] partitioned_dataset_names = [] # Parse line file if not self._filename: print_error("SAVGReader requires a FileName") return 0 # Stores lines of text from the file associated with each group of # geometries encountered. geometries = {"lines": [], "points": [], "poly": []} # Read the file and build up data structure to hold the primitives with open(self._filename, "r") as file: current = None for line in file: parts = line.split("#") line = parts[0].strip().lower() if len(line) < 1: continue if not_supported(line): continue if line.startswith("lin"): geometries["lines"].append({"rgba": None, "values": []}) current = geometries["lines"][-1] line_parts = line.split(" ") if len(line_parts) == 5: current["rgba"] = [float(n) for n in line_parts[1:]] elif line.startswith("point"): geometries["points"].append({ "rgba": None, "values": [], }) current = geometries["points"][-1] line_parts = line.split(" ") if len(line_parts) == 5: current["rgba"] = [float(n) for n in line_parts[1:]] elif line.startswith("poly"): geometries["poly"].append({ "rgba": None, "npts": None, "values": [], }) current = geometries["poly"][-1] line_parts = line.split(" ") if len(line_parts) == 2: current["npts"] = int(line_parts[1]) elif len(line_parts) == 6: current["rgba"] = [float(n) for n in line_parts[1:5]] current["npts"] = int(line_parts[5]) elif line.startswith("end"): current = None else: if current is not None: if "npts" in current and current["npts"] is not None: # polygon, known num pts per poly if len(current["values"]) == current["npts"]: # Reached the number of points for the current one, # start a new one. geometries["poly"].append({ "npts": current["npts"], "rgba": current["rgba"], "values": [] }) current = geometries["poly"][-1] pt, pt_col, pt_n = get_coords_from_line(line) if pt: current["values"].append({ "pos": pt, }) color = pt_col or current["rgba"] if color: current["values"][-1]["col"] = color if pt_n: current["values"][-1]["norm"] = pt_n # Build lines polydata if there were any lines if geometries["lines"]: line_points = vtkPoints() line_cells = vtkCellArray() line_point_colors = vtkFloatArray() line_point_colors.SetNumberOfComponents(4) line_point_colors.SetName("rgba_colors") line_point_normals = vtkFloatArray() line_point_normals.SetNumberOfComponents(3) line_point_normals.SetName("vertex_normals") pt_count = 0 for batch in geometries["lines"]: num_in_batch = len(batch["values"]) first_in_batch = True for coord in batch["values"]: if "pos" in coord: line_points.InsertNextPoint(coord["pos"]) if "norm" in coord: line_point_normals.InsertNextTuple(coord["norm"]) if "col" in coord: line_point_colors.InsertNextTuple(coord["col"]) if first_in_batch: line_cells.InsertNextCell(num_in_batch) first_in_batch = False line_cells.InsertCellPoint(pt_count) pt_count += 1 output_lines = vtkPolyData() output_lines.SetPoints(line_points) output_lines.SetLines(line_cells) if line_point_colors.GetNumberOfTuples() > 0: output_lines.GetPointData().AddArray(line_point_colors) if line_point_normals.GetNumberOfTuples() > 0: output_lines.GetPointData().AddArray(line_point_normals) ds = vtkPartitionedDataSet() ds.SetNumberOfPartitions(1) ds.SetPartition(0, output_lines) partitioned_datasets.append(ds) partitioned_dataset_names.append("Lines") # Build the points polydata if we found points if geometries["points"]: p_points = vtkPoints() p_cells = vtkCellArray() p_point_colors = vtkFloatArray() p_point_colors.SetNumberOfComponents(4) p_point_colors.SetName("rgba_colors") p_point_normals = vtkFloatArray() p_point_normals.SetNumberOfComponents(3) p_point_normals.SetName("vertex_normals") p_count = 0 for batch in geometries["points"]: num_in_batch = len(batch["values"]) first_in_batch = True for coord in batch["values"]: if "pos" in coord: p_points.InsertNextPoint(coord["pos"]) if "norm" in coord: p_point_normals.InsertNextTuple(coord["norm"]) if "col" in coord: p_point_colors.InsertNextTuple(coord["col"]) if first_in_batch: p_cells.InsertNextCell(num_in_batch) first_in_batch = False p_cells.InsertCellPoint(p_count) p_count += 1 output_points = vtkPolyData() output_points.SetPoints(p_points) output_points.SetVerts(p_cells) if p_point_colors.GetNumberOfTuples() > 0: output_points.GetPointData().AddArray(p_point_colors) if p_point_normals.GetNumberOfTuples() > 0: output_points.GetPointData().AddArray(p_point_normals) ds = vtkPartitionedDataSet() ds.SetNumberOfPartitions(1) ds.SetPartition(0, output_points) partitioned_datasets.append(ds) partitioned_dataset_names.append("Points") # Build the polygons if there were any if geometries["poly"]: poly_points = vtkPoints() poly_cells = vtkCellArray() poly_point_colors = vtkFloatArray() poly_point_colors.SetNumberOfComponents(4) poly_point_colors.SetName("rgba_colors") poly_point_normals = vtkFloatArray() poly_point_normals.SetNumberOfComponents(3) poly_point_normals.SetName("vertex_normals") pt_count = 0 for batch in geometries["poly"]: num_in_batch = len(batch["values"]) if num_in_batch < 1: continue first_in_batch = True for coord in batch["values"]: if "pos" in coord: poly_points.InsertNextPoint(coord["pos"]) if "norm" in coord: poly_point_normals.InsertNextTuple(coord["norm"]) if "col" in coord: poly_point_colors.InsertNextTuple(coord["col"]) if first_in_batch: np_in_cell = num_in_batch poly_cells.InsertNextCell(np_in_cell) first_in_batch = False poly_cells.InsertCellPoint(pt_count) pt_count += 1 output_polys = vtkPolyData() output_polys.SetPoints(poly_points) output_polys.SetPolys(poly_cells) if poly_point_colors.GetNumberOfTuples() > 0: output_polys.GetPointData().AddArray(poly_point_colors) if poly_point_normals.GetNumberOfTuples() > 0: output_polys.GetPointData().AddArray(poly_point_normals) ds = vtkPartitionedDataSet() ds.SetNumberOfPartitions(1) ds.SetPartition(0, output_polys) partitioned_datasets.append(ds) partitioned_dataset_names.append("Polygons") # Add any partioned datasets we created output.SetNumberOfPartitionedDataSets(len(partitioned_datasets)) for idx, pds in enumerate(partitioned_datasets): output.SetPartitionedDataSet(idx, pds) output.GetMetaData(idx).Set(vtkCompositeDataSet.NAME(), partitioned_dataset_names[idx]) return 1
def ascent_to_vtk(node, topology=None, extent=None): ''' Read from Ascent node ("topologies/" + topology) into VTK data. topology is one of the names returned by topology_names(node) or topology_names(node)[0] if the parameter is None ''' global _keep_around # we use the same Python interpreter between time steps _keep_around = [] if topology is None: topology = topology_names(node)[0] data = None coords = node["topologies/" + topology + "/coordset"] if (node["topologies/" + topology + "/type"] == "uniform"): # tested with noise data = vtkImageData() origin = np.array([ float(o) for o in [ node["coordsets/" + coords + "/origin/x"], node["coordsets/" + coords + "/origin/y"], node["coordsets/" + coords + "/origin/z"] ] ]) spacing = np.array([ float(s) for s in [ node["coordsets/" + coords + "/spacing/dx"], node["coordsets/" + coords + "/spacing/dy"], node["coordsets/" + coords + "/spacing/dz"] ] ]) if extent is None: data.SetDimensions(node["coordsets/" + coords + "/dims/i"], node["coordsets/" + coords + "/dims/j"], node["coordsets/" + coords + "/dims/k"]) data.SetOrigin(origin) else: data.SetExtent(extent) origin = origin - np.array([extent[0], extent[2], extent[4] ]) * spacing data.SetOrigin(origin) data.SetSpacing(spacing) elif (node["topologies/" + topology + "/type"] == "rectilinear"): # tested on cloverleaf3d and kripke data = vtkRectilinearGrid() xn = node["coordsets/" + coords + "/values/x"] xa = numpy_support.numpy_to_vtk(xn) data.SetXCoordinates(xa) yn = node["coordsets/" + coords + "/values/y"] ya = numpy_support.numpy_to_vtk(yn) data.SetYCoordinates(ya) zn = node["coordsets/" + coords + "/values/z"] za = numpy_support.numpy_to_vtk(zn) data.SetZCoordinates(za) if (extent is None): data.SetDimensions(xa.GetNumberOfTuples(), ya.GetNumberOfTuples(), za.GetNumberOfTuples()) else: data.SetExtent(extent) elif (node["coordsets/" + coords + "/type"] == "explicit"): xn = node["coordsets/" + coords + "/values/x"] yn = node["coordsets/" + coords + "/values/y"] zn = node["coordsets/" + coords + "/values/z"] xyzn = np.stack((xn, yn, zn), axis=1) _keep_around.append(xyzn) xyza = numpy_support.numpy_to_vtk(xyzn) points = vtkPoints() points.SetData(xyza) if (node["topologies/" + topology + "/type"] == "structured"): # tested on lulesh data = vtkStructuredGrid() data.SetPoints(points) # elements are one less than points nx = node["topologies/" + topology + "/elements/dims/i"] + 1 ny = node["topologies/" + topology + "/elements/dims/j"] + 1 nz = node["topologies/" + topology + "/elements/dims/k"] + 1 data.SetDimensions(nx, ny, nz) elif (node["topologies/" + topology + "/type"] == "unstructured"): # tested with laghos data = vtkUnstructuredGrid() data.SetPoints(points) shape = node["topologies/" + topology + "/elements/shape"] c = node["topologies/" + topology + "/elements/connectivity"] # vtkIdType is int64 c = c.astype(np.int64) if (shape == "hex"): npoints = 8 cellType = vtkConstants.VTK_HEXAHEDRON elif (shape == "quad"): npoints = 4 cellType = vtkConstants.VTK_QUAD else: print("Error: Shape not implemented") return None c = c.reshape(c.shape[0] / npoints, npoints) # insert the number of points before point references c = np.insert(c, 0, npoints, axis=1) ncells = c.shape[0] c = c.flatten() _keep_around.append(c) ita = numpy_support.numpy_to_vtkIdTypeArray(c) cells = vtkCellArray() cells.SetCells(ncells, ita) data.SetCells((cellType), cells) read_fields(node, topology, data) return data
def _export_to_vtk_cyl(self, filename: str): """Does not work well if the Cylinder has only one angular int""" # Export to VTS format struct_grid = vtkCommonDataModel.vtkStructuredGrid() dimensions = [ len(self.vector_k), len(self.vector_i), len(self.vector_j) ] struct_grid.SetDimensions(*dimensions) vtk_points = vtkCommonCore.vtkPoints() vtk_points.Allocate(dimensions[0] * dimensions[1] * dimensions[2], 0) points = [] bar = tqdm(unit=' J slices', desc=' Writing', total=len(self.vector_j)) for j in self.vector_j: for i in self.vector_i: for k in self.vector_k: theta = k * 2 * np.pi point = [i * np.cos(theta), i * np.sin(theta), j] points.append(point) bar.update() bar.close() # TODO: Rotate the cylinder according to the mesh axis points = np.array( points) + self.origin # Displace the points to the origin for i in range(len(points)): vtk_points.InsertPoint(i, points[i]) struct_grid.SetPoints(vtk_points) # Add the data arrays cell_data: vtkCommonDataModel.vtkCellData = struct_grid.GetCellData() for particle in self.particles: for energy in self.energies[particle]: # The array should have the order: k,i,j instead of k, j, i array_name = f'{particle}_{energy:.3e}MeV' val_array = self.values[particle][energy] val_array = val_array.swapaxes( 1, 2) # Swap the i axis with the j axis => k,i,j # Now we swap the axes again so in the flatten operation we would be looping like j,i,k instead of k,i,j val_array = val_array.swapaxes( 0, 2) # Swap the k axis with the j axis => j,i,k val_array = val_array.flatten() vtk_array = numpy_to_vtk(val_array, deep=True, array_type=vtkCommonCore.VTK_DOUBLE) vtk_array.SetName(array_name) cell_data.AddArray(vtk_array) # If the ratios are calculated add them to the data arrays if self.ratios is not None: for particle in self.particles: for energy in self.energies[particle]: # The array should have the order: k,i,j instead of k, j, i array_name = f'Max_ratio_{particle}_{energy:.3e}MeV' val_array = self.ratios[particle][energy] val_array = val_array.swapaxes( 1, 2) # Swap the i axis with the j axis => k,i,j # Now we swap the axes again so in the flatten operation we would be looping like j,i,k val_array = val_array.swapaxes( 0, 2) # Swap the k axis with the j axis => j,i,k val_array = val_array.flatten() vtk_array = numpy_to_vtk( val_array, deep=True, array_type=vtkCommonCore.VTK_DOUBLE) vtk_array.SetName(array_name) cell_data.AddArray(vtk_array) # The array should have the order: k,i,j instead of k, j, i array_name = f'Total_max_ratio_{particle}' val_array = self.ratios_total_max[particle] val_array = val_array.swapaxes( 1, 2) # Swap the i axis with the j axis => k,i,j # Now we swap the axes again so in the flatten operation we would be looping like j,i,k val_array = val_array.swapaxes( 0, 2) # Swap the k axis with the j axis => j,i,k val_array = val_array.flatten() vtk_array = numpy_to_vtk(val_array, deep=True, array_type=vtkCommonCore.VTK_DOUBLE) vtk_array.SetName(array_name) cell_data.AddArray(vtk_array) writer = vtkIOXML.vtkXMLStructuredGridWriter() writer.SetInputData(struct_grid) writer.SetFileName(filename + '.vts') writer.Write() return