def CreateSurfaceCells(self, inMesh): #Remove the surface cells from the mesh cellDimFilter = vtkvmtkcontrib.vtkvmtkCellDimensionFilter() cellDimFilter.SetInput(inMesh) cellDimFilter.ThresholdByUpper(3) cellDimFilter.Update() volumetricMesh = cellDimFilter.GetOutput() #Get new surface cells geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInput(cellDimFilter.GetOutput()) 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.SetInput(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 = vtkvmtkcontrib.vtkvmtkSurfaceProjectCellArray() projector.SetInput(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 = vtkvmtkcontrib.vtkvmtkCellDimensionFilter() cellDimFilter.SetInput(inMesh) cellDimFilter.ThresholdByUpper(3) cellDimFilter.Update() volumetricMesh = cellDimFilter.GetOutput() #Get new surface cells geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInput(cellDimFilter.GetOutput()) 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.SetInput(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 = vtkvmtkcontrib.vtkvmtkSurfaceProjectCellArray() projector.SetInput(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.') 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.') 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): 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): if self.Surface == None: self.PrintError('Error: No input surface.') wallEntityOffset = 1 if self.SkipCapping: self.PrintLog("Not capping surface") surface = self.Surface else: self.PrintLog("Capping surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = self.Surface capper.Interactive = 0 capper.Method = self.CappingMethod capper.TriangleOutput = 0 capper.CellEntityIdOffset = 1 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.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") 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.SubLayerRatio = 0.5 boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength boundaryLayer.Execute() cellEntityIdsArray = vtk.vtkIntArray() cellEntityIdsArray.SetName(self.CellEntityIdsArrayName) cellEntityIdsArray.SetNumberOfTuples( boundaryLayer.Mesh.GetNumberOfCells()) cellEntityIdsArray.FillComponent(0, 0.0) boundaryLayer.Mesh.GetCellData().AddArray(cellEntityIdsArray) innerCellEntityIdsArray = vtk.vtkIntArray() innerCellEntityIdsArray.SetName(self.CellEntityIdsArrayName) innerCellEntityIdsArray.SetNumberOfTuples( boundaryLayer.InnerSurfaceMesh.GetNumberOfCells()) innerCellEntityIdsArray.FillComponent(0, 0.0) boundaryLayer.InnerSurfaceMesh.GetCellData().AddArray( cellEntityIdsArray) meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh meshToSurface.Execute() self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInput(meshToSurface.Surface) 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() 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.' ) appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(surfaceToMesh.Mesh) appendFilter.AddInput(boundaryLayer.Mesh) appendFilter.AddInput(tetgen.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput() else: self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInput(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 = vtk.vtkDataSetTriangleFilter() tetrahedralize.SetInput(self.Mesh) tetrahedralize.Update() self.Mesh = tetrahedralize.GetOutput() self.RemeshedSurface = remeshedSurface
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 = vmtkcontribscripts.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) 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() if self.Mesh.GetSource(): self.Mesh.GetSource().UnRegisterAllOutputs()
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') self.PrintLog("Capping surface") capper = vmtkscripts.vmtkSurfaceCapper() capper.Surface = self.Surface capper.Interactive = 0 capper.Method = 'simple' capper.TriangleOutput = 0 capper.CellEntityIdOffset = 1 capper.Execute() self.PrintLog("Remeshing surface") remeshing = vmtkscripts.vmtkSurfaceRemeshing() remeshing.Surface = capper.Surface remeshing.CellEntityIdsArrayName = capper.CellEntityIdsArrayName remeshing.TargetEdgeLength = self.TargetEdgeLength remeshing.MaxEdgeLength = self.MaxEdgeLength remeshing.MinEdgeLength = self.MinEdgeLength remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName remeshing.ElementSizeMode = self.ElementSizeMode remeshing.Execute() if self.BoundaryLayer: projection = vmtkscripts.vmtkSurfaceProjection() projection.Surface = remeshing.Surface projection.ReferenceSurface = capper.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") 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.SubLayerRatio = 0.5 boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength boundaryLayer.Execute() cellEntityIdsArray = vtk.vtkIntArray() cellEntityIdsArray.SetName(self.CellEntityIdsArrayName) cellEntityIdsArray.SetNumberOfTuples(boundaryLayer.Mesh.GetNumberOfCells()) cellEntityIdsArray.FillComponent(0,0.0) boundaryLayer.Mesh.GetCellData().AddArray(cellEntityIdsArray) innerCellEntityIdsArray = vtk.vtkIntArray() innerCellEntityIdsArray.SetName(self.CellEntityIdsArrayName) innerCellEntityIdsArray.SetNumberOfTuples(boundaryLayer.InnerSurfaceMesh.GetNumberOfCells()) innerCellEntityIdsArray.FillComponent(0,0.0) boundaryLayer.InnerSurfaceMesh.GetCellData().AddArray(cellEntityIdsArray) meshToSurface = vmtkscripts.vmtkMeshToSurface() meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh meshToSurface.Execute() self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInput(meshToSurface.Surface) 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() 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.') appendFilter = vtkvmtk.vtkvmtkAppendFilter() appendFilter.AddInput(surfaceToMesh.Mesh) appendFilter.AddInput(boundaryLayer.Mesh) appendFilter.AddInput(tetgen.Mesh) appendFilter.Update() self.Mesh = appendFilter.GetOutput() else: self.PrintLog("Computing sizing function") sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction() sizingFunction.SetInput(remeshing.Surface) 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 = vtk.vtkDataSetTriangleFilter() tetrahedralize.SetInput(self.Mesh) tetrahedralize.Update() self.Mesh = tetrahedralize.GetOutput()
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 = vmtkcontribscripts.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) 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() if self.Mesh.GetSource(): self.Mesh.GetSource().UnRegisterAllOutputs()