def clipSurfacesForFullLVMesh(endo, epi, verbose=1): myVTK.myPrint(verbose, "*** clipSurfacesForFullLVMesh ***") endo_implicit_distance = vtk.vtkImplicitPolyDataDistance() endo_implicit_distance.SetInput(endo) epi_implicit_distance = vtk.vtkImplicitPolyDataDistance() epi_implicit_distance.SetInput(epi) epi_clip = vtk.vtkClipPolyData() epi_clip.SetInputData(epi) epi_clip.SetClipFunction(endo_implicit_distance) epi_clip.GenerateClippedOutputOn() epi_clip.Update() clipped_epi = epi_clip.GetOutput(0) clipped_valve = epi_clip.GetOutput(1) endo_clip = vtk.vtkClipPolyData() endo_clip.SetInputData(endo) endo_clip.SetClipFunction(epi_implicit_distance) endo_clip.InsideOutOn() endo_clip.Update() clipped_endo = endo_clip.GetOutput(0) return (clipped_endo, clipped_epi, clipped_valve)
def clipSurfacesForFullLVMesh(endo, epi, verbose=0): myVTK.myPrint(verbose, "*** clipSurfacesForFullLVMesh ***") endo_implicit_distance = vtk.vtkImplicitPolyDataDistance() endo_implicit_distance.SetInput(endo) epi_implicit_distance = vtk.vtkImplicitPolyDataDistance() epi_implicit_distance.SetInput(epi) epi_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): epi_clip.SetInputData(epi) else: epi_clip.SetInput(epi) epi_clip.SetClipFunction(endo_implicit_distance) epi_clip.GenerateClippedOutputOn() epi_clip.Update() clipped_epi = epi_clip.GetOutput(0) clipped_valve = epi_clip.GetOutput(1) endo_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): endo_clip.SetInputData(endo) else: endo_clip.SetInput(endo) endo_clip.SetClipFunction(epi_implicit_distance) endo_clip.InsideOutOn() endo_clip.Update() clipped_endo = endo_clip.GetOutput(0) return (clipped_endo, clipped_epi, clipped_valve)
def clipSurfacesForFullBiVMesh(pdata_endLV, pdata_endRV, pdata_epi, verbose=0): myVTK.myPrint(verbose, "*** clipSurfacesForFullBiVMesh ***") pdata_endLV_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_endLV_implicit_distance.SetInput(pdata_endLV) pdata_endRV_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_endRV_implicit_distance.SetInput(pdata_endRV) pdata_epi_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_epi_implicit_distance.SetInput(pdata_epi) pdata_endLV_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): pdata_endLV_clip.SetInputData(pdata_endLV) else: pdata_endLV_clip.SetInput(pdata_endLV) pdata_endLV_clip.SetClipFunction(pdata_epi_implicit_distance) pdata_endLV_clip.InsideOutOn() pdata_endLV_clip.Update() clipped_pdata_endLV = pdata_endLV_clip.GetOutput(0) pdata_endRV_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): pdata_endRV_clip.SetInputData(pdata_endRV) else: pdata_endRV_clip.SetInput(pdata_endRV) pdata_endRV_clip.SetClipFunction(pdata_epi_implicit_distance) pdata_endRV_clip.InsideOutOn() pdata_endRV_clip.Update() clipped_pdata_endRV = pdata_endRV_clip.GetOutput(0) pdata_epi_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): pdata_epi_clip.SetInputData(pdata_epi) else: pdata_epi_clip.SetInput(pdata_epi) pdata_epi_clip.SetClipFunction(pdata_endLV_implicit_distance) pdata_epi_clip.GenerateClippedOutputOn() pdata_epi_clip.Update() clipped_pdata_epi = pdata_epi_clip.GetOutput(0) clipped_valM = pdata_epi_clip.GetOutput(1) pdata_epi_clip = vtk.vtkClipPolyData() if (vtk.vtkVersion.GetVTKMajorVersion() >= 6): pdata_epi_clip.SetInputData(clipped_pdata_epi) else: pdata_epi_clip.SetInput(clipped_pdata_epi) pdata_epi_clip.SetClipFunction(pdata_endRV_implicit_distance) pdata_epi_clip.GenerateClippedOutputOn() pdata_epi_clip.Update() clipped_pdata_epi = pdata_epi_clip.GetOutput(0) clipped_valP = pdata_epi_clip.GetOutput(1) return (clipped_pdata_endLV, clipped_pdata_endRV, clipped_pdata_epi, clipped_valM, clipped_valP)
def clipSurfacesForFullBiVMesh( pdata_endLV, pdata_endRV, pdata_epi, verbose=1): myVTK.myPrint(verbose, "*** clipSurfacesForFullBiVMesh ***") pdata_endLV_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_endLV_implicit_distance.SetInput(pdata_endLV) pdata_endRV_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_endRV_implicit_distance.SetInput(pdata_endRV) pdata_epi_implicit_distance = vtk.vtkImplicitPolyDataDistance() pdata_epi_implicit_distance.SetInput(pdata_epi) pdata_endLV_clip = vtk.vtkClipPolyData() pdata_endLV_clip.SetInputData(pdata_endLV) pdata_endLV_clip.SetClipFunction(pdata_epi_implicit_distance) pdata_endLV_clip.InsideOutOn() pdata_endLV_clip.Update() clipped_pdata_endLV = pdata_endLV_clip.GetOutput(0) pdata_endRV_clip = vtk.vtkClipPolyData() pdata_endRV_clip.SetInputData(pdata_endRV) pdata_endRV_clip.SetClipFunction(pdata_epi_implicit_distance) pdata_endRV_clip.InsideOutOn() pdata_endRV_clip.Update() clipped_pdata_endRV = pdata_endRV_clip.GetOutput(0) pdata_epi_clip = vtk.vtkClipPolyData() pdata_epi_clip.SetInputData(pdata_epi) pdata_epi_clip.SetClipFunction(pdata_endLV_implicit_distance) pdata_epi_clip.GenerateClippedOutputOn() pdata_epi_clip.Update() clipped_pdata_epi = pdata_epi_clip.GetOutput(0) clipped_valM = pdata_epi_clip.GetOutput(1) pdata_epi_clip = vtk.vtkClipPolyData() pdata_epi_clip.SetInputData(clipped_pdata_epi) pdata_epi_clip.SetClipFunction(pdata_endRV_implicit_distance) pdata_epi_clip.GenerateClippedOutputOn() pdata_epi_clip.Update() clipped_pdata_epi = pdata_epi_clip.GetOutput(0) clipped_valP = pdata_epi_clip.GetOutput(1) return (clipped_pdata_endLV, clipped_pdata_endRV, clipped_pdata_epi, clipped_valM, clipped_valP)
def findLocalCsys(self, filename): poly = vtk.vtkGeometryFilter() poly.SetInputData(self.vtkMeshes[filename]) poly.Update() distanceFilter = vtk.vtkImplicitPolyDataDistance() distanceFilter.SetInput(poly.GetOutput()) gradients = vtk.vtkFloatArray() gradients.SetNumberOfComponents(3) gradients.SetName("LevelSet Normals") distances = vtk.vtkFloatArray() distances.SetNumberOfComponents(1) distances.SetName("Signed Distances") N = self.vtkMeshes[filename].GetCellData().GetArray( "Centroids").GetNumberOfTuples() for i in range(N): g = np.zeros(3, np.float32) p = self.vtkMeshes[filename].GetCellData().GetArray( "Centroids").GetTuple3(i) d = distanceFilter.EvaluateFunction(p) distanceFilter.EvaluateGradient(p, g) g = old_div(np.array(g), np.linalg.norm(np.array(g))) gradients.InsertNextTuple(g) distances.InsertNextValue(d) self.vtkMeshes[filename].GetCellData().AddArray(gradients) self.vtkMeshes[filename].GetCellData().AddArray(distances)
def ClipMRIWithCylinder(mri_data,cylinderTransformed): implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(cylinderTransformed) mri_data_copy=mri_data # Create an array to hold distance information signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName("SignedDistances") # Evaluate the signed distance function at all of the grid points for pointId in range(mri_data.GetNumberOfPoints()): p = mri_data.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction(p) signedDistances.InsertNextValue(signedDistance) # add the SignedDistances to the grid mriDistanceData=np.zeros([int(mri_data.GetNumberOfPoints()),1]) for i in range(mri_data.GetNumberOfPoints()): mriDist=signedDistances.GetTuple(i)[0] mriDistanceData[i]=mriDist mriDistVtk=vtk.vtkDoubleArray() mriDistVtk.SetArray(mriDistanceData,mri_data.GetNumberOfPoints(),1) mri_data_copy.GetPointData().SetScalars(mriDistVtk) clipper = vtk.vtkClipDataSet() clipper.SetInputData(mri_data_copy) clipper.InsideOutOn() clipper.SetValue(0.0) clipper.Update() return clipper
def unpack_sdf_vtk_samples(filename, num_points=1000): reader = vtk.vtkOBJReader() reader.SetFileName(filename) reader.Update() polydata = reader.GetOutput() pdd = vtk.vtkImplicitPolyDataDistance() pdd.SetInput(polydata) sdf = [] closestPoints = [] vectors = [] F=3 V = np.random.uniform(-1,1,(int(num_points),F)) for i in range(int(num_points)): closestPoint = np.zeros(3) distance = pdd.EvaluateFunctionAndGetClosestPoint(V[i,:],closestPoint) sdf.append(distance) vector_gt = np.subtract(V[i,:],closestPoint) closestPoints.append(closestPoint) vectors.append(vector_gt) vectors = np.stack(vectors) vectors = np.reshape(vectors,(vectors.shape[0],-1)) sdf = np.stack(sdf) sdf = np.reshape(sdf,(sdf.shape[0],-1)) samples = np.concatenate((V,sdf,vectors),axis=1) samples = torch.from_numpy(samples).float() return samples
def pointDistancesLabelsFromSurface(self, inputPoints, inputModel): """Calculate closest point to point distance""" if not inputModel.GetPolyData() or inputModel.GetPolyData().GetNumberOfPoints() == 0: raise ValueError("Empty input model") # Transform model polydata to world coordinate system if inputModel.GetParentTransformNode(): transformModelToWorld = vtk.vtkGeneralTransform() slicer.vtkMRMLTransformNode.GetTransformBetweenNodes(inputModel.GetParentTransformNode(), None, transformModelToWorld) polyTransformToWorld = vtk.vtkTransformPolyDataFilter() polyTransformToWorld.SetTransform(transformModelToWorld) polyTransformToWorld.SetInputData(inputModel.GetPolyData()) polyTransformToWorld.Update() surface_World = polyTransformToWorld.GetOutput() else: surface_World = inputModel.GetPolyData() distanceFilter = vtk.vtkImplicitPolyDataDistance() distanceFilter.SetInput(surface_World) nOfFiducialPoints = inputPoints.GetNumberOfFiducials() import numpy as np distances = np.zeros(nOfFiducialPoints) labels = [""] * nOfFiducialPoints for i in range(nOfFiducialPoints): point_World = np.zeros(3) inputPoints.GetNthControlPointPositionWorld(i, point_World) closestPointOnSurface_World = np.zeros(3) closestPointDistance = distanceFilter.EvaluateFunctionAndGetClosestPoint(point_World, closestPointOnSurface_World) labels[i] = inputPoints.GetNthControlPointLabel(i) distances[i] = closestPointDistance return distances, labels
def stltoh5(stlfile, basepath, epsilon_inside, epsilon_outside, lattice=Lattice(), verbosity=0): if not os.path.exists(stlfile): if sys.version_info.major == 2: raise IOError('No such file or directory: {}'.format(stlfile)) # py2 else: raise FileNotFoundError('No such file or directory: {}'.format(stlfile)) # py3 print('--> timer start') time_start = time.time() # read in .stl file reader = vtk.vtkSTLReader() reader.SetFileName(stlfile) reader.Update() polydata = reader.GetOutput() # write .vtp file writer = vtk.vtkXMLPolyDataWriter() writer.SetInputData(polydata) writer.SetFileName(basepath + '.' + writer.GetDefaultFileExtension()) writer.Write() # set up implicit_function implicit_function = vtk.vtkImplicitPolyDataDistance() implicit_function.SetInput(polydata) print("--> Elapsed time: %.4f sec" % (time.time() - time_start)) stl_to_vts_and_h5(implicit_function, basepath, lattice, epsilon_inside, epsilon_outside) print("--> Elapsed time: %.4f sec" % (time.time() - time_start)) return
def _shellPreserveCracks(self, shrunkenPd): """Remove cells of the mesh that are far from the original surface""" # Cells that are far from the input mesh will be removed from this shrunkenPdWithCracks = vtk.vtkPolyData() shrunkenPdWithCracks.DeepCopy(shrunkenPd) shrunkenPdWithCracks.BuildLinks() # Measure distance from input mesh implicitDistance = vtk.vtkImplicitPolyDataDistance() implicitDistance.SetInput(self._inputPd) # Determine cutoff distance spacing = self._inputSpacing / self.remeshOversampling maxDistance = 0.9 * spacing # 0.9 because it is a bit more than half diameter of a cube (0.5*sqrt(3)) numberOfCells = shrunkenPdWithCracks.GetNumberOfCells() for c in range(numberOfCells): cell = shrunkenPdWithCracks.GetCell(c) points = cell.GetPoints() for p in range(points.GetNumberOfPoints()): point = points.GetPoint(p) distance = implicitDistance.EvaluateFunction( point) # TODO: check if cell locator is faster if abs(distance) > maxDistance: shrunkenPdWithCracks.DeleteCell(c) break shrunkenPdWithCracks.RemoveDeletedCells() return shrunkenPdWithCracks
def polydata_distance_on_ref(mflo, mref, mtpl, do_signed=True): """ distance from mflo to mref recorded on mtpl mflo and mtpl must have same number (and matching) points """ mout = vtk.vtkPolyData() mout.DeepCopy(mtpl) pdd = vtk.vtkImplicitPolyDataDistance() pdd.SetInput(mref) numPts = mflo.GetNumberOfPoints() distArray = vtk.vtkDoubleArray() distArray.SetName("Distance") distArray.SetNumberOfComponents(1) distArray.SetNumberOfTuples(numPts) for i in range(numPts): pt = mflo.GetPoint(i) d = pdd.EvaluateFunction(pt) if do_signed: distArray.SetValue(i, d) else: distArray.SetValue(i, np.abs(d)) mout.GetPointData().AddArray(distArray) return mout
def convertToImplicitPolyDataDistance(polyData): triFilter = vtk.vtkTriangleFilter() # triFilter to clean the polydata triFilter.SetInputData(polyData) triFilter.Update() ImpDist = vtk.vtkImplicitPolyDataDistance() ImpDist.SetTolerance(1e-1) ImpDist.SetInput(triFilter.GetOutput()) return ImpDist
def point_to_mesh_distances(inmesh, refmesh): distfunc = vtk.vtkImplicitPolyDataDistance() distfunc.SetInput(refmesh) points = polydata_to_points_polys(inmesh) dists = np.zeros(len(points)) for i, p in enumerate(points): dists[i] = distfunc.FunctionValue(p[0], p[1], p[2]) return dists
def distanceForModel(filename): reader = vtk.vtkPolyDataReader() reader.SetFileName(filename) reader.Update() # implicit function that will be used to slice the mesh distance = vtk.vtkImplicitPolyDataDistance() distance.SetInput(reader.GetOutput()) return distance
def cut_polydata_with_another(poly1, poly2, plane_info): """ Cuts the first VTK PolyData with another Args: poly1: 1st VTK PolyData poly2: 2nd VTK PolyData inside: whether inside or outside gets kept (bool) Returns: poly: cut VTK PolyData """ implicit = vtk.vtkImplicitPolyDataDistance() implicit.SetInput(poly2) signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName("SignedDistances") # Evaluate the signed distance function at all of the grid points points = poly1.GetPoints() ctr, nrm = plane_info for pointId in range(points.GetNumberOfPoints()): p = points.GetPoint(pointId) signedDistance = implicit.EvaluateFunction(p) plane_sign = np.sum(np.array(p - ctr) * nrm) signedDistance = np.abs( signedDistance) if plane_sign < 0 else signedDistance signedDistances.InsertNextValue(signedDistance) poly1.GetPointData().SetScalars(signedDistances) ##clipper = vtk.vtkClipPolyData() #clipper = vtk.vtkExtractPolyDataGeometry() ##clipper.SetClipFunction(implicit) #clipper.SetImplicitFunction(implicit) #clipper.SetInputData(poly1) ##clipper.SetInsideOut(inside) #clipper.SetExtractInside(inside) #clipper.SetExtractBoundaryCells(True) #clipper.Update() p2c = vtk.vtkPointDataToCellData() p2c.SetInputData(poly1) p2c.Update() poly1 = p2c.GetOutput() clipper = threshold_polydata(poly1, 'SignedDistances', (0., np.inf)) connectivity = vtk.vtkPolyDataConnectivityFilter() #connectivity.SetInputData(clipper.GetOutput()) connectivity.SetInputData(clipper) connectivity.SetExtractionModeToLargestRegion() connectivity.Update() poly = connectivity.GetOutput() return poly
def non_overlapping_segmentation(meshfiles, reffile, resolve): refnii = radiological.load(reffile) meshes = [loadmesh(mf) for mf in meshfiles] allmasks = np.zeros(refnii.shape + (len(meshes), )) for i, mesh in enumerate(meshes): imd = vtk.vtkImageData() imd.SetExtent(0, refnii.shape[0] - 1, 0, refnii.shape[1] - 1, 0, refnii.shape[2] - 1) imd.SetSpacing(*refnii.get_header().get_zooms()) filt = vtk.vtkSelectEnclosedPoints() filt.SetInputData(imd) filt.SetSurfaceData(mesh) filt.SetTolerance(0.00001) filt.Update() mask = np.reshape(vtknp.vtk_to_numpy( filt.GetOutput().GetPointData().GetArray('SelectedPoints')).copy(), refnii.shape, order='F') allmasks[..., i] = mask labels = (allmasks * np.arange(1, 1 + len(meshes))).sum(axis=3) contested = np.transpose(np.nonzero(allmasks.sum(axis=3) > 1)) if resolve: ipdds = list() for mesh in meshes: ipdd = vtk.vtkImplicitPolyDataDistance() ipdd.SetInput(mesh) ipdds.append(ipdd) for voxel in contested: # NB: This also includes the meshes that do not include the point, but those meshes will have higher distances # and will not influence the result dists = [ ipdd.FunctionValue(*(voxel * refnii.get_header().get_zooms())) for ipdd in ipdds ] labels[voxel[0], voxel[1], voxel[2]] = np.argmin(np.array(dists)) + 1 else: for voxel in contested: labels[voxel[0], voxel[1], voxel[2]] = 0 result = nii.Nifti1Image(labels, refnii.affine) result.set_qform(refnii.affine) return result
def getPointDistances(self, pointsNP, modelPoly): nPoints = pointsNP.shape[0] distanceNP = numpy.ndarray(shape=(nPoints, 1)) distance = vtk.vtkImplicitPolyDataDistance() distance.SetInput(modelPoly) for i in range(nPoints): pos = pointsNP[i, :] distanceNP[i, 0] = distance.EvaluateFunction(pos) return distanceNP
def cutWithMesh(self, mesh, invert=False, onlyTets=False, onlyBoundary=False): """ Cut a ``TetMesh`` mesh with a ``Mesh``. :param bool invert: if True return cut off part of the input TetMesh. """ polymesh = mesh.polydata() ug = self._ugrid scalname = ug.GetCellData().GetScalars().GetName() ippd = vtk.vtkImplicitPolyDataDistance() ippd.SetInput(polymesh) if onlyTets or onlyBoundary: clipper = vtk.vtkExtractGeometry() clipper.SetInputData(ug) clipper.SetImplicitFunction(ippd) clipper.SetExtractInside(not invert) clipper.SetExtractBoundaryCells(False) if onlyBoundary: clipper.SetExtractBoundaryCells(True) clipper.SetExtractOnlyBoundaryCells(True) else: signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName("SignedDistances") for pointId in range(ug.GetNumberOfPoints()): p = ug.GetPoint(pointId) signedDistance = ippd.EvaluateFunction(p) signedDistances.InsertNextValue(signedDistance) ug.GetPointData().SetScalars(signedDistances) clipper = vtk.vtkClipDataSet() clipper.SetInputData(ug) clipper.SetInsideOut(not invert) clipper.SetValue(0.0) clipper.Update() cug = clipper.GetOutput() if scalname: # not working if self.useCells: self.selectCellArray(scalname) else: self.selectPointArray(scalname) self._update(cug) return self
def gocad2simpegMeshIndex(gcFile,mesh,extractBoundaryCells=True,extractInside=True): """" Function to read gocad polystructure file and output indexes of mesh with in the structure. """ # Make the polydata polyData = gocad2vtp(gcFile) # Make implicit func ImpDistFunc = vtk.vtkImplicitPolyDataDistance() ImpDistFunc.SetInput(polyData) # Convert the mesh vtkMesh = vtk.vtkRectilinearGrid() vtkMesh.SetDimensions(mesh.nNx,mesh.nNy,mesh.nNz) vtkMesh.SetXCoordinates(npsup.numpy_to_vtk(mesh.vectorNx,deep=1)) vtkMesh.SetYCoordinates(npsup.numpy_to_vtk(mesh.vectorNy,deep=1)) vtkMesh.SetZCoordinates(npsup.numpy_to_vtk(mesh.vectorNz,deep=1)) # Add indexes cell data to the object vtkInd = npsup.numpy_to_vtk(np.arange(mesh.nC),deep=1) vtkInd.SetName('Index') vtkMesh.GetCellData().AddArray(vtkInd) # Define the extractGeometry extractImpDistRectGridFilt = vtk.vtkExtractGeometry() # Object constructor extractImpDistRectGridFilt.SetImplicitFunction(ImpDistFunc) # extractImpDistRectGridFilt.SetInputData(vtkMesh) # Set extraction type if extractBoundaryCells is True: extractImpDistRectGridFilt.ExtractBoundaryCellsOn() else: extractImpDistRectGridFilt.ExtractBoundaryCellsOff() if extractInside is True: extractImpDistRectGridFilt.ExtractInsideOn() else: extractImpDistRectGridFilt.ExtractInsideOff() print "Extracting indices from grid..." # Executing the pipe extractImpDistRectGridFilt.Update() # Get index inside insideGrid = extractImpDistRectGridFilt.GetOutput() insideGrid = npsup.vtk_to_numpy(insideGrid.GetCellData().GetArray('Index')) # Return the indexes inside return insideGrid
def volumeFromMesh(mesh, bounds=None, dims=(20, 20, 20), signed=True, negate=False): """ Compute signed distances over a volume from an input mesh. The output is a ``Volume`` object whose voxels contains the signed distance from the mesh. :param list bounds: bounds of the output volume. :param list dims: dimensions (nr. of voxels) of the output volume. See example script: |volumeFromMesh.py|_ """ if bounds is None: bounds = mesh.GetBounds() sx = (bounds[1] - bounds[0]) / dims[0] sy = (bounds[3] - bounds[2]) / dims[1] sz = (bounds[5] - bounds[4]) / dims[2] img = vtk.vtkImageData() img.SetDimensions(dims) img.SetSpacing(sx, sy, sz) img.SetOrigin(bounds[0], bounds[2], bounds[4]) img.AllocateScalars(vtk.VTK_FLOAT, 1) imp = vtk.vtkImplicitPolyDataDistance() imp.SetInput(mesh.polydata()) b4 = bounds[4] r2 = range(dims[2]) for i in range(dims[0]): x = i * sx + bounds[0] for j in range(dims[1]): y = j * sy + bounds[2] for k in r2: v = imp.EvaluateFunction((x, y, k * sz + b4)) if signed: if negate: v = -v else: v = abs(v) img.SetScalarComponentFromFloat(i, j, k, 0, v) vol = Volume(img) vol.name = "VolumeFromMesh" return vol
def createBreastModel(self, breastBound, InputModel, breastFlag, reverseNormal, setInsideOut, plane, planeWithSplineTransform): # Creates the cropped breast model from the original input model and the created warped posterior wall of the breast # Clip the input model with the breast boundary loop to isolate the breast clippedBreastModel = vtk.vtkClipPolyData() clippedBreastModel.SetClipFunction(breastBound) clippedBreastModel.SetInputData(InputModel) # This value below may need to be changed clippedBreastModel.SetInsideOut(True) clippedBreastModel.Update() # Now use the vtkPolyDataConnectivityFilter to extract the largest region connectedBreastModel = vtk.vtkPolyDataConnectivityFilter() connectedBreastModel.SetInputConnection(clippedBreastModel.GetOutputPort()) connectedBreastModel.SetExtractionModeToLargestRegion() connectedBreastModel.Update() # linearly extrude the breast model to ensure the final surface will be airtight extrudeBreastModel = vtk.vtkLinearExtrusionFilter() extrudeBreastModel.SetInputConnection(connectedBreastModel.GetOutputPort()) extrudeBreastModel.SetScaleFactor(100) extrudeBreastModel.CappingOn() normVec = plane.GetNormal() if breastFlag == True: normVec = [normVec[0] * -1, normVec[1] * -1, normVec[2] * -1] if reverseNormal == True: normVec = [normVec[0] * -1, normVec[1] * -1, normVec[2] * -1] extrudeBreastModel.SetVector(normVec) extrudeBreastModel.Update() # create implicit representation of the plane transformed with the spline implictSplinePlane = vtk.vtkImplicitPolyDataDistance() implictSplinePlane.SetInput(planeWithSplineTransform.GetOutput()) # Now re-clip the now air-tight breast model wit the curved surface breastModel = vtk.vtkClipPolyData() breastModel.SetClipFunction(implictSplinePlane) breastModel.SetInputConnection(extrudeBreastModel.GetOutputPort()) # This value below may need to be changed if setInsideOut == True: breastModel.SetInsideOut(True) else: breastModel.SetInsideOut(False) breastModel.Update() return breastModel.GetOutput()
def CreateSphereClippingSkin(cs): sphere = vtk.vtkSphereSource() sphere.SetCenter(xCenter, yCenter, zCenter) sphere.SetRadius(radius + 3) ipdd = vtk.vtkImplicitPolyDataDistance() ipdd.SetInput(cs.GetOutput(0)) clipperSphere = vtk.vtkClipPolyData() clipperSphere.SetInputConnection(sphere.GetOutputPort()) clipperSphere.SetClipFunction(ipdd) clipperSphere.SetValue(0) clipperSphere.Update() return clipperSphere
def obj_func(radii, grad=None): """ Square of signed distance from tips of spokes to the input_mesh """ implicit_distance = vtk.vtkImplicitPolyDataDistance() implicit_distance.SetInput(input_mesh) total_loss = 0 for i, radius in enumerate(radii): direction = dir_array[i, :] base_pt = base_array[i, :] bdry_pt = base_pt + radius * direction dist = implicit_distance.FunctionValue(bdry_pt) total_loss += dist**2 return total_loss
def _absolute_surface_distance(source, target): assert (isinstance(source, vtk.vtkPolyData)) assert (isinstance(target, vtk.vtkPolyData)) distances = [] implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(target) # evaluate the signed distance function for pointId in range(source.GetNumberOfPoints()): p = source.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction(p) distances.append(signedDistance) return np.abs(distances)
def query(self, mesh, component): surface_distance_function = vtk.vtkImplicitPolyDataDistance() surface_distance_function.SetInput(self.mesh.pyvista.extract_surface()) surface_distances = np.empty(mesh.pyvista.GetNumberOfPoints()) points = mesh.pyvista.GetPoints() for i in tqdm(range(mesh.pyvista.GetNumberOfPoints())): distance = surface_distance_function.EvaluateFunction( points.GetPoint(i)) surface_distances[i] = abs(distance) if component == 'points': return surface_distances <= self.distance elif component == 'cells': return self._map_points_to_cells(surface_distances, mesh) <= self.distance
def Geometry_Mask_ImplicitPolyDataDistance(data,stl_file_path): #returns list of all PIV images print('\nFiltering Using Manifold Surface') print("\nReading STL File...") meshReader = vtk.vtkSTLReader() meshReader.SetFileName(stl_file_path) meshReader.Update() polydata = meshReader.GetOutput() implicit_function = vtk.vtkImplicitPolyDataDistance() implicit_function.SetInput(polydata) masked_data = [None]*len(data) print("\nMasking points...\n") for file in range(len(data)): data_file = np.array(data[file]) data_shape = np.shape(data_file) points = data_file[:,0:3] #these are the data points you want to mask, you can pass any number of point attributes in "data" as long as the point locations are in the first three indices of each row mask_indices = np.zeros(data_shape[0]) for point in range(data_shape[0]): if (implicit_function.FunctionValue(points[point,:]) <= 0): mask_indices[point] = 1 masked_data[file] = data_file[(mask_indices != 0),:] #pull all points that passed the test into a new matrix return masked_data
def Geometry_Mask_ImplicitPolyDataDistance(data, stl_file_path): points = data[:, 0: 3] #these are the data points you want to mask, you can pass any number of point attributes in "data" as long as the point locations are in the first three indices of each row data_shape = np.shape(data) print("Reading STL File...") meshReader = vtk.vtkSTLReader() meshReader.SetFileName(stl_file_path) meshReader.Update() polydata = meshReader.GetOutput() implicit_function = vtk.vtkImplicitPolyDataDistance() implicit_function.SetInput(polydata) print("Masking points...") mask_indices = np.zeros(data_shape[0]) for point in range(data_shape[0]): if (implicit_function.FunctionValue(points[point, :]) <= 0): mask_indices[point] = 1 masked_data = data[( mask_indices != 0), :] #pull all points that passed the test into a new matrix return masked_data
### TODO: # 1. Close mesh (e.g. using 'repair') # 2. Get all values which are within mesh # 3. Get closest points on mesh to these values # 4. Sum up the intensity for these values and add them to the corresponding closest points # 5. Get angles and distance to apex for each of these points # 6. Do fourier analysis on this #pts = vi.utilities.MakeVTKPointsMesh(A.mesh.points) from pymeshfix import meshfix mf = meshfix.MeshFix(A.mesh) mf.Repair() rep_mesh = mf.mesh ipd = vtk.vtkImplicitPolyDataDistance() ipd.SetInput(A.mesh) ipd.Modified() dists = np.zeros((len(coords),)) pts = np.zeros((len(coords), 3)) for ii in xrange(len(coords)): dists[ii] = ipd.EvaluateFunctionAndGetClosestPoint(coords[ii], pts[ii]) # filter_ = np.logical_and(dists > -6, dists < 0) filter_ = dists < 0 #idxs = idxs[~np.isinf(dists)] coords = coords[filter_] vals = vals[filter_] dists = dists[filter_] #coords[idxs]
def main(): colors = vtk.vtkNamedColors() sphereSource = vtk.vtkSphereSource() sphereSource.SetCenter(0.0, 0.0, 0.0) sphereSource.SetRadius(1.0) sphereSource.Update() sphereMapper = vtk.vtkPolyDataMapper() sphereMapper.SetInputConnection(sphereSource.GetOutputPort()) sphereMapper.ScalarVisibilityOff() sphereActor = vtk.vtkActor() sphereActor.SetMapper(sphereMapper) sphereActor.GetProperty().SetOpacity(0.3) sphereActor.GetProperty().SetColor(1, 0, 0) implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(sphereSource.GetOutput()) # Setup a grid points = vtk.vtkPoints() step = 0.1 for x in np.arange(-2, 2, step): for y in np.arange(-2, 2, step): for z in np.arange(-2, 2, step): points.InsertNextPoint(x, y, z) # Add distances to each point signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName('SignedDistances') # Evaluate the signed distance function at all of the grid points for pointId in range(points.GetNumberOfPoints()): p = points.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction(p) signedDistances.InsertNextValue(signedDistance) polyData = vtk.vtkPolyData() polyData.SetPoints(points) polyData.GetPointData().SetScalars(signedDistances) vertexGlyphFilter = vtk.vtkVertexGlyphFilter() vertexGlyphFilter.SetInputData(polyData) vertexGlyphFilter.Update() signedDistanceMapper = vtk.vtkPolyDataMapper() signedDistanceMapper.SetInputConnection(vertexGlyphFilter.GetOutputPort()) signedDistanceMapper.ScalarVisibilityOn() signedDistanceActor = vtk.vtkActor() signedDistanceActor.SetMapper(signedDistanceMapper) renderer = vtk.vtkRenderer() renderer.AddViewProp(sphereActor) renderer.AddViewProp(signedDistanceActor) renderer.SetBackground(colors.GetColor3d('SlateGray')) renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(renderer) renderWindow.SetWindowName('ImplicitPolyDataDistance') renWinInteractor = vtk.vtkRenderWindowInteractor() renWinInteractor.SetRenderWindow(renderWindow) renderWindow.Render() renWinInteractor.Start()
def gocad2vtk(gcFile, mesh, bcflag, inflag): """" Function to read gocad polystructure file and output indexes of mesh with in the structure. """ print("Reading GOCAD ts file...", bcflag, inflag) vrtx, trgl = read_GOCAD_ts(gcFile) vrtx, trgl = np.vstack(vrtx), np.vstack(trgl) # Adjust the index trgl = trgl - 1 # Make vtk pts ptsvtk = vtk.vtkPoints() ptsvtk.SetData(npsup.numpy_to_vtk(vrtx, deep=1)) # Make the polygon connection polys = vtk.vtkCellArray() for face in trgl: poly = vtk.vtkPolygon() poly.GetPointIds().SetNumberOfIds(len(face)) for nrv, vert in enumerate(face): poly.GetPointIds().SetId(nrv, vert) polys.InsertNextCell(poly) # Make the polydata, structure of connections and vrtx polyData = vtk.vtkPolyData() polyData.SetPoints(ptsvtk) polyData.SetPolys(polys) # Make implicit func ImpDistFunc = vtk.vtkImplicitPolyDataDistance() ImpDistFunc.SetInput(polyData) # Convert the mesh vtkMesh = vtk.vtkRectilinearGrid() vtkMesh.SetDimensions(mesh.nNx, mesh.nNy, mesh.nNz) vtkMesh.SetXCoordinates(npsup.numpy_to_vtk(mesh.vectorNx, deep=1)) vtkMesh.SetYCoordinates(npsup.numpy_to_vtk(mesh.vectorNy, deep=1)) vtkMesh.SetZCoordinates(npsup.numpy_to_vtk(mesh.vectorNz, deep=1)) # Add indexes vtkInd = npsup.numpy_to_vtk(np.arange(mesh.nC), deep=1) vtkInd.SetName('Index') vtkMesh.GetCellData().AddArray(vtkInd) extractImpDistRectGridFilt = vtk.vtkExtractGeometry() extractImpDistRectGridFilt.SetImplicitFunction(ImpDistFunc) extractImpDistRectGridFilt.SetInputData(vtkMesh) if bcflag is True: extractImpDistRectGridFilt.ExtractBoundaryCellsOn() else: extractImpDistRectGridFilt.ExtractBoundaryCellsOff() if inflag is True: extractImpDistRectGridFilt.ExtractInsideOn() else: extractImpDistRectGridFilt.ExtractInsideOff() print("Extracting indices from grid...") # Executing the pipe extractImpDistRectGridFilt.Update() # Get index inside insideGrid = extractImpDistRectGridFilt.GetOutput() insideGrid = npsup.vtk_to_numpy(insideGrid.GetCellData().GetArray('Index')) # Return the indexes inside return insideGrid
sphereSource = vtk.vtkSphereSource() sphereSource.SetCenter(0.0, 0.0, 0.0) sphereSource.SetRadius(1.0) sphereSource.Update() sphereMapper = vtk.vtkPolyDataMapper() sphereMapper.SetInputConnection(sphereSource.GetOutputPort()) sphereMapper.ScalarVisibilityOff() sphereActor = vtk.vtkActor() sphereActor.SetMapper(sphereMapper) sphereActor.GetProperty().SetOpacity(.3) sphereActor.GetProperty().SetColor(1, 0, 0) implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(sphereSource.GetOutput()) # Setup a grid points = vtk.vtkPoints() step = 0.1 for x in np.arange(-2, 2, step): for y in np.arange(-2, 2, step): for z in np.arange(-2, 2, step): points.InsertNextPoint(x, y, z) # Add distances to each point signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName("SignedDistances")
def surface2inds(vrtx, trgl, mesh, boundaries=True, internal=True): """" Function to read gocad polystructure file and output indexes of mesh with in the structure. """ import vtk import vtk.util.numpy_support as npsup # Adjust the index trgl = trgl - 1 # Make vtk pts ptsvtk = vtk.vtkPoints() ptsvtk.SetData(npsup.numpy_to_vtk(vrtx, deep=1)) # Make the polygon connection polys = vtk.vtkCellArray() for face in trgl: poly = vtk.vtkPolygon() poly.GetPointIds().SetNumberOfIds(len(face)) for nrv, vert in enumerate(face): poly.GetPointIds().SetId(nrv, vert) polys.InsertNextCell(poly) # Make the polydata, structure of connections and vrtx polyData = vtk.vtkPolyData() polyData.SetPoints(ptsvtk) polyData.SetPolys(polys) # Make implicit func ImpDistFunc = vtk.vtkImplicitPolyDataDistance() ImpDistFunc.SetInput(polyData) # Convert the mesh vtkMesh = vtk.vtkRectilinearGrid() vtkMesh.SetDimensions(mesh.nNx, mesh.nNy, mesh.nNz) vtkMesh.SetXCoordinates(npsup.numpy_to_vtk(mesh.vectorNx, deep=1)) vtkMesh.SetYCoordinates(npsup.numpy_to_vtk(mesh.vectorNy, deep=1)) vtkMesh.SetZCoordinates(npsup.numpy_to_vtk(mesh.vectorNz, deep=1)) # Add indexes vtkInd = npsup.numpy_to_vtk(np.arange(mesh.nC), deep=1) vtkInd.SetName('Index') vtkMesh.GetCellData().AddArray(vtkInd) extractImpDistRectGridFilt = vtk.vtkExtractGeometry() # Object constructor extractImpDistRectGridFilt.SetImplicitFunction(ImpDistFunc) # extractImpDistRectGridFilt.SetInputData(vtkMesh) if boundaries is True: extractImpDistRectGridFilt.ExtractBoundaryCellsOn() else: extractImpDistRectGridFilt.ExtractBoundaryCellsOff() if internal is True: extractImpDistRectGridFilt.ExtractInsideOn() else: extractImpDistRectGridFilt.ExtractInsideOff() print("Extracting indices from grid...") # Executing the pipe extractImpDistRectGridFilt.Update() # Get index inside insideGrid = extractImpDistRectGridFilt.GetOutput() insideGrid = npsup.vtk_to_numpy(insideGrid.GetCellData().GetArray('Index')) # Return the indexes inside return insideGrid
def main(): colors = vtk.vtkNamedColors() # Create polydata to slice the grid with. In this case, use a cone. This # could # be any polydata including a stl file. cone = vtk.vtkConeSource() cone.SetResolution(50) cone.SetDirection(0, 0, -1) cone.SetHeight(3.0) cone.CappingOn() cone.Update() # Implicit function that will be used to slice the mesh implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(cone.GetOutput()) # create a grid dimension = 51 xCoords = vtk.vtkFloatArray() for x, i in enumerate(np.linspace(-1.0, 1.0, dimension)): xCoords.InsertNextValue(i) yCoords = vtk.vtkFloatArray() for y, i in enumerate(np.linspace(-1.0, 1.0, dimension)): yCoords.InsertNextValue(i) zCoords = vtk.vtkFloatArray() for z, i in enumerate(np.linspace(-1.0, 1.0, dimension)): zCoords.InsertNextValue(i) # # create a grid - if not using numpy # dimension = 51 # xCoords = vtk.vtkFloatArray() # for i in range(0, dimension): # xCoords.InsertNextValue(-1.0 + i * 2.0 / (dimension - 1)) # # yCoords = vtk.vtkFloatArray() # for i in range(0, dimension): # yCoords.InsertNextValue(-1.0 + i * 2.0 / (dimension - 1)) # # zCoords = vtk.vtkFloatArray() # for i in range(0, dimension): # zCoords.InsertNextValue(-1.0 + i * 2.0 / (dimension - 1)) # The coordinates are assigned to the rectilinear grid. Make sure that # the number of values in each of the XCoordinates, YCoordinates, # and ZCoordinates is equal to what is defined in SetDimensions(). rgrid = vtk.vtkRectilinearGrid() rgrid.SetDimensions(xCoords.GetNumberOfTuples(), yCoords.GetNumberOfTuples(), zCoords.GetNumberOfTuples()) rgrid.SetXCoordinates(xCoords) rgrid.SetYCoordinates(yCoords) rgrid.SetZCoordinates(zCoords) # Create an array to hold distance information signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName('SignedDistances') # Evaluate the signed distance function at all of the grid points for pointId in range(0, rgrid.GetNumberOfPoints()): p = rgrid.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction(p) signedDistances.InsertNextValue(signedDistance) # Add the SignedDistances to the grid rgrid.GetPointData().SetScalars(signedDistances) # Use vtkClipDataSet to slice the grid with the polydata clipper = vtk.vtkClipDataSet() clipper.SetInputData(rgrid) clipper.InsideOutOn() clipper.SetValue(0.0) clipper.GenerateClippedOutputOn() clipper.Update() # --- mappers, actors, render, etc. --- # mapper and actor to view the cone coneMapper = vtk.vtkPolyDataMapper() coneMapper.SetInputConnection(cone.GetOutputPort()) coneActor = vtk.vtkActor() coneActor.SetMapper(coneMapper) # geometry filter to view the background grid geometryFilter = vtk.vtkRectilinearGridGeometryFilter() geometryFilter.SetInputData(rgrid) geometryFilter.SetExtent(0, dimension, 0, dimension, int(dimension / 2), int(dimension / 2)) geometryFilter.Update() rgridMapper = vtk.vtkPolyDataMapper() rgridMapper.SetInputConnection(geometryFilter.GetOutputPort()) rgridMapper.SetScalarRange( rgrid.GetPointData().GetArray('SignedDistances').GetRange()) wireActor = vtk.vtkActor() wireActor.SetMapper(rgridMapper) wireActor.GetProperty().SetRepresentationToWireframe() # mapper and actor to view the clipped mesh clipperMapper = vtk.vtkDataSetMapper() clipperMapper.SetInputConnection(clipper.GetOutputPort()) clipperMapper.ScalarVisibilityOff() clipperOutsideMapper = vtk.vtkDataSetMapper() clipperOutsideMapper.SetInputConnection(clipper.GetOutputPort(1)) clipperOutsideMapper.ScalarVisibilityOff() clipperActor = vtk.vtkActor() clipperActor.SetMapper(clipperMapper) clipperActor.GetProperty().SetColor(colors.GetColor3d('Banana')) clipperOutsideActor = vtk.vtkActor() clipperOutsideActor.SetMapper(clipperOutsideMapper) clipperOutsideActor.GetProperty().SetColor( colors.GetColor3d('Banana')) # A renderer and render window # Create a renderer, render window, and interactor leftViewport = [0.0, 0.0, 0.5, 1.0] leftRenderer = vtk.vtkRenderer() leftRenderer.SetViewport(leftViewport) leftRenderer.SetBackground(colors.GetColor3d('SteelBlue')) rightViewport = [0.5, 0.0, 1.0, 1.0] rightRenderer = vtk.vtkRenderer() rightRenderer.SetViewport(rightViewport) rightRenderer.SetBackground(colors.GetColor3d('CadetBlue')) # add the actors leftRenderer.AddActor(wireActor) leftRenderer.AddActor(clipperActor) rightRenderer.AddActor(clipperOutsideActor) renwin = vtk.vtkRenderWindow() renwin.SetSize(640, 480) renwin.AddRenderer(leftRenderer) renwin.AddRenderer(rightRenderer) renwin.SetWindowName('ClipDataSetWithPolyData') # An interactor interactor = vtk.vtkRenderWindowInteractor() interactor.SetRenderWindow(renwin) # Share the camera leftRenderer.GetActiveCamera().SetPosition(0, -1, 0) leftRenderer.GetActiveCamera().SetFocalPoint(0, 0, 0) leftRenderer.GetActiveCamera().SetViewUp(0, 0, 1) leftRenderer.GetActiveCamera().Azimuth(30) leftRenderer.GetActiveCamera().Elevation(30) leftRenderer.ResetCamera() rightRenderer.SetActiveCamera(leftRenderer.GetActiveCamera()) renwin.Render() interactor.Start() # Generate a report ct = vtk.vtkCellTypes() numberOfCells = clipper.GetOutput().GetNumberOfCells() print('------------------------') print('The clipped dataset(inside) contains a\n', clipper.GetOutput().GetClassName(), 'that has', numberOfCells, 'cells') cellMap = dict() for i in range(0, numberOfCells): cellMap[clipper.GetOutput().GetCellType(i)] = cellMap.get(clipper.GetOutput().GetCellType(i), 0) + 1 for k, v in cellMap.items(): print('\tCell type ', ct.GetClassNameFromTypeId(k), 'occurs', v, 'times.') numberOfCells = clipper.GetClippedOutput().GetNumberOfCells() print('------------------------') print('The clipped dataset(outside) contains a\n', clipper.GetClippedOutput().GetClassName(), 'that has', numberOfCells, 'cells') outsideCellMap = dict() for i in range(0, numberOfCells): outsideCellMap[clipper.GetClippedOutput().GetCellType(i)] = outsideCellMap.get( clipper.GetClippedOutput().GetCellType(i), 0) + 1 for k, v in outsideCellMap.items(): print('\tCell type ', ct.GetClassNameFromTypeId(k), 'occurs', v, 'times.')
cutter = vtk.vtkCutter() cutter.SetCutFunction(plane) cutter.SetInputData(vtu_data) cutter.Update() vtu_slice = cutter.GetOutput() # write_polydata(vtu_slice,"group_slice"+str(j)+".vtp") sphere = vtk.vtkSphereSource() sphere.SetCenter(group_roi_center[j][0], group_roi_center[j][1], group_roi_center[j][2]) sphere.SetRadius(group_roi_maxR[j] * 1.5) sphere.Update() implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(sphere.GetOutput()) signedDistances = vtk.vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName("SignedDistances") # print"cutter num points",vtu_slice.GetNumberOfPoints() if vtu_slice.GetNumberOfPoints() == 0: print "0 sliced point for group=", j exit() for pointId in range(vtu_slice.GetNumberOfPoints()): p = vtu_slice.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction( p) signedDistances.InsertNextValue(signedDistance)
def ligamentPathMarai2004(pIns, vtkFemur, vtkTibia, Ns, iterInitP, iterArgs={}, equalizeInitIterP=True): # Unpack insertion points p1 = pIns[0, :] p2 = pIns[1, :] # Create pose matrin from global to straight ligament reference frame z = p1 - p2 z = z / np.linalg.norm(z) x = np.cross(z, (1, 0, 0)) x = x / np.linalg.norm(x) y = np.cross(z, x) y = y / np.linalg.norm(y) R = np.array((x, y, z)).T Rt = np.vstack((np.hstack((R, p2[:, None])), (0, 0, 0, 1))) # Repose all elements in new reference frame vtkFemur2 = reposeVTKData(vtkFemur, Rt.ravel()) vtkTibia2 = reposeVTKData(vtkTibia, Rt.ravel()) p12 = np.dot(Rt, np.append(p1, 1))[:3] p22 = np.dot(Rt, np.append(p2, 1))[:3] if Ns is None: iterInitP2 = np.dot( Rt, np.vstack((iterInitP.T, np.ones( (1, iterInitP.shape[0]))))).T[:, :3] print(p12) print(p22) print(iterInitP2) # Create points if Ns is not None: L = np.arange(Ns + 1) V = (p12 - p22) / Ns p = np.zeros((Ns + 1, 3)) for l in L: ps2 = p22 + l * V p[l, :] = ps2 else: p = iterInitP2.copy()[::-1, :] Ns = p.shape[0] - 1 if equalizeInitIterP: print(p) # p = p[::-1,:] xuf = RegularGridInterpolator((p[:, 2], ), p[:, 0], bounds_error=False, fill_value=None) yuf = RegularGridInterpolator((p[:, 2], ), p[:, 1], bounds_error=False, fill_value=None) Ns = p.shape[0] - 1 L = np.arange(Ns + 1) Z = (p12[2] - p22[2]) / Ns for l in L: z = p22[2] + l * Z x = xuf([[z]])[0] y = yuf([[z]])[0] ps2 = (x, y, z) p[l, :] = ps2 # p = p[::-1,:] print(p) points = vtk.vtkPoints() for ps2 in p: points.InsertNextPoint(ps2) checkPoints = vtk.vtkPolyData() checkPoints.SetPoints(points) # Create points checker penetration = arePointsPenetrating(vtkFemur2, checkPoints) or \ arePointsPenetrating(vtkTibia2, checkPoints) print(('Penetration: %d' % penetration)) if penetration: # Create points distancer pointDistancer = vtk.vtkImplicitPolyDataDistance() # Minimize length def retablePoints2C(x): # reorganize via points xv = x.reshape((Ns - 1, 2)) # reconstruct (Ns+1) x 3 all points array pp = np.vstack((p22[0:2], xv, p12[0:2])) pp = np.hstack((pp, p[:, 2:3])) return pp retablePoints = retablePoints2C def fun(x): pp = retablePoints(x) d = np.linalg.norm(pp[1:, :] - pp[:-1, :], axis=1) dtot = d.sum() print(('Current length: %f' % dtot)) return dtot x0 = p[1:-1, 0:2].ravel() print('-- Initial condition:') fun(x0) def consFun(x, ip, bone): pp = retablePoints(x) if bone == 'tibia': pointDistancer.SetInput(vtkTibia2) elif bone == 'femur': pointDistancer.SetInput(vtkFemur2) d = pointDistancer.EvaluateFunction(pp[ip, :]) return d cons = [] for ip in range(1, Ns): cons.append({ 'type': 'ineq', 'fun': consFun, 'args': (ip, 'tibia') }) cons.append({ 'type': 'ineq', 'fun': consFun, 'args': (ip, 'femur') }) def jac2C(x): pp = retablePoints(x) Nv = pp.shape[0] - 2 jaco = np.zeros((Nv, 2)) dx = pp[1:, 0:2] - pp[:-1, 0:2] dist = np.linalg.norm(dx, axis=1) for i in range(0, Nv): jaco[i, :] = (dx[i, :] / dist[i]) - (dx[i + 1, :] / dist[i + 1]) return jaco.ravel() def jac2Cc(x): pp = retablePoints(x) Nv = pp.shape[0] - 2 jaco = np.zeros((Nv, 3)) dx = pp[1:, :] - pp[:-1, :] dist = np.linalg.norm(dx, axis=1) for i in range(0, Nv): jaco[i, :] = (dx[i, :] / dist[i]) - (dx[i + 1, :] / dist[i + 1]) return jaco[:, :2].ravel() jac = jac2Cc if not iterArgs: # if it is empty options = {'disp': True, 'eps': 50e0, 'maxiter': 20} #options = {'disp': True, 'eps' : 50e0, 'maxiter': 0} else: options = iterArgs print('-- Iterative algorithm:') res = spminimize(fun, x0, method='SLSQP', constraints=cons, jac=jac, options=options) print('-- Final condition:') fun(res.x) pw = retablePoints(res.x) pw = pw[::-1, :] p = p[::-1, :] print((pw - p)) print(pw) # Repose all points in original global reference frames p = np.dot(np.linalg.inv(Rt), np.vstack((p.T, np.ones( (1, p.shape[0]))))).T[:, :3] pw = np.dot(np.linalg.inv(Rt), np.vstack((pw.T, np.ones((1, pw.shape[0]))))).T[:, :3] else: p = pIns.copy() pw = p.copy() return p, pw