diff --git a/geos-pv/examples/PVproxyInputs.py b/geos-pv/examples/PVproxyInputs.py new file mode 100644 index 000000000..892fb12d1 --- /dev/null +++ b/geos-pv/examples/PVproxyInputs.py @@ -0,0 +1,374 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. +# SPDX-FileContributor: Martin Lemay +# ruff: noqa: E402 # disable Module level import not at top of file +import sys +import numpy as np +from pathlib import Path +from typing_extensions import Self + +# update sys.path to load all GEOS Python Package dependencies +geos_pv_path: Path = Path( __file__ ).parent.parent +sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths + +update_paths() + +from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase + +from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] + smdomain, smproperty, smproxy, smhint ) +from vtkmodules.vtkCommonCore import ( + vtkInformation, + vtkInformationVector, + vtkDoubleArray, +) +from vtkmodules.vtkCommonDataModel import ( + vtkPointSet, + vtkUnstructuredGrid, + vtkFieldData, + vtkMultiBlockDataSet, +) + +__doc__ = """ +This file defines multiple Paraview plugins with various configurations. + +Examples of Source, Reader and Writer can be found on `Paraview documentation page `_. + +Additional examples are here defined: + +* PVPreserveInputTypeFilter is an example of a Paraview plugin where output is of same type as input data. + + .. Note:: + if Input data is a composite data set, the RequestData method is applied to each part of input object. + Results are concatenated to output object. Point data and cell data are added to each block, + a new line per block is added to output Field data or output vtkTable. + +* PVCompositeDataSetFilter is an example of a Paraview plugin that treats composite data sets as a single object conversely to PVPreserveInputTypeFilter. + +* PVMultipleInputFilter is an example of a Paraview plugin using 2 inputs of different type. + + The output is here of same type as input 1. + + .. Note:: Inputs are ordered in the reverse order compared to their definition using decorators. + + + +""" + + +@smproxy.filter( name="PVPreserveInputTypeFilter", label="Preserve Input Type Filter" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=True, +) +class PVPreserveInputTypeFilter( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=1, nOutputPorts=1, outputType="vtkUnstructuredGrid" ) + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + print( "RequestDataObject" ) + inData1 = self.GetInputData( inInfoVec, 0, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + print( "RequestData" ) + input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 ) + + assert input is not None, "input 0 server mesh is null." + assert outData is not None, "Output pipeline is null." + + # do something... + # for instance copy input and create a Field data in output object + + outData.ShallowCopy( input ) + + # add Field data attribute + nbArrays: int = 3 + fieldData: vtkFieldData = outData.GetFieldData() + fieldData.AllocateArrays( nbArrays ) + for i in range( nbArrays ): + newArray: vtkDoubleArray = vtkDoubleArray() + newArray.SetName( f"Column{i}" ) + newArray.SetNumberOfComponents( 1 ) + newArray.SetNumberOfValues( 1 ) + val: float = i + np.random.rand( 1 )[ 0 ] + newArray.SetValue( 0, val ) + fieldData.AddArray( newArray ) + fieldData.Modified() + + # add Point attribute + + # add Cell attribute + + outData.Modified() + return 1 + + +@smproxy.filter( name="PVCompositeDataSetFilter", label="Composite Data Set Filter" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkMultiBlockDataSet" ], + composite_data_supported=True, +) +class PVCompositeDataSetFilter( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=2, nOutputPorts=1, outputType="vtkMultiBlockDataSet" ) + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + inData1 = self.GetInputData( inInfoVec, 0, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input: vtkMultiBlockDataSet = self.GetInputData( inInfoVec, 0, 0 ) + outData: vtkMultiBlockDataSet = self.GetOutputData( outInfoVec, 0 ) + + assert input is not None, "input 0 server mesh is null." + assert outData is not None, "Output pipeline is null." + + # do something... + # for instance copy input and create a Field data in output object + + outData.ShallowCopy( input ) + nbArrays: int = 3 + fieldData: vtkFieldData = outData.GetFieldData() + fieldData.AllocateArrays( nbArrays ) + for i in range( nbArrays ): + newArray: vtkDoubleArray = vtkDoubleArray() + newArray.SetName( f"Column{i}" ) + newArray.SetNumberOfComponents( 1 ) + newArray.SetNumberOfValues( 1 ) + val: float = i + np.random.rand( 1 )[ 0 ] + newArray.SetValue( 0, val ) + fieldData.AddArray( newArray ) + + fieldData.Modified() + outData.Modified() + return 1 + + +@smproxy.filter( name="PVMultiInputFilter", label="Multiple Input Filter" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input1", port_index=1, label="Input 1" ) +@smdomain.datatype( + dataTypes=[ + "vtkPointSet", + ], + composite_data_supported=False, +) +@smproperty.input( name="Input0", port_index=0, label="Input 0" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=False, +) +class PVMultipleInputFilter( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=2, nOutputPorts=1, outputType="vtkUnstructuredGrid" ) + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + # here output data is of same type as input 1 + inData1 = self.GetInputData( inInfoVec, 1, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input0: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + input1: vtkPointSet = self.GetInputData( inInfoVec, 1, 0 ) + outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 ) + + assert input0 is not None, "input 0 server mesh is null." + assert input1 is not None, "input 1 client mesh is null." + assert outData is not None, "Output pipeline is null." + + # do something... + + return 1 + + +@smproxy.filter( name="PVMultiOutputFilter", label="Multiple Output Filter" ) +@smhint.xml( """ + + + + """ ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=False, +) +class PVMultipleOutputFilter( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=1, nOutputPorts=2, outputType="vtkUnstructuredGrid" ) + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + # here output data is of same type as input 1 + inData1 = self.GetInputData( inInfoVec, 1, 0 ) + outData0 = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData0 is None or ( not outData0.IsA( inData1.GetClassName() ) ): + outData0 = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData0.DATA_OBJECT(), outData0 ) + outData1 = self.GetOutputData( outInfoVec, 1 ) + if outData1 is None or ( not outData1.IsA( inData1.GetClassName() ) ): + outData1 = inData1.NewInstance() + outInfoVec.GetInformationObject( 1 ).Set( outData1.DATA_OBJECT(), outData1 ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + outData0: vtkUnstructuredGrid = self.GetOutputData( outInfoVec, 0 ) + outData1: vtkUnstructuredGrid = self.GetOutputData( outInfoVec, 1 ) + + assert input is not None, "input 0 server mesh is null." + assert outData0 is not None, "Output pipeline 0 is null." + assert outData1 is not None, "Output pipeline 1 is null." + + # do something... + + return 1 diff --git a/geos-pv/examples/PVproxyTimeStepAggregator.py b/geos-pv/examples/PVproxyTimeStepAggregator.py new file mode 100644 index 000000000..4b14166c2 --- /dev/null +++ b/geos-pv/examples/PVproxyTimeStepAggregator.py @@ -0,0 +1,190 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. +# SPDX-FileContributor: Martin Lemay +# ruff: noqa: E402 # disable Module level import not at top of file +import sys +import numpy as np +import numpy.typing as npt +from pathlib import Path +from typing_extensions import Self + +# update sys.path to load all GEOS Python Package dependencies +geos_pv_path: Path = Path( __file__ ).parent.parent +sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths + +update_paths() + +from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase + +from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] + smdomain, smproperty, smproxy, smhint ) +from vtkmodules.vtkCommonCore import ( + vtkInformation, + vtkInformationVector, +) +from vtkmodules.vtkCommonDataModel import ( + vtkPointSet, + vtkUnstructuredGrid, +) + +__doc__ = """ +Example of a Paraview plugin that runs aggregate data from various time steps. + +For instance, to copy arrays from oter time steps to the current one, or to compute +array differences between successive time steps. + +""" + + +@smproxy.filter( name="PVTimeStepAggregatorFilter", label="Time Step Aggregator Filter" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=True, +) +class PVTimeStepAggregatorFilter( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=1, nOutputPorts=1, outputType="vtkUnstructuredGrid" ) + + #: all time steps from input + self._timeSteps: npt.NDArray[ np.float64 ] = np.array( [] ) + #: displayed time step in the IHM + self._currentTime: float = 0.0 + #: time step index of displayed time step + self._currentTimeStepIndex: int = 0 + #: request data processing step - incremented each time RequestUpdateExtent is called + #: start at -1 to perform initialization when filter is selected (but not applied yet) + self._requestDataStep: int = -1 + + #: saved object at each time step + self._savedInputs: list[ vtkUnstructuredGrid ] = [] + + def RequestInformation( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestInformation. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + executive = self.GetExecutive() + inInfo = inInfoVec[ 0 ] + # get displayed time step info at filter intialization only + if self._requestDataStep == -1: + self._timeSteps = inInfo.GetInformationObject( 0 ).Get( executive.TIME_STEPS() # type: ignore + ) + self._currentTime = inInfo.GetInformationObject( 0 ).Get( executive.UPDATE_TIME_STEP() # type: ignore + ) + self._currentTimeStepIndex = self.getTimeStepIndex( self._currentTime, self._timeSteps ) + + self._savedInputs.clear() + + # update requestDataStep + self._requestDataStep += 1 + # update time according to requestDataStep iterator + inInfo.GetInformationObject( 0 ).Set( + executive.UPDATE_TIME_STEP(), # type: ignore[attr-defined] + self._timeSteps[ self._requestDataStep ] ) + outInfoVec.GetInformationObject( 0 ).Set( + executive.UPDATE_TIME_STEP(), # type: ignore[attr-defined] + self._timeSteps[ self._requestDataStep ] ) + # update all objects according to new time info + self.Modified() + return 1 + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + inData1 = self.GetInputData( inInfoVec, 0, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 ) + + assert input is not None, "input 0 server mesh is null." + assert outData is not None, "Output pipeline is null." + + # time controller + executive = self.GetExecutive() + if self._requestDataStep <= self._currentTimeStepIndex: + + # do something repeated at each time step... + dataAtT: vtkUnstructuredGrid = vtkUnstructuredGrid() + dataAtT.ShallowCopy( input ) + self._savedInputs.append( dataAtT ) + print( f"Input data saved at time step {self._requestDataStep}" ) + # keep running through time steps + request.Set( executive.CONTINUE_EXECUTING(), 1 ) # type: ignore + if self._requestDataStep >= self._currentTimeStepIndex: + # displayed time step, stop running + request.Remove( executive.CONTINUE_EXECUTING() ) # type: ignore + + # reinitialize requestDataStep if filter is re-applied later + self._requestDataStep = -1 + + # do something to finalize process... + outData.ShallowCopy( input ) + print( "Finalization process" ) + + outData.Modified() + return 1 + + def getTimeStepIndex( self: Self, time: float, timeSteps: npt.NDArray[ np.float64 ] ) -> int: + """Get the time step index of input time from the list of time steps. + + Args: + time (float): Time + timeSteps (npt.NDArray[np.float64]): Array of time steps + + Returns: + int: Time step index + """ + indexes: npt.NDArray[ np.int64 ] = np.where( np.isclose( timeSteps, time ) )[ 0 ] + assert ( indexes.size > 0 ), f"Current time {time} does not exist in the selected object." + return int( indexes[ 0 ] ) diff --git a/geos-pv/examples/PVproxyWidgetsDynamic.py b/geos-pv/examples/PVproxyWidgetsDynamic.py new file mode 100644 index 000000000..257d05dd8 --- /dev/null +++ b/geos-pv/examples/PVproxyWidgetsDynamic.py @@ -0,0 +1,564 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. +# SPDX-FileContributor: Martin Lemay +# ruff: noqa: E402 # disable Module level import not at top of file +import sys +from enum import Enum +from pathlib import Path +from typing_extensions import Self + +# update sys.path to load all GEOS Python Package dependencies +geos_pv_path: Path = Path( __file__ ).parent.parent +sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths + +update_paths() + +from geos.pv.utils.paraviewTreatments import ( strListToEnumerationDomainXml, strEnumToEnumerationDomainXml, + getArrayChoices ) +from geos_posp.visu.PVUtils.checkboxFunction import ( # type: ignore[attr-defined] + createModifiedCallback, ) + +from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase +from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] + smdomain, smproperty, smproxy, smhint, +) +from vtkmodules.vtkCommonCore import ( + vtkInformation, + vtkInformationVector, + vtkDataArraySelection, +) +from vtkmodules.vtkCommonDataModel import ( + vtkPointSet, + vtkUnstructuredGrid, +) + +__doc__ = """ +Example of a Paraview plugin that defines various dynamic input widgets. + +Dynamic inputs vary according to input data object or context. +See `Plugin HowTo page `_ +and `property hints documentation `_ + + tag from filter @smdomain.xml allows to filter arrays: attribute_type keyword filters array +if they are supported by point, cell, or field; number_of_components keyword filters on the number of components. + + tag required 2 arguments: +* mode options are defined by `vtkSMBoundsDomain::Modes enum `_ + (may have a way to select which axis, but not found) +* scale_factor: factor by which extent is multiplied for display. + +""" + +# TODO: try this https://discourse.paraview.org/t/difficulties-to-use-propertygroup-in-python-plugin-of-a-filter/12070 + +DROP_DOWN_LIST_ELEMENTS: tuple[ str, str, str ] = ( "Choice1", "Choice2", "Choice3" ) + + +class DROP_DOWN_LIST_ENUM( Enum ): + CHOICE1 = "Enum1" + CHOICE2 = "Enum2" + CHOICE3 = "Enum3" + + +@smproxy.filter( name="PVproxyWidgetsDynamic", label="Dynamic Widget Examples" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=True, +) +@smdomain.xml( """ + + + + + + """ ) +class PVproxyWidgetsDynamic( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=1, nOutputPorts=1, outputType="vtkUnstructuredGrid" ) + + self._strSingle: str = "" + self._intSingle: int = 0 + self._doubleSingle: float = 0.0 + + self._dropDownListSelection: int = 0 + self._dropDownListSelection2: int = 0 + + self._selectedAttributeSingle: str = "" + self._clearSelectedAttributeMulti: bool = True + self._selectedAttributeMulti: list[ str ] = [] + + # used to init data + self._initArraySelections: bool = True + self._selectedTimes: vtkDataArraySelection = vtkDataArraySelection() + self._selectedTimes.AddObserver( 0, createModifiedCallback( self ) ) + + self._extentSlider: list[ float ] = [ 0.0, 1.0 ] + + self._selectedAttributeSingleType: str = "" + self._componentIndex: int = 0 + + self.clearBlockNames: bool = True + self._blockNames: list[ str ] = [] + + @smproperty.intvector( + name="BoolSingle", + label="Show/Hide More Widgets", + default_values=0, + panel_visibility="default", + ) + @smdomain.xml( """""" ) + def a00BoolSingle( self: Self, value: bool ) -> None: + """Define boolean input. + + Args: + value (bool): Input bool. + """ + # no necessarily need to store the checkbox state + self.Modified() + + @smproperty.stringvector( + name="StringSingle", + label="String Single", + number_of_elements="1", + default_values="-", + panel_visibility="default", + ) + def a01StringSingle( self: Self, value: str ) -> None: + """Define an input string field. + + Args: + value (str): Input + """ + if value != self._strSingle: + self._strSingle = value + self.Modified() + + @smproperty.intvector( + name="IntSingle", + label="Int Single", + number_of_elements="1", + default_values=0, + panel_visibility="default", + ) + def a02IntSingle( self: Self, value: int ) -> None: + """Define an input int field. + + Args: + value (int): Input + """ + if value != self._intSingle: + self._intSingle = value + self.Modified() + + @smproperty.doublevector( + name="DoubleSingle", + label="Double Single", + number_of_elements="1", + default_values=0.0, + panel_visibility="default", + ) + def a03DoubleSingle( self: Self, value: float ) -> None: + """Define an input double field. + + Args: + value (float): Input + """ + if value != self._doubleSingle: + self._doubleSingle = value + self.Modified() + + @smproperty.xml( """ + + + + + """ ) + def a04ShowHideGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.intvector( + name="DropDownListFromVariable", + number_of_elements=1, + label="Dropdown List From Variable", + default_values=0, + ) + @smdomain.xml( strListToEnumerationDomainXml( DROP_DOWN_LIST_ELEMENTS ) ) + def b01DropDownListFromVariable( self: Self, intValue: int ) -> None: + """Set selection from drop down list filled with variable elements. + + Args: + intValue (int): int value. + """ + if intValue != self._dropDownListSelection: + self._dropDownListSelection = intValue + self.Modified() + + @smproperty.intvector( + name="DropDownListFromEnum", + number_of_elements=1, + label="Dropdown List From Enum", + default_values=0, + ) + @smdomain.xml( strEnumToEnumerationDomainXml( DROP_DOWN_LIST_ENUM ) ) + def b02DropDownListFromEnum( self: Self, intValue: int ) -> None: + """Set selection from drop down list filled with enumeration elements. + + Args: + intValue (int): int value. + """ + if intValue != self._dropDownListSelection2: + self._dropDownListSelection2 = intValue + self.Modified() + + @smproperty.xml( """ + + + """ ) + def b03DropDownListGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.stringvector( + name="SelectSingleAttribute", + label="Select Single Attribute", + number_of_elements="1", + element_types="2", + default_values="", + panel_visibility="default", + ) + @smdomain.xml( """ + + + + + + + Select a unique attribute from all the scalars cell attributes from input object. + Input object is defined by its name Input that must corresponds to the name in @smproperty.input + Attribute support is defined by input_domain_name: inputs_array (all arrays) or user defined + function from tag from filter @smdomain.xml. + Attribute type is defined by keyword `attribute_type`: Scalars or Vectors + + """ ) + def a01SelectSingleAttribute( self: Self, name: str ) -> None: + """Set selected attribute name. + + Args: + name (str): Input value + """ + if name != self._selectedAttributeSingle: + self._selectedAttributeSingle = name + self.Modified() + + @smproperty.stringvector( + name="SelectMultipleAttribute", + label="Select Multiple Attribute", + repeat_command=1, + number_of_elements_per_command="1", + element_types="2", + default_values="", + panel_visibility="default", + ) + @smdomain.xml( """ + + + + + + + Select a unique attribute from all the scalars cell attributes from input object. + Input object is defined by its name Input that must corresponds to the name in @smproperty.input + Attribute support is defined by input_domain_name: inputs_array (all arrays) or user defined + function from tag from filter @smdomain.xml. + Attribute type is defined by keyword `attribute_type`: Scalars or Vectors + + """ ) + def a02SelectMultipleAttribute( self: Self, name: str ) -> None: + """Set selected attribute name. + + Args: + name (str): Input value + """ + if self._clearSelectedAttributeMulti: + self._selectedAttributeMulti.clear() + self._clearSelectedAttributeMulti = False + self._selectedAttributeMulti.append( name ) + self.Modified() + + @smproperty.xml( """ + + + """ ) + def a05AttributeSelectionGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.xml( """ + + """ ) + def d01ActionButton( self: Self ) -> None: + """Action button to reset self._initArraySelections.""" + self._initArraySelections = True + self.Modified() + + @smproperty.dataarrayselection( name="TimeSelection" ) + def d02GetSelectedTimes( self: Self ) -> vtkDataArraySelection: + """Get selected times. + + Returns: + vtkDataArraySelection: selected attribute names. + """ + return self._selectedTimes + + @smproperty.doublevector( name="ExtentSlider", + label="Extent Slider", + number_of_elements=2, + default_values=( 0.0, 0.0 ), + panel_visibility="default", + panel_widget="double_range" ) + @smdomain.xml( """ + + + + + + + + + + """ ) + def d05ExtentSlider( self: Self, mini: float, maxi: float ) -> None: + """Define a double slider. + + Args: + mini (float): Minimum + maxi (float): Maximum + """ + if mini != self._extentSlider[ 0 ]: + self._extentSlider[ 0 ] = mini + self.Modified() + if maxi != self._extentSlider[ 1 ]: + self._extentSlider[ 1 ] = maxi + self.Modified() + + # use mode="leaves" to display only leaves, or discard it to display the whole tree + @smproperty.intvector( name="CompositeDataSetIndex", + default_values=1, + number_of_elements=1, + number_of_elements_per_command=1, + panel_visibility="default", + repeat_command=1 ) + @smdomain.xml( """ + + + + + + + + """ ) + def e00SetBlockNames( self: Self, value: str ) -> None: + """Define component selector. + + Args: + value (int): Component index + """ + if self.clearBlockNames: + self._blockNames.clear() + self.clearBlockNames = False + self._blockNames.append( value ) + self.Modified() + + @smproperty.intvector( name="AttributeType", default_values=0, number_of_elements=1 ) + @smdomain.xml( """ + + + + """ ) + def e01SetFieldAssociation( self: Self, value: int ) -> None: + """Set attribute support for next attribute selector. + + Args: + value (int): Input value + """ + self.Modified() + + @smproperty.xml( """ + + + + + + + + + + This property indicates the name of the array to be extracted. + + + """ ) + def e02SelectSingleAttributeWithType( self: Self, v1: int, v2: int, v3: int, support: int, name: str ) -> None: + """Set selected attribute name. + + Args: + v1 (int): Input value 1 + v2 (int): Input value 2 + v3 (int): Input value 3 + support (int): Attribute support (point 0, cell 1, field 2) + name (str): Input value + """ + if name != self._selectedAttributeSingleType: + self._selectedAttributeSingleType = name + self.Modified() + + @smproperty.xml( """ + + + + + + + + This property indicates the component of the array to be extracted. + + + """ ) + def e04SetInputArrayComponent( self: Self, value: int ) -> None: + """Define component selector. + + Args: + value (int): Component index + """ + if value != self._componentIndex: + self._componentIndex = value + self.Modified() + + @smproperty.xml( """ + + + + + """ ) + def e05SelectorGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + def RequestInformation( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], # noqa: F841 + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestInformation. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + # init arrays only if self._initArraySelections is True + # self._initArraySelections is True only when filter is selected + # or after hitting `Reset Arrays button` + if self._initArraySelections: + executive = self.GetExecutive() # noqa: F841 + inInfo = inInfoVec[ 0 ] + self.m_timeSteps = inInfo.GetInformationObject( 0 ).Get( executive.TIME_STEPS() ) # type: ignore + for timestep in self.m_timeSteps: # type: ignore[attr-defined] + if not self._selectedTimes.ArrayExists( str( timestep ) ): + self._selectedTimes.AddArray( str( timestep ) ) + self._initArraySelections = False + return 1 + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + inData1 = self.GetInputData( inInfoVec, 0, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None, "Input object is undefined" + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 ) + + assert input is not None, "input 0 server mesh is null." + assert outData is not None, "Output pipeline is null." + + # do something... + print( f"Single String {self._strSingle}" ) + print( f"Single int {self._intSingle}" ) + print( f"Single double {self._doubleSingle}" ) + print( f"Single Attribute selection {self._selectedAttributeSingle}" ) + print( f"Single Attribute selection with type {self._selectedAttributeSingleType}" ) + print( f"Multiple Attribute selection {self._selectedAttributeMulti}" ) + + selectedTimes = getArrayChoices( self.d02GetSelectedTimes() ) + print( f"Selected times: {selectedTimes}" ) + + print( f"Bounds slider: {self._extentSlider}" ) + print( f"Attribute {self._selectedAttributeSingleType} component: {self._componentIndex}" ) + print( f"Selected Block names: {self._blockNames}" ) + self._clearSelectedAttributeMulti = True + self.clearBlockNames = True + return 1 diff --git a/geos-pv/examples/PVproxyWidgetsStatic.py b/geos-pv/examples/PVproxyWidgetsStatic.py new file mode 100644 index 000000000..18d6f6c91 --- /dev/null +++ b/geos-pv/examples/PVproxyWidgetsStatic.py @@ -0,0 +1,605 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies. +# SPDX-FileContributor: Martin Lemay +# ruff: noqa: E402 # disable Module level import not at top of file +import sys +from pathlib import Path +from typing_extensions import Self + +from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase +from paraview.util.vtkAlgorithm import ( # type: ignore[import-not-found] + smdomain, smproperty, smproxy, smhint, +) +from vtkmodules.vtkCommonCore import ( + vtkInformation, + vtkInformationVector, +) +from vtkmodules.vtkCommonDataModel import ( + vtkPointSet, + vtkUnstructuredGrid, +) + +# update sys.path to load all GEOS Python Package dependencies +geos_pv_path: Path = Path( __file__ ).parent.parent +sys.path.insert( 0, str( geos_pv_path / "src" ) ) +from geos.pv.utils.config import update_paths + +update_paths() + +__doc__ = """ +Example of a Paraview plugin that defines various static input widgets. + +Static inputs do not depend on input data object or context but are entirely defined by the decorators. +See `Plugin HowTo page `_ +and `property hints documentation `_ +""" + + +@smproxy.filter( name="PVproxyWidgetsStatic", label="Static Widget Examples" ) +@smhint.xml( """""" ) +@smproperty.input( name="Input", port_index=0, label="Input" ) +@smdomain.datatype( + dataTypes=[ "vtkUnstructuredGrid" ], + composite_data_supported=True, +) +class PVproxyWidgetsStatic( VTKPythonAlgorithmBase ): + + def __init__( self: Self ) -> None: + """Map the properties of a server mesh to a client mesh.""" + super().__init__( nInputPorts=1, nOutputPorts=1, outputType="vtkUnstructuredGrid" ) + + self._strSingle: str = "" + self._strMultiline: str = "" + self._inputFilePath: str = "" + self._outputFilePath: str = "" + self._directoryPath: str = "" + self._intSingle: float = 0 + self._intMulti: list[ float ] = [ 0, 0, 0 ] + self._boolSingle: bool = False + self._doubleSingle: float = 0.0 + self._doubleMulti: list[ float ] = [ 0.0, 0.0, 0.0 ] + self._singleSliderValue: float = 0.0 + self._singleIntSliderValue: int = 0 + self._doubleSlider: list[ float ] = [ 0.0, 0.0 ] + self._color: list[ float ] = [ 0.0, 0.0, 0.0 ] + self._table: list[ tuple[ int, float, str ] ] = [] + self._clearTable: bool = True + self._dropDownListSelection: int = 0 + + @smproperty.xml( """ + + """ ) + def a00ActionButton( self: Self ) -> None: + """Action button example.""" + print( "Executes action" ) + self.Modified() + + @smproperty.stringvector( + name="StringSingle", + label="String Single", + number_of_elements="1", + default_values="-", + panel_visibility="default", + ) + def a01StringSingle( self: Self, value: str ) -> None: + """Define an input string field. + + Args: + value (str): Input + """ + if value != self._strSingle: + self._strSingle = value + self.Modified() + + +# may be used with panel_widget="calculator" to create a scriptable widget. +# +# +# This property contains the equation for computing the new +# array. +# +# + +# use syntax= to highlight text with language color + + @smproperty.stringvector( + name="StringMultiline", + label="MultiLine String", + number_of_elements="1", + default_values="-", + panel_visibility="default", + ) + @smdomain.xml( """ + + + + """ ) + def a02StringMultiLine( self: Self, value: str ) -> None: + """Define an input string field. + + Args: + value (str): Input + """ + if value != self._strMultiline: + self._strMultiline = value + self.Modified() + + @smproperty.xml( """ + + + """ ) + def a03StringInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.stringvector( + name="InputFilePath", + label="Input File Path", + number_of_elements="1", + default_values="Select Input .txt file...", + panel_visibility="default", + ) + @smdomain.filelist() + @smhint.filechooser( extensions=[ "txt" ], file_description="Input text file." ) + def b01InputFilePath( self: Self, value: str ) -> None: + """Define an input file path. + + Args: + value (str): Input + """ + if value != self._inputFilePath: + self._inputFilePath = value + self.Modified() + + # @smdomain.filelist() and @smhint.filechooser may be replaced by this @smdomain.xml + # @smdomain.xml(""" + # + # + # + # + # + # """) + @smproperty.stringvector( + name="OutputFilePath", + label="Output File Path", + number_of_elements="1", + default_values="Select output file...", + panel_visibility="default", + ) + @smdomain.filelist() + @smhint.filechooser( extensions=[ "txt" ], file_description="Output text file." ) + @smdomain.xml( """ + + + + """ ) + def b02OutputFilePath( self: Self, value: str ) -> None: + """Define an input file path. + + Args: + value (str): Input + """ + if value != self._outputFilePath: + self._outputFilePath = value + self.Modified() + + # @smdomain.filelist() and @smhint.filechooser may be replaced by this @smdomain.xml + # @smdomain.xml(""" + # + # + # + # + # + + @smproperty.stringvector( + name="DirectoryPath", + label="Directory Path", + number_of_elements="1", + default_values="Select a directory...", + panel_visibility="default", + ) + @smdomain.filelist() + @smhint.filechooser( extensions="", file_description="Output directory." ) + @smdomain.xml( """ + + + + """ ) + def b03DirectoryPath( self: Self, value: str ) -> None: + """Define an input string field. + + Args: + value (str): Input + """ + if value != self._directoryPath: + self._directoryPath = value + self.Modified() + + @smproperty.xml( """ + + + + """ ) + def b04FileInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.intvector( + name="IntSingle", + label="Int Single", + number_of_elements="1", + default_values=0, + panel_visibility="default", + ) + def c01IntSingle( self: Self, value: int ) -> None: + """Define an input int field. + + Args: + value (int): Input + """ + if value != self._intSingle: + self._intSingle = value + self.Modified() + + @smproperty.intvector( + name="IntMulti", + label="Int Multi", + number_of_elements="3", + default_values=( 0, 0, 0 ), + panel_visibility="default", + ) + def c02IntMulti( self: Self, value0: int, value1: int, value2: int ) -> None: + """Define an input int field. + + Args: + value0 (int): Input 0 + value1 (int): Input 1 + value2 (int): Input 2 + """ + if value0 != self._intMulti[ 0 ]: + self._intMulti[ 0 ] = value0 + self.Modified() + if value1 != self._intMulti[ 1 ]: + self._intMulti[ 1 ] = value1 + self.Modified() + if value2 != self._intMulti[ 2 ]: + self._intMulti[ 2 ] = value2 + self.Modified() + + @smproperty.xml( """ + + + """ ) + def c03IntInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.intvector( + name="BoolSingle", + label="Single Boolean Input", + default_values=0, + panel_visibility="default", + ) + @smdomain.xml( """""" ) + def c04BoolSingle( self: Self, value: bool ) -> None: + """Define boolean input. + + Args: + value (bool): Input bool. + """ + self._boolSingle = value + self.Modified() + + @smproperty.xml( """ + + """ ) + def c05BoolInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.doublevector( + name="DoubleSingle", + label="Double Single", + number_of_elements="1", + default_values=0.0, + panel_visibility="default", + ) + def d01DoubleSingle( self: Self, value: float ) -> None: + """Define an input double field. + + Args: + value (float): Input + """ + if value != self._doubleSingle: + self._doubleSingle = value + self.Modified() + + @smproperty.doublevector( + name="DoubleMulti", + label="Double Multi", + number_of_elements="3", + default_values=( 0.0, 0.0, 0.0 ), + panel_visibility="default", + ) + def d02DoubleMulti( self: Self, value0: float, value1: float, value2: float ) -> None: + """Define an input double field. + + Args: + value0 (float): Input 0 + value1 (float): Input 1 + value2 (float): Input 2 + """ + if value0 != self._doubleMulti[ 0 ]: + self._doubleMulti[ 0 ] = value0 + self.Modified() + if value1 != self._doubleMulti[ 1 ]: + self._doubleMulti[ 1 ] = value1 + self.Modified() + if value2 != self._doubleMulti[ 2 ]: + self._doubleMulti[ 2 ] = value2 + self.Modified() + + @smproperty.xml( """ + + + """ ) + def d03DoubleInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.intvector( name="SingleIntSlider", + label="Single Int Slider", + number_of_elements=1, + default_values=0.0, + panel_visibility="default", + panel_widget="range" ) + @smdomain.xml( """ + + """ ) + def d04SingleIntSlider( self: Self, value: int ) -> None: + """Define a slider. + + Args: + value (float): Input value + """ + if value != self._singleIntSliderValue: + self._singleIntSliderValue = value + self.Modified() + + @smproperty.xml( """ + + + + """ ) + def d05SingleFloatSlider( self: Self, value: float ) -> None: + """Define a slider. + + Args: + value (float): Input value + """ + if value != self._singleSliderValue: + self._singleSliderValue = value + self.Modified() + + # add or remove inside Hints tag + @smproperty.xml( """ + + + + + + + + """ ) + def d06DoubleSlider( self: Self, mini: float, maxi: float ) -> None: + """Define a double slider. + + Args: + mini (float): Minimum + maxi (float): Maximum + """ + if mini != self._doubleSlider[ 0 ]: + self._doubleSlider[ 0 ] = mini + self.Modified() + if maxi != self._doubleSlider[ 1 ]: + self._doubleSlider[ 1 ] = maxi + self.Modified() + + @smproperty.xml( """ + + + + """ ) + def d07SliderInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.doublevector( name="Color", + label="Color", + number_of_elements="3", + default_values=( 0.0, 0.0, 0.0 ), + panel_visibility="default", + panel_widget="color_selector_with_palette" ) + @smdomain.xml( """ + + + + """ ) + def d07Color( self: Self, value0: float, value1: float, value2: float ) -> None: + """Define an input double field. + + Args: + value0 (float): Input 0 + value1 (float): Input 1 + value2 (float): Input 2 + """ + if value0 != self._color[ 0 ]: + self._color[ 0 ] = value0 + self.Modified() + if value1 != self._color[ 1 ]: + self._color[ 1 ] = value1 + self.Modified() + if value2 != self._color[ 2 ]: + self._color[ 2 ] = value2 + self.Modified() + + @smproperty.xml( """ + + """ ) + def d08ColorInputsGroup( self: Self ) -> None: + """Create a group of widgets.""" + self.Modified() + + @smproperty.intvector( + name="DropDownList", + label="Drop Down List", + number_of_elements=1, + default_values=0, + panel_visibility="default", + ) + @smdomain.xml( """ + + + + + + """ ) + def e01DropDownList( self: Self, intValue: int ) -> None: + """Set selection from predefined drop down list. + + Args: + intValue (int): int value. + """ + if intValue != self._dropDownListSelection: + self._dropDownListSelection = intValue + self.Modified() + + @smproperty.xml( """ + + + + + + + + + + """ ) + def f01VariableTableMultiType( self: Self, intValue: int, floatValue: float, strValue: str ) -> None: + """Set multi type table with undefined size. + + Args: + intValue (int): int value. + floatValue (float): float value. + strValue (str): string value. + """ + # clear the table the first time the method is called + if self._clearTable: + self._table.clear() + self._clearTable = False + self._table.append( ( int( intValue ), float( floatValue ), str( strValue ) ) ) + self.Modified() + + def RequestDataObject( + self: Self, + request: vtkInformation, + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestDataObject. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + inData1 = self.GetInputData( inInfoVec, 0, 0 ) + outData = self.GetOutputData( outInfoVec, 0 ) + assert inData1 is not None + if outData is None or ( not outData.IsA( inData1.GetClassName() ) ): + outData = inData1.NewInstance() + outInfoVec.GetInformationObject( 0 ).Set( outData.DATA_OBJECT(), outData ) + return super().RequestDataObject( request, inInfoVec, outInfoVec ) # type: ignore[no-any-return] + + def RequestData( + self: Self, + request: vtkInformation, # noqa: F841 + inInfoVec: list[ vtkInformationVector ], + outInfoVec: vtkInformationVector, + ) -> int: + """Inherited from VTKPythonAlgorithmBase::RequestData. + + Args: + request (vtkInformation): Request + inInfoVec (list[vtkInformationVector]): Input objects + outInfoVec (vtkInformationVector): Output objects + + Returns: + int: 1 if calculation successfully ended, 0 otherwise. + """ + input: vtkUnstructuredGrid = self.GetInputData( inInfoVec, 0, 0 ) + outData: vtkPointSet = self.GetOutputData( outInfoVec, 0 ) + + assert input is not None, "input 0 server mesh is null." + assert outData is not None, "Output pipeline is null." + + # do something... + print( f"Single String {self._strSingle}" ) + print( f"Multiline String {self._strMultiline}" ) + print( f"Input file path {self._inputFilePath}" ) + print( f"Output file path {self._outputFilePath}" ) + print( f"Directory path {self._directoryPath}" ) + print( f"Single int {self._intSingle}" ) + print( f"Multiple int {self._intMulti}" ) + print( f"Boolean {self._boolSingle}" ) + print( f"Single double {self._doubleSingle}" ) + print( f"Multiple double {self._doubleMulti}" ) + print( f"Single Slider {self._singleIntSliderValue}" ) + print( f"Single Slider {self._singleSliderValue}" ) + print( f"Double Slider {self._doubleSlider}" ) + print( f"Color {self._color}" ) + print( f"Variable table {self._table}" ) + + # set self._clearTable to True for the next time the table is updated + self._clearTable = True + return 1