1717from geos .mesh .model .CellTypeCounts import CellTypeCounts
1818
1919__doc__ = """
20- SplitMesh module is a vtk filter that split cells of a mesh composed of Tetrahedra, pyramids, and hexahedra.
20+ SplitMesh module is a vtk filter that splits cells of a mesh composed of tetrahedra, pyramids, hexahedra, triangles, and quads.
21+
22+ Warning: Current implementation only supports meshes composed of either polygons or polyhedra, not both together.
2123
2224Filter input and output types are vtkUnstructuredGrid.
2325
@@ -95,21 +97,23 @@ def applyFilter( self: Self ) -> None:
9597 """Apply the filter SplitMesh."""
9698 self .logger .info ( f"Applying filter { self .logger .name } ." )
9799 try :
100+ # Count the number of cells before splitting. Then we will be able to know how many new cells and points
101+ # to allocate because each cell type is splitted in a known number of new cells and points.
98102 nbCells : int = self .inputMesh .GetNumberOfCells ()
99103 counts : CellTypeCounts = self ._getCellCounts ()
100- nbTet : int = counts .getTypeCount ( VTK_TETRA )
101- nbPyr : int = counts .getTypeCount ( VTK_PYRAMID )
102- nbHex : int = counts .getTypeCount ( VTK_HEXAHEDRON )
103- nbTriangles : int = counts .getTypeCount ( VTK_TRIANGLE )
104- nbQuad : int = counts .getTypeCount ( VTK_QUAD )
104+ nbTet : int = counts .getTypeCount ( VTK_TETRA ) # will divide into 8 tets
105+ nbPyr : int = counts .getTypeCount ( VTK_PYRAMID ) # will divide into 6 pyramids and 4 tets so 10 new cells
106+ nbHex : int = counts .getTypeCount ( VTK_HEXAHEDRON ) # will divide into 8 hexes
107+ nbTriangles : int = counts .getTypeCount ( VTK_TRIANGLE ) # will divide into 4 triangles
108+ nbQuad : int = counts .getTypeCount ( VTK_QUAD ) # will divide into 4 quads
105109 nbPolygon : int = counts .getTypeCount ( VTK_POLYGON )
106110 nbPolyhedra : int = counts .getTypeCount ( VTK_POLYHEDRON )
107111 assert counts .getTypeCount ( VTK_WEDGE ) == 0 , "Input mesh contains wedges that are not currently supported."
108- assert nbPolyhedra * nbPolygon == 0 , ( "Input mesh is composed of both polygons and polyhedra,"
109- " but it must contains only one of the two." )
112+ # Current implementation only supports meshes composed of either polygons or polyhedra
113+ assert nbPolyhedra * nbPolygon == 0 , "Input mesh is composed of both polygons and polyhedra, but it must contains only one of the two."
110114 nbNewPoints : int = 0
111115 nbNewPoints = nbHex * 19 + nbTet * 6 + nbPyr * 9 if nbPolyhedra > 0 else nbTriangles * 3 + nbQuad * 5
112- nbNewCells : int = nbHex * 8 + nbTet * 8 + nbPyr * 10 * nbTriangles * 4 + nbQuad * 4
116+ nbNewCells : int = nbHex * 8 + nbTet * 8 + nbPyr * 10 + nbTriangles * 4 + nbQuad * 4
113117
114118 self .points = vtkPoints ()
115119 self .points .DeepCopy ( self .inputMesh .GetPoints () )
@@ -121,21 +125,22 @@ def applyFilter( self: Self ) -> None:
121125 self .originalId .SetName ( "OriginalID" )
122126 self .originalId .Allocate ( nbNewCells )
123127 self .cellTypes = []
128+ # Define cell type to splitting method mapping
129+ splitMethods = {
130+ VTK_HEXAHEDRON : self ._splitHexahedron ,
131+ VTK_TETRA : self ._splitTetrahedron ,
132+ VTK_PYRAMID : self ._splitPyramid ,
133+ VTK_TRIANGLE : self ._splitTriangle ,
134+ VTK_QUAD : self ._splitQuad ,
135+ }
124136 for c in range ( nbCells ):
125137 cell : vtkCell = self .inputMesh .GetCell ( c )
126138 cellType : int = cell .GetCellType ()
127- if cellType == VTK_HEXAHEDRON :
128- self ._splitHexahedron ( cell , c )
129- elif cellType == VTK_TETRA :
130- self ._splitTetrahedron ( cell , c )
131- elif cellType == VTK_PYRAMID :
132- self ._splitPyramid ( cell , c )
133- elif cellType == VTK_TRIANGLE :
134- self ._splitTriangle ( cell , c )
135- elif cellType == VTK_QUAD :
136- self ._splitQuad ( cell , c )
139+ splitMethod = splitMethods .get ( cellType )
140+ if splitMethod is not None :
141+ splitMethod ( cell , c )
137142 else :
138- raise TypeError ( f"Cell type { vtkCellTypes .GetClassNameFromTypeId (cellType ) } is not supported." )
143+ raise TypeError ( f"Cell type { vtkCellTypes .GetClassNameFromTypeId ( cellType ) } is not supported." )
139144 # add points and cells
140145 self .outputMesh .SetPoints ( self .points )
141146 self .outputMesh .SetCells ( self .cellTypes , self .cells )
@@ -233,7 +238,7 @@ def _splitPyramid( self: Self, cell: vtkCell, index: int ) -> None:
233238 r"""Split a pyramid.
234239
235240 Let's suppose an input pyramid composed of nodes (0, 1, 2, 3, 4),
236- the cell is splitted in 8 pyramids using edge centers.
241+ the cell is split into 6 pyramids and 4 tetrahedra using edge centers.
237242
238243 4
239244 ,/|\
@@ -282,7 +287,8 @@ def _splitPyramid( self: Self, cell: vtkCell, index: int ) -> None:
282287 self .cells .InsertNextCell ( 4 , [ pt12 , pt7 , pt6 , pt13 ] )
283288 for _ in range ( 10 ):
284289 self .originalId .InsertNextValue ( index )
285- self .cellTypes .extend ( [ VTK_PYRAMID ] * 8 )
290+ self .cellTypes .extend ( [ VTK_PYRAMID ] * 6 )
291+ self .cellTypes .extend ( [ VTK_TETRA ] * 4 )
286292
287293 def _splitHexahedron ( self : Self , cell : vtkCell , index : int ) -> None :
288294 r"""Split a hexahedron.
@@ -350,7 +356,7 @@ def _splitTriangle( self: Self, cell: vtkCell, index: int ) -> None:
350356 r"""Split a triangle.
351357
352358 Let's suppose an input triangle composed of nodes (0, 1, 2),
353- the cell is splitted in 3 triangles using edge centers.
359+ the cell is split into 4 triangles using edge centers.
354360
355361 2
356362 |\
0 commit comments