def CreateSurfaceCells(self, inMesh): #Remove the surface cells from the mesh cellDimFilter = vtkvmtk.vtkvmtkCellDimensionFilter() cellDimFilter.SetInputData(inMesh) cellDimFilter.ThresholdByUpper(3) cellDimFilter.Update() volumetricMesh = cellDimFilter.GetOutput() #Get new surface cells geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInputConnection(cellDimFilter.GetOutputPort()) geomFilter.Update() newSurfaceCells = geomFilter.GetOutput() #If the celEntityIdArray exist, project the original entity ids cellEntityIdsArray = newSurfaceCells.GetCellData().GetArray( self.CellEntityIdsArrayName) if (cellEntityIdsArray != None): #Convert the surface cells to poly data surfaceCellsToSurface = vmtkscripts.vmtkMeshToSurface() surfaceCellsToSurface.Mesh = newSurfaceCells surfaceCellsToSurface.Execute() #Get the original surface cells meshThreshold = vtk.vtkThreshold() meshThreshold.SetInputData(self.Mesh) meshThreshold.ThresholdByUpper(self.WallCellEntityId + 0.5) meshThreshold.SetInputArrayToProcess(0, 0, 0, 1, self.CellEntityIdsArrayName) meshThreshold.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = meshThreshold.GetOutput() meshToSurface.Execute() #Project the entity ids form the old surface cells to the new surface cells #TODO: This is hackish(need for a tolerance), find a beeter way projector = vtkvmtk.vtkvmtkSurfaceProjectCellArray() projector.SetInputData(surfaceCellsToSurface.Surface) projector.SetReferenceSurface(meshToSurface.Surface) projector.SetProjectedArrayName(self.CellEntityIdsArrayName) projector.SetDefaultValue(self.WallCellEntityId) projector.SetDistanceTolerance(self.Tolerance) projector.Update() #Convert the surface cells back to unstructured grid surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = projector.GetOutput() surfaceToMesh.Execute() newSurfaceCells = surfaceToMesh.Mesh #append the new surface cells to the volumetric elements appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(volumetricMesh) appendFilter.AddInput(newSurfaceCells) appendFilter.Update() return appendFilter.GetOutput()
def CreateSurfaceCells(self,inMesh): #Remove the surface cells from the mesh cellDimFilter = vtkvmtk.vtkvmtkCellDimensionFilter() cellDimFilter.SetInputData(inMesh) cellDimFilter.ThresholdByUpper(3) cellDimFilter.Update() volumetricMesh = cellDimFilter.GetOutput() #Get new surface cells geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInputConnection(cellDimFilter.GetOutputPort()) geomFilter.Update() newSurfaceCells = geomFilter.GetOutput() #If the celEntityIdArray exist, project the original entity ids cellEntityIdsArray = newSurfaceCells.GetCellData().GetArray(self.CellEntityIdsArrayName) if (cellEntityIdsArray != None): #Convert the surface cells to poly data surfaceCellsToSurface = vmtkscripts.vmtkMeshToSurface() surfaceCellsToSurface.Mesh = newSurfaceCells surfaceCellsToSurface.Execute() #Get the original surface cells meshThreshold = vtk.vtkThreshold() meshThreshold.SetInputData(self.Mesh) meshThreshold.ThresholdByUpper(self.WallCellEntityId+0.5) meshThreshold.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) meshThreshold.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = meshThreshold.GetOutput() meshToSurface.Execute() #Project the entity ids form the old surface cells to the new surface cells #TODO: This is hackish(need for a tolerance), find a beeter way projector = vtkvmtk.vtkvmtkSurfaceProjectCellArray() projector.SetInputData(surfaceCellsToSurface.Surface) projector.SetReferenceSurface(meshToSurface.Surface) projector.SetProjectedArrayName(self.CellEntityIdsArrayName) projector.SetDefaultValue(self.WallCellEntityId) projector.SetDistanceTolerance(self.Tolerance) projector.Update() #Convert the surface cells back to unstructured grid surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = projector.GetOutput() surfaceToMesh.Execute() newSurfaceCells = surfaceToMesh.Mesh #append the new surface cells to the volumetric elements appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(volumetricMesh) appendFilter.AddInput(newSurfaceCells) appendFilter.Update() return appendFilter.GetOutput()
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') if self.CheckNonManifold: self.PrintLog('NonManifold check.') nonManifoldChecker = vmtkNonManifoldSurfaceChecker() nonManifoldChecker.Surface = self.Surface nonManifoldChecker.PrintError = self.PrintError nonManifoldChecker.Execute() if (nonManifoldChecker.NumberOfNonManifoldEdges > 0): self.PrintLog(nonManifoldChecker.Report) return if not self.vmtkRenderer and self.SeedSelectorName in [ 'pickpoint', 'openprofiles' ]: self.vmtkRenderer = vmtkrenderer.vmtkRenderer() self.vmtkRenderer.Initialize() self.OwnRenderer = 1 self.PrintLog('Cleaning surface.') surfaceCleaner = vtk.vtkCleanPolyData() surfaceCleaner.SetInputData(self.Surface) surfaceCleaner.Update() self.PrintLog('Triangulating surface.') surfaceTriangulator = vtk.vtkTriangleFilter() surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort()) surfaceTriangulator.PassLinesOff() surfaceTriangulator.PassVertsOff() surfaceTriangulator.Update() centerlineInputSurface = surfaceTriangulator.GetOutput() capCenterIds = None if self.SeedSelectorName in [ 'openprofiles', 'carotidprofiles', 'pickpoint', 'profileidlist' ]: self.PrintLog('Capping surface.') surfaceCapper = vtkvmtk.vtkvmtkCapPolyData() surfaceCapper.SetInputConnection( surfaceTriangulator.GetOutputPort()) surfaceCapper.SetDisplacement(self.CapDisplacement) surfaceCapper.SetInPlaneDisplacement(self.CapDisplacement) surfaceCapper.Update() centerlineInputSurface = surfaceCapper.GetOutput() capCenterIds = surfaceCapper.GetCapCenterIds() if self.SeedSelector: pass elif self.SeedSelectorName: if self.SeedSelectorName == 'pickpoint': self.SeedSelector = vmtkPickPointSeedSelector() self.SeedSelector.vmtkRenderer = self.vmtkRenderer self.SeedSelector.Script = self elif self.SeedSelectorName == 'openprofiles': self.SeedSelector = vmtkOpenProfilesSeedSelector() self.SeedSelector.vmtkRenderer = self.vmtkRenderer self.SeedSelector.Script = self self.SeedSelector.SetSeedIds(surfaceCapper.GetCapCenterIds()) elif self.SeedSelectorName == 'carotidprofiles': self.SeedSelector = vmtkCarotidProfilesSeedSelector() self.SeedSelector.SetSeedIds(surfaceCapper.GetCapCenterIds()) elif self.SeedSelectorName == 'idlist': self.SeedSelector = vmtkIdListSeedSelector() self.SeedSelector.SourceIds = self.SourceIds self.SeedSelector.TargetIds = self.TargetIds elif self.SeedSelectorName == 'pointlist': self.SeedSelector = vmtkPointListSeedSelector() self.SeedSelector.SourcePoints = self.SourcePoints self.SeedSelector.TargetPoints = self.TargetPoints elif self.SeedSelectorName != 'profileidlist': self.PrintError( "SeedSelectorName unknown (available: pickpoint, openprofiles, carotidprofiles, profileidlist, idlist, pointlist)" ) return else: self.PrintError( 'vmtkCenterlines error: either SeedSelector or SeedSelectorName must be specified' ) return if self.SeedSelector: self.SeedSelector.SetSurface(centerlineInputSurface) self.SeedSelector.InputInfo = self.InputInfo self.SeedSelector.InputText = self.InputText self.SeedSelector.OutputText = self.OutputText self.SeedSelector.PrintError = self.PrintError self.SeedSelector.PrintLog = self.PrintLog self.SeedSelector.Execute() inletSeedIds = self.SeedSelector.GetSourceSeedIds() outletSeedIds = self.SeedSelector.GetTargetSeedIds() else: inletSeedIds = vtk.vtkIdList() outletSeedIds = vtk.vtkIdList() for id in self.SourceIds: inletSeedIds.InsertNextId(id) if self.TargetIds: for id in self.TargetIds: outletSeedIds.InsertNextId(id) else: for i in range(capCenterIds.GetNumberOfIds()): if i not in self.SourceIds: outletSeedIds.InsertNextId(i) self.PrintLog('Computing centerlines.') self.InputInfo('Computing centerlines...') centerlineFilter = vtkvmtk.vtkvmtkPolyDataCenterlines() centerlineFilter.SetInputData(centerlineInputSurface) if self.SeedSelectorName in [ 'openprofiles', 'carotidprofiles', 'profileidlist' ]: centerlineFilter.SetCapCenterIds(capCenterIds) centerlineFilter.SetSourceSeedIds(inletSeedIds) centerlineFilter.SetTargetSeedIds(outletSeedIds) centerlineFilter.SetRadiusArrayName(self.RadiusArrayName) centerlineFilter.SetCostFunction(self.CostFunction) centerlineFilter.SetFlipNormals(self.FlipNormals) centerlineFilter.SetAppendEndPointsToCenterlines(self.AppendEndPoints) centerlineFilter.SetSimplifyVoronoi(self.SimplifyVoronoi) if self.DelaunayTessellation != None: centerlineFilter.GenerateDelaunayTessellationOff() centerlineFilter.SetDelaunayTessellation(self.DelaunayTessellation) centerlineFilter.SetDelaunayTolerance(self.DelaunayTolerance) if self.UseTetGen == 1: self.PrintLog('Running TetGen.') from vmtk import vmtkscripts surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = centerlineInputSurface surfaceToMesh.Execute() tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.PLC = 1 tetgen.NoMerge = 1 tetgen.Quality = 0 if self.TetGenDetectInter == 1: tetgen.DetectInter = 1 tetgen.NoMerge = 0 tetgen.OutputSurfaceElements = 0 tetgen.Execute() centerlineFilter.GenerateDelaunayTessellationOff() centerlineFilter.SetDelaunayTessellation(tetgen.Mesh) centerlineFilter.SetCenterlineResampling(self.Resampling) centerlineFilter.SetResamplingStepLength(self.ResamplingStepLength) centerlineFilter.Update() self.Centerlines = centerlineFilter.GetOutput() self.VoronoiDiagram = centerlineFilter.GetVoronoiDiagram() self.DelaunayTessellation = centerlineFilter.GetDelaunayTessellation() self.PoleIds = centerlineFilter.GetPoleIds() self.EikonalSolutionArrayName = centerlineFilter.GetEikonalSolutionArrayName( ) self.EdgeArrayName = centerlineFilter.GetEdgeArrayName() self.EdgePCoordArrayName = centerlineFilter.GetEdgePCoordArrayName() self.CostFunctionArrayName = centerlineFilter.GetCostFunctionArrayName( ) if self.OwnRenderer: self.vmtkRenderer.Deallocate()
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') if self.CheckNonManifold: self.PrintLog('NonManifold check.') nonManifoldChecker = vmtkNonManifoldSurfaceChecker() nonManifoldChecker.Surface = self.Surface nonManifoldChecker.PrintError = self.PrintError nonManifoldChecker.Execute() if nonManifoldChecker.NumberOfNonManifoldEdges > 0: self.PrintLog(nonManifoldChecker.Report) return self.PrintLog('Cleaning surface.') surfaceCleaner = vtk.vtkCleanPolyData() surfaceCleaner.SetInputData(self.Surface) surfaceCleaner.Update() self.PrintLog('Triangulating surface.') surfaceTriangulator = vtk.vtkTriangleFilter() surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort()) surfaceTriangulator.PassLinesOff() surfaceTriangulator.PassVertsOff() surfaceTriangulator.Update() surfaceCapper = vtkvmtk.vtkvmtkCapPolyData() surfaceCapper.SetInputConnection(surfaceTriangulator.GetOutputPort()) surfaceCapper.SetDisplacement(self.CapDisplacement) surfaceCapper.SetInPlaneDisplacement(self.CapDisplacement) surfaceCapper.Update() capCenterIds = surfaceCapper.GetCapCenterIds() surfaceNormals = vtk.vtkPolyDataNormals() surfaceNormals.SetInputConnection(surfaceCapper.GetOutputPort()) surfaceNormals.SplittingOff() surfaceNormals.AutoOrientNormalsOn() surfaceNormals.SetFlipNormals(self.FlipNormals) surfaceNormals.ComputePointNormalsOn() surfaceNormals.ConsistencyOn() surfaceNormals.Update() inputSurface = surfaceNormals.GetOutput() if self.UseTetGen: self.PrintLog('Running TetGen.') from vmtk import vmtkscripts surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = inputSurface surfaceToMesh.Execute() tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.PLC = 1 tetgen.NoMerge = 1 tetgen.Quality = 0 if self.TetGenDetectInter: tetgen.DetectInter = 1 tetgen.NoMerge = 0 tetgen.OutputSurfaceElements = 0 tetgen.Execute() self.DelaunayTessellation = tetgen.Mesh else: delaunayTessellator = vtk.vtkDelaunay3D() delaunayTessellator.CreateDefaultLocator() delaunayTessellator.SetInputConnection(surfaceNormals.GetOutputPort()) delaunayTessellator.SetTolerance(self.DelaunayTolerance) delaunayTessellator.Update() self.DelaunayTessellation = delaunayTessellator.GetOutput() normalsArray = surfaceNormals.GetOutput().GetPointData().GetNormals() self.DelaunayTessellation.GetPointData().AddArray(normalsArray) internalTetrahedraExtractor = vtkvmtk.vtkvmtkInternalTetrahedraExtractor() internalTetrahedraExtractor.SetInputData(self.DelaunayTessellation) internalTetrahedraExtractor.SetOutwardNormalsArrayName(normalsArray.GetName()) if self.RemoveSubresolutionTetrahedra: internalTetrahedraExtractor.RemoveSubresolutionTetrahedraOn() internalTetrahedraExtractor.SetSubresolutionFactor(self.SubresolutionFactor) internalTetrahedraExtractor.SetSurface(inputSurface) if capCenterIds.GetNumberOfIds() > 0: internalTetrahedraExtractor.UseCapsOn() internalTetrahedraExtractor.SetCapCenterIds(capCenterIds) internalTetrahedraExtractor.Update() self.DelaunayTessellation = internalTetrahedraExtractor.GetOutput() voronoiDiagramFilter = vtkvmtk.vtkvmtkVoronoiDiagram3D() voronoiDiagramFilter.SetInputData(self.DelaunayTessellation) voronoiDiagramFilter.SetRadiusArrayName(self.RadiusArrayName) voronoiDiagramFilter.Update() self.PoleIds = voronoiDiagramFilter.GetPoleIds() self.VoronoiDiagram = voronoiDiagramFilter.GetOutput() if self.SimplifyVoronoi: voronoiDiagramSimplifier = vtkvmtk.vtkvmtkSimplifyVoronoiDiagram() voronoiDiagramSimplifier.SetInputConnection(voronoiDiagramFilter.GetOutputPort()) voronoiDiagramSimplifier.SetUnremovablePointIds(voronoiDiagramFilter.GetPoleIds()) voronoiDiagramSimplifier.Update() self.VoronoiDiagram = voronoiDiagramSimplifier.GetOutput() self.Mesh = self.DelaunayTessellation self.Surface = self.VoronoiDiagram
def Execute(self): if self.Mesh == None: self.PrintError('Error: No input mesh.') if not self.CellEntityIdsArrayName: self.PrintError('Error: No input CellEntityIdsArrayName.') return cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName) #cut off the volumetric elements wallThreshold = vtk.vtkThreshold() wallThreshold.SetInputData(self.Mesh) wallThreshold.ThresholdByUpper(self.SurfaceCellEntityId-0.5) wallThreshold.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) wallThreshold.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = wallThreshold.GetOutput() meshToSurface.Execute() #Compute the normals for this surface, orientation should be right because the surface is closed #TODO: Add option for cell normals in vmtksurfacenormals normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(0) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOff() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = normalsFilter.GetOutput() surfaceToMesh.Execute() #Save the current normals wallWithBoundariesMesh = surfaceToMesh.Mesh savedNormals = vtk.vtkDoubleArray() savedNormals.DeepCopy(wallWithBoundariesMesh.GetCellData().GetNormals()) savedNormals.SetName('SavedNormals') wallWithBoundariesMesh.GetCellData().AddArray(savedNormals) #cut off the boundaries and other surfaces extrudeThresholdLower = vtk.vtkThreshold() extrudeThresholdLower.SetInputData(wallWithBoundariesMesh) extrudeThresholdLower.ThresholdByLower(self.ExtrudeCellEntityId+0.5) extrudeThresholdLower.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) extrudeThresholdLower.Update() extrudeThresholdUpper = vtk.vtkThreshold() extrudeThresholdUpper.SetInputConnection(extrudeThresholdLower.GetOutputPort()) extrudeThresholdUpper.ThresholdByUpper(self.ExtrudeCellEntityId-0.5) extrudeThresholdUpper.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) extrudeThresholdUpper.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = extrudeThresholdUpper.GetOutput() meshToSurface.Execute() #Compute cell normals without boundaries normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(0) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOn() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() wallWithoutBoundariesSurface = normalsFilter.GetOutput() normals = wallWithoutBoundariesSurface.GetCellData().GetNormals() savedNormals = wallWithoutBoundariesSurface.GetCellData().GetArray('SavedNormals') math = vtk.vtkMath() #If the normal are inverted, recompute the normals with flipping on if normals.GetNumberOfTuples() > 0 and math.Dot(normals.GetTuple3(0),savedNormals.GetTuple3(0)) < 0: normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(1) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOn() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() wallWithoutBoundariesSurface = normalsFilter.GetOutput() wallWithoutBoundariesSurface.GetPointData().GetNormals().SetName('Normals') wallWithoutBoundariesSurface.GetCellData().RemoveArray('SavedNormals') surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = wallWithoutBoundariesSurface surfaceToMesh.Execute() #Offset to apply to the array wallOffset = 0 if self.IncludeSurfaceCells or self.IncludeOriginalSurfaceCells: wallOffset += 1 if self.IncludeSurfaceCells or self.IncludeExtrudedSurfaceCells: wallOffset+=1 boundaryLayer = vmtkscripts.vmtkBoundaryLayer2() boundaryLayer.Mesh = surfaceToMesh.Mesh boundaryLayer.WarpVectorsArrayName = 'Normals' boundaryLayer.NegateWarpVectors = False boundaryLayer.ThicknessArrayName = self.ThicknessArrayName boundaryLayer.ConstantThickness = self.ConstantThickness boundaryLayer.IncludeSurfaceCells = self.IncludeSurfaceCells boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer.SubLayerRatio = self.SubLayerRatio boundaryLayer.Thickness = self.Thickness boundaryLayer.ThicknessRatio = self.Thickness boundaryLayer.MaximumThickness = self.MaximumThickness boundaryLayer.CellEntityIdsArrayName = self.CellEntityIdsArrayName boundaryLayer.IncludeExtrudedOpenProfilesCells = self.IncludeExtrudedOpenProfilesCells boundaryLayer.IncludeExtrudedSurfaceCells = self.IncludeExtrudedSurfaceCells boundaryLayer.IncludeOriginalSurfaceCells = self.IncludeOriginalSurfaceCells boundaryLayer.LayerEntityId = self.SurfaceCellEntityId boundaryLayer.SurfaceEntityId = self.InletOutletCellEntityId + 1 if cellEntityIdsArray != None: #Append the new surface ids idRange = cellEntityIdsArray.GetRange() boundaryLayer.OpenProfilesEntityId = idRange[1] + wallOffset + 2 boundaryLayer.Execute() if cellEntityIdsArray != None: #offset the previous cellentityids to make room for the new ones arrayCalculator = vtk.vtkArrayCalculator() arrayCalculator.SetInputData(self.Mesh) if vtk.vtkVersion.GetVTKMajorVersion()>=9 or (vtk.vtkVersion.GetVTKMajorVersion()>=8 and vtk.vtkVersion.GetVTKMinorVersion()>=1): arrayCalculator.SetAttributeTypeToCellData() else: arrayCalculator.SetAttributeModeToUseCellData() arrayCalculator.AddScalarVariable("entityid",self.CellEntityIdsArrayName,0) arrayCalculator.SetFunction("if( entityid > " + str(self.InletOutletCellEntityId-1) +", entityid + " + str(wallOffset) + ", entityid)") arrayCalculator.SetResultArrayName('CalculatorResult') arrayCalculator.Update() #This need to be copied in order to be of the right type (int) cellEntityIdsArray.DeepCopy(arrayCalculator.GetOutput().GetCellData().GetArray('CalculatorResult')) arrayCalculator.SetFunction("if( entityid > " + str(self.SurfaceCellEntityId-1) +", entityid + 1, entityid)") arrayCalculator.Update() ##This need to be copied in order to be of the right type (int) cellEntityIdsArray.DeepCopy(arrayCalculator.GetOutput().GetCellData().GetArray('CalculatorResult')) appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(self.Mesh) appendFilter.AddInput(boundaryLayer.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput()
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') if self.CheckNonManifold: self.PrintLog('NonManifold check.') nonManifoldChecker = vmtkNonManifoldSurfaceChecker() nonManifoldChecker.Surface = self.Surface nonManifoldChecker.PrintError = self.PrintError nonManifoldChecker.Execute() if nonManifoldChecker.NumberOfNonManifoldEdges > 0: self.PrintLog(nonManifoldChecker.Report) return self.PrintLog('Cleaning surface.') surfaceCleaner = vtk.vtkCleanPolyData() surfaceCleaner.SetInputData(self.Surface) surfaceCleaner.Update() self.PrintLog('Triangulating surface.') surfaceTriangulator = vtk.vtkTriangleFilter() surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort()) surfaceTriangulator.PassLinesOff() surfaceTriangulator.PassVertsOff() surfaceTriangulator.Update() surfaceCapper = vtkvmtk.vtkvmtkCapPolyData() surfaceCapper.SetInputConnection(surfaceTriangulator.GetOutputPort()) surfaceCapper.SetDisplacement(self.CapDisplacement) surfaceCapper.SetInPlaneDisplacement(self.CapDisplacement) surfaceCapper.Update() capCenterIds = surfaceCapper.GetCapCenterIds() surfaceNormals = vtk.vtkPolyDataNormals() surfaceNormals.SetInputConnection(surfaceCapper.GetOutputPort()) surfaceNormals.SplittingOff() surfaceNormals.AutoOrientNormalsOn() surfaceNormals.SetFlipNormals(self.FlipNormals) surfaceNormals.ComputePointNormalsOn() surfaceNormals.ConsistencyOn() surfaceNormals.Update() inputSurface = surfaceNormals.GetOutput() if self.UseTetGen: self.PrintLog('Running TetGen.') from vmtk import vmtkscripts surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = inputSurface surfaceToMesh.Execute() tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.PLC = 1 tetgen.NoMerge = 1 tetgen.Quality = 0 if self.TetGenDetectInter: tetgen.DetectInter = 1 tetgen.NoMerge = 0 tetgen.OutputSurfaceElements = 0 tetgen.Execute() self.DelaunayTessellation = tetgen.Mesh else: delaunayTessellator = vtk.vtkDelaunay3D() delaunayTessellator.CreateDefaultLocator() delaunayTessellator.SetInputConnection(surfaceNormals.GetOutputPort()) delaunayTessellator.SetTolerance(self.DelaunayTolerance) delaunayTessellator.Update() self.DelaunayTessellation = delaunayTessellator.GetOutput() normalsArray = surfaceNormals.GetOutput().GetPointData().GetNormals() self.DelaunayTessellation.GetPointData().AddArray(normalsArray) internalTetrahedraExtractor = vtkvmtk.vtkvmtkInternalTetrahedraExtractor() internalTetrahedraExtractor.SetInputData(self.DelaunayTessellation) internalTetrahedraExtractor.SetOutwardNormalsArrayName(normalsArray.GetName()) if self.RemoveSubresolutionTetrahedra: internalTetrahedraExtractor.RemoveSubresolutionTetrahedraOn() internalTetrahedraExtractor.SetSubresolutionFactor(self.SubresolutionFactor) internalTetrahedraExtractor.SetSurface(inputSurface) if capCenterIds.GetNumberOfIds() > 0: internalTetrahedraExtractor.UseCapsOn() internalTetrahedraExtractor.SetCapCenterIds(capCenterIds) internalTetrahedraExtractor.Update() self.DelaunayTessellation = internalTetrahedraExtractor.GetOutput() voronoiDiagramFilter = vtkvmtk.vtkvmtkVoronoiDiagram3D() voronoiDiagramFilter.SetInputData(self.DelaunayTessellation) voronoiDiagramFilter.SetRadiusArrayName(self.RadiusArrayName) voronoiDiagramFilter.Update() self.PoleIds = voronoiDiagramFilter.GetPoleIds() self.VoronoiDiagram = voronoiDiagramFilter.GetOutput() if self.SimplifyVoronoi: voronoiDiagramSimplifier = vtkvmtk.vtkvmtkSimplifyVoronoiDiagram() voronoiDiagramSimplifier.SetInputConnection(voronoiDiagramFilter.GetOutputPort()) voronoiDiagramSimplifier.SetUnremovablePointIds(voronoiDiagramFilter.GetPoleIds()) voronoiDiagramSimplifier.Update() self.VoronoiDiagram = voronoiDiagramSimplifier.GetOutput() self.Mesh = self.DelaunayTessellation self.Surface = self.VoronoiDiagram
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') if self.CheckNonManifold: self.PrintLog('NonManifold check.') nonManifoldChecker = vmtkNonManifoldSurfaceChecker() nonManifoldChecker.Surface = self.Surface nonManifoldChecker.PrintError = self.PrintError nonManifoldChecker.Execute() if (nonManifoldChecker.NumberOfNonManifoldEdges > 0): self.PrintLog(nonManifoldChecker.Report) return if not self.vmtkRenderer and self.SeedSelectorName in ['pickpoint','openprofiles']: self.vmtkRenderer = vmtkrenderer.vmtkRenderer() self.vmtkRenderer.Initialize() self.OwnRenderer = 1 self.PrintLog('Cleaning surface.') surfaceCleaner = vtk.vtkCleanPolyData() surfaceCleaner.SetInputData(self.Surface) surfaceCleaner.Update() self.PrintLog('Triangulating surface.') surfaceTriangulator = vtk.vtkTriangleFilter() surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort()) surfaceTriangulator.PassLinesOff() surfaceTriangulator.PassVertsOff() surfaceTriangulator.Update() centerlineInputSurface = surfaceTriangulator.GetOutput() capCenterIds = None if self.SeedSelectorName in ['openprofiles', 'carotidprofiles', 'pickpoint', 'profileidlist']: self.PrintLog('Capping surface.') surfaceCapper = vtkvmtk.vtkvmtkCapPolyData() surfaceCapper.SetInputConnection(surfaceTriangulator.GetOutputPort()) surfaceCapper.SetDisplacement(self.CapDisplacement) surfaceCapper.SetInPlaneDisplacement(self.CapDisplacement) surfaceCapper.Update() centerlineInputSurface = surfaceCapper.GetOutput() capCenterIds = surfaceCapper.GetCapCenterIds() if self.SeedSelector: pass elif self.SeedSelectorName: if self.SeedSelectorName == 'pickpoint': self.SeedSelector = vmtkPickPointSeedSelector() self.SeedSelector.vmtkRenderer = self.vmtkRenderer self.SeedSelector.Script = self elif self.SeedSelectorName == 'openprofiles': self.SeedSelector = vmtkOpenProfilesSeedSelector() self.SeedSelector.vmtkRenderer = self.vmtkRenderer self.SeedSelector.Script = self self.SeedSelector.SetSeedIds(surfaceCapper.GetCapCenterIds()) elif self.SeedSelectorName == 'carotidprofiles': self.SeedSelector = vmtkCarotidProfilesSeedSelector() self.SeedSelector.SetSeedIds(surfaceCapper.GetCapCenterIds()) elif self.SeedSelectorName == 'idlist': self.SeedSelector = vmtkIdListSeedSelector() self.SeedSelector.SourceIds = self.SourceIds self.SeedSelector.TargetIds = self.TargetIds elif self.SeedSelectorName == 'pointlist': self.SeedSelector = vmtkPointListSeedSelector() self.SeedSelector.SourcePoints = self.SourcePoints self.SeedSelector.TargetPoints = self.TargetPoints elif self.SeedSelectorName != 'profileidlist': self.PrintError("SeedSelectorName unknown (available: pickpoint, openprofiles, carotidprofiles, profileidlist, idlist, pointlist)") return else: self.PrintError('vmtkCenterlines error: either SeedSelector or SeedSelectorName must be specified') return if self.SeedSelector: self.SeedSelector.SetSurface(centerlineInputSurface) self.SeedSelector.InputInfo = self.InputInfo self.SeedSelector.InputText = self.InputText self.SeedSelector.OutputText = self.OutputText self.SeedSelector.PrintError = self.PrintError self.SeedSelector.PrintLog = self.PrintLog self.SeedSelector.Execute() inletSeedIds = self.SeedSelector.GetSourceSeedIds() outletSeedIds = self.SeedSelector.GetTargetSeedIds() else: inletSeedIds = vtk.vtkIdList() outletSeedIds = vtk.vtkIdList() for id in self.SourceIds: inletSeedIds.InsertNextId(id) if self.TargetIds: for id in self.TargetIds: outletSeedIds.InsertNextId(id) else: for i in range(capCenterIds.GetNumberOfIds()): if i not in self.SourceIds: outletSeedIds.InsertNextId(i) self.PrintLog('Computing centerlines.') self.InputInfo('Computing centerlines...') centerlineFilter = vtkvmtk.vtkvmtkPolyDataCenterlines() centerlineFilter.SetInputData(centerlineInputSurface) if self.SeedSelectorName in ['openprofiles','carotidprofiles','profileidlist']: centerlineFilter.SetCapCenterIds(capCenterIds) centerlineFilter.SetSourceSeedIds(inletSeedIds) centerlineFilter.SetTargetSeedIds(outletSeedIds) centerlineFilter.SetRadiusArrayName(self.RadiusArrayName) centerlineFilter.SetCostFunction(self.CostFunction) centerlineFilter.SetFlipNormals(self.FlipNormals) centerlineFilter.SetAppendEndPointsToCenterlines(self.AppendEndPoints) centerlineFilter.SetSimplifyVoronoi(self.SimplifyVoronoi) if self.DelaunayTessellation != None: centerlineFilter.GenerateDelaunayTessellationOff() centerlineFilter.SetDelaunayTessellation(self.DelaunayTessellation) centerlineFilter.SetDelaunayTolerance(self.DelaunayTolerance) if self.UseTetGen==1: self.PrintLog('Running TetGen.') from vmtk import vmtkscripts surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = centerlineInputSurface surfaceToMesh.Execute() tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.PLC = 1 tetgen.NoMerge = 1 tetgen.Quality = 0 if self.TetGenDetectInter == 1: tetgen.DetectInter = 1 tetgen.NoMerge = 0 tetgen.OutputSurfaceElements = 0 tetgen.Execute() centerlineFilter.GenerateDelaunayTessellationOff() centerlineFilter.SetDelaunayTessellation(tetgen.Mesh) centerlineFilter.SetCenterlineResampling(self.Resampling) centerlineFilter.SetResamplingStepLength(self.ResamplingStepLength) centerlineFilter.Update() self.Centerlines = centerlineFilter.GetOutput() self.VoronoiDiagram = centerlineFilter.GetVoronoiDiagram() self.DelaunayTessellation = centerlineFilter.GetDelaunayTessellation() self.PoleIds = centerlineFilter.GetPoleIds() self.EikonalSolutionArrayName = centerlineFilter.GetEikonalSolutionArrayName() self.EdgeArrayName = centerlineFilter.GetEdgeArrayName() self.EdgePCoordArrayName = centerlineFilter.GetEdgePCoordArrayName() self.CostFunctionArrayName = centerlineFilter.GetCostFunctionArrayName() if self.OwnRenderer: self.vmtkRenderer.Deallocate()
def Execute(self): if self.Mesh == None: self.PrintError('Error: No input mesh.') if not self.CellEntityIdsArrayName: self.PrintError('Error: No input CellEntityIdsArrayName.') return cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName) #cut off the volumetric elements wallThreshold = vtk.vtkThreshold() wallThreshold.SetInputData(self.Mesh) wallThreshold.ThresholdByUpper(self.SurfaceCellEntityId-0.5) wallThreshold.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) wallThreshold.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = wallThreshold.GetOutput() meshToSurface.Execute() #Compute the normals for this surface, orientation should be right because the surface is closed #TODO: Add option for cell normals in vmtksurfacenormals normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(0) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOff() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = normalsFilter.GetOutput() surfaceToMesh.Execute() #Save the current normals wallWithBoundariesMesh = surfaceToMesh.Mesh savedNormals = vtk.vtkDoubleArray() savedNormals.DeepCopy(wallWithBoundariesMesh.GetCellData().GetNormals()) savedNormals.SetName('SavedNormals') wallWithBoundariesMesh.GetCellData().AddArray(savedNormals) #cut off the boundaries and other surfaces extrudeThresholdLower = vtk.vtkThreshold() extrudeThresholdLower.SetInputData(wallWithBoundariesMesh) extrudeThresholdLower.ThresholdByLower(self.ExtrudeCellEntityId+0.5) extrudeThresholdLower.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) extrudeThresholdLower.Update() extrudeThresholdUpper = vtk.vtkThreshold() extrudeThresholdUpper.SetInputConnection(extrudeThresholdLower.GetOutputPort()) extrudeThresholdUpper.ThresholdByUpper(self.ExtrudeCellEntityId-0.5) extrudeThresholdUpper.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) extrudeThresholdUpper.Update() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = extrudeThresholdUpper.GetOutput() meshToSurface.Execute() #Compute cell normals without boundaries normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(0) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOn() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() wallWithoutBoundariesSurface = normalsFilter.GetOutput() normals = wallWithoutBoundariesSurface.GetCellData().GetNormals() savedNormals = wallWithoutBoundariesSurface.GetCellData().GetArray('SavedNormals') math = vtk.vtkMath() #If the normal are inverted, recompute the normals with flipping on if normals.GetNumberOfTuples() > 0 and math.Dot(normals.GetTuple3(0),savedNormals.GetTuple3(0)) < 0: normalsFilter = vtk.vtkPolyDataNormals() normalsFilter.SetInputData(meshToSurface.Surface) normalsFilter.SetAutoOrientNormals(1) normalsFilter.SetFlipNormals(1) normalsFilter.SetConsistency(1) normalsFilter.SplittingOff() normalsFilter.ComputePointNormalsOn() normalsFilter.ComputeCellNormalsOn() normalsFilter.Update() wallWithoutBoundariesSurface = normalsFilter.GetOutput() wallWithoutBoundariesSurface.GetPointData().GetNormals().SetName('Normals') wallWithoutBoundariesSurface.GetCellData().RemoveArray('SavedNormals') surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = wallWithoutBoundariesSurface surfaceToMesh.Execute() #Offset to apply to the array wallOffset = 0 if self.IncludeSurfaceCells or self.IncludeOriginalSurfaceCells: wallOffset += 1 if self.IncludeSurfaceCells or self.IncludeExtrudedSurfaceCells: wallOffset+=1 boundaryLayer = vmtkscripts.vmtkBoundaryLayer2() boundaryLayer.Mesh = surfaceToMesh.Mesh boundaryLayer.WarpVectorsArrayName = 'Normals' boundaryLayer.NegateWarpVectors = False boundaryLayer.ThicknessArrayName = self.ThicknessArrayName boundaryLayer.ConstantThickness = self.ConstantThickness boundaryLayer.IncludeSurfaceCells = self.IncludeSurfaceCells boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer.SubLayerRatio = self.SubLayerRatio boundaryLayer.Thickness = self.Thickness boundaryLayer.ThicknessRatio = self.Thickness boundaryLayer.MaximumThickness = self.MaximumThickness boundaryLayer.CellEntityIdsArrayName = self.CellEntityIdsArrayName boundaryLayer.IncludeExtrudedOpenProfilesCells = self.IncludeExtrudedOpenProfilesCells boundaryLayer.IncludeExtrudedSurfaceCells = self.IncludeExtrudedSurfaceCells boundaryLayer.IncludeOriginalSurfaceCells = self.IncludeOriginalSurfaceCells boundaryLayer.LayerEntityId = self.SurfaceCellEntityId boundaryLayer.SurfaceEntityId = self.InletOutletCellEntityId + 1 if cellEntityIdsArray != None: #Append the new surface ids idRange = cellEntityIdsArray.GetRange() boundaryLayer.OpenProfilesEntityId = idRange[1] + wallOffset + 2 boundaryLayer.Execute() if cellEntityIdsArray != None: #offset the previous cellentityids to make room for the new ones arrayCalculator = vtk.vtkArrayCalculator() arrayCalculator.SetInputData(self.Mesh) if vtk.vtkVersion.GetVTKMajorVersion()>=9 or (vtk.vtkVersion.GetVTKMajorVersion()>=8 and vtk.vtkVersion.GetVTKMinorVersion()>=1): arrayCalculator.SetAttributeTypeToCellData() else: arrayCalculator.SetAttributeModeToUseCellData() arrayCalculator.AddScalarVariable("entityid",self.CellEntityIdsArrayName,0) arrayCalculator.SetFunction("if( entityid > " + str(self.InletOutletCellEntityId-1) +", entityid + " + str(wallOffset) + ", entityid)") arrayCalculator.SetResultArrayName('CalculatorResult') arrayCalculator.Update() #This need to be copied in order to be of the right type (int) cellEntityIdsArray.DeepCopy(arrayCalculator.GetOutput().GetCellData().GetArray('CalculatorResult')) arrayCalculator.SetFunction("if( entityid > " + str(self.SurfaceCellEntityId-1) +", entityid + 1, entityid)") arrayCalculator.Update() ##This need to be copied in order to be of the right type (int) cellEntityIdsArray.DeepCopy(arrayCalculator.GetOutput().GetCellData().GetArray('CalculatorResult')) appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(self.Mesh) appendFilter.AddInput(boundaryLayer.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput()
def Execute(self): from vmtk import vmtkscripts if self.Surface == None: self.PrintError('Error: No input surface.') wallEntityOffset = 1 if self.SkipCapping or not self.BoundaryLayerOnCaps: self.PrintLog("Not capping surface") surface = self.Surface cellEntityIdsArray = vtk.vtkIntArray() cellEntityIdsArray.SetName(self.CellEntityIdsArrayName) cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells()) cellEntityIdsArray.FillComponent(0,0.0) surface.GetCellData().AddArray(cellEntityIdsArray) else: self.PrintLog("Capping surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = self.Surface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 0 capper.CellEntityIdOffset = wallEntityOffset capper.Execute() surface = capper.Surface if self.SkipRemeshing: remeshedSurface = surface else: self.PrintLog("Remeshing surface") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode if self.RemeshCapsOnly: remeshing.ExcludeEntityIds = [wallEntityOffset] remeshing.Execute() remeshedSurface = remeshing.Surface if self.BoundaryLayer: projection = vmtkscripts.vmtkSurfaceProjection() projection.Surface = remeshedSurface projection.ReferenceSurface = surface projection.Execute() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = projection.Surface normals.NormalsArrayName = 'Normals' normals.Execute() surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = normals.Surface surfaceToMesh.Execute() self.PrintLog("Generating boundary layer") placeholderCellEntityId = 9999 boundaryLayer = vmtkscripts.vmtkBoundaryLayer() boundaryLayer.Mesh = surfaceToMesh.Mesh boundaryLayer.WarpVectorsArrayName = 'Normals' boundaryLayer.NegateWarpVectors = True boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName if self.ElementSizeMode == 'edgelength': boundaryLayer.ConstantThickness = True else: boundaryLayer.ConstantThickness = False boundaryLayer.IncludeSurfaceCells = 0 boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps boundaryLayer.Relaxation = self.Relaxation boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor boundaryLayer.SubLayerRatio = self.SubLayerRatio boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength if not self.BoundaryLayerOnCaps: boundaryLayer.SidewallCellEntityId = placeholderCellEntityId boundaryLayer.InnerSurfaceCellEntityId = wallEntityOffset boundaryLayer.Execute() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh meshToSurface.Execute() innerSurface = meshToSurface.Surface if not self.BoundaryLayerOnCaps: self.PrintLog("Capping inner surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = innerSurface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 1 capper.CellEntityIdOffset = wallEntityOffset capper.Execute() self.PrintLog("Remeshing endcaps") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = capper.Surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode remeshing.ExcludeEntityIds = [wallEntityOffset] remeshing.Execute() innerSurface = remeshing.Surface self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(innerSurface) sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh2.Surface = sizingFunction.GetOutput() surfaceToMesh2.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh2.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 0 tetgen.OutputVolumeElements = 1 tetgen.Execute() #w = vtk.vtkXMLUnstructuredGridWriter() #w.SetInput(tetgen.Mesh) #w.SetFileName('tet.vtu') #w.Write() if tetgen.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0: self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh and boundary layer.') if not self.BoundaryLayerOnCaps: surfaceToMesh.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName).FillComponent(0,wallEntityOffset) self.PrintLog("Assembling final mesh") appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInputData(surfaceToMesh.Mesh) appendFilter.AddInputData(boundaryLayer.Mesh) appendFilter.AddInputData(tetgen.Mesh) #appendFilter.AddInput(boundaryLayer.InnerSurfaceMesh) if not self.BoundaryLayerOnCaps: threshold = vtk.vtkThreshold() threshold.SetInputData(surfaceToMesh2.Mesh) threshold.ThresholdByUpper(1.5) threshold.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName) threshold.Update() endcaps = threshold.GetOutput() appendFilter.AddInputData(endcaps) appendFilter.Update() self.Mesh = appendFilter.GetOutput() if not self.BoundaryLayerOnCaps: cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName) def VisitNeighbors(i, cellEntityId): cellPointIds = vtk.vtkIdList() self.Mesh.GetCellPoints(i,cellPointIds) neighborPointIds = vtk.vtkIdList() neighborPointIds.SetNumberOfIds(1) pointNeighborCellIds = vtk.vtkIdList() neighborCellIds = vtk.vtkIdList() for j in range(cellPointIds.GetNumberOfIds()): neighborPointIds.SetId(0,cellPointIds.GetId(j)) self.Mesh.GetCellNeighbors(i,neighborPointIds,pointNeighborCellIds) for k in range(pointNeighborCellIds.GetNumberOfIds()): neighborCellIds.InsertNextId(pointNeighborCellIds.GetId(k)) for j in range(neighborCellIds.GetNumberOfIds()): cellId = neighborCellIds.GetId(j) neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId) neighborCellType = self.Mesh.GetCellType(cellId) if neighborCellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]: continue if neighborCellEntityId != placeholderCellEntityId: continue cellEntityIdsArray.SetTuple1(cellId,cellEntityId) VisitNeighbors(cellId,cellEntityId) for i in range(self.Mesh.GetNumberOfCells()): cellEntityId = cellEntityIdsArray.GetTuple1(i) cellType = self.Mesh.GetCellType(i) if cellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]: continue if cellEntityId in [0, 1, placeholderCellEntityId]: continue VisitNeighbors(i,cellEntityId) else: self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(remeshedSurface) sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() self.PrintLog("Converting surface to mesh") surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = sizingFunction.GetOutput() surfaceToMesh.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 1 tetgen.OutputVolumeElements = 1 tetgen.Execute() self.Mesh = tetgen.Mesh if self.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0: self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh.') self.Mesh = surfaceToMesh.Mesh if self.Tetrahedralize: tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter() tetrahedralize.SetInputData(self.Mesh) tetrahedralize.Update() self.Mesh = tetrahedralize.GetOutput() self.RemeshedSurface = remeshedSurface
def Execute(self): from vmtk import vmtkscripts if self.Surface == None: self.PrintError('Error: No input surface.') wallEntityOffset = 1 if self.SkipCapping or not self.BoundaryLayerOnCaps: self.PrintLog("Not capping surface") surface = self.Surface cellEntityIdsArray = vtk.vtkIntArray() cellEntityIdsArray.SetName(self.CellEntityIdsArrayName) cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells()) cellEntityIdsArray.FillComponent(0,0.0) surface.GetCellData().AddArray(cellEntityIdsArray) else: self.PrintLog("Capping surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = self.Surface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 0 capper.CellEntityIdOffset = wallEntityOffset capper.Execute() surface = capper.Surface if self.SkipRemeshing: remeshedSurface = surface else: self.PrintLog("Remeshing surface") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode if self.RemeshCapsOnly: remeshing.ExcludeEntityIds = [wallEntityOffset] remeshing.Execute() remeshedSurface = remeshing.Surface if self.BoundaryLayer: projection = vmtkscripts.vmtkSurfaceProjection() projection.Surface = remeshedSurface projection.ReferenceSurface = surface projection.Execute() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = projection.Surface normals.NormalsArrayName = 'Normals' normals.Execute() surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = normals.Surface surfaceToMesh.Execute() self.PrintLog("Generating boundary layer fluid") placeholderCellEntityId = 9999 boundaryLayer = vmtkscripts.vmtkBoundaryLayer() boundaryLayer.Mesh = surfaceToMesh.Mesh boundaryLayer.WarpVectorsArrayName = 'Normals' boundaryLayer.NegateWarpVectors = True boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName if self.ElementSizeMode == 'edgelength': boundaryLayer.ConstantThickness = True else: boundaryLayer.ConstantThickness = False boundaryLayer.IncludeSurfaceCells = 0 boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps boundaryLayer.Relaxation = self.Relaxation boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor boundaryLayer.SubLayerRatio = self.SubLayerRatio boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength if not self.BoundaryLayerOnCaps: boundaryLayer.SidewallCellEntityId = placeholderCellEntityId boundaryLayer.InnerSurfaceCellEntityId = wallEntityOffset boundaryLayer.VolumeCellEntityId = self.VolumeId_fluid boundaryLayer.Execute() self.PrintLog("Generating boundary layer solid") boundaryLayer2 = vmtkscripts.vmtkBoundaryLayer() boundaryLayer2.Mesh = surfaceToMesh.Mesh boundaryLayer2.WarpVectorsArrayName = 'Normals' boundaryLayer2.NegateWarpVectors = True boundaryLayer2.ThicknessArrayName = self.TargetEdgeLengthArrayName if self.ElementSizeMode == 'edgelength': boundaryLayer2.ConstantThickness = True else: boundaryLayer2.ConstantThickness = False boundaryLayer2.IncludeSurfaceCells = 1 boundaryLayer2.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer2.NumberOfSubsteps = self.NumberOfSubsteps boundaryLayer2.Relaxation = self.Relaxation boundaryLayer2.LocalCorrectionFactor = self.LocalCorrectionFactor boundaryLayer2.SubLayerRatio = self.SubLayerRatio boundaryLayer2.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer2.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer2.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength if not self.BoundaryLayerOnCaps: boundaryLayer2.SidewallCellEntityId = self.SolidSideWallId #placeholderCellEntityId boundaryLayer2.InnerSurfaceCellEntityId = self.InterfaceId_fsi # wallEntityOffset boundaryLayer2.OuterSurfaceCellEntityId = self.InterfaceId_outer # wallEntityOffset boundaryLayer2.VolumeCellEntityId = self.VolumeId_solid boundaryLayer2.Execute() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh meshToSurface.Execute() innerSurface = meshToSurface.Surface if not self.BoundaryLayerOnCaps: self.PrintLog("Capping inner surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = innerSurface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 1 capper.CellEntityIdOffset = wallEntityOffset capper.Execute() self.PrintLog("Remeshing endcaps") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = capper.Surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode remeshing.ExcludeEntityIds = [wallEntityOffset] # [wallEntityOffset, InterfaceId] #[wallEntityOffset] remeshing.Execute() innerSurface = remeshing.Surface self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(innerSurface) sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh2.Surface = sizingFunction.GetOutput() surfaceToMesh2.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh2.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 1 tetgen.OutputVolumeElements = 1 tetgen.RegionAttrib = 0 tetgen.Execute() ##### ADDING CELL IDs #array = vtk.vtkDoubleArray() #array.SetNumberOfTuples(tetgen.Mesh.GetNumberOfCells()) #array.SetNumberOfComponents(1) #array.FillComponent(0, 1.0) #array.SetName('RegionIDs') #tetgen.Mesh.GetCellData().AddArray(array) #array = vtk.vtkDoubleArray() #array.SetNumberOfTuples(boundaryLayer.Mesh.GetNumberOfCells()) #array.SetNumberOfComponents(1) #array.FillComponent(0, 1.0) #array.SetName('RegionIDs') #boundaryLayer.Mesh.GetCellData().AddArray(array) #array = vtk.vtkDoubleArray() #array.SetNumberOfTuples(boundaryLayer2.Mesh.GetNumberOfCells()) #array.SetNumberOfComponents(1) #array.FillComponent(0, 2.0) #array.SetName('RegionIDs') #boundaryLayer2.Mesh.GetCellData().AddArray(array) ##### # w1 = vtk.vtkXMLUnstructuredGridWriter() # w1.SetInputData(boundaryLayer2.Mesh) # w1.SetFileName('BoundaryLayer2.vtu') # w1.Write() # # w2 = vtk.vtkXMLUnstructuredGridWriter() # w2.SetInputData(tetgen.Mesh) # w2.SetFileName('Tetgen.vtu') # w2.Write() # # w3 = vtk.vtkXMLUnstructuredGridWriter() # w3.SetInputData(boundaryLayer.Mesh) # w3.SetFileName('BoundaryLayer.vtu') # w3.Write() # # w4 = vtk.vtkXMLUnstructuredGridWriter() # w4.SetInputData(boundaryLayer.InnerSurfaceMesh) # w4.SetFileName('InnerLayer.vtu') # w4.Write() #from IPython import embed; embed() self.PrintLog("Assembling fluid mesh") appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInputData(boundaryLayer.Mesh) appendFilter.AddInputData(tetgen.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput() if not self.BoundaryLayerOnCaps: cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName) def VisitNeighbors(i, cellEntityId): cellPointIds = vtk.vtkIdList() self.Mesh.GetCellPoints(i,cellPointIds) neighborPointIds = vtk.vtkIdList() neighborPointIds.SetNumberOfIds(1) pointNeighborCellIds = vtk.vtkIdList() neighborCellIds = vtk.vtkIdList() for j in range(cellPointIds.GetNumberOfIds()): neighborPointIds.SetId(0,cellPointIds.GetId(j)) self.Mesh.GetCellNeighbors(i,neighborPointIds,pointNeighborCellIds) for k in range(pointNeighborCellIds.GetNumberOfIds()): neighborCellIds.InsertNextId(pointNeighborCellIds.GetId(k)) for j in range(neighborCellIds.GetNumberOfIds()): cellId = neighborCellIds.GetId(j) neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId) neighborCellType = self.Mesh.GetCellType(cellId) if neighborCellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]: continue if neighborCellEntityId != placeholderCellEntityId: continue cellEntityIdsArray.SetTuple1(cellId,cellEntityId) VisitNeighbors(cellId,cellEntityId) for i in range(self.Mesh.GetNumberOfCells()): cellEntityId = cellEntityIdsArray.GetTuple1(i) cellType = self.Mesh.GetCellType(i) if cellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]: continue if cellEntityId in [0, 1, placeholderCellEntityId]: continue VisitNeighbors(i,cellEntityId) self.PrintLog("Assembling final FSI mesh") appendFilter2 = vtkvmtk.vtkvmtkAppendFilter() appendFilter2.AddInputData(appendFilter.GetOutput()) appendFilter2.AddInputData(boundaryLayer2.Mesh) appendFilter2.Update() self.Mesh = appendFilter2.GetOutput() else: self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(remeshedSurface) sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() self.PrintLog("Converting surface to mesh") surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = sizingFunction.GetOutput() surfaceToMesh.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 1 tetgen.OutputVolumeElements = 1 tetgen.Execute() self.Mesh = tetgen.Mesh if self.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0: self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh.') self.Mesh = surfaceToMesh.Mesh if self.Tetrahedralize: tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter() tetrahedralize.SetInputData(self.Mesh) tetrahedralize.Update() self.Mesh = tetrahedralize.GetOutput() self.RemeshedSurface = remeshedSurface
def Execute(self): from vmtk import vmtkscripts if self.Surface == None: self.PrintError('Error: No input surface.') wallEntityOffset = 1 if self.SkipCapping or not self.BoundaryLayerOnCaps: self.PrintLog("Not capping surface") surface = self.Surface cellEntityIdsArray = vtk.vtkIntArray() cellEntityIdsArray.SetName(self.CellEntityIdsArrayName) cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells()) cellEntityIdsArray.FillComponent(0, 0.0) surface.GetCellData().AddArray(cellEntityIdsArray) else: self.PrintLog("Capping surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = self.Surface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 0 capper.CellEntityIdOffset = self.Vessel_inlet_outlet capper.Execute() surface = capper.Surface if self.SkipRemeshing: remeshedSurface = surface else: self.PrintLog("Remeshing surface") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode if self.RemeshCapsOnly: remeshing.ExcludeEntityIds = [self.Vessel_wall] remeshing.Execute() remeshedSurface = remeshing.Surface if self.BoundaryLayer: projection = vmtkscripts.vmtkSurfaceProjection() projection.Surface = remeshedSurface projection.ReferenceSurface = surface projection.Execute() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = projection.Surface normals.NormalsArrayName = 'Normals' normals.Execute() surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = normals.Surface surfaceToMesh.Execute() self.PrintLog("Generating 1st boundary layer -- PVS") placeholderCellEntityId = 9999 boundaryLayer = vmtkscripts.vmtkBoundaryLayer() boundaryLayer.Mesh = surfaceToMesh.Mesh boundaryLayer.WarpVectorsArrayName = 'Normals' boundaryLayer.NegateWarpVectors = True boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName if self.ElementSizeMode == 'edgelength': boundaryLayer.ConstantThickness = True else: boundaryLayer.ConstantThickness = False boundaryLayer.IncludeSurfaceCells = 0 boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps boundaryLayer.Relaxation = self.Relaxation boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor boundaryLayer.SubLayerRatio = self.SubLayerRatio boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength if not self.BoundaryLayerOnCaps: boundaryLayer.SidewallCellEntityId = placeholderCellEntityId boundaryLayer.InnerSurfaceCellEntityId = self.Vessel_wall boundaryLayer.VolumeCellEntityId = self.PVS boundaryLayer.Execute() # We need a second boundary layer to make sure we have the right OuterSurface self.PrintLog("Generating 2nd boundary layer -- PVS") placeholderCellEntityId2 = 99999 boundaryLayer2 = vmtkscripts.vmtkBoundaryLayer() boundaryLayer2.Mesh = surfaceToMesh.Mesh boundaryLayer2.WarpVectorsArrayName = 'Normals' boundaryLayer2.NegateWarpVectors = True boundaryLayer2.ThicknessArrayName = self.TargetEdgeLengthArrayName if self.ElementSizeMode == 'edgelength': boundaryLayer2.ConstantThickness = True else: boundaryLayer2.ConstantThickness = False boundaryLayer2.IncludeSurfaceCells = 1 boundaryLayer2.NumberOfSubLayers = self.NumberOfSubLayers boundaryLayer2.NumberOfSubsteps = self.NumberOfSubsteps boundaryLayer2.Relaxation = self.Relaxation boundaryLayer2.LocalCorrectionFactor = self.LocalCorrectionFactor boundaryLayer2.SubLayerRatio = self.SubLayerRatio boundaryLayer2.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer2.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer2.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength if not self.BoundaryLayerOnCaps: boundaryLayer2.SidewallCellEntityId = placeholderCellEntityId2 boundaryLayer2.OuterSurfaceCellEntityId = self.PVS_wall boundaryLayer2.VolumeCellEntityId = self.PVS boundaryLayer2.Execute() meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh meshToSurface.Execute() innerSurface = meshToSurface.Surface if not self.BoundaryLayerOnCaps: self.PrintLog("Capping inner surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = innerSurface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 1 capper.CellEntityIdOffset = self.Vessel_inlet_outlet capper.Execute() self.PrintLog("Remeshing endcaps") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = capper.Surface remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.TriangleSplitFactor = self.TriangleSplitFactor remeshing.ElementSizeMode = self.ElementSizeMode remeshing.ExcludeEntityIds = [self.Vessel_wall] remeshing.Execute() innerSurface = remeshing.Surface self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(innerSurface) sizingFunction.SetSizingFunctionArrayName( self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh2.Surface = sizingFunction.GetOutput() surfaceToMesh2.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh2.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 1 tetgen.OutputVolumeElements = 1 tetgen.RegionAttrib = 1 tetgen.Execute() # Define VisitNeighbors used to differenciate markers in Sidewall areas def VisitNeighbors(i, cellEntityId, cellEntityIdsArray, placeholderTag): cellPointIds = vtk.vtkIdList() self.Mesh.GetCellPoints(i, cellPointIds) neighborPointIds = vtk.vtkIdList() neighborPointIds.SetNumberOfIds(1) pointNeighborCellIds = vtk.vtkIdList() neighborCellIds = vtk.vtkIdList() for j in range(cellPointIds.GetNumberOfIds()): neighborPointIds.SetId(0, cellPointIds.GetId(j)) self.Mesh.GetCellNeighbors(i, neighborPointIds, pointNeighborCellIds) for k in range(pointNeighborCellIds.GetNumberOfIds()): neighborCellIds.InsertNextId( pointNeighborCellIds.GetId(k)) for j in range(neighborCellIds.GetNumberOfIds()): cellId = neighborCellIds.GetId(j) neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId) neighborCellType = self.Mesh.GetCellType(cellId) if neighborCellType not in [ vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD ]: continue if neighborCellEntityId != placeholderTag: continue cellEntityIdsArray.SetTuple1(cellId, cellEntityId) VisitNeighbors(cellId, cellEntityId, cellEntityIdsArray, placeholderTag) self.PrintLog("Assembling PVS mesh - 1st layer") appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInputData(boundaryLayer.Mesh) appendFilter.AddInputData(tetgen.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput() # Use placeholderCellEntityId - inlet/outlet for the PVS-1 if not self.BoundaryLayerOnCaps: cellEntityIdsArray = self.Mesh.GetCellData().GetArray( self.CellEntityIdsArrayName) for i in range(self.Mesh.GetNumberOfCells()): cellEntityId = cellEntityIdsArray.GetTuple1(i) cellType = self.Mesh.GetCellType(i) if cellType not in [ vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD ]: continue if cellEntityId in [ 0, 1, placeholderCellEntityId, self.Vessel_wall ]: continue VisitNeighbors( i, cellEntityId + self.PVS_inlet_outlet - self.Vessel_inlet_outlet, cellEntityIdsArray, placeholderCellEntityId) appendFilter.Update() self.Mesh = appendFilter.GetOutput() self.PrintLog("Assembling PVS mesh - 2nd layer") appendFilter2 = vtkvmtk.vtkvmtkAppendFilter() appendFilter2.AddInputData(appendFilter.GetOutput()) appendFilter2.AddInputData(boundaryLayer2.Mesh) appendFilter2.Update() self.Mesh = appendFilter2.GetOutput() # Use placeholderCellEntityId2 - inlet/outlet for the PVS-2 if not self.BoundaryLayerOnCaps: cellEntityIdsArray = self.Mesh.GetCellData().GetArray( self.CellEntityIdsArrayName) for i in range(self.Mesh.GetNumberOfCells()): cellEntityId = cellEntityIdsArray.GetTuple1(i) cellType = self.Mesh.GetCellType(i) if cellType not in [ vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD ]: continue if cellEntityId in [ 0, 1, placeholderCellEntityId2, self.Vessel_wall ]: continue VisitNeighbors(i, cellEntityId, cellEntityIdsArray, placeholderCellEntityId2) self.PrintLog("Assembling final mesh") appendFilter2.Update() self.Mesh = appendFilter2.GetOutput() else: self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInputData(remeshedSurface) sizingFunction.SetSizingFunctionArrayName( self.SizingFunctionArrayName) sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor) sizingFunction.Update() self.PrintLog("Converting surface to mesh") surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh() surfaceToMesh.Surface = sizingFunction.GetOutput() surfaceToMesh.Execute() self.PrintLog("Generating volume mesh") tetgen = vmtkscripts.vmtkTetGen() tetgen.Mesh = surfaceToMesh.Mesh tetgen.GenerateCaps = 0 tetgen.UseSizingFunction = 1 tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName tetgen.Order = 1 tetgen.Quality = 1 tetgen.PLC = 1 tetgen.NoBoundarySplit = 1 tetgen.RemoveSliver = 1 tetgen.OutputSurfaceElements = 1 tetgen.OutputVolumeElements = 1 tetgen.Execute() self.Mesh = tetgen.Mesh if self.Mesh.GetNumberOfCells( ) == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0: self.PrintLog( 'An error occurred during tetrahedralization. Will only output surface mesh.' ) self.Mesh = surfaceToMesh.Mesh if self.Tetrahedralize: tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter() tetrahedralize.SetInputData(self.Mesh) tetrahedralize.Update() self.Mesh = tetrahedralize.GetOutput() self.RemeshedSurface = remeshedSurface