예제 #1
0
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)
예제 #2
0
    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)
예제 #3
0
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()
예제 #5
0
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
예제 #6
0
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
예제 #7
0
    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
예제 #8
0
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
예제 #9
0
    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