def __init__(self,
                 poly_src: vtkPolyDataAlgorithm,
                 parent: Optional['QObject'] = None) -> None:
        super().__init__(parent=parent)
        self._poly_src = poly_src
        self.id = QUuid.createUuid().toString()
        self.actor = vtkActor()

        mapper = vtkPolyDataMapper()
        mapper.SetInputConnection(poly_src.GetOutputPort())
        self.actor.SetMapper(mapper)

        user_transform = vtkTransform()
        user_transform.Identity()
        user_transform.PostMultiply()
        self.actor.SetUserTransform(user_transform)

        self.actor.ComputeMatrix()
        transform = vtkTransform()
        transform.SetMatrix(self.actor.GetMatrix())

        self._coord_converter = vtkTransformPolyDataFilter()
        self._coord_converter.SetTransform(transform)
        self._coord_converter.AddInputData(poly_src.GetOutput())
        self._coord_converter.Update()

        self._voxelizer = VoxelSlicer()
        self._voxelizer.SetInputConnection(
            self._coord_converter.GetOutputPort())

        self.results = vtkActor()
        self._init_input_id_key()
        self._init_output_id_key(self.results)
예제 #2
0
def _arrow_glyph(grid, factor):
    glyph = vtkGlyphSource2D()
    glyph.SetGlyphTypeToArrow()
    glyph.FilledOff()
    glyph.Update()

    # fix position
    tr = vtkTransform()
    tr.Translate(0.5, 0., 0.)
    trp = vtkTransformPolyDataFilter()
    trp.SetInputConnection(glyph.GetOutputPort())
    trp.SetTransform(tr)
    trp.Update()

    alg = _glyph(
        grid,
        scale_mode='vector',
        scalars=False,
        orient='vec',
        factor=factor,
        geom=trp.GetOutputPort(),
    )
    mapper = vtkDataSetMapper()
    mapper.SetInputConnection(alg.GetOutputPort())
    return mapper
예제 #3
0
 def TransformPeelPosition(self, p):
     peel_transform = vtkTransform()
     if not np.all(np.equal(self.affine, np.eye(4))):
         affine_vtk = self.CreateTransformedVTKAffine()
         peel_transform.SetMatrix(affine_vtk)
     refpeelspace = vtkTransformPolyDataFilter()
     refpeelspace.SetInputData(self.peel[p])
     refpeelspace.SetTransform(peel_transform)
     refpeelspace.Update()
     currentPeel = refpeelspace.GetOutput()
     return currentPeel
예제 #4
0
    def _do_surface_creation(self, mask, mask_sFormMatrix=None):
        if mask_sFormMatrix is None:
            mask_sFormMatrix = vtkMatrix4x4()

        value = np.mean(mask.GetScalarRange())

        # Use the mask to create isosurface
        mc = vtkContourFilter()
        mc.SetInputData(mask)
        mc.SetValue(0, value)
        mc.ComputeNormalsOn()
        mc.Update()

        # Mask isosurface
        refSurface = mc.GetOutput()

        # Create a uniformly meshed surface
        tmpPeel = downsample(refSurface)
        # Standard space coordinates

        # Apply coordinate transform to the meshed mask
        mask_ijk2xyz = vtkTransform()
        mask_ijk2xyz.SetMatrix(mask_sFormMatrix)

        mask_ijk2xyz_filter = vtkTransformPolyDataFilter()
        mask_ijk2xyz_filter.SetInputData(tmpPeel)
        mask_ijk2xyz_filter.SetTransform(mask_ijk2xyz)
        mask_ijk2xyz_filter.Update()

        # Smooth the mesh
        tmpPeel = smooth(mask_ijk2xyz_filter.GetOutput())
        # Configure calculation of normals
        tmpPeel = fixMesh(tmpPeel)
        # Remove duplicate points etc
        # tmpPeel = cleanMesh(tmpPeel)
        # Generate triangles
        tmpPeel = upsample(tmpPeel)

        tmpPeel = smooth(tmpPeel)
        tmpPeel = fixMesh(tmpPeel)
        tmpPeel = cleanMesh(tmpPeel)

        refImageSpace2_xyz_transform = vtkTransform()
        refImageSpace2_xyz_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(np.linalg.inv(self.affine)))

        self.refImageSpace2_xyz = vtkTransformPolyDataFilter()
        self.refImageSpace2_xyz.SetTransform(refImageSpace2_xyz_transform)

        xyz2_refImageSpace_transform = vtkTransform()
        xyz2_refImageSpace_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(self.affine))

        self.xyz2_refImageSpace = vtkTransformPolyDataFilter()
        self.xyz2_refImageSpace.SetTransform(xyz2_refImageSpace_transform)

        currentPeel = tmpPeel
        self.currentPeelNo = 0
        currentPeel= self.MapImageOnCurrentPeel(currentPeel)

        newPeel = vtkPolyData()
        newPeel.DeepCopy(currentPeel)
        newPeel.DeepCopy(currentPeel)
        self.peel_normals = vtkFloatArray()
        self.peel_centers = vtkFloatArray()
        self.peel.append(newPeel)
        self.currentPeelActor = vtkActor()
        if not np.all(np.equal(self.affine, np.eye(4))):
            affine_vtk = self.CreateTransformedVTKAffine()
            self.currentPeelActor.SetUserMatrix(affine_vtk)
        self.GetCurrentPeelActor(currentPeel)
        self.peelActors.append(self.currentPeelActor)
        # locator will later find the triangle on the peel surface where the coil's normal intersect
        self.locator = vtkCellLocator()
        self.PeelDown(currentPeel)
