4141 isAttributeGlobal ,
4242 getVtkArrayTypeInObject ,
4343 getVtkArrayTypeInMultiBlock ,
44+ getNumberOfComponentsMultiBlock ,
4445)
4546from geos .mesh .utils .multiblockHelpers import (
4647 getBlockElementIndexesFlatten ,
@@ -61,18 +62,18 @@ def fillPartialAttributes(
6162 multiBlockDataSet : Union [ vtkMultiBlockDataSet , vtkCompositeDataSet , vtkDataObject ],
6263 attributeName : str ,
6364 onPoints : bool = False ,
64- value : Any = np . nan ,
65+ listValues : Union [ list [ Any ], None ] = None ,
6566 logger : Union [ Logger , None ] = None ,
6667) -> bool :
67- """Fill input partial attribute of multiBlockDataSet with the same value for all the components .
68+ """Fill input partial attribute of multiBlockDataSet with a constant value per component .
6869
6970 Args:
7071 multiBlockDataSet (vtkMultiBlockDataSet | vtkCompositeDataSet | vtkDataObject): MultiBlockDataSet where to fill the attribute.
7172 attributeName (str): Attribute name.
7273 onPoints (bool, optional): True if attributes are on points, False if they are on cells.
7374 Defaults to False.
74- value ( Any, optional): Filling value. It is recommended to use numpy scalar type for the values .
75- Defaults to:
75+ listValues (list[ Any] , optional): List of filling value for each component .
76+ Defaults to None, the filling value is for all components :
7677 -1 for int VTK arrays.
7778 0 for uint VTK arrays.
7879 nan for float VTK arrays.
@@ -98,40 +99,53 @@ def fillPartialAttributes(
9899
99100 # Get information of the attribute to fill.
100101 vtkDataType : int = getVtkArrayTypeInMultiBlock ( multiBlockDataSet , attributeName , onPoints )
101- infoAttributes : dict [ str , int ] = getAttributesWithNumberOfComponents ( multiBlockDataSet , onPoints )
102- nbComponents : int = infoAttributes [ attributeName ]
102+ nbComponents : int = getNumberOfComponentsMultiBlock ( multiBlockDataSet , attributeName , onPoints )
103103 componentNames : tuple [ str , ...] = ()
104104 if nbComponents > 1 :
105105 componentNames = getComponentNames ( multiBlockDataSet , attributeName , onPoints )
106106
107+ typeMapping : dict [ int , type ] = vnp .get_vtk_to_numpy_typemap ()
108+ valueType : type = typeMapping [ vtkDataType ]
107109 # Set the default value depending of the type of the attribute to fill
108- if np . isnan ( value ) :
109- typeMapping : dict [ int , type ] = vnp . get_vtk_to_numpy_typemap ()
110- valueType : type = typeMapping [ vtkDataType ]
110+ if listValues is None :
111+ defaultValue : Any
112+ logger . warning ( f"The attribute { attributeName } is filled with the default value for each component." )
111113 # Default value for float types is nan.
112114 if vtkDataType in ( VTK_FLOAT , VTK_DOUBLE ):
113- value = valueType ( value )
115+ defaultValue = valueType ( np . nan )
114116 logger .warning (
115- f"{ attributeName } vtk data type is { vtkDataType } corresponding to { value .dtype } numpy type, default value is automatically set to nan."
117+ f"{ attributeName } vtk data type is { vtkDataType } corresponding to { defaultValue .dtype } numpy type, default value is automatically set to nan."
116118 )
117119 # Default value for int types is -1.
118120 elif vtkDataType in ( VTK_CHAR , VTK_SIGNED_CHAR , VTK_SHORT , VTK_LONG , VTK_INT , VTK_LONG_LONG , VTK_ID_TYPE ):
119- value = valueType ( - 1 )
121+ defaultValue = valueType ( - 1 )
120122 logger .warning (
121- f"{ attributeName } vtk data type is { vtkDataType } corresponding to { value .dtype } numpy type, default value is automatically set to -1."
123+ f"{ attributeName } vtk data type is { vtkDataType } corresponding to { defaultValue .dtype } numpy type, default value is automatically set to -1."
122124 )
123125 # Default value for uint types is 0.
124126 elif vtkDataType in ( VTK_BIT , VTK_UNSIGNED_CHAR , VTK_UNSIGNED_SHORT , VTK_UNSIGNED_LONG , VTK_UNSIGNED_INT ,
125127 VTK_UNSIGNED_LONG_LONG ):
126- value = valueType ( 0 )
128+ defaultValue = valueType ( 0 )
127129 logger .warning (
128- f"{ attributeName } vtk data type is { vtkDataType } corresponding to { value .dtype } numpy type, default value is automatically set to 0."
130+ f"{ attributeName } vtk data type is { vtkDataType } corresponding to { defaultValue .dtype } numpy type, default value is automatically set to 0."
129131 )
130132 else :
131133 logger .error ( f"The type of the attribute { attributeName } is not compatible with the function." )
132134 return False
133135
134- values : list [ Any ] = [ value for _ in range ( nbComponents ) ]
136+ listValues = [ defaultValue ] * nbComponents
137+
138+ else :
139+ if len ( listValues ) != nbComponents :
140+ return False
141+
142+ for idValue in range ( nbComponents ):
143+ value : Any = listValues [ idValue ]
144+ if type ( value ) is not valueType :
145+ listValues [ idValue ] = valueType ( listValues [ idValue ] )
146+ logger .warning (
147+ f"The filling value { value } for the attribute { attributeName } has not the correct type, it is convert to the numpy scalar type { valueType ().dtype } ."
148+ )
135149
136150 # Parse the multiBlockDataSet to create and fill the attribute on blocks where it is not.
137151 iterator : vtkDataObjectTreeIterator = vtkDataObjectTreeIterator ()
@@ -141,7 +155,7 @@ def fillPartialAttributes(
141155 while iterator .GetCurrentDataObject () is not None :
142156 dataSet : vtkDataSet = vtkDataSet .SafeDownCast ( iterator .GetCurrentDataObject () )
143157 if not isAttributeInObjectDataSet ( dataSet , attributeName , onPoints ) and \
144- not createConstantAttributeDataSet ( dataSet , values , attributeName , componentNames , onPoints , vtkDataType , logger ):
158+ not createConstantAttributeDataSet ( dataSet , listValues , attributeName , componentNames , onPoints , vtkDataType , logger ):
145159 return False
146160
147161 iterator .GoToNextItem ()
@@ -172,7 +186,7 @@ def fillAllPartialAttributes(
172186 infoAttributes : dict [ str , int ] = getAttributesWithNumberOfComponents ( multiBlockDataSet , onPoints )
173187 for attributeName in infoAttributes :
174188 if not isAttributeGlobal ( multiBlockDataSet , attributeName , onPoints ) and \
175- not fillPartialAttributes ( multiBlockDataSet , attributeName , onPoints , logger = logger ):
189+ not fillPartialAttributes ( multiBlockDataSet , attributeName , onPoints = onPoints , logger = logger ):
176190 return False
177191
178192 return True
@@ -384,7 +398,7 @@ def createConstantAttributeDataSet(
384398 if valueType in ( int , float ):
385399 npType : type = type ( np .array ( listValues )[ 0 ] )
386400 logger .warning (
387- f"During the creation of the constant attribute { attributeName } , values will be converted from { valueType } to { npType } ."
401+ f"During the creation of the constant attribute { attributeName } , values have been converted from { valueType } to { npType } ."
388402 )
389403 logger .warning ( "To avoid any issue with the conversion, please use directly numpy scalar type for the values" )
390404 valueType = npType
0 commit comments