|
1 | 1 | # SPDX-License-Identifier: Apache-2.0 |
2 | 2 | # SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. |
3 | 3 | # SPDX-FileContributor: Martin Lemay, Paloma Martinez |
4 | | -import numpy as np |
5 | 4 | import logging |
| 5 | +import numpy as np |
6 | 6 | import numpy.typing as npt |
7 | | -from typing import Iterator, List, Sequence, Any, Union, Tuple |
| 7 | +from typing import ( Iterator, List, Sequence, Any, Union, Tuple ) |
| 8 | + |
8 | 9 | from vtkmodules.util.numpy_support import ( numpy_to_vtk, vtk_to_numpy ) |
9 | 10 | from vtkmodules.vtkCommonCore import vtkIdList, vtkPoints, reference, vtkDataArray, vtkLogger, vtkFloatArray |
10 | | -from vtkmodules.vtkCommonDataModel import ( |
11 | | - vtkUnstructuredGrid, |
12 | | - vtkMultiBlockDataSet, |
13 | | - vtkPolyData, |
14 | | - vtkDataSet, |
15 | | - vtkDataObject, |
16 | | - vtkPlane, |
17 | | - vtkCellTypes, |
18 | | - vtkIncrementalOctreePointLocator, |
19 | | -) |
| 11 | +from vtkmodules.vtkCommonDataModel import ( vtkUnstructuredGrid, vtkMultiBlockDataSet, vtkPolyData, vtkDataSet, |
| 12 | + vtkDataObject, vtkPlane, vtkCellTypes, vtkIncrementalOctreePointLocator, |
| 13 | + VTK_TRIANGLE ) |
20 | 14 | from vtkmodules.vtkFiltersCore import ( vtk3DLinearGridPlaneCutter, vtkPolyDataNormals, vtkPolyDataTangents ) |
21 | 15 | from vtkmodules.vtkFiltersTexture import vtkTextureMapToPlane |
| 16 | +from vtkmodules.vtkFiltersGeometry import vtkDataSetSurfaceFilter |
| 17 | +from vtkmodules.vtkFiltersGeneral import vtkDataSetTriangleFilter |
22 | 18 |
|
23 | 19 | from geos.mesh.utils.multiblockHelpers import ( getBlockElementIndexesFlatten, getBlockFromFlatIndex ) |
24 | 20 |
|
25 | | -from geos.utils.algebraFunctions import ( |
26 | | - getAttributeMatrixFromVector, |
27 | | - getAttributeVectorFromMatrix, |
28 | | -) |
| 21 | +from geos.utils.algebraFunctions import ( getAttributeMatrixFromVector, getAttributeVectorFromMatrix ) |
29 | 22 | from geos.utils.geometryFunctions import ( getChangeOfBasisMatrix, CANONICAL_BASIS_3D ) |
30 | 23 | from geos.utils.Logger import ( getLogger, Logger, VTKCaptureLog, RegexExceptionFilter ) |
31 | 24 | from geos.utils.Errors import VTKError |
|
40 | 33 | """ |
41 | 34 |
|
42 | 35 |
|
| 36 | +def isTriangulate( dataSet: vtkUnstructuredGrid ) -> bool: |
| 37 | + """Check if the mesh is fully triangulated. |
| 38 | +
|
| 39 | + Args: |
| 40 | + dataSet (vtkUnstructuredGrid): The mesh to check |
| 41 | +
|
| 42 | + Returns: |
| 43 | + bool: True if the mesh is triangulate only, False otherwise. |
| 44 | + """ |
| 45 | + cellTypes: vtkCellTypes = vtkCellTypes() |
| 46 | + dataSet.GetCellTypes( cellTypes ) |
| 47 | + |
| 48 | + return all( cellTypes.GetCellType( cell ) == VTK_TRIANGLE for cell in range( cellTypes.GetNumberOfTypes() ) ) |
| 49 | + |
| 50 | + |
| 51 | +def triangulateMesh( |
| 52 | + dataSet: vtkUnstructuredGrid, |
| 53 | + logger: Union[ Logger, None ] = None, |
| 54 | +) -> vtkUnstructuredGrid: |
| 55 | + """Triangulate any type of dataset. |
| 56 | +
|
| 57 | + Args: |
| 58 | + dataSet (vtkUnstructuredGrid): The mesh to triangulate |
| 59 | + logger (Union[Logger, None], optional): A logger to manage the output messages. |
| 60 | + Defaults to None, an internal logger is used. |
| 61 | +
|
| 62 | + Returns: |
| 63 | + vtkUnstructuredGrid: Triangulated mesh |
| 64 | + """ |
| 65 | + if logger is None: |
| 66 | + logger = getLogger( "Triangulate", True ) |
| 67 | + # Creation of a child logger to deal with VTKErrors without polluting parent logger |
| 68 | + vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger", True ) |
| 69 | + vtkErrorLogger.propagate = False |
| 70 | + |
| 71 | + vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR ) |
| 72 | + |
| 73 | + vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error |
| 74 | + vtkErrorLogger.setLevel( logging.DEBUG ) |
| 75 | + |
| 76 | + with VTKCaptureLog() as capturedLog: |
| 77 | + triangulateMeshFilter: vtkDataSetTriangleFilter = vtkDataSetTriangleFilter() |
| 78 | + triangulateMeshFilter.SetInputData( dataSet ) |
| 79 | + triangulateMeshFilter.Update() |
| 80 | + |
| 81 | + capturedLog.seek( 0 ) |
| 82 | + captured = capturedLog.read().decode() |
| 83 | + |
| 84 | + vtkErrorLogger.debug( captured.strip() ) |
| 85 | + |
| 86 | + triangulatedMesh: vtkUnstructuredGrid = triangulateMeshFilter.GetOutput() |
| 87 | + |
| 88 | + if triangulatedMesh.GetCellData() is None: |
| 89 | + raise VTKError( "Something went wrong with VTK triangulation of the mesh." ) |
| 90 | + |
| 91 | + return triangulatedMesh |
| 92 | + |
| 93 | + |
| 94 | +def convertUnstructuredGridToPolyData( |
| 95 | + dataSet: vtkUnstructuredGrid, |
| 96 | + logger: Union[ Logger, None ] = None, |
| 97 | +) -> vtkPolyData: |
| 98 | + """Convert vtkUnstructuredGrid to vtkPolyData. |
| 99 | +
|
| 100 | + ..Warning:: Work only with triangulated mesh |
| 101 | +
|
| 102 | + Args: |
| 103 | + dataSet (vtkUnstructuredGrid): Input mesh block |
| 104 | + logger (Union[Logger, None], optional): A logger to manage the output messages. |
| 105 | + Defaults to None, an internal logger is used. |
| 106 | +
|
| 107 | + Returns: |
| 108 | + vtkPolyData: Extracted surface |
| 109 | + """ |
| 110 | + if logger is None: |
| 111 | + logger = getLogger( "ConvertVtkUnstructuredGridToVtkPolyData.", True ) |
| 112 | + # Creation of a child logger to deal with VTKErrors without polluting parent logger |
| 113 | + vtkErrorLogger: Logger = getLogger( f"{logger.name}.vtkErrorLogger", True ) |
| 114 | + vtkErrorLogger.propagate = False |
| 115 | + |
| 116 | + vtkLogger.SetStderrVerbosity( vtkLogger.VERBOSITY_ERROR ) |
| 117 | + |
| 118 | + vtkErrorLogger.addFilter( RegexExceptionFilter() ) # will raise VTKError if captured VTK Error |
| 119 | + vtkErrorLogger.setLevel( logging.DEBUG ) |
| 120 | + |
| 121 | + with VTKCaptureLog() as capturedLog: |
| 122 | + extractSurfaceFilter: vtkDataSetSurfaceFilter = vtkDataSetSurfaceFilter() |
| 123 | + extractSurfaceFilter.SetInputData( dataSet ) |
| 124 | + # fast mode should be used for rendering only |
| 125 | + extractSurfaceFilter.FastModeOff() |
| 126 | + # Delegation activated allow to accelerate the processing with unstructured mesh |
| 127 | + # see https://vtk.org/doc/nightly/html/classvtkDataSetSurfaceFilter.html |
| 128 | + extractSurfaceFilter.DelegationOn() |
| 129 | + extractSurfaceFilter.Update() |
| 130 | + |
| 131 | + capturedLog.seek( 0 ) |
| 132 | + captured = capturedLog.read().decode() |
| 133 | + |
| 134 | + vtkErrorLogger.debug( captured.strip() ) |
| 135 | + |
| 136 | + extractedSurface: vtkPolyData = extractSurfaceFilter.GetOutput() |
| 137 | + |
| 138 | + if extractedSurface is None: |
| 139 | + raise VTKError( "Something went wrong with VTK convert vtu to vtp." ) |
| 140 | + |
| 141 | + return extractedSurface |
| 142 | + |
| 143 | + |
43 | 144 | def toVtkIdList( data: List[ int ] ) -> vtkIdList: |
44 | 145 | """Utility function transforming a list of ids into a vtkIdList. |
45 | 146 |
|
|
0 commit comments