예제 #5
0
 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,
              colormap=None,
              backface_culling=False,
              line_width=2.,
              name=None,
              glyph_width=None,
              glyph_depth=None,
              glyph_radius=0.15,
              solid_transform=None,
              *,
              clim=None):
     _check_option('mode', mode, ALLOWED_QUIVER_MODES)
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore", category=FutureWarning)
         factor = scale
         vectors = np.c_[u, v, w]
         points = np.vstack(np.c_[x, y, z])
         n_points = len(points)
         cell_type = np.full(n_points, VTK_VERTEX)
         cells = np.c_[np.full(n_points, 1), range(n_points)]
         args = (cells, cell_type, points)
         if not VTK9:
             args = (np.arange(n_points) * 3, ) + args
         grid = UnstructuredGrid(*args)
         if scalars is None:
             scalars = np.ones((n_points, ))
         _point_data(grid)['scalars'] = np.array(scalars)
         _point_data(grid)['vec'] = vectors
         if mode == '2darrow':
             return _arrow_glyph(grid, factor), grid
         elif mode == 'arrow':
             alg = _glyph(grid,
                          orient='vec',
                          scalars='scalars',
                          factor=factor)
             mesh = pyvista.wrap(alg.GetOutput())
         else:
             tr = None
             if mode == 'cone':
                 glyph = vtkConeSource()
                 glyph.SetCenter(0.5, 0, 0)
                 if glyph_radius is not None:
                     glyph.SetRadius(glyph_radius)
             elif mode == 'cylinder':
                 glyph = vtkCylinderSource()
                 if glyph_radius is not None:
                     glyph.SetRadius(glyph_radius)
             elif mode == 'oct':
                 glyph = vtkPlatonicSolidSource()
                 glyph.SetSolidTypeToOctahedron()
             else:
                 assert mode == 'sphere', mode  # guaranteed above
                 glyph = vtkSphereSource()
             if mode == 'cylinder':
                 if glyph_height is not None:
                     glyph.SetHeight(glyph_height)
                 if glyph_center is not None:
                     glyph.SetCenter(glyph_center)
                 if glyph_resolution is not None:
                     glyph.SetResolution(glyph_resolution)
                 tr = vtkTransform()
                 tr.RotateWXYZ(90, 0, 0, 1)
             elif mode == 'oct':
                 if solid_transform is not None:
                     assert solid_transform.shape == (4, 4)
                     tr = vtkTransform()
                     tr.SetMatrix(
                         solid_transform.astype(np.float64).ravel())
             if tr is not None:
                 # fix orientation
                 glyph.Update()
                 trp = vtkTransformPolyDataFilter()
                 trp.SetInputData(glyph.GetOutput())
                 trp.SetTransform(tr)
                 glyph = trp
             glyph.Update()
             geom = glyph.GetOutput()
             mesh = grid.glyph(orient='vec',
                               scale=scale_mode == 'vector',
                               factor=factor,
                               geom=geom)
         actor = _add_mesh(
             self.plotter,
             mesh=mesh,
             color=color,
             opacity=opacity,
             scalars=None,
             colormap=colormap,
             show_scalar_bar=False,
             backface_culling=backface_culling,
             clim=clim,
         )
     return actor, mesh
