Skip to content

Commit f45f362

Browse files
authored
docs: Add Paraview Proxy examples (#90)
* Add Paraview Proxy examples * linting, formating, typing
1 parent 7bccab6 commit f45f362

File tree

4 files changed

+1733
-0
lines changed

4 files changed

+1733
-0
lines changed

geos-pv/examples/PVproxyInputs.py

Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies.
3+
# SPDX-FileContributor: Martin Lemay
4+
# ruff: noqa: E402 # disable Module level import not at top of file
5+
import sys
6+
import numpy as np
7+
from pathlib import Path
8+
from typing_extensions import Self
9+
10+
# update sys.path to load all GEOS Python Package dependencies
11+
geos_pv_path: Path = Path( __file__ ).parent.parent
12+
sys.path.insert( 0, str( geos_pv_path / "src" ) )
13+
from geos.pv.utils.config import update_paths
14+
15+
update_paths()
16+
17+
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
18+
19+
from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found]
20+
smdomain, smproperty, smproxy, smhint )
21+
from vtkmodules.vtkCommonCore import (
22+
vtkInformation,
23+
vtkInformationVector,
24+
vtkDoubleArray,
25+
)
26+
from vtkmodules.vtkCommonDataModel import (
27+
vtkPointSet,
28+
vtkUnstructuredGrid,
29+
vtkFieldData,
30+
vtkMultiBlockDataSet,
31+
)
32+
33+
__doc__ = """
34+
This file defines multiple Paraview plugins with various configurations.
35+
36+
Examples of Source, Reader and Writer can be found on `Paraview documentation page <https://www.paraview.org/paraview-docs/nightly/python/paraview.util.vtkAlgorithm.html>`_.
37+
38+
Additional examples are here defined:
39+
40+
* PVPreserveInputTypeFilter is an example of a Paraview plugin where output is of same type as input data.
41+
42+
.. Note::
43+
if Input data is a composite data set, the RequestData method is applied to each part of input object.
44+
Results are concatenated to output object. Point data and cell data are added to each block,
45+
a new line per block is added to output Field data or output vtkTable.
46+
47+
* PVCompositeDataSetFilter is an example of a Paraview plugin that treats composite data sets as a single object conversely to PVPreserveInputTypeFilter.
48+
49+
* PVMultipleInputFilter is an example of a Paraview plugin using 2 inputs of different type.
50+
51+
The output is here of same type as input 1.
52+
53+
.. Note:: Inputs are ordered in the reverse order compared to their definition using decorators.
54+
55+
56+
57+
"""
58+
59+
60+
@smproxy.filter( name="PVPreserveInputTypeFilter", label="Preserve Input Type Filter" )
61+
@smhint.xml( """<ShowInMenu category="Filter Examples"/>""" )
62+
@smproperty.input( name="Input", port_index=0, label="Input" )
63+
@smdomain.datatype(
64+
dataTypes=[ "vtkUnstructuredGrid" ],
65+
composite_data_supported=True,
66+
)
67+
class PVPreserveInputTypeFilter( VTKPythonAlgorithmBase ):
68+
69+
def __init__( self: Self ) -> None:
70+
"""Map the properties of a server mesh to a client mesh."""
71+
super().__init__( nInputPorts=1, nOutputPorts=1, outputType="vtkUnstructuredGrid" )
72+
73+
def RequestDataObject(
74+
self: Self,
75+
request: vtkInformation,
76+
inInfoVec: list[ vtkInformationVector ],
77+
outInfoVec: vtkInformationVector,
78+
) -> int:
79+
"""Inherited from VTKPythonAlgorithmBase::RequestDataObject.
80+
81+
Args:
82+
request (vtkInformation): Request
83+
inInfoVec (list[vtkInformationVector]): Input objects
84+
outInfoVec (vtkInformationVector): Output objects
85+
86+
Returns:
87+
int: 1 if calculation successfully ended, 0 otherwise.
88+
"""
89+
print( "RequestDataObject" )
90+
inData1 = self.GetInputData( inInfoVec, 0, 0 )
91+
outData = self.GetOutputData( outInfoVec, 0 )
92+
assert inData1 is not None
93+
if outData is None or ( not outData.IsA( inData1.GetClassName() ) ):
94+
outData = inData1.NewInstance()
95+
outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData )
96+
return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return]
97+
98+
def RequestData(
99+
self: Self,
100+
request: vtkInformation, # noqa: F841
101+
inInfoVec: list[ vtkInformationVector ],
102+
outInfoVec: vtkInformationVector,
103+
) -> int:
104+
"""Inherited from VTKPythonAlgorithmBase::RequestData.
105+
106+
Args:
107+
request (vtkInformation): Request
108+
inInfoVec (list[vtkInformationVector]): Input objects
109+
outInfoVec (vtkInformationVector): Output objects
110+
111+
Returns:
112+
int: 1 if calculation successfully ended, 0 otherwise.
113+
"""
114+
print( "RequestData" )
115+
input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 )
116+
outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 )
117+
118+
assert input is not None, "input 0 server mesh is null."
119+
assert outData is not None, "Output pipeline is null."
120+
121+
# do something...
122+
# for instance copy input and create a Field data in output object
123+
124+
outData.ShallowCopy( input )
125+
126+
# add Field data attribute
127+
nbArrays: int = 3
128+
fieldData: vtkFieldData = outData.GetFieldData()
129+
fieldData.AllocateArrays( nbArrays )
130+
for i in range( nbArrays ):
131+
newArray: vtkDoubleArray = vtkDoubleArray()
132+
newArray.SetName( f"Column{i}" )
133+
newArray.SetNumberOfComponents( 1 )
134+
newArray.SetNumberOfValues( 1 )
135+
val: float = i + np.random.rand( 1 )[ 0 ]
136+
newArray.SetValue( 0, val )
137+
fieldData.AddArray( newArray )
138+
fieldData.Modified()
139+
140+
# add Point attribute
141+
142+
# add Cell attribute
143+
144+
outData.Modified()
145+
return 1
146+
147+
148+
@smproxy.filter( name="PVCompositeDataSetFilter", label="Composite Data Set Filter" )
149+
@smhint.xml( """<ShowInMenu category="Filter Examples"/>""" )
150+
@smproperty.input( name="Input", port_index=0, label="Input" )
151+
@smdomain.datatype(
152+
dataTypes=[ "vtkMultiBlockDataSet" ],
153+
composite_data_supported=True,
154+
)
155+
class PVCompositeDataSetFilter( VTKPythonAlgorithmBase ):
156+
157+
def __init__( self: Self ) -> None:
158+
"""Map the properties of a server mesh to a client mesh."""
159+
super().__init__( nInputPorts=2, nOutputPorts=1, outputType="vtkMultiBlockDataSet" )
160+
161+
def RequestDataObject(
162+
self: Self,
163+
request: vtkInformation,
164+
inInfoVec: list[ vtkInformationVector ],
165+
outInfoVec: vtkInformationVector,
166+
) -> int:
167+
"""Inherited from VTKPythonAlgorithmBase::RequestDataObject.
168+
169+
Args:
170+
request (vtkInformation): Request
171+
inInfoVec (list[vtkInformationVector]): Input objects
172+
outInfoVec (vtkInformationVector): Output objects
173+
174+
Returns:
175+
int: 1 if calculation successfully ended, 0 otherwise.
176+
"""
177+
inData1 = self.GetInputData( inInfoVec, 0, 0 )
178+
outData = self.GetOutputData( outInfoVec, 0 )
179+
assert inData1 is not None
180+
if outData is None or ( not outData.IsA( inData1.GetClassName() ) ):
181+
outData = inData1.NewInstance()
182+
outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData )
183+
return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return]
184+
185+
def RequestData(
186+
self: Self,
187+
request: vtkInformation, # noqa: F841
188+
inInfoVec: list[ vtkInformationVector ],
189+
outInfoVec: vtkInformationVector,
190+
) -> int:
191+
"""Inherited from VTKPythonAlgorithmBase::RequestData.
192+
193+
Args:
194+
request (vtkInformation): Request
195+
inInfoVec (list[vtkInformationVector]): Input objects
196+
outInfoVec (vtkInformationVector): Output objects
197+
198+
Returns:
199+
int: 1 if calculation successfully ended, 0 otherwise.
200+
"""
201+
input: vtkMultiBlockDataSet = self.GetInputData( inInfoVec, 0, 0 )
202+
outData: vtkMultiBlockDataSet = self.GetOutputData( outInfoVec, 0 )
203+
204+
assert input is not None, "input 0 server mesh is null."
205+
assert outData is not None, "Output pipeline is null."
206+
207+
# do something...
208+
# for instance copy input and create a Field data in output object
209+
210+
outData.ShallowCopy( input )
211+
nbArrays: int = 3
212+
fieldData: vtkFieldData = outData.GetFieldData()
213+
fieldData.AllocateArrays( nbArrays )
214+
for i in range( nbArrays ):
215+
newArray: vtkDoubleArray = vtkDoubleArray()
216+
newArray.SetName( f"Column{i}" )
217+
newArray.SetNumberOfComponents( 1 )
218+
newArray.SetNumberOfValues( 1 )
219+
val: float = i + np.random.rand( 1 )[ 0 ]
220+
newArray.SetValue( 0, val )
221+
fieldData.AddArray( newArray )
222+
223+
fieldData.Modified()
224+
outData.Modified()
225+
return 1
226+
227+
228+
@smproxy.filter( name="PVMultiInputFilter", label="Multiple Input Filter" )
229+
@smhint.xml( """<ShowInMenu category="Filter Examples"/>""" )
230+
@smproperty.input( name="Input1", port_index=1, label="Input 1" )
231+
@smdomain.datatype(
232+
dataTypes=[
233+
"vtkPointSet",
234+
],
235+
composite_data_supported=False,
236+
)
237+
@smproperty.input( name="Input0", port_index=0, label="Input 0" )
238+
@smdomain.datatype(
239+
dataTypes=[ "vtkUnstructuredGrid" ],
240+
composite_data_supported=False,
241+
)
242+
class PVMultipleInputFilter( VTKPythonAlgorithmBase ):
243+
244+
def __init__( self: Self ) -> None:
245+
"""Map the properties of a server mesh to a client mesh."""
246+
super().__init__( nInputPorts=2, nOutputPorts=1, outputType="vtkUnstructuredGrid" )
247+
248+
def RequestDataObject(
249+
self: Self,
250+
request: vtkInformation,
251+
inInfoVec: list[ vtkInformationVector ],
252+
outInfoVec: vtkInformationVector,
253+
) -> int:
254+
"""Inherited from VTKPythonAlgorithmBase::RequestDataObject.
255+
256+
Args:
257+
request (vtkInformation): Request
258+
inInfoVec (list[vtkInformationVector]): Input objects
259+
outInfoVec (vtkInformationVector): Output objects
260+
261+
Returns:
262+
int: 1 if calculation successfully ended, 0 otherwise.
263+
"""
264+
# here output data is of same type as input 1
265+
inData1 = self.GetInputData( inInfoVec, 1, 0 )
266+
outData = self.GetOutputData( outInfoVec, 0 )
267+
assert inData1 is not None
268+
if outData is None or ( not outData.IsA( inData1.GetClassName() ) ):
269+
outData = inData1.NewInstance()
270+
outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData )
271+
return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return]
272+
273+
def RequestData(
274+
self: Self,
275+
request: vtkInformation, # noqa: F841
276+
inInfoVec: list[ vtkInformationVector ],
277+
outInfoVec: vtkInformationVector,
278+
) -> int:
279+
"""Inherited from VTKPythonAlgorithmBase::RequestData.
280+
281+
Args:
282+
request (vtkInformation): Request
283+
inInfoVec (list[vtkInformationVector]): Input objects
284+
outInfoVec (vtkInformationVector): Output objects
285+
286+
Returns:
287+
int: 1 if calculation successfully ended, 0 otherwise.
288+
"""
289+
input0: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 )
290+
input1: vtkPointSet = self.GetInputData( inInfoVec, 1, 0 )
291+
outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 )
292+
293+
assert input0 is not None, "input 0 server mesh is null."
294+
assert input1 is not None, "input 1 client mesh is null."
295+
assert outData is not None, "Output pipeline is null."
296+
297+
# do something...
298+
299+
return 1
300+
301+
302+
@smproxy.filter( name="PVMultiOutputFilter", label="Multiple Output Filter" )
303+
@smhint.xml( """
304+
<ShowInMenu category="Filter Examples"/>
305+
<OutputPort index="0" name="Output0"/>
306+
<OutputPort index="1" name="Output1"/>
307+
""" )
308+
@smproperty.input( name="Input", port_index=0, label="Input" )
309+
@smdomain.datatype(
310+
dataTypes=[ "vtkUnstructuredGrid" ],
311+
composite_data_supported=False,
312+
)
313+
class PVMultipleOutputFilter( VTKPythonAlgorithmBase ):
314+
315+
def __init__( self: Self ) -> None:
316+
"""Map the properties of a server mesh to a client mesh."""
317+
super().__init__( nInputPorts=1, nOutputPorts=2, outputType="vtkUnstructuredGrid" )
318+
319+
def RequestDataObject(
320+
self: Self,
321+
request: vtkInformation,
322+
inInfoVec: list[ vtkInformationVector ],
323+
outInfoVec: vtkInformationVector,
324+
) -> int:
325+
"""Inherited from VTKPythonAlgorithmBase::RequestDataObject.
326+
327+
Args:
328+
request (vtkInformation): Request
329+
inInfoVec (list[vtkInformationVector]): Input objects
330+
outInfoVec (vtkInformationVector): Output objects
331+
332+
Returns:
333+
int: 1 if calculation successfully ended, 0 otherwise.
334+
"""
335+
# here output data is of same type as input 1
336+
inData1 = self.GetInputData( inInfoVec, 1, 0 )
337+
outData0 = self.GetOutputData( outInfoVec, 0 )
338+
assert inData1 is not None
339+
if outData0 is None or ( not outData0.IsA( inData1.GetClassName() ) ):
340+
outData0 = inData1.NewInstance()
341+
outInfoVec.GetInformationObject( 0 ).Set( outData0.DATA_OBJECT(), outData0 )
342+
outData1 = self.GetOutputData( outInfoVec, 1 )
343+
if outData1 is None or ( not outData1.IsA( inData1.GetClassName() ) ):
344+
outData1 = inData1.NewInstance()
345+
outInfoVec.GetInformationObject( 1 ).Set( outData1.DATA_OBJECT(), outData1 )
346+
return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return]
347+
348+
def RequestData(
349+
self: Self,
350+
request: vtkInformation, # noqa: F841
351+
inInfoVec: list[ vtkInformationVector ],
352+
outInfoVec: vtkInformationVector,
353+
) -> int:
354+
"""Inherited from VTKPythonAlgorithmBase::RequestData.
355+
356+
Args:
357+
request (vtkInformation): Request
358+
inInfoVec (list[vtkInformationVector]): Input objects
359+
outInfoVec (vtkInformationVector): Output objects
360+
361+
Returns:
362+
int: 1 if calculation successfully ended, 0 otherwise.
363+
"""
364+
input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 )
365+
outData0: vtkUnstructuredGrid = self.GetOutputData( outInfoVec, 0 )
366+
outData1: vtkUnstructuredGrid = self.GetOutputData( outInfoVec, 1 )
367+
368+
assert input is not None, "input 0 server mesh is null."
369+
assert outData0 is not None, "Output pipeline 0 is null."
370+
assert outData1 is not None, "Output pipeline 1 is null."
371+
372+
# do something...
373+
374+
return 1

0 commit comments

Comments
 (0)