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 vmtkmeshtosurface(mesh, cleanoutput=1): """Convert a mesh to a surface by throwing out volume elements and (optionally) the relative points Args: mesh: Volumetric mesh. cleanoutput (bool): Remove unused points. Returns: vtkPolyData object. """ extractor = vmtkscripts.vmtkMeshToSurface() extractor.Mesh = mesh extractor.CleanOutput = cleanoutput extractor.Execute() return extractor.Surface
def vmtkmeshtosurface(mesh, cleanoutput=1): """Convert a mesh to a surface by throwing out volume elements and (optionally) the relative points Args: mesh: Volumetric mesh. cleanoutput (bool): Remove unused points. Returns: vtkPolyData object. """ extractor = vmtkscripts.vmtkMeshToSurface() extractor.Mesh = mesh extractor.CleanOutput = cleanoutput extractor.Execute() return extractor.Surface
def Execute(args): print("clip surface") mesh_reader = vmtkscripts.vmtkMeshReader() mesh_reader.InputFileName = args.mesh_file mesh_reader.Execute() mesh2surf = vmtkscripts.vmtkMeshToSurface() mesh2surf.Mesh = mesh_reader.Mesh mesh2surf.CleanOutput = 0 mesh2surf.Execute() scale_cfd = vmtkscripts.vmtkSurfaceScaling() scale_cfd.ScaleFactor = args.scale # meters to mm scale_cfd.Surface = mesh2surf.Surface scale_cfd.Execute() surface = vtk.vtkPolyData() surface.DeepCopy(scale_cfd.Surface) reader_trim = vmtkscripts.vmtkSurfaceReader() reader_trim.InputFileName = args.polydata_trim reader_trim.Execute() br_trim = reader_trim.Surface reader_ext = vmtkscripts.vmtkSurfaceReader() reader_ext.InputFileName = args.polydata_ext reader_ext.Execute() br_ext = reader_ext.Surface # have to make sure that they both have the same number of GetNumberOfPoints assert br_trim.GetNumberOfPoints() == br_ext.GetNumberOfPoints() locator = vtk.vtkPointLocator() locator.SetDataSet(br_trim) locator.BuildLocator() point_ext = [0.0, 0.0, 0.0] pt_cross = [0.0, 0.0, 0.0] pt_dot = 0.0 count = 0 for trim_id in range(br_ext.GetNumberOfPoints()): # get extension point point_ext = br_ext.GetPoint(trim_id) #closest trim point point_trim_id = locator.FindClosestPoint(point_ext) point_trim = br_trim.GetPoint(point_trim_id) # check that the points are close to the same direction pt_trim_normal = br_trim.GetPointData().GetArray( "BoundaryNormals").GetTuple(point_trim_id) pt_ext_normal = br_ext.GetPointData().GetArray( "BoundaryNormals").GetTuple(trim_id) #print(pt_trim_normal, pt_ext_normal) pt_dot = vtk.vtkMath.Dot(pt_trim_normal, pt_ext_normal) #vtk.vtkMath.Cross(pt_trim_normal, pt_ext_normal, pt_cross) #print(pt_dot, vtk.vtkMath.Norm(pt_cross))#, pt_cross) if (pt_dot < 0.95): print("help the vectors aren't colinear") assert pt_dot > .95 v = np.array(point_ext) - np.array(point_trim) #pt1 - pt2 v_mag = np.linalg.norm(v) n = v / v_mag # print("should be 1.0", np.linalg.norm(n), n) b1, b2 = hughes_moeller(n) #orthogonal basis #Get maximum radius box_radius = br_ext.GetPointData().GetArray("BoundaryRadius").GetTuple( trim_id) box_radius_trim = br_trim.GetPointData().GetArray( "BoundaryRadius").GetTuple(point_trim_id) #print(box_radius_trim, box_radius) extra_room = args.margin extra_z = 0.0 r_max = extra_room * max([box_radius[0], box_radius_trim[0] ]) # max radius z_max = extra_room * v_mag #create transformation matrix R = np.zeros((4, 4), dtype=np.float64) R[:3, 0] = b1 #x R[:3, 1] = b2 #y R[:3, 2] = n #z R[:3, 3] = np.array(point_trim) # the beginning of the clip R[3, 3] = 1.0 trans_matrix = vtk.vtkTransform() trans_inverse = vtk.vtkTransform() trans_matrix.SetMatrix(list(R.ravel())) #print(trans_matrix.GetMatrix()) trans_inverse.DeepCopy(trans_matrix) trans_inverse.Inverse() # point to define bounds dims_min = [-r_max, -r_max, -extra_z * z_max] dims_max = [r_max, r_max, z_max] planes = vtk.vtkBox() planes.SetBounds(dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) planes.SetTransform(trans_inverse) clipper = vtk.vtkTableBasedClipDataSet() clipper.SetInputData(surface) clipper.SetClipFunction(planes) clipper.InsideOutOff() #clipper.SetMergeTolerance(1.0E-6) clipper.Update() #print(clipper.GetMergeTolerance()) surface = clipper.GetOutput() #test = vtk.vtkCubeSource() #test.SetBounds (dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) #trans_cube = vtk.vtkTransformPolyDataFilter() #trans_cube.SetInputConnection(test.GetOutputPort()) #trans_cube.SetTransform(trans_matrix) #trans_cube.Update() #writer2 = vmtkscripts.vmtkSurfaceWriter() #writer2.OutputFileName = os.path.join(os.path.split(args.out_file)[0], "test_clip_box_{0}.vtp".format(count)) #writer2.Input = trans_cube.GetOutput() #writer2.Execute() count += 1 geom = vtk.vtkGeometryFilter() geom.SetInputData(surface) geom.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = geom.GetOutput() writer.Execute()
def Execute(args): print("get average along line probes") cell_type = "point" if (cell_type == "cell"): vtk_process = vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS vtk_data_type = vtk.vtkDataObject.CELL else: vtk_process = vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS vtk_data_type = vtk.vtkDataObject.POINT reader = vmtkscripts.vmtkMeshReader() reader.InputFileName = args.mesh_file reader.Execute() mesh = reader.Mesh pass_filt = vtk.vtkPassArrays() pass_filt.SetInputData(mesh) pass_filt.AddArray(vtk_data_type, "velocity") pass_filt.Update() surf = vmtkscripts.vmtkMeshToSurface() surf.Mesh = pass_filt.GetOutput() surf.Execute() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = surf.Surface #accept defaults normals.Execute() calc1 = vtk.vtkArrayCalculator() calc1.SetFunction( "velocity_X*-Normals_X+velocity_Y*-Normals_Y+velocity_Z*-Normals_Z") calc1.AddScalarVariable("velocity_X", "velocity_X", 0) calc1.AddScalarVariable("velocity_Y", "velocity_Y", 0) calc1.AddScalarVariable("velocity_Z", "velocity_Z", 0) calc1.SetResultArrayName("vdotn") calc1.SetInputData(normals.Surface) if (cell_type == "cell"): calc1.SetAttributeModeToUseCellData() else: calc1.SetAttributeModeToUsePointData() calc1.SetResultArrayType(vtk.VTK_DOUBLE) integrate_attrs = vtk.vtkIntegrateAttributes() integrate_attrs.SetInputConnection(calc1.GetOutputPort()) integrate_attrs.UpdateData() area = integrate_attrs.GetCellData().GetArray(0).GetValue(0) D = 2.0 * np.sqrt(area / np.pi) calc2 = vtk.vtkArrayCalculator() calc2.SetFunction("vdotn*10**6*60") calc2.AddScalarVariable("vdotn", "vdotn", 0) calc2.SetResultArrayName("Q") calc2.SetInputConnection(integrate_attrs.GetOutputPort()) if (cell_type == "cell"): calc2.SetAttributeModeToUseCellData() else: calc2.SetAttributeModeToUsePointData() calc2.SetResultArrayType(vtk.VTK_DOUBLE) calc2.UpdateData() calc3 = vtk.vtkArrayCalculator() calc3.SetFunction("vdotn/{0}*1050.0/0.0035*{1}".format(area, D)) calc3.AddScalarVariable("vdotn", "vdotn", 0) calc3.SetResultArrayName("Re") calc3.SetInputConnection(integrate_attrs.GetOutputPort()) if (cell_type == "cell"): calc3.SetAttributeModeToUseCellData() else: calc3.SetAttributeModeToUsePointData() calc3.SetResultArrayType(vtk.VTK_DOUBLE) calc3.UpdateData() over_time = vtk.vtkExtractDataArraysOverTime() over_time.SetInputConnection(calc3.GetOutputPort()) if (cell_type == "cell"): over_time.SetFieldAssociation(vtk_data_type) else: over_time.SetFieldAssociation(vtk_data_type) over_time.UpdateData() writer = vtk.vtkDelimitedTextWriter() writer.SetInputConnection(over_time.GetOutputPort()) writer.SetFileName(args.file_out) writer.Write()
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.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