예제 #6
0
    def CreateSurfaceFromPolydata(self,
                                  polydata,
                                  overwrite=False,
                                  index=None,
                                  name=None,
                                  colour=None,
                                  transparency=None,
                                  volume=None,
                                  area=None,
                                  scalar=False):
        if self.convert_to_inv:
            # convert between invesalius and world space with shift in the Y coordinate
            matrix_shape = sl.Slice().matrix.shape
            spacing = sl.Slice().spacing
            img_shift = spacing[1] * (matrix_shape[1] - 1)
            affine = sl.Slice().affine.copy()
            affine[1, -1] -= img_shift
            affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine)

            polydata_transform = vtkTransform()
            polydata_transform.PostMultiply()
            polydata_transform.Concatenate(affine_vtk)

            transformFilter = vtkTransformPolyDataFilter()
            transformFilter.SetTransform(polydata_transform)
            transformFilter.SetInputData(polydata)
            transformFilter.Update()
            polydata = transformFilter.GetOutput()
            self.convert_to_inv = False

        normals = vtkPolyDataNormals()
        normals.SetInputData(polydata)
        normals.SetFeatureAngle(80)
        normals.AutoOrientNormalsOn()
        normals.Update()

        mapper = vtkPolyDataMapper()
        mapper.SetInputData(normals.GetOutput())
        if scalar:
            mapper.ScalarVisibilityOn()
        else:
            mapper.ScalarVisibilityOff()
        #  mapper.ImmediateModeRenderingOn() # improve performance

        actor = vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetBackfaceCulling(1)

        if overwrite:
            if index is None:
                index = self.last_surface_index
            surface = Surface(index=index)
        else:
            surface = Surface()

        if not colour:
            surface.colour = random.choice(const.SURFACE_COLOUR)
        else:
            surface.colour = colour
        surface.polydata = polydata

        if transparency:
            surface.transparency = transparency

        if name:
            surface.name = name

        # Append surface into Project.surface_dict
        proj = prj.Project()
        if overwrite:
            proj.ChangeSurface(surface)
        else:
            index = proj.AddSurface(surface)
            surface.index = index
            self.last_surface_index = index

        # Set actor colour and transparency
        actor.GetProperty().SetColor(surface.colour)
        actor.GetProperty().SetOpacity(1 - surface.transparency)

        if overwrite and self.actors_dict.keys():
            try:
                old_actor = self.actors_dict[index]
                Publisher.sendMessage('Remove surface actor from viewer',
                                      actor=old_actor)
            except KeyError:
                pass

        self.actors_dict[surface.index] = actor

        session = ses.Session()
        session.ChangeProject()

        # The following lines have to be here, otherwise all volumes disappear
        if not volume or not area:
            triangle_filter = vtkTriangleFilter()
            triangle_filter.SetInputData(polydata)
            triangle_filter.Update()

            measured_polydata = vtkMassProperties()
            measured_polydata.SetInputConnection(
                triangle_filter.GetOutputPort())
            measured_polydata.Update()
            volume = measured_polydata.GetVolume()
            area = measured_polydata.GetSurfaceArea()
            surface.volume = volume
            surface.area = area
            print(">>>>", surface.volume)
        else:
            surface.volume = volume
            surface.area = area

        self.last_surface_index = surface.index

        Publisher.sendMessage('Load surface actor into viewer', actor=actor)
        Publisher.sendMessage('Update surface info in GUI', surface=surface)
        return surface.index