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()
Beispiel #2
0
 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()
Beispiel #3
0
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
Beispiel #4
0
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()
Beispiel #8
0
    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()
Beispiel #9
0
    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
Beispiel #11
0
    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