]> SALOME platform Git repositories - tools/paravisaddons_common.git/commitdiff
Salome HOME
initial commit from paravisaddons
authorcrouzet <nicolas.crouzet@cea.fr>
Mon, 8 Feb 2021 08:35:01 +0000 (09:35 +0100)
committercrouzet <nicolas.crouzet@cea.fr>
Mon, 8 Feb 2021 08:35:01 +0000 (09:35 +0100)
289 files changed:
CMakeLists.txt [new file with mode: 0644]
PARAVISADDONS_version.h.in [new file with mode: 0644]
README [new file with mode: 0644]
doc/README [new file with mode: 0644]
src/AppendAttributesOverTime/CMakeLists.txt [new file with mode: 0644]
src/AppendAttributesOverTime/README.md [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/CMakeLists.txt [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtk.module [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.cxx [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.h [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/CMakeLists.txt [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/README.md [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/filters.xml [new file with mode: 0644]
src/AppendAttributesOverTime/plugin/paraview.plugin [new file with mode: 0644]
src/AutoConvertPropertiesPlugin/CMakeLists.txt [new file with mode: 0644]
src/AutoConvertPropertiesPlugin/plugin/CMakeLists.txt [new file with mode: 0644]
src/AutoConvertPropertiesPlugin/plugin/paraview.plugin [new file with mode: 0644]
src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.cxx [new file with mode: 0644]
src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.h [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/CellDataContour/CMakeLists.txt [new file with mode: 0644]
src/CellDataContour/plugin/CMakeLists.txt [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/CMakeLists.txt [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtk.module [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.cxx [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.h [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.cxx [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.h [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.cxx [new file with mode: 0644]
src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.h [new file with mode: 0644]
src/CellDataContour/plugin/filters.xml [new file with mode: 0644]
src/CellDataContour/plugin/paraview.plugin [new file with mode: 0644]
src/ComplexMode/CMakeLists.txt [new file with mode: 0644]
src/ComplexMode/MobileMesh.xml [new file with mode: 0644]
src/ComplexMode/MoveMesh.py [new file with mode: 0644]
src/ComplexMode/example.med [new file with mode: 0644]
src/ComplexMode/harmo.resu.vtu [new file with mode: 0644]
src/ComplexMode/plugin/CMakeLists.txt [new file with mode: 0644]
src/ComplexMode/plugin/ComplexModeModule/CMakeLists.txt [new file with mode: 0644]
src/ComplexMode/plugin/ComplexModeModule/vtk.module [new file with mode: 0644]
src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.cxx [new file with mode: 0644]
src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.h [new file with mode: 0644]
src/ComplexMode/plugin/filters.xml [new file with mode: 0644]
src/ComplexMode/plugin/paraview.plugin [new file with mode: 0644]
src/ContactReader/CMakeLists.txt [new file with mode: 0644]
src/ContactReader/plugin/CMakeLists.txt [new file with mode: 0644]
src/ContactReader/plugin/ContactReaderModule/CMakeLists.txt [new file with mode: 0644]
src/ContactReader/plugin/ContactReaderModule/vtk.module [new file with mode: 0644]
src/ContactReader/plugin/ContactReaderModule/vtkContactReader.cxx [new file with mode: 0644]
src/ContactReader/plugin/ContactReaderModule/vtkContactReader.h [new file with mode: 0644]
src/ContactReader/plugin/paraview.plugin [new file with mode: 0644]
src/ContactReader/plugin/sources.xml [new file with mode: 0644]
src/ContactReader/resultante_rn.rco [new file with mode: 0644]
src/ContactReader/resultante_rn.txt [new file with mode: 0644]
src/CustomFilters/CMakeLists.txt [new file with mode: 0644]
src/CustomFilters/Electromagnetism.xml [new file with mode: 0644]
src/CustomFilters/TemporalCSVReader.xml [new file with mode: 0644]
src/CustomFilters/papbComp.cpd [new file with mode: 0644]
src/CustomFilters/papbComp.xml [new file with mode: 0644]
src/CustomFilters/post_R_resuir.trco [new file with mode: 0644]
src/DepthVsTime/CMakeLists.txt [new file with mode: 0644]
src/DepthVsTime/TestCase.py [new file with mode: 0644]
src/DepthVsTime/plugin/CMakeLists.txt [new file with mode: 0644]
src/DepthVsTime/plugin/DepthVsTimeModule/CMakeLists.txt [new file with mode: 0644]
src/DepthVsTime/plugin/DepthVsTimeModule/vtk.module [new file with mode: 0644]
src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.cxx [new file with mode: 0644]
src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.h [new file with mode: 0644]
src/DepthVsTime/plugin/filters.xml [new file with mode: 0644]
src/DepthVsTime/plugin/paraview.plugin [new file with mode: 0644]
src/ElectromagnetismFluxDisc/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtk.module [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.cxx [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.h [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/Test/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/Test/test_flux_disc0.py [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/filters.xml [new file with mode: 0644]
src/ElectromagnetismFluxDisc/plugin/paraview.plugin [new file with mode: 0644]
src/ElectromagnetismRotation/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.cxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/MEDLoaderForPV.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/VTKMEDTraits.hxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtk.module [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.cxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.cxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/ElectromagnetismRotation.xml [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqCellData16.png [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqPointData16.png [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/pqElectromagnetismRotation.qrc [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.cxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.cxx [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.h [new file with mode: 0644]
src/ElectromagnetismRotation/plugin/paraview.plugin [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtk.module [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.cxx [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.h [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/filters.xml [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/plugin/paraview.plugin [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/scripts/generate.py [new file with mode: 0644]
src/ElectromagnetismStreamTraceur/scripts/test_stream.py [new file with mode: 0644]
src/ElectromagnetismVecteur/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/VecteurFilters/CMakeLists.txt [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/VecteurFilters/vtk.module [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.cxx [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.h [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/filters.xml [new file with mode: 0644]
src/ElectromagnetismVecteur/plugin/paraview.plugin [new file with mode: 0644]
src/ElectromagnetismVecteur/scripts/generate.py [new file with mode: 0644]
src/ExtractComponentsPlugin/CMakeLists.txt [new file with mode: 0644]
src/ExtractComponentsPlugin/ExtractCompo.med [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/CMakeLists.txt [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/CMakeLists.txt [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtk.module [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.cxx [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.h [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.cxx [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.h [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/filters.xml [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/paraview.plugin [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.cxx [new file with mode: 0644]
src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.h [new file with mode: 0644]
src/ExtractThreeD/CMakeLists.txt [new file with mode: 0644]
src/ExtractThreeD/plugin/CMakeLists.txt [new file with mode: 0644]
src/ExtractThreeD/plugin/ExtractThreeDModule/CMakeLists.txt [new file with mode: 0644]
src/ExtractThreeD/plugin/ExtractThreeDModule/vtk.module [new file with mode: 0644]
src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.cxx [new file with mode: 0644]
src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.h [new file with mode: 0644]
src/ExtractThreeD/plugin/filters.xml [new file with mode: 0644]
src/ExtractThreeD/plugin/paraview.plugin [new file with mode: 0644]
src/GlyphCIH/CMakeLists.txt [new file with mode: 0644]
src/GlyphCIH/plugin/CMakeLists.txt [new file with mode: 0644]
src/GlyphCIH/plugin/GlyphCIHFilters/CMakeLists.txt [new file with mode: 0644]
src/GlyphCIH/plugin/GlyphCIHFilters/vtk.module [new file with mode: 0644]
src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.cxx [new file with mode: 0644]
src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.h [new file with mode: 0644]
src/GlyphCIH/plugin/filters.xml [new file with mode: 0644]
src/GlyphCIH/plugin/paraview.plugin [new file with mode: 0644]
src/MoveZCote/CMakeLists.txt [new file with mode: 0644]
src/MoveZCote/MobileMesh.xml [new file with mode: 0644]
src/MoveZCote/MoveMesh.py [new file with mode: 0644]
src/MoveZCote/plugin/CMakeLists.txt [new file with mode: 0644]
src/MoveZCote/plugin/MoveZCoteModule/CMakeLists.txt [new file with mode: 0644]
src/MoveZCote/plugin/MoveZCoteModule/vtk.module [new file with mode: 0644]
src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.cxx [new file with mode: 0644]
src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.h [new file with mode: 0644]
src/MoveZCote/plugin/filters.xml [new file with mode: 0644]
src/MoveZCote/plugin/paraview.plugin [new file with mode: 0644]
src/ProbePointOverTime/CMakeLists.txt [new file with mode: 0644]
src/ProbePointOverTime/HowtoTest.txt [new file with mode: 0644]
src/ProbePointOverTime/ProbePointOverTimePlugin.xml [new file with mode: 0644]
src/ProbePointOverTime/example.med [new file with mode: 0644]
src/QuadraticToLinear/CMakeLists.txt [new file with mode: 0644]
src/QuadraticToLinear/TestCase.py [new file with mode: 0644]
src/QuadraticToLinear/plugin/CMakeLists.txt [new file with mode: 0644]
src/QuadraticToLinear/plugin/QuadraticToLinearModule/CMakeLists.txt [new file with mode: 0644]
src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtk.module [new file with mode: 0644]
src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.cxx [new file with mode: 0644]
src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.h [new file with mode: 0644]
src/QuadraticToLinear/plugin/filters.xml [new file with mode: 0644]
src/QuadraticToLinear/plugin/paraview.plugin [new file with mode: 0644]
src/RateOfFlowThroughSection/CMakeLists.txt [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/CMakeLists.txt [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/CMakeLists.txt [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKMEDTraits.hxx [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.cxx [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.h [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtk.module [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.cxx [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.h [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.cxx [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.h [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.cxx [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.h [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/filters.xml [new file with mode: 0644]
src/RateOfFlowThroughSection/plugin/paraview.plugin [new file with mode: 0644]
src/RateOfFlowThroughSection/script/TestCase.py [new file with mode: 0644]
src/RateOfFlowThroughSection/script/calcul_3.py [new file with mode: 0644]
src/RateOfFlowThroughSection/script/calcul_sediment_deposit.py [new file with mode: 0644]
src/RateOfFlowThroughSection/script/test_sediment_deposit.py [new file with mode: 0644]
src/RosetteCIH/CMakeLists.txt [new file with mode: 0644]
src/RosetteCIH/plugin/CMakeLists.txt [new file with mode: 0644]
src/RosetteCIH/plugin/RosetteCIHFilters/CMakeLists.txt [new file with mode: 0644]
src/RosetteCIH/plugin/RosetteCIHFilters/vtk.module [new file with mode: 0644]
src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.cxx [new file with mode: 0644]
src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.h [new file with mode: 0644]
src/RosetteCIH/plugin/filters.xml [new file with mode: 0644]
src/RosetteCIH/plugin/paraview.plugin [new file with mode: 0644]
src/SerafinReader/CMakeLists.txt [new file with mode: 0644]
src/SerafinReader/geo_TW.slf [new file with mode: 0644]
src/SerafinReader/plugin/CMakeLists.txt [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/CMakeLists.txt [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/FFileReader.h [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/stdSerafinReader.h [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/vtk.module [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.cxx [new file with mode: 0644]
src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.h [new file with mode: 0644]
src/SerafinReader/plugin/paraview.plugin [new file with mode: 0644]
src/SerafinReader/plugin/sources.xml [new file with mode: 0644]
src/SinusXReader/CMakeLists.txt [new file with mode: 0644]
src/SinusXReader/LigneDEau.sx [new file with mode: 0644]
src/SinusXReader/plugin/CMakeLists.txt [new file with mode: 0644]
src/SinusXReader/plugin/SinusXReaderModule/CMakeLists.txt [new file with mode: 0644]
src/SinusXReader/plugin/SinusXReaderModule/vtk.module [new file with mode: 0644]
src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.cxx [new file with mode: 0644]
src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.h [new file with mode: 0644]
src/SinusXReader/plugin/paraview.plugin [new file with mode: 0644]
src/SinusXReader/plugin/sources.xml [new file with mode: 0644]
src/SpatialPfl/CMakeLists.txt [new file with mode: 0644]
src/SpatialPfl/TestCase.py [new file with mode: 0644]
src/SpatialPfl/plugin/CMakeLists.txt [new file with mode: 0644]
src/SpatialPfl/plugin/SpatialPflModule/CMakeLists.txt [new file with mode: 0644]
src/SpatialPfl/plugin/SpatialPflModule/vtk.module [new file with mode: 0644]
src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.cxx [new file with mode: 0644]
src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.h [new file with mode: 0644]
src/SpatialPfl/plugin/filters.xml [new file with mode: 0644]
src/SpatialPfl/plugin/paraview.plugin [new file with mode: 0644]
src/SphereAlongLines/CMakeLists.txt [new file with mode: 0644]
src/SphereAlongLines/Test/test_dev_surface.py [new file with mode: 0644]
src/SphereAlongLines/Test/test_dev_surface2.py [new file with mode: 0644]
src/SphereAlongLines/Test/test_dev_surface3.py [new file with mode: 0644]
src/SphereAlongLines/plugin/CMakeLists.txt [new file with mode: 0644]
src/SphereAlongLines/plugin/SphereAlongLinesModule/CMakeLists.txt [new file with mode: 0644]
src/SphereAlongLines/plugin/SphereAlongLinesModule/vtk.module [new file with mode: 0644]
src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.cxx [new file with mode: 0644]
src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.h [new file with mode: 0644]
src/SphereAlongLines/plugin/filters.xml [new file with mode: 0644]
src/SphereAlongLines/plugin/paraview.plugin [new file with mode: 0644]
src/TemporalOnPoint/CMakeLists.txt [new file with mode: 0644]
src/TemporalOnPoint/TestCase.py [new file with mode: 0644]
src/TemporalOnPoint/plugin/CMakeLists.txt [new file with mode: 0644]
src/TemporalOnPoint/plugin/TemporalOnPointModule/CMakeLists.txt [new file with mode: 0644]
src/TemporalOnPoint/plugin/TemporalOnPointModule/vtk.module [new file with mode: 0644]
src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.cxx [new file with mode: 0644]
src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.h [new file with mode: 0644]
src/TemporalOnPoint/plugin/filters.xml [new file with mode: 0644]
src/TemporalOnPoint/plugin/paraview.plugin [new file with mode: 0644]
src/Tools/Clean.py [new file with mode: 0644]
src/TorseurCIH/CMakeLists.txt [new file with mode: 0644]
src/TorseurCIH/Test.py [new file with mode: 0644]
src/TorseurCIH/plugin/CMakeLists.txt [new file with mode: 0644]
src/TorseurCIH/plugin/TorseurCIHModule/CMakeLists.txt [new file with mode: 0644]
src/TorseurCIH/plugin/TorseurCIHModule/vtk.module [new file with mode: 0644]
src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.cxx [new file with mode: 0644]
src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.h [new file with mode: 0644]
src/TorseurCIH/plugin/filters.xml [new file with mode: 0644]
src/TorseurCIH/plugin/paraview.plugin [new file with mode: 0644]
src/TorseurCIH/script/Test.py [new file with mode: 0644]
src/TorseurCIH/script/slice.med [new file with mode: 0644]
src/TorseurCIH/slice.med [new file with mode: 0644]
src/View/CMakeLists.txt [new file with mode: 0644]
src/View/MyDisplay.cxx [new file with mode: 0644]
src/View/MyDisplay.h [new file with mode: 0644]
src/View/MyView.cxx [new file with mode: 0644]
src/View/MyView.h [new file with mode: 0644]
src/View/MyViewActiveOptions.cxx [new file with mode: 0755]
src/View/MyViewActiveOptions.h [new file with mode: 0755]
src/View/MyViewOptions.cxx [new file with mode: 0755]
src/View/MyViewOptions.h [new file with mode: 0755]
src/View/MyViewSM.xml [new file with mode: 0644]
src/XYChartRepresentationColumns/CMakeLists.txt [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/CMakeLists.txt [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/CMakeLists.txt [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtk.module [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.cxx [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.h [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/paraview.plugin [new file with mode: 0644]
src/XYChartRepresentationColumns/plugin/views.xml [new file with mode: 0644]
src/ZJFilter/CMakeLists.txt [new file with mode: 0644]
src/ZJFilter/TestCase.py [new file with mode: 0644]
src/ZJFilter/plugin/CMakeLists.txt [new file with mode: 0644]
src/ZJFilter/plugin/ZJFilterModule/CMakeLists.txt [new file with mode: 0644]
src/ZJFilter/plugin/ZJFilterModule/vtk.module [new file with mode: 0644]
src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.cxx [new file with mode: 0644]
src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.h [new file with mode: 0644]
src/ZJFilter/plugin/filters.xml [new file with mode: 0644]
src/ZJFilter/plugin/paraview.plugin [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f1b8780
--- /dev/null
@@ -0,0 +1,83 @@
+# Copyright (C) 2010-2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR)
+INCLUDE(CMakeDependentOption)
+PROJECT(PARAVISADDONS C CXX)
+
+IF(WIN32)
+  STRING( REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags ${CMAKE_SHARED_LINKER_FLAGS_DEBUG} )
+  SET( CMAKE_SHARED_LINKER_FLAGS_DEBUG "${replacementFlags}" )
+ENDIF(WIN32)
+
+# Versioning
+# ===========
+# Project name, upper case
+STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
+
+SET(${PROJECT_NAME_UC}_MAJOR_VERSION 9)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 6)
+SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
+SET(${PROJECT_NAME_UC}_VERSION
+  ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
+SET(${PROJECT_NAME_UC}_VERSION_DEV 0)
+
+# Common CMake macros
+# ===================
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros NO_POLICY_SCOPE)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+# Find KERNEL
+# ===========
+SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL")
+IF(EXISTS ${KERNEL_ROOT_DIR})
+  FIND_PACKAGE(SalomeKERNEL REQUIRED)
+  ADD_DEFINITIONS(${KERNEL_DEFINITIONS})
+  INCLUDE_DIRECTORIES(${KERNEL_INCLUDE_DIRS})
+ELSE(EXISTS ${KERNEL_ROOT_DIR})
+  MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR")
+ENDIF(EXISTS ${KERNEL_ROOT_DIR})
+
+# Platform setup
+# ==============
+INCLUDE(SalomeSetupPlatform)   # From KERNEL
+# Always build libraries as shared objects:
+SET(BUILD_SHARED_LIBS TRUE)
+
+FIND_PACKAGE(SalomeQt5 REQUIRED)
+
+##
+## Specific to ParaViS:
+##
+
+FIND_PACKAGE(SalomeParaView REQUIRED)
+
+# Header configuration
+# ====================
+SALOME_XVERSION(${PROJECT_NAME})
+SALOME_CONFIGURE_FILE(PARAVISADDONS_version.h.in PARAVISADDONS_version.h INSTALL ${SALOME_INSTALL_HEADERS})
+
+# Sources
+# ========
+ADD_SUBDIRECTORY(src)
diff --git a/PARAVISADDONS_version.h.in b/PARAVISADDONS_version.h.in
new file mode 100644 (file)
index 0000000..a75a540
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright (C) 2010-2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : PARAVISADDONS_version.h
+
+#if !defined(__PARAVISADDONS_VERSION_H__)
+#define __PARAVISADDONS_VERSION_H__
+
+/*!
+  Specify version of SALOME PARAVISADDONS module, as follows
+
+  PARAVISADDONS_VERSION_MAJOR       : (integer) number identifying major version
+  PARAVISADDONS_VERSION_MINOR       : (integer) number identifying minor version
+  PARAVISADDONS_VERSION_MAINTENANCE : (integer) number identifying maintenance version
+  PARAVISADDONS_VERSION_STR         : (string)  complete version number "major.minor.maintenance"
+  PARAVISADDONS_VERSION             : (hex)     complete version number (major << 16) + (minor << 8) + maintenance
+  PARAVISADDONS_DEVELOPMENT         : (integer) indicates development version when set to 1
+*/
+
+#define PARAVISADDONS_VERSION_MAJOR       @SALOMEPARAVISADDONS_MAJOR_VERSION@
+#define PARAVISADDONS_VERSION_MINOR       @SALOMEPARAVISADDONS_MINOR_VERSION@
+#define PARAVISADDONS_VERSION_MAINTENANCE @SALOMEPARAVISADDONS_PATCH_VERSION@
+#define PARAVISADDONS_VERSION_STR         "@SALOMEPARAVISADDONS_VERSION@"
+#define PARAVISADDONS_VERSION             @SALOMEPARAVISADDONS_XVERSION@
+#define PARAVISADDONS_DEVELOPMENT         @SALOMEPARAVISADDONS_VERSION_DEV@
+
+#endif // __PARAVISADDONS_VERSION_H__
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..b47d93d
--- /dev/null
+++ b/README
@@ -0,0 +1,59 @@
+**************************
+About SALOME PARAVISADDONS
+**************************
+
+=======
+License
+=======
+
+
+============
+Installation
+============
+
+--------------
+Pre-requisites
+--------------
+
+------------------
+Basic Installation
+------------------
+
+The build procedure of the SALOME platform is implemented with CMake.
+In order to build the module you have to do the following actions: 
+
+1. Set up environment for pre-requisites (see "Pre-requisites" section above).
+
+2. Create a build directory:
+
+   % mkdir PARAVISADDONS_BUILD
+
+3. Configure the build procedure:
+
+   % cd PARAVISADDONS_BUILD
+   % cmake -DCMAKE_BUILD_TYPE=<mode> -DCMAKE_INSTALL_PREFIX=<installation_directory> <path_to_src_dir>
+
+   where
+   - <mode> is either Release or Debug (default: Release);
+   - <installation_directory> is a destination folder to install SALOME PARAVISADDONS
+      module (default: /usr); 
+   - <path_to_src_dir> is a path to the PARAVISADDONS sources directory.
+
+
+4. Build and install:
+
+   % make
+   % make install
+
+   This will install SALOME PARAVISADDONS module to the <installation_directory>
+   specified to cmake command on the previous step.
+
+=============
+Documentation
+=============
+
+===============
+Troubleshooting
+===============
+
+Please, send a mail to webmaster.salome@opencascade.com.
diff --git a/doc/README b/doc/README
new file mode 100644 (file)
index 0000000..61b249d
--- /dev/null
@@ -0,0 +1,4 @@
+***********************************
+SALOME PARAVISADDONS Documentation
+***********************************
+
diff --git a/src/AppendAttributesOverTime/CMakeLists.txt b/src/AppendAttributesOverTime/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5c2aab6
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(AppendAttributesOverTime)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/AppendAttributesOverTime/README.md b/src/AppendAttributesOverTime/README.md
new file mode 100644 (file)
index 0000000..74af88c
--- /dev/null
@@ -0,0 +1,8 @@
+Merge TimeSteps Plugin
+======================
+
+Add the filter 'Append Attributes Over Timesteps' (vtkMergeArraysAndTimeSteps)
+that is based on the 'Append Attributes' (vtkMergeArrays) filter. Arrays from each
+timestep from each input are append to the output, with the name
+'originalName_input_#N_ts_#TS' where #N is the input index and #TS is the
+timestep.
diff --git a/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/CMakeLists.txt b/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d6634fc
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkAppendAttributesOverTime
+)
+
+vtk_module_add_module(AppendAttributesOverTimeModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtk.module b/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtk.module
new file mode 100644 (file)
index 0000000..2ddd1e7
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  AppendAttributesOverTimeModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsFiltersGeneral
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.cxx b/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.cxx
new file mode 100644 (file)
index 0000000..4f5a5e0
--- /dev/null
@@ -0,0 +1,223 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkAppendAttributesOverTime.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+#include "vtkAppendAttributesOverTime.h"
+
+#include <vtkCompositeDataIterator.h>
+#include <vtkCompositeDataSet.h>
+#include <vtkDataObject.h>
+#include <vtkDataSet.h>
+#include <vtkFieldData.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkObjectFactory.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+
+vtkStandardNewMacro(vtkAppendAttributesOverTime);
+
+//----------------------------------------------------------------------------
+vtkAppendAttributesOverTime::vtkAppendAttributesOverTime()
+  :RestoreOriginalTimeStep(false)
+{
+}
+
+//----------------------------------------------------------------------------
+namespace
+{
+std::string GetPaddedValue(int value, int maxValue)
+{
+  int padding = 1 + static_cast<int>(log10(maxValue));
+  std::ostringstream os;
+  os << std::setw(padding) << std::setfill('0') << std::to_string(value);
+  return os.str();
+}
+
+//----------------------------------------------------------------------------
+void ResetAttributes(vtkDataObject* obj)
+{
+  vtkCompositeDataSet* cObj = vtkCompositeDataSet::SafeDownCast(obj);
+  if (cObj)
+  {
+    vtkSmartPointer<vtkCompositeDataIterator> iter;
+    iter.TakeReference(cObj->NewIterator());
+    iter->InitTraversal();
+    for (; !iter->IsDoneWithTraversal(); iter->GoToNextItem())
+    {
+      ResetAttributes(vtkDataSet::SafeDownCast(iter->GetCurrentDataObject()));
+    }
+  }
+  else
+  {
+    // reset fields data, so TempDataObject contains only geometry.
+    for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
+    {
+      vtkFieldData *fd = obj->GetAttributesAsFieldData(attr);
+      if (fd != nullptr)
+      {
+        fd->Initialize();
+      }
+    }
+  }
+}
+}
+
+//----------------------------------------------------------------------------
+bool vtkAppendAttributesOverTime::GetOutputArrayName(vtkFieldData* vtkNotUsed(arrays),
+  const char* arrayName, int vtkNotUsed(inputIndex), std::string& outArrayName)
+{
+  std::string inString = ::GetPaddedValue(this->CurrentInputIndex, this->TimeSteps.size());
+  std::string tsString = ::GetPaddedValue(this->UpdateTimeIndex, this->TimeSteps[this->CurrentInputIndex].size());
+  outArrayName = std::string(arrayName) + "_input_" + inString + "_ts_" + tsString;
+  return true;
+}
+
+//----------------------------------------------------------------------------
+int vtkAppendAttributesOverTime::RequestUpdateExtent(vtkInformation* vtkNotUsed(request),
+  vtkInformationVector** inInfo, vtkInformationVector* vtkNotUsed(outInfo))
+{
+  vtkInformation* info = inInfo[0]->GetInformationObject(this->CurrentInputIndex);
+  if (this->RestoreOriginalTimeStep)
+  {
+    info->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), this->OriginalTimeStep);
+  }
+  else
+  {
+    this->OriginalTimeStep = info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
+    info->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(),
+              this->TimeSteps[this->CurrentInputIndex][this->UpdateTimeIndex]);
+  }
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkAppendAttributesOverTime::RequestInformation(vtkInformation* vtkNotUsed(request),
+  vtkInformationVector** inInfo, vtkInformationVector* outInfoVec)
+{
+  this->UpdateTimeIndex = 0;
+  this->CurrentInputIndex = 0;
+  int num = inInfo[0]->GetNumberOfInformationObjects();
+
+  // Fill this->TimeSteps
+  for (int idx = 0; idx < num; idx++)
+  {
+    vtkInformation* info = inInfo[0]->GetInformationObject(idx);
+    int len = info->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    double* timeSteps = info->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    std::vector<double> timeStepsVector;
+    timeStepsVector.resize(len);
+    std::copy(timeSteps, timeSteps + len, timeStepsVector.begin());
+    this->TimeSteps.push_back(timeStepsVector);
+  }
+
+  vtkInformation* outInfo = outInfoVec->GetInformationObject(0);
+  outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+/**
+ * This method calls the Superclass::RequestData to perform the real
+ * merge.
+ * Here we do the following:
+ * - extract a dataset from 2 internal vars: an input index and a timestep index.
+ * (see this->TimeSteps).
+ * - call the Superclass RequestData method with 2 datasets as inputs:
+ * buffer containing previously merged arrays and current dataset to process.
+ * - store the resulting dataset in the buffer
+ * - increment the timestep index. When last timestep of current input was
+ * processed, increment input index and reset timestep index
+ * - loop
+ */
+int vtkAppendAttributesOverTime::RequestData(
+  vtkInformation* request, vtkInformationVector** inInfo, vtkInformationVector* outInfoVec)
+{
+  if (this->RestoreOriginalTimeStep)
+  {
+    this->RestoreOriginalTimeStep = false;
+    request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+    return 1;
+  }
+
+  vtkInformation* info = inInfo[0]->GetInformationObject(this->CurrentInputIndex);
+  vtkInformation* outInfo = outInfoVec->GetInformationObject(0);
+
+  if (this->UpdateTimeIndex == 0 && this->CurrentInputIndex == 0)
+  {
+    // Before looping, we create the temporary output object
+    vtkInformation *inputInfo = inInfo[0]->GetInformationObject(0);
+    vtkDataObject *inputData = vtkDataObject::GetData(inputInfo);
+    this->TempDataObject = vtkSmartPointer<vtkDataObject>::Take(inputData->NewInstance());
+    this->TempDataObject->ShallowCopy(inputData);
+    // Remove all arrays in the ouput
+    ::ResetAttributes(this->TempDataObject);
+  }
+
+  this->CurrentOutInfo->Set(vtkDataObject::DATA_OBJECT(), this->TempDataObject);
+  vtkInformationVector* reducedInputVec = vtkInformationVector::New();
+  reducedInputVec->Append(this->CurrentOutInfo);
+  reducedInputVec->Append(info);
+
+  // perform the effective merge.
+  this->Superclass::RequestData(request, &reducedInputVec, outInfoVec);
+  reducedInputVec->Delete();
+  // save merge result in a buffer.
+  this->TempDataObject->ShallowCopy(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  if (this->UpdateTimeIndex <
+    static_cast<vtkIdType>(this->TimeSteps.at(this->CurrentInputIndex).size()) - 1)
+  {
+    this->UpdateTimeIndex++;
+    request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+  }
+  else if (this->CurrentInputIndex < static_cast<vtkIdType>(this->TimeSteps.size()) - 1)
+  {
+    this->UpdateTimeIndex = 0;
+    this->CurrentInputIndex++;
+    request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+  }
+  else
+  {
+    this->RestoreOriginalTimeStep = true;
+    request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+    vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
+    output->ShallowCopy(this->TempDataObject);
+  }
+
+  return 1;
+}
diff --git a/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.h b/src/AppendAttributesOverTime/plugin/AppendAttributesOverTimeModule/vtkAppendAttributesOverTime.h
new file mode 100644 (file)
index 0000000..0c518a1
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkAppendAttributesOverTime.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkAppendAttributesOverTime
+ * @brief   Multiple inputs with one output.
+ *
+ * vtkAppendAttributesOverTime put all arrays from all inputs into one output,
+ * and this for each timesteps.
+ * The output data object is the same as the first data input, and has no timeteps.
+ * It extends vtkMergeArrays to process every available timestep.
+ * The new arrays will have the name mangled to be the original array name plus
+ * `_input_<inputid>_ts_<tsindex>` where `<inputid>` is the id/index of the input filter
+ * that is providing that array, and `<tsindex>` is the timestep index of corresponing input.
+ */
+
+#ifndef vtkAppendAttributesOverTime_h
+#define vtkAppendAttributesOverTime_h
+
+#include <vtkMergeArrays.h>
+
+#include <vtkInformation.h>
+#include <vtkNew.h>                          // vtkNew
+#include <vtkSmartPointer.h>                 // Smart Pointer
+
+#include <vector>
+
+class vtkFieldData;
+class vtkDataObject;
+
+class VTK_EXPORT vtkAppendAttributesOverTime : public vtkMergeArrays
+{
+public:
+  static vtkAppendAttributesOverTime* New();
+  vtkTypeMacro(vtkAppendAttributesOverTime, vtkMergeArrays);
+
+protected:
+  vtkAppendAttributesOverTime();
+  ~vtkAppendAttributesOverTime() override = default;
+
+  //@{
+  /**
+   * Given an array name, return an appropriate name to use for the output array.
+   * Reimplemented to add original timestep index in the name.
+   * Returns true.
+   */
+  bool GetOutputArrayName(vtkFieldData* arrays, const char* inArrayName, int inputIndex,
+    std::string& outArrayName) override;
+  //@}
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestUpdateExtent(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+private:
+  vtkAppendAttributesOverTime(const vtkAppendAttributesOverTime&) = delete;
+  void operator=(const vtkAppendAttributesOverTime&) = delete;
+
+  int UpdateTimeIndex = 0;
+  int CurrentInputIndex = 0;
+
+  /**
+   * this->TimeSteps contains for each input a vector of timesteps
+   * time = this->TimeSteps[inputIndex][tsIndex]
+   */
+  std::vector<std::vector<double> > TimeSteps;
+  vtkNew<vtkInformation> CurrentOutInfo;
+  vtkSmartPointer<vtkDataObject> TempDataObject;
+  double OriginalTimeStep;
+  bool RestoreOriginalTimeStep;
+};
+
+#endif // vtkAppendAttributesOverTime_h
diff --git a/src/AppendAttributesOverTime/plugin/CMakeLists.txt b/src/AppendAttributesOverTime/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8b085d4
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(AppendAttributesOverTime
+  VERSION "1.0"
+  MODULES AppendAttributesOverTimeModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/AppendAttributesOverTimeModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+install(TARGETS AppendAttributesOverTime
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/AppendAttributesOverTime/plugin/README.md b/src/AppendAttributesOverTime/plugin/README.md
new file mode 100644 (file)
index 0000000..74af88c
--- /dev/null
@@ -0,0 +1,8 @@
+Merge TimeSteps Plugin
+======================
+
+Add the filter 'Append Attributes Over Timesteps' (vtkMergeArraysAndTimeSteps)
+that is based on the 'Append Attributes' (vtkMergeArrays) filter. Arrays from each
+timestep from each input are append to the output, with the name
+'originalName_input_#N_ts_#TS' where #N is the input index and #TS is the
+timestep.
diff --git a/src/AppendAttributesOverTime/plugin/filters.xml b/src/AppendAttributesOverTime/plugin/filters.xml
new file mode 100644 (file)
index 0000000..6332470
--- /dev/null
@@ -0,0 +1,33 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+
+    <SourceProxy class="vtkAppendAttributesOverTime"
+                 label="Append Attributes Over Time"
+                 name="AppendAttributesOverTime">
+      <Documentation long_help="Copies geometry from first input. Puts all of the arrays of each timesteps into the output."
+                     short_help="Puts all input arrays into the single output.">
+        The Append Attributes Over Time filter takes multiple input data
+        sets with the same geometry and merges their attributes to produce
+        a single output containing all these attributes.
+        Any inputs without the same number of points and cells as the first
+        input are ignored.
+        Each array of each timestep of each input is copied to the output.
+        Note that the output is not a temporal dataset.</Documentation>
+      <InputProperty clean_command="RemoveAllInputs"
+                     command="AddInputConnection"
+                     multiple_input="1"
+                     name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain composite_data_supported="1"
+                        name="input_type">
+          <DataType value="vtkDataObject" />
+        </DataTypeDomain>
+        <Documentation>This property specifies the input to the filter.</Documentation>
+      </InputProperty>
+    </SourceProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/AppendAttributesOverTime/plugin/paraview.plugin b/src/AppendAttributesOverTime/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..2e42ade
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  AppendAttributesOverTime
+DESCRIPTION
+  Provides a filter to Append attributes from each timesteps and each inputs
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/AutoConvertPropertiesPlugin/CMakeLists.txt b/src/AutoConvertPropertiesPlugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..346f979
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(AutoConvertPropertiesPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/AutoConvertPropertiesPlugin/plugin/CMakeLists.txt b/src/AutoConvertPropertiesPlugin/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..158f3be
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Create an auto-start plugin. Auto start plugins provide callbacks that get
+# called when the plugin is loaded and when the application shutsdown.
+paraview_plugin_add_auto_start(
+  CLASS_NAME pqAutoConvertPropertiesStarter
+  STARTUP onStartup
+  SHUTDOWN onShutdown
+  INTERFACES autostart_interface
+  SOURCES autostart_sources
+)
+
+# create a plugin for this starter
+paraview_add_plugin(AutoConvertProperties
+  VERSION "1.0"
+  UI_INTERFACES ${autostart_interface}
+  SOURCES ${autostart_sources} pqAutoConvertPropertiesStarter.cxx
+)
+
+target_include_directories(AutoConvertProperties
+  PRIVATE
+    "${CMAKE_CURRENT_BINARY_DIR}")
+
+target_link_libraries(AutoConvertProperties
+  PRIVATE
+    ParaView::pqApplicationComponents
+    ParaView::RemotingServerManager
+)
+
+install(TARGETS AutoConvertProperties
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
+
diff --git a/src/AutoConvertPropertiesPlugin/plugin/paraview.plugin b/src/AutoConvertPropertiesPlugin/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..555e6d6
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  AutoConvertProperties
+DESCRIPTION
+  Plugin that automatically turns some ParaView options at startup.
+CONDITION
+  PARAVIEW_USE_QT
+REQUIRES_MODULES
+  ParaView::RemotingCore
+  ParaView::RemotingServerManager
+  ParaView::pqApplicationComponents
diff --git a/src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.cxx b/src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.cxx
new file mode 100644 (file)
index 0000000..1b07a8c
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    pqAutoConvertPropertiesStarter.cxx
+
+   Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2.
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#include "pqAutoConvertPropertiesStarter.h"
+
+#include <vtkSMSettings.h>
+
+//-----------------------------------------------------------------------------
+pqAutoConvertPropertiesStarter::pqAutoConvertPropertiesStarter(QObject* p)
+  : QObject(p)
+{
+}
+
+//-----------------------------------------------------------------------------
+void pqAutoConvertPropertiesStarter::onStartup()
+{
+  vtkSMSettings* settings = vtkSMSettings::GetInstance();
+  if (!settings->HasSetting(".settings.GeneralSettings.AutoConvertProperties"))
+  {
+    settings->SetSetting("settings.GeneralSettings.AutoConvertProperties", 1);
+  }
+  if (!settings->HasSetting(".settings.GeneralSettings.ShowAnimationShortcuts"))
+  {
+    settings->SetSetting("settings.GeneralSettings.ShowAnimationShortcuts", 1);
+  }
+  if (!settings->HasSetting(".settings.GeneralSettings.ResetDisplayEmptyViews"))
+  {
+    settings->SetSetting("settings.GeneralSettings.ResetDisplayEmptyViews", 0);
+  }
+}
diff --git a/src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.h b/src/AutoConvertPropertiesPlugin/plugin/pqAutoConvertPropertiesStarter.h
new file mode 100644 (file)
index 0000000..7a54167
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    pqAutoConvertPropertiesStarter.h
+
+   Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2.
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#ifndef pqAutoConvertPropertiesStarter_h
+#define pqAutoConvertPropertiesStarter_h
+
+#include <QObject>
+
+class pqAutoConvertPropertiesStarter : public QObject
+{
+  Q_OBJECT
+  typedef QObject Superclass;
+
+public:
+  pqAutoConvertPropertiesStarter(QObject* p = nullptr);
+  ~pqAutoConvertPropertiesStarter() = default;
+
+  // Callback for startup.
+  void onStartup();
+
+  // Callback for shutdown. Does nothing.
+  void onShutdown() {}
+
+private:
+  Q_DISABLE_COPY(pqAutoConvertPropertiesStarter)
+};
+
+#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ad9fc2c
--- /dev/null
@@ -0,0 +1,77 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+INCLUDE(SalomeSetupPlatform)
+
+FOREACH(_Qt5_COMPONENT_ ${Qt5_FIND_COMPONENTS} ${Qt5_OPTIONAL_COMPONENTS})
+  SET(_Qt5_COMPONENT Qt5${_Qt5_COMPONENT_})
+  LIST(FIND Qt5_OPTIONAL_COMPONENTS ${_Qt5_COMPONENT_} idx)
+  IF(${idx} GREATER -1)
+    SET(Salome${_Qt5_COMPONENT}_FIND_QUIETLY TRUE)
+  ENDIF()
+  FIND_PACKAGE(${_Qt5_COMPONENT})
+  LIST(APPEND QT_INCLUDES    ${${_Qt5_COMPONENT}_INCLUDE_DIRS})
+  LIST(APPEND QT_DEFINITIONS ${${_Qt5_COMPONENT}_DEFINITIONS})
+  LIST(APPEND QT_LIBRARIES   ${${_Qt5_COMPONENT}_LIBRARIES})
+ENDFOREACH()
+
+ENABLE_TESTING()
+
+ADD_SUBDIRECTORY(MoveZCote)
+ADD_SUBDIRECTORY(ComplexMode)
+ADD_SUBDIRECTORY(QuadraticToLinear)
+ADD_SUBDIRECTORY(ExtractComponentsPlugin)
+ADD_SUBDIRECTORY(ZJFilter)
+ADD_SUBDIRECTORY(SerafinReader)
+ADD_SUBDIRECTORY(SpatialPfl)
+ADD_SUBDIRECTORY(SinusXReader)
+ADD_SUBDIRECTORY(TemporalOnPoint)
+ADD_SUBDIRECTORY(DepthVsTime)
+ADD_SUBDIRECTORY(SphereAlongLines)
+ADD_SUBDIRECTORY(RateOfFlowThroughSection)
+ADD_SUBDIRECTORY(ProbePointOverTime)
+ADD_SUBDIRECTORY(CustomFilters)
+ADD_SUBDIRECTORY(CellDataContour)
+ADD_SUBDIRECTORY(AutoConvertPropertiesPlugin)
+ADD_SUBDIRECTORY(AppendAttributesOverTime)
+ADD_SUBDIRECTORY(ExtractThreeD)
+ADD_SUBDIRECTORY(ContactReader)
+ADD_SUBDIRECTORY(TorseurCIH)
+ADD_SUBDIRECTORY(RosetteCIH)
+ADD_SUBDIRECTORY(XYChartRepresentationColumns)
+ADD_SUBDIRECTORY(GlyphCIH) # EDF15785
+ADD_SUBDIRECTORY(ElectromagnetismVecteur)
+ADD_SUBDIRECTORY(ElectromagnetismStreamTraceur)
+ADD_SUBDIRECTORY(ElectromagnetismFluxDisc)
+
+IF(NOT WIN32)
+  # still being under investigations
+  MESSAGE(WARNING "ElectromagnetismRotation will be skipped")
+  ADD_SUBDIRECTORY(ElectromagnetismRotation)
+ENDIF(NOT WIN32)
diff --git a/src/CellDataContour/CMakeLists.txt b/src/CellDataContour/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6e4ce35
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(MyContour)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/CellDataContour/plugin/CMakeLists.txt b/src/CellDataContour/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..85cdacb
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(MyContour
+  VERSION "1.0"
+  MODULES CellDataContourModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/CellDataContourModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS MyContour
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/CellDataContour/plugin/CellDataContourModule/CMakeLists.txt b/src/CellDataContour/plugin/CellDataContourModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a8427ea
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkMyCellDataToPointData
+  vtkMyContourFilter
+  vtkMyPVContourFilter
+)
+
+vtk_module_add_module(CellDataContourModule
+  FORCE_STATIC
+  CLASSES ${classes}
+  )
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtk.module b/src/CellDataContour/plugin/CellDataContourModule/vtk.module
new file mode 100644 (file)
index 0000000..b9210a2
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  CellDataContourModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsAMR
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.cxx b/src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.cxx
new file mode 100644 (file)
index 0000000..c690deb
--- /dev/null
@@ -0,0 +1,610 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyCellDataToPointData.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notice for more information.
+
+  =========================================================================*/
+#include "vtkMyCellDataToPointData.h"
+
+#include <vtkArrayDispatch.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkDataArrayRange.h>
+#include <vtkDataSet.h>
+#include <vtkIdList.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkSmartPointer.h>
+#include <vtkStructuredGrid.h>
+#include <vtkUniformGrid.h>
+#include <vtkUnsignedIntArray.h>
+
+#include <algorithm>
+#include <functional>
+#include <set>
+
+#define VTK_MAX_CELLS_PER_POINT 4096
+
+vtkStandardNewMacro(vtkMyCellDataToPointData);
+
+namespace
+{
+
+//----------------------------------------------------------------------------
+// Helper template function that implement the major part of the algorighm
+// which will be expanded by the vtkTemplateMacro. The template function is
+// provided so that coverage test can cover this function.
+struct Spread
+{
+  template <typename SrcArrayT, typename DstArrayT>
+  void operator()(SrcArrayT *const srcarray, DstArrayT *const dstarray,
+                  vtkDataSet *const src, vtkUnsignedIntArray *const num,
+                  vtkIdType ncells, vtkIdType npoints, vtkIdType ncomps,
+                  int highestCellDimension, int contributingCellOption) const
+  {
+    // Both arrays will have the same value type:
+    using T = vtk::GetAPIType<SrcArrayT>;
+
+    // zero initialization
+    std::fill_n(vtk::DataArrayValueRange(dstarray).begin(),
+                npoints * ncomps, T(0));
+
+    const auto srcTuples = vtk::DataArrayTupleRange(srcarray);
+    auto dstTuples = vtk::DataArrayTupleRange(dstarray);
+
+    // accumulate
+    if (contributingCellOption != vtkMyCellDataToPointData::Patch)
+    {
+      for (vtkIdType cid = 0; cid < ncells; ++cid)
+      {
+        vtkCell *cell = src->GetCell(cid);
+        if (cell->GetCellDimension() >= highestCellDimension)
+        {
+          const auto srcTuple = srcTuples[cid];
+          vtkIdList *pids = cell->GetPointIds();
+          for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
+          {
+            const vtkIdType ptId = pids->GetId(i);
+            auto dstTuple = dstTuples[ptId];
+            // accumulate cell data to point data <==> point_data += cell_data
+            std::transform(srcTuple.cbegin(),
+                           srcTuple.cend(),
+                           dstTuple.cbegin(),
+                           dstTuple.begin(),
+                           std::plus<T>());
+          }
+        }
+      }
+      // average
+      for (vtkIdType pid = 0; pid < npoints; ++pid)
+      {
+        // guard against divide by zero
+        if (unsigned int const denom = num->GetValue(pid))
+        {
+          // divide point data by the number of cells using it <==>
+          // point_data /= denum
+          auto dstTuple = dstTuples[pid];
+          std::transform(dstTuple.cbegin(),
+                         dstTuple.cend(),
+                         dstTuple.begin(),
+                         std::bind(std::divides<T>(), std::placeholders::_1, denom));
+        }
+      }
+    }
+    else
+    { // compute over cell patches
+      vtkNew<vtkIdList> cellsOnPoint;
+      std::vector<T> data(4 * ncomps);
+      for (vtkIdType pid = 0; pid < npoints; ++pid)
+      {
+        std::fill(data.begin(), data.end(), 0);
+        T numPointCells[4] = {0, 0, 0, 0};
+        // Get all cells touching this point.
+        src->GetPointCells(pid, cellsOnPoint);
+        vtkIdType numPatchCells = cellsOnPoint->GetNumberOfIds();
+        for (vtkIdType pc = 0; pc < numPatchCells; pc++)
+        {
+          vtkIdType cellId = cellsOnPoint->GetId(pc);
+          int cellDimension = src->GetCell(cellId)->GetCellDimension();
+          numPointCells[cellDimension] += 1;
+          const auto srcTuple = srcTuples[cellId];
+          for (int comp = 0; comp < ncomps; comp++)
+          {
+            data[comp + ncomps * cellDimension] += srcTuple[comp];
+          }
+        }
+        auto dstTuple = dstTuples[pid];
+        for (int dimension = 3; dimension >= 0; dimension--)
+        {
+          if (numPointCells[dimension])
+          {
+            for (int comp = 0; comp < ncomps; comp++)
+            {
+              dstTuple[comp] = data[comp + dimension * ncomps] / numPointCells[dimension];
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+};
+
+} // end anonymous namespace
+
+class vtkMyCellDataToPointData::Internals
+{
+public:
+  std::set<std::string> CellDataArrays;
+
+  // Special traversal algorithm for vtkUniformGrid and vtkRectilinearGrid to support blanking
+  // points will not have more than 8 cells for either of these data sets
+  template <typename T>
+  int InterpolatePointDataWithMask(vtkMyCellDataToPointData *filter, T *input, vtkDataSet *output)
+  {
+    vtkNew<vtkIdList> allCellIds;
+    allCellIds->Allocate(8);
+    vtkNew<vtkIdList> cellIds;
+    cellIds->Allocate(8);
+
+    vtkIdType numPts = input->GetNumberOfPoints();
+
+    vtkCellData *inputInCD = input->GetCellData();
+    vtkCellData *inCD;
+    vtkPointData *outPD = output->GetPointData();
+
+    if (!filter->GetProcessAllArrays())
+    {
+      inCD = vtkCellData::New();
+
+      for (const auto &name : this->CellDataArrays)
+      {
+        vtkAbstractArray *arr = inputInCD->GetAbstractArray(name.c_str());
+        if (arr == nullptr)
+        {
+          vtkWarningWithObjectMacro(filter, "cell data array name not found.");
+          continue;
+        }
+        inCD->AddArray(arr);
+      }
+    }
+    else
+    {
+      inCD = inputInCD;
+    }
+
+    outPD->InterpolateAllocate(inCD, numPts);
+
+    double weights[8];
+
+    int abort = 0;
+    vtkIdType progressInterval = numPts / 20 + 1;
+    for (vtkIdType ptId = 0; ptId < numPts && !abort; ptId++)
+    {
+      if (!(ptId % progressInterval))
+      {
+        filter->UpdateProgress(static_cast<double>(ptId) / numPts);
+        abort = filter->GetAbortExecute();
+      }
+      input->GetPointCells(ptId, allCellIds);
+      cellIds->Reset();
+      // Only consider cells that are not masked:
+      for (vtkIdType cId = 0; cId < allCellIds->GetNumberOfIds(); ++cId)
+      {
+        vtkIdType curCell = allCellIds->GetId(cId);
+        if (input->IsCellVisible(curCell))
+        {
+          cellIds->InsertNextId(curCell);
+        }
+      }
+
+      vtkIdType numCells = cellIds->GetNumberOfIds();
+
+      if (numCells > 0)
+      {
+        double weight = 1.0 / numCells;
+        for (vtkIdType cellId = 0; cellId < numCells; cellId++)
+        {
+          weights[cellId] = weight;
+        }
+        outPD->InterpolatePoint(inCD, ptId, cellIds, weights);
+      }
+      else
+      {
+        outPD->NullPoint(ptId);
+      }
+    }
+
+    if (!filter->GetProcessAllArrays())
+    {
+      inCD->Delete();
+    }
+
+    return 1;
+  }
+};
+
+//----------------------------------------------------------------------------
+// Instantiate object so that cell data is not passed to output.
+vtkMyCellDataToPointData::vtkMyCellDataToPointData()
+{
+  this->PassCellData = 0;
+  this->ContributingCellOption = vtkMyCellDataToPointData::All;
+  this->ProcessAllArrays = true;
+  this->Implementation = new Internals();
+}
+
+//----------------------------------------------------------------------------
+vtkMyCellDataToPointData::~vtkMyCellDataToPointData()
+{
+  delete this->Implementation;
+}
+
+//----------------------------------------------------------------------------
+void vtkMyCellDataToPointData::AddCellDataArray(const char *name)
+{
+  if (!name)
+  {
+    vtkErrorMacro("name cannot be null.");
+    return;
+  }
+
+  this->Implementation->CellDataArrays.insert(std::string(name));
+  this->Modified();
+}
+
+//----------------------------------------------------------------------------
+void vtkMyCellDataToPointData::RemoveCellDataArray(const char *name)
+{
+  if (!name)
+  {
+    vtkErrorMacro("name cannot be null.");
+    return;
+  }
+
+  this->Implementation->CellDataArrays.erase(name);
+  this->Modified();
+}
+
+//----------------------------------------------------------------------------
+void vtkMyCellDataToPointData::ClearCellDataArrays()
+{
+  if (!this->Implementation->CellDataArrays.empty())
+  {
+    this->Modified();
+  }
+  this->Implementation->CellDataArrays.clear();
+}
+
+//----------------------------------------------------------------------------
+int vtkMyCellDataToPointData::RequestData(
+    vtkInformation *, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkInformation *info = outputVector->GetInformationObject(0);
+  vtkDataSet *output = vtkDataSet::SafeDownCast(info->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkDataSet *input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkDebugMacro(<< "Mapping cell data to point data");
+
+  // Special traversal algorithm for unstructured grid
+  if (input->IsA("vtkUnstructuredGrid") || input->IsA("vtkPolyData"))
+  {
+    return this->RequestDataForUnstructuredData(nullptr, inputVector, outputVector);
+  }
+
+  vtkDebugMacro(<< "Mapping cell data to point data");
+
+  // First, copy the input to the output as a starting point
+  output->CopyStructure(input);
+
+  // Pass the point data first. The fields and attributes
+  // which also exist in the cell data of the input will
+  // be over-written during CopyAllocate
+  output->GetPointData()->CopyGlobalIdsOff();
+  output->GetPointData()->PassData(input->GetPointData());
+  output->GetPointData()->CopyFieldOff(vtkDataSetAttributes::GhostArrayName());
+
+  if (input->GetNumberOfPoints() < 1)
+  {
+    vtkDebugMacro(<< "No input point data!");
+    return 1;
+  }
+
+  // Do the interpolation, taking care of masked cells if needed.
+  vtkStructuredGrid *sGrid = vtkStructuredGrid::SafeDownCast(input);
+  vtkUniformGrid *uniformGrid = vtkUniformGrid::SafeDownCast(input);
+  int result;
+  if (sGrid && sGrid->HasAnyBlankCells())
+  {
+    result = this->Implementation->InterpolatePointDataWithMask(this, sGrid, output);
+  }
+  else if (uniformGrid && uniformGrid->HasAnyBlankCells())
+  {
+    result = this->Implementation->InterpolatePointDataWithMask(this, uniformGrid, output);
+  }
+  else
+  {
+    result = this->InterpolatePointData(input, output);
+  }
+
+  if (result == 0)
+  {
+    return 0;
+  }
+
+  if (!this->PassCellData)
+  {
+    output->GetCellData()->CopyAllOff();
+    output->GetCellData()->CopyFieldOn(vtkDataSetAttributes::GhostArrayName());
+  }
+  output->GetCellData()->PassData(input->GetCellData());
+  output->GetFieldData()->PassData(input->GetFieldData());
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkMyCellDataToPointData::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+
+  os << indent << "PassCellData: " << (this->PassCellData ? "On\n" : "Off\n");
+  os << indent << "ContributingCellOption: " << this->ContributingCellOption << endl;
+}
+
+//----------------------------------------------------------------------------
+int vtkMyCellDataToPointData::RequestDataForUnstructuredData(
+    vtkInformation *, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkDataSet *const src = vtkDataSet::SafeDownCast(
+      inputVector[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
+  vtkDataSet *const dst = vtkDataSet::SafeDownCast(
+      outputVector->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkIdType const ncells = src->GetNumberOfCells();
+  vtkIdType const npoints = src->GetNumberOfPoints();
+  if (ncells < 1 || npoints < 1)
+  {
+    vtkDebugMacro(<< "No input data!");
+    return 1;
+  }
+
+  // count the number of cells associated with each point. if we are doing patches
+  // though we will do that later on.
+  vtkSmartPointer<vtkUnsignedIntArray> num;
+  int highestCellDimension = 0;
+  if (this->ContributingCellOption != vtkMyCellDataToPointData::Patch)
+  {
+    num = vtkSmartPointer<vtkUnsignedIntArray>::New();
+    num->SetNumberOfComponents(1);
+    num->SetNumberOfTuples(npoints);
+    std::fill_n(num->GetPointer(0), npoints, 0u);
+    if (this->ContributingCellOption == vtkMyCellDataToPointData::DataSetMax)
+    {
+      int maxDimension = src->IsA("vtkPolyData") == 1 ? 2 : 3;
+      for (vtkIdType i = 0; i < src->GetNumberOfCells(); i++)
+      {
+        int dim = src->GetCell(i)->GetCellDimension();
+        if (dim > highestCellDimension)
+        {
+          highestCellDimension = dim;
+          if (highestCellDimension == maxDimension)
+          {
+            break;
+          }
+        }
+      }
+    }
+    vtkNew<vtkIdList> pids;
+    for (vtkIdType cid = 0; cid < ncells; ++cid)
+    {
+      if (src->GetCell(cid)->GetCellDimension() >= highestCellDimension)
+      {
+        src->GetCellPoints(cid, pids);
+        for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
+        {
+          vtkIdType const pid = pids->GetId(i);
+          num->SetValue(pid, num->GetValue(pid) + 1);
+        }
+      }
+    }
+  }
+
+  // First, copy the input to the output as a starting point
+  dst->CopyStructure(src);
+  vtkPointData *const opd = dst->GetPointData();
+
+  // Pass the point data first. The fields and attributes
+  // which also exist in the cell data of the input will
+  // be over-written during CopyAllocate
+  opd->CopyGlobalIdsOff();
+  opd->PassData(src->GetPointData());
+  opd->CopyFieldOff(vtkDataSetAttributes::GhostArrayName());
+
+  // Copy all existing cell fields into a temporary cell data array,
+  // unless the SelectCellDataArrays option is active
+  vtkSmartPointer<vtkCellData> processedCellData;
+  if (!this->ProcessAllArrays)
+  {
+    processedCellData = vtkSmartPointer<vtkCellData>::New();
+
+    vtkCellData *processedCellDataTemp = src->GetCellData();
+    for (const auto &name : this->Implementation->CellDataArrays)
+    {
+      vtkAbstractArray *arr = processedCellDataTemp->GetAbstractArray(name.c_str());
+      if (arr == nullptr)
+      {
+        vtkWarningMacro("cell data array name not found.");
+        continue;
+      }
+      processedCellData->AddArray(arr);
+    }
+  }
+  else
+  {
+    processedCellData = vtkSmartPointer<vtkCellData>(src->GetCellData());
+  }
+
+  // Remove all fields that are not a data array.
+  for (vtkIdType fid = processedCellData->GetNumberOfArrays(); fid--;)
+  {
+    if (!vtkDataArray::FastDownCast(processedCellData->GetAbstractArray(fid)))
+    {
+      processedCellData->RemoveArray(fid);
+    }
+  }
+
+  // Cell field list constructed from the filtered cell data array
+  vtkDataSetAttributes::FieldList cfl(1);
+  cfl.InitializeFieldList(processedCellData);
+  opd->InterpolateAllocate(cfl, npoints, npoints);
+
+  const auto nfields = processedCellData->GetNumberOfArrays();
+  int fid = 0;
+  auto f = [this, &fid, nfields, npoints, src, num, ncells, highestCellDimension](
+               vtkAbstractArray *aa_srcarray, vtkAbstractArray *aa_dstarray) {
+    // update progress and check for an abort request.
+    this->UpdateProgress((fid + 1.0) / nfields);
+    ++fid;
+
+    if (this->GetAbortExecute())
+    {
+      return;
+    }
+
+    vtkDataArray *const srcarray = vtkDataArray::FastDownCast(aa_srcarray);
+    vtkDataArray *const dstarray = vtkDataArray::FastDownCast(aa_dstarray);
+    if (srcarray && dstarray)
+    {
+      dstarray->SetNumberOfTuples(npoints);
+      vtkIdType const ncomps = srcarray->GetNumberOfComponents();
+
+      Spread worker;
+      using Dispatcher = vtkArrayDispatch::Dispatch2SameValueType;
+      if (!Dispatcher::Execute(srcarray, dstarray, worker, src, num,
+                               ncells, npoints, ncomps, highestCellDimension,
+                               this->ContributingCellOption))
+      { // fallback for unknown arrays:
+        worker(srcarray, dstarray, src, num, ncells, npoints, ncomps,
+               highestCellDimension, this->ContributingCellOption);
+      }
+    }
+  };
+
+  if (processedCellData != nullptr && dst->GetPointData() != nullptr)
+  {
+    cfl.TransformData(0, processedCellData, dst->GetPointData(), f);
+  }
+
+  if (!this->PassCellData)
+  {
+    dst->GetCellData()->CopyAllOff();
+    dst->GetCellData()->CopyFieldOn(vtkDataSetAttributes::GhostArrayName());
+  }
+  dst->GetCellData()->PassData(src->GetCellData());
+
+  return 1;
+}
+
+int vtkMyCellDataToPointData::InterpolatePointData(vtkDataSet *input, vtkDataSet *output)
+{
+  vtkNew<vtkIdList> cellIds;
+  cellIds->Allocate(VTK_MAX_CELLS_PER_POINT);
+
+  vtkIdType numPts = input->GetNumberOfPoints();
+
+  vtkCellData *inputInCD = input->GetCellData();
+  vtkCellData *inCD;
+  vtkPointData *outPD = output->GetPointData();
+
+  if (!this->ProcessAllArrays)
+  {
+    inCD = vtkCellData::New();
+
+    for (const auto &name : this->Implementation->CellDataArrays)
+    {
+      vtkAbstractArray *arr = inputInCD->GetAbstractArray(name.c_str());
+      if (arr == nullptr)
+      {
+        vtkWarningMacro("cell data array name not found.");
+        continue;
+      }
+      inCD->AddArray(arr);
+    }
+  }
+  else
+  {
+    inCD = inputInCD;
+  }
+
+  outPD->InterpolateAllocate(inCD, numPts);
+
+  double weights[VTK_MAX_CELLS_PER_POINT];
+
+  int abort = 0;
+  vtkIdType progressInterval = numPts / 20 + 1;
+  for (vtkIdType ptId = 0; ptId < numPts && !abort; ptId++)
+  {
+    if (!(ptId % progressInterval))
+    {
+      this->UpdateProgress(static_cast<double>(ptId) / numPts);
+      abort = GetAbortExecute();
+    }
+
+    input->GetPointCells(ptId, cellIds);
+    vtkIdType numCells = cellIds->GetNumberOfIds();
+
+    if (numCells > 0 && numCells < VTK_MAX_CELLS_PER_POINT)
+    {
+      double weight = 1.0 / numCells;
+      for (vtkIdType cellId = 0; cellId < numCells; cellId++)
+      {
+        weights[cellId] = weight;
+      }
+      outPD->InterpolatePoint(inCD, ptId, cellIds, weights);
+    }
+    else
+    {
+      outPD->NullPoint(ptId);
+    }
+  }
+
+  if (!this->ProcessAllArrays)
+  {
+    inCD->Delete();
+  }
+
+  return 1;
+}
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.h b/src/CellDataContour/plugin/CellDataContourModule/vtkMyCellDataToPointData.h
new file mode 100644 (file)
index 0000000..cb008e7
--- /dev/null
@@ -0,0 +1,182 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyCellDataToPointData.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkMyCellDataToPointData
+ * @brief   map cell data to point data
+ *
+ * vtkMyCellDataToPointData is a filter that transforms cell data (i.e., data
+ * specified per cell) into point data (i.e., data specified at cell
+ * points). The method of transformation is based on averaging the data
+ * values of all cells using a particular point. For large datasets with
+ * several cell data arrays, the filter optionally supports selective
+ * processing to speed up processing. Optionally, the input cell data can
+ * be passed through to the output as well.
+ * Unstructured grids and polydata can have cells of different dimensions.
+ * To handle different use cases in this situation, the user can specify
+ * which cells contribute to the computation. The options for this are
+ * All (default), Patch and DataSetMax. Patch uses only the highest dimension
+ * cells attached to a point. DataSetMax uses the highest cell dimension in
+ * the entire data set.
+ *
+ * @warning
+ * This filter is an abstract filter, that is, the output is an abstract type
+ * (i.e., vtkDataSet). Use the convenience methods (e.g.,
+ * GetPolyDataOutput(), GetStructuredPointsOutput(), etc.) to get the type
+ * of output you want.
+ *
+ * @sa
+ * vtkPointData vtkCellData vtkPointDataToCellData
+*/
+
+#ifndef vtkMyCellDataToPointData_h
+#define vtkMyCellDataToPointData_h
+
+#include <vtkDataSetAlgorithm.h>
+
+class vtkDataSet;
+
+class VTK_EXPORT vtkMyCellDataToPointData : public vtkDataSetAlgorithm
+{
+public:
+  static vtkMyCellDataToPointData *New();
+  vtkTypeMacro(vtkMyCellDataToPointData,vtkDataSetAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  /// Options to choose what cells contribute to the calculation
+  enum ContributingCellEnum {
+    All=0,        //!< All cells
+    Patch=1,      //!< Highest dimension cells in the patch of cells contributing to the calculation
+    DataSetMax=2  //!< Highest dimension cells in the data set
+  };
+
+  //@{
+  /**
+   * Control whether the input cell data is to be passed to the output. If
+   * on, then the input cell data is passed through to the output; otherwise,
+   * only generated point data is placed into the output.
+   */
+  vtkSetMacro(PassCellData, bool);
+  vtkGetMacro(PassCellData, bool);
+  vtkBooleanMacro(PassCellData, bool);
+  //@}
+
+  //@{
+  /**
+   * Option to specify what cells to include in the gradient computation.
+   * Options are all cells (All, Patch and DataSetMax). The default is All.
+   */
+  vtkSetClampMacro(ContributingCellOption, int, 0, 2);
+  vtkGetMacro(ContributingCellOption, int);
+  //@}
+
+  //@{
+  /**
+   * Activate selective processing of arrays. If inactive, only arrays selected
+   * by the user will be considered by this filter. The default is true.
+   */
+  vtkSetMacro(ProcessAllArrays, bool);
+  vtkGetMacro(ProcessAllArrays, bool);
+  vtkBooleanMacro(ProcessAllArrays, bool);
+  //@}
+
+  /**
+   * Adds an array to be processed. This only has an effect if the
+   * ProcessAllArrays option is turned off. If a name is already present,
+   * nothing happens.
+   */
+  virtual void AddCellDataArray(const char *name);
+
+  /**
+   * Removes an array to be processed. This only has an effect if the
+   * ProcessAllArrays option is turned off. If the specified name is not
+   * present, nothing happens.
+   */
+  virtual void RemoveCellDataArray(const char *name);
+
+  /**
+   * Removes all arrays to be processed from the list. This only has an effect
+   * if the ProcessAllArrays option is turned off.
+   */
+  virtual void ClearCellDataArrays();
+
+protected:
+  vtkMyCellDataToPointData();
+  ~vtkMyCellDataToPointData() override;
+
+  int RequestData(vtkInformation* request,
+                  vtkInformationVector** inputVector,
+                  vtkInformationVector* outputVector) override;
+
+  //@{
+  /**
+   * Special algorithm for unstructured grids and polydata to make sure
+   * that we properly take into account ContributingCellOption.
+   */
+  int RequestDataForUnstructuredData
+    (vtkInformation*, vtkInformationVector**, vtkInformationVector*);
+  //@}
+
+  int InterpolatePointData(vtkDataSet *input, vtkDataSet *output);
+
+  //@{
+  /**
+   * Option to pass cell data arrays through to the output. Default is 0/off.
+   */
+  bool PassCellData;
+  //@}
+
+  //@{
+  /**
+   * Option to specify what cells to include in the computation.
+   * Options are all cells (All, Patch and DataSet). The default is All.
+   */
+  int ContributingCellOption;
+  //@}
+
+  /**
+   * Option to activate selective processing of arrays.
+   */
+  bool ProcessAllArrays;
+
+  class Internals;
+  Internals *Implementation;
+
+private:
+  vtkMyCellDataToPointData(const vtkMyCellDataToPointData&) = delete;
+  void operator=(const vtkMyCellDataToPointData&) = delete;
+};
+
+#endif
+
+
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.cxx b/src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.cxx
new file mode 100644 (file)
index 0000000..7484f77
--- /dev/null
@@ -0,0 +1,855 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyContourFilter.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+#include "vtkMyContourFilter.h"
+
+#include <vtkCallbackCommand.h>
+#include <vtkCell.h>
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkContourGrid.h>
+#include <vtkContourHelper.h>
+#include <vtkContourValues.h>
+#include <vtkCutter.h>
+#include <vtkGarbageCollector.h>
+#include <vtkGenericCell.h>
+#include <vtkGridSynchronizedTemplates3D.h>
+#include <vtkImageData.h>
+#include <vtkIncrementalPointLocator.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkMergePoints.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkRectilinearGrid.h>
+#include <vtkRectilinearSynchronizedTemplates.h>
+#include <vtkSpanSpace.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStructuredGrid.h>
+#include <vtkSynchronizedTemplates2D.h>
+#include <vtkSynchronizedTemplates3D.h>
+#include <vtkTimerLog.h>
+#include <vtkUniformGrid.h>
+
+#include <cmath>
+
+vtkStandardNewMacro(vtkMyContourFilter);
+vtkCxxSetObjectMacro(vtkMyContourFilter,ScalarTree,vtkScalarTree);
+
+//-----------------------------------------------------------------------------
+// Construct object with initial range (0,1) and single contour value
+// of 0.0.
+vtkMyContourFilter::vtkMyContourFilter()
+{
+  this->ContourValues = vtkContourValues::New();
+
+  // -1 == uninitialized. This is so we know if ComputeNormals has been set
+  // by the user, so that we can preserve old (broken) behavior that ignored
+  // this setting for certain dataset types.
+  this->ComputeNormals = -1;
+  this->ComputeGradients = 0;
+  this->ComputeScalars = 1;
+
+  this->Locator = nullptr;
+
+  this->UseScalarTree = 0;
+  this->ScalarTree = nullptr;
+
+  this->OutputPointsPrecision = DEFAULT_PRECISION;
+
+  this->GenerateTriangles = 1;
+
+  this->SynchronizedTemplates2D = vtkSynchronizedTemplates2D::New();
+  this->SynchronizedTemplates3D = vtkSynchronizedTemplates3D::New();
+  this->GridSynchronizedTemplates = vtkGridSynchronizedTemplates3D::New();
+  this->RectilinearSynchronizedTemplates = vtkRectilinearSynchronizedTemplates::New();
+
+  this->InternalProgressCallbackCommand = vtkCallbackCommand::New();
+  this->InternalProgressCallbackCommand->SetCallback(
+    &vtkMyContourFilter::InternalProgressCallbackFunction);
+  this->InternalProgressCallbackCommand->SetClientData(this);
+
+  this->SynchronizedTemplates2D->AddObserver(vtkCommand::ProgressEvent,
+                                             this->InternalProgressCallbackCommand);
+  this->SynchronizedTemplates3D->AddObserver(vtkCommand::ProgressEvent,
+                                             this->InternalProgressCallbackCommand);
+  this->GridSynchronizedTemplates->AddObserver(vtkCommand::ProgressEvent,
+                                               this->InternalProgressCallbackCommand);
+  this->RectilinearSynchronizedTemplates->AddObserver(vtkCommand::ProgressEvent,
+                                                      this->InternalProgressCallbackCommand);
+
+  // by default process active point scalars
+  this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
+                               vtkDataSetAttributes::SCALARS);
+}
+
+//-----------------------------------------------------------------------------
+vtkMyContourFilter::~vtkMyContourFilter()
+{
+  this->ContourValues->Delete();
+  if ( this->Locator )
+  {
+    this->Locator->UnRegister(this);
+    this->Locator = nullptr;
+  }
+  if ( this->ScalarTree )
+  {
+    this->ScalarTree->Delete();
+    this->ScalarTree = nullptr;
+  }
+  this->SynchronizedTemplates2D->Delete();
+  this->SynchronizedTemplates3D->Delete();
+  this->GridSynchronizedTemplates->Delete();
+  this->RectilinearSynchronizedTemplates->Delete();
+  this->InternalProgressCallbackCommand->Delete();
+}
+
+//-----------------------------------------------------------------------------
+// Overload standard modified time function. If contour values are modified,
+// then this object is modified as well.
+vtkMTimeType vtkMyContourFilter::GetMTime()
+{
+  vtkMTimeType mTime=this->Superclass::GetMTime();
+  vtkMTimeType time;
+
+  if (this->ContourValues)
+  {
+    time = this->ContourValues->GetMTime();
+    mTime = ( time > mTime ? time : mTime );
+  }
+  if (this->Locator)
+  {
+    time = this->Locator->GetMTime();
+    mTime = ( time > mTime ? time : mTime );
+  }
+
+  return mTime;
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyContourFilter::RequestUpdateExtent(vtkInformation* request,
+                                          vtkInformationVector** inputVector,
+                                          vtkInformationVector* outputVector)
+{
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  vtkDataSet *input =
+    vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  int numContours=this->ContourValues->GetNumberOfContours();
+  double *values=this->ContourValues->GetValues();
+
+  vtkInformation *fInfo =
+    vtkDataObject::GetActiveFieldInformation(inInfo,
+                                             vtkDataObject::FIELD_ASSOCIATION_POINTS,
+                                             vtkDataSetAttributes::SCALARS);
+  int sType = VTK_DOUBLE;
+  if (fInfo)
+  {
+    sType = fInfo->Get(vtkDataObject::FIELD_ARRAY_TYPE());
+  }
+
+  // handle 2D images
+  int i;
+  if (vtkImageData::SafeDownCast(input) && sType != VTK_BIT &&
+      !vtkUniformGrid::SafeDownCast(input))
+  {
+    int dim = 3;
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    if (uExt[0] == uExt[1])
+    {
+      --dim;
+    }
+    if (uExt[2] == uExt[3])
+    {
+      --dim;
+    }
+    if (uExt[4] == uExt[5])
+    {
+      --dim;
+    }
+
+    if ( dim == 2 )
+    {
+      this->SynchronizedTemplates2D->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->SynchronizedTemplates2D->SetValue(i,values[i]);
+      }
+      this->SynchronizedTemplates2D->SetComputeScalars(this->ComputeScalars);
+      return this->SynchronizedTemplates2D->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+    else if (dim == 3)
+    {
+      this->SynchronizedTemplates3D->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->SynchronizedTemplates3D->SetValue(i,values[i]);
+      }
+      this->SynchronizedTemplates3D->SetComputeNormals(this->ComputeNormals);
+      this->SynchronizedTemplates3D->SetComputeGradients(this->ComputeGradients);
+      this->SynchronizedTemplates3D->SetComputeScalars(this->ComputeScalars);
+      this->SynchronizedTemplates3D->SetGenerateTriangles(this->GenerateTriangles);
+      return this->SynchronizedTemplates3D->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+  } //if image data
+
+  // handle 3D RGrids
+  if (vtkRectilinearGrid::SafeDownCast(input) && sType != VTK_BIT)
+  {
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    // if 3D
+    if (uExt[0] < uExt[1] && uExt[2] < uExt[3] && uExt[4] < uExt[5])
+    {
+      this->RectilinearSynchronizedTemplates->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->RectilinearSynchronizedTemplates->SetValue(i,values[i]);
+      }
+      this->RectilinearSynchronizedTemplates->SetComputeNormals(this->ComputeNormals);
+      this->RectilinearSynchronizedTemplates->SetComputeGradients(this->ComputeGradients);
+      this->RectilinearSynchronizedTemplates->SetComputeScalars(this->ComputeScalars);
+      this->RectilinearSynchronizedTemplates->SetGenerateTriangles(this->GenerateTriangles);
+      return this->RectilinearSynchronizedTemplates->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+  } //if 3D RGrid
+
+  // handle 3D SGrids
+  if (vtkStructuredGrid::SafeDownCast(input) && sType != VTK_BIT)
+  {
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    // if 3D
+    if (uExt[0] < uExt[1] && uExt[2] < uExt[3] && uExt[4] < uExt[5])
+    {
+      this->GridSynchronizedTemplates->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->GridSynchronizedTemplates->SetValue(i,values[i]);
+      }
+      this->GridSynchronizedTemplates->SetComputeNormals(this->ComputeNormals);
+      this->GridSynchronizedTemplates->SetComputeGradients(this->ComputeGradients);
+      this->GridSynchronizedTemplates->SetComputeScalars(this->ComputeScalars);
+      this->GridSynchronizedTemplates->SetOutputPointsPrecision(this->OutputPointsPrecision);
+      this->GridSynchronizedTemplates->SetGenerateTriangles(this->GenerateTriangles);
+      return this->GridSynchronizedTemplates->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+  } //if 3D SGrid
+
+  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+// General contouring filter.  Handles arbitrary input.
+//
+int vtkMyContourFilter::RequestData(
+  vtkInformation* request,
+  vtkInformationVector** inputVector,
+  vtkInformationVector* outputVector)
+{
+  // get the input
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  vtkDataSet *input = vtkDataSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  if (!input)
+  {
+    return 0;
+  }
+
+  vtkDataArray* inScalars = this->GetInputArrayToProcess(0, inputVector);
+  // is the input array a cell data ?
+  int association = this->GetInputArrayAssociation(0, inputVector);
+  vtkNew<vtkMyCellDataToPointData> cd2pd;
+  vtkNew<vtkInformationVector> cd2pdInputVector;
+  vtkNew<vtkInformation> arrayInfo;
+  if (association == vtkDataObject::FIELD_ASSOCIATION_CELLS)
+  {
+    const char* name = inScalars->GetName();
+    cd2pd->SetInputData(input);
+    cd2pd->SetProcessAllArrays(false);
+    cd2pd->AddCellDataArray(name);
+    cd2pd->Update();
+    input = cd2pd->GetOutput();
+    inScalars = input->GetPointData()->GetArray(name);
+
+    cd2pdInputVector->Copy(inputVector[0]);
+    inInfo = cd2pdInputVector->GetInformationObject(0);
+    inInfo->Set(vtkDataObject::DATA_OBJECT(), input);
+    vtkInformationVector* tmp = cd2pdInputVector.Get();
+    inputVector = &tmp;
+
+    arrayInfo->Copy(this->GetInputArrayInformation(0));
+    arrayInfo->Set(vtkDataObject::FIELD_ASSOCIATION(), vtkDataObject::FIELD_ASSOCIATION_POINTS);
+    this->SetInputArrayToProcess(0, arrayInfo);
+  }
+  else if (association != vtkDataObject::FIELD_ASSOCIATION_POINTS)
+  {
+    vtkErrorMacro("Invalid Array Association");
+    return 1;
+  }
+
+  // get the contours
+  int numContours = this->ContourValues->GetNumberOfContours();
+  double *values = this->ContourValues->GetValues();
+  int i;
+
+  // is there data to process?
+  if (!inScalars)
+  {
+    return 1;
+  }
+
+  int sType = inScalars->GetDataType();
+
+  // handle 2D images
+  if (vtkImageData::SafeDownCast(input) && sType != VTK_BIT &&
+      !vtkUniformGrid::SafeDownCast(input))
+  {
+    int dim = 3;
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    if (uExt[0] == uExt[1])
+    {
+      --dim;
+    }
+    if (uExt[2] == uExt[3])
+    {
+      --dim;
+    }
+    if (uExt[4] == uExt[5])
+    {
+      --dim;
+    }
+
+    if ( dim == 2 )
+    {
+      this->SynchronizedTemplates2D->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->SynchronizedTemplates2D->SetValue(i,values[i]);
+      }
+      this->SynchronizedTemplates2D->
+        SetInputArrayToProcess(0,this->GetInputArrayInformation(0));
+      return
+        this->SynchronizedTemplates2D->ProcessRequest(request,inputVector,outputVector);
+    }
+    else if ( dim == 3 )
+    {
+      this->SynchronizedTemplates3D->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->SynchronizedTemplates3D->SetValue(i,values[i]);
+      }
+      this->SynchronizedTemplates3D->SetComputeNormals(this->ComputeNormals);
+      this->SynchronizedTemplates3D->SetComputeGradients(this->ComputeGradients);
+      this->SynchronizedTemplates3D->SetComputeScalars(this->ComputeScalars);
+      this->SynchronizedTemplates3D->SetGenerateTriangles(this->GenerateTriangles);
+      this->SynchronizedTemplates3D->
+        SetInputArrayToProcess(0,this->GetInputArrayInformation(0));
+
+      return this->SynchronizedTemplates3D->ProcessRequest(request,inputVector,outputVector);
+    }
+  } //if image data
+
+  // handle 3D RGrids
+  if (vtkRectilinearGrid::SafeDownCast(input) && sType != VTK_BIT)
+  {
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    // if 3D
+    if (uExt[0] < uExt[1] && uExt[2] < uExt[3] && uExt[4] < uExt[5])
+    {
+      this->RectilinearSynchronizedTemplates->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->RectilinearSynchronizedTemplates->SetValue(i,values[i]);
+      }
+      this->RectilinearSynchronizedTemplates->SetComputeNormals(this->ComputeNormals);
+      this->RectilinearSynchronizedTemplates->SetComputeGradients(this->ComputeGradients);
+      this->RectilinearSynchronizedTemplates->SetComputeScalars(this->ComputeScalars);
+      this->RectilinearSynchronizedTemplates->SetGenerateTriangles(this->GenerateTriangles);
+      this->RectilinearSynchronizedTemplates->
+        SetInputArrayToProcess(0,this->GetInputArrayInformation(0));
+      return this->RectilinearSynchronizedTemplates->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+  } // if 3D Rgrid
+
+  // handle 3D SGrids
+  if (vtkStructuredGrid::SafeDownCast(input) && sType != VTK_BIT)
+  {
+    int *uExt = inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
+    // if 3D
+    if (uExt[0] < uExt[1] && uExt[2] < uExt[3] && uExt[4] < uExt[5])
+    {
+      this->GridSynchronizedTemplates->SetNumberOfContours(numContours);
+      for (i=0; i < numContours; i++)
+      {
+        this->GridSynchronizedTemplates->SetValue(i,values[i]);
+      }
+      this->GridSynchronizedTemplates->SetComputeNormals(this->ComputeNormals);
+      this->GridSynchronizedTemplates->SetComputeGradients(this->ComputeGradients);
+      this->GridSynchronizedTemplates->SetComputeScalars(this->ComputeScalars);
+      this->GridSynchronizedTemplates->SetOutputPointsPrecision(this->OutputPointsPrecision);
+      this->GridSynchronizedTemplates->SetGenerateTriangles(this->GenerateTriangles);
+      this->GridSynchronizedTemplates->
+        SetInputArrayToProcess(0,this->GetInputArrayInformation(0));
+      return this->GridSynchronizedTemplates->
+        ProcessRequest(request,inputVector,outputVector);
+    }
+  } //if 3D SGrid
+
+  vtkIdType cellId;
+  int abortExecute=0;
+  vtkIdList *cellPts;
+  vtkCellArray *newVerts, *newLines, *newPolys;
+  vtkPoints *newPts;
+  vtkIdType numCells, estimatedSize;
+  vtkDataArray *cellScalars;
+
+  vtkInformation* info = outputVector->GetInformationObject(0);
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    info->Get(vtkDataObject::DATA_OBJECT()));
+  if (!output) {return 0;}
+
+  vtkPointData *inPdOriginal = input->GetPointData();
+
+  // We don't want to change the active scalars in the input, but we
+  // need to set the active scalars to match the input array to
+  // process so that the point data copying works as expected. Create
+  // a shallow copy of point data so that we can do this without
+  // changing the input.
+  vtkSmartPointer<vtkPointData> inPd = vtkSmartPointer<vtkPointData>::New();
+  inPd->ShallowCopy(inPdOriginal);
+
+  // Keep track of the old active scalars because when we set the new
+  // scalars, the old scalars are removed from the point data entirely
+  // and we have to add them back.
+  vtkAbstractArray* oldScalars = inPd->GetScalars();
+  inPd->SetScalars(inScalars);
+  if (oldScalars)
+  {
+    inPd->AddArray(oldScalars);
+  }
+  vtkPointData *outPd = output->GetPointData();
+
+  vtkCellData *inCd = input->GetCellData();
+  vtkCellData *outCd = output->GetCellData();
+
+  vtkDebugMacro(<< "Executing contour filter");
+  if (input->IsA("vtkUnstructuredGridBase"))
+  {
+    vtkDebugMacro(<< "Processing unstructured grid");
+    vtkContourGrid *cgrid;
+
+    cgrid = vtkContourGrid::New();
+    cgrid->SetInputData(input);
+    // currently vtkContourGrid has a ComputeGradients option
+    // but this doesn't do anything and will soon be deprecated.
+    cgrid->SetComputeNormals(this->ComputeNormals);
+    cgrid->SetComputeScalars(this->ComputeScalars);
+    cgrid->SetOutputPointsPrecision(this->OutputPointsPrecision);
+    cgrid->SetGenerateTriangles(this->GenerateTriangles);
+    cgrid->SetUseScalarTree(this->UseScalarTree);
+    if ( this->UseScalarTree ) //special treatment to reuse it
+    {
+      if ( this->ScalarTree == nullptr )
+      {
+        this->ScalarTree = vtkSpanSpace::New();
+      }
+      this->ScalarTree->SetDataSet(input);
+      cgrid->SetScalarTree(this->ScalarTree);
+    }
+    if ( this->Locator )
+    {
+      cgrid->SetLocator( this->Locator );
+    }
+
+    for (i = 0; i < numContours; i++)
+    {
+      cgrid->SetValue(i, values[i]);
+    }
+    cgrid->SetInputArrayToProcess(0,this->GetInputArrayInformation(0));
+    cgrid->UpdatePiece(
+      info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()),
+      info->Get(vtkStreamingDemandDrivenPipeline:: UPDATE_NUMBER_OF_PIECES()),
+      info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
+
+    output->ShallowCopy(cgrid->GetOutput());
+    cgrid->Delete();
+  } //if type VTK_UNSTRUCTURED_GRID
+  else
+  {
+    numCells = input->GetNumberOfCells();
+    inScalars = this->GetInputArrayToProcess(0,inputVector);
+    if ( ! inScalars || numCells < 1 )
+    {
+      vtkDebugMacro(<<"No data to contour");
+      return 1;
+    }
+
+    // Create objects to hold output of contour operation. First estimate
+    // allocation size.
+    //
+    estimatedSize=
+      static_cast<vtkIdType>(pow(static_cast<double>(numCells),.75));
+    estimatedSize *= numContours;
+    estimatedSize = estimatedSize / 1024 * 1024; //multiple of 1024
+    if (estimatedSize < 1024)
+    {
+      estimatedSize = 1024;
+    }
+
+    newPts = vtkPoints::New();
+    // set precision for the points in the output
+    if(this->OutputPointsPrecision == vtkAlgorithm::DEFAULT_PRECISION)
+    {
+      vtkPointSet *inputPointSet = vtkPointSet::SafeDownCast(input);
+      if(inputPointSet)
+      {
+        newPts->SetDataType(inputPointSet->GetPoints()->GetDataType());
+      }
+      else
+      {
+        newPts->SetDataType(VTK_FLOAT);
+      }
+    }
+    else if(this->OutputPointsPrecision == vtkAlgorithm::SINGLE_PRECISION)
+    {
+      newPts->SetDataType(VTK_FLOAT);
+    }
+    else if(this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
+    {
+      newPts->SetDataType(VTK_DOUBLE);
+    }
+    newPts->Allocate(estimatedSize,estimatedSize);
+    newVerts = vtkCellArray::New();
+    newVerts->Allocate(estimatedSize,estimatedSize);
+    newLines = vtkCellArray::New();
+    newLines->Allocate(estimatedSize,estimatedSize);
+    newPolys = vtkCellArray::New();
+    newPolys->Allocate(estimatedSize,estimatedSize);
+    cellScalars = inScalars->NewInstance();
+    cellScalars->SetNumberOfComponents(inScalars->GetNumberOfComponents());
+    cellScalars->Allocate(cellScalars->GetNumberOfComponents()*VTK_CELL_SIZE);
+
+    // locator used to merge potentially duplicate points
+    if ( this->Locator == nullptr )
+    {
+      this->CreateDefaultLocator();
+    }
+    this->Locator->InitPointInsertion (newPts,
+                                       input->GetBounds(),
+                                       input->GetNumberOfPoints());
+
+    // interpolate data along edge
+    // if we did not ask for scalars to be computed, don't copy them
+    if (!this->ComputeScalars)
+    {
+      outPd->CopyScalarsOff();
+    }
+    outPd->InterpolateAllocate(inPd,estimatedSize,estimatedSize);
+    outCd->CopyAllocate(inCd,estimatedSize,estimatedSize);
+
+    vtkContourHelper helper(this->Locator, newVerts, newLines, newPolys, inPd, inCd, outPd,outCd, estimatedSize, this->GenerateTriangles!=0);
+    // If enabled, build a scalar tree to accelerate search
+    //
+    if ( !this->UseScalarTree )
+    {
+      vtkGenericCell *cell = vtkGenericCell::New();
+      // Three passes over the cells to process lower dimensional cells first.
+      // For poly data output cells need to be added in the order:
+      // verts, lines and then polys, or cell data gets mixed up.
+      // A better solution is to have an unstructured grid output.
+      // I create a table that maps cell type to cell dimensionality,
+      // because I need a fast way to get cell dimensionality.
+      // This assumes GetCell is slow and GetCellType is fast.
+      // I do not like hard coding a list of cell types here,
+      // but I do not want to add GetCellDimension(vtkIdType cellId)
+      // to the vtkDataSet API.  Since I anticipate that the output
+      // will change to vtkUnstructuredGrid.  This temporary solution
+      // is acceptable.
+      //
+      int cellType;
+      unsigned char cellTypeDimensions[VTK_NUMBER_OF_CELL_TYPES];
+      vtkCutter::GetCellTypeDimensions(cellTypeDimensions);
+      int dimensionality;
+      // We skip 0d cells (points), because they cannot be cut (generate no data).
+      for (dimensionality = 1; dimensionality <= 3; ++dimensionality)
+      {
+        // Loop over all cells; get scalar values for all cell points
+        // and process each cell.
+        //
+        for (cellId=0; cellId < numCells && !abortExecute; cellId++)
+        {
+          // I assume that "GetCellType" is fast.
+          cellType = input->GetCellType(cellId);
+          if (cellType >= VTK_NUMBER_OF_CELL_TYPES)
+          { // Protect against new cell types added.
+            vtkErrorMacro("Unknown cell type " << cellType);
+            continue;
+          }
+          if (cellTypeDimensions[cellType] != dimensionality)
+          {
+            continue;
+          }
+          input->GetCell(cellId,cell);
+          cellPts = cell->GetPointIds();
+          if (cellScalars->GetSize()/cellScalars->GetNumberOfComponents() <
+            cellPts->GetNumberOfIds())
+          {
+            cellScalars->Allocate(
+              cellScalars->GetNumberOfComponents()*cellPts->GetNumberOfIds());
+          }
+          inScalars->GetTuples(cellPts,cellScalars);
+
+          if (dimensionality == 3 &&  ! (cellId % 5000) )
+          {
+            vtkDebugMacro(<<"Contouring #" << cellId);
+            this->UpdateProgress (static_cast<double>(cellId)/numCells);
+            abortExecute = this->GetAbortExecute();
+          }
+
+          for (i=0; i < numContours; i++)
+          {
+            helper.Contour(cell,values[i],cellScalars,cellId);
+          } // for all contour values
+        } // for all cells
+      } // for all dimensions
+      cell->Delete();
+    } //if using scalar tree
+    else
+    {
+      vtkCell *cell;
+      // Note: This will have problems when input contains 2D and 3D cells.
+      // CellData will get scrabled because of the implicit ordering of
+      // verts, lines and polys in vtkPolyData.  The solution
+      // is to convert this filter to create unstructured grid.
+      //
+      // Loop over all contour values.  Then for each contour value,
+      // loop over all cells.
+      //
+      for (i=0; i < numContours; i++)
+      {
+        for ( this->ScalarTree->InitTraversal(values[i]);
+              (cell=this->ScalarTree->GetNextCell(cellId,cellPts,cellScalars)) != nullptr; )
+        {
+          helper.Contour(cell,values[i],cellScalars,cellId);
+        } //for all cells
+      } //for all contour values
+    } //using scalar tree
+
+    vtkDebugMacro(<<"Created: "
+                  << newPts->GetNumberOfPoints() << " points, "
+                  << newVerts->GetNumberOfCells() << " verts, "
+                  << newLines->GetNumberOfCells() << " lines, "
+                  << newPolys->GetNumberOfCells() << " triangles");
+
+    // Update ourselves.  Because we don't know up front how many verts, lines,
+    // polys we've created, take care to reclaim memory.
+    //
+    output->SetPoints(newPts);
+    newPts->Delete();
+    cellScalars->Delete();
+
+    if (newVerts->GetNumberOfCells())
+    {
+      output->SetVerts(newVerts);
+    }
+    newVerts->Delete();
+
+    if (newLines->GetNumberOfCells())
+    {
+      output->SetLines(newLines);
+    }
+    newLines->Delete();
+
+    if (newPolys->GetNumberOfCells())
+    {
+      output->SetPolys(newPolys);
+    }
+    newPolys->Delete();
+
+    // -1 == uninitialized. This setting used to be ignored, and we preserve the
+    // old behavior for backward compatibility. Normals will be computed here
+    // if and only if the user has explicitly set the option.
+    if (this->ComputeNormals != 0 && this->ComputeNormals != -1)
+    {
+      vtkNew<vtkPolyDataNormals> normalsFilter;
+      normalsFilter->SetOutputPointsPrecision(this->OutputPointsPrecision);
+      vtkNew<vtkPolyData> tempInput;
+      tempInput->ShallowCopy(output);
+      normalsFilter->SetInputData(tempInput);
+      normalsFilter->SetFeatureAngle(180.);
+      normalsFilter->UpdatePiece(
+        info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()),
+        info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()),
+        info->Get(vtkStreamingDemandDrivenPipeline::
+                  UPDATE_NUMBER_OF_GHOST_LEVELS()));
+      output->ShallowCopy(normalsFilter->GetOutput());
+    }
+
+    this->Locator->Initialize();//releases leftover memory
+    output->Squeeze();
+  } //else if not vtkUnstructuredGrid
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Specify a spatial locator for merging points. By default,
+// an instance of vtkMergePoints is used.
+void vtkMyContourFilter::SetLocator(vtkIncrementalPointLocator *locator)
+{
+  if ( this->Locator == locator )
+  {
+    return;
+  }
+  if ( this->Locator )
+  {
+    this->Locator->UnRegister(this);
+    this->Locator = nullptr;
+  }
+  if ( locator )
+  {
+    locator->Register(this);
+  }
+  this->Locator = locator;
+  this->Modified();
+}
+
+//-----------------------------------------------------------------------------
+void vtkMyContourFilter::CreateDefaultLocator()
+{
+  if ( this->Locator == nullptr )
+  {
+    this->Locator = vtkMergePoints::New();
+    this->Locator->Register(this);
+    this->Locator->Delete();
+  }
+}
+
+//-----------------------------------------------------------------------------
+void vtkMyContourFilter::SetArrayComponent( int comp )
+{
+  this->SynchronizedTemplates2D->SetArrayComponent( comp );
+  this->SynchronizedTemplates3D->SetArrayComponent( comp );
+  this->RectilinearSynchronizedTemplates->SetArrayComponent( comp );
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyContourFilter::GetArrayComponent()
+{
+  return( this->SynchronizedTemplates2D->GetArrayComponent() );
+}
+
+//-----------------------------------------------------------------------------
+void vtkMyContourFilter::SetOutputPointsPrecision(int precision)
+{
+  this->OutputPointsPrecision = precision;
+  this->Modified();
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyContourFilter::GetOutputPointsPrecision() const
+{
+  return this->OutputPointsPrecision;
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyContourFilter::FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
+  return 1;
+}
+
+void vtkMyContourFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Compute Gradients: "
+     << (this->ComputeGradients ? "On\n" : "Off\n");
+  os << indent << "Compute Normals: "
+     << (this->ComputeNormals ? "On\n" : "Off\n");
+  os << indent << "Compute Scalars: "
+     << (this->ComputeScalars ? "On\n" : "Off\n");
+
+  this->ContourValues->PrintSelf(os,indent.GetNextIndent());
+
+  os << indent << "Use Scalar Tree: "
+     << (this->UseScalarTree ? "On\n" : "Off\n");
+  if ( this->ScalarTree )
+  {
+    os << indent << "Scalar Tree: " << this->ScalarTree << "\n";
+  }
+  else
+  {
+    os << indent << "Scalar Tree: (none)\n";
+  }
+
+  if ( this->Locator )
+  {
+    os << indent << "Locator: " << this->Locator << "\n";
+  }
+  else
+  {
+    os << indent << "Locator: (none)\n";
+  }
+
+  os << indent << "Precision of the output points: "
+     << this->OutputPointsPrecision << "\n";
+}
+
+//----------------------------------------------------------------------------
+void vtkMyContourFilter::ReportReferences(vtkGarbageCollector* collector)
+{
+  this->Superclass::ReportReferences(collector);
+  // These filters share our input and are therefore involved in a
+  // reference loop.
+  vtkGarbageCollectorReport(collector, this->ScalarTree, "ScalarTree");
+}
+
+//----------------------------------------------------------------------------
+void vtkMyContourFilter::InternalProgressCallbackFunction(vtkObject *vtkNotUsed(caller),
+                                                        unsigned long vtkNotUsed(eid),
+                                                        void *clientData,
+                                                        void *callData)
+{
+  vtkMyContourFilter *contourFilter = static_cast<vtkMyContourFilter *>(clientData);
+  double progress = *static_cast<double *>(callData);
+  contourFilter->UpdateProgress(progress);
+}
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.h b/src/CellDataContour/plugin/CellDataContourModule/vtkMyContourFilter.h
new file mode 100644 (file)
index 0000000..995969c
--- /dev/null
@@ -0,0 +1,317 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyContourFilter.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkMyContourFilter
+ * @brief   generate isosurfaces/isolines from scalar values
+ *
+ * vtkMyContourFilter is a filter that takes as input any dataset and
+ * generates on output isosurfaces and/or isolines. The exact form
+ * of the output depends upon the dimensionality of the input data.
+ * Data consisting of 3D cells will generate isosurfaces, data
+ * consisting of 2D cells will generate isolines, and data with 1D
+ * or 0D cells will generate isopoints. Combinations of output type
+ * are possible if the input dimension is mixed.
+ *
+ * To use this filter you must specify one or more contour values.
+ * You can either use the method SetValue() to specify each contour
+ * value, or use GenerateValues() to generate a series of evenly
+ * spaced contours. It is also possible to accelerate the operation of
+ * this filter (at the cost of extra memory) by using a
+ * vtkScalarTree. A scalar tree is used to quickly locate cells that
+ * contain a contour surface. This is especially effective if multiple
+ * contours are being extracted. If you want to use a scalar tree,
+ * invoke the method UseScalarTreeOn().
+ *
+ * @warning
+ * For unstructured data or structured grids, normals and gradients
+ * are not computed. Use vtkPolyDataNormals to compute the surface
+ * normals.
+ *
+ * @sa
+ * vtkFlyingEdges3D vtkFlyingEdges2D vtkDiscreteFlyingEdges3D
+ * vtkDiscreteFlyingEdges2D vtkMarchingContourFilter vtkMarchingCubes
+ * vtkSliceCubes vtkMarchingSquares vtkImageMarchingCubes
+*/
+
+#ifndef vtkMyContourFilter_h
+#define vtkMyContourFilter_h
+
+#include <vtkPolyDataAlgorithm.h>
+
+#include "vtkContourValues.h" // Needed for inline methods
+
+#include "vtkMyCellDataToPointData.h"
+
+class vtkIncrementalPointLocator;
+class vtkScalarTree;
+class vtkSynchronizedTemplates2D;
+class vtkSynchronizedTemplates3D;
+class vtkGridSynchronizedTemplates3D;
+class vtkRectilinearSynchronizedTemplates;
+class vtkCallbackCommand;
+
+class VTK_EXPORT vtkMyContourFilter : public vtkPolyDataAlgorithm
+{
+public:
+  vtkTypeMacro(vtkMyContourFilter,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  /**
+   * Construct object with initial range (0,1) and single contour value
+   * of 0.0.
+   */
+  static vtkMyContourFilter *New();
+
+  //@{
+  /**
+   * Methods to set / get contour values.
+   */
+  void SetValue(int i, double value);
+  double GetValue(int i);
+  double *GetValues();
+  void GetValues(double *contourValues);
+  void SetNumberOfContours(int number);
+  int GetNumberOfContours();
+  void GenerateValues(int numContours, double range[2]);
+  void GenerateValues(int numContours, double rangeStart, double rangeEnd);
+  //@}
+
+  /**
+   * Modified GetMTime Because we delegate to vtkContourValues
+   */
+  vtkMTimeType GetMTime() override;
+
+  //@{
+  /**
+   * Set/Get the computation of normals. Normal computation is fairly
+   * expensive in both time and storage. If the output data will be
+   * processed by filters that modify topology or geometry, it may be
+   * wise to turn Normals and Gradients off.
+   * This setting defaults to On for vtkImageData, vtkRectilinearGrid,
+   * vtkStructuredGrid, and vtkUnstructuredGrid inputs, and Off for all others.
+   * This default behavior is to preserve the behavior of an older version of
+   * this filter, which would ignore this setting for certain inputs.
+   */
+  vtkSetMacro(ComputeNormals, bool);
+  vtkGetMacro(ComputeNormals, bool);
+  vtkBooleanMacro(ComputeNormals, bool);
+  //@}
+
+  //@{
+  /**
+   * Set/Get the computation of gradients. Gradient computation is
+   * fairly expensive in both time and storage. Note that if
+   * ComputeNormals is on, gradients will have to be calculated, but
+   * will not be stored in the output dataset.  If the output data
+   * will be processed by filters that modify topology or geometry, it
+   * may be wise to turn Normals and Gradients off.
+   */
+  vtkSetMacro(ComputeGradients, bool);
+  vtkGetMacro(ComputeGradients, bool);
+  vtkBooleanMacro(ComputeGradients, bool);
+  //@}
+
+  //@{
+  /**
+   * Set/Get the computation of scalars.
+   */
+  vtkSetMacro(ComputeScalars, bool);
+  vtkGetMacro(ComputeScalars, bool);
+  vtkBooleanMacro(ComputeScalars, bool);
+  //@}
+
+  //@{
+  /**
+   * Enable the use of a scalar tree to accelerate contour extraction.
+   */
+  vtkSetMacro(UseScalarTree, bool);
+  vtkGetMacro(UseScalarTree, bool);
+  vtkBooleanMacro(UseScalarTree, bool);
+  //@}
+
+  //@{
+  /**
+   * Enable the use of a scalar tree to accelerate contour extraction.
+   */
+  virtual void SetScalarTree(vtkScalarTree*);
+  vtkGetObjectMacro(ScalarTree,vtkScalarTree);
+  //@}
+
+  //@{
+  /**
+   * Set / get a spatial locator for merging points. By default,
+   * an instance of vtkMergePoints is used.
+   */
+  void SetLocator(vtkIncrementalPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkIncrementalPointLocator);
+  //@}
+
+  /**
+   * Create default locator. Used to create one when none is
+   * specified. The locator is used to merge coincident points.
+   */
+  void CreateDefaultLocator();
+
+  //@{
+  /**
+   * Set/get which component of the scalar array to contour on; defaults to 0.
+   * Currently this feature only works if the input is a vtkImageData.
+   */
+  void SetArrayComponent(int);
+  int  GetArrayComponent();
+  //@}
+
+
+  //@{
+  /**
+   * If this is enabled (by default), the output will be triangles
+   * otherwise, the output will be the intersection polygon
+   * WARNING: if the contour surface is not planar, the output
+   * polygon will not be planar, which might be nice to look at but hard
+   * to compute with downstream.
+   */
+  vtkSetMacro(GenerateTriangles, bool);
+  vtkGetMacro(GenerateTriangles, bool);
+  vtkBooleanMacro(GenerateTriangles, bool);
+  //@}
+
+  //@{
+  /**
+   * Set/get the desired precision for the output types. See the documentation
+   * for the vtkAlgorithm::Precision enum for an explanation of the available
+   * precision settings.
+   */
+  void SetOutputPointsPrecision(int precision);
+  int GetOutputPointsPrecision() const;
+  //@}
+
+protected:
+  vtkMyContourFilter();
+  ~vtkMyContourFilter() override;
+
+  void ReportReferences(vtkGarbageCollector*) override;
+
+  int RequestData(vtkInformation* request,
+                  vtkInformationVector** inputVector,
+                  vtkInformationVector* outputVector) override;
+  int RequestUpdateExtent(vtkInformation*,
+                          vtkInformationVector**,
+                          vtkInformationVector*) override;
+  int FillInputPortInformation(int port, vtkInformation *info) override;
+
+  vtkContourValues *ContourValues;
+  bool ComputeNormals;
+  bool ComputeGradients;
+  bool ComputeScalars;
+  vtkIncrementalPointLocator *Locator;
+  bool UseScalarTree;
+  vtkScalarTree *ScalarTree;
+  int OutputPointsPrecision;
+  bool GenerateTriangles;
+
+  vtkSynchronizedTemplates2D *SynchronizedTemplates2D;
+  vtkSynchronizedTemplates3D *SynchronizedTemplates3D;
+  vtkGridSynchronizedTemplates3D *GridSynchronizedTemplates;
+  vtkRectilinearSynchronizedTemplates *RectilinearSynchronizedTemplates;
+  vtkCallbackCommand *InternalProgressCallbackCommand;
+
+  static void InternalProgressCallbackFunction(vtkObject *caller,
+                                               unsigned long eid,
+                                               void *clientData,
+                                               void *callData);
+
+private:
+  vtkMyContourFilter(const vtkMyContourFilter&) = delete;
+  void operator=(const vtkMyContourFilter&) = delete;
+};
+
+/**
+ * Set a particular contour value at contour number i. The index i ranges
+ * between 0<=i<NumberOfContours.
+ */
+inline void vtkMyContourFilter::SetValue(int i, double value)
+{this->ContourValues->SetValue(i,value);}
+
+/**
+ * Get the ith contour value.
+ */
+inline double vtkMyContourFilter::GetValue(int i)
+{return this->ContourValues->GetValue(i);}
+
+/**
+ * Get a pointer to an array of contour values. There will be
+ * GetNumberOfContours() values in the list.
+ */
+inline double *vtkMyContourFilter::GetValues()
+{return this->ContourValues->GetValues();}
+
+/**
+ * Fill a supplied list with contour values. There will be
+ * GetNumberOfContours() values in the list. Make sure you allocate
+ * enough memory to hold the list.
+ */
+inline void vtkMyContourFilter::GetValues(double *contourValues)
+{this->ContourValues->GetValues(contourValues);}
+
+/**
+ * Set the number of contours to place into the list. You only really
+ * need to use this method to reduce list size. The method SetValue()
+ * will automatically increase list size as needed.
+ */
+inline void vtkMyContourFilter::SetNumberOfContours(int number)
+{this->ContourValues->SetNumberOfContours(number);}
+
+/**
+ * Get the number of contours in the list of contour values.
+ */
+inline int vtkMyContourFilter::GetNumberOfContours()
+{return this->ContourValues->GetNumberOfContours();}
+
+/**
+ * Generate numContours equally spaced contour values between specified
+ * range. Contour values will include min/max range values.
+ */
+inline void vtkMyContourFilter::GenerateValues(int numContours, double range[2])
+{this->ContourValues->GenerateValues(numContours, range);}
+
+/**
+ * Generate numContours equally spaced contour values between specified
+ * range. Contour values will include min/max range values.
+ */
+inline void vtkMyContourFilter::GenerateValues(int numContours, double
+                                             rangeStart, double rangeEnd)
+{this->ContourValues->GenerateValues(numContours, rangeStart, rangeEnd);}
+
+
+#endif
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.cxx b/src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.cxx
new file mode 100644 (file)
index 0000000..2205421
--- /dev/null
@@ -0,0 +1,266 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyContourFilter.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkMyPVContourFilter.h"
+
+#include <vtkAMRDualContour.h>
+#include <vtkAppendPolyData.h>
+#include <vtkCompositeDataIterator.h>
+#include <vtkDataObject.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkHierarchicalBoxDataSet.h>
+#include <vtkInformation.h>
+#include <vtkInformationStringVectorKey.h>
+#include <vtkInformationVector.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkObjectFactory.h>
+#include <vtkSmartPointer.h>
+
+vtkStandardNewMacro(vtkMyPVContourFilter);
+
+//-----------------------------------------------------------------------------
+vtkMyPVContourFilter::vtkMyPVContourFilter()
+  : vtkMyContourFilter()
+{
+  this->SetComputeNormals(true);
+}
+
+//-----------------------------------------------------------------------------
+vtkMyPVContourFilter::~vtkMyPVContourFilter()
+{
+}
+
+//-----------------------------------------------------------------------------
+void vtkMyPVContourFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyPVContourFilter::ProcessRequest(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // create the output
+  if (request->Has(vtkDemandDrivenPipeline::REQUEST_DATA_OBJECT()))
+  {
+    return this->RequestDataObject(request, inputVector, outputVector);
+  }
+
+  return this->Superclass::ProcessRequest(request, inputVector, outputVector);
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyPVContourFilter::RequestData(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  if (!inInfo)
+  {
+    vtkErrorMacro("Failed to get input information.");
+    return 1;
+  }
+
+  vtkDataObject* inDataObj = inInfo->Get(vtkDataObject::DATA_OBJECT());
+  if (!inDataObj)
+  {
+    vtkErrorMacro("Failed to get input data object.");
+    return 1;
+  }
+
+  vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  if (!outInfo)
+  {
+    vtkErrorMacro("Failed to get output information.");
+    return 1;
+  }
+
+  vtkDataObject* outDataObj = outInfo->Get(vtkDataObject::DATA_OBJECT());
+  if (!outDataObj)
+  {
+    vtkErrorMacro("Failed get output data object.");
+    return 1;
+  }
+
+  // Check if input is AMR data.
+  if (vtkHierarchicalBoxDataSet::SafeDownCast(inDataObj))
+  {
+    // This is a lot to go through to get the name of the array to process.
+    vtkInformation* inArrayInfo = this->GetInputArrayInformation(0);
+    if (!inArrayInfo)
+    {
+      vtkErrorMacro("Problem getting name of array to process.");
+      return 0;
+    }
+    int fieldAssociation = -1;
+    if (!inArrayInfo->Has(vtkDataObject::FIELD_ASSOCIATION()))
+    {
+      vtkErrorMacro("Unable to query field association for the scalar.");
+      return 0;
+    }
+    fieldAssociation = inArrayInfo->Get(vtkDataObject::FIELD_ASSOCIATION());
+    if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_CELLS)
+    {
+      vtkSmartPointer<vtkAMRDualContour> amrDC(vtkSmartPointer<vtkAMRDualContour>::New());
+
+      amrDC->SetInputData(0, inDataObj);
+      amrDC->SetInputArrayToProcess(0, inArrayInfo);
+      amrDC->SetEnableCapping(1);
+      amrDC->SetEnableDegenerateCells(1);
+      amrDC->SetEnableMultiProcessCommunication(1);
+      amrDC->SetSkipGhostCopy(1);
+      amrDC->SetTriangulateCap(1);
+      amrDC->SetEnableMergePoints(1);
+
+      for (int i = 0; i < this->GetNumberOfContours(); ++i)
+      {
+        vtkSmartPointer<vtkMultiBlockDataSet> out(vtkSmartPointer<vtkMultiBlockDataSet>::New());
+        amrDC->SetIsoValue(this->GetValue(i));
+        amrDC->Update();
+        out->ShallowCopy(amrDC->GetOutput(0));
+        vtkMultiBlockDataSet::SafeDownCast(outDataObj)->SetBlock(i, out);
+      }
+      return 1;
+    }
+  }
+
+  return this->ContourUsingSuperclass(request, inputVector, outputVector);
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyPVContourFilter::RequestDataObject(vtkInformation* vtkNotUsed(request),
+  vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  if (!inInfo)
+  {
+    return 0;
+  }
+
+  vtkHierarchicalBoxDataSet* input = vtkHierarchicalBoxDataSet::GetData(inInfo);
+  vtkInformation* outInfo = outputVector->GetInformationObject(0);
+
+  if (input)
+  {
+    vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::GetData(outInfo);
+    if (!output)
+    {
+      output = vtkMultiBlockDataSet::New();
+      outInfo->Set(vtkDataObject::DATA_OBJECT(), output);
+      this->GetOutputPortInformation(0)->Set(
+        vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType());
+      output->Delete();
+    }
+    return 1;
+  }
+  else
+  {
+    vtkDataSet* output = vtkDataSet::GetData(outInfo);
+    if (!output)
+    {
+      output = vtkPolyData::New();
+      outInfo->Set(vtkDataObject::DATA_OBJECT(), output);
+      this->GetOutputPortInformation(0)->Set(
+        vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType());
+      output->Delete();
+    }
+    return 1;
+  }
+}
+
+//----------------------------------------------------------------------------
+int vtkMyPVContourFilter::ContourUsingSuperclass(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  vtkDataObject* inputDO = vtkDataObject::GetData(inputVector[0], 0);
+  vtkDataObject* outputDO = vtkDataObject::GetData(outputVector, 0);
+
+  vtkCompositeDataSet* inputCD = vtkCompositeDataSet::SafeDownCast(inputDO);
+  if (!inputCD)
+  {
+    return this->Superclass::RequestData(request, inputVector, outputVector);
+  }
+
+  vtkCompositeDataSet* outputCD = vtkCompositeDataSet::SafeDownCast(outputDO);
+  outputCD->CopyStructure(inputCD);
+
+  vtkSmartPointer<vtkCompositeDataIterator> iter;
+  iter.TakeReference(inputCD->NewIterator());
+
+  // for input.
+  vtkSmartPointer<vtkInformationVector> newInInfoVec = vtkSmartPointer<vtkInformationVector>::New();
+  vtkSmartPointer<vtkInformation> newInInfo = vtkSmartPointer<vtkInformation>::New();
+  newInInfoVec->SetInformationObject(0, newInInfo);
+
+  // for output.
+  vtkSmartPointer<vtkInformationVector> newOutInfoVec =
+    vtkSmartPointer<vtkInformationVector>::New();
+  vtkSmartPointer<vtkInformation> newOutInfo = vtkSmartPointer<vtkInformation>::New();
+  newOutInfoVec->SetInformationObject(0, newOutInfo);
+
+  // Loop over all the datasets.
+  for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
+  {
+    newInInfo->Set(vtkDataObject::DATA_OBJECT(), iter->GetCurrentDataObject());
+    vtkPolyData* polydata = vtkPolyData::New();
+    newOutInfo->Set(vtkDataObject::DATA_OBJECT(), polydata);
+    polydata->FastDelete();
+
+    vtkInformationVector* newInInfoVecPtr = newInInfoVec.GetPointer();
+    if (!this->Superclass::RequestData(request, &newInInfoVecPtr, newOutInfoVec.GetPointer()))
+    {
+      return 0;
+    }
+    outputCD->SetDataSet(iter, polydata);
+  }
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyPVContourFilter::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkDataObject");
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+int vtkMyPVContourFilter::FillInputPortInformation(int port, vtkInformation* info)
+{
+  this->Superclass::FillInputPortInformation(port, info);
+
+  // According to the documentation this is the way to append additional
+  // input data set type since VTK 5.2.
+  info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkHierarchicalBoxDataSet");
+  return 1;
+}
diff --git a/src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.h b/src/CellDataContour/plugin/CellDataContourModule/vtkMyPVContourFilter.h
new file mode 100644 (file)
index 0000000..65eaa7a
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMyContourFilter.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkMyPVContourFilter
+ * @brief   generate isosurfaces/isolines from scalar values
+ *
+ * vtkMyPVContourFilter is an extension to vtkMyContourFilter. It adds the
+ * ability to generate isosurfaces / isolines for AMR dataset.
+ *
+ * @warning
+ * Certain flags in vtkAMRDualContour are assumed to be ON.
+ *
+ * @sa
+ * vtkMyContourFilter vtkAMRDualContour
+*/
+
+#ifndef vtkMyPVContourFilter_h
+#define vtkMyPVContourFilter_h
+
+#include "vtkMyContourFilter.h"
+
+class VTK_EXPORT vtkMyPVContourFilter : public vtkMyContourFilter
+{
+public:
+  vtkTypeMacro(vtkMyPVContourFilter, vtkMyContourFilter);
+
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  static vtkMyPVContourFilter* New();
+
+  int ProcessRequest(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+
+protected:
+  vtkMyPVContourFilter();
+  ~vtkMyPVContourFilter() override;
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector) override;
+
+  virtual int RequestDataObject(vtkInformation* request, vtkInformationVector** inputVector,
+    vtkInformationVector* outputVector);
+
+  int FillInputPortInformation(int port, vtkInformation* info) override;
+  int FillOutputPortInformation(int port, vtkInformation *info) override;
+
+  /**
+   * Class superclass request data. Also handles iterating over
+   * vtkHierarchicalBoxDataSet.
+   */
+  int ContourUsingSuperclass(vtkInformation* request, vtkInformationVector** inputVector,
+    vtkInformationVector* outputVector);
+
+private:
+  vtkMyPVContourFilter(const vtkMyPVContourFilter&) = delete;
+  void operator=(const vtkMyPVContourFilter&) = delete;
+};
+
+#endif // vtkMyPVContourFilter_h
diff --git a/src/CellDataContour/plugin/filters.xml b/src/CellDataContour/plugin/filters.xml
new file mode 100644 (file)
index 0000000..b44a2b1
--- /dev/null
@@ -0,0 +1,180 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy class="vtkMyPVContourFilter"
+                 name="ContourOnCells" label="Contour On Cells">
+      <Documentation long_help="Generate isolines or isosurfaces using point scalars."
+                     short_help="Generate isolines or isosurfaces.">The Contour
+                     filter computes isolines or isosurfaces using a selected
+                     point-centered scalar array. The Contour filter operates
+                     on any type of data set, but the input is required to have
+                     at least one point-centered scalar (single-component)
+                     array. The output of this filter is
+                     polygonal.</Documentation>
+      <InputProperty command="SetInputConnection"
+                     name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet" />
+        </DataTypeDomain>
+        <InputArrayDomain attribute_type="any"
+                          name="input_array"
+                          number_of_components="1" />
+        <Documentation>This property specifies the input dataset to be used by
+        the contour filter.</Documentation>
+      </InputProperty>
+      <StringVectorProperty animateable="0"
+                            command="SetInputArrayToProcess"
+                            element_types="0 0 0 0 2"
+                            label="Contour By"
+                            name="SelectInputScalars"
+                            number_of_elements="5">
+        <ArrayListDomain attribute_type="Scalars"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>This property specifies the name of the scalar array
+        from which the contour filter will compute isolines and/or
+        isosurfaces.</Documentation>
+      </StringVectorProperty>
+      <IntVectorProperty animateable="0"
+                         command="SetComputeNormals"
+                         default_values="1"
+                         name="ComputeNormals"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Hints>
+          <PropertyWidgetDecorator type="NonPolyDataInputDecorator" />
+        </Hints>
+        <Documentation>If this property is set to 1, a scalar array containing
+        a normal value at each point in the isosurface or isoline will be
+        created by the contour filter; otherwise an array of normals will not
+        be computed. This operation is fairly expensive both in terms of
+        computation time and memory required, so if the output dataset produced
+        by the contour filter will be processed by filters that modify the
+        dataset's topology or geometry, it may be wise to set the value of this
+        property to 0. Select whether to compute normals.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty animateable="0"
+                         command="SetComputeGradients"
+                         default_values="0"
+                         name="ComputeGradients"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Hints>
+          <PropertyWidgetDecorator type="InputDataTypeDecorator" name="Structured" />
+        </Hints>
+        <Documentation>If this property is set to 1, a scalar array containing
+        a gradient value at each point in the isosurface or isoline will be
+        created by this filter; otherwise an array of gradients will not be
+        computed. This operation is fairly expensive both in terms of
+        computation time and memory required, so if the output dataset produced
+        by the contour filter will be processed by filters that modify the
+        dataset's topology or geometry, it may be wise to set the value of this
+        property to 0. Not that if ComputeNormals is set to 1, then gradients
+        will have to be calculated, but they will only be stored in the output
+        dataset if ComputeGradients is also set to 1.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty animateable="0"
+                         command="SetComputeScalars"
+                         default_values="0"
+                         name="ComputeScalars"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Documentation>If this property is set to 1, an array of scalars
+        (containing the contour value) will be added to the output dataset. If
+        set to 0, the output will not contain this array.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty animateable="0"
+                         command="SetOutputPointsPrecision"
+                         default_values="2"
+                         name="OutputPointsPrecision"
+                         number_of_elements="1"
+                         panel_visibility="advanced" >
+        <EnumerationDomain name="enum">
+          <Entry text="Single"
+                 value="0" />
+          <Entry text="Double"
+                 value="1" />
+          <Entry text="Same as input"
+                 value="2" />
+        </EnumerationDomain>
+        <Documentation>
+Select the output precision of the coordinates. **Single** sets the
+output to single-precision floating-point (i.e., float), **Double**
+sets it to double-precision floating-point (i.e., double), and
+**Default** sets it to the same precision as the precision of the
+points in the input. Defaults to ***Single***.
+        </Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty animateable="0"
+                         command="SetGenerateTriangles"
+                         default_values="1"
+                         name="GenerateTriangles"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Documentation>This parameter controls whether to produce triangles in the output.
+        Warning: Many filters do not properly handle non-triangular polygons.
+        </Documentation>
+      </IntVectorProperty>
+      <DoubleVectorProperty animateable="1"
+                            command="SetValue"
+                            label="Isosurfaces"
+                            name="ContourValues"
+                            number_of_elements="0"
+                            number_of_elements_per_command="1"
+                            repeat_command="1"
+                            set_number_command="SetNumberOfContours"
+                            use_index="1">
+        <ArrayRangeDomain name="scalar_range">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+            <Property function="ArraySelection"
+                      name="SelectInputScalars" />
+          </RequiredProperties>
+        </ArrayRangeDomain>
+        <Documentation>This property specifies the values at which to compute
+        isosurfaces/isolines and also the number of such
+        values.</Documentation>
+      </DoubleVectorProperty>
+      <Hints>
+        <Visibility replace_input="2" />
+        <ShowInMenu category="CFD" />
+      </Hints>
+      <!-- incremental point locator begin -->
+      <ProxyProperty command="SetLocator"
+                     label="Point Merge Method"
+                     name="Locator"
+                     panel_visibility="advanced" >
+        <ProxyGroupDomain name="groups">
+          <Group name="incremental_point_locators" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="incremental_point_locators"
+                 name="MergePoints" />
+          <Proxy group="incremental_point_locators"
+                 name="IncrementalOctreeMergePoints" />
+          <Proxy group="incremental_point_locators"
+                 name="NonMergingPointLocator" />
+        </ProxyListDomain>
+        <Documentation>This property specifies an incremental point locator for
+        merging duplicate / coincident points.</Documentation>
+      </ProxyProperty>
+      <!-- incremental point locator end -->
+
+      <PropertyGroup label="Isosurfaces">
+        <Property name="ContourValues" />
+      </PropertyGroup>
+      <PropertyGroup label="Point Locator">
+        <Property name="Locator" />
+      </PropertyGroup>
+      <!-- End Contour -->
+    </SourceProxy>
+ </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/CellDataContour/plugin/paraview.plugin b/src/CellDataContour/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..c983c18
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  MyContour
+DESCRIPTION
+  This plugin provides a customized Contour filter
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/ComplexMode/CMakeLists.txt b/src/ComplexMode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..63bf4ff
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ComplexModePlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ComplexMode/MobileMesh.xml b/src/ComplexMode/MobileMesh.xml
new file mode 100644 (file)
index 0000000..01747ac
--- /dev/null
@@ -0,0 +1,93 @@
+<CustomFilterDefinitions>
+  <CustomProxyDefinition name="MobileMesh" group="filters">
+    <CompoundSourceProxy id="4863" servers="1">
+      <Proxy group="filters" type="Calculator" id="4401" servers="1" compound_name="Calculator1">
+        <Property name="AttributeMode" id="4401.AttributeMode" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="enum" id="4401.AttributeMode.enum">
+            <Entry value="1" text="Point Data"/>
+            <Entry value="2" text="Cell Data"/>
+          </Domain>
+        </Property>
+        <Property name="CoordinateResults" id="4401.CoordinateResults" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.CoordinateResults.bool"/>
+        </Property>
+        <Property name="Function" id="4401.Function" number_of_elements="1">
+          <Element index="0" value="COTE Z-coordsZ"/>
+        </Property>
+        <Property name="Input" id="4401.Input" number_of_elements="1">
+          <Domain name="groups" id="4401.Input.groups"/>
+          <Domain name="input_array" id="4401.Input.input_array"/>
+          <Domain name="input_type" id="4401.Input.input_type"/>
+        </Property>
+        <Property name="ReplaceInvalidValues" id="4401.ReplaceInvalidValues" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="4401.ReplaceInvalidValues.bool"/>
+        </Property>
+        <Property name="ReplacementValue" id="4401.ReplacementValue" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="range" id="4401.ReplacementValue.range"/>
+        </Property>
+        <Property name="ResultArrayName" id="4401.ResultArrayName" number_of_elements="1">
+          <Element index="0" value="DisplacementsZ"/>
+        </Property>
+        <Property name="ResultNormals" id="4401.ResultNormals" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.ResultNormals.bool"/>
+        </Property>
+        <Property name="ResultTCoords" id="4401.ResultTCoords" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.ResultTCoords.bool"/>
+        </Property>
+      </Proxy>
+      <Proxy group="filters" type="WarpScalar" id="4636" servers="1" compound_name="WarpByScalar1">
+        <Property name="Input" id="4636.Input" number_of_elements="1">
+          <Proxy value="4401" output_port="0"/>
+          <Domain name="groups" id="4636.Input.groups"/>
+          <Domain name="input_array" id="4636.Input.input_array"/>
+          <Domain name="input_type" id="4636.Input.input_type"/>
+        </Property>
+        <Property name="Normal" id="4636.Normal" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="0"/>
+          <Element index="2" value="1"/>
+          <Domain name="range" id="4636.Normal.range"/>
+        </Property>
+        <Property name="ScaleFactor" id="4636.ScaleFactor" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="range" id="4636.ScaleFactor.range"/>
+        </Property>
+        <Property name="SelectInputScalars" id="4636.SelectInputScalars" number_of_elements="5">
+          <Element index="0" value=""/>
+          <Element index="1" value=""/>
+          <Element index="2" value=""/>
+          <Element index="3" value="0"/>
+          <Element index="4" value="DisplacementsZ"/>
+          <Domain name="array_list" id="4636.SelectInputScalars.array_list">
+            <String text="COTE Z"/>
+            <String text="DisplacementsZ"/>
+            <String text="VITESSE U"/>
+            <String text="VITESSE V"/>
+            <String text="VITESSE W"/>
+          </Domain>
+        </Property>
+        <Property name="UseNormal" id="4636.UseNormal" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4636.UseNormal.bool"/>
+        </Property>
+        <Property name="XYPlane" id="4636.XYPlane" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4636.XYPlane.bool"/>
+        </Property>
+      </Proxy>
+      <ExposedProperties>
+        <Property name="Input" proxy_name="Calculator1" exposed_name="Input"/>
+      </ExposedProperties>
+      <OutputPort name="Output" proxy="WarpByScalar1" port_index="0"/>
+      <Hints>
+        <ShowInMenu/>
+      </Hints>
+    </CompoundSourceProxy>
+  </CustomProxyDefinition>
+</CustomFilterDefinitions>
diff --git a/src/ComplexMode/MoveMesh.py b/src/ComplexMode/MoveMesh.py
new file mode 100644 (file)
index 0000000..0966452
--- /dev/null
@@ -0,0 +1,62 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#### import the simple module from the paraview
+from paraview.simple import *
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'MED Reader'
+#f3d_gouttedomed = MEDReader(FileName='/home/H87074/TMP52/f3d_gouttedo.med')
+#f3d_gouttedomed.AllArrays = ['TS0/MESH/ComSup0/COTE Z@@][@@P1', 'TS0/MESH/ComSup0/VITESSE U@@][@@P1', 'TS0/MESH/ComSup0/VITESSE V@@][@@P1', 'TS0/MESH/ComSup0/VITESSE W@@][@@P1']
+#f3d_gouttedomed.AllTimeSteps = ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '00010']
+
+source = GetActiveSource()
+renderView1 = GetActiveViewOrCreate('RenderView')
+# get animation scene
+animationScene1 = GetAnimationScene()
+
+# update animation scene based on data timesteps
+animationScene1.UpdateAnimationUsingDataTimeSteps()
+
+# create a new 'Calculator'
+calculator1 = Calculator(Input=source)
+
+# Properties modified on calculator1
+calculator1.ResultArrayName = 'DisplacementsZ'
+calculator1.Function = 'COTE Z-coordsZ'
+
+# get color transfer function/color map for 'DisplacementsZ'
+displacementsZLUT = GetColorTransferFunction('DisplacementsZ')
+
+# show data in view
+#calculator1Display = Show(calculator1, renderView1)
+
+# hide data in view
+Hide(source, renderView1)
+
+# show color bar/color legend
+#calculator1Display.SetScalarBarVisibility(renderView1, True)
+
+# get opacity transfer function/opacity map for 'DisplacementsZ'
+
+# create a new 'Warp By Scalar'
+warpByScalar1 = WarpByScalar(Input=calculator1)
+warpByScalar1.Scalars = ['POINTS', 'DisplacementsZ']
+
diff --git a/src/ComplexMode/example.med b/src/ComplexMode/example.med
new file mode 100644 (file)
index 0000000..3fee74f
Binary files /dev/null and b/src/ComplexMode/example.med differ
diff --git a/src/ComplexMode/harmo.resu.vtu b/src/ComplexMode/harmo.resu.vtu
new file mode 100644 (file)
index 0000000..c2911b9
--- /dev/null
@@ -0,0 +1,71 @@
+<VTKFile type="UnstructuredGrid" version="1.0" byte_order="LittleEndian" header_type="UInt64">
+  <UnstructuredGrid>
+    <Piece NumberOfPoints="309" NumberOfCells="378">
+      <PointData>
+        <DataArray type="Float64" Name="IMAG____ACCE" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="1.1899426062e-21" RangeMax="5.6948973698">
+          8DkAAAAAAABqleExIn6WvwY4M4H6spE/viNKOxDWS7hrqr/H2TupP+/wu/8pR64/NhC+9Vh6NTecQYN87YyDv04NILnpZnw/E5Voh5yJfDgBk3KP3zqpP6O/5dgwRq4/UlG8scB5ZTfOwTY59AZzP57xqr0uCnS/pX7tp5O9gTjcqD5sqDmpPy0Srx0PRa4/AgpxWWp5BTieNEi4JXaVu0AZB2NeuXo7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAg0freIqyZP9w8apV7cZa/YGAEbTUicDgN8pnpgimlPz4qNRSnbak/ATmv052ATTMnvTJkptGlP31Dy+GhsaK/bj8V3RHNNLgSn5nr0G+ePwbzBJnrV6I/hhhp/uF2FbjvB/gnhrisP3AwiXqIaqi/sdblAmzRibhKUkG5O0OXP1kLtaYLI5w/iFh4bOUjSDjzAlv+usSwP7z2JFhYY6y/QNwNulFqdLjJQ9IjVW6JPxtNxQibIo8/JOoNjmoWULj4ONwNIXyxPxdVpQKvja2/1F3B6OHQezhr+dFJH4Z2P4/xx59Sfnw/JJmlLmP6gji+svJdiAKyPwQe3nVWYq6/7TsnUWwUQThbDSouls50P8s51lP+cno/BJSqoa5VmbMwPHv6QVCyPxH6OCS/3K6/8V4hhM+LxLiACnH/eaFzP4BKqmYDDXk//7sqwfJ8i7jnJiVp14+yP3nKlyobQa+/i/WoPEeMWDjTbONdhwhyP5BIV1whJ3c/S3N/KfZIUrgh9znzBAqzPwykAhQxALC/Qp9oK87Bijh/hnxz7a5rP9A3HM2fLHI/AN1voJTRdLjppkezCDGzP5WTz9srHrC/uD/GMziyiziMCRO1IbhoPzdPJ5gZanA/fOfJLr5TSThQdkeYgXmzP0s6UgEfVLC/GZaKPZHZYbiGJ1dKb1FhPx4b16WfCmg/zUJp1Mnvcbgtr2mrxqqzP11d07SIdrC/81irq65EgjiaJPc+R0lTP8JcvyUe3F0/5U2yE8rvVbg1+FozGbmzP5FJCUd9f7C/CTdS8DYqX7hosuwZsUxCP23NEiFk01E/kCuElY/TgDjt6vMkFr6zPyreWsB+fLC/832H3+5MFrg+4hx5555RvxMTMyKS7Eu/Ee4omBiSz7fN0ajxVrSzP9/PtCtscbC/cSumr8Yyljh3B7mf6idcvwFZuEaNeVq/dsE6r2BhcriM56P7SpizP/BJ398XVbC/FLo56pyyQ7hUhsdtv9Fkv91yfj/9PmW/B9z9YY8FZrjqc4NBw26zPyoPnOtrLbC/gr5OzI4TpDiEBMzW24Frv/stGgCOMW2/Q7I1Q1OSWjgddVD+2UyzP2j3cWMJDrC/NG2568vHSbhhmU1iOlVwvwGXjOKeqXG/vxflSWacTLg//NSdctqyP3AceeVVTa+/RejCq0bNczjFC5cVmsZ2vxMNOCjSUnm/bJ1HBc5tgjgb7m+8D56yP5Ds0qCZ4a6/mOXE1oixobh50YH63yt5v4c6Qf1hLHy/HT/nkLSyULj+Q2NtAAiyP+Uh63EL162/yV6ECmDGajjFSRfkIbp8v5W0V6/9M4C/N6c8GkpYjDh4PdwJHFyxP5OZ42vhp6y/1KENMN7pabjjFknydAWAv4piodq4LYK/gMRJgv7H9LcV1rceTwyxP/SIscwkHKy/wMXnrcjCcTgarwzziaqAv55bhN6X8oK/rmpqbEi3b7h8WYZbwCywPxLlY6WUlqq/8RqYW4gQdjj4PFkSgm+Cv39tJIE4D4W/qm/IEGGCZziXxvWadYCvPxIn2DfD2am/b6DfSI2FcTjI74X5ChaDv99b4Vkv1oW/eEDEDwBDQzi5gEi+vniuP59vhc7C86i/NKYmVmdeSjjkQzb454yDv1Xum6RgZIa/lZ0a+UCfJDiTHdmPs8GsPwM9zcxmdae/76mh+HlJjLi42aepQjGEv0anuMuDKYe/xkmnxovDNzhtGx66kfiqP2K6VFXR7KW/n/VH2x5nDTjLoRfSEA6Ov+trtifGgZG/f+a6pdHEMjgKnm4sDDamP3Ow6e7X36G/grdFTfCeejgVKa1T+oWVv3JoNHSlTpm/++P4CEosKrND5X91olGgP03SCJWZwpm/+EAV0CQ1gLhxi+II8p6Yv4b6alw1BJ2/8LkbGwN2FbgGN38IRhiWPzEKRi1e1ZC/wHaOSTzbcLg7kVRGkdKYvyINaJ63OZ2/VHlr7NV2FbhI3x/FlYGIPzhTc+GN9YC/hPHujDm+XLgRuXr9ih6VvxX6mne3uZi/eMwBML8Ak7NuzdcZ0jqBP7VT4YCcgXW/KV99+JWafjh9OQ8dkzeUvxS+DHMAope/N9aneKcQMDjo5HHcfqVaP2JWvZw61EI/jG1TdSBidDiuo3YD98SFvxYk6xftr4i/UgRDOM92FThq8qDKHh9Mv4LaBRRVSGc/QlzF4Fqjaji1nsUY+P5iP1Njr91Phm0/jbqXVKtvFThPse3T0VxdP9/2d0NxyFA/3+nZ10jlcjgqFeEsPZ54P0KAENp8goA/IEJ58flsFTjZOioyjU2APzt1htXjwG6/wWPfJjzRhrj8M99ot0SQP9y/fVD6eJQ/U30ZiDsUMDh/0xDM3N6UP9CSZ7qhD4y/8aoxRbvDhLhwbwl5fV+aP0XEytAeWqA/XtLm3NF0JbiQ//OsHnm1O0f8Y11R+aw7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAICB0xDM3N6UP82SZ7qhD4y/pRe6pjx5l7hybwl5fV+aP0PEytAeWqA/dUmrlEEXULiKkRNbs4CkP4NNdC1Aap6/V2SCVQZzdThYAAj2LLOgP6Zhy5cTrqQ/M0xIWsJuRbgIGeQGzEGuP+DQwYqXHae/Y/YYVKrtYziQ1A9C8k+hPyDbWTD7pKU/esIeunRvNbi4nO3l99yzP6azx+RXsa6/l2dphBSjdrgxoguwl9GdP2Mgh1bzGqM/W+Zt1N3LWjihp44Uf+63PwsNjVpQf7K/pwdKWBW5g7iDZ8457kySP647JC6DWZk//xqK0QJpXbhf/5anIeK4P4rQ12QSMrO/RWbC7XA4XzhC9KzbNF2LP3XlaD/WIpQ/k75qk0oxdThgwakkNke5P44cjWA6ebO/cVcLxlu7Wrg1XV8aTi+IPwqJYHVaVpI/wDY5XPW0PziEn5iu0We6P4bA4c/eOrS/+RXAlwFbY7ilTiVAbNyBP3bFDJ/4f40/kJvHYEfFhTgeiAsxqPS6P7WJPwnck7S/TWsJVP+HSDhQIVzas3B8P9zKqt0lXIk/AHKAr+D3ZTjbwmylNzO7P6R6oKeJubS/pcYfOc/iYDjQ2us5gSZ5P/n06NfsfIc/78HZ2M6DkDiIE7y3K7i7P+s8vC/cBLW/rNh7rrGUbLhhltU+lmVyP4Us40bVpIM/t+O+CJBuP7ix9mrVe3u8P9cle9nzYrW/6GC0y3bmerigSo3mVr9gP3EOBLFy4Hs/aqKBfHFrpbi++TcPzi69P2U+fe0dk7W/T+iuezEDjriJPblZm8JDv8nQWMc9Fm8/ya81hgN+aLitQEA2RHe9Pxv8qZU/s7W/U7dfAiPBNLgY+32Yvoxcv0qPPBbIfGQ/YBE4ibOBd7huRbVh76i9P2LIOwCyxbW/+4/7ZzZBdzifhSbRh1Nlv5mT+9Mh+Vg/cfYKGmzj5i90D0ctM8a9Pyainujtx7W/7DakwVJRxDirW75PMeZpv82XZtiwNE0/EIW55hZobjhCbGsBdMq9PzX3lfS4wLW/53Pji5VGVjjVxXbH8eVqv5PT8xVnrUg/NcZuH+MIgrjKhT335du9PwwmR5TVeLW/AlmaNB3Tbri1jBNyjfFwv0hfEnxmziq/XKpO7QfijLiFIe0ERdy9P3SxkMhFbrW/w4beYvufkjjgU+Ph0Vxxv4dQJ0a24zS/j01tlb+3Rbj9k83DSe69P1SdA/wTZ7W/7mzIgfrpWbh0eYUxTUt0v8C/FZg8S1K/kPINQdxMaTg5qTha4Qa+PxDGx+dkW7W/PkwuHsPuWziJ5rtdbe95vxWY+PejsGW/yWvWrMSsWDiqcGDcKgi+P2bSBP1LRbW/i1at92cpcTg+XUCHfPl8vznL5vEobmy/i54BqF3LTLjjMBs5ngS+P8rqthAsObW/qvn8sq0SkDghiSLCxMN9v7oyzh4TLm6/gGJRvYcRIDhBOcAFTeG9P9rJPfQY87S/9Dft8hnavTjAS4N/YV1/v+7iOG7B2nC/ye00hHpDizi0k1LdfNu9PyqocVZE5bS/VIa1iUL7S7hruUGtoSmAv/86SiwP6XG/cbMPJox8TrhCi0WLjtO9P+JqGUoi0bS/BMN9L/KjNDjwDrdXfjWBv1EcZCsrNXS/GjGP5a15RbhkSc1Tgb+9P3pcavoFprS/zmvklVNhWrg8sbvRBauDv2OkTwTll3m/7YhIIiZubTgbfzHGI6m9P10ZKGmWgLS/rdzqZfGg0jhqEVcgiO6Ev6KpY+SBWny/MGzKxl3wg7jFDFq06gW9Py3Ij0Cbk7O/hI7GUSHiuLgltkQ/YBWGv4qd/g3j2H6/DYEctUNXGji9Ya/qFN+8P5GcU3BuX7O/0N93vPzxbLiy4E2Ml8aGv4SLJgZJKoC/Ba7zm3WDaTi1UhvIc4q8PyuNfs9W8bK/DMstEToEcrhaheBWISuIv5e8AXXzpYG/bkD2gpIFQjgthWtyoSK8PysKLrxoa7K/IGO+JZfPrDgotWMQ5VSJv1GMo9Fs4IK/WLypSjekZDg+uGJrYSe7PxRaPHXaILG/pmwlVDZLsrjp2c+9F3uKvxVSRmNzEYS/CBl3qzjXfLiQLbARsLS6PwpEPiiGlrC/LCXFRfmtdbjIq0zOKnaLvxzgCgwhEIW/0nKmI0K+Wrgr0GxbyAC6P+48DQTjj6+/E6Vd6OV5fLijmLMWFkyNv0nFl+185Ya/I4lRyKirari+5kQ2Kn25P6g0gMvqWq6/EU8g8zgZzTgluVzfh0WOv6Xo0aWX2oe/ViImL6gKkziFPVaTSz64P3nmpWDpQau/WfuEzv0BizgyG/7IvWWPvwfNC0g67Yi/9R1Riulgazg2HF/ygZW3P/S5rfQCx6m/MWyKgGORerhK06Z80UKQv1xXdwT59Im/OdGz8OgSZbj7B6xbTOy2PyJ3C5ozXKi/kZnW423VObiSWUPzUu6Qv1exThSyJ4u/6aLW6XCfOrgVjq6qvpW2P9jw6ayaoae/38zejs7AxLgrVpCTOkORv8/+ZxauvIu/1xmtF3JIiLg735g45k+1P+AaAKx0iKS/OfpkSwWvrzgk2841LM+RvxkcLsUZqIy/06YaeIfXS7hZTya9teq0P1uSyEvEvaO/h0a1zrqcYriQXR38ymeSv+Q3Ei5XnI2/+Gd7PGYcQjjoYbS8tjq0P3f1Hfx9bKK/hxBE0uIpQTgQvt06FZGTv3Ah8rjHbI+/aUEUMj2iHLiYaxJ0luSzPzQqhmDJwKG/Vi28R9YLQDi/JdBHtg+Uv8sWRnwEF5C/81iNtIRYYbiDcLyhsrKzP8IyoBhSV6G/fvqMyYERtbhM7uZY3UmUv9Jqd7PMQpC/u34rPYWxcLid39dkkg6zP4W9jcTWkZ+/U9AVGvvJ0Th/4lr8U6qUv5oowLw5iZC/ZxXW6LEqgbilwpBfU92yP1HRN6+nvZ6/bVFXEvZSl7iW/GNz6NmUvxgBp3TfqpC/eLSRJzEhKTjUgTKn5keyP300DPWTXpy/fOznjrwbjzgvW+p7UJGVvzdrTBBaKZG/jlcUT5voWThm8r1tY02xP5s5Js7EiJi/usS7Ru34bLiaqPsqG+eWvyKGl3uRCpK/kPEn6MYmS7jATbGmZK6wPxmIq8Tt8pW/8oQ83z2EsjjtDKrUf5mXv0jecuRsepK/exlu0CnLVLhM8PdtCXqwP7YI19N37pS/vFXECiNcNLg7L4iUELOXv0BsA/PtiZK/f7ykk6UWOrjzbgSJK56tPzsdrkstPom/52dd0mrfcriGPyNND4aYv83Ybthp+5K/3ASq/IU4griCfTVuazGtP0eeNU1LH4e/R/iqHXp5lTi0xra8faSYv03oXYObCZO/QIelO8unUTiOYY2YfBOsPxmT+i+uK4K/4ScV3bvDVjjFkKVM6TCZvwIC8tI7R5O/7qgfjARsQzjTIV1sV7mqP563TZf89ni/EDEfoPtIBjhHEkGC/wuav1BvxX0Rn5O/zLSTAMWUOzg7OuF0FQGpP6TJBccqcGS/5jcHKbU9s7jWrHPEZDKbv4k7ZD99B5S/ya81hgN+WDidvP0Yn1SkP4qrKyN0l4M/Iaq2trSQizjaBsMCrgCev/5/ms/topS/M0Fr6XEzXrhHF8gEzuigP4qJaiezcJM/1J73et5ojbh6kv8GcWagv0f/F/atu5S/1wQaBdRVQriEFXfNBx2ePwe4xt3b/Jg/vJZ4Y0aJO7igrMQzDGmhv2yHoNI0hJS/4BhmqJqfBLg+fE47+ZCcPzRDpOH+ZZs/RkbyeyrDgjhBcNUWeeyhv7K1p1KoU5S/wIzeMXhSRTi4Bnu2mXqZP2ByPL8+PaA/Hd/zVUrHfbiFEqbWqhujv6PGXrnzuZO/kZvHYEfFVbimMLVd3l2UP4MkyXCWBKU/fH9prp4HdrjUhlJqhVulvyp1E+LB+ZG/G/KvaHGddzhnlMveLOGSP7Ro4Zz1i6Y/ZpARHkVNYrh4YdTVdZimv8nN+siFtZC/kb5qk0oxBbjbcHlIfyKQP19bZXxs+6k/+tdKv9ZMa7gUOKCsSXKqv62YV955QYi/KeC1grZiJbh21r+EsvGIPz/3b3Yp47I/rDQkGI49abgspvpB8oCyv6jKRv27+HQ/6ILbqNggbDhqnw7k4iWQP7IPKxDVnLo/s0qPbvcAkzjXKCAno2m3v256jpVp4Jw/4nOVfr9rcjiQzhhkU/ugPwvOFMFmM8M/gTLNsAocf7ihpIwdj7K8vyZCHhP2Q7A/Q7EQXd1oXbjJB5hfBYaqPz1ftqm/a8c/P9r2s68Uo7j9MEW0IAy+vwViQZgsULM//4TGddFLobhEheyWJvSyPyWrFie60cs/MSN7MubotriBfcX51U+/vwS7RA3TwrY/yWcxxnwOZTgqXVv2QsfAP1NXo+GDL9I/63U1b1hIz7jBDAdjUwHCv6XVFjv7WsM/7zSdNoRscrhltu3vjCrMPzb9ljCeA9c/NEZCAdktqbhf6QTOxcvDv5xjARNr9co/XtLm3NF0RbgVd5EjwXnFu6Naatx9tdc7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIBltu3vjCrMPzX9ljCeA9c/JRcMPI8HzDhg6QTOxcvDv5xjARNr9co/rAY6O/h/nTh2WUUZtZbVP4G4ey+W79w/fCWwCqiHsjjrVPUvShTBv90zXqbYsdA/QF/a8HLKmjgzltxn5h/dPy2/6203V+A/KwlrzU/Gqjjdgb15MpWlv9RhMlIREtM/Qfw9owYBszOUJWSbjLXiP68xrO/AoeA/PCkaDAZJwLh69SWgrtS9P2QMqXoUftQ//xasadp5rbi6BUQ2CU7nP2PG0owVgNw/Bb2/Jr43pLjoCVHvEH3WP8j2JUmf6dQ/irZ79aRjhbinIUjyYcPoP5TNwxY+i9k/SG56SsuGhrhqIr4Rj7nbPx4yauVf1dQ/2B0g3e/JX7iXovJ9A3zpPyVjh8v5xtc/vs3+zu1Gszj9YAwED3fdP9vHDPaQydQ/VAyF0BnmLrA6bDOyZunrP+OEYHD/CdE/+9Ic+NtWxjjthc6rN2PgP/ZUal69ptQ/mvD2ttd4ojh1ze1SDE/tP1F30jCSh8k/gxGK8y67oThYlgUpJU3hP0if00gnjdQ/U/tajpcDn7hsxXS/MQDuP5iZ/ikAE8U/3LXMdPrjzzgyjRI55LThP+O2zfWYgNQ/PfTSqK3BkLizL2ZdmKfvP2T/1Uaw1rM/WhpxBHXjjjh6RcMOCIbiP5T2gnQ3ZdQ/0JfUBWD0dLhqyX5dcFzxPyfjsyUZpLi/mh8Ve6T+s7ihVIl2LrTjP5WCpmhbOtQ/jRzd0Bhiojjl2ohCHYHzPxha7XVmF9e/IBU4Nl2g6DjDr1hAgvPkPzImjQTfDNQ/g8axtQPImbizH3YA6iD0P2gL5zWN1du/S5ZBOcBytrg0ZcXtsnvlP/PZgKv2+tM/BpUBNSG3nriMP64xFqD0PzPmQOzPud+/5av8zehwoTjc8qXAbuLlPyt4/RUQ7tM/6qgfjARsU7igwEITdRX1P4lqDmRgw+G/7rGdcQQIxzjceWDOAyXmP76VNWUR5tM/XdW6qffSpTjgwV11gEv1P1FutLdtseK/Fwfr+uDctzhWIQbGjzPmPwvc7q9j5NM/P46krJwHwzgFLHyxL/n2P38G7VinNeq/xU8Zl98b0LgNSag9O5zmP2YrNRIt3tM/dWJz+PjNvrgQbHee/DL3PxeO7YmCN+u/1aKBUNQt3DhVfXMPr6jmP3n3BhaD3dM/A+jsdwouVjjem4T4sgD4P84JbcKqcu6/us3SFiimyLhNpHoEy/fmP0Zd9s4d0NM/hvW/Sxy/g7iHAoQz7Vb5PyiZme5N5PG/JCRKWtEItDgKHN8mC3jnP4+VUJEmnNM/pLzeI2q9o7gm5TM9eiH6P5QzoLjVivO/nkdXtI1mtbgBnuyWyrDnP0BTokmrctM/KJ73Qch9wDh1HBc9LGL6P2v3xuFGGPS/x2zUAnju8DiGaWzit73nPw+iXmDkZdM/V2JRvYcRULhJlO9oYyj7P808oAHj9PW/b3jXppy/GDmQPzimg9PnP4KiUX1YR9M/JZZFDPue2LiFcPlp7Gv7Pwq+wvLBifa/Dop1oZfjtDgxJF/K9t3nP9y3Lf4tMtM/KvkrDPXRYLhTFK9csOX7P5wT0rZrj/e/AOvLJ/zsk7gp6rW+yPHnP2UUxLHiANM/O7nRi/UNqTgjPGXIk+f8P0uC5Nk9uPm/r6lpRgGUw7iKp8rQEBToP4ALH5HGf9I/9d/5pd0lqLjCJQsYknr9PwqJ+aWZAvu/pISHc8fJE7llr/ZIBh/oPzSOuQFBNtI/GBSb1X5SvzhowGb5wyL/P3A2bjRWXP+/OPtkCgrLBrlmg4uZkxzoP0CI3ZEP5tE/YP6FP6guzrgPuuEg/Z//P00R0GiERwDAvuiXnR/xkLiGbkBLMRToP44iArehrtE/NbsTkWZJvDj/DdZJs0wAQL37LipNfAHAQbmdR+CVsjhq9VA+LvznP7mCNBWyN9E/fBm3iJjnmzjg5OWQ1McAQLoU1obTuwLAyxcR4pHDIjnl5myTHuDnPw1zfQcQzNA/NRkltBRZwrimIJ1vtaMBQKoUXOnrKwXAraWVhWfb+Dhh29RJrLbnP0vzEfe1U9A/qCNxyUzAxzj+YzpOhAYCQMUVGpTjPgbAVc4PwZ8v0Li8TnjO1ojnP5Usyoogxc8/nVl6LdXwzbgA3x3fXpUCQDAq+cZa0AfAsvUBLPyvlDgra5T36ibnP0Sw9hWrBc4/GJaCZkO+urgVBIVTqu8CQE+YCndT2wjAnaPbfPvmFjnMrfQBj+zmPzLTt6CiC80/SEDvbZ9y2TgmL5jBUaoDQKieoxohLQvAjiGAm6BQAjmwjLeNP57mP3pMuqPm1cs/WL1ffo5c1jhl0p4bHwEEQJab2gZRRgzA9OVYGpoywjgLfN2To0XmP3R7NkJejco/d36aXFGFzriazDN1900EQOkqMXkBSA3A/WkKniOUprjznT0esNXlP8wv3UV/+sg/QmPlwJp+njOsYYp1EnIEQFFrBYyRxQ3AmQ4n3Q9/yDh2oR1m9JvlP2iZITrxLsg/AAAAAAAAAIADJkoDyfYEQIzlNPGyqg/ANGps5Sma/ricrGLFKTblP3x/GTUn1MY/gsNtg5GFmbide7ezThIFQKVzeamyDhDAOTKEgYi1qjiuelcjlMDkP2M/m9d6T8U/59MGtVGLtzhqS9w2yTcFQDUxy15vZhDAqyKuz8OSkbhuf1E2UNbjP/LcAoGBUsI/A8R/aarTnTiXeop/W0gFQAjT1HgskBDAQkg1udHBsLjRrCT2cXDjP9Y/eXuKCcE/M/9/DV5rpbifUgK9L1IFQFzlloMiqRDANVxC0N551rhM01IVIUHjPy/Iql6rccA/I2blywaodTj2ikQK73cFQJyB9WJ8BRHA9SvVOXDxLLme2Diq0fDiP4Kk4+YP5r4/TFVcJqvV77gZFdnCyn8FQJL3hkN8HBHA6SnUSBBUuzg9QZUZbcjiP+WOt1S+6L0/sOC7jG0anriHbP4RV5EFQMrg5r4/WhHAveSFf2Coobj4yzcUpyriP85NrzoXE7o/ztCggZOB0jjk3i34+aEFQPb6s/gysxHAlfPEwq22f7hJ9aCRCP7gPwLIaHJy3bI/n10thYd307j25uov0qkFQIN7pWGS6hHAX2AjAO+UCTnGTaRWn13gP3CRK6E5I64/yF7+YnnGrbhWDsIckK4FQOh58gnZABLAiOD8m6ZYkjhyCy31UEbgP7ed11EmC60/2c5/DcX2tLgCH+kEAcsFQI+nAWtYrBLAXxr/QKdTdThTbqXWF/3eP67kqbPG4KM/p4fT/IMb9rin3In8a80FQClyXgL+wBLAubGR0Ao05bhkME8RScLeP8Y1053mjaI/Qdb1vuSikjjCmG0skckFQLo9wTqw6RLA8gTiQUZ6wDidnAGs+LHdPxZA4xDj7Jg/kq+gtMij7DgYlQfrjrwFQI/Y++XqEBPAmzoYmoxPkTgs6MH7WQfcP/jTNOv9/Xc/wbSTAMWUezgTq7gbHaYFQBD2muiNPRPAZ4g3ZRcNCLmThq2Im8fZP+n0IOEfSpO/ie4jeCIp4bickQQBGW4FQHvH28kF1BPAxc/qayDGszjaG8bCGkLUPyzICcL857O/7LL8gGUCxTh/9cIqchwFQNj2HTA7HxTAThqVTZty1LjaH+pHeJTNPxC3TAlSKsG/N1cxhaWp8jhPPFrO3d4EQPajpxK6ORTARMd/W0zGuzhEuGmKPM7FP6kS5yaYKMa//pLPfHEArbiT44iao8AEQFWAIcMwQRTAfZW1p7f+yLjUyvFZq+fBP9SQdrPaoMi/MWeU7KV/3zh/7AWsE3oEQE9szwp5SBTAHX0F5P+hijgF0M4CPhKyP64TE0VELM6/FEbfiw8fxDhAqCCDmeEDQJuzkVgkPBTAj/9y34v1yjjbEalXDRStv9pvBEYCDdS/Blx59WgC4ThsCK3YRaoDQENa1XlKMBTAifsrAe4Cr7if0tEJ6uS/v4lx3AJcoNa/d0YREvpd0zO5kL1Vex8DQM5wuOzMARTAwuR6USRmzrhQgZqY+iDVv/RJpi3LSt6/ORS687pn3Tj1qIvMNw0BQBpZWrLk+BLAVMa7j/Nivbg5OoY7cz/rv9gn9MJpUui/QvxDrUHFtjgYItXMCYr8P3eSRkL/QBHA5Ayirl600DhqsISrIzz0vwWs9qWVru6/REndt60kzrgsp6fNi4z0Pzq85LNl6wzAjvD/qaDZ4rhuYFdu2In5v5nOvM6SHvG/3xoJSqcKkLjMGX0dnrvuP4nkeX0PBQnA66qJiJ1PsrgHOZEa+Vj6v/L13PsBGfG/xhSA/wqsxDgajDe92HzkP4xsJqceCQXAWVLIohsHzzgs+SkzS5r6v7PIJCtkqfC/xkKgOBC9qrivsLC6DLG+P0Jw9ZVQ5Pu/LmGGho/u3DjtOFUyMG/4vyXvZmbtOOm/U30ZiDsUsLgf1TFa3TfPv+RCRYB2Hu+/qg8hiZ1Z0Dil0gm7zVTzvznGi0Pcytu/XtLm3NF0hbjcsm1MkY1XO2v/xATitBE8AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAh1TFa3TfPv+JCRYB2Hu+/D4BnEgvKvTii0gm7zVTzvzjGi0Pcytu/bnodTW3RqrjZvSvS1ArVvwrN7azxYuC/5/vUmacO0Diz5OjyMRrrv7CnYWXaUbe/6b1a6f1poThLBxJCBpbRv2tOQwnGstC/nSQo1ys7zDhGMrwGY3ngv9lJyiZblMY/3BGXi5cTgDheNDo+kr/Av+7h4HA2JMG/VXo9TSRkuTgaShcm9FPNv5ueaAfPe9Y/0CN1f+sTkLhsxcYiMSmzP4jJJwt5HLy/59PAaRaMuTiehU48wSl/P0ajkJVBIds/6MgcuLsKkDgahsKZhlDCP5ku/XWj8r6/2wGsIxBmsDjO73VKi26wPyqqAJr3FNs/3h0g3e/JX7hSRL/LIYPGPzmOyXMna8C/UzJiFLjFxzjbUmx8caO0P3TzMNqz6do/1nl7PU4jVbjLRJwNnA3SP6bTKr1p8MO/i7m4Qoq1mbgtkblDwBS7P/o03JqXMto/9xLRPmQcVbhFobrbleDVP9JpKuY6QMa/4lMeBfS30bhYrsgQecW9P7zCE6JZldk/Hxa5EC9enjgRY0MwNbzXP6FfbwSVcse/4vstgQOlszgpnw9Oe8i+Pwu1MPnbQ9k/7hhmqJqfdLi+8E1WOhTcPznP9kcLYsq/iOvaEzaDvLhxDntEqjfAP0+aGDtxhtg/AhkbB9WJqThf0yMLQefhP63Eo+HW/s+/di3qysIYujjqmrIXou3AP+VPYNeaNtc/YQx7QZiDjzgyVQMQLfXmPwfMBYko+tO/xgjMsPSCnbjCv8EvvhTBPzbuEhDGh9U/zDILgQJnsbgNTRqJxbToPzlwizuEh9W/GyEng7L0ezi3TReHvPfAPwCTyogRutQ/L2i4XagWXjhEUalcdxDqP13Mv0m7wta/t/qLl2t2gThiTE9t4tbAP6c49lzBGdQ/voJtiUbriziHP5iydzDrP8woFnmxxde/fQphYPQs0zgqw+DE67vAP7xDZvs4r9M/YV+HT2SKVzi/YesPCqDrP2yEEK0YJti/lhJPFCWv1Dg32RowKLXAP0wHpiOMl9M/lC2YqpeHzzhTvgMlAgbvP3WKLt65Hdu/JYajwAgP2rgu51vj73nAPw4gfKUT6tI/KpVeFNyQk7jR72uoPHDvPxTObQqEe9u/aj7Y5QuQ6bj9AT0ZUHHAPz+OAQVz1NI/GrdrH+uQh7hXMFQxClTwPx+rcSthpdy/eVgX8prAkrhBiDyd3jDAPw8GrKr+OtI/SfCfcaqefThLlmYQgUXxP/xknIPRg96/lO4zGHrgszgCBVr0/VC/PyNkQpBNDdE/wAYM2PXXjjjJSKNM6NTxP+TSeVupod+/mw4sN4cLgTgyLAKSR7G+PzNltAFyZ9A/DlJ/A2RRXbi8BidxUwTyP0EKG2o7/9+/ucQHpTG837iDU5XH3oW+PyXnlvfUO9A/YilHdVCJzrhOCDPeR6TyP4WGqWNUmOC/RCVA7+9z2jhig/5l3Sm+PzW6870rxM8/0Ulsrvx/MDjEU9N73tPyP0uryzthyOC/FPqF3zZIxzhaMNvl/O+9P+ZztHTZVs8/vkURvqf3mLjHEfLBKCXzP+h+p02LHOG/DEgk4lvSITg0npxf0G69P6lkQj7+Zs4/vUbroBcFb7hIb+jDO8nzPxnBg2cJy+G/I8/HGTLaqbhXIWXiYTK8P4He1cJSLMw/4iesSyXFm7hBeZUwDCf0P1s5vliUL+K/w4153j211bjFQZaR0Ii7P+CIVzZHA8s/qEqmL43Xi7jSNd0k+Vf1P15gDRRDa+O/HhFTfhpRELlQMRb1tOG6P57qpJVv7Mk/jtwkLqPR1DiWODU4SKf1P+XpceNBwuO/qZnfZt4FZjjj3rL7S3a6P4ygQTclQMk/tWoAqYcvZriHgL/fJkH2P71kf58ibuS/O+bSm+GBgbgbFyQx3Ja5P132e2LY4Mc/BBF6sGWakjg5uL9C6Nn2P7OA74UYGuW/nudNKMT97rgp/ZX9+tO4P4j1VexGtsY/NRkltBRZUjg2aThza/r3P3cAhWsWW+a/RSC45Poj5Tgjwn13gQW4P89lp8y7hcU/FeXPb7mms7jalnalS2/4PyZoOY/85Oa/Uk2LvK1xsDgtV8DyzUq3P0/gEoubesQ/JysjNSYTpbgGqVR4Nwz5P36iLFGWp+e/0VEN0b0JuTiyBS/LKOG1P829/YbofsI/xYsu9/HthDiuqxfwEm/5P0ZhlLs2JOi/60T5FCMv6jg1DNhbyxq1P3XbYVtPbcE/6aMQXCmUmriRwfGeEkf6P8YjPayVMOm/71Q79VfyJrllaik4CSu0P5XRCN+sKcA/K5ELt8lcwbgaX9oTEJ36Pz7khLC2p+m/KtUxpXzYsDifx+Sw7jGzPzeroBO4v70/eDVnOzGdi7gvQ0u/U+D6P1Kg74B9Duq//pPdS+bXizgGj7gLbgOyP0haGqC/pro/s1QIcxJipDjqzArsbv76P5KIGWq/Puq/b5XF8R/bljg8t1OJoGuxPznIhCKXG7k/mzDl6SO7Xjh/xj5zd4D7P/XszvIK/Oq/Wtt6Upnh+zilHJgg82uwP52Iu6vWiLY/TGsvJtKttbjewQANoI77P5B1MFOJH+u/fl1bxp/BoLifcpwDk6CuPyFELiwZtbM/AnBe8Wxkf7jTZxhNcJX7PxF2K9INTeu/7n3aQZoxjzgMBYuZm0iqP2LOKOUeZKw/mjZmVIjcl7imTm8o0Zb7P5OBckdSYeu/Pf7mJu7fU7h/toLGQGyoPyfvSOQrsac/smJA+tO/brjZd//7p5j7P5aVb03gbeu/ZSFrBDJJG7kHNy4XzZCnP6XFIcqAiKU/QtqQtQnwjrgSCaEZ/qz7P93IcV8lo+u/1lKc0bIMUrgbtt7CRyKmP6f8fd2A76E/i6zGraIxoDgylTehwKz7PySl+tVKreu/5geQsTDEqzinDiNFpmylP1BBEObMKKA/ablwVNsPcrh0PBzD96D7P6Z8nZneweu/JrJNlimmbjiP5j+0wa6iP+lDN9aoo5I/fE0zoIaGeriSuuPAOXj7P13Pnxjh0Ou/P9FxAr6bWTh4XMSNuBqbPz6Rs4sBNXu/03JHl2HWmLieuqSijVv7P2yoP++01+u/B7In/Lkwvrj2cS1NM7qVP+p9gC/sDJS/1n7u7d5UdLgZakHO21b7P7slQ8NW3uu/ZW7T07UPvjgowXUIcfSUPxprmx9R8pW/4Wczo50DwLhZokD/0SH7P4NUURdCBuy/uFh3zLr4iDiZcX4CqQuNP1eBfLvH2qK/D8m7f5ooojgimiUGShn7P5HdGDCpCey/bRncgaR/uzjd2Z3PJTOLP/HTppOe+qO/uvsnVpeAibiES+icD/P6PzZ6sl+rAuy/eb7iSfKikbi0h9UP+LmCPyQii6nfIKm/cH0v0gYijTh1dRMCAbj6Pw2ckLqq7eu/CDqP7A6IrLiAw8ffJ21mPyL3gJuaibC/AOb3Hjk3pDi3wPan7GP6P7ZOEbPcyuu/BYp2sddlsLhG/55sebN3v3fjqqp6zbW/v2jCwVwUZDSZ52p8IYf5P+fI7Jk0feu/k0awIz3TcbjFsH5Eh4Cav3LWP+v/CMG/gZgErXiqtbiuUITxNKf4P2sE+RrvDOu/zaVQe3H73ziC//q3Ju+mv2X/zHbpuca/SXTsBjLiuLiMa7ucPhP4P9QMsrK0uOq/2SqqkmHflLgs6tLGLI2tv8FymhfPksq/FOW23dnItDg/tGMhgc73PwRxKJh6j+q/IhXyvgahmLjOtyspbWawvwIGR7uLc8y/lhK1vW0XcrgpVWZITDX3P7Or92qYL+q/TfUW41kVm7iYFaUkUwW0vyotzfq9TtC/RlfMz9VwpTjCEvsIN//1PyIlbR8TYum/sqZzw8UMdLiEU8SQqWe6v/NDzugZ8NO/UtStIIx8szjF9eWk5ZP1P8QqG+GuF+m/9dh1YlI2xLhUN0ivMaq9vzMhlOxWxdW/n2jPPsCHlLgYYdiJg5P0P4DYFjdaXui/n6rbQFzKnrjzg0Ek4p/Dv4ZyaIgyHdu/J+C1grZiVbg6u0ajCw/xP656wzcXq+W/LZzXWnK9ojhU8wm876HOv6X8rHVNhOO/sM9L4EkWw7hSZXc7BWDpP1GWrIe9JuK/Yu2SJfp0wbj2caWRlbbSv/ipuZKL3+a/XELe4YQTgDh4+alCwLrbP2Be/db3tdq/4GTTBdKJv7g/q14ma8vTv+nOTmPwQue/qD/RlOMUgDiuufbH6Ha4P8O7vxGHUdG/HtxQnn9lyziKXvQFdCDRv3fH28rD5+K/8IVgFkV2dTilUODesXT1O3khniRC7/C7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAICtufbH6Ha4P8O7vxGHUdG/XpOkbb2msbiKXvQFdCDRv3fH28rD5+K/8IVgFkV2dbiqMjTguqu8v85IoEMf38W/HJykIHzU0DiCN0vH04HJv6xhBuS9Jdm/lAkzsCbDYjiYEJYmrpfMvw+t4OG+2Lu/WputRKIDoTiKbUnLghPDv43GzzDnx8+/0945pbsZdDjoOgZhy1zSvwzr2HU6x6+/AlpHVyYbrTg/B8MnT1+6vzdA3gDyGL6/3TeEJAlxRbj4Ri0isHDTvwoWkg4uVqC/c0eBHCpprbie3EO7v2Kwv5UHU31Te4O/MrUNVU5vRThwPX7vaKrSv+ohJy8aOpO/lijBpNJ3wbiu2p1kXmykvz9IoyaDGaw/yL7DBstgXTi+o+kXFlbRv7Pp5+aFqYK/tpS+ce6uuLh2fx/X6m2hvxgt4fQQ27E/RBbsaMj3VzjyU1QekmXPvyg/Md4Jc1S/CPYr3GYAvbhUiAEr++6dv80F1OH/u7Q/THkSheZeJbhFITXMNhzKv+IXbAXZimQ/NXJjWE8Mm7gyPsMmfqCMv4qgH7cJZLw/o6xxhRn2ibPUgF6G5XfCv7NK2GGs8mA/xyMyVEZtfDh2KiBsdlVlvy9Q9CxqX78/ysVLjPxoJbgQEUL8DHe/v3o+BO42lFA/XfKM98NIcTgYchPm3eYsvwa9D3D71r4/IClmFC9qRbh2VapR4KqqvwzUt1K2q3G/Tu3x1UURfrjt+6/8fhZPP0Q48ezhgrU/IIyMGcvFUDSMDd83lHDVO/nqCsEQ+lW7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAICDq7vR+gKbv0kDFpdniGe/2/4NlMJ0iTj3qWOZS0Bqv6YrAEbCWJs/+mURuklrBTi2OLZKm7iWvy3lr8LkEFu/oVe8QrYsXTj9EIs5qAVwvyh7z+2dgoo/9oX2YmNBMTgsGDF6QPaUv2bad55VH0u//s3gJgCgf7jCCOL3pHdwvzoXYE6tXYQ/f/9nKVQxBbjUHBGfTvqSv0XvwZyHw08/QOasYlBIg7i0GVLoYcFwv8kZ8kqRWXE/XD3yiQ+iMjj0mB26lRmTv5KNTSjlh2Y//rtq11x9Z7ixccmDWSVwv1caXveQT0K/2bbpEWFLJTgF8+atufKUv/Wjs1dzGnI/LWo7tLkhjLiabFYvlE5tvyn6AgcIKnK/GvCblkJdPzi8aQFK7yyXv2AwY50PIXg/FOdfxprgYLh3dFrNMmNsvx0hP0kSfHS/wIG6G+mJJLi8i5rucJaZv0OZsN8Z7H0/AOQrH678cjhuKVQpsxlrv+YuCXxMJHa/n++P5SLvYjjFriVUZR6cvyrT3yc+tIE/HedfxprgUDj4yxDJlXZpvzDnraIkKne/mQUhQfucYrgkHkEktrSev7XtOJwVQoQ/GS30Uc8+gjhg3v8tX39nv4woYmrXlXe/ptn+iUpBQ7hvOYeQE6WgvxuU5+Esl4Y/UFZDez8aYrhGiYD6iDplvzECncN2cHe/w4G6G+mJBDhLQUfLNuihv0MUcKfVq4g/HedfxprggLjxR7Dub69iv2fK04rrw3a/Z58YwuVdYLiLsEPMIx2jvzSYBVUweYo/HVvDNC3ucDjjpQjufcxfv00hn4fymnW/bHIghqA9LLgMpHhLyT2kvyxIg1hA+Ys/2Co98SAyULih8tIer89Zv77n3hAVAXS/nE1g18mlbrh4X5ZtsESlv+fPEdr9Jo0/UsXqJcQdRbjBVrGKb3tTv7T026udAnK/bImHZg2wMDghJanEBi2mv1Y+dp5k/o0/bwTkvq9HeLhy65+oeMdJv4ZZCQcSWW+/gHoL0vmvcLjqGpa40vGmv41PsK89fI4/MmS1sN1aXriMGvpr3Xs4vyUCYscQGmq/oQovnilybrhda+b2sJCnv0Bc7stEn44/jwlFBDDQYLiOrKILHtoHP3+/kQCWY2S/ZZOFFWMcSbh8me8O8Qaov6rSoYO/Zo4/aYY63+tZYjicJTz3loA+P77RnumVpVy//RQZQV49DDhEtpCwo1Kov1cCZ+EQ040/jwlFBDDQYDitDJHyFd9MP2HQgSkWC1C/Zs+UKO9JcbgPrluxnnKov/JHyAC45Yw/jwlFBDDQYDihODqXwBdVP+lwKrLloim/zRZId/buUrhYz7ubf2aovz4nj0JLoYs/jwlFBDDQcDg4d5yBA4RbP0QYM2i5QkM/GZ6tQK/Larg+KhO+rC6ov9cS6yhwCYo/2eEa52/6a7ixMlGwJtBgP3Kfk/LDOFY/OK+59gSxwDN7nja2VMynv1Y21e/PIog/IuqhCIz3V7hlpT4/yaxjP0aUS/pvKmE/kwQfeFTSRbgEvSd8bEGnv3ut8f8I84U/qAgADHy8UDh3hQqG/k5mPxg4fSvA3GY/eXY063RQWric0171q5Cmv5luomOdgIM/cGLFfRRjhbh/L7GKkq5oP6Oxd5XUFWw/EFdIXPdcTzgUyfv5mWalvy0e+9I2PIA/EgDyLWzJYzhpboNJZ9lxP1pGOjn0Ono/PPPAEP9KJTheLSzcmayjv14/YDo17nc/hC9bmA/GfDjc8A99UpR2P/TKz5NsT4I/7k8avuJMQTiNCN5wbXmhvzM8xNvBXGs/BNDSB6tMc7jV8sPTAIV6P0B9uuPMj4Y/rk7lru9KNbjkJNKJvsidv8mc3ROqS0A/XBCz33UqczgG/cfPCqZ9P+IhtAJAzYk/brPmQCDLtzO2JOriE0CZv7eCH7J5Tl+/Tg/hIIBnQbiGqvHJt1KBP/VJ1AowlY4/hWeIB5XV1LNEbPLC2RuTv8cEdCQ7C3W/ebCmh3vvXTjwkubodhuFP4CKt5E9aZI/EOa8ljATMDi66r09l4GIvzwIx2QeHoK/raxA5u97bjgv4rBAMZiHP1dWdnW3vZM/5sxYP5VwJTgKB5uSvYiVOzqqvJs66KE7AAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAlOeyMzllsv2PBdLcMC42/vywfsxU+ZDj+xjCuueCJP9GiEMk3R5Q/LfrzCktv9bfe7+VxGHFoP6sdEdAm1ZK/pEL1/lf0ObjCQGoX1e2KPx7QRzhEh5Q/qXJmCo9R1TekpEAFN2F7P4OAk8+lVZW/8cbhl0h5k7iaQ2qh3huLPxrjXhMlkpQ/9w0oKld/VjgSpbSYfUKCP6x2uaOD15a/c6r2NflYorjdQwXE1B6LPxQwBhzYkpQ/+klHAbOUIjTGQ/X02LSRP1eg86AUg5y/Wm7Imq1Nl7iENdhnOymLP790wtVGlZQ/W14uGXjl1Lf//XRh80uaP0LjGovRF6G/a8zDgQAgk7hA/5mEQSyLP3FChn/wlZQ/JFHQht5G9zM=
+        </DataArray>
+        <DataArray type="Float64" Name="IMAG____DEPL" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="4.8226557332e-26" RangeMax="0.00023080549689">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="IMAG____VITE" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="5.9484092681e-24" RangeMax="0.034897173794">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____ACCE" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="9.3437394286e-22" RangeMax="5.4816352411">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____DEPL" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="3.7868749542e-26" RangeMax="0.00022216230837">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____VITE" NumberOfComponents="6" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" ComponentName3="DRX" ComponentName4="DRY" ComponentName5="DRZ" format="binary" RangeMin="7.575409911e-24" RangeMax="0.036254842672">
+          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
+        </DataArray>
+        <DataArray type="Int32" Name="FamilyIdNode" format="binary" RangeMin="1" RangeMax="309">
+          1AQAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAABAAAAAQQAAAEIAAABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAASgAAAEsAAABMAAAATQAAAE4AAABPAAAAUAAAAFEAAABSAAAAUwAAAFQAAABVAAAAVgAAAFcAAABYAAAAWQAAAFoAAABbAAAAXAAAAF0AAABeAAAAXwAAAGAAAABhAAAAYgAAAGMAAABkAAAAZQAAAGYAAABnAAAAaAAAAGkAAABqAAAAawAAAGwAAABtAAAAbgAAAG8AAABwAAAAcQAAAHIAAABzAAAAdAAAAHUAAAB2AAAAdwAAAHgAAAB5AAAAegAAAHsAAAB8AAAAfQAAAH4AAAB/AAAAgAAAAIEAAACCAAAAgwAAAIQAAACFAAAAhgAAAIcAAACIAAAAiQAAAIoAAACLAAAAjAAAAI0AAACOAAAAjwAAAJAAAACRAAAAkgAAAJMAAACUAAAAlQAAAJYAAACXAAAAmAAAAJkAAACaAAAAmwAAAJwAAACdAAAAngAAAJ8AAACgAAAAoQAAAKIAAACjAAAApAAAAKUAAACmAAAApwAAAKgAAACpAAAAqgAAAKsAAACsAAAArQAAAK4AAACvAAAAsAAAALEAAACyAAAAswAAALQAAAC1AAAAtgAAALcAAAC4AAAAuQAAALoAAAC7AAAAvAAAAL0AAAC+AAAAvwAAAMAAAADBAAAAwgAAAMMAAADEAAAAxQAAAMYAAADHAAAAyAAAAMkAAADKAAAAywAAAMwAAADNAAAAzgAAAM8AAADQAAAA0QAAANIAAADTAAAA1AAAANUAAADWAAAA1wAAANgAAADZAAAA2gAAANsAAADcAAAA3QAAAN4AAADfAAAA4AAAAOEAAADiAAAA4wAAAOQAAADlAAAA5gAAAOcAAADoAAAA6QAAAOoAAADrAAAA7AAAAO0AAADuAAAA7wAAAPAAAADxAAAA8gAAAPMAAAD0AAAA9QAAAPYAAAD3AAAA+AAAAPkAAAD6AAAA+wAAAPwAAAD9AAAA/gAAAP8AAAAAAQAAAQEAAAIBAAADAQAABAEAAAUBAAAGAQAABwEAAAgBAAAJAQAACgEAAAsBAAAMAQAADQEAAA4BAAAPAQAAEAEAABEBAAASAQAAEwEAABQBAAAVAQAAFgEAABcBAAAYAQAAGQEAABoBAAAbAQAAHAEAAB0BAAAeAQAAHwEAACABAAAhAQAAIgEAACMBAAAkAQAAJQEAACYBAAAnAQAAKAEAACkBAAAqAQAAKwEAACwBAAAtAQAALgEAAC8BAAAwAQAAMQEAADIBAAAzAQAANAEAADUBAAA=
+        </DataArray>
+        <DataArray type="Float64" Name="IMAG____ACCE_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="1.1899426062e-21" RangeMax="5.6897158426">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="IMAG____DEPL_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="4.8226557332e-26" RangeMax="0.0002305954975">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="IMAG____VITE_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="5.9484092681e-24" RangeMax="0.034893077912">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____ACCE_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="9.3437394286e-22" RangeMax="5.4809918614">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____DEPL_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="3.7868749542e-26" RangeMax="0.00022213623317">
+          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
+        </DataArray>
+        <DataArray type="Float64" Name="REEL____VITE_Vector" NumberOfComponents="3" ComponentName0="DX" ComponentName1="DY" ComponentName2="DZ" format="binary" RangeMin="7.575409911e-24" RangeMax="0.036221856045">
+          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
+        </DataArray>
+      </PointData>
+      <CellData>
+        <DataArray type="Int32" Name="FamilyIdCell" format="binary" RangeMin="-378" RangeMax="-1">
+          6AUAAAAAAAD//////v////3////8////+/////r////5////+P////f////2////9f////T////z////8v////H////w////7////+7////t////7P///+v////q////6f///+j////n////5v///+X////k////4////+L////h////4P///9/////e////3f///9z////b////2v///9n////Y////1////9b////V////1P///9P////S////0f///9D////P////zv///83////M////y////8r////J////yP///8f////G////xf///8T////D////wv///8H////A////v////77///+9////vP///7v///+6////uf///7j///+3////tv///7X///+0////s////7L///+x////sP///6////+u////rf///6z///+r////qv///6n///+o////p////6b///+l////pP///6P///+i////of///6D///+f////nv///53///+c////m////5r///+Z////mP///5f///+W////lf///5T///+T////kv///5H///+Q////j////47///+N////jP///4v///+K////if///4j///+H////hv///4X///+E////g////4L///+B////gP///3////9+////ff///3z///97////ev///3n///94////d////3b///91////dP///3P///9y////cf///3D///9v////bv///23///9s////a////2r///9p////aP///2f///9m////Zf///2T///9j////Yv///2H///9g////X////17///9d////XP///1v///9a////Wf///1j///9X////Vv///1X///9U////U////1L///9R////UP///0////9O////Tf///0z///9L////Sv///0n///9I////R////0b///9F////RP///0P///9C////Qf///0D///8/////Pv///z3///88////O////zr///85////OP///zf///82////Nf///zT///8z////Mv///zH///8w////L////y7///8t////LP///yv///8q////Kf///yj///8n////Jv///yX///8k////I////yL///8h////IP///x////8e////Hf///xz///8b////Gv///xn///8Y////F////xb///8V////FP///xP///8S////Ef///xD///8P////Dv///w3///8M////C////wr///8J////CP///wf///8G////Bf///wT///8D////Av///wH///8A//////7///7+///9/v///P7///v+///6/v//+f7///j+///3/v//9v7///X+///0/v//8/7///L+///x/v//8P7//+/+///u/v//7f7//+z+///r/v//6v7//+n+///o/v//5/7//+b+///l/v//5P7//+P+///i/v//4f7//+D+///f/v//3v7//93+///c/v//2/7//9r+///Z/v//2P7//9f+///W/v//1f7//9T+///T/v//0v7//9H+///Q/v//z/7//87+///N/v//zP7//8v+///K/v//yf7//8j+///H/v//xv7//8X+///E/v//w/7//8L+///B/v//wP7//7/+//++/v//vf7//7z+//+7/v//uv7//7n+//+4/v//t/7//7b+//+1/v//tP7//7P+//+y/v//sf7//7D+//+v/v//rv7//63+//+s/v//q/7//6r+//+p/v//qP7//6f+//+m/v//pf7//6T+//+j/v//ov7//6H+//+g/v//n/7//57+//+d/v//nP7//5v+//+a/v//mf7//5j+//+X/v//lv7//5X+//+U/v//k/7//5L+//+R/v//kP7//4/+//+O/v//jf7//4z+//+L/v//iv7//4n+//+I/v//h/7//4b+//8=
+        </DataArray>
+        <DataArray type="Int32" Name="NumIdCell" format="binary" RangeMin="1" RangeMax="378">
+          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
+        </DataArray>
+      </CellData>
+      <Points>
+        <DataArray type="Float64" Name="Points" NumberOfComponents="3" format="binary" RangeMin="0" RangeMax="68.568">
+          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
+        </DataArray>
+      </Points>
+      <Cells>
+        <DataArray type="Int32" Name="connectivity" format="binary" RangeMin="0" RangeMax="308">
+          qAoAAAAAAAAAAAAAAQAAAAEAAAACAAAAAgAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAADgAAAA4AAAAPAAAADwAAABAAAAAQAAAAEQAAABEAAAASAAAAEgAAABMAAAATAAAAFAAAABQAAAAVAAAAFQAAABYAAAAWAAAAFwAAABcAAAAYAAAAGAAAABkAAAAZAAAAGgAAABoAAAAbAAAAGwAAABwAAAAcAAAAHQAAAB0AAAAeAAAAHgAAAB8AAAAfAAAAIAAAACAAAAAhAAAAIQAAACIAAAAiAAAAIwAAACMAAAAkAAAAJAAAACUAAAAlAAAAJgAAACYAAAAnAAAAJwAAACgAAAAoAAAAKQAAACsAAAAsAAAALAAAAC0AAAAtAAAALgAAAC4AAAAvAAAALwAAADAAAAAwAAAAMQAAADEAAAAyAAAAMgAAADMAAAAzAAAANAAAADQAAAA1AAAANQAAADYAAAA2AAAANwAAADcAAAA4AAAAOAAAADkAAAA5AAAAOgAAADoAAAA7AAAAOwAAADwAAAA8AAAAPQAAAD0AAAA+AAAAPgAAAD8AAAA/AAAAQAAAAEAAAABBAAAAQQAAAEIAAABCAAAAQwAAAEMAAABEAAAARAAAAEUAAABFAAAARgAAAEYAAABHAAAARwAAAEgAAABIAAAASQAAAEkAAABKAAAASgAAAEsAAABLAAAATAAAAEwAAABNAAAATQAAAE4AAABOAAAATwAAAE8AAABQAAAAUAAAAFEAAABRAAAAUgAAAFIAAABTAAAAUwAAAFQAAABUAAAAVQAAAFUAAABWAAAAVgAAAFcAAABXAAAAWAAAAFgAAABZAAAAWQAAAFoAAABaAAAAWwAAAFsAAABcAAAAXAAAAF0AAABdAAAAXgAAAF4AAABfAAAAXwAAAGAAAABgAAAAYQAAAGEAAABiAAAAYgAAAGMAAABjAAAAZAAAAGQAAABlAAAAZQAAAGYAAABmAAAAZwAAAGcAAABoAAAAaAAAAGkAAABpAAAAagAAAGoAAABrAAAAawAAAGwAAABsAAAAbQAAAG0AAABuAAAAbgAAAG8AAABvAAAAcAAAAHAAAABxAAAAcwAAAHQAAAB0AAAAdQAAAHUAAAB2AAAAdgAAAHcAAAB3AAAAeAAAAHgAAAB5AAAAeQAAAHoAAAB6AAAAewAAAHsAAAB8AAAAfAAAAH0AAAB9AAAAfgAAAH4AAAB/AAAAfwAAAIAAAACAAAAAgQAAAIEAAACCAAAAggAAAIMAAACDAAAAhAAAAIQAAACFAAAAhQAAAIYAAACGAAAAhwAAAIcAAACIAAAAiAAAAIkAAACJAAAAigAAAIoAAACLAAAAiwAAAIwAAACMAAAAjQAAAI0AAACOAAAAjgAAAI8AAACPAAAAkAAAAJAAAACRAAAAkQAAAJIAAACSAAAAkwAAAJMAAACUAAAAlAAAAJUAAACVAAAAlgAAAJYAAACXAAAAlwAAAJgAAACYAAAAmQAAAJkAAACaAAAAmgAAAJsAAACbAAAAnAAAAJwAAACdAAAAnQAAAJ4AAACeAAAAnwAAAJ8AAACgAAAAoAAAAKEAAAChAAAAogAAAKIAAACjAAAAowAAAKQAAACkAAAApQAAAKUAAACmAAAApgAAAKcAAACnAAAAqAAAAKgAAACpAAAAqQAAAKoAAACqAAAAqwAAAKsAAACsAAAArAAAAK0AAACtAAAArgAAAK4AAACvAAAArwAAALAAAACwAAAAsQAAALEAAACyAAAAsgAAALMAAACzAAAAtAAAALQAAAC1AAAAtQAAALYAAAC2AAAAtwAAALcAAAC4AAAAuAAAALkAAAC7AAAAvAAAALwAAAC9AAAAvQAAAL4AAAC+AAAAvwAAAL8AAADAAAAAwAAAAMEAAADBAAAAwgAAAMIAAADDAAAAwwAAAMQAAADEAAAAxQAAAMUAAADGAAAAxgAAAMcAAADHAAAAyAAAAMgAAADJAAAAyQAAAMoAAADKAAAAywAAAMsAAADMAAAAzAAAAM0AAADNAAAAzgAAAM4AAADPAAAAzwAAANAAAADQAAAA0QAAANEAAADSAAAA0gAAANMAAADTAAAA1AAAANQAAADVAAAA1QAAANYAAADWAAAA1wAAANcAAADYAAAA2AAAANkAAADZAAAA2gAAANoAAADbAAAA2wAAANwAAADcAAAA3QAAAN0AAADeAAAA3gAAAN8AAADfAAAA4AAAAOAAAADhAAAA4QAAAOIAAADiAAAA4wAAAOMAAADkAAAA5AAAAOUAAADlAAAA5gAAAOYAAADnAAAA5wAAAOgAAADoAAAA6QAAAOkAAADqAAAA6gAAAOsAAADrAAAA7AAAAOwAAADtAAAA7QAAAO4AAADuAAAA7wAAAO8AAADwAAAA8AAAAPEAAADxAAAA8gAAAPIAAADzAAAA8wAAAPQAAAD0AAAA9QAAAPUAAAD2AAAA9gAAAPcAAAD3AAAA+AAAAPgAAAD5AAAA+QAAAPoAAAD6AAAA+wAAAPsAAAD8AAAA/AAAAP0AAAD9AAAA/gAAAAABAAABAQAAAQEAAAIBAAACAQAAAwEAAAMBAAAEAQAABAEAAAUBAAAFAQAABgEAAAYBAAAHAQAABwEAAAgBAAAIAQAACQEAAAkBAAAKAQAACgEAAAsBAAALAQAADQEAAA0BAAAOAQAADgEAAA8BAAAPAQAAEAEAABABAAARAQAAEQEAABIBAAASAQAAEwEAABMBAAAUAQAAFAEAABUBAAAVAQAAFgEAABYBAAAXAQAAFwEAABgBAAAYAQAAGQEAABkBAAAaAQAAGgEAABsBAAAbAQAAHAEAABwBAAAdAQAAHQEAAB4BAAAeAQAAHwEAAB8BAAAgAQAAIAEAACEBAAAhAQAAIgEAACIBAAAjAQAAIwEAACQBAAAkAQAAJQEAACUBAAAmAQAAJgEAACcBAAAnAQAAKAEAACgBAAApAQAAKQEAACoBAAAqAQAAKwEAACsBAAAsAQAALAEAAC0BAAAtAQAALwEAAC8BAAAwAQAAMAEAADEBAAAxAQAAMgEAADIBAAAzAQAAMwEAADQBAAADAAAAAgAAACoAAAApAAAAcgAAAHEAAAC6AAAAuQAAAP8AAAD+AAAADAEAAAsBAAAuAQAALQEAAAgAAAAJAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAA7AAAAQQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAAAE0AAABOAAAATwAAAFAAAABRAAAAUgAAAFcAAABdAAAAgwAAAIkAAACOAAAAjwAAAJAAAACRAAAAkgAAAJMAAACVAAAAlgAAAJcAAACYAAAAmQAAAJoAAACfAAAApQAAAMsAAADRAAAA1gAAANcAAADYAAAA2QAAANoAAADbAAAA3QAAAN4AAADfAAAA4AAAAOEAAADiAAAA5wAAAO0AAAAOAQAADwEAABABAAARAQAAEgEAACYBAAAnAQAAKAEAACkBAAAqAQAA
+        </DataArray>
+        <DataArray type="Int32" Name="offsets" format="binary" RangeMin="2" RangeMax="682">
+          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
+        </DataArray>
+        <DataArray type="UInt8" Name="types" format="binary" RangeMin="1" RangeMax="3">
+          egEAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=
+        </DataArray>
+      </Cells>
+    </Piece>
+  </UnstructuredGrid>
+</VTKFile>
diff --git a/src/ComplexMode/plugin/CMakeLists.txt b/src/ComplexMode/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0cc63e0
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(ComplexModePlugin
+  VERSION "1.0"
+  MODULES ComplexModeModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ComplexModeModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ComplexModePlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ComplexMode/plugin/ComplexModeModule/CMakeLists.txt b/src/ComplexMode/plugin/ComplexModeModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e0f0b1e
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkComplexMode
+)
+# Visual C++ 2017 bug: defining _USE_MATH_DEFINES inside .cpp/.h file is inoperant
+IF(WIN32)
+ADD_COMPILE_DEFINITIONS(_USE_MATH_DEFINES)
+ENDIF(WIN32)
+
+vtk_module_add_module(ComplexModeModule
+  FORCE_STATIC
+  CLASSES ${classes}
+  )
diff --git a/src/ComplexMode/plugin/ComplexModeModule/vtk.module b/src/ComplexMode/plugin/ComplexModeModule/vtk.module
new file mode 100644 (file)
index 0000000..c906fa4
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ComplexModeModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsFiltersRendering
+  ParaView::VTKExtensionsMisc
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::vtksys
+  VTK::zlib
diff --git a/src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.cxx b/src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.cxx
new file mode 100644 (file)
index 0000000..911eed6
--- /dev/null
@@ -0,0 +1,396 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkComplexMode.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkIntArray.h>
+#include <vtkCellData.h>
+#include <vtkPointData.h>
+
+#include <vtkAlgorithmOutput.h>
+#include <vtkCharArray.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkObjectFactory.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+#include <vtkWarpVector.h>
+
+#include <map>
+#include <deque>
+#include <sstream>
+
+vtkStandardNewMacro(vtkComplexMode);
+
+static const char ZE_DISPLACEMENT_NAME1[]="@@ForReal?@@";
+
+static const char ZE_DISPLACEMENT_NAME2[]="@@ForImag?@@";
+
+static const char ZE_DISPLACEMENT_NAME3[]="MagnitudeOfCpxDisp";
+
+static const double EPS=1e-12;
+
+///////////////////
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s):_reason(s) { }
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() { }
+private:
+  std::string _reason;
+};
+
+vtkSmartPointer<vtkDoubleArray> ForceTo3Compo(vtkDoubleArray *arr)
+{
+  if(!arr)
+    return vtkSmartPointer<vtkDoubleArray>();
+  int nbCompo(arr->GetNumberOfComponents()),nbTuples(arr->GetNumberOfTuples());
+  if(nbCompo==3)
+    {
+      vtkSmartPointer<vtkDoubleArray> ret(arr);
+      arr->Register(0);
+      return ret;
+    }
+  if(nbCompo==6)
+    {
+      vtkSmartPointer<vtkDoubleArray> ret(vtkSmartPointer<vtkDoubleArray>::New());
+      ret->SetNumberOfComponents(3);
+      ret->SetNumberOfTuples(nbTuples);
+      const double *srcPt(arr->Begin());
+      double *destPt(ret->Begin());
+      for(int i=0;i<nbTuples;i++,destPt+=3,srcPt+=6)
+        std::copy(srcPt,srcPt+3,destPt);
+      return ret;
+    }
+  throw MZCException("ForceTo3Compo : internal error ! 6 or 3 compo arrays expected !");
+}
+
+std::vector< std::string > GetPossibleArrayNames(vtkDataSet *dataset)
+{
+  if(!dataset)
+    throw MZCException("The input dataset is null !");
+  std::vector< std::string > ret;
+  vtkPointData *att(dataset->GetPointData());
+  for(int i=0;i<att->GetNumberOfArrays();i++)
+    {
+      vtkDataArray *locArr(att->GetArray(i));
+      int nbComp(locArr->GetNumberOfComponents());
+      if(nbComp!=3 && nbComp!=6)
+        continue;
+      std::string s(locArr->GetName());
+      ret.push_back(s);
+    }
+  return ret;
+}
+
+std::string FindTheBest(const std::vector<std::string>& arrNames, const std::string& key0, const std::string& key1)
+{
+  std::string ret;
+  char points(0);
+  if(arrNames.empty())
+    return ret;
+  for(std::vector<std::string>::const_iterator it=arrNames.begin();it!=arrNames.end();it++)
+    {
+      char curNbPts(1);
+      if((*it).find(key0,0)!=std::string::npos)
+        curNbPts++;
+      if((*it).find(key1,0)!=std::string::npos)
+        curNbPts++;
+      if(curNbPts>points)
+        {
+          points=curNbPts;
+          ret=*it;
+        }
+    }
+  return ret;
+}
+
+std::string FindBestRealAmong(const std::vector<std::string>& arrNames)
+{
+  static const char KEY1[]="DEPL";
+  static const char KEY2[]="REEL";
+  return FindTheBest(arrNames,KEY1,KEY2);
+}
+
+std::string FindBestImagAmong(const std::vector<std::string>& arrNames)
+{
+  static const char KEY1[]="DEPL";
+  static const char KEY2[]="IMAG";
+  return FindTheBest(arrNames,KEY1,KEY2);
+}
+
+vtkUnstructuredGrid *ExtractInfo1(vtkInformationVector *inputVector)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if(input0)
+    input=input0;
+  else
+    {
+      if(!input1)
+        throw MZCException("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+      if(input1->GetNumberOfBlocks()!=1)
+        throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      vtkDataObject *input2(input1->GetBlock(0));
+      if(!input2)
+        throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+      vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+      if(!input2c)
+        throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      input=input2c;
+    }
+  if(!input)
+    throw MZCException("Input data set is NULL !");
+  vtkUnstructuredGrid *usgIn(vtkUnstructuredGrid::SafeDownCast(input));
+  if(!usgIn)
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+  return usgIn;
+}
+
+void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *& usgIn, const std::string& arrName, vtkDoubleArray *& arr)
+{
+  usgIn=ExtractInfo1(inputVector);
+  vtkPointData *att(usgIn->GetPointData());
+  if(!att)
+    throw MZCException("Input dataset has no point data attribute ! Impossible to move mesh !");
+  vtkDataArray *zeArr(0);
+  for(int i=0;i<att->GetNumberOfArrays();i++)
+    {
+      vtkDataArray *locArr(att->GetArray(i));
+      std::string s(locArr->GetName());
+      if(s==arrName)
+        {
+          zeArr=locArr;
+          break;
+        }
+    }
+  if(!zeArr)
+    {
+      std::ostringstream oss;
+      oss << "Impossible to locate the array called \"" << arrName << "\" used to move mesh !";
+      throw MZCException(oss.str());
+    }
+  arr=vtkDoubleArray::SafeDownCast(zeArr);
+  if(!arr)
+    {
+      std::ostringstream oss;
+      oss << "Array called \"" << arrName << "\" has been located but this is NOT a float64 array !";
+      throw MZCException(oss.str());
+    }
+  if(arr->GetNumberOfComponents()!=3 && arr->GetNumberOfComponents()!=6)
+    {
+      std::ostringstream oss;
+      oss << "Float64 array called \"" << arrName << "\" has been located but this array has not exactly 3 or 6 components as it should !";
+      throw MZCException(oss.str());
+    }
+  if(arr->GetNumberOfTuples()!=usgIn->GetNumberOfPoints())
+    {
+      std::ostringstream oss;
+      oss << "Float64-1 components array called \"" << arrName << "\" has been located but the number of tuples is invalid ! Should be " << usgIn->GetNumberOfPoints() << " instead of " << arr->GetNumberOfTuples() << " !";
+      throw MZCException(oss.str());
+    }
+}
+
+////////////////////
+
+class vtkComplexMode::vtkComplexModeInternal
+{
+public:
+  void setFieldForReal(const std::string& st) { _real=st; }
+  void setFieldForImagin(const std::string& st) { _imag=st; }
+  std::string getFieldForReal() const { return _real; }
+  std::string getFieldForImag() const { return _imag; }
+private:
+  std::string _real;
+  std::string _imag;
+};
+
+vtkComplexMode::vtkComplexMode():Factor(1.),Phase(90.),AnimationTime(0.),Internal(new vtkComplexMode::vtkComplexModeInternal)
+{
+  //this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,vtkDataSetAttributes::VECTORS);
+}
+
+vtkComplexMode::~vtkComplexMode()
+{
+  delete this->Internal;
+}
+
+void vtkComplexMode::SetInputArrayToProcess(int idx, int port, int connection, int ff, const char *name)
+{
+  if(idx==0)
+    this->Internal->setFieldForReal(name);
+  if(idx==1)
+    this->Internal->setFieldForImagin(name);
+  vtkUnstructuredGridAlgorithm::SetInputArrayToProcess(idx,port,connection,ff,name);
+}
+
+double GetOptimalRatioFrom(vtkUnstructuredGrid *dataset, vtkDoubleArray *array)
+{
+  if(!dataset || !array)
+    throw MZCException("The input dataset and or array is null !");
+  vtkDataArray *coords(dataset->GetPoints()->GetData());
+  vtkDoubleArray *coords2(vtkDoubleArray::SafeDownCast(coords));
+  if(!coords2)
+    throw MZCException("Input coordinates are not float64 !");
+  int nbCompo(array->GetNumberOfComponents());
+  if(coords2->GetNumberOfComponents()!=3 || (nbCompo!=3 && nbCompo!=6))
+    throw MZCException("Input coordinates do not have 3 components as it should !");
+  int nbPts(dataset->GetNumberOfPoints());
+  const double *srcPt1(array->Begin());
+  dataset->ComputeBounds();
+  double *minmax1(dataset->GetBounds());
+  double minmax2[3]={0.,0.,0.};
+  for(int i=0;i<nbPts;i++,srcPt1+=nbCompo)
+    {
+      minmax2[0]=std::max(fabs(srcPt1[0]),minmax2[0]);
+      minmax2[1]=std::max(fabs(srcPt1[1]),minmax2[1]);
+      minmax2[2]=std::max(fabs(srcPt1[2]),minmax2[2]);
+    }
+  double maxDispDelta(*std::max_element(minmax2,minmax2+3));
+  if(maxDispDelta<EPS)
+    maxDispDelta=1.;
+  for(int i=0;i<3;i++)
+    minmax2[i]=minmax1[2*i+1]-minmax1[2*i];
+  double maxGeoDelta(*std::max_element(minmax2,minmax2+3));
+  if(maxDispDelta<EPS)
+    maxDispDelta=1.;
+  return maxGeoDelta/maxDispDelta;
+}
+
+int vtkComplexMode::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkComplexMode::RequestInformation ##########################################" << std::endl;
+  try
+    {
+      if(this->Internal->getFieldForReal().empty())
+        return 1;
+      vtkUnstructuredGrid *usgIn(0);
+      vtkDoubleArray *arr(0);
+      /*ExtractInfo(inputVector[0],usgIn,this->Internal->getFieldForReal(),arr);
+      std::vector<std::string> candidatesArrName(GetPossibleArrayNames(usgIn));
+      //
+      double ratio(GetOptimalRatioFrom(usgIn,arr));
+      std::string optArrNameForReal(FindBestRealAmong(candidatesArrName));
+      std::string optArrNameForImag(FindBestImagAmong(candidatesArrName));*/
+      //std::cerr << ratio << std::endl;
+      //std::cerr << optArrNameForReal << " * " << optArrNameForImag << std::endl;
+    }
+  catch(MZCException& e)
+    {
+      std::ostringstream oss;
+      oss << "Exception has been thrown in vtkComplexMode::RequestInformation : " << e.what() << std::endl;
+      if(this->HasObserver("ErrorEvent") )
+        this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+      else
+        vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+      vtkObject::BreakOnError();
+      return 0;
+    }
+  return 1;
+}
+
+int vtkComplexMode::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkComplexMode::RequestData        ##########################################" << std::endl;
+  try
+    {
+      vtkUnstructuredGrid *usgIn(0);
+      vtkDoubleArray *arrRealBase(0),*arrImagBase(0);
+      ExtractInfo(inputVector[0],usgIn,this->Internal->getFieldForReal(),arrRealBase);
+      ExtractInfo(inputVector[0],usgIn,this->Internal->getFieldForImag(),arrImagBase);
+      vtkSmartPointer<vtkDoubleArray> arrReal(ForceTo3Compo(arrRealBase));
+      vtkSmartPointer<vtkDoubleArray> arrImag(ForceTo3Compo(arrImagBase));
+      //
+      int nbPts(usgIn->GetNumberOfPoints());
+      vtkSmartPointer<vtkUnstructuredGrid> step1(vtkSmartPointer<vtkUnstructuredGrid>::New());
+      step1->DeepCopy(usgIn);
+      vtkSmartPointer<vtkDoubleArray> arr1(vtkSmartPointer<vtkDoubleArray>::New()),arr2(vtkSmartPointer<vtkDoubleArray>::New()),zearr(vtkSmartPointer<vtkDoubleArray>::New());
+      arr1->SetName(ZE_DISPLACEMENT_NAME1); arr2->SetName(ZE_DISPLACEMENT_NAME2); zearr->SetName(ZE_DISPLACEMENT_NAME3);
+      arr1->SetNumberOfComponents(3); arr2->SetNumberOfComponents(3); zearr->SetNumberOfComponents(1);
+      arr1->SetNumberOfTuples(nbPts); arr2->SetNumberOfTuples(nbPts); zearr->SetNumberOfTuples(nbPts);
+      double *ptToFeed1(arr1->Begin()),*ptToFeed2(arr2->Begin()),*ptToFeed3(zearr->Begin());
+      const double *srcPt1(arrReal->Begin()),*srcPt2(arrImag->Begin());
+      double cst1(Factor*sin(AnimationTime*2*M_PI)),cst2(Factor*sin(AnimationTime*2*M_PI+Phase*M_PI/180.));
+      std::transform(srcPt1,srcPt1+3*nbPts,ptToFeed1,std::bind2nd(std::multiplies<double>(),cst1));
+      std::transform(srcPt2,srcPt2+3*nbPts,ptToFeed2,std::bind2nd(std::multiplies<double>(),cst2));
+      std::transform(ptToFeed1,ptToFeed1+3*nbPts,ptToFeed2,ptToFeed1,std::plus<double>());
+      {
+        for(int i=0;i<nbPts;i++)
+          ptToFeed3[i]=sqrt(ptToFeed1[3*i]*ptToFeed1[3*i]+ptToFeed1[3*i+1]*ptToFeed1[3*i+1]+ptToFeed1[3*i+2]*ptToFeed1[3*i+2]);
+      }
+      int idx1(step1->GetPointData()->AddArray(arr1));
+      step1->GetPointData()->SetActiveAttribute(idx1,vtkDataSetAttributes::VECTORS);
+      //
+      vtkSmartPointer<vtkWarpVector> ws(vtkSmartPointer<vtkWarpVector>::New());//vtkNew
+      ws->SetInputData(step1);
+      ws->SetScaleFactor(1.);
+      ws->SetInputArrayToProcess(idx1,0,0,"vtkDataObject::FIELD_ASSOCIATION_POINTS",ZE_DISPLACEMENT_NAME1);
+      ws->Update();
+      vtkSmartPointer<vtkDataSet> ds(ws->GetOutput());
+      ds->GetPointData()->RemoveArray(idx1);
+      int idx3(ds->GetPointData()->AddArray(zearr));
+      ds->GetPointData()->SetActiveAttribute(idx3,vtkDataSetAttributes::SCALARS);
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      output->ShallowCopy(ds);
+    }
+  catch(MZCException& e)
+    {
+      std::ostringstream oss;
+      oss << "Exception has been thrown in vtkComplexMode::RequestInformation : " << e.what() << std::endl;
+      if(this->HasObserver("ErrorEvent") )
+        this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+      else
+        vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+      vtkObject::BreakOnError();
+      return 0;
+    }
+  return 1;
+}
+
+void vtkComplexMode::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.h b/src/ComplexMode/plugin/ComplexModeModule/vtkComplexMode.h
new file mode 100644 (file)
index 0000000..1c5230c
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkComplexMode_h__
+#define vtkComplexMode_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkComplexMode : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkComplexMode* New();
+  vtkTypeMacro(vtkComplexMode, vtkUnstructuredGridAlgorithm)
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  vtkGetMacro(Factor,double);
+  vtkSetClampMacro(Factor,double,0.,VTK_DOUBLE_MAX);
+
+  vtkGetMacro(Phase,double);
+  vtkSetClampMacro(Phase,double,-180.,180.);
+
+  vtkGetMacro(AnimationTime,double);
+  vtkSetClampMacro(AnimationTime,double,0.,1.);
+
+  void SetInputArrayToProcess(int idx, int port, int connection, int fieldAssociation, const char *name);
+
+protected:
+  vtkComplexMode();
+  ~vtkComplexMode();
+
+  int RequestInformation(vtkInformation *request,
+                         vtkInformationVector **inputVector, vtkInformationVector *outputVector);
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector);
+
+private:
+  vtkComplexMode(const vtkComplexMode&);
+  void operator=(const vtkComplexMode&); // Not implemented.
+
+protected:
+  double Factor;
+  double Phase;
+  double AnimationTime;
+  class vtkComplexModeInternal;
+  vtkComplexModeInternal* Internal;
+};
+
+#endif
diff --git a/src/ComplexMode/plugin/filters.xml b/src/ComplexMode/plugin/filters.xml
new file mode 100644 (file)
index 0000000..00d2311
--- /dev/null
@@ -0,0 +1,106 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="ComplexMode"
+                 class="vtkComplexMode"
+                 label="Normal modes animation (complex)">
+     <InputProperty name="Input"
+                    command="SetInputConnection">
+       <ProxyGroupDomain name="groups">
+         <Group name="sources"/>
+         <Group name="filters"/>
+       </ProxyGroupDomain>
+       <DataTypeDomain name="input_type">
+         <DataType value="vtkUnstructuredGrid"/>
+       </DataTypeDomain>
+       <Documentation>
+         This property specifies the input to the Level Scalars filter.
+       </Documentation>
+     <InputArrayDomain name="input_array2"
+                      number_of_components="3,6"
+                      optional="1" />
+     </InputProperty>
+
+     <StringVectorProperty command="SetInputArrayToProcess"
+                           default_values="0;0;0;3;REEL____DEPL"
+                           default_values_delimiter=";"
+                           element_types="0 0 0 0 2"
+                           name="Real"
+                           number_of_elements="5">
+        <!-- default value=1 so normals go to the right place -->
+        <ArrayListDomain attribute_type="Vectors"
+                         input_domain_name="input_array2"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>
+          Select the array that represent the real part of the complex mode.
+        </Documentation>
+      </StringVectorProperty>
+
+     <StringVectorProperty command="SetInputArrayToProcess"
+                                            default_values="1;0;0;3;IMAG____DEPL"
+                           default_values_delimiter=";"
+                           element_types="0 0 0 0 2"
+                           name="Imaginary"
+                           number_of_elements="5">
+        <!-- default value=1 so normals go to the right place -->
+        <ArrayListDomain attribute_type="Vectors"
+                         input_domain_name="input_array2"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>
+          Select the array that represent the imaginary part of the complex mode.
+        </Documentation>
+      </StringVectorProperty>
+
+      <DoubleVectorProperty animateable="0"
+                            command="SetFactor"
+                            default_values="1"
+                            name="Factor"
+                            number_of_elements="1">
+        <BoundsDomain name="range" mode="array_scaled_extent">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="ArraySelection" name="Real" />
+          </RequiredProperties>
+        </BoundsDomain>
+        <Documentation>
+          The value of this property sets the scale factor applied for all nodes displacement.
+        </Documentation>
+      </DoubleVectorProperty>
+
+      <DoubleVectorProperty animateable="1"
+                            command="SetPhase"
+                            default_values="90"
+                            name="Phase"
+                            panel_visibility="advanced"
+                            number_of_elements="1">
+        <DoubleRangeDomain max="180" min="-180" name="range" />
+        <Documentation>
+          The value of phase between real and imaginary.
+        </Documentation>
+      </DoubleVectorProperty>
+
+      <DoubleVectorProperty animateable="1"
+                            command="SetAnimationTime"
+                            default_values="0"
+                            name="AnimationTime"
+                            number_of_elements="1">
+        <DoubleRangeDomain max="1" min="0" name="range" />
+        <Documentation>
+          The value of this property sets the scale factor applied for all nodes displacement.
+        </Documentation>
+      </DoubleVectorProperty>
+      <Hints>
+        <ShowInMenu category="Mechanics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ComplexMode/plugin/paraview.plugin b/src/ComplexMode/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..48dae84
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ComplexModePlugin
+DESCRIPTION
+  This plugin provides ...
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  ParaView::VTKExtensionsFiltersRendering
diff --git a/src/ContactReader/CMakeLists.txt b/src/ContactReader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..11dbaf6
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ContactReader)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ContactReader/plugin/CMakeLists.txt b/src/ContactReader/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b8b86d3
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(ContactReader
+  VERSION "1.0"
+  MODULES ContactReaderModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ContactReaderModule/vtk.module"
+  SERVER_MANAGER_XML sources.xml
+)
+
+install(TARGETS ContactReader
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ContactReader/plugin/ContactReaderModule/CMakeLists.txt b/src/ContactReader/plugin/ContactReaderModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b938966
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkContactReader
+)
+
+vtk_module_add_module(ContactReaderModule
+  FORCE_STATIC
+  CLASSES ${classes}
+  )
diff --git a/src/ContactReader/plugin/ContactReaderModule/vtk.module b/src/ContactReader/plugin/ContactReaderModule/vtk.module
new file mode 100644 (file)
index 0000000..e129733
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ContactReaderModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOInfovis
+  ParaView::VTKExtensionsFiltersGeneral
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::vtksys
diff --git a/src/ContactReader/plugin/ContactReaderModule/vtkContactReader.cxx b/src/ContactReader/plugin/ContactReaderModule/vtkContactReader.cxx
new file mode 100644 (file)
index 0000000..e3839d3
--- /dev/null
@@ -0,0 +1,225 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkContactReader.h"
+
+#include <vtkArrowSource.h>
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkDelimitedTextReader.h>
+#include <vtkDoubleArray.h>
+#include <vtkErrorCode.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkTable.h>
+#include <vtkVariant.h>
+#include <vtkVariantArray.h>
+
+#include <exception>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+class MyException : public std::exception
+{
+public:
+  MyException(const char *what) : _what(what) {}
+  MyException(const std::string &what) : _what(what) {}
+  ~MyException() throw() {}
+  const char *what() const throw() { return _what.c_str(); }
+
+private:
+  std::string _what;
+};
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T *ptr = 0) : _ptr(ptr) {}
+  ~AutoPtr() { destroyPtr(); }
+  bool isNull() const { return _ptr == 0; }
+  bool isNotNull() const { return !isNull(); }
+  AutoPtr &operator=(T *ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T *operator->() { return _ptr; }
+  const T *operator->() const { return _ptr; }
+  T &operator*() { return *_ptr; }
+  const T &operator*() const { return *_ptr; }
+  operator T *() { return _ptr; }
+  operator const T *() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T *_ptr;
+};
+
+vtkIdType PosOf(const std::vector<std::string> &arr, const std::string &what)
+{
+  auto pos = std::find(arr.begin(), arr.end(), what);
+  if (pos == arr.end())
+  {
+    std::ostringstream oss;
+    oss << "vtkContactReader::PosOf : Fail to locate \"" << what << "\" in array !";
+    throw MyException(oss.str());
+  }
+  return std::distance(arr.begin(), pos);
+}
+
+vtkStandardNewMacro(vtkContactReader);
+
+vtkContactReader::vtkContactReader() : FileName(NULL), ScaleFactor(0.02)
+{
+  this->SetNumberOfInputPorts(0);
+}
+
+vtkContactReader::~vtkContactReader()
+{
+}
+
+int vtkContactReader::RequestInformation(vtkInformation *vtkNotUsed(request),
+                                         vtkInformationVector **vtkNotUsed(inputVector),
+                                         vtkInformationVector *outputVector)
+{
+  return 1;
+}
+
+void FillValue(vtkVariantArray *row, double *ptToFeed, std::size_t ipos, vtkIdType pos)
+{
+  bool isOK(false);
+  vtkVariant *elt(row->GetPointer(pos));
+  ptToFeed[ipos] = elt->ToDouble(&isOK);
+  if (!isOK)
+  {
+    std::ostringstream oss;
+    oss << "vtkContactReader::FillValue : Error during analyze content of file ! Float64 expected !";
+    throw MyException(oss.str());
+  }
+}
+
+int vtkContactReader::RequestData(vtkInformation *vtkNotUsed(request),
+                                  vtkInformationVector **vtkNotUsed(inputVector),
+                                  vtkInformationVector *outputVector)
+{
+  vtkInformation *outInfo(outputVector->GetInformationObject(0));
+  vtkPolyData *output(vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+  //
+  try
+  {
+    vtkNew<vtkDelimitedTextReader> reader;
+    reader->SetFileName(this->FileName);
+    reader->SetDetectNumericColumns(true);
+    reader->SetUseStringDelimiter(true);
+    reader->SetHaveHeaders(true);
+    reader->SetFieldDelimiterCharacters(" ");
+    reader->SetAddTabFieldDelimiter(true);
+    reader->SetMergeConsecutiveDelimiters(true);
+    reader->Update();
+    vtkTable *table(reader->GetOutput());
+    vtkIdType nbRows(table->GetNumberOfRows()), nbCols(table->GetNumberOfColumns());
+    std::vector<std::string> colNames(nbCols);
+    for (vtkIdType iCol = 0; iCol < nbCols; iCol++)
+    {
+      colNames[iCol] = table->GetColumnName(iCol);
+    }
+    vtkIdType XPos(PosOf(colNames, "X")), YPos(PosOf(colNames, "Y")), ZPos(PosOf(colNames, "Z")), DXPos(PosOf(colNames, "DX")), DYPos(PosOf(colNames, "DY")), DZPos(PosOf(colNames, "DZ"));
+    //
+    vtkSmartPointer<vtkDoubleArray> coords(vtkSmartPointer<vtkDoubleArray>::New()), vectArr(vtkSmartPointer<vtkDoubleArray>::New());
+    vectArr->SetNumberOfComponents(3);
+    coords->SetNumberOfComponents(3);
+    coords->SetNumberOfTuples(nbRows);
+    vectArr->SetNumberOfTuples(nbRows);
+    double *ptToFeed1(coords->Begin()), *ptToFeed2(vectArr->Begin());
+    const vtkIdType POS[3] = {XPos, YPos, ZPos}, DX[3] = {DXPos, DYPos, DZPos};
+    for (vtkIdType iRow = 0; iRow < nbRows; iRow++, ptToFeed1 += 3, ptToFeed2 += 3)
+    {
+      vtkVariantArray *row(table->GetRow(iRow));
+      for (std::size_t ipos = 0; ipos < 3; ipos++)
+      {
+        FillValue(row, ptToFeed1, ipos, POS[ipos]);
+        FillValue(row, ptToFeed2, ipos, DX[ipos]);
+      }
+      std::for_each(ptToFeed2, ptToFeed2 + 3, [](double &v) { v = -v; });
+    }
+    vectArr->SetName("Resultante");
+    vtkNew<vtkPolyData> ret;
+    vtkSmartPointer<vtkPoints> pts(vtkSmartPointer<vtkPoints>::New());
+    pts->SetData(coords);
+    ret->SetPoints(pts);
+    ret->GetPointData()->AddArray(vectArr);
+    //
+    vtkNew<vtkPVGlyphFilter> glyph;
+    glyph->SetInputData(ret);
+    glyph->SetGlyphMode(0);       //vtkPVGlyphFilter::ALL_POINTS
+    glyph->SetVectorScaleMode(0); //vtkPVGlyphFilter::SCALE_BY_MAGNITUDE
+    //
+    vtkNew<vtkArrowSource> arrow;
+    arrow->SetTipResolution(6);
+    arrow->SetTipRadius(0.1);
+    arrow->SetTipLength(0.35);
+    arrow->SetShaftResolution(6);
+    arrow->SetShaftRadius(0.03);
+    glyph->SetSourceConnection(arrow->GetOutputPort());
+    //idx,port,connection,fieldAssociation,name
+    glyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Resultante"); //idx==0 -> scaleArray
+    glyph->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Resultante"); //idx==1 -> orientationArray
+    glyph->SetScaleFactor(this->ScaleFactor);
+    glyph->Update();
+    output->ShallowCopy(glyph->GetOutput());
+    output->GetPointData()->SetActiveAttribute(0, vtkDataSetAttributes::SCALARS);
+    //output->ShallowCopy(ret);
+  }
+  catch (MyException &e)
+  {
+    vtkErrorMacro(<< "vtkContactReader::RequestData : during read of " << this->FileName << " : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkContactReader::SetScaleFactor(double newScaleFactor)
+{
+  if (this->ScaleFactor != newScaleFactor)
+  {
+    this->ScaleFactor = newScaleFactor;
+    this->Modified();
+  }
+}
+
+void vtkContactReader::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ContactReader/plugin/ContactReaderModule/vtkContactReader.h b/src/ContactReader/plugin/ContactReaderModule/vtkContactReader.h
new file mode 100644 (file)
index 0000000..1195eeb
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkContactReader_h__
+#define __vtkContactReader_h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+class VTK_EXPORT vtkContactReader : public vtkPolyDataAlgorithm
+{
+public:
+  static vtkContactReader *New();
+  vtkTypeMacro(vtkContactReader, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  vtkSetStringMacro(FileName);
+  vtkGetStringMacro(FileName);
+
+  void SetScaleFactor(double newScaleFactor);
+
+protected:
+  vtkContactReader();
+  ~vtkContactReader() override;
+
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+
+  char *FileName;
+  double ScaleFactor;
+
+private:
+  vtkContactReader(const vtkContactReader &) = delete;
+  void operator=(const vtkContactReader &) = delete;
+};
+
+#endif
diff --git a/src/ContactReader/plugin/paraview.plugin b/src/ContactReader/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..2320b30
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ContactReader
+DESCRIPTION
+  This plugin provides the ContactReader reader.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::IOInfovis
+  VTK::FiltersCore
diff --git a/src/ContactReader/plugin/sources.xml b/src/ContactReader/plugin/sources.xml
new file mode 100644 (file)
index 0000000..ef82977
--- /dev/null
@@ -0,0 +1,33 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="sources">
+    <SourceProxy class="vtkContactReader"
+                 name="ContactReader">
+      <Documentation
+        short_help= "Lit un fichier pour afficher les resultantes au contact."
+        long_help = "Lit un fichier pour afficher les resultantes au contact.">
+      </Documentation>
+      <StringVectorProperty number_of_elements="1"
+                            animateable="0"
+                            name="FileName"
+                            command="SetFileName">
+        <FileListDomain name="files" />
+        <Documentation>
+          This property specifies the file name for this reader.
+        </Documentation>
+      </StringVectorProperty>
+      <DoubleVectorProperty command="SetScaleFactor"
+                            default_values="0.02"
+                            name="ScaleFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <Documentation>
+          This property specifies the scale factor applied to the size of arrows.
+        </Documentation>
+      </DoubleVectorProperty>
+      <Hints>
+        <ReaderFactory extensions="rco" file_description="Resultantes files (Plugin)" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ContactReader/resultante_rn.rco b/src/ContactReader/resultante_rn.rco
new file mode 100644 (file)
index 0000000..d3de61f
--- /dev/null
@@ -0,0 +1,16 @@
+X         Y         Z                DX           DY           DZ          
+31.1904  -77.7735  925.000      -8.35353E+07  9.40967E+07  6.90162E+07
+22.1834  -61.2353  908.778      -7.45578E+07  7.06419E+07  9.90851E+07
+13.0107  -37.3614  891.655      -1.12622E+08  6.34184E+07  1.44383E+08
+7.51714  -13.1788  878.021      -2.56908E+08  1.12063E+08  3.62862E+08
+7.33547  15.1584   875.000      -2.30530E+08 -5.64037E+07  2.79925E+08
+17.3523  38.7410   892.437      -1.50812E+08 -7.11926E+07  1.93785E+08
+23.1342  61.0311   902.140      -9.96464E+07 -6.47382E+07  1.24483E+08
+36.1858  80.8956   916.589      -7.26821E+07 -5.30730E+07  8.41775E+07
+50.9030  94.6827   932.711      -6.46772E+07 -5.50817E+07  6.21764E+07
+
+
+
+
+
+
diff --git a/src/ContactReader/resultante_rn.txt b/src/ContactReader/resultante_rn.txt
new file mode 100644 (file)
index 0000000..d3de61f
--- /dev/null
@@ -0,0 +1,16 @@
+X         Y         Z                DX           DY           DZ          
+31.1904  -77.7735  925.000      -8.35353E+07  9.40967E+07  6.90162E+07
+22.1834  -61.2353  908.778      -7.45578E+07  7.06419E+07  9.90851E+07
+13.0107  -37.3614  891.655      -1.12622E+08  6.34184E+07  1.44383E+08
+7.51714  -13.1788  878.021      -2.56908E+08  1.12063E+08  3.62862E+08
+7.33547  15.1584   875.000      -2.30530E+08 -5.64037E+07  2.79925E+08
+17.3523  38.7410   892.437      -1.50812E+08 -7.11926E+07  1.93785E+08
+23.1342  61.0311   902.140      -9.96464E+07 -6.47382E+07  1.24483E+08
+36.1858  80.8956   916.589      -7.26821E+07 -5.30730E+07  8.41775E+07
+50.9030  94.6827   932.711      -6.46772E+07 -5.50817E+07  6.21764E+07
+
+
+
+
+
+
diff --git a/src/CustomFilters/CMakeLists.txt b/src/CustomFilters/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6526e4b
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#
+# Author : Anthony Geay (EDF R&D)
+
+project(CustomFilters)
+cmake_minimum_required(VERSION 2.8)
+install(FILES papbComp.xml DESTINATION lib/paraview)
+install(FILES TemporalCSVReader.xml DESTINATION lib/paraview)
+# make testMEDReader3.py fail
+#install(FILES Electromagnetism.xml DESTINATION lib/paraview)
diff --git a/src/CustomFilters/Electromagnetism.xml b/src/CustomFilters/Electromagnetism.xml
new file mode 100644 (file)
index 0000000..c5c80fb
--- /dev/null
@@ -0,0 +1,59 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+
+    <SourceProxy name="MyClip" label="Clip"
+                class="vtkPVMetaClipDataSet"
+                base_proxygroup="filters"
+                base_proxyname="Clip">
+     <Hints>
+       <ShowInMenu category="Electromagnetism" icon=":/pqWidgets/Icons/pqClip.svg"/>
+     </Hints>
+   </SourceProxy>
+
+   <SourceProxy name="MyProbeLocation" label="Probe Location"
+                class="vtkPProbeFilter"
+                base_proxygroup="filters"
+                base_proxyname="ProbePoint">
+     <Hints>
+       <ShowInMenu category="Electromagnetism"/>
+     </Hints>
+   </SourceProxy>
+   
+   <SourceProxy name="MyDataSetSurfaceFilter" label="Extract Surface"
+                class="vtkTubeFilter"
+                base_proxygroup="filters"
+                base_proxyname="DataSetSurfaceFilter">
+     <Hints>
+       <ShowInMenu category="Electromagnetism"/>
+     </Hints>
+   </SourceProxy>
+
+    <SourceProxy name="MyTubeFilter" label="Tube"
+                class="vtkDataSetSurfaceFilter"
+                base_proxygroup="filters"
+                base_proxyname="TubeFilter">
+     <Hints>
+       <ShowInMenu category="Electromagnetism"/>
+     </Hints>
+   </SourceProxy>
+   
+  <SourceProxy name="MyCut" label="Slice"
+                class="vtkPVMetaSliceDataSet"
+                base_proxygroup="filters"
+                base_proxyname="Cut">
+     <Hints>
+       <ShowInMenu category="Electromagnetism"/>
+     </Hints>
+   </SourceProxy>
+   
+   <SourceProxy name="MyCellDataToPointData" label="Cell Data to Point Data"
+                class="vtkPCellDataToPointData"
+                base_proxygroup="filters"
+                base_proxyname="CellDataToPointData">
+     <Hints>
+       <ShowInMenu category="Electromagnetism"/>
+     </Hints>
+   </SourceProxy>
+
+ </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/CustomFilters/TemporalCSVReader.xml b/src/CustomFilters/TemporalCSVReader.xml
new file mode 100644 (file)
index 0000000..761c2ff
--- /dev/null
@@ -0,0 +1,117 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="sources">
+    <SourceProxy class="vtkTemporalDelimitedTextReader"
+                 label="Temporal CSV Reader"
+                 name="TemporalCSVReader">
+      <Documentation long_help="Reads a temporal Delimited Text values file into a 1D rectilinear grid."
+                     short_help="Read a temporal Delimited Text values file.">The
+                    temporal Delimited text reader reads a Delimited Text values
+                    file into a 1D rectilinear grid. A user defined column is
+                    used as time step indicator. On a given time step s, only
+                    the lines having this column at the value s are kept. The
+                    default file extensions are .csv, .tcsv, .txt.
+      </Documentation>
+      <!-- CSV Reader parameters -->
+      <StringVectorProperty animateable="1"
+                            command="SetFileName"
+                            name="FileName"
+                            number_of_elements="1"
+                            panel_visibility="never">
+        <FileListDomain name="files" />
+        <Documentation>This property specifies the file name for the temporal CSV
+          (Command Separated Values) reader.
+        </Documentation>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetFieldDelimiterCharacters"
+                            default_values=""
+                            name="FieldDelimiterCharacters"
+                            number_of_elements="1">
+        <Documentation>This property lists the characters that may be used to
+          separate fields. For example, a value of "," indicates a
+          comma-separated value file. A value of ".:;" indicates that columns
+          may be separated by a period, colon or semicolon. The order of the
+          characters in the text string does not matter.
+        </Documentation>
+      </StringVectorProperty>
+      <IntVectorProperty command="SetAddTabFieldDelimiter"
+                         default_values="0"
+                         name="AddTabFieldDelimiter"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <BooleanDomain name="bool" />
+        <Documentation>This property indicates whether to add the tab character as a
+          field delimiter to the list of other delimiter characters. This is needed
+          since in the GUI the user can't enter a tab character.
+        </Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetMergeConsecutiveDelimiters"
+                         default_values="0"
+                         name="MergeConsecutiveDelimiters"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <BooleanDomain name="bool" />
+        <Documentation>Whether to merge successive delimiters. Use this if (for
+          example) your fields are separated by spaces but you don't know exactly
+          how many.
+        </Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetHaveHeaders"
+                         default_values="1"
+                         name="HaveHeaders"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Documentation>If the value of this property is 1, treat the first line
+          of the file as headers. Otherwise, column are named using their
+          position with the following pattern: "Field [num]" starting at 0. Use
+          this name to define the temporal indicator.
+        </Documentation>
+      </IntVectorProperty>
+
+      <!-- Time step indicator fields -->
+      <StringVectorProperty animateable="1"
+                            command="SetTimeColumnName"
+                            name="TimeColumnName"
+                            number_of_elements="1">
+        <Documentation>This property specifies the name of the column
+          to use as time indicator.
+        </Documentation>
+      </StringVectorProperty>
+      <IntVectorProperty command="SetRemoveTimeStepColumn"
+                         default_values="1"
+                         name="RemoveTimeStepColumn"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <BooleanDomain name="bool" />
+        <Documentation>This property specifies wether or not to keep
+          the column chosen as time step indicator in the output.
+        </Documentation>
+      </IntVectorProperty>
+      <!-- Tell paraview about time steps -->
+      <DoubleVectorProperty information_only="1"
+                            name="TimestepValues"
+                            repeatable="1">
+        <TimeStepsInformationHelper />
+        <Documentation>Available timestep values.</Documentation>
+      </DoubleVectorProperty>
+
+       <!-- structure -->
+      <PropertyGroup panel_widget="Line" label="Temporal indicator parmeters">
+        <Property name="TimeColumnName" />
+        <Property name="RemoveTimeStepColumn" />
+      </PropertyGroup>
+      <PropertyGroup panel_widget="Line" label="Input file parameters">
+        <Property name="FieldDelimiterCharacters" />
+        <Property name="AddTabFieldDelimiter" />
+        <Property name="HaveHeaders" />
+        <Property name="MergeConsecutiveDelimiters" />
+      </PropertyGroup>
+
+      <Hints>
+        <View type="SpreadSheetView" />
+        <ReaderFactory extensions="csv trco tsv txt CSV TSV TXT"
+                       file_description="Temporal Delimited Text" />
+      </Hints>
+
+   </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/CustomFilters/papbComp.cpd b/src/CustomFilters/papbComp.cpd
new file mode 100644 (file)
index 0000000..520260a
--- /dev/null
@@ -0,0 +1,98 @@
+<CustomFilterDefinitions>
+  <CustomProxyDefinition name="PA PB Computation" group="filters">
+    <CompoundSourceProxy id="26994" servers="1">
+      <Proxy group="filters" type="ProbeLine" id="14588" servers="1" compound_name="PlotOverLine1">
+        <Property name="ComputeTolerance" id="14588.ComputeTolerance" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="14588.ComputeTolerance.bool"/>
+        </Property>
+        <Property name="Input" id="14588.Input" number_of_elements="1">
+          <Domain name="groups" id="14588.Input.groups"/>
+          <Domain name="input_array" id="14588.Input.input_array"/>
+          <Domain name="input_type" id="14588.Input.input_type"/>
+        </Property>
+        <Property name="PassPartialArrays" id="14588.PassPartialArrays" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="14588.PassPartialArrays.bool"/>
+        </Property>
+        <Property name="Source" id="14588.Source" number_of_elements="1">
+          <Proxy value="14555" output_port="0"/>
+          <Domain name="groups" id="14588.Source.groups"/>
+          <Domain name="proxy_list" id="14588.Source.proxy_list">
+            <Proxy value="14555"/>
+          </Domain>
+        </Property>
+        <Property name="Tolerance" id="14588.Tolerance" number_of_elements="1">
+          <Element index="0" value="2.220446049250313e-16"/>
+          <Domain name="range" id="14588.Tolerance.range"/>
+        </Property>
+      </Proxy>
+      <Proxy group="filters" type="ProgrammableFilter" id="14610" servers="1" compound_name="ProgrammableFilter1">
+        <Property name="CopyArrays" id="14610.CopyArrays" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="14610.CopyArrays.bool"/>
+        </Property>
+        <Property name="InformationScript" id="14610.InformationScript" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+        <Property name="Input" id="14610.Input" number_of_elements="1">
+          <Proxy value="14588" output_port="0"/>
+          <Domain name="groups" id="14610.Input.groups"/>
+          <Domain name="input_type" id="14610.Input.input_type"/>
+        </Property>
+        <Property name="OutputDataSetType" id="14610.OutputDataSetType" number_of_elements="1">
+          <Element index="0" value="19"/>
+          <Domain name="enum" id="14610.OutputDataSetType.enum">
+            <Entry value="8" text="Same as Input"/>
+            <Entry value="0" text="vtkPolyData"/>
+            <Entry value="2" text="vtkStructuredGrid"/>
+            <Entry value="3" text="vtkRectilinearGrid"/>
+            <Entry value="4" text="vtkUnstructuredGrid"/>
+            <Entry value="6" text="vtkImageData"/>
+            <Entry value="10" text="vtkUniformGrid"/>
+            <Entry value="13" text="vtkMultiblockDataSet"/>
+            <Entry value="15" text="vtkHierarchicalBoxDataSet"/>
+            <Entry value="19" text="vtkTable"/>
+            <Entry value="33" text="vtkMolecule"/>
+          </Domain>
+        </Property>
+        <Property name="PythonPath" id="14610.PythonPath" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+        <Property name="Script" id="14610.Script" number_of_elements="1">
+          <Element index="0" value="import numpy as np&#xa;import vtk&#xa;from vtk.numpy_interface import dataset_adapter as da&#xa;&#xa;####REPERE LOCAL&#xa;&#xa;##deux extremites de la ligne de coupe&#xa;&#xa;P0 = inputs[0].GetPoint(0)&#xa;P1 = inputs[0].GetPoint(inputs[0].GetNumberOfPoints() - 1)&#xa;&#xa;R = np.array([[P0[0]-P1[0], P0[1]-P1[1],  P0[2]-P1[2]]])&#xa;R=  R/np.linalg.norm(R)&#xa;&#xa;###vecteur normal au plan&#xa;L = np.array([[1,0,0]])&#xa;L = L/np.linalg.norm(L)&#xa;&#xa;##complete le triedre&#xa;C = np.cross(R,L)&#xa;&#xa;##matrice de passage&#xa;BBp = np.concatenate((R,L,C), axis=0).T&#xa;&#xa;&#xa;M=np.eye(3,3)&#xa;B=np.eye(3,3)&#xa;&#xa;siefNoeu = np.array(inputs[0].GetPointData().GetAbstractArray(&#x27;RESU____SIEF_NOEU&#x27;))&#xa;arr0 = siefNoeu[:,0]&#xa;arr1 = siefNoeu[:,1]&#xa;arr2 = siefNoeu[:,2]&#xa;arr3 = siefNoeu[:,3]&#xa;arr4 = siefNoeu[:,4]&#xa;arr5 = siefNoeu[:,5]&#xa;&#xa;arcLength = np.array(inputs[0].GetPointData().GetAbstractArray(&#x27;arc_length&#x27;))&#xa;&#xa;##remove nans&#xa;nans = numpy.isnan(arr0)&#xa;arr0 = arr0[numpy.logical_not(nans)]&#xa;arr1 = arr1[numpy.logical_not(nans)]&#xa;arr2 = arr2[numpy.logical_not(nans)]&#xa;arr3 = arr3[numpy.logical_not(nans)]&#xa;arr4 = arr4[numpy.logical_not(nans)]&#xa;arr5 = arr5[numpy.logical_not(nans)]&#xa;arcLength = arcLength[numpy.logical_not(nans)]&#xa;&#xa;for i in range(size(arr0)):&#xa;                S=np.eye(3,3)&#xa;                S[0][0] = arr0[i]&#xa;                S[0][1] = arr3[i]&#xa;                S[0][2] = arr4[i]&#xa;                S[1][0] = S[0][1]&#xa;                S[1][1] = arr1[i]&#xa;                S[1][2] = arr5[i]&#xa;                S[2][0] = S[0][2]&#xa;                S[2][1] = S[1][2]&#xa;                S[2][2] = arr2[i]&#xa;                Sp = np.linalg.inv(BBp).dot(S).dot(BBp)&#xa;                arr0[i] = Sp[0][0]&#xa;                arr3[i] = Sp[0][1] &#xa;                arr4[i] = Sp[0][2]&#xa;                arr1[i] = Sp[1][1]&#xa;                arr5[i] = Sp[1][2]&#xa;                arr2[i] = Sp[2][2]&#xa;                &#xa;M=np.eye(3,3)&#xa;M[0][0] = np.mean(arr0)&#xa;M[0][1] = np.mean(arr3)&#xa;M[0][2] = np.mean(arr4)&#xa;M[1][0] = M[0][1]&#xa;M[1][1] = np.mean(arr1)&#xa;M[1][2] = np.mean(arr5)&#xa;M[2][0] = M[0][2]&#xa;M[2][1] = M[1][2]&#xa;M[2][2] = np.mean(arr2)&#xa;&#xa;w_m, v_m = np.linalg.eig(M)&#xa;&#xa;PM = np.maximum(np.abs(w_m[0]-w_m[1]),np.abs(w_m[2]-w_m[1]))&#xa;PM = np.maximum(PM,np.abs(w_m[0]-w_m[2]))&#xa;print(&#x22;PM :&#x22;, PM)&#xa;&#xa;B=np.eye(3,3)&#xa;&#xa;X = arcLength - min(arcLength)&#xa;&#xa;&#xa;DELTA = max(X) - min(X)&#xa;&#xa;B[0][0] = 6*np.trapz((X-DELTA/2)*arr0,x=(X-DELTA/2))/(DELTA**2)&#xa;B[0][1] = 6*np.trapz((X-DELTA/2)*arr3,x=(X-DELTA/2))/(DELTA**2)&#xa;B[0][2] = 6*np.trapz((X-DELTA/2)*arr4,x=(X-DELTA/2))/(DELTA**2)&#xa;B[1][0] = B[0][1]&#xa;B[1][1] = 6*np.trapz((X-DELTA/2)*arr1,x=(X-DELTA/2))/(DELTA**2)&#xa;B[1][2] = 6*np.trapz((X-DELTA/2)*arr5,x=(X-DELTA/2))/(DELTA**2)&#xa;B[2][0] = B[0][2]&#xa;B[2][1] = B[1][2]&#xa;B[2][2] = 6*np.trapz((X-DELTA/2)*arr2,x=(arcLength-DELTA/2))/(DELTA**2)&#xa;&#xa; &#xa;w_b, v_b = np.linalg.eig(B)&#xa;&#xa;PB = np.maximum(np.abs(w_b[0]-w_b[1]),np.abs(w_b[2]-w_b[1]))&#xa;PB = np.maximum(PB,np.abs(w_b[0]-w_b[2]))&#xa;print(&#x22;PB :&#x22;, PB)&#xa;MB = M + B&#xa;w_mb, v_mb = np.linalg.eig(MB)&#xa;&#xa;PMB = np.maximum(np.abs(w_mb[0]-w_mb[1]),np.abs(w_mb[2]-w_mb[1]))&#xa;PMB = np.maximum(PMB,np.abs(w_mb[0]-w_mb[2]))&#xa;print(&#x22;PMB :&#x22;, PMB)&#xa;&#xa;&#xa;MB_ = M - B&#xa;&#xa;w_mb_, v_mb_ = np.linalg.eig(MB_)&#xa;&#xa;PMB_ = np.maximum(np.abs(w_mb_[0]-w_mb_[1]),np.abs(w_mb_[2]-w_mb_[1]))&#xa;PMB_ = np.maximum(PMB_,np.abs(w_mb_[0]-w_mb_[2]))&#xa;print(&#x22;PMB_ :&#x22;, PMB_)&#xa;&#xa;&#xa;ca = vtk.vtkDoubleArray()&#xa;cas = vtk.vtkStringArray()&#xa;ca.SetName(&#x22;Results&#x22;)&#xa;cas.SetName(&#x22;Names&#x22;)&#xa;ca.SetNumberOfComponents(1)&#xa;cas.SetNumberOfComponents(1)&#xa;ca.SetNumberOfTuples(4)&#xa;cas.SetNumberOfTuples(4)&#xa;ca.SetValue(0, PM)&#xa;ca.SetValue(1, PB)&#xa;ca.SetValue(2, PMB)&#xa;ca.SetValue(3, PMB_)&#xa;cas.SetValue(0, &#x22;PM&#x22;)&#xa;cas.SetValue(1, &#x22;PB&#x22;)&#xa;cas.SetValue(2, &#x22;PMB&#x22;)&#xa;cas.SetValue(3, &#x22;PMB_&#x22;)&#xa;output.AddColumn(cas)&#xa;output.AddColumn(ca)&#xa;&#xa;"/>
+        </Property>
+        <Property name="TimestepValues" id="14610.TimestepValues"/>
+        <Property name="UpdateExtentScript" id="14610.UpdateExtentScript" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+      </Proxy>
+      <Proxy group="extended_sources" type="HighResLineSource" id="14555" servers="1" compound_name="auto_14555">
+        <Property name="Point1" id="14555.Point1" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="256"/>
+          <Element index="2" value="238"/>
+          <Domain name="range" id="14555.Point1.range"/>
+        </Property>
+        <Property name="Point2" id="14555.Point2" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="250"/>
+          <Element index="2" value="234"/>
+          <Domain name="range" id="14555.Point2.range"/>
+        </Property>
+        <Property name="Resolution" id="14555.Resolution" number_of_elements="1">
+          <Element index="0" value="50"/>
+          <Domain name="range" id="14555.Resolution.range"/>
+        </Property>
+      </Proxy>
+      <ExposedProperties>
+        <Property name="Input" proxy_name="PlotOverLine1" exposed_name="Input"/>
+        <Property name="Source" proxy_name="PlotOverLine1" exposed_name="Probe Type"/>
+      </ExposedProperties>
+      <OutputPort name="Output" proxy="ProgrammableFilter1" port_index="0"/>
+      <Hints>
+        <ShowInMenu/>
+      </Hints>
+    </CompoundSourceProxy>
+  </CustomProxyDefinition>
+</CustomFilterDefinitions>
diff --git a/src/CustomFilters/papbComp.xml b/src/CustomFilters/papbComp.xml
new file mode 100644 (file)
index 0000000..cf70eaf
--- /dev/null
@@ -0,0 +1,105 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <CompoundSourceProxy name="PAPBComputation" label="PA PB Computation" id="26994" servers="1">
+      <Proxy group="filters" type="ExtractThreeDim" id="8310" servers="1" compound_name="ExtractThreeDim1">
+        <Property name="Input" id="8310.Input" number_of_elements="1">
+          <Domain name="groups" id="8310.Input.groups"/>
+          <Domain name="input_type" id="8310.Input.input_type"/>
+        </Property>
+      </Proxy>
+      <Proxy group="filters" type="ProbeLine" id="14588" servers="1" compound_name="PlotOverLine1">
+        <Property name="ComputeTolerance" id="14588.ComputeTolerance" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="14588.ComputeTolerance.bool"/>
+        </Property>
+        <Property name="Input" id="14588.Input" number_of_elements="1">
+         <Proxy value="8310" output_port="0"/>
+          <Domain name="groups" id="14588.Input.groups"/>
+          <Domain name="input_array" id="14588.Input.input_array"/>
+          <Domain name="input_type" id="14588.Input.input_type"/>
+        </Property>
+        <Property name="PassPartialArrays" id="14588.PassPartialArrays" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="14588.PassPartialArrays.bool"/>
+        </Property>
+        <Property name="Source" id="14588.Source" number_of_elements="1">
+          <Proxy value="14555" output_port="0"/>
+          <Domain name="groups" id="14588.Source.groups"/>
+          <Domain name="proxy_list" id="14588.Source.proxy_list">
+            <Proxy value="14555"/>
+          </Domain>
+        </Property>
+        <Property name="Tolerance" id="14588.Tolerance" number_of_elements="1">
+          <Element index="0" value="2.220446049250313e-16"/>
+          <Domain name="range" id="14588.Tolerance.range"/>
+        </Property>
+      </Proxy>
+      <Proxy group="filters" type="ProgrammableFilter" id="14610" servers="1" compound_name="ProgrammableFilter1">
+        <Property name="CopyArrays" id="14610.CopyArrays" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="14610.CopyArrays.bool"/>
+        </Property>
+        <Property name="InformationScript" id="14610.InformationScript" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+        <Property name="Input" id="14610.Input" number_of_elements="1">
+          <Proxy value="14588" output_port="0"/>
+          <Domain name="groups" id="14610.Input.groups"/>
+          <Domain name="input_type" id="14610.Input.input_type"/>
+        </Property>
+        <Property name="OutputDataSetType" id="14610.OutputDataSetType" number_of_elements="1">
+          <Element index="0" value="19"/>
+          <Domain name="enum" id="14610.OutputDataSetType.enum">
+            <Entry value="8" text="Same as Input"/>
+            <Entry value="0" text="vtkPolyData"/>
+            <Entry value="2" text="vtkStructuredGrid"/>
+            <Entry value="3" text="vtkRectilinearGrid"/>
+            <Entry value="4" text="vtkUnstructuredGrid"/>
+            <Entry value="6" text="vtkImageData"/>
+            <Entry value="10" text="vtkUniformGrid"/>
+            <Entry value="13" text="vtkMultiblockDataSet"/>
+            <Entry value="15" text="vtkHierarchicalBoxDataSet"/>
+            <Entry value="19" text="vtkTable"/>
+            <Entry value="33" text="vtkMolecule"/>
+          </Domain>
+        </Property>
+        <Property name="PythonPath" id="14610.PythonPath" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+        <Property name="Script" id="14610.Script" number_of_elements="1">
+          <Element index="0" value="import numpy as np&#xa;import vtk&#xa;from vtk.numpy_interface import dataset_adapter as da&#xa;&#xa;####REPERE LOCAL&#xa;&#xa;##deux extremites de la ligne de coupe&#xa;&#xa;P0 = inputs[0].GetPoint(0)&#xa;P1 = inputs[0].GetPoint(inputs[0].GetNumberOfPoints() - 1)&#xa;&#xa;R = np.array([[P0[0]-P1[0], P0[1]-P1[1],  P0[2]-P1[2]]])&#xa;R=  R/np.linalg.norm(R)&#xa;&#xa;###vecteur normal au plan&#xa;L = np.array([[1,-1,0]])&#xa;L = L/np.linalg.norm(L)&#xa;&#xa;##complete le triedre&#xa;C = np.cross(R,L)&#xa;&#xa;##matrice de passage&#xa;BBp = np.concatenate((R,L,C), axis=0).T&#xa;&#xa;&#xa;M=np.eye(3,3)&#xa;B=np.eye(3,3)&#xa;&#xa;siefNoeu = np.array(inputs[0].GetPointData().GetAbstractArray(&#x27;RESU____SIEF_NOEU&#x27;))&#xa;arr0 = siefNoeu[:,0]&#xa;arr1 = siefNoeu[:,1]&#xa;arr2 = siefNoeu[:,2]&#xa;arr3 = siefNoeu[:,3]&#xa;arr4 = siefNoeu[:,4]&#xa;arr5 = siefNoeu[:,5]&#xa;&#xa;arcLength = np.array(inputs[0].GetPointData().GetAbstractArray(&#x27;arc_length&#x27;))&#xa;&#xa;##remove nans&#xa;nans = numpy.isnan(arr0)&#xa;arr0 = arr0[numpy.logical_not(nans)]&#xa;arr1 = arr1[numpy.logical_not(nans)]&#xa;arr2 = arr2[numpy.logical_not(nans)]&#xa;arr3 = arr3[numpy.logical_not(nans)]&#xa;arr4 = arr4[numpy.logical_not(nans)]&#xa;arr5 = arr5[numpy.logical_not(nans)]&#xa;arcLength = arcLength[numpy.logical_not(nans)]&#xa;&#xa;for i in range(size(arr0)):&#xa;                S=np.eye(3,3)&#xa;                S[0][0] = arr0[i]&#xa;                S[0][1] = arr3[i]&#xa;                S[0][2] = arr4[i]&#xa;                S[1][0] = S[0][1]&#xa;                S[1][1] = arr1[i]&#xa;                S[1][2] = arr5[i]&#xa;                S[2][0] = S[0][2]&#xa;                S[2][1] = S[1][2]&#xa;                S[2][2] = arr2[i]&#xa;                Sp = np.linalg.inv(BBp).dot(S).dot(BBp)&#xa;                arr0[i] = Sp[0][0]&#xa;                arr3[i] = Sp[0][1] &#xa;                arr4[i] = Sp[0][2]&#xa;                arr1[i] = Sp[1][1]&#xa;                arr5[i] = Sp[1][2]&#xa;                arr2[i] = Sp[2][2]&#xa;                &#xa;M=np.eye(3,3)&#xa;M[0][0] = np.mean(arr0)&#xa;M[0][1] = np.mean(arr3)&#xa;M[0][2] = np.mean(arr4)&#xa;M[1][0] = M[0][1]&#xa;M[1][1] = np.mean(arr1)&#xa;M[1][2] = np.mean(arr5)&#xa;M[2][0] = M[0][2]&#xa;M[2][1] = M[1][2]&#xa;M[2][2] = np.mean(arr2)&#xa;&#xa;w_m, v_m = np.linalg.eig(M)&#xa;&#xa;PM = np.maximum(np.abs(w_m[0]-w_m[1]),np.abs(w_m[2]-w_m[1]))&#xa;PM = np.maximum(PM,np.abs(w_m[0]-w_m[2]))&#xa;print(&#x22;PM :&#x22;, PM)&#xa;&#xa;B=np.eye(3,3)&#xa;&#xa;X = arcLength - min(arcLength)&#xa;&#xa;&#xa;DELTA = max(X) - min(X)&#xa;&#xa;B[0][0] = 6*np.trapz(-(X-DELTA/2)*arr0,x=X)/(DELTA**2)&#xa;B[0][1] = 6*np.trapz(-(X-DELTA/2)*arr3,x=X)/(DELTA**2)&#xa;B[0][2] = 6*np.trapz(-(X-DELTA/2)*arr4,x=X)/(DELTA**2)&#xa;B[1][0] = B[0][1]&#xa;B[1][1] = 6*np.trapz(-(X-DELTA/2)*arr1,x=X)/(DELTA**2)&#xa;B[1][2] = 6*np.trapz(-(X-DELTA/2)*arr5,x=X)/(DELTA**2)&#xa;B[2][0] = B[0][2]&#xa;B[2][1] = B[1][2]&#xa;B[2][2] = 6*np.trapz(-(X-DELTA/2)*arr2,x=X)/(DELTA**2)&#xa;&#xa; &#xa;w_b, v_b = np.linalg.eig(B)&#xa;&#xa;PB = np.maximum(np.abs(w_b[0]-w_b[1]),np.abs(w_b[2]-w_b[1]))&#xa;PB = np.maximum(PB,np.abs(w_b[0]-w_b[2]))&#xa;print(&#x22;PB :&#x22;, PB)&#xa;MB = M + B&#xa;w_mb, v_mb = np.linalg.eig(MB)&#xa;&#xa;PMB = np.maximum(np.abs(w_mb[0]-w_mb[1]),np.abs(w_mb[2]-w_mb[1]))&#xa;PMB = np.maximum(PMB,np.abs(w_mb[0]-w_mb[2]))&#xa;print(&#x22;PMB :&#x22;, PMB)&#xa;&#xa;&#xa;MB_ = M - B&#xa;&#xa;w_mb_, v_mb_ = np.linalg.eig(MB_)&#xa;&#xa;PMB_ = np.maximum(np.abs(w_mb_[0]-w_mb_[1]),np.abs(w_mb_[2]-w_mb_[1]))&#xa;PMB_ = np.maximum(PMB_,np.abs(w_mb_[0]-w_mb_[2]))&#xa;print(&#x22;PMB_ :&#x22;, PMB_)&#xa;&#xa;&#xa;ca = vtk.vtkDoubleArray()&#xa;cas = vtk.vtkStringArray()&#xa;ca.SetName(&#x22;Results&#x22;)&#xa;cas.SetName(&#x22;Names&#x22;)&#xa;ca.SetNumberOfComponents(1)&#xa;cas.SetNumberOfComponents(1)&#xa;ca.SetNumberOfTuples(4)&#xa;cas.SetNumberOfTuples(4)&#xa;ca.SetValue(0, PM)&#xa;ca.SetValue(1, PB)&#xa;ca.SetValue(2, PMB)&#xa;ca.SetValue(3, PMB_)&#xa;cas.SetValue(0, &#x22;PM&#x22;)&#xa;cas.SetValue(1, &#x22;PB&#x22;)&#xa;cas.SetValue(2, &#x22;PMB&#x22;)&#xa;cas.SetValue(3, &#x22;PMB_&#x22;)&#xa;output.AddColumn(cas)&#xa;output.AddColumn(ca)&#xa;&#xa;"/>
+        </Property>
+        <Property name="TimestepValues" id="14610.TimestepValues"/>
+        <Property name="UpdateExtentScript" id="14610.UpdateExtentScript" number_of_elements="1">
+          <Element index="0" value=""/>
+        </Property>
+      </Proxy>
+      <Proxy group="extended_sources" type="HighResLineSource" id="14555" servers="1" compound_name="auto_14555">
+        <Property name="Point1" id="14555.Point1" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="256"/>
+          <Element index="2" value="238"/>
+          <Domain name="range" id="14555.Point1.range"/>
+        </Property>
+        <Property name="Point2" id="14555.Point2" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="250"/>
+          <Element index="2" value="234"/>
+          <Domain name="range" id="14555.Point2.range"/>
+        </Property>
+        <Property name="Resolution" id="14555.Resolution" number_of_elements="1">
+          <Element index="0" value="50"/>
+          <Domain name="range" id="14555.Resolution.range"/>
+        </Property>
+      </Proxy>
+      <ExposedProperties>
+        <Property name="Input" proxy_name="ExtractThreeDim1" exposed_name="Input"/>
+        <Property name="Source" proxy_name="PlotOverLine1" exposed_name="Probe Type"/>
+      </ExposedProperties>
+      <OutputPort name="Output" proxy="ProgrammableFilter1" port_index="0"/>
+      <Hints>
+        <ShowInMenu/>
+      </Hints>
+    </CompoundSourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/CustomFilters/post_R_resuir.trco b/src/CustomFilters/post_R_resuir.trco
new file mode 100644 (file)
index 0000000..7379706
--- /dev/null
@@ -0,0 +1,181 @@
+INST;DX;DY;DZ;X;Y;Z
+1.0;16.9;-13.0;-20.5;50.9;-84.7;798.4
+2.0;32.3;-17.1;-21.4;50.9;-84.7;798.4
+3.0;33.7;-16.8;-21.5;50.9;-84.7;798.4
+4.0;34.2;-16.7;-21.5;50.9;-84.7;798.4
+5.0;35.9;-16.3;-21.6;50.9;-84.7;798.4
+6.0;40.0;-19.0;-22.0;50.9;-84.7;798.4
+7.0;67.0;-44.2;-19.2;50.9;-84.7;798.4
+8.0;68.5;-43.9;-19.3;50.9;-84.7;798.4
+9.0;68.9;-43.8;-19.3;50.9;-84.7;798.4
+10.0;-5.3;12.1;-23.4;50.9;-84.7;798.4
+11.0;-3.9;12.4;-23.5;50.9;-84.7;798.4
+12.0;-3.4;12.5;-23.5;50.9;-84.7;798.4
+1.0;0.6;-5.4;-9.7;35.5;-73.5;795.2
+2.0;11.4;-9.3;-11.0;35.5;-73.5;795.2
+3.0;12.3;-9.3;-11.0;35.5;-73.5;795.2
+4.0;12.6;-9.3;-11.1;35.5;-73.5;795.2
+5.0;13.7;-9.2;-11.2;35.5;-73.5;795.2
+6.0;16.1;-11.5;-11.6;35.5;-73.5;795.2
+7.0;11.9;-19.8;-7.1;35.5;-73.5;795.2
+8.0;12.8;-19.7;-7.2;35.5;-73.5;795.2
+9.0;13.1;-19.7;-7.3;35.5;-73.5;795.2
+10.0;9.8;3.0;-15.0;35.5;-73.5;795.2
+11.0;10.7;3.0;-15.0;35.5;-73.5;795.2
+12.0;11.0;3.0;-15.1;35.5;-73.5;795.2
+1.0;2.8;-11.6;-11.1;26.2;-63.2;791.4
+2.0;27.8;-24.6;-13.7;26.2;-63.2;791.4
+3.0;29.4;-25.1;-13.9;26.2;-63.2;791.4
+4.0;29.9;-25.3;-14.0;26.2;-63.2;791.4
+5.0;31.8;-25.8;-14.2;26.2;-63.2;791.4
+6.0;36.9;-29.9;-15.5;26.2;-63.2;791.4
+7.0;29.7;-44.2;-3.3;26.2;-63.2;791.4
+8.0;31.3;-44.7;-3.5;26.2;-63.2;791.4
+9.0;31.8;-44.8;-3.5;26.2;-63.2;791.4
+10.0;23.6;-1.0;-25.0;26.2;-63.2;791.4
+11.0;25.2;-1.4;-25.2;26.2;-63.2;791.4
+12.0;25.8;-1.6;-25.3;26.2;-63.2;791.4
+1.0;-0.3;-12.0;-27.8;19.2;-51.6;785.2
+2.0;43.8;-33.9;-34.3;19.2;-51.6;785.2
+3.0;45.9;-34.8;-34.7;19.2;-51.6;785.2
+4.0;46.6;-35.1;-34.8;19.2;-51.6;785.2
+5.0;49.1;-36.1;-35.3;19.2;-51.6;785.2
+6.0;58.9;-42.1;-37.9;19.2;-51.6;785.2
+7.0;41.2;-58.8;-21.5;19.2;-51.6;785.2
+8.0;43.3;-59.7;-21.9;19.2;-51.6;785.2
+9.0;44.0;-60.0;-22.0;19.2;-51.6;785.2
+10.0;44.0;-2.5;-49.3;19.2;-51.6;785.2
+11.0;46.1;-3.4;-49.7;19.2;-51.6;785.2
+12.0;46.8;-3.7;-49.8;19.2;-51.6;785.2
+1.0;-6.0;-3.5;-53.0;14.0;-39.1;777.7
+2.0;57.3;-31.5;-64.9;14.0;-39.1;777.7
+3.0;59.6;-32.5;-65.4;14.0;-39.1;777.7
+4.0;60.4;-32.9;-65.6;14.0;-39.1;777.7
+5.0;63.0;-34.0;-66.2;14.0;-39.1;777.7
+6.0;78.0;-40.7;-69.9;14.0;-39.1;777.7
+7.0;48.9;-58.9;-54.9;14.0;-39.1;777.7
+8.0;51.2;-59.9;-55.4;14.0;-39.1;777.7
+9.0;52.0;-60.3;-55.6;14.0;-39.1;777.7
+10.0;64.1;5.6;-77.9;14.0;-39.1;777.7
+11.0;66.4;4.6;-78.4;14.0;-39.1;777.7
+12.0;67.1;4.2;-78.6;14.0;-39.1;777.7
+1.0;-8.0;3.1;-75.7;10.8;-25.8;770.0
+2.0;67.0;-27.1;-87.7;10.8;-25.8;770.0
+3.0;69.2;-28.1;-88.1;10.8;-25.8;770.0
+4.0;69.9;-28.4;-88.2;10.8;-25.8;770.0
+5.0;72.4;-29.5;-88.6;10.8;-25.8;770.0
+6.0;91.0;-36.0;-92.2;10.8;-25.8;770.0
+7.0;64.1;-63.4;-85.0;10.8;-25.8;770.0
+8.0;66.3;-64.3;-85.3;10.8;-25.8;770.0
+9.0;67.0;-64.6;-85.4;10.8;-25.8;770.0
+10.0;69.9;18.9;-93.0;10.8;-25.8;770.0
+11.0;72.1;17.9;-93.3;10.8;-25.8;770.0
+12.0;72.8;17.6;-93.5;10.8;-25.8;770.0
+1.0;-4.6;-0.7;-102.4;7.7;-13.2;763.3
+2.0;81.5;-3.3;-76.2;7.7;-13.2;763.3
+3.0;83.4;-3.4;-75.1;7.7;-13.2;763.3
+4.0;84.0;-3.4;-74.7;7.7;-13.2;763.3
+5.0;86.2;-3.5;-73.4;7.7;-13.2;763.3
+6.0;104.7;-4.4;-66.9;7.7;-13.2;763.3
+7.0;67.2;-42.3;-109.3;7.7;-13.2;763.3
+8.0;69.1;-42.4;-108.2;7.7;-13.2;763.3
+9.0;69.7;-42.4;-107.8;7.7;-13.2;763.3
+10.0;101.3;51.7;-37.6;7.7;-13.2;763.3
+11.0;103.1;51.6;-36.4;7.7;-13.2;763.3
+12.0;103.7;51.6;-36.1;7.7;-13.2;763.3
+1.0;-1.7;-1.2;-111.9;6.3;0.0;760.2
+2.0;66.7;0.3;-79.6;6.3;0.0;760.2
+3.0;68.0;0.2;-78.2;6.3;0.0;760.2
+4.0;68.4;0.2;-77.8;6.3;0.0;760.2
+5.0;69.8;0.1;-76.1;6.3;0.0;760.2
+6.0;85.0;-1.4;-66.0;6.3;0.0;760.2
+7.0;52.5;-7.5;-122.3;6.3;0.0;760.2
+8.0;53.7;-7.6;-120.9;6.3;0.0;760.2
+9.0;54.1;-7.6;-120.4;6.3;0.0;760.2
+10.0;88.3;11.3;-24.7;6.3;0.0;760.2
+11.0;89.5;11.2;-23.3;6.3;0.0;760.2
+12.0;90.0;11.2;-22.8;6.3;0.0;760.2
+1.0;-5.1;-2.6;-100.2;7.7;13.2;763.3
+2.0;81.3;7.5;-89.2;7.7;13.2;763.3
+3.0;83.1;7.7;-88.5;7.7;13.2;763.3
+4.0;83.7;7.8;-88.3;7.7;13.2;763.3
+5.0;85.9;8.1;-87.6;7.7;13.2;763.3
+6.0;105.4;8.0;-82.7;7.7;13.2;763.3
+7.0;64.4;22.3;-107.6;7.7;13.2;763.3
+8.0;66.2;22.6;-106.9;7.7;13.2;763.3
+9.0;66.8;22.6;-106.7;7.7;13.2;763.3
+10.0;104.9;-16.1;-67.8;7.7;13.2;763.3
+11.0;106.8;-15.9;-67.2;7.7;13.2;763.3
+12.0;107.4;-15.8;-67.0;7.7;13.2;763.3
+1.0;-9.0;-4.1;-81.6;11.0;25.3;768.6
+2.0;79.8;13.3;-84.4;11.0;25.3;768.6
+3.0;82.2;13.9;-84.4;11.0;25.3;768.6
+4.0;83.0;14.1;-84.4;11.0;25.3;768.6
+5.0;85.8;14.9;-84.4;11.0;25.3;768.6
+6.0;106.1;18.5;-84.2;11.0;25.3;768.6
+7.0;63.3;32.3;-87.8;11.0;25.3;768.6
+8.0;65.7;33.0;-87.8;11.0;25.3;768.6
+9.0;66.5;33.2;-87.8;11.0;25.3;768.6
+10.0;100.2;-15.9;-83.8;11.0;25.3;768.6
+11.0;102.6;-15.3;-83.8;11.0;25.3;768.6
+12.0;103.4;-15.1;-83.8;11.0;25.3;768.6
+1.0;-9.4;0.9;-58.8;15.0;38.7;775.6
+2.0;71.3;29.7;-71.1;15.0;38.7;775.6
+3.0;74.1;30.9;-71.6;15.0;38.7;775.6
+4.0;75.0;31.2;-71.7;15.0;38.7;775.6
+5.0;78.3;32.6;-72.3;15.0;38.7;775.6
+6.0;96.9;40.8;-75.7;15.0;38.7;775.6
+7.0;63.5;75.7;-53.8;15.0;38.7;775.6
+8.0;66.3;76.9;-54.3;15.0;38.7;775.6
+9.0;67.2;77.3;-54.5;15.0;38.7;775.6
+10.0;77.2;-30.6;-93.7;15.0;38.7;775.6
+11.0;80.0;-29.4;-94.2;15.0;38.7;775.6
+12.0;80.9;-29.0;-94.4;15.0;38.7;775.6
+1.0;-3.0;10.4;-34.6;19.9;51.1;782.9
+2.0;46.1;30.2;-43.1;19.9;51.1;782.9
+3.0;48.5;31.1;-43.5;19.9;51.1;782.9
+4.0;49.2;31.4;-43.6;19.9;51.1;782.9
+5.0;52.0;32.3;-44.1;19.9;51.1;782.9
+6.0;63.3;39.6;-46.8;19.9;51.1;782.9
+7.0;40.9;61.2;-26.7;19.9;51.1;782.9
+8.0;43.2;62.1;-27.1;19.9;51.1;782.9
+9.0;44.0;62.3;-27.3;19.9;51.1;782.9
+10.0;48.6;-9.4;-62.5;19.9;51.1;782.9
+11.0;50.9;-8.6;-63.0;19.9;51.1;782.9
+12.0;51.7;-8.3;-63.1;19.9;51.1;782.9
+1.0;4.7;16.1;-15.5;26.3;62.2;788.8
+2.0;33.4;28.5;-21.6;26.3;62.2;788.8
+3.0;35.1;29.0;-21.9;26.3;62.2;788.8
+4.0;35.7;29.1;-22.0;26.3;62.2;788.8
+5.0;37.8;29.7;-22.4;26.3;62.2;788.8
+6.0;44.6;35.1;-24.4;26.3;62.2;788.8
+7.0;39.7;60.3;-9.5;26.3;62.2;788.8
+8.0;41.5;60.8;-9.8;26.3;62.2;788.8
+9.0;42.1;60.9;-9.9;26.3;62.2;788.8
+10.0;23.3;-9.9;-34.7;26.3;62.2;788.8
+11.0;25.1;-9.4;-35.1;26.3;62.2;788.8
+12.0;25.6;-9.3;-35.2;26.3;62.2;788.8
+1.0;5.0;10.2;-10.3;35.6;73.3;794.5
+2.0;19.6;15.1;-14.0;35.6;73.3;794.5
+3.0;20.9;15.2;-14.3;35.6;73.3;794.5
+4.0;21.3;15.2;-14.3;35.6;73.3;794.5
+5.0;22.7;15.3;-14.6;35.6;73.3;794.5
+6.0;26.2;18.2;-15.7;35.6;73.3;794.5
+7.0;28.3;35.5;-9.4;35.6;73.3;794.5
+8.0;29.5;35.6;-9.7;35.6;73.3;794.5
+9.0;29.9;35.6;-9.8;35.6;73.3;794.5
+10.0;8.5;-8.4;-18.4;35.6;73.3;794.5
+11.0;9.8;-8.3;-18.7;35.6;73.3;794.5
+12.0;10.2;-8.3;-18.8;35.6;73.3;794.5
+1.0;17.1;13.5;-15.7;51.8;85.5;799.0
+2.0;23.8;15.5;-16.7;51.8;85.5;799.0
+3.0;24.4;15.5;-16.8;51.8;85.5;799.0
+4.0;24.7;15.5;-16.8;51.8;85.5;799.0
+5.0;25.5;15.4;-16.9;51.8;85.5;799.0
+6.0;29.0;16.8;-17.4;51.8;85.5;799.0
+7.0;60.6;44.8;-11.4;51.8;85.5;799.0
+8.0;61.2;44.8;-11.5;51.8;85.5;799.0
+9.0;61.5;44.8;-11.5;51.8;85.5;799.0
+10.0;-15.3;-15.5;-21.9;51.8;85.5;799.0
+11.0;-14.6;-15.6;-22.0;51.8;85.5;799.0
+12.0;-14.4;-15.6;-22.0;51.8;85.5;799.0
diff --git a/src/DepthVsTime/CMakeLists.txt b/src/DepthVsTime/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d18fcb4
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(DepthVsTimePlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/DepthVsTime/TestCase.py b/src/DepthVsTime/TestCase.py
new file mode 100644 (file)
index 0000000..ef022a5
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDLoader import *
+
+fname="hydrau_test4.med"
+meshName="mesh"
+arr=DataArrayDouble([0,1,2,3,4,5])
+m=MEDCouplingCMesh()
+m.setCoords(arr,arr)
+m=m.buildUnstructured()
+m.setName(meshName)
+m.simplexize(0)
+WriteMesh(fname,m,True)
+#
+f=MEDCouplingFieldDouble(ON_NODES)
+f.setMesh(m)
+f.setName("Field")
+arr=m.getCoords().magnitude()
+f.setArray(arr)
+for i in range(10):
+    arr+=0.1
+    f.setTime(float(i)+0.2,i,0)
+    WriteFieldUsingAlreadyWrittenMesh(fname,f)
+    pass
+
diff --git a/src/DepthVsTime/plugin/CMakeLists.txt b/src/DepthVsTime/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f9ef0ae
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(DepthVsTimePlugin
+  VERSION "1.0"
+  MODULES DepthVsTimeModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/DepthVsTimeModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+  )
+
+install(TARGETS DepthVsTimePlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/DepthVsTime/plugin/DepthVsTimeModule/CMakeLists.txt b/src/DepthVsTime/plugin/DepthVsTimeModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..156a14a
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkDepthVsTime
+)
+
+vtk_module_add_module(DepthVsTimeModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/DepthVsTime/plugin/DepthVsTimeModule/vtk.module b/src/DepthVsTime/plugin/DepthVsTimeModule/vtk.module
new file mode 100644 (file)
index 0000000..d120ded
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  DepthVsTimeModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
diff --git a/src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.cxx b/src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.cxx
new file mode 100644 (file)
index 0000000..5afd50e
--- /dev/null
@@ -0,0 +1,681 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkDepthVsTime.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkCompositeDataProbeFilter.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkRectilinearGrid.h>
+#include <vtkResampleWithDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+
+#include <deque>
+#include <map>
+#include <set>
+#include <sstream>
+
+vtkStandardNewMacro(vtkDepthVsTime);
+
+constexpr int NB_OF_DISCR_TO_DEDUCE_START_STOP = 1001;
+
+///////////////////
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T *ptr = 0) : _ptr(ptr) {}
+  ~AutoPtr() { destroyPtr(); }
+  AutoPtr &operator=(T *ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T *operator->() { return _ptr; }
+  const T *operator->() const { return _ptr; }
+  T &operator*() { return *_ptr; }
+  const T &operator*() const { return *_ptr; }
+  operator T *() { return _ptr; }
+  operator const T *() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T *_ptr;
+};
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string &s) : _reason(s) {}
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+class vtkDepthVsTime::vtkInternal
+{
+public:
+  vtkInternal() : _isInit(true) { _nbItems = std::numeric_limits<std::size_t>::max(); }
+  void operate(double timeStep, vtkUnstructuredGrid *usgIn);
+  void pushData(double timeStep, vtkPolyData *data);
+  void fillGrid(vtkRectilinearGrid *grid) const;
+  void scanCoordsOfDS(vtkUnstructuredGrid *usg, vtkPolyData *zePoint, int nbOfExpectedDiscr);
+  static std::size_t CheckPts(vtkPointSet *usg, vtkDataArray *&arr);
+
+private:
+  void pushDataInit(double timeStep, vtkDataSetAttributes *dsa);
+  void pushDataStd(double timeStep, vtkDataSetAttributes *dsa);
+
+private:
+  bool _isInit;
+  std::size_t _nbItems;
+  std::vector<std::string> _columnNames;
+  std::vector<double> _time;
+  // sizeof(_data)==sizeof(_columnNames)
+  std::vector<std::vector<double>> _data;
+  vtkSmartPointer<vtkPolyData> _ladder;
+};
+
+void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *&usgIn)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw MZCException("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject *input2(input1->GetBlock(0));
+    if (!input2)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+    vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw MZCException("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+}
+
+////////////////////
+
+vtkDepthVsTime::vtkDepthVsTime() : NbDiscrPtsAlongZ(10), NumberOfTimeSteps(0), IsExecuting(false), CurrentTimeIndex(0), Internal(NULL)
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfOutputPorts(1);
+}
+
+vtkDepthVsTime::~vtkDepthVsTime()
+{
+  delete this->Internal;
+  this->Internal = NULL;
+}
+
+int vtkDepthVsTime::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkDepthVsTime::RequestInformation ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+    if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      this->NumberOfTimeSteps = inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    else
+    {
+      this->NumberOfTimeSteps = 0;
+    }
+    // The output of this filter does not contain a specific time, rather
+    // it contains a collection of time steps. Also, this filter does not
+    // respond to time requests. Therefore, we remove all time information
+    // from the output.
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
+    }
+    return 1;
+  }
+  catch (MZCException &e)
+  {
+    vtkErrorMacro(<< "Exception has been thrown in vtkDepthVsTime::RequestInformation : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+int vtkDepthVsTime::RequestUpdateExtent(vtkInformation *, vtkInformationVector **inputVector, vtkInformationVector *vtkNotUsed(outputVector))
+{
+  // vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  vtkInformation *inInfo1 = inputVector[0]->GetInformationObject(0);
+
+  // get the requested update extent
+  double *inTimes = inInfo1->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  if (inTimes)
+  {
+    double timeReq = inTimes[this->CurrentTimeIndex];
+    inInfo1->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), timeReq);
+  }
+
+  return 1;
+}
+
+std::string buildNameOfEntryFrom(const std::string &name, std::size_t id, std::size_t nbOfElt)
+{
+  if (nbOfElt == 0)
+    throw MZCException("buildNameOfEntryFrom : nbElt == 0 !");
+  if (nbOfElt == 1)
+    return name;
+  std::ostringstream oss;
+  oss << name << "_" << id;
+  return oss.str();
+}
+
+void fillFieldInGrid(vtkDataSet *ds, const std::vector<std::vector<double>> &valuesByColumn, std::size_t szX, std::size_t szY, const std::vector<std::string> &columnNames)
+{
+  vtkPointData *pd(ds->GetPointData());
+  if (!pd)
+    throw MZCException("fillFieldInGrid : internal error 1 !");
+  std::size_t nbFields(columnNames.size());
+  for (std::size_t i = 0; i < nbFields; i++)
+  {
+    vtkNew<vtkDoubleArray> arr;
+    arr->SetName(columnNames[i].c_str());
+    arr->SetNumberOfTuples(szX * szY);
+    const std::vector<double> &data(valuesByColumn[i]);
+    double *pt(arr->GetPointer(0));
+    if (data.size() != szX * szY)
+    {
+      std::ostringstream oss;
+      oss << "fillFieldInGrid : fatal internal error !"
+          << "Expect " << szX << "*" << szY << "=" << szX * szY << " But having " << data.size() << " ! mail to anthony.geay@edf.fr !";
+      throw MZCException(oss.str());
+    }
+    // transpose
+    for (std::size_t i = 0; i < szX; i++)
+      for (std::size_t j = 0; j < szY; j++)
+        pt[j * szX + i] = data[i * szY + j];
+    //
+    pd->AddArray(arr);
+  }
+}
+
+void vtkDepthVsTime::vtkInternal::operate(double timeStep, vtkUnstructuredGrid *usgIn)
+{
+  vtkNew<vtkPolyData> sourceCpy;
+  sourceCpy->DeepCopy(_ladder);
+  vtkNew<vtkCompositeDataProbeFilter> probeFilter;
+  probeFilter->SetInputData(sourceCpy);
+  probeFilter->SetSourceData(usgIn);
+  probeFilter->Update();
+  vtkDataObject *res(probeFilter->GetOutput());
+  vtkPolyData *res2(vtkPolyData::SafeDownCast(res));
+  if (!res2)
+  {
+    std::ostringstream oss;
+    oss << "Internal error ! unexpected returned of resample filter !";
+    throw MZCException(oss.str());
+  }
+  pushData(timeStep, res2);
+}
+
+void vtkDepthVsTime::vtkInternal::pushData(double timeStep, vtkPolyData *ds)
+{
+  if (!ds)
+    throw MZCException("pushData : no  data !");
+  vtkDataSetAttributes *dsa(ds->GetPointData());
+  if (!dsa)
+    throw MZCException("pushData : no point data !");
+  _time.push_back(timeStep);
+  if (_isInit)
+    pushDataInit(timeStep, dsa);
+  else
+    pushDataStd(timeStep, dsa);
+  _isInit = false;
+}
+
+void vtkDepthVsTime::vtkInternal::pushDataInit(double timeStep, vtkDataSetAttributes *dsa)
+{
+  int nba(dsa->GetNumberOfArrays());
+  for (int i = 0; i < nba; i++)
+  {
+    vtkDataArray *arr(dsa->GetArray(i));
+    if (!arr)
+      continue;
+    if (arr->GetNumberOfComponents() != 1)
+      continue;
+    std::size_t tmp(arr->GetNumberOfTuples());
+    if (tmp == 0)
+      continue;
+    if (_nbItems == std::numeric_limits<std::size_t>::max())
+      _nbItems = tmp;
+    if (tmp != _nbItems)
+      continue;
+    const char *name(arr->GetName());
+    if (!name)
+      continue;
+    vtkDoubleArray *arr1(vtkDoubleArray::SafeDownCast(arr));
+    vtkFloatArray *arr2(vtkFloatArray::SafeDownCast(arr));
+    if (!arr1 && !arr2)
+      continue;
+    _columnNames.push_back(name);
+    if (arr1)
+    {
+      const double *pt(arr1->GetPointer(0));
+      _data.resize(_columnNames.size());
+      std::vector<double> &data(_data[_columnNames.size() - 1]);
+      data.insert(data.end(), pt, pt + _nbItems);
+      continue;
+    }
+    if (arr2)
+    {
+      const float *pt(arr2->GetPointer(0));
+      _data.resize(_columnNames.size());
+      std::vector<double> &data(_data[_columnNames.size() - 1]);
+      data.insert(data.end(), pt, pt + _nbItems);
+      continue;
+    }
+  }
+}
+
+void vtkDepthVsTime::vtkInternal::pushDataStd(double timeStep, vtkDataSetAttributes *dsa)
+{
+  std::set<std::string> cnsRef(_columnNames.begin(), _columnNames.end()), cns;
+  int nba(dsa->GetNumberOfArrays());
+  for (int i = 0; i < nba; i++)
+  {
+    vtkDataArray *arr(dsa->GetArray(i));
+    if (!arr)
+      continue;
+    if (arr->GetNumberOfComponents() != 1)
+      continue;
+    if (arr->GetNumberOfTuples() != _nbItems)
+      continue;
+    const char *name(arr->GetName());
+    if (!name)
+      continue;
+    vtkDoubleArray *arr1(vtkDoubleArray::SafeDownCast(arr));
+    vtkFloatArray *arr2(vtkFloatArray::SafeDownCast(arr));
+    if (!arr1 && !arr2)
+      continue;
+    std::string nameCpp(name);
+    std::vector<std::string>::iterator it(std::find(_columnNames.begin(), _columnNames.end(), nameCpp));
+    if (it == _columnNames.end())
+      continue;
+    std::size_t columnId(std::distance(_columnNames.begin(), it));
+    if (cns.find(nameCpp) != cns.end())
+      throw MZCException("pushDataStd : internal error 1 !");
+    cns.insert(nameCpp);
+    std::vector<double> &data(_data[columnId]);
+    if (arr1)
+    {
+      const double *pt(arr1->GetPointer(0));
+      data.insert(data.end(), pt, pt + _nbItems);
+      continue;
+    }
+    if (arr2)
+    {
+      const float *pt(arr2->GetPointer(0));
+      data.insert(data.end(), pt, pt + _nbItems);
+      continue;
+    }
+  }
+  if (cnsRef != cns)
+    throw MZCException("Some float arrays are not present along time !");
+}
+
+void vtkDepthVsTime::vtkInternal::fillGrid(vtkRectilinearGrid *grid) const
+{
+  grid->SetDimensions(_time.size(), _nbItems, 1);
+  {
+    vtkNew<vtkDoubleArray> arrX;
+    arrX->SetNumberOfTuples(_time.size());
+    std::copy(_time.begin(), _time.end(), arrX->GetPointer(0));
+    grid->SetXCoordinates(arrX);
+  }
+  {
+    vtkNew<vtkDoubleArray> arrY;
+    arrY->SetNumberOfTuples(_nbItems);
+    double *arrYPt(arrY->GetPointer(0));
+    vtkDoubleArray *data(vtkDoubleArray::SafeDownCast(_ladder->GetPoints()->GetData()));
+    if (!data)
+      throw MZCException("fillGrid : internal error 1 !");
+    if (data->GetNumberOfTuples() != _nbItems)
+      throw MZCException("fillGrid : internal error 2 !");
+    const double *pt(data->GetPointer(0));
+    for (std::size_t i = 0; i < _nbItems; i++)
+      arrYPt[i] = pt[3 * i + 2];
+    grid->SetYCoordinates(arrY);
+  }
+  fillFieldInGrid(grid, _data, _time.size(), _nbItems, _columnNames);
+}
+
+std::size_t vtkDepthVsTime::vtkInternal::CheckPts(vtkPointSet *usg, vtkDataArray *&arr)
+{
+  if (!usg)
+    throw MZCException("CheckPts : expect an unstucturedgrid !");
+  vtkPoints *pts(usg->GetPoints());
+  if (!pts)
+    throw MZCException("CheckPts : no points in grid !");
+  arr = pts->GetData();
+  if (!arr)
+    throw MZCException("CheckPts : no data in points in grid !");
+  if (arr->GetNumberOfComponents() != 3)
+    throw MZCException("CheckPts : 3D expected !");
+  std::size_t nbPts(arr->GetNumberOfTuples());
+  if (nbPts < 1)
+    throw MZCException("CheckPts : no input point !");
+  vtkDoubleArray *arr1(vtkDoubleArray::SafeDownCast(arr));
+  vtkFloatArray *arr2(vtkFloatArray::SafeDownCast(arr));
+  if (!arr1 && !arr2)
+    throw MZCException("scanCoordsOfDS : for coords expected FLOAT32 or FLOAT64 !");
+  return nbPts;
+}
+
+void fillLader(vtkPolyData *source, double xpos, double ypos, double zmin, double zmax, int nbOfDiscr, const double *&ptOnInputDiscr)
+{
+  vtkNew<vtkDoubleArray> arr;
+  arr->SetNumberOfComponents(3);
+  arr->SetNumberOfTuples(nbOfDiscr);
+  double *pt(arr->GetPointer(0)), delta((zmax - zmin) / ((double)(nbOfDiscr - 1)));
+  for (int i = 0; i < nbOfDiscr; i++)
+  {
+    pt[3 * i] = xpos;
+    pt[3 * i + 1] = ypos;
+    pt[3 * i + 2] = ((double)i) * delta + zmin;
+  }
+  ptOnInputDiscr = pt;
+  vtkNew<vtkPoints> pts;
+  pts->SetData(arr);
+  source->SetPoints(pts);
+  vtkNew<vtkCellArray> verts;
+  {
+    vtkNew<vtkIdTypeArray> conn;
+    conn->SetNumberOfComponents(1);
+    conn->SetNumberOfTuples(2 * nbOfDiscr);
+    vtkIdType *pt(conn->GetPointer(0));
+    for (vtkIdType i = 0; i < nbOfDiscr; i++)
+    {
+      pt[2 * i] = 1;
+      pt[2 * i + 1] = i;
+    }
+    verts->SetCells(nbOfDiscr, conn);
+  }
+  source->SetVerts(verts);
+}
+
+void vtkDepthVsTime::vtkInternal::scanCoordsOfDS(vtkUnstructuredGrid *usg, vtkPolyData *zePoint, int nbOfExpectedDiscr)
+{
+  vtkDataArray *arr(0);
+  std::size_t nbPts(CheckPts(usg, arr));
+  double Zmin(std::numeric_limits<double>::max()), Zmax(std::numeric_limits<double>::max()), LocZmin(std::numeric_limits<double>::max()), LocZmax(std::numeric_limits<double>::max());
+  {
+    double tmp[6];
+    usg->GetBounds(tmp);
+    Zmin = tmp[4];
+    Zmax = tmp[5];
+  }
+  if (Zmin == Zmax)
+    throw MZCException("scanCoordsOfDS : Zmin == Zmax ! Looks bad !");
+  vtkNew<vtkUnstructuredGrid> usgCpy;
+  usgCpy->DeepCopy(usg);
+  vtkPointData *pd(usgCpy->GetPointData());
+  if (!pd)
+    throw MZCException("scanCoordsOfDS : unexpected case ! send mail to anthony.geay@edf.fr !");
+  int nbArr(pd->GetNumberOfArrays());
+  if (nbArr >= 1)
+  {
+    for (int i = nbArr - 1; i >= 0; i--)
+      pd->RemoveArray(i);
+  }
+  {
+    vtkNew<vtkDoubleArray> fakeArr;
+    fakeArr->SetName("a");
+    std::size_t nbPts(usgCpy->GetNumberOfPoints());
+    fakeArr->SetNumberOfTuples(nbPts);
+    double *pt(fakeArr->GetPointer(0));
+    std::fill(pt, pt + nbPts, 1.);
+    pd->AddArray(fakeArr);
+  }
+  //
+  if (zePoint->GetNumberOfPoints() != 1)
+    throw MZCException("scanCoordsOfDS : source has to have exactly one point !");
+  vtkDataArray *pts(zePoint->GetPoints()->GetData());
+  if (!pts)
+    throw MZCException("scanCoordsOfDS : internal error ! send mail to anthony.geay@edf.fr !");
+  vtkDoubleArray *pts1(vtkDoubleArray::SafeDownCast(pts));
+  vtkFloatArray *pts2(vtkFloatArray::SafeDownCast(pts));
+  if (!pts1 && !pts2)
+    throw MZCException("scanCoordsOfDS : internal error 2 ! send mail to anthony.geay@edf.fr !");
+  double Xpos(std::numeric_limits<double>::max()), Ypos(std::numeric_limits<double>::max());
+  if (pts1)
+  {
+    Xpos = pts1->GetTypedComponent(0, 0);
+    Ypos = pts1->GetTypedComponent(0, 1);
+  }
+  else
+  {
+    Xpos = (double)pts2->GetTypedComponent(0, 0);
+    Ypos = (double)pts2->GetTypedComponent(0, 1);
+  }
+  //
+  vtkNew<vtkPolyData> source;
+  const double *ptOnInputDiscr(NULL);
+  {
+    fillLader(source, Xpos, Ypos, Zmin, Zmax, NB_OF_DISCR_TO_DEDUCE_START_STOP, ptOnInputDiscr);
+  }
+  //
+  vtkNew<vtkCompositeDataProbeFilter> probeFilter;
+  probeFilter->SetInputData(source);
+  probeFilter->SetSourceData(usgCpy);
+  probeFilter->Update();
+  vtkDataObject *res(probeFilter->GetOutput());
+  vtkPolyData *res2(vtkPolyData::SafeDownCast(res));
+  if (!res2)
+    throw MZCException("scanCoordsOfDS : Internal error ! unexpected returned of resample filter !");
+  //
+  {
+    vtkPointData *pd(res2->GetPointData());
+    if (!pd)
+      throw MZCException("scanCoordsOfDS : internal error 3 ! send mail to anthony.geay@edf.fr !");
+    vtkDataArray *pts(pd->GetArray("a"));
+    if (!pts)
+      throw MZCException("scanCoordsOfDS : internal error 4 ! send mail to anthony.geay@edf.fr !");
+    vtkDoubleArray *pts1(vtkDoubleArray::SafeDownCast(pts));
+    if (!pts1)
+      throw MZCException("scanCoordsOfDS : internal error 5 ! send mail to anthony.geay@edf.fr !");
+    const double *vals(pts1->GetPointer(0));
+    int is(std::numeric_limits<int>::max()), ie(std::numeric_limits<int>::max());
+    for (int i = 0; i < NB_OF_DISCR_TO_DEDUCE_START_STOP; i++)
+    {
+      if (vals[i] == 1.)
+      {
+        is = i;
+        break;
+      }
+    }
+    if (is == std::numeric_limits<int>::max())
+      throw MZCException("scanCoordsOfDS : selected point seems to be outside of domain !");
+    for (int i = NB_OF_DISCR_TO_DEDUCE_START_STOP - 1; i >= 0; i--)
+    {
+      if (vals[i] == 1.)
+      {
+        ie = i;
+        break;
+      }
+    }
+    if (is == ie)
+      throw MZCException("scanCoordsOfDS : internal error 6 ! send mail to anthony.geay@edf.fr !");
+    LocZmin = ptOnInputDiscr[3 * is + 2];
+    LocZmax = ptOnInputDiscr[3 * ie + 2];
+  }
+  //
+  //std::cerr << "mmmmmmm " << Xpos << " " << Ypos << std::endl;
+  //std::cerr << "-> " << Zmin << " " << Zmax << std::endl;
+  //std::cerr << "-> " << LocZmin << " " << LocZmax << std::endl;
+  //
+  {
+    _ladder.TakeReference(vtkPolyData::New());
+    fillLader(_ladder, Xpos, Ypos, LocZmin, LocZmax, nbOfExpectedDiscr, ptOnInputDiscr);
+  }
+}
+
+int vtkDepthVsTime::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkDepthVsTime::RequestData        ##########################################" << std::endl;
+  try
+  {
+    //
+    if (this->NumberOfTimeSteps == 0)
+    {
+      vtkErrorMacro("No time steps in input data!");
+      return 0;
+    }
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation *sourceInfo(inputVector[1]->GetInformationObject(0));
+    vtkDataObject *source(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+    vtkPolyData *source2(vtkPolyData::SafeDownCast(source));
+    if (!source2)
+      throw MZCException("vtkPolyData expected as source !");
+    // is this the first request
+    if (!this->IsExecuting)
+    {
+      request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+      this->IsExecuting = true;
+      delete this->Internal;
+      this->Internal = new vtkInternal;
+      this->Internal->scanCoordsOfDS(usgIn, source2, this->NbDiscrPtsAlongZ);
+    }
+    //
+    // do something
+    {
+      double timeStep;
+      {
+        vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+        vtkDataObject *input(vtkDataObject::GetData(inInfo));
+        timeStep = input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP());
+      }
+      this->Internal->operate(timeStep, usgIn);
+    }
+    this->UpdateProgress(double(this->CurrentTimeIndex) / double(this->NumberOfTimeSteps));
+    //
+    this->CurrentTimeIndex++;
+    if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkRectilinearGrid *output(vtkRectilinearGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      vtkNew<vtkRectilinearGrid> grid;
+      this->Internal->fillGrid(grid);
+      output->ShallowCopy(grid);
+    }
+  }
+  catch (MZCException &e)
+  {
+    if (this->IsExecuting)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+    }
+    vtkErrorMacro(<< "Exception has been thrown in vtkDepthVsTime::RequestData : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkDepthVsTime::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkDepthVsTime::SetSourceData(vtkDataObject *input)
+{
+  this->SetInputData(1, input);
+}
+
+void vtkDepthVsTime::SetSourceConnection(vtkAlgorithmOutput *algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+int vtkDepthVsTime::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkRectilinearGrid");
+  return 1;
+}
diff --git a/src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.h b/src/DepthVsTime/plugin/DepthVsTimeModule/vtkDepthVsTime.h
new file mode 100644 (file)
index 0000000..863a4e7
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkDepthVsTime_h__
+#define vtkDepthVsTime_h__
+
+#include <vtkDataObjectAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkDepthVsTime : public vtkDataObjectAlgorithm
+{
+public:
+  static vtkDepthVsTime *New();
+  vtkTypeMacro(vtkDepthVsTime, vtkDataObjectAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  void SetSourceData(vtkDataObject *input);
+
+  void SetSourceConnection(vtkAlgorithmOutput *algOutput);
+
+  vtkSetMacro(NbDiscrPtsAlongZ, int);
+  vtkGetMacro(NbDiscrPtsAlongZ, int);
+
+  int FillOutputPortInformation(int vtkNotUsed(port), vtkInformation *info) override;
+
+protected:
+  vtkDepthVsTime();
+  ~vtkDepthVsTime();
+
+  int RequestInformation(vtkInformation *request,
+                         vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
+  int RequestUpdateExtent(vtkInformation *, vtkInformationVector **inputVector, vtkInformationVector *vtkNotUsed(outputVector)) override;
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector) override;
+
+  int NbDiscrPtsAlongZ;
+  int NumberOfTimeSteps;
+  bool IsExecuting;
+  int CurrentTimeIndex;
+  class vtkInternal;
+  vtkInternal *Internal;
+
+private:
+  vtkDepthVsTime(const vtkDepthVsTime &) = delete;
+  void operator=(const vtkDepthVsTime &) = delete;
+};
+
+#endif
diff --git a/src/DepthVsTime/plugin/filters.xml b/src/DepthVsTime/plugin/filters.xml
new file mode 100644 (file)
index 0000000..bd3cc0f
--- /dev/null
@@ -0,0 +1,52 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="DepthVsTime"
+                 class="vtkDepthVsTime"
+                 label="Depth Vs Time On Point">
+
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+
+      <InputProperty command="SetSourceConnection"
+                     label="Source"
+                     name="Source"
+                     panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="extended_sources"
+                 name="FixedRadiusPointSource" />
+        </ProxyListDomain>
+        <Documentation>This property specifies the dataset whose geometry will
+        be used in determining positions to probe.</Documentation>
+      </InputProperty>
+
+      <IntVectorProperty name="NbDiscrPtsAlongZ"
+                         command="SetNbDiscrPtsAlongZ"
+                         number_of_elements="1"
+                         default_values="10">
+        <IntRangeDomain name="range" min="5" max="1000"/>
+        <Documentation>
+          This property specifies nb of samples equaly spaced expected along Z in depth.
+          In other words, nb of points along Y-axis expected in output dataset.
+        </Documentation>
+      </IntVectorProperty>
+
+      <Hints>
+        <ShowInMenu category="Hydraulics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/DepthVsTime/plugin/paraview.plugin b/src/DepthVsTime/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..7fb7915
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  DepthVsTimePlugin
+DESCRIPTION
+  This plugin provides the DepthVsTime filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/ElectromagnetismFluxDisc/CMakeLists.txt b/src/ElectromagnetismFluxDisc/CMakeLists.txt
new file mode 100644 (file)
index 0000000..300abc5
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ElectromagnetismFluxDiscPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ElectromagnetismFluxDisc/plugin/CMakeLists.txt b/src/ElectromagnetismFluxDisc/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8fd5190
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(BUILD_SHARED_LIBS TRUE)
+
+paraview_add_plugin(ElectromagnetismFluxDiscPlugin
+  VERSION "1.0"
+  MODULES ElectromagnetismFluxDiscModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ElectromagnetismFluxDiscModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+  )
+
+install(TARGETS ElectromagnetismFluxDiscPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/CMakeLists.txt b/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..82eec71
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkElectromagnetismFluxDisc
+)
+
+vtk_module_add_module(ElectromagnetismFluxDiscModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtk.module b/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtk.module
new file mode 100644 (file)
index 0000000..2835d1b
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismFluxDiscModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::FiltersVerdict
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.cxx b/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.cxx
new file mode 100644 (file)
index 0000000..288e964
--- /dev/null
@@ -0,0 +1,413 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkElectromagnetismFluxDisc.h"
+
+#include "vtkAdjacentVertexIterator.h"
+#include "vtkIntArray.h"
+#include "vtkLongArray.h"
+#include "vtkCellData.h"
+#include "vtkPointData.h"
+#include "vtkCylinder.h"
+#include "vtkNew.h"
+#include "vtkCutter.h"
+#include "vtkTransform.h"
+
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkUnstructuredGrid.h"
+#include  "vtkMultiBlockDataSet.h"
+
+#include "vtkInformationStringKey.h"
+#include "vtkAlgorithmOutput.h"
+#include "vtkObjectFactory.h"
+#include "vtkMutableDirectedGraph.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkDataSet.h"
+#include "vtkInformationVector.h"
+#include "vtkInformation.h"
+#include "vtkDataArraySelection.h"
+#include "vtkTimeStamp.h"
+#include "vtkInEdgeIterator.h"
+#include "vtkInformationDataObjectKey.h"
+#include "vtkExecutive.h"
+#include "vtkVariantArray.h"
+#include "vtkStringArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkFloatArray.h"
+#include "vtkCharArray.h"
+#include "vtkUnsignedCharArray.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkDemandDrivenPipeline.h"
+#include "vtkDataObjectTreeIterator.h"
+#include "vtkWarpScalar.h"
+#include "vtkDiskSource.h"
+#include "vtkTransform.h"
+#include "vtkTransformPolyDataFilter.h"
+#include "vtkResampleWithDataSet.h"
+#include "vtkPointDataToCellData.h"
+#include "vtkMeshQuality.h"
+
+#include <cmath>
+
+
+#ifdef WIN32
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+
+#include <map>
+#include <deque>
+#include <sstream>
+#include <algorithm>
+
+vtkStandardNewMacro(vtkElectromagnetismFluxDisc);
+
+class VTK_EXPORT MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s):_reason(s) { }
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() { }
+private:
+  std::string _reason;
+};
+
+
+void ExtractInfo(vtkInformationVector *inputVector, vtkDataSet *& usgIn)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if(input0)
+    input=input0;
+  else
+    {
+      if(!input1)
+        throw MZCException("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+      if(input1->GetNumberOfBlocks()!=1)
+      {
+        std::cerr << "**** " << input1->GetNumberOfBlocks() << std::endl;
+        throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      }
+      vtkDataObject *input2(input1->GetBlock(0));
+      if(!input2)
+        throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+      vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+      if(!input2c)
+        throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      input=input2c;
+    }
+  if(!input)
+    throw MZCException("Input data set is NULL !");
+  vtkPointData *att(input->GetPointData());
+  if(!att)
+    throw MZCException("Input dataset has no point data attribute ! Impossible to deduce a developed surface on it !");
+  usgIn=input;
+}
+
+class vtkElectromagnetismFluxDisc::vtkInternals
+{
+public:
+  vtkNew<vtkCutter> Cutter;
+};
+
+////////////////////
+
+vtkElectromagnetismFluxDisc::vtkElectromagnetismFluxDisc():_cyl(nullptr),Internal(new vtkInternals),RadialResolution(80),CircumferentialResolution(80)
+{
+}
+
+vtkElectromagnetismFluxDisc::~vtkElectromagnetismFluxDisc()
+{
+  delete this->Internal;
+}
+
+int vtkElectromagnetismFluxDisc::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{ 
+  //std::cerr << "########################################## vtkElectromagnetismFluxDisc::RequestInformation ##########################################" << std::endl;
+  try
+    {
+      vtkDataSet *usgIn(0);
+      ExtractInfo(inputVector[0],usgIn);
+    }
+  catch(MZCException& e)
+    {
+      vtkErrorMacro("Exception has been thrown in vtkElectromagnetismFluxDisc::RequestInformation : " << e.what());
+      return 0;
+    }
+  return 1;
+}
+
+double ComputeFlux(vtkIdType nbOfTuples, const double *area, const double *vector3Field, const double axis[3])
+{
+  double ret(0.0);
+  for( vtkIdType i = 0 ; i < nbOfTuples ; ++i )
+    ret += area[i] * vtkMath::Dot(vector3Field+i*3,axis);
+  return ret;
+}
+
+template<class T>
+void Rotate3DAlg(const double *center, const double *vect, double angle, vtkIdType nbNodes, const T *coordsIn, T *coordsOut)
+{
+  double sina(sin(angle));
+  double cosa(cos(angle));
+  double vectorNorm[3];
+  T matrix[9];
+  T matrixTmp[9];
+  double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
+  if(norm<std::numeric_limits<double>::min())
+    throw MZCException("Rotate3DAlg : magnitude of input vector is too close of 0. !");
+  std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
+  //rotation matrix computation
+  matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
+  matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
+  matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
+  matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
+  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<T>(),1-cosa));
+  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<T>());
+  matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
+  matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
+  matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
+  std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<T>(),sina));
+  std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<T>());
+  //rotation matrix computed.
+  T tmp[3];
+  for(vtkIdType i=0; i<nbNodes; i++)
+    {
+      std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<T>());
+      coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+(T)center[0];
+      coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+(T)center[1];
+      coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+(T)center[2];
+    }
+}
+
+int vtkElectromagnetismFluxDisc::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkElectromagnetismFluxDisc::RequestData        ##########################################" << std::endl;
+  try
+    {
+      if(!_cyl)
+        throw MZCException("No cylinder object as cut function !");
+      double center[3],axis[3],radius,orthoAxis[3];
+      const double ZVec[3] = {0.,0.,1.};
+      vtkAbstractTransform* trf(_cyl->GetTransform());
+      {
+        _cyl->GetCenter(center);
+        _cyl->GetAxis(axis[0],axis[1],axis[2]);
+        radius=_cyl->GetRadius();
+      }
+      if(trf)
+        {
+          double axis3[3]={center[0]+0.,center[1]+1.,center[2]+0.},axis4[3];
+          trf->TransformPoint(axis3,axis4);
+          std::transform(axis4,axis4+3,center,axis,[](double a, double b) { return b-a; });
+          axis[1]=-axis[1];
+          if(std::isnan(axis[0]) && std::isnan(axis[1]) && std::isnan(axis[2]))
+            { axis[0]=0.; axis[1]=-1.; axis[2]=0.; }
+        }
+      
+      //std::cerr << trf << " jjj " << axis[0] << " " << axis[1] << " " << axis[2]  << " : " << center[0] <<  " " << center[1] << " " << center[2] <<  " " " " << " -> " << radius << std::endl;
+      vtkDataSet *usgIn(0);
+      ExtractInfo(inputVector[0],usgIn);
+      //
+      vtkNew<vtkUnstructuredGrid> outputMesh;
+      {
+        vtkIdType nbPoints(this->RadialResolution*this->CircumferentialResolution+1);
+        vtkNew<vtkDoubleArray> coords;
+        coords->SetNumberOfComponents(3); coords->SetNumberOfTuples(nbPoints);
+        double *coordsPtr(coords->GetPointer(0));
+        coordsPtr[0] = 0; coordsPtr[1] = 0; coordsPtr[2] = 0; coordsPtr+=3;
+        for(int circI = 0 ; circI < this->CircumferentialResolution ; ++circI)
+        {
+          double a(2*M_PI*(double(circI)/double(this->CircumferentialResolution)));
+          double c(cos(a)),s(sin(a));
+          for(int radI = 0 ; radI < this->RadialResolution ; ++radI)
+          {
+            coordsPtr[0] = c*(double(radI+1)/double(this->RadialResolution))*radius;
+            coordsPtr[1] = s*(double(radI+1)/double(this->RadialResolution))*radius;
+            coordsPtr[2] = 0;
+            coordsPtr+=3;
+          }
+        }
+        vtkNew<vtkPoints> pts;
+        pts->SetData(coords);
+        outputMesh->SetPoints(pts);
+        //
+        vtkIdType nbOfCells(this->CircumferentialResolution*this->RadialResolution);
+        vtkNew<vtkCellArray> cells;
+        vtkNew<vtkIdTypeArray> cellsData;
+        vtkNew<vtkIdTypeArray> cellLocations;
+        vtkNew<vtkUnsignedCharArray> cellTypes;
+        //
+        cellTypes->SetNumberOfComponents(1); cellTypes->SetNumberOfTuples(nbOfCells);
+        cellLocations->SetNumberOfComponents(1); cellLocations->SetNumberOfTuples(nbOfCells);
+        cellsData->SetNumberOfComponents(1); cellsData->SetNumberOfTuples( ( 5*(this->RadialResolution)-1 ) * this->CircumferentialResolution );
+        vtkIdType *clPtr(cellLocations->GetPointer(0)),*cdPtr(cellsData->GetPointer(0));
+        vtkIdType offset(0),deltaPt(this->RadialResolution);
+        unsigned char *ctPtr(cellTypes->GetPointer(0));
+        for( int iCirc = 0 ; iCirc < this->CircumferentialResolution - 1; ++iCirc )
+        {
+          vtkIdType zeDelta(iCirc*deltaPt);
+          for( int iRadial = 0 ; iRadial < this->RadialResolution ; ++iRadial )
+          {
+            *clPtr++ = offset;
+            if(iRadial!=0)
+            {
+              *ctPtr++ = VTK_QUAD;
+              cdPtr[0] = 4 ; cdPtr[1] = zeDelta + iRadial ; cdPtr[2] = zeDelta + iRadial+1;
+              cdPtr[3] = (zeDelta + deltaPt + iRadial+1); cdPtr[4] = ( zeDelta + deltaPt + iRadial);
+              cdPtr+=5;
+              offset += 4;
+            }
+            else
+            {
+              *ctPtr++ = VTK_TRIANGLE;
+              cdPtr[0] = 3 ; cdPtr[1] = 0 ; cdPtr[2] = zeDelta + 1; cdPtr[3] = (zeDelta + deltaPt +1);
+              cdPtr += 4;
+              offset += 3;
+            }
+          }
+        }
+        vtkIdType zeDelta((this->CircumferentialResolution - 1)*deltaPt);
+        for( int iRadial = 0 ; iRadial < this->RadialResolution ; ++iRadial )
+          {
+            *clPtr++ = offset;
+            if(iRadial!=0)
+            {
+              *ctPtr++ = VTK_QUAD;
+              cdPtr[0] = 4 ; cdPtr[1] = zeDelta + iRadial ; cdPtr[2] = zeDelta + iRadial+1;
+              cdPtr[3] = iRadial+1; cdPtr[4] = iRadial;
+              cdPtr+=5;
+              offset += 4;
+            }
+            else
+            {
+              *ctPtr++ = VTK_TRIANGLE;
+              cdPtr[0] = 3 ; cdPtr[1] = 0 ; cdPtr[2] = zeDelta + 1; cdPtr[3] = 1;
+              cdPtr += 4;
+              offset += 3;
+            }
+          }
+        //
+        cells->SetCells(nbOfCells,cellsData);
+        outputMesh->SetCells(cellTypes,cellLocations,cells);
+      }
+      // Rotation
+      {
+        vtkIdType nbPoints(outputMesh->GetNumberOfPoints());
+        vtkMath::Cross(ZVec,axis,orthoAxis);
+        double normOrthoAxis( vtkMath::Norm(orthoAxis) );
+        if(normOrthoAxis > 1e-5)
+        {
+          //std::cerr << "ortho : " << normOrthoAxis << " X = " << orthoAxis[0] << " Y = " << orthoAxis[1] << " Z = " << orthoAxis[2] << std::endl;
+          orthoAxis[0] *= normOrthoAxis; orthoAxis[1] *= normOrthoAxis; orthoAxis[2] *= normOrthoAxis;
+          const double Center[3] = {0.,0.,0.};
+          vtkNew<vtkDoubleArray> newArray;
+          newArray->SetNumberOfComponents(3); newArray->SetNumberOfTuples(nbPoints);
+          vtkDoubleArray *oldPts( vtkDoubleArray::SafeDownCast( outputMesh->GetPoints()->GetData() ) );
+          double angle(asin(normOrthoAxis));
+          if( vtkMath::Dot(ZVec,axis) < 0. )
+            angle = M_PI - angle;
+          Rotate3DAlg<double>(Center,orthoAxis,angle,nbPoints,oldPts->GetPointer(0),newArray->GetPointer(0));
+          outputMesh->GetPoints()->SetData(newArray);
+        }
+      }
+      // Translation
+      {
+        vtkDoubleArray *coords(vtkDoubleArray::SafeDownCast( outputMesh->GetPoints()->GetData()));
+        vtkIdType nbPts(coords->GetNumberOfTuples());
+        double *coordsPtr(coords->GetPointer(0));
+        for(vtkIdType i = 0 ; i < nbPts ; ++i)
+        { coordsPtr[3*i] += center[0]; coordsPtr[3*i+1] += center[1]; coordsPtr[3*i+2] += center[2]; }
+      }
+      //
+      vtkNew<vtkResampleWithDataSet> probeFilter;
+      probeFilter->SetInputData(outputMesh);
+      probeFilter->SetSourceData(usgIn);
+      //
+      vtkNew<vtkPointDataToCellData> pd2cd;
+      pd2cd->SetInputConnection(probeFilter->GetOutputPort());
+      pd2cd->Update();
+      //
+      vtkNew<vtkMeshQuality> mq;
+      mq->SetInputData(outputMesh);
+      mq->SetTriangleQualityMeasureToArea();
+      mq->SetQuadQualityMeasureToArea();
+      mq->Update();
+      double *area( ( vtkDoubleArray::SafeDownCast(mq->GetOutput()->GetCellData()->GetArray("Quality")) )->GetPointer(0) );
+      //
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      output->ShallowCopy(outputMesh);
+      //
+      vtkIdType nbOfCells(output->GetNumberOfCells());
+      vtkFieldData* dsa(pd2cd->GetOutput()->GetCellData());
+      int nbOfArrays(dsa->GetNumberOfArrays());
+      for(int i = 0 ; i < nbOfArrays ; ++i )
+      {
+        vtkDoubleArray *arr( vtkDoubleArray::SafeDownCast(dsa->GetArray(i)) );
+        if( arr && arr->GetNumberOfComponents() == 3 )
+        {
+          vtkNew<vtkDoubleArray> arr2;
+          arr2->ShallowCopy(arr);
+          output->GetCellData()->AddArray(arr2);
+          double flux(ComputeFlux(nbOfCells,area,arr->GetPointer(0),axis));
+          std::ostringstream oss; oss << dsa->GetArrayName(i) << "_flux";
+          vtkNew<vtkDoubleArray> arrFlux;
+          arrFlux->SetName(oss.str().c_str());
+          arrFlux->SetNumberOfComponents(1); arrFlux->SetNumberOfTuples(nbOfCells);
+          std::for_each(arrFlux->GetPointer(0),arrFlux->GetPointer(nbOfCells),[flux](double& elt) { elt = flux; });
+          output->GetCellData()->AddArray(arrFlux);
+        }
+      }
+    }
+  catch(MZCException& e)
+    {
+      vtkErrorMacro("Exception has been thrown in vtkElectromagnetismFluxDisc::RequestInformation : " << e.what());
+      return 0;
+    }
+  return 1;
+}
+
+void vtkElectromagnetismFluxDisc::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkElectromagnetismFluxDisc::SetCutFunction(vtkImplicitFunction* func)
+{
+  vtkCylinder *cyl(vtkCylinder::SafeDownCast(func));
+  if(cyl)
+    {
+      _cyl=cyl;
+      this->Modified();
+    }
+}
+
+vtkMTimeType vtkElectromagnetismFluxDisc::GetMTime()
+{
+  vtkMTimeType maxMTime = this->Superclass::GetMTime(); // My MTime
+  if(_cyl)
+    {
+      maxMTime=std::max(maxMTime,_cyl->GetMTime());
+    }
+  return maxMTime;
+}
diff --git a/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.h b/src/ElectromagnetismFluxDisc/plugin/ElectromagnetismFluxDiscModule/vtkElectromagnetismFluxDisc.h
new file mode 100644 (file)
index 0000000..ffad69c
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#pragma once
+
+#include <vtkUnstructuredGridAlgorithm.h>
+//#include <vtkPolyDataAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+class vtkImplicitFunction;
+class vtkCylinder;
+
+class VTK_EXPORT vtkElectromagnetismFluxDisc : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkElectromagnetismFluxDisc* New();
+  vtkTypeMacro(vtkElectromagnetismFluxDisc, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  void SetCutFunction(vtkImplicitFunction* func);
+
+  vtkMTimeType GetMTime();
+
+  vtkSetClampMacro(RadialResolution, int, 1, VTK_INT_MAX);
+  vtkGetMacro(RadialResolution, int);
+  
+  vtkSetClampMacro(CircumferentialResolution, int, 3, VTK_INT_MAX);
+  vtkGetMacro(CircumferentialResolution, int);
+
+protected:
+  vtkElectromagnetismFluxDisc();
+  ~vtkElectromagnetismFluxDisc();
+  
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  vtkCylinder* _cyl;
+  class vtkInternals;
+  vtkInternals* Internal;
+
+private:
+  vtkElectromagnetismFluxDisc(const vtkElectromagnetismFluxDisc&) = delete;
+  void operator=(const vtkElectromagnetismFluxDisc&) = delete;
+  
+  int RadialResolution;
+  int CircumferentialResolution;
+};
diff --git a/src/ElectromagnetismFluxDisc/plugin/Test/CMakeLists.txt b/src/ElectromagnetismFluxDisc/plugin/Test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd37495
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+SET(TEMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary")
+
+IF(NOT EXISTS ${TEMP_DIR})
+  FILE(MAKE_DIRECTORY ${TEMP_DIR})
+ENDIF(NOT EXISTS ${TEMP_DIR})
+
+#SET(DEV_SURFACE_TESTS test_dev_surface2 test_dev_surface3)
+
+#IF(NOT SALOME_PARAVIS_NO_VISU_TESTS)
+#  FOREACH(tfile ${DEV_SURFACE_TESTS})
+#    ADD_TEST(${tfile} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${tfile}.py )
+#    SET_TESTS_PROPERTIES(${tfile} PROPERTIES LABELS "PVS_ADD_ONS")
+#  ENDFOREACH(tfile ${DEV_SURFACE_TESTS})
+#ENDIF()
diff --git a/src/ElectromagnetismFluxDisc/plugin/Test/test_flux_disc0.py b/src/ElectromagnetismFluxDisc/plugin/Test/test_flux_disc0.py
new file mode 100644 (file)
index 0000000..da991ae
--- /dev/null
@@ -0,0 +1,164 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#  -*- coding: utf-8 -*-
+
+from paraview.simple import *
+from vtk.util import numpy_support
+import numpy as np
+import vtk
+
+from medcoupling import *
+
+def MyAssert(clue):
+    if not clue:
+        raise RuntimeError("Assertion failed !")
+
+def Write(ds,fn):
+    writer = vtk.vtkUnstructuredGridWriter()
+    writer.SetInputData(ds)
+    writer.SetFileName(fn)
+    writer.Update()
+
+def MCField(fn,fieldName):
+    mm = MEDFileMesh.New(fn)
+    fs = MEDFileFields.New(fn)
+    return fs[fieldName][0].field(mm)
+
+def ComputeFlux(mc_f):
+    area = mc_f.getMesh().getMeasureField(True).getArray()
+    mc_vector = DataArrayDouble(vector,1,3)
+    mc_vector /= mc_vector.magnitude()[0]
+    mc_vector = DataArrayDouble.Aggregate(mc_f.getNumberOfTuples()*[mc_vector])
+    flux_per_cell = DataArrayDouble.Dot(mc_f.getArray(),mc_vector)*area
+    return flux_per_cell.accumulate()[0]
+
+ref_flux_b_a = -60.47
+ref_flux_h_a = -127446
+ref_flux_hsomega = 1896.991081794051
+vector = [0.13,-0.47,0.87]
+center = [0.0, 0.0, 3900.0]
+
+mr = MEDReader(FileName='/home/H87074/TMP81/paravistests_new/FilesForTests/Electromagnetism/mesh_benjamin_8_sept_2020.med')
+mr.AllArrays = ['TS0/Mesh_1/ComSup0/B_A@@][@@P0', 'TS0/Mesh_1/ComSup0/B_HsOmega@@][@@P0', 'TS0/Mesh_1/ComSup0/H_A@@][@@P0', 'TS0/Mesh_1/ComSup0/H_HsOmega@@][@@P0']
+mr.AllTimeSteps = ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009']
+mr.UpdatePipeline()
+
+resRadial = 200
+resCircum = 200
+fluxDisc1 = FluxDisc(Input=mr)
+fluxDisc1.SliceType = 'Cylinder'
+fluxDisc1.SliceType.Center = center
+fluxDisc1.SliceType.Axis = vector
+fluxDisc1.SliceType.Radius = 293
+fluxDisc1.RadialResolution = resRadial
+fluxDisc1.CircumferentialResolution = resCircum
+
+mw = MEDWriter(FileName="Base.med",Input=fluxDisc1)
+mw.UpdatePipeline()
+
+ds0 = servermanager.Fetch(fluxDisc1)
+MyAssert(ds0.GetNumberOfCells()==resRadial*resCircum)
+MyAssert(ds0.GetNumberOfPoints()==resRadial*resCircum+1)
+
+flux_b_a = ds0.GetBlock(0).GetCellData().GetArray("B_A_flux").GetValue(0)
+MyAssert(np.isclose(ref_flux_b_a,flux_b_a,0.1,0))
+
+flux_h_a = ds0.GetBlock(0).GetCellData().GetArray("H_A_flux").GetValue(0)
+#MyAssert(np.isclose(ref_flux_h_a,flux_h_a,0.01,0))
+
+flux_hsomega = ds0.GetBlock(0).GetCellData().GetArray("H_HsOmega_flux").GetValue(0)
+#MyAssert(np.isclose(ref_flux_hsomega,flux_hsomega,0.01,0))
+
+Write(ds0.GetBlock(0),"Base.vtu")
+mc_f_base = MCField("Base.med","H_HsOmega")
+
+# On inverse l'axe et on verifie que le flux est inversé
+
+fluxDisc1.SliceType.Axis = [-elt for elt in vector]
+mw = MEDWriter(FileName="Invert.med",Input=fluxDisc1)
+mw.UpdatePipeline()
+
+ds1 = servermanager.Fetch(fluxDisc1)
+
+MyAssert(ds1.GetNumberOfCells()==resRadial*resCircum)
+MyAssert(ds1.GetNumberOfPoints()==resRadial*resCircum+1)
+
+flux_b_a = ds1.GetBlock(0).GetCellData().GetArray("B_A_flux").GetValue(0)
+#MyAssert(np.isclose(-ref_flux_b_a,flux_b_a,0.1,0))
+
+flux_h_a = ds1.GetBlock(0).GetCellData().GetArray("H_A_flux").GetValue(0)
+#MyAssert(np.isclose(-ref_flux_h_a,flux_h_a,0.1,0))
+
+flux_hsomega = ds1.GetBlock(0).GetCellData().GetArray("H_HsOmega_flux").GetValue(0)
+#MyAssert(np.isclose(-ref_flux_hsomega,flux_hsomega,0.1,0))
+
+
+Write(ds0.GetBlock(0),"Invert.vtu")
+mc_f_invert = MCField("Invert.med","H_HsOmega")
+
+###
+
+ComputeFlux(mc_f_base)
+ComputeFlux(mc_f_invert)
+
+# debug : pourquoi une telle difference de flux sur H_HsOmega ?
+
+a  = mc_f_base.getMesh().getMeasureField(True).getArray()
+b  = mc_f_invert.getMesh().getMeasureField(True).getArray()
+assert(a.isEqual(b,1e-10))
+
+# OK pour l'area
+
+m_base = mc_f_base.getMesh()
+m_invert = mc_f_invert.getMesh()
+base_base = DataArrayDouble.GiveBaseForPlane(vector)
+
+newX = DataArrayDouble(resRadial*resCircum+1,3) ; newX[:] = base_base[0]
+newY = DataArrayDouble(resRadial*resCircum+1,3) ; newY[:] = base_base[1]
+newZ = DataArrayDouble(resRadial*resCircum+1,3) ; newZ[:] = 0
+
+base_new_coords=DataArrayDouble.Meld([DataArrayDouble.Dot(m_base.getCoords(),newX),DataArrayDouble.Dot(m_base.getCoords(),newY),newZ])
+invert_new_coords=DataArrayDouble.Meld([DataArrayDouble.Dot(m_invert.getCoords(),newX),DataArrayDouble.Dot(m_invert.getCoords(),newY),newZ])
+
+m_base.setCoords(base_new_coords)
+m_invert.setCoords(invert_new_coords)
+
+mc_f_base.write("base_dbg.vtu")
+mc_f_invert.write("invert_dbg.vtu")
+
+m_base.changeSpaceDimension(2,0.)
+m_invert.changeSpaceDimension(2,0.)
+a,b= m_base.getCellsContainingPoints(m_invert.computeCellCenterOfMass(),1e-12)
+assert(b.isIota(len(b)))
+
+a2 = a[:] ; a2.sort() ; assert( a2.isIota(len(a2) ) )
+
+array_base_in_invert_ref = mc_f_base.getArray()[a]
+
+not_of_ids = (array_base_in_invert_ref-mc_f_invert.getArray()).magnitude().findIdsGreaterThan(1.)
+ok_ids = (array_base_in_invert_ref-mc_f_invert.getArray()).magnitude().findIdsLowerThan(1.)
+
+ze_ids = ok_ids
+ze_ids = not_of_ids
+print(ComputeFlux(mc_f_invert[ze_ids]))
+ze_ids_base_ref = a.findIdForEach(ze_ids)
+print(ComputeFlux(mc_f_base[ze_ids_base_ref]))
+
+mc_f_invert[ze_ids].write("invert_dbg_pb.vtu")
diff --git a/src/ElectromagnetismFluxDisc/plugin/filters.xml b/src/ElectromagnetismFluxDisc/plugin/filters.xml
new file mode 100644 (file)
index 0000000..f9dffe5
--- /dev/null
@@ -0,0 +1,58 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="Flux Disc"
+                 class="vtkElectromagnetismFluxDisc">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+      <ProxyProperty command="SetCutFunction"
+                     label="Slice Type"
+                     name="CutFunction">
+        <ProxyGroupDomain name="groups">
+          <Group name="implicit_functions" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="implicit_functions" name="Cylinder" />
+        </ProxyListDomain>
+        <Documentation>
+          This property sets the parameters of cylinder used for slice.
+        </Documentation>
+      </ProxyProperty>
+
+      <IntVectorProperty command="SetRadialResolution"
+                         default_values="8"
+                         name="RadialResolution"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <IntRangeDomain max="1024"
+                        min="3"
+                        name="range" />
+        <Documentation>Set the number of points in radial direction.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetCircumferentialResolution"
+                         default_values="8"
+                         name="CircumferentialResolution"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <IntRangeDomain max="1024"
+                        min="3"
+                        name="range" />
+        <Documentation>Set the number of points in circumferential direction.</Documentation>
+      </IntVectorProperty>
+
+      <Hints>
+        <ShowInMenu category="Electromagnetism" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ElectromagnetismFluxDisc/plugin/paraview.plugin b/src/ElectromagnetismFluxDisc/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..eb9343d
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismFluxDiscPlugin
+DESCRIPTION
+  This plugin provides the ElectromagnetismFluxDisc filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/ElectromagnetismRotation/CMakeLists.txt b/src/ElectromagnetismRotation/CMakeLists.txt
new file mode 100644 (file)
index 0000000..195e2ad
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ElectromagnetismRotation)
+
+find_package(ParaView REQUIRED)
+
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+enable_testing()
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach (module IN LISTS required_modules)
+  if (NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return ()
+  endif ()
+endforeach ()
+
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins})
diff --git a/src/ElectromagnetismRotation/plugin/CMakeLists.txt b/src/ElectromagnetismRotation/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..442308a
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Common CMake macros
+# ===================
+set(TMP_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+set(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+if(EXISTS ${CONFIGURATION_ROOT_DIR})
+  list(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  include(SalomeMacros)
+else()
+  message(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+endif()
+
+set(MEDCOUPLING_ROOT_DIR $ENV{MEDCOUPLING_ROOT_DIR} CACHE PATH "Path to the MEDCoupling tool")
+if(EXISTS ${MEDCOUPLING_ROOT_DIR})
+  list(APPEND CMAKE_MODULE_PATH "${MEDCOUPLING_ROOT_DIR}/cmake_files")
+endif()
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
+list(APPEND CMAKE_MODULE_PATH ${TMP_CMAKE_MODULE_PATH})
+
+include(SalomeSetupPlatform)
+set(BUILD_SHARED_LIBS TRUE)
+
+find_package(SalomePythonInterp REQUIRED)
+find_package(SalomePythonLibs REQUIRED)
+find_package(SalomeHDF5 REQUIRED)
+find_package(SalomeMEDCoupling REQUIRED)
+find_package(SalomeMEDFile REQUIRED)
+
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}
+                                                 ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON})
+SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS})
+SALOME_ACCUMULATE_ENVIRONMENT(PV_PLUGIN_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/lib/paraview)
+
+add_subdirectory(ElectromagnetismRotationHelper)
+add_subdirectory(ParaViewPlugin)
+
+
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/CMakeLists.txt b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f7aed0a
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+add_library(ElectromagnetismRotationHelper SHARED ElectromagnetismRotationHelper.cxx)
+target_include_directories(ElectromagnetismRotationHelper PRIVATE . ${MEDCOUPLING_INCLUDE_DIRS})
+
+target_link_libraries(ElectromagnetismRotationHelper VTK::CommonCore VTK::CommonDataModel VTK::IOXML ${MEDFILE_C_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(ElectromagnetismRotationHelper ${MEDCoupling_medloader})
+
+install(TARGETS ElectromagnetismRotationHelper DESTINATION lib/paraview)
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.cxx b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.cxx
new file mode 100644 (file)
index 0000000..b7c3032
--- /dev/null
@@ -0,0 +1,375 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "ElectromagnetismRotationHelper.h"
+
+#include "InterpKernelException.hxx"
+
+#include "vtkInformation.h"
+#include "vtkInformationDataObjectMetaDataKey.h"
+#include "vtkAdjacentVertexIterator.h"
+#include "vtkMutableDirectedGraph.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkStringArray.h"
+
+#include <cstring>
+#include <limits>
+#include <algorithm>
+
+const char ZE_SEPP[]="@@][@@";
+
+const char ElectromagnetismRotationGrp::START[]="GRP_";
+
+const char ElectromagnetismRotationFam::START[]="FAM_";
+
+ElectromagnetismRotationStatus::ElectromagnetismRotationStatus(const char *name):_status(false),_name(name)
+{
+}
+
+void ElectromagnetismRotationStatus::printMySelf(std::ostream& os) const
+{
+  os << "      -" << _ze_key_name << "(";
+  if(_status)
+    os << "X";
+  else
+    os << " ";
+  os << ")" << std::endl;
+}
+
+bool ElectromagnetismRotationStatus::isSameAs(const ElectromagnetismRotationStatus& other) const
+{
+  return _name==other._name && _ze_key_name==other._ze_key_name;
+}
+
+bool ElectromagnetismRotationGrp::isSameAs(const ElectromagnetismRotationGrp& other) const
+{
+  bool ret(ElectromagnetismRotationStatus::isSameAs(other));
+  if(ret)
+    return _fams==other._fams;
+  else
+    return false;
+}
+
+ElectromagnetismRotationFam::ElectromagnetismRotationFam(const char *name):ElectromagnetismRotationStatus(name),_id(0)
+{
+  std::size_t pos(_name.find(ZE_SEPP));
+  std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(ZE_SEPP)));
+  std::istringstream iss(name1);
+  iss >> _id;
+  std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
+}
+
+bool ElectromagnetismRotationFam::isSameAs(const ElectromagnetismRotationFam& other) const
+{
+  bool ret(ElectromagnetismRotationStatus::isSameAs(other));
+  if(ret)
+    return _id==other._id;
+  else
+    return false;
+}
+
+void ElectromagnetismRotationFam::printMySelf(std::ostream& os) const
+{
+  os << "      -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
+  if(_status)
+    os << "X";
+  else
+    os << " ";
+  os << ")" << std::endl;
+}
+
+void ElectromagnetismRotationFam::fillIdsToKeep(std::set<int>& s) const
+{
+  s.insert(_id);
+}
+///////////////////
+
+bool ElectromagnetismRotationInternal::IndependantIsInformationOK(vtkInformationDataObjectMetaDataKey *medReaderMetaData, vtkInformation *info)
+{
+  // Check the information contain meta data key
+  if(!info->Has(medReaderMetaData))
+    return false;
+
+  // Recover Meta Data
+  vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(medReaderMetaData)));
+  if(!sil)
+    return false;
+  int idNames(0);
+  vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
+  vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
+  if(!verticesNames2)
+    return false;
+  for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
+    {
+      vtkStdString &st(verticesNames2->GetValue(i));
+      if(st=="MeshesFamsGrps")
+        return true;
+    }
+  return false;
+}
+
+const char *ElectromagnetismRotationInternal::getMeshName() const
+{
+  return this->_mesh_name.c_str();
+}
+
+void ElectromagnetismRotationInternal::loadFrom(vtkMutableDirectedGraph *sil)
+{
+  std::vector<ElectromagnetismRotationGrp> oldGrps(_groups); _groups.clear();
+  std::vector<ElectromagnetismRotationFam> oldFams(_fams); _fams.clear();
+  int idNames(0);
+  vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
+  vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
+  vtkIdType id0;
+  bool found(false);
+  for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
+    {
+      vtkStdString &st(verticesNames2->GetValue(i));
+      if(st=="MeshesFamsGrps")
+        {
+          id0=i;
+          found=true;
+        }
+    }
+  if(!found)
+    throw INTERP_KERNEL::Exception("There is an internal error ! The tree on server side has not the expected look !");
+  vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
+  sil->GetAdjacentVertices(id0,it0);
+  int kk(0),ll(0);
+  while(it0->HasNext())
+    {
+      vtkIdType id1(it0->Next());
+      std::string meshName((const char *)verticesNames2->GetValue(id1));
+      this->_mesh_name=meshName;
+      vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());
+      sil->GetAdjacentVertices(id1,it1);
+      vtkIdType idZeGrps(it1->Next());//zeGroups
+      vtkAdjacentVertexIterator *itGrps(vtkAdjacentVertexIterator::New());
+      sil->GetAdjacentVertices(idZeGrps,itGrps);
+      while(itGrps->HasNext())
+        {
+          vtkIdType idg(itGrps->Next());
+          ElectromagnetismRotationGrp grp((const char *)verticesNames2->GetValue(idg));
+          vtkAdjacentVertexIterator *itGrps2(vtkAdjacentVertexIterator::New());
+          sil->GetAdjacentVertices(idg,itGrps2);
+          std::vector<std::string> famsOnGroup;
+          while(itGrps2->HasNext())
+            {
+              vtkIdType idgf(itGrps2->Next());
+              famsOnGroup.push_back(std::string((const char *)verticesNames2->GetValue(idgf)));
+            }
+          grp.setFamilies(famsOnGroup);
+          itGrps2->Delete();
+          _groups.push_back(grp);
+        }
+      itGrps->Delete();
+      vtkIdType idZeFams(it1->Next());//zeFams
+      it1->Delete();
+      vtkAdjacentVertexIterator *itFams(vtkAdjacentVertexIterator::New());
+      sil->GetAdjacentVertices(idZeFams,itFams);
+      while(itFams->HasNext())
+        {
+          vtkIdType idf(itFams->Next());
+          ElectromagnetismRotationFam fam((const char *)verticesNames2->GetValue(idf));
+          _fams.push_back(fam);
+        }
+      itFams->Delete();
+    }
+  it0->Delete();
+  // filter groups on cells
+  std::vector<ElectromagnetismRotationGrp> groupsToKeep;
+  std::size_t ii(0);
+  for(auto grp : _groups)
+  {
+    std::vector<int> famIds(this->getFamiliesIdsOnGroup(grp.getName()));
+    if ( std::all_of(famIds.begin(), famIds.end(), [](int i){ return i<0; }) )
+      groupsToKeep.emplace_back(std::move(grp));
+  }
+  _groups = std::move(groupsToKeep);
+  //
+  std::size_t szg(_groups.size()),szf(_fams.size());
+  if(szg==oldGrps.size() && szf==oldFams.size())
+    {
+      bool isSame(true);
+      for(std::size_t i=0;i<szg && isSame;i++)
+        isSame=_groups[i].isSameAs(oldGrps[i]);
+      for(std::size_t i=0;i<szf && isSame;i++)
+        isSame=_fams[i].isSameAs(oldFams[i]);
+      if(isSame)
+        {
+          for(std::size_t i=0;i<szg;i++)
+            _groups[i].cpyStatusFrom(oldGrps[i]);
+          for(std::size_t i=0;i<szf;i++)
+            _fams[i].cpyStatusFrom(oldFams[i]);
+        }
+    }
+}
+
+int ElectromagnetismRotationInternal::getNumberOfEntries() const
+{
+  std::size_t sz0(_groups.size());
+  return (int)(sz0);
+}
+
+const char *ElectromagnetismRotationInternal::getKeyOfEntry(int i) const
+{
+  return _groups[i].getKeyOfEntry();
+}
+
+bool ElectromagnetismRotationInternal::getStatusOfEntryStr(const char *entry) const
+{
+  const ElectromagnetismRotationStatus& elt(getEntry(entry));
+  return elt.getStatus();
+}
+
+void ElectromagnetismRotationInternal::setStatusOfEntryStr(const char *entry, bool status)
+{
+  _selection.emplace_back(entry,status);
+}
+
+const ElectromagnetismRotationStatus& ElectromagnetismRotationInternal::getEntry(const char *entry) const
+{
+  std::string entryCpp(entry);
+  for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getEntry : no such entry \"" << entry << "\"!";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+ElectromagnetismRotationStatus& ElectromagnetismRotationInternal::getEntry(const char *entry)
+{
+  std::string entryCpp(entry);
+  for(std::vector<ElectromagnetismRotationGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getEntry : no such entry \"" << entry << "\"!";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+void ElectromagnetismRotationInternal::printMySelf(std::ostream& os) const
+{
+  os << "Groups :" << std::endl;
+  for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    (*it0).printMySelf(os);
+}
+
+std::vector<int> ElectromagnetismRotationInternal::getFamiliesIdsOnGroup(const std::string& groupName) const
+{
+  for(auto grp : _groups)
+  {
+    if(grp.getName() == groupName)
+    {
+      std::vector<std::string> fams(grp.getFamiliesLyingOn());
+      auto sz(fams.size());
+      std::vector<int> famIds(sz);
+      for(auto i = 0 ; i < sz ; ++i)
+        famIds[i] = this->getIdOfFamily(fams[i]);
+      return famIds;
+    }
+  }
+  std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getFamiliesIdsOnGroup : no such group \"" << groupName << "\"!";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+int ElectromagnetismRotationInternal::getIdOfFamily(const std::string& famName) const
+{
+  for(std::vector<ElectromagnetismRotationFam>::const_iterator it=_fams.begin();it!=_fams.end();it++)
+    {
+      if((*it).getName()==famName)
+        return (*it).getId();
+    }
+  return std::numeric_limits<int>::max();
+}
+
+std::set<int> ElectromagnetismRotationInternal::getIdsToKeep() const
+{
+  for(auto it: _selection)
+    {
+      const ElectromagnetismRotationStatus& elt(getEntry(it.first.c_str()));
+      elt.setStatus(it.second);
+    }
+  std::map<std::string,int> m(this->computeFamStrIdMap());
+  std::set<int> s;
+  for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    {
+      if((*it0).getStatus())
+        {
+          const std::vector<std::string>& fams((*it0).getFamiliesLyingOn());
+          for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
+            {
+              std::map<std::string,int>::iterator it2(m.find((*it1)));
+              if(it2!=m.end())
+                s.insert((*it2).second);
+            }
+        }
+     }
+  for(std::vector<ElectromagnetismRotationFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    if((*it0).getStatus())
+      (*it0).fillIdsToKeep(s);
+  return s;
+}
+
+// see reference : https://en.cppreference.com/w/cpp/iterator/iterator
+class FamilyIterator : public std::iterator< std::input_iterator_tag, long, long, int*, int >
+{
+  long _num = 0;
+  const ElectromagnetismRotationInternal *_egi = nullptr;
+  const std::vector<std::string> *_fams = nullptr;
+public:
+  explicit FamilyIterator(long num , const ElectromagnetismRotationInternal *egi, const std::vector<std::string>& fams) : _num(num),_egi(egi),_fams(&fams) {}
+  FamilyIterator& operator++() { ++_num; return *this;}
+  bool operator==(const FamilyIterator& other) const {return _num == other._num;}
+  bool operator!=(const FamilyIterator& other) const {return !(*this == other);}
+  reference operator*() const {return _egi->getIdOfFamily((*_fams)[_num]);}
+};
+
+std::vector< std::pair<std::string,std::vector<int> > > ElectromagnetismRotationInternal::getAllGroups() const
+{
+    std::vector< std::pair<std::string,std::vector<int> > > ret;
+    for(const auto&  grp : _groups)
+    {
+        const std::vector<std::string>& fams(grp.getFamiliesLyingOn());
+        std::vector<int> famIds(FamilyIterator(0,this,fams),FamilyIterator(fams.size(),this,fams));
+        if ( std::all_of(famIds.begin(), famIds.end(), [](int i){ return i<0; }) )// only groups on cells considered here
+        {
+          std::pair<std::string,std::vector<int> > elt(grp.getName(),std::move(famIds));
+          ret.emplace_back(std::move(elt));
+        }
+    }
+    return ret;
+}
+
+void ElectromagnetismRotationInternal::clearSelection() const
+{
+  _selection.clear();
+  for(auto it : _groups)
+    it.resetStatus();
+  for(auto it : _fams)
+    it.resetStatus();
+}
+
+std::map<std::string,int> ElectromagnetismRotationInternal::computeFamStrIdMap() const
+{
+  std::map<std::string,int> ret;
+  for(std::vector<ElectromagnetismRotationFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    ret[(*it0).getName()]=(*it0).getId();
+  return ret;
+}
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.h b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/ElectromagnetismRotationHelper.h
new file mode 100644 (file)
index 0000000..aade392
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#pragma once
+
+#include <sstream>
+#include <vector>
+#include <set>
+#include <map>
+
+#include "MEDLoaderForPV.h"
+
+class MEDLOADERFORPV_EXPORT ElectromagnetismRotationStatus
+{
+public:
+  ElectromagnetismRotationStatus():_status(false) { }
+  ElectromagnetismRotationStatus(const char *name);
+  bool getStatus() const { return _status; }
+  void setStatus(bool status) const { _status=status; }
+  void cpyStatusFrom(const ElectromagnetismRotationStatus& other) { _status=other._status; }
+  std::string getName() const { return _name; }
+  void resetStatus() const { _status=false; }
+  const char *getKeyOfEntry() const { return _ze_key_name.c_str(); }
+  virtual void printMySelf(std::ostream& os) const;
+  virtual bool isSameAs(const ElectromagnetismRotationStatus& other) const;
+protected:
+mutable bool _status;
+std::string _name;
+std::string _ze_key_name;
+};
+
+class MEDLOADERFORPV_EXPORT ElectromagnetismRotationGrp : public ElectromagnetismRotationStatus
+{
+public:
+  ElectromagnetismRotationGrp(const char *name):ElectromagnetismRotationStatus(name) { std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); }
+  void setFamilies(const std::vector<std::string>& fams) { _fams=fams; }
+  const std::vector<std::string>& getFamiliesLyingOn() const { return _fams; }
+  bool isSameAs(const ElectromagnetismRotationGrp& other) const;
+public:
+  static const char START[];
+  std::vector<std::string> _fams;
+};
+
+class MEDLOADERFORPV_EXPORT ElectromagnetismRotationFam : public ElectromagnetismRotationStatus
+{
+public:
+  ElectromagnetismRotationFam(const char *name);
+  void printMySelf(std::ostream& os) const;
+  void fillIdsToKeep(std::set<int>& s) const;
+  int getId() const { return _id; }
+  bool isSameAs(const ElectromagnetismRotationFam& other) const;
+public:
+  static const char START[];
+private:
+  int _id;
+};
+
+class vtkInformationDataObjectMetaDataKey;
+class vtkMutableDirectedGraph;
+class vtkInformation;
+
+class MEDLOADERFORPV_EXPORT ElectromagnetismRotationInternal
+{
+public:
+  void loadFrom(vtkMutableDirectedGraph *sil);
+  int getNumberOfEntries() const;
+  const char *getMeshName() const;
+  const char *getKeyOfEntry(int i) const;
+  bool getStatusOfEntryStr(const char *entry) const;
+  void setStatusOfEntryStr(const char *entry, bool status);
+  void printMySelf(std::ostream& os) const;
+  std::vector<int> getFamiliesIdsOnGroup(const std::string& groupName) const;
+  std::set<int> getIdsToKeep() const;
+  std::vector< std::pair<std::string,std::vector<int> > > getAllGroups() const;
+  void clearSelection() const;
+  int getIdOfFamily(const std::string& famName) const;
+  static bool IndependantIsInformationOK(vtkInformationDataObjectMetaDataKey *medReaderMetaData, vtkInformation *info);
+private:
+  std::map<std::string,int> computeFamStrIdMap() const;
+  const ElectromagnetismRotationStatus& getEntry(const char *entry) const;
+  ElectromagnetismRotationStatus& getEntry(const char *entry);
+private:
+  std::vector<ElectromagnetismRotationGrp> _groups;
+  std::vector<ElectromagnetismRotationFam> _fams;
+  mutable std::vector< std::pair<std::string,bool> > _selection;
+  std::string _mesh_name;
+};
+
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/MEDLoaderForPV.h b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationHelper/MEDLoaderForPV.h
new file mode 100644 (file)
index 0000000..a40ce84
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __MEDLOADERFORPV_HXX__
+#define __MEDLOADERFORPV_HXX__
+
+#ifdef WIN32
+# if defined MEDLoaderForPV_EXPORTS || defined MEDLOADERFORPV_EXPORTS
+#  define MEDLOADERFORPV_EXPORT __declspec( dllexport )
+# else
+#  define MEDLOADERFORPV_EXPORT __declspec( dllimport )
+# endif
+#else
+ #define MEDLOADERFORPV_EXPORT
+#endif
+
+#endif
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/CMakeLists.txt b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d5c5fc4
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkElectromagnetismRotation
+  vtkPVMetaDataInformation
+)
+
+vtk_module_add_module(ElectromagnetismRotationIO
+  FORCE_STATIC
+  CLASSES ${classes}
+)
+
+target_include_directories(ElectromagnetismRotationIO PRIVATE
+  "${CMAKE_CURRENT_SOURCE_DIR}/../ElectromagnetismRotationHelper"
+  ${MEDCOUPLING_INCLUDE_DIRS})
+
+target_link_libraries(ElectromagnetismRotationIO PUBLIC ElectromagnetismRotationHelper)
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/VTKMEDTraits.hxx b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/VTKMEDTraits.hxx
new file mode 100644 (file)
index 0000000..4c7832d
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __VTKMEDTRAITS_HXX__
+#define __VTKMEDTRAITS_HXX__
+
+class vtkIntArray;
+class vtkLongArray;
+#ifdef WIN32
+class vtkLongLongArray;
+#endif
+class vtkFloatArray;
+class vtkDoubleArray;
+
+template<class T>
+class MEDFileVTKTraits
+{
+public:
+  typedef void VtkType;
+  typedef void MCType;
+};
+
+template<>
+class MEDFileVTKTraits<int>
+{
+public:
+  typedef vtkIntArray VtkType;
+  typedef MEDCoupling::DataArrayInt32 MCType;
+};
+
+template<>
+#ifdef WIN32
+class MEDFileVTKTraits<long long>
+#else 
+class MEDFileVTKTraits<long>
+#endif
+#
+{
+public:
+#ifdef WIN32
+  typedef vtkLongLongArray VtkType;
+#else
+  typedef vtkLongArray VtkType;
+#endif
+  typedef MEDCoupling::DataArrayInt64 MCType;
+};
+
+template<>
+class MEDFileVTKTraits<float>
+{
+public:
+  typedef vtkFloatArray VtkType;
+  typedef MEDCoupling::DataArrayFloat MCType;
+};
+
+template<>
+class MEDFileVTKTraits<double>
+{
+public:
+  typedef vtkDoubleArray VtkType;
+  typedef MEDCoupling::DataArrayDouble MCType;
+};
+
+#endif
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtk.module b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtk.module
new file mode 100644 (file)
index 0000000..4f21a46
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismRotationIO
+DEPENDS
+  VTK::FiltersGeneral
+  VTK::IOLegacy
+  ParaView::RemotingCore
+PRIVATE_DEPENDS
+  VTK::IOLegacy
+  ParaView::VTKExtensionsFiltersRendering
+  ParaView::VTKExtensionsMisc
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.cxx b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.cxx
new file mode 100644 (file)
index 0000000..ce20795
--- /dev/null
@@ -0,0 +1,454 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "vtkElectromagnetismRotation.h"
+
+#include "MEDCouplingMemArray.hxx"
+
+#include "ElectromagnetismRotationHelper.h"
+#include "VTKMEDTraits.hxx"
+
+#include "vtkAdjacentVertexIterator.h"
+#include "vtkDataArrayTemplate.h"
+#include "vtkIntArray.h"
+#include "vtkLongArray.h"
+#ifdef WIN32
+#include "vtkLongLongArray.h"
+#endif
+#include "vtkCellData.h"
+#include "vtkPointData.h"
+
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkUnstructuredGrid.h"
+#include  "vtkMultiBlockDataSet.h"
+
+#include "vtkInformationStringKey.h"
+#include "vtkAlgorithmOutput.h"
+#include "vtkObjectFactory.h"
+#include "vtkMutableDirectedGraph.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkDataSet.h"
+#include "vtkInformationVector.h"
+#include "vtkInformation.h"
+#include "vtkDataArraySelection.h"
+#include "vtkTimeStamp.h"
+#include "vtkInEdgeIterator.h"
+#include "vtkInformationDataObjectKey.h"
+#include "vtkExecutive.h"
+#include "vtkVariantArray.h"
+#include "vtkStringArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkCharArray.h"
+#include "vtkUnsignedCharArray.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkDemandDrivenPipeline.h"
+#include "vtkDataObjectTreeIterator.h"
+#include "vtkThreshold.h"
+#include "vtkMultiBlockDataGroupFilter.h"
+#include "vtkCompositeDataToUnstructuredGridFilter.h"
+#include "vtkInformationDataObjectMetaDataKey.h"
+#include "vtkTransform.h"
+#include "vtkFunctionParser.h"
+
+#include <map>
+#include <deque>
+#include <cstring>
+#include <memory>
+
+const char ZE_SEP[]="@@][@@";
+
+const char TS_STR[]="TS";
+
+const char COM_SUP_STR[]="ComSup";
+
+const char FAMILY_ID_CELL_NAME[]="FamilyIdCell";
+
+const char NUM_ID_CELL_NAME[]="NumIdCell";
+
+const char FAMILY_ID_NODE_NAME[]="FamilyIdNode";
+
+const char NUM_ID_NODE_NAME[]="NumIdNode";
+
+const char GLOBAL_NODE_ID_NAME[]="GlobalNodeIds";
+
+vtkStandardNewMacro(vtkElectromagnetismRotation);
+
+vtkInformationDataObjectMetaDataKey* GetMEDReaderMetaDataIfAny()
+{
+  static const char ZE_KEY[] = "vtkMEDReader::META_DATA";
+  MEDCoupling::GlobalDict* gd(MEDCoupling::GlobalDict::GetInstance());
+  if (!gd->hasKey(ZE_KEY))
+    return 0;
+  std::string ptSt(gd->value(ZE_KEY));
+  void* pt(0);
+  std::istringstream iss(ptSt);
+  iss >> pt;
+  return reinterpret_cast<vtkInformationDataObjectMetaDataKey*>(pt);
+}
+
+bool IsInformationOK(vtkInformation* info)
+{
+  vtkInformationDataObjectMetaDataKey* key(GetMEDReaderMetaDataIfAny());
+  if (!key)
+    return false;
+  // Check the information contain meta data key
+  if (!info->Has(key))
+    return false;
+  // Recover Meta Data
+  vtkMutableDirectedGraph* sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(key)));
+  if (!sil)
+    return false;
+  int idNames(0);
+  vtkAbstractArray* verticesNames(sil->GetVertexData()->GetAbstractArray("Names", idNames));
+  vtkStringArray* verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
+  if (!verticesNames2)
+    return false;
+  for (int i = 0; i < verticesNames2->GetNumberOfValues(); i++)
+  {
+    vtkStdString& st(verticesNames2->GetValue(i));
+    if (st == "MeshesFamsGrps")
+      return true;
+  }
+  return false;
+}
+
+class vtkElectromagnetismRotation::vtkElectromagnetismRotationInternal : public ElectromagnetismRotationInternal
+{
+};
+
+////////////////////
+
+vtkElectromagnetismRotation::vtkElectromagnetismRotation():SIL(NULL),Internal(new vtkElectromagnetismRotationInternal),InsideOut(0),Axis(2),RotationRotor(1e300)
+{
+}
+
+vtkElectromagnetismRotation::~vtkElectromagnetismRotation()
+{
+  delete this->Internal;
+}
+
+void vtkElectromagnetismRotation::SetInsideOut(int val)
+{
+  if(this->InsideOut!=val)
+    {
+      this->InsideOut=val;
+      this->Modified();
+    }
+}
+
+void vtkElectromagnetismRotation::SetAxis(int axis)
+{
+  if(this->Axis!=axis)
+    {
+      this->Axis=axis;
+      this->Modified();
+    }
+}
+
+void vtkElectromagnetismRotation::SetAngularStep(char *angStep)
+{
+  this->AngularStep = angStep;
+  this->Modified();
+}
+
+int vtkElectromagnetismRotation::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+//  vtkUnstructuredGridAlgorithm::RequestInformation(request,inputVector,outputVector);
+  try
+    {
+//      std::cerr << "########################################## vtkElectromagnetismRotation::RequestInformation ##########################################" << std::endl;
+//      request->Print(cout);
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
+      if(!ElectromagnetismRotationInternal::IndependantIsInformationOK(GetMEDReaderMetaDataIfAny(),inputInfo))
+        {
+        vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
+        return 0;
+        }
+
+      this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(GetMEDReaderMetaDataIfAny())));
+      this->Internal->loadFrom(this->SIL);
+      //this->Internal->printMySelf(std::cerr);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      std::cerr << "Exception has been thrown in vtkElectromagnetismRotation::RequestInformation : " << e.what() << std::endl;
+      return 0;
+    }
+  return 1;
+}
+
+/*!
+ * Do not use vtkCxxSetObjectMacro macro because input mdg comes from an already managed in the pipeline just a ref on it.
+ */
+void vtkElectromagnetismRotation::SetSIL(vtkMutableDirectedGraph *mdg)
+{
+  if(this->SIL==mdg)
+    return ;
+  this->SIL=mdg;
+}
+
+template<class CellPointExtractor>
+vtkDataSet *FilterFamilies(vtkThreshold *thres,
+                           vtkDataSet *input, const std::set<int>& idsToKeep, bool insideOut, const char *arrNameOfFamilyField,
+                           const char *associationForThreshold, bool& catchAll, bool& catchSmth)
+{
+  const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
+  const char ZE_SELECTION_ARR_NAME[]="@@ZeSelection@@";
+  vtkDataSet *output(input->NewInstance());
+  output->ShallowCopy(input);
+  thres->SetInputData(output);
+  vtkDataSetAttributes *dscIn(input->GetCellData()),*dscIn2(input->GetPointData());
+  vtkDataSetAttributes *dscOut(output->GetCellData()),*dscOut2(output->GetPointData());
+  //
+  double vMin(insideOut==0?1.:0.),vMax(insideOut==0?2.:1.);
+  thres->ThresholdBetween(vMin,vMax);
+  // OK for the output
+  //
+  CellPointExtractor cpe2(input);
+  vtkDataArray *da(cpe2.Get()->GetScalars(arrNameOfFamilyField));
+  if(!da)
+    return 0;
+  std::string daName(da->GetName());
+  typedef MEDFileVTKTraits<mcIdType>::VtkType vtkMCIdTypeArray;
+  vtkMCIdTypeArray *dai(vtkMCIdTypeArray::SafeDownCast(da));
+  if(daName!=arrNameOfFamilyField || !dai)
+    return 0;
+  //
+  int nbOfTuples(dai->GetNumberOfTuples());
+  vtkCharArray *zeSelection(vtkCharArray::New());
+  zeSelection->SetName(ZE_SELECTION_ARR_NAME);
+  zeSelection->SetNumberOfComponents(1);
+  char *pt(new char[nbOfTuples]);
+  zeSelection->SetArray(pt,nbOfTuples,0,VTK_DATA_ARRAY_DELETE);
+  const mcIdType *inPtr(dai->GetPointer(0));
+  std::fill(pt,pt+nbOfTuples,0);
+  catchAll=true; catchSmth=false;
+  std::vector<bool> pt2(nbOfTuples,false);
+  for(std::set<int>::const_iterator it=idsToKeep.begin();it!=idsToKeep.end();it++)
+    {
+      bool catchFid(false);
+      for(int i=0;i<nbOfTuples;i++)
+        if(inPtr[i]==*it)
+          { pt2[i]=true; catchFid=true; }
+      if(!catchFid)
+        catchAll=false;
+      else
+        catchSmth=true;
+    }
+  for(int ii=0;ii<nbOfTuples;ii++)
+    if(pt2[ii])
+      pt[ii]=2;
+  CellPointExtractor cpe3(output);
+  int idx(cpe3.Get()->AddArray(zeSelection));
+  cpe3.Get()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
+  cpe3.Get()->CopyScalarsOff();
+  zeSelection->Delete();
+  //
+  thres->SetInputArrayToProcess(idx,0,0,associationForThreshold,ZE_SELECTION_ARR_NAME);
+  thres->Update();
+  vtkUnstructuredGrid *zeComputedOutput(thres->GetOutput());
+  CellPointExtractor cpe(zeComputedOutput);
+  cpe.Get()->RemoveArray(idx);
+  output->Delete();
+  zeComputedOutput->Register(0);
+  return zeComputedOutput;
+}
+
+class CellExtractor
+{
+public:
+  CellExtractor(vtkDataSet *ds):_ds(ds) { }
+  vtkDataSetAttributes *Get() { return _ds->GetCellData(); }
+private:
+  vtkDataSet *_ds;
+};
+
+class PointExtractor
+{
+public:
+  PointExtractor(vtkDataSet *ds):_ds(ds) { }
+  vtkDataSetAttributes *Get() { return _ds->GetPointData(); }
+private:
+  vtkDataSet *_ds;
+};
+
+int vtkElectromagnetismRotation::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  try
+    {
+      // std::cerr << "########################################## vtkElectromagnetismRotation::RequestData        ##########################################" << std::endl;
+      // request->Print(cout);
+      vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
+      vtkMultiBlockDataSet *inputMB(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+      if(inputMB->GetNumberOfBlocks()!=1)
+        {
+          vtkErrorMacro(<< "vtkElectromagnetismRotation::RequestData : input has not the right number of parts ! Expected 1 !" ) ;
+          return 0;
+        }
+      vtkDataSet *input(vtkDataSet::SafeDownCast(inputMB->GetBlock(0)));
+      vtkInformation *info(input->GetInformation());
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkMultiBlockDataSet *output(vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      output->SetNumberOfBlocks(2);
+      std::set<int> idsToKeep(this->Internal->getIdsToKeep());
+      this->Internal->clearSelection();
+      // first shrink the input
+      bool catchAll,catchSmth;
+      vtkNew<vtkThreshold> thres1,thres2;
+      vtkSmartPointer<vtkDataSet> rotor(FilterFamilies<CellExtractor>(thres1,input,idsToKeep,0,FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
+      vtkSmartPointer<vtkDataSet> stator(FilterFamilies<CellExtractor>(thres2,input,idsToKeep,1,FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
+      //
+      double reqTS(0.);
+      int nbOfSteps(-1);
+      std::unique_ptr<double[]> timeSteps;
+       
+      if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
+        reqTS=outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
+      if(outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+      {
+        nbOfSteps = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+        timeSteps.reset(new double[ nbOfSteps ]);
+        outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),timeSteps.get());
+        //std::cerr << "nb : " << nbOfSteps << std::endl;
+        //std::for_each(timeSteps.get(),timeSteps.get()+nbOfSteps,[](double v) { std::cerr << v << std::endl; });
+      }
+      if(nbOfSteps<2 || !timeSteps.get())
+      {
+        vtkErrorMacro(<< "vtkElectromagnetismRotation::RequestData : A temporal dataset is expected ! Here < 2 time steps found !" ) ;
+        return 0;
+      }
+      // Calcul de l angle effectif de rotation
+      double minTime(timeSteps[0]),maxTime(timeSteps[nbOfSteps-1]);
+      if(minTime == maxTime)
+      {
+        vtkErrorMacro(<< "vtkElectromagnetismRotation::RequestData : minTime == maxTime !" ) ;
+        return 0;
+      }
+      double angularStepD = 0;
+      {
+        vtkNew<vtkFunctionParser> fp;
+        fp->SetFunction(this->AngularStep.c_str());
+        angularStepD = fp->GetScalarResult();
+      }
+      double effectiveTime(reqTS); effectiveTime = std::max(effectiveTime,minTime); effectiveTime = std::min(effectiveTime,maxTime);
+      this->RotationRotor = (angularStepD*((effectiveTime-minTime)/(maxTime-minTime)));
+      //std::cout << "*** " << effectiveTime << " " << minTime << " " << maxTime << " " << angleDegree << std::endl << std::flush;
+      //std::cout << "*** " << this->RotationRotor << std::endl << std::flush;
+      //
+      if(rotor)
+        {
+          if(catchAll)
+            {
+              vtkNew<vtkTransform> transformR;
+              switch(this->Axis)
+              {
+                case 0:
+                {
+                  transformR->RotateX(this->RotationRotor);
+                  break;
+                }
+                case 1:
+                {
+                  transformR->RotateY(this->RotationRotor);
+                  break;
+                }
+                case 2:
+                {
+                  transformR->RotateZ(this->RotationRotor);
+                  break;
+                }
+                default:
+                {
+                  vtkErrorMacro(<< "vtkElectromagnetismRotation::RequestData : not recognized axis !" ) ;
+                  return 0;
+                }
+              }
+              vtkNew<vtkPoints> newCoords;
+              transformR->TransformPoints(vtkPointSet::SafeDownCast(rotor)->GetPoints(),newCoords);
+              vtkPointSet::SafeDownCast(rotor)->SetPoints(newCoords);
+              output->SetBlock(0,rotor);
+              output->SetBlock(1,stator);
+              return 1;
+            }
+          else
+            return 0;
+        }
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      vtkErrorMacro(<< "Exception has been thrown in vtkElectromagnetismRotation::RequestData : " << e.what());
+      return 0;
+    }
+}
+
+int vtkElectromagnetismRotation::GetSILUpdateStamp()
+{
+  return (int)this->SILTime;
+}
+
+const char* vtkElectromagnetismRotation::GetGrpStart()
+{
+  return ElectromagnetismRotationGrp::START;
+}
+
+const char* vtkElectromagnetismRotation::GetFamStart()
+{
+  return ElectromagnetismRotationFam::START;
+}
+
+void vtkElectromagnetismRotation::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+int vtkElectromagnetismRotation::GetNumberOfGroupsFlagsArrays()
+{
+  int ret(this->Internal->getNumberOfEntries());
+  //std::cerr << "vtkElectromagnetismRotation::GetNumberOfFieldsTreeArrays() -> " << ret << std::endl;
+  return ret;
+}
+
+const char *vtkElectromagnetismRotation::GetGroupsFlagsArrayName(int index)
+{
+  const char *ret(this->Internal->getKeyOfEntry(index));
+//  std::cerr << "vtkElectromagnetismRotation::GetFieldsTreeArrayName(" << index << ") -> " << ret << std::endl;
+  return ret;
+}
+
+int vtkElectromagnetismRotation::GetGroupsFlagsArrayStatus(const char *name)
+{
+  int ret((int)this->Internal->getStatusOfEntryStr(name));
+//  std::cerr << "vtkElectromagnetismRotation::GetGroupsFlagsArrayStatus(" << name << ") -> " << ret << std::endl;
+  return ret;
+}
+
+void vtkElectromagnetismRotation::SetGroupsFlagsStatus(const char *name, int status)
+{
+  //std::cerr << "vtkElectromagnetismRotation::SetFieldsStatus(" << name << "," << status << ")" << std::endl;
+  this->Internal->setStatusOfEntryStr(name,(bool)status);
+  this->Modified();
+  //this->Internal->printMySelf(std::cerr);
+}
+
+const char *vtkElectromagnetismRotation::GetMeshName()
+{
+  return this->Internal->getMeshName();
+}
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.h b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkElectromagnetismRotation.h
new file mode 100644 (file)
index 0000000..e272e2a
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#pragma once
+
+#include "vtkMultiBlockDataSetAlgorithm.h"
+
+#include <string>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkElectromagnetismRotation : public vtkMultiBlockDataSetAlgorithm
+{
+public:
+  static vtkElectromagnetismRotation* New();
+  vtkTypeMacro(vtkElectromagnetismRotation, vtkMultiBlockDataSetAlgorithm)
+  void PrintSelf(ostream& os, vtkIndent indent);
+  virtual int GetNumberOfGroupsFlagsArrays();
+  const char *GetGroupsFlagsArrayName(int index);
+  int GetGroupsFlagsArrayStatus(const char *name);
+  virtual void SetGroupsFlagsStatus(const char *name, int status);
+  void SetInsideOut(int val);
+  void SetAxis(int axis);
+  void SetAngularStep(char *angStep);
+
+  // Description:
+  // Every time the SIL is updated a this will return a different value.
+  virtual int GetSILUpdateStamp();
+  const char *GetMeshName();
+  static const char* GetGrpStart();
+  static const char* GetFamStart();
+protected:
+  vtkElectromagnetismRotation();
+  ~vtkElectromagnetismRotation();
+
+  int RequestInformation(vtkInformation *request,
+      vtkInformationVector **inputVector, vtkInformationVector *outputVector);
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+      vtkInformationVector *outputVector);
+
+  // Description:
+  // This SIL stores the structure of the mesh/groups/cell types
+  // that can be selected.
+  virtual void SetSIL(vtkMutableDirectedGraph*);
+  vtkGetObjectMacro(SIL, vtkMutableDirectedGraph);
+protected:
+  vtkMutableDirectedGraph *SIL;
+  vtkTimeStamp SILTime;
+private:
+  vtkElectromagnetismRotation(const vtkElectromagnetismRotation&);
+  void operator=(const vtkElectromagnetismRotation&); // Not implemented.
+ private:
+  //BTX
+  //ETX
+  class vtkElectromagnetismRotationInternal;
+  vtkElectromagnetismRotationInternal *Internal;
+  int InsideOut;
+  int Axis;
+  std::string AngularStep;
+  mutable double RotationRotor;
+};
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.cxx b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.cxx
new file mode 100644 (file)
index 0000000..975fa12
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "vtkPVMetaDataInformation.h"
+
+#include "vtkAlgorithm.h"
+#include "vtkAlgorithmOutput.h"
+#include "vtkClientServerStream.h"
+#include "vtkExecutive.h"
+#include "vtkDataObject.h"
+#include "vtkGenericDataObjectReader.h"
+#include "vtkGenericDataObjectWriter.h"
+#include "vtkInformationDataObjectMetaDataKey.h"
+#include "vtkInformation.h"
+#include "vtkObjectFactory.h"
+
+#include "MEDCouplingRefCountObject.hxx"
+
+#include <sstream>
+
+vtkStandardNewMacro(vtkPVMetaDataInformation);
+vtkCxxSetObjectMacro(vtkPVMetaDataInformation, InformationData, vtkDataObject);
+
+static vtkInformationDataObjectMetaDataKey* GetMEDReaderMetaDataIfAny()
+{
+  static const char ZE_KEY[] = "vtkMEDReader::META_DATA";
+  MEDCoupling::GlobalDict* gd(MEDCoupling::GlobalDict::GetInstance());
+  if (!gd->hasKey(ZE_KEY))
+    return 0;
+  std::string ptSt(gd->value(ZE_KEY));
+  void* pt(0);
+  std::istringstream iss(ptSt);
+  iss >> pt;
+  return reinterpret_cast<vtkInformationDataObjectMetaDataKey*>(pt);
+}
+
+//----------------------------------------------------------------------------
+vtkPVMetaDataInformation::vtkPVMetaDataInformation()
+{
+  this->InformationData = NULL;
+}
+
+//----------------------------------------------------------------------------
+vtkPVMetaDataInformation::~vtkPVMetaDataInformation()
+{
+  this->SetInformationData(NULL);
+}
+
+//----------------------------------------------------------------------------
+void vtkPVMetaDataInformation::CopyFromObject(vtkObject* obj)
+{
+  this->SetInformationData(NULL);
+
+  vtkAlgorithmOutput* algOutput = vtkAlgorithmOutput::SafeDownCast(obj);
+  if (!algOutput)
+    {
+    vtkAlgorithm* alg = vtkAlgorithm::SafeDownCast(obj);
+    if (alg)
+      {
+      algOutput = alg->GetOutputPort(0);
+      }
+
+    }
+  if (!algOutput)
+    {
+    vtkErrorMacro("Information can only be gathered from a vtkAlgorithmOutput.");
+    return;
+    }
+
+  vtkAlgorithm* reader = algOutput->GetProducer();
+  vtkInformation* info = reader->GetExecutive()->GetOutputInformation(
+    algOutput->GetIndex());
+
+  if (info && info->Has(GetMEDReaderMetaDataIfAny()))
+    {
+    this->SetInformationData(vtkDataObject::SafeDownCast(info->Get(GetMEDReaderMetaDataIfAny())));
+    }
+}
+
+//----------------------------------------------------------------------------
+void vtkPVMetaDataInformation::CopyToStream(vtkClientServerStream* css)
+{
+  css->Reset();
+  if (!this->InformationData)
+    {
+    *css << vtkClientServerStream::Reply
+         << vtkClientServerStream::InsertArray(
+           static_cast<unsigned char*>(NULL), 0)
+         << vtkClientServerStream::End;
+    return;
+    }
+
+  vtkDataObject* clone = this->InformationData->NewInstance();
+  clone->ShallowCopy(this->InformationData);
+
+  vtkGenericDataObjectWriter* writer = vtkGenericDataObjectWriter::New();
+  writer->SetFileTypeToBinary();
+  writer->WriteToOutputStringOn();
+  writer->SetInputData(clone);
+  writer->Write();
+
+  *css << vtkClientServerStream::Reply
+       << vtkClientServerStream::InsertArray(
+         writer->GetBinaryOutputString(),
+         writer->GetOutputStringLength())
+       << vtkClientServerStream::End;
+  writer->RemoveAllInputs();
+  writer->Delete();
+  clone->Delete();
+}
+
+//----------------------------------------------------------------------------
+void vtkPVMetaDataInformation::CopyFromStream(const vtkClientServerStream* css)
+{
+  this->SetInformationData(0);
+  vtkTypeUInt32 length;
+  if (css->GetArgumentLength(0, 0, &length) && length > 0)
+    {
+    unsigned char* raw_data = new unsigned char[length];
+    css->GetArgument(0, 0, raw_data, length);
+    vtkGenericDataObjectReader* reader = vtkGenericDataObjectReader::New();
+    reader->SetBinaryInputString(reinterpret_cast<const char*>(raw_data), length);
+    reader->ReadFromInputStringOn();
+    delete []raw_data;
+    reader->Update();
+    this->SetInformationData(reader->GetOutput());
+    reader->Delete();
+    }
+}
+
+void vtkPVMetaDataInformation::AddInformation(vtkPVInformation*)
+{
+}
+
+//----------------------------------------------------------------------------
+void vtkPVMetaDataInformation::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "InformationData: " <<  this->InformationData << endl;
+}
diff --git a/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.h b/src/ElectromagnetismRotation/plugin/ElectromagnetismRotationIO/vtkPVMetaDataInformation.h
new file mode 100644 (file)
index 0000000..b2f3133
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#ifndef __vtkPVMetaDataInformation_h
+#define __vtkPVMetaDataInformation_h
+
+#include "vtkPVInformation.h"
+
+class vtkDataObject;
+class vtkInformationDataObjectKey;
+
+class VTK_EXPORT vtkPVMetaDataInformation : public vtkPVInformation
+{
+public:
+  static vtkPVMetaDataInformation* New();
+  vtkTypeMacro(vtkPVMetaDataInformation, vtkPVInformation);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Transfer information about a single object into this object.
+  virtual void CopyFromObject(vtkObject*);
+
+  //BTX
+  // Description:
+  // Manage a serialized version of the information.
+  virtual void CopyToStream(vtkClientServerStream*);
+  virtual void CopyFromStream(const vtkClientServerStream*);
+  virtual void AddInformation(vtkPVInformation*);
+  //ETX
+
+  // Description:
+  // Returns the Information Data.
+  vtkGetObjectMacro(InformationData, vtkDataObject);
+
+//BTX
+protected:
+  vtkPVMetaDataInformation();
+  ~vtkPVMetaDataInformation();
+  void SetInformationData(vtkDataObject*);
+  vtkDataObject* InformationData;
+
+private:
+  vtkPVMetaDataInformation(const vtkPVMetaDataInformation&); // Not implemented
+  void operator=(const vtkPVMetaDataInformation&); // Not implemented
+//ETX
+};
+
+#endif
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/CMakeLists.txt b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f248280
--- /dev/null
@@ -0,0 +1,58 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(interfaces)
+set(sources)
+
+cmake_policy(SET CMP0071 OLD) # bug in ParaViewPlugin.cmake?
+
+if(PARAVIEW_USE_QT)
+
+  set(sources
+    pqElectroRotationAbstractFieldsWidget.cxx
+    pqElectroRotationGroupWidget.cxx)
+
+  paraview_plugin_add_property_widget(
+    KIND WIDGET
+    TYPE "ElectroRotationGroupWidgetType"
+    CLASS_NAME pqElectroRotationGroupWidget
+    INTERFACES property_interfaces
+    SOURCES property_sources)
+  list(APPEND interfaces
+    ${property_interfaces})
+  list(APPEND sources
+    ${property_sources})
+
+endif(PARAVIEW_USE_QT)
+
+paraview_add_plugin(ElectromagnetismRotation
+  VERSION "5.0"
+  UI_INTERFACES ${interfaces}
+  SOURCES ${sources}
+  UI_RESOURCES Resources/pqElectromagnetismRotation.qrc
+  SERVER_MANAGER_XML Resources/ElectromagnetismRotation.xml
+  MODULES ElectromagnetismRotationIO
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../ElectromagnetismRotationIO/vtk.module"
+  )
+
+install(TARGETS ElectromagnetismRotation
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/ElectromagnetismRotation.xml b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/ElectromagnetismRotation.xml
new file mode 100644 (file)
index 0000000..a6dae23
--- /dev/null
@@ -0,0 +1,75 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="RotationOfGroup" class="vtkElectromagnetismRotation" label="Rotation Of Group">
+     <InputProperty name="Input" command="SetInputConnection">
+       <ProxyGroupDomain name="groups">
+         <Group name="sources"/>
+         <Group name="filters"/>
+       </ProxyGroupDomain>
+       <DataTypeDomain name="input_type">
+         <DataType value="vtkDataSet"/>
+       </DataTypeDomain>
+       <Documentation>
+         This property specifies the input to the Level Scalars filter.
+       </Documentation>
+     </InputProperty>
+
+     <StringVectorProperty name="GroupsFlagsInfo" information_only="1">
+       <ArraySelectionInformationHelper attribute_name="GroupsFlags" />
+     </StringVectorProperty>
+
+     <StringVectorProperty name="GroupsFlagsStatus" command="SetGroupsFlagsStatus"
+                           label="All Groups"
+                           number_of_elements="0"
+                           repeat_command="1"
+                           number_of_elements_per_command="2"
+                           element_types="2 0"
+                           information_property="GroupsFlagsInfo"
+                           panel_widget="ElectroRotationGroupWidgetType">
+       <ArraySelectionDomain name="array_list">
+         <RequiredProperties>
+           <Property name="GroupsFlagsInfo" function="ArrayList" />
+         </RequiredProperties>
+       </ArraySelectionDomain>
+       <Documentation>
+          This property lists all groups and families to select.
+       </Documentation>
+     </StringVectorProperty>
+
+      <IntVectorProperty command="SetAxis" default_values="2" name="Axis" number_of_elements="1">
+        <EnumerationDomain name="enum">
+          <Entry text="X" value="0" />
+          <Entry text="Y" value="1" />
+          <Entry text="Z" value="2" />
+        </EnumerationDomain>
+        <Documentation>This property determines the axis (X, Y or Z) along which rotation is performed.</Documentation>
+      </IntVectorProperty>
+
+      <StringVectorProperty command="SetAngularStep"
+                            default_values="36"
+                            label="Angular Step"
+                            name="AngularStep"
+                            number_of_elements="1">
+        <Documentation>Pas angulaire en degre</Documentation>
+      </StringVectorProperty>
+
+      <StringVectorProperty
+          name="MeshName"
+          command="GetMeshName"
+          number_of_elements="1"
+          animateable="0"
+          information_only="1">
+        <Documentation>
+          This property returns the name of the mesh.
+        </Documentation>
+      </StringVectorProperty>
+
+      <Hints>
+        <ShowInMenu category="Electromagnetism" />
+      </Hints>
+    
+
+    </SourceProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqCellData16.png b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqCellData16.png
new file mode 100644 (file)
index 0000000..8a6f2a6
Binary files /dev/null and b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqCellData16.png differ
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqPointData16.png b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqPointData16.png
new file mode 100644 (file)
index 0000000..50367ea
Binary files /dev/null and b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/Icons/pqPointData16.png differ
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/pqElectromagnetismRotation.qrc b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/Resources/pqElectromagnetismRotation.qrc
new file mode 100644 (file)
index 0000000..d1fe75a
--- /dev/null
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/ParaViewResources">
+        <file>Icons/pqCellData16.png</file>
+        <file>Icons/pqPointData16.png</file>
+    </qresource>
+</RCC>
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.cxx b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.cxx
new file mode 100644 (file)
index 0000000..f6307a8
--- /dev/null
@@ -0,0 +1,147 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "pqElectroRotationAbstractFieldsWidget.h"
+
+#include "pqArrayListDomain.h"
+#include "pqTreeWidget.h"
+#include "pqTreeWidgetItemObject.h"
+
+#include <QGridLayout>
+#include <QHeaderView>
+//-----------------------------------------------------------------------------
+pqElectroRotationAbstractFieldsWidget::pqElectroRotationAbstractFieldsWidget(
+  vtkSMProxy *smproxy, vtkSMProperty *smproperty, QWidget *parentObject)
+: Superclass(smproxy, parentObject)
+{
+  this->NItems = 0;
+  this->visibleHeader = true;
+  this->setShowLabel(false);
+
+  // Grid Layout
+  QGridLayout* gridLayout = new QGridLayout(this);
+
+  // Tree widget
+  this->TreeWidget = new pqTreeWidget(this);
+  gridLayout->addWidget(this->TreeWidget);
+}
+
+//-----------------------------------------------------------------------------
+pqElectroRotationAbstractFieldsWidget::~pqElectroRotationAbstractFieldsWidget()
+{
+  delete this->TreeWidget;
+}
+
+void pqElectroRotationAbstractFieldsWidget::initializeTreeWidget(vtkSMProxy *smproxy, vtkSMProperty *smproperty)
+{
+  // Load Tree Widget Items
+  this->loadTreeWidgetItems();
+
+  // Connect Property Domain to the fieldDomain property,
+  // so setFieldDomain is called when the domain changes.
+  vtkSMDomain* arraySelectionDomain = smproperty->GetDomain("array_list");
+  new pqArrayListDomain(this,"fieldsDomain", smproxy, smproperty, arraySelectionDomain);
+
+  // Connect property to field QProperty using a biderectionnal property link
+  this->addPropertyLink(this, "fields", SIGNAL(fieldsChanged()),
+                        smproxy, smproperty);
+
+  // Call slot when the tree is changed
+  QObject::connect(this->TreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
+                   this, SLOT(onItemChanged(QTreeWidgetItem*, int)));
+
+}
+
+//-----------------------------------------------------------------------------
+QSize pqElectroRotationAbstractFieldsWidget::sizeHint() const
+{
+  // TreeWidget sizeHintForRow is too low, correcting to +3.
+  int pix = (this->TreeWidget->sizeHintForRow(0) + 3) * this->NItems;
+  int margin[4];
+  this->TreeWidget->getContentsMargins(margin, margin + 1, margin + 2, margin + 3);
+  int h =  pix + margin[1] + margin[3];
+  if (this->visibleHeader)
+    {
+    h += this->TreeWidget->header()->frameSize().height();
+    } 
+  h = std::min(300, h);
+  return QSize(156, h);
+}
+
+//-----------------------------------------------------------------------------
+void pqElectroRotationAbstractFieldsWidget::onItemChanged(QTreeWidgetItem* item, int column) const
+{
+  if (column != 0)
+    {
+    return;
+    }
+  emit fieldsChanged();
+}
+
+//-----------------------------------------------------------------------------
+QList< QList< QVariant> > pqElectroRotationAbstractFieldsWidget::getFields() const
+{
+  // Put together a Field list, using ItemMap
+  QList< QList< QVariant> > ret;
+  QList< QVariant > field;
+  QMap<QString, pqTreeWidgetItemObject*>::const_iterator it;
+  for (it = this->ItemMap.begin(); it != this->ItemMap.end(); it++)
+    {
+    field.clear();
+    field.append(it.key());
+    field.append(it.value()->isChecked());
+    ret.append(field);
+    }
+  return ret;
+}
+
+//-----------------------------------------------------------------------------
+void pqElectroRotationAbstractFieldsWidget::setFields(QList< QList< QVariant> > fields)
+{
+  // Update each item checkboxes, using fields names and ItemMap
+  QMap<QString, pqTreeWidgetItemObject*>::iterator it;
+  foreach (QList< QVariant> field, fields)
+    {
+    it = this->ItemMap.find(field[0].toString());
+    if (it == this->ItemMap.end())
+      {
+      qDebug("Found an unknow Field in pqElectroRotationAbstractFieldsWidget::setFields, ignoring");
+      continue;
+      }
+    it.value()->setChecked(field[1].toBool());
+    }
+}
+
+//-----------------------------------------------------------------------------
+void pqElectroRotationAbstractFieldsWidget::setFieldsDomain(QList< QList< QVariant> > fields)
+{
+  // Block signals so the reloading does not trigger
+  // UncheckPropertyModified event
+  this->blockSignals(true);
+
+  // Load the tree widget
+  this->loadTreeWidgetItems();
+
+  // Set fields checkboxes
+  this->setFields(fields);
+
+  // Restore signals
+  this->blockSignals(false);
+}
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.h b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationAbstractFieldsWidget.h
new file mode 100644 (file)
index 0000000..8496862
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#pragma once
+
+#include "pqPropertyWidget.h"
+
+class pqTreeWidget;
+class pqTreeWidgetItemObject;
+class QTreeWidgetItem;
+class vtkSMProxy;
+class vtkSMProperty;
+
+class pqElectroRotationAbstractFieldsWidget : public pqPropertyWidget
+{
+  typedef pqPropertyWidget Superclass;
+  Q_OBJECT
+
+  // Description
+  // Property Qt used to set/get the fields with the property link
+  Q_PROPERTY(QList< QList< QVariant> > fields READ getFields WRITE setFields)
+
+  // Description
+  // Property Qt used to set the gorup fields domain with the property link
+  Q_PROPERTY(QList< QList< QVariant> > fieldsDomain READ getFields WRITE setFieldsDomain)
+public:
+  pqElectroRotationAbstractFieldsWidget(
+    vtkSMProxy *smproxy, vtkSMProperty *smproperty, QWidget *parentObject = 0);
+  virtual ~pqElectroRotationAbstractFieldsWidget();
+
+  // Description
+  // Corrected size hint, +3 pixel on each line
+  virtual QSize sizeHint() const;
+
+signals:
+  // Description
+  // Signal emited when selected field changed
+  void fieldsChanged() const;
+
+protected:
+  // Description
+  // bidrectionnal property link setter/getter
+  virtual QList< QList< QVariant> > getFields() const;
+  virtual void setFields(QList< QList< QVariant> > fields);
+
+  // Description
+  // Update the domain, eg: reload
+  virtual void setFieldsDomain(QList< QList< QVariant> > fields);
+
+
+  // Description
+  // Initialize the widget items and connect it to property
+  // To be called by subclasses in constructor
+  virtual void initializeTreeWidget(vtkSMProxy *smproxy, vtkSMProperty *smproperty);
+
+  // Description
+  // (Re)Load the tree widget items using recovered meta data graph
+  virtual void loadTreeWidgetItems() = 0;
+
+  // Description
+  // Tree widget
+  pqTreeWidget* TreeWidget;
+
+  // Description
+  // Number of items, for graphic purpose
+  int NItems;
+
+  // Description
+  // Map of ItemPropertyName -> Item Pointer, contains only leaf.
+  QMap< QString, pqTreeWidgetItemObject*> ItemMap;
+
+  // Description
+  // Bug in qt, header->isVisible always return false, storing this info here
+  // https://bugreports.qt.io/browse/QTBUG-12939
+  bool visibleHeader;
+protected slots:
+  // Description
+  // Slot called when the tree widget changed
+  virtual void onItemChanged(QTreeWidgetItem* itemOrig, int column) const;
+
+private:
+  Q_DISABLE_COPY(pqElectroRotationAbstractFieldsWidget);
+};
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.cxx b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.cxx
new file mode 100644 (file)
index 0000000..0ee85e5
--- /dev/null
@@ -0,0 +1,162 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "pqElectroRotationGroupWidget.h"
+
+#include "vtkElectromagnetismRotation.h"
+#include "vtkPVMetaDataInformation.h"
+
+#include "pqTreeWidget.h"
+#include "pqTreeWidgetItemObject.h"
+#include "vtkGraph.h"
+#include "vtkNew.h"
+#include "vtkStringArray.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkTree.h"
+
+#include <QStringList>
+
+//-----------------------------------------------------------------------------
+pqElectroRotationGroupWidget::pqElectroRotationGroupWidget(
+  vtkSMProxy *smproxy, vtkSMProperty *smproperty, QWidget *parentObject)
+: Superclass(smproxy, smproperty, parentObject)
+{
+  this->TreeWidget->setHeaderLabel("Groups");
+  this->initializeTreeWidget(smproxy, smproperty);
+}
+
+//-----------------------------------------------------------------------------
+pqElectroRotationGroupWidget::~pqElectroRotationGroupWidget()
+{
+}
+
+//-----------------------------------------------------------------------------
+void pqElectroRotationGroupWidget::loadTreeWidgetItems()
+{
+  // Recover Graph
+  vtkPVMetaDataInformation *info(vtkPVMetaDataInformation::New());
+  this->proxy()->GatherInformation(info);
+  vtkGraph* graph = vtkGraph::SafeDownCast(info->GetInformationData());
+  if(!graph)
+    {
+    return;
+    }
+
+  // Clear Tree Widget
+  this->TreeWidget->clear();
+
+  // Clear Item Map
+  this->ItemMap.clear();
+
+  // Create a tree
+  vtkNew<vtkTree> tree;
+  tree->CheckedShallowCopy(graph);
+  vtkStringArray* names = vtkStringArray::SafeDownCast(tree->GetVertexData()->GetAbstractArray("Names"));
+
+  vtkIdType root = tree->GetRoot();
+  vtkIdType mfg = tree->GetChild(root, 1); // MeshesFamsGrps
+
+  vtkIdType mesh = tree->GetChild(mfg, 0); // mesh
+  QString meshName = QString(names->GetValue(mesh));
+
+  this->NItems = 0;
+
+  vtkIdType grps = tree->GetChild(mesh, 0); // grps
+  pqTreeWidgetItemObject* grpsItem = new pqTreeWidgetItemObject(this->TreeWidget, QStringList());
+  this->NItems++;
+  grpsItem->setText(0, QString("Groups of \"" + meshName + "\""));
+
+  vtkIdType fams = tree->GetChild(mesh, 1); // fams
+  std::map<std::string, int> famDataTypeMap;
+  for (int i = 0; i < tree->GetNumberOfChildren(fams); i++)
+    {
+      vtkIdType fam = tree->GetChild(fams, i);
+      // Familly name
+      std::string str = names->GetValue(fam);
+      const char separator[]= "@@][@@";
+      size_t pos = str.find(separator);
+      std::string name = str.substr(0, pos);
+      // Datatype flag
+      int dataTypeFlag = atoi(str.substr(pos + strlen(separator)).c_str());
+      famDataTypeMap[name] = dataTypeFlag;
+    }
+
+  for (int i = 0; i < tree->GetNumberOfChildren(grps); i++)
+    {
+    // Grp Item
+    vtkIdType grp = tree->GetChild(grps, i);
+
+    // Datatype flag
+    bool hasPoint = false;
+    bool hasCell = false;
+    int dataTypeFlag = 0;
+    for (int j = 0; j < tree->GetNumberOfChildren(grp); j++)
+    {
+      dataTypeFlag = famDataTypeMap[names->GetValue(tree->GetChild(grp, j))];
+      if (dataTypeFlag > 0)
+        {
+        hasPoint = true;
+        }
+      else if (dataTypeFlag < 0)
+        {
+        hasCell = true;
+        }
+      else
+        {
+        dataTypeFlag = 0;
+        break;
+        }
+
+      if (hasPoint && hasCell)
+        {
+        dataTypeFlag = 0;
+        break;
+        }
+    }
+
+    //
+
+    if (dataTypeFlag<0) // if group on cells
+    {
+      pqTreeWidgetItemObject *grpItem = new pqTreeWidgetItemObject(grpsItem, QStringList());
+      this->NItems++;
+
+      // Group name
+      QString name = QString(names->GetValue(grp));
+      grpItem->setText(0, name);
+
+      // Property Name
+      QString propertyName = QString(vtkElectromagnetismRotation::GetGrpStart()) + name;
+      this->ItemMap[propertyName] = grpItem;
+
+      // Checkbox
+      grpItem->setFlags(grpItem->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
+      grpItem->setChecked(true);
+
+      // Tooltip
+      grpItem->setData(0, Qt::ToolTipRole, name);
+      
+      grpItem->setData(0, Qt::DecorationRole, QPixmap(":/ParaViewResources/Icons/pqCellData16.png"));
+    }
+  }
+
+  // Expand Widget
+  this->TreeWidget->expandAll();
+}
diff --git a/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.h b/src/ElectromagnetismRotation/plugin/ParaViewPlugin/pqElectroRotationGroupWidget.h
new file mode 100644 (file)
index 0000000..9fe4dfc
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#pragma once
+
+#include "pqElectroRotationAbstractFieldsWidget.h"
+
+class vtkSMProxy;
+class vtkSMProperty;
+
+class pqElectroRotationGroupWidget : public pqElectroRotationAbstractFieldsWidget
+{
+  typedef pqElectroRotationAbstractFieldsWidget Superclass;
+  Q_OBJECT
+
+public:
+  pqElectroRotationGroupWidget(
+    vtkSMProxy *smproxy, vtkSMProperty *smproperty, QWidget *parentObject = 0);
+  virtual ~pqElectroRotationGroupWidget();
+
+protected:
+  // Description
+  // Load the tree widget using recovered meta data graph
+  void loadTreeWidgetItems();
+
+private:
+  Q_DISABLE_COPY(pqElectroRotationGroupWidget);
+};
+
diff --git a/src/ElectromagnetismRotation/plugin/paraview.plugin b/src/ElectromagnetismRotation/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..d583b66
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismRotation
+DESCRIPTION
+  Rotation d une partie d un dataset
+REQUIRES_MODULES
diff --git a/src/ElectromagnetismStreamTraceur/CMakeLists.txt b/src/ElectromagnetismStreamTraceur/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9374ac2
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ElectromagnetismStreamTraceur)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ElectromagnetismStreamTraceur/plugin/CMakeLists.txt b/src/ElectromagnetismStreamTraceur/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4c90358
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Create an auto-start plugin. Auto start plugins provide callbacks that get
+# called when the plugin is loaded and when the application shutsdown.
+
+paraview_add_plugin(ElectromagnetismStreamTraceur
+  VERSION "1.0"
+  MODULES ElectromagnetismStreamTraceurFilters
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/StreamTraceurFilters/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ElectromagnetismStreamTraceur
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/CMakeLists.txt b/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7cac3e1
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkElectromagnetismStreamTraceur
+)
+
+vtk_module_add_module(ElectromagnetismStreamTraceurFilters
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtk.module b/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtk.module
new file mode 100644 (file)
index 0000000..fce280f
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismStreamTraceurFilters
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeometry
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::FiltersFlowPaths
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsFiltersGeneral
+  ParaView::VTKExtensionsMisc
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
+  VTK::IOInfovis
diff --git a/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.cxx b/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.cxx
new file mode 100644 (file)
index 0000000..7618934
--- /dev/null
@@ -0,0 +1,221 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkElectromagnetismStreamTraceur.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkNew.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkMultiBlockDataSet.h>
+#include "vtkStreamTracer.h"
+#include "vtkPointSource.h"
+#include "vtkPCellDataToPointData.h"
+
+#include "vtkCompositeDataIterator.h"
+#include "vtkCompositeInterpolatedVelocityField.h"
+#include "vtkCompositeDataPipeline.h"
+#include "vtkInterpolatedVelocityField.h"
+
+#include <vector>
+
+vtkObjectFactoryNewMacro(vtkElectromagnetismStreamTraceur);
+
+vtkElectromagnetismStreamTraceur::vtkElectromagnetismStreamTraceur():IntegrationDirection(BOTH),IntegratorType(RUNGE_KUTTA45),IntegrationStepUnit(2)
+,InitialIntegrationStep(0.2),TerminalSpeed(1e-12),MaximumError(1e-6),MaximumNumberOfSteps(2000)
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, vtkDataSetAttributes::VECTORS);
+}
+
+void vtkElectromagnetismStreamTraceur::SetSourceConnection(vtkAlgorithmOutput* algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+void vtkElectromagnetismStreamTraceur::SetSourceData(vtkDataSet* source)
+{
+  this->SetInputData(1, source);
+}
+
+vtkDataSet* vtkElectromagnetismStreamTraceur::GetSource()
+{
+  if (this->GetNumberOfInputConnections(1) < 1)
+  {
+    return nullptr;
+  }
+  return vtkDataSet::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
+}
+
+int vtkElectromagnetismStreamTraceur::SetupOutput(vtkInformation* inInfo, vtkInformation* outInfo)
+{
+  int piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
+  int numPieces = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
+
+  vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
+  vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
+
+  // Pass through field data
+  output->GetFieldData()->PassData(input->GetFieldData());
+
+  vtkCompositeDataSet* hdInput = vtkCompositeDataSet::SafeDownCast(input);
+  vtkDataSet* dsInput = vtkDataSet::SafeDownCast(input);
+  if (hdInput)
+  {
+    this->InputData = hdInput;
+    hdInput->Register(this);
+    return 1;
+  }
+  else if (dsInput)
+  {
+    vtkNew<vtkMultiBlockDataSet> mb;
+    mb->SetNumberOfBlocks(numPieces);
+    mb->SetBlock(piece, dsInput);
+    this->InputData = mb;
+    mb->Register(this);
+    return 1;
+  }
+  else
+  {
+    vtkErrorMacro(
+      "This filter cannot handle input of type: " << (input ? input->GetClassName() : "(none)"));
+    return 0;
+  }
+}
+
+int vtkElectromagnetismStreamTraceur::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  vtkDataArray* arr = nullptr;
+  vtkDataSet* input0 = nullptr;
+  if (!this->SetupOutput(inInfo, outInfo))
+  {
+    return 0;
+  }
+
+  vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0);
+  vtkDataSet* source = nullptr;
+  if (sourceInfo)
+  {
+    source = vtkDataSet::SafeDownCast(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+  }
+
+  vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkSmartPointer<vtkCompositeDataIterator> iterP;
+  iterP.TakeReference(this->InputData->NewIterator());
+
+  iterP->GoToFirstItem();
+  if (!iterP->IsDoneWithTraversal() && !input0)
+  {
+    input0 = vtkDataSet::SafeDownCast(iterP->GetCurrentDataObject());
+    iterP->GoToNextItem();
+  }
+
+  int vecType(0);
+  arr =  this->GetInputArrayToProcess(0, input0, vecType);
+  if(!arr)
+  {
+    vtkErrorMacro("No vector field selected in input !");
+    return 0;
+  }
+
+  vtkDataSet *input( vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())) );
+  const char *ArrayForGlyph(arr->GetName());
+  //
+  vtkNew<vtkPCellDataToPointData> cc;
+  cc->SetInputData(input0);
+  cc->SetProcessAllArrays(1);
+  cc->SetPassCellData(0);
+  cc->SetPieceInvariant(0);
+  cc->Update();
+  // Compute default Maximum Propagation
+  input0->ComputeBounds();
+  double james[6];
+  input0->GetBounds(james);
+  double dftMaxProp(std::min(std::min(james[1]-james[0],james[3]-james[2]),james[5]-james[4]));
+  //
+  vtkNew<vtkStreamTracer> streamTracer;
+  streamTracer->SetInputConnection(cc->GetOutputPort());
+  streamTracer->SetInterpolatorTypeToDataSetPointLocator();
+  streamTracer->SetIntegrationDirection(this->IntegrationDirection);
+  streamTracer->SetIntegratorType(this->IntegratorType);
+  streamTracer->SetIntegrationStepUnit(this->IntegrationStepUnit);// 2 <=> Cell Length
+  streamTracer->SetInitialIntegrationStep(this->InitialIntegrationStep);//initial step length
+  streamTracer->SetMinimumIntegrationStep(this->MinimumIntegrationStep);//Minimum Step Length
+  streamTracer->SetMaximumIntegrationStep(this->MaximumIntegrationStep);//Maximum Step Length
+  streamTracer->SetMaximumNumberOfSteps(this->MaximumNumberOfSteps);
+  streamTracer->SetMaximumError(this->MaximumError);
+  streamTracer->SetTerminalSpeed(this->TerminalSpeed);
+  streamTracer->SetMaximumPropagation(dftMaxProp);
+  streamTracer->SetSourceConnection(this->GetInputConnection(1,0));
+  streamTracer->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, ArrayForGlyph); // idx==0  -> Vector selected
+  streamTracer->Update();
+  output->ShallowCopy(streamTracer->GetOutput());
+  //
+  vtkDataArray *arrToBeUsedToColor(output->GetPointData()->GetArray(ArrayForGlyph));
+  vtkSmartPointer<vtkDataArray> arrColor(arrToBeUsedToColor->NewInstance());
+  arrColor->ShallowCopy(arrToBeUsedToColor);
+  arrColor->SetName(GetColorArrayName());
+  int idx(output->GetPointData()->AddArray(arrColor));
+  output->GetPointData()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
+  return 1;
+}
+
+const char vtkElectromagnetismStreamTraceur::NAME_COLOR_ARRAY[] = "Quantity To Display";
+
+const char *vtkElectromagnetismStreamTraceur::GetColorArrayName()
+{
+  return NAME_COLOR_ARRAY;
+}
+
+//------------------------------------------------------------------------------
+int vtkElectromagnetismStreamTraceur::FillInputPortInformation(int port, vtkInformation* info)
+{
+  if (port == 0)
+  {
+    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject");
+  }
+  else if (port == 1)
+  {
+    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
+    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+void vtkElectromagnetismStreamTraceur::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+//------------------------------------------------------------------------------
+vtkExecutive* vtkElectromagnetismStreamTraceur::CreateDefaultExecutive()
+{
+  return vtkCompositeDataPipeline::New();
+}
diff --git a/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.h b/src/ElectromagnetismStreamTraceur/plugin/StreamTraceurFilters/vtkElectromagnetismStreamTraceur.h
new file mode 100644 (file)
index 0000000..d59e1b0
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#pragma once
+
+#include "vtkFiltersFlowPathsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+#include "vtkInitialValueProblemSolver.h" // Needed for constants
+
+class vtkAbstractInterpolatedVelocityField;
+class vtkCompositeDataSet;
+class vtkDataArray;
+class vtkDataSetAttributes;
+class vtkDoubleArray;
+class vtkExecutive;
+class vtkGenericCell;
+class vtkIdList;
+class vtkIntArray;
+class vtkPoints;
+
+#include <vector>
+
+class VTK_EXPORT vtkElectromagnetismStreamTraceur : public vtkPolyDataAlgorithm
+{
+public:
+  enum
+  {
+    FORWARD,
+    BACKWARD,
+    BOTH
+  };
+
+    enum Solvers
+  {
+    RUNGE_KUTTA2,
+    RUNGE_KUTTA4,
+    RUNGE_KUTTA45,
+    NONE,
+    UNKNOWN
+  };
+
+
+  vtkTypeMacro(vtkElectromagnetismStreamTraceur, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  static vtkElectromagnetismStreamTraceur* New();
+
+
+  void SetSourceData(vtkDataSet* source);
+  vtkDataSet* GetSource();
+  void SetSourceConnection(vtkAlgorithmOutput* algOutput);
+
+  vtkSetClampMacro(IntegrationDirection, int, FORWARD, BOTH);
+  vtkGetMacro(IntegrationDirection, int);
+
+  void SetIntegratorType(int type) { IntegratorType=type; }
+  
+  void SetIntegrationStepUnit(int unit) { IntegrationStepUnit=unit; }
+  
+  vtkSetMacro(InitialIntegrationStep, double);
+  vtkGetMacro(InitialIntegrationStep, double);
+
+  vtkSetMacro(MinimumIntegrationStep, double);
+  vtkGetMacro(MinimumIntegrationStep, double);
+
+  vtkSetMacro(MaximumIntegrationStep, double);
+  vtkGetMacro(MaximumIntegrationStep, double);
+
+  vtkSetMacro(TerminalSpeed, double);
+  vtkGetMacro(TerminalSpeed, double);
+
+  vtkSetMacro(MaximumError, double);
+  vtkGetMacro(MaximumError, double);
+
+  vtkSetMacro(MaximumNumberOfSteps, vtkIdType);
+  vtkGetMacro(MaximumNumberOfSteps, vtkIdType);
+
+protected:
+  vtkElectromagnetismStreamTraceur();
+  ~vtkElectromagnetismStreamTraceur() override = default;
+  // Create a default executive.
+  vtkExecutive* CreateDefaultExecutive() override;
+  static const char *GetColorArrayName();
+  // hide the superclass' AddInput() from the user and the compiler
+  void AddInput(vtkDataObject*) { vtkErrorMacro(<< "AddInput() must be called with a vtkDataSet not a vtkDataObject."); }
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int FillInputPortInformation(int, vtkInformation*) override;
+
+  int SetupOutput(vtkInformation* inInfo, vtkInformation* outInfo);
+
+  vtkCompositeDataSet* InputData;
+private:
+  vtkElectromagnetismStreamTraceur(const vtkElectromagnetismStreamTraceur&) = delete;
+  void operator=(const vtkElectromagnetismStreamTraceur&) = delete;
+  static const char NAME_COLOR_ARRAY[];
+public:
+  int IntegrationDirection;
+  int IntegratorType;
+  int IntegrationStepUnit;
+  double InitialIntegrationStep; 
+  double MinimumIntegrationStep;
+  double MaximumIntegrationStep;
+  double TerminalSpeed;
+  double MaximumError;
+  vtkIdType MaximumNumberOfSteps;
+};
diff --git a/src/ElectromagnetismStreamTraceur/plugin/filters.xml b/src/ElectromagnetismStreamTraceur/plugin/filters.xml
new file mode 100644 (file)
index 0000000..e3cbb89
--- /dev/null
@@ -0,0 +1,204 @@
+<ServerManagerConfiguration>
+
+  <ProxyGroup name="filters">
+
+    <SourceProxy class="vtkElectromagnetismStreamTraceur"
+                 label=" Ligne De Champ"
+                 name="LigneDeChamp">
+      <Documentation long_help="Int."
+                     short_help="Int.">The
+                     Stream Tracer filter generates streamlines in a vector
+                     field from a colleces.
+      </Documentation>
+
+      <InputProperty clean_command="RemoveAllInputs"
+                     command="AddInputConnection"
+                     name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain composite_data_supported="1"
+                        name="input_type">
+          <DataType value="vtkDataSet" />
+        </DataTypeDomain>
+        <InputArrayDomain name="input_array"
+                          number_of_components="3" />
+        <Documentation>This property specifies the input to the Stream Tracer
+        filter.</Documentation>
+      </InputProperty>
+      <StringVectorProperty animateable="0"
+                            command="SetInputArrayToProcess"
+                            element_types="0 0 0 0 2"
+                            label="Vectors"
+                            name="SelectInputVectors"
+                            number_of_elements="5">
+        <ArrayListDomain attribute_type="Vectors"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>This property contains the name of the vector array from
+        which to generate streamlines.</Documentation>
+      </StringVectorProperty>
+
+      <InputProperty command="SetSourceConnection"
+                     label="Seed Type"
+                     name="Source"
+                     panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Group name="seed_sources"/>
+        </ProxyListDomain>
+        <Documentation>The value of this property determines how the seeds for
+        the streamlines will be generated.</Documentation>
+      </InputProperty>
+
+      <PropertyGroup label="Seeds">
+        <Property name="Source" />
+      </PropertyGroup>
+
+      <PropertyGroup label="Integration Parameters">
+        <Property name="IntegrationDirection" />
+        <Property name="IntegratorType" />
+        <Property name="IntegrationStepUnit" />
+        <Property name="InitialIntegrationStep" />
+        <Property name="MinimumIntegrationStep" />
+        <Property name="MaximumIntegrationStep" />
+        <Property name="MaximumError" />
+      </PropertyGroup>
+
+      <PropertyGroup label="Streamline Parameters" >
+        <Property name="MaximumNumberOfSteps" />
+        <Property name="MaximumPropagation" />
+        <Property name="TerminalSpeed" />
+      </PropertyGroup>
+
+
+
+      <IntVectorProperty command="SetIntegrationDirection"
+                         default_values="2"
+                         name="IntegrationDirection"
+                         number_of_elements="1">
+        <EnumerationDomain name="enum">
+          <Entry text="FORWARD"
+                 value="0" />
+          <Entry text="BACKWARD"
+                 value="1" />
+          <Entry text="BOTH"
+                 value="2" />
+        </EnumerationDomain>
+        <Documentation>This property determines in which direction(s) a
+        streamline is generated.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetIntegratorType"
+                         default_values="2"
+                         name="IntegratorType"
+                         number_of_elements="1">
+        <EnumerationDomain name="enum">
+          <Entry text="Runge-Kutta 2"
+                 value="0" />
+          <Entry text="Runge-Kutta 4"
+                 value="1" />
+          <Entry text="Runge-Kutta 4-5"
+                 value="2" />
+        </EnumerationDomain>
+        <Documentation>This property determines which integrator (with
+        increasing accuracy) to use for creating streamlines.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetIntegrationStepUnit"
+                         default_values="2"
+                         label="Integration Step Unit"
+                         name="IntegrationStepUnit"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <EnumerationDomain name="enum">
+          <Entry text="Length"
+                 value="1" />
+          <Entry text="Cell Length"
+                 value="2" />
+        </EnumerationDomain>
+        <Documentation>This property specifies the unit for
+        Minimum/Initial/Maximum integration step size. The Length unit refers
+        to the arc length that a particle travels/advects within a single step.
+        The Cell Length unit represents the step size as a number of
+        cells.</Documentation>
+      </IntVectorProperty>
+      <DoubleVectorProperty command="SetInitialIntegrationStep"
+                            default_values="0.2"
+                            label="Initial Step Length"
+                            name="InitialIntegrationStep"
+                            number_of_elements="1"
+                            panel_visibility="advanced" >
+        <DoubleRangeDomain name="range" />
+        <Documentation>This property specifies the initial integration step
+        size. For non-adaptive integrators (Runge-Kutta 2 and Runge-Kutta 4),
+        it is fixed (always equal to this initial value) throughout the
+        integration. For an adaptive integrator (Runge-Kutta 4-5), the actual
+        step size varies such that the numerical error is less than a specified
+        threshold.</Documentation>
+      </DoubleVectorProperty>
+      <DoubleVectorProperty command="SetMinimumIntegrationStep"
+                            default_values="0.01"
+                            label="Minimum Step Length"
+                            name="MinimumIntegrationStep"
+                            number_of_elements="1"
+                            panel_visibility="advanced" >
+        <DoubleRangeDomain name="range" />
+        <Documentation>When using the Runge-Kutta 4-5 integrator, this property
+        specifies the minimum integration step size.</Documentation>
+      </DoubleVectorProperty>
+      <DoubleVectorProperty command="SetMaximumIntegrationStep"
+                            default_values="0.5"
+                            label="Maximum Step Length"
+                            name="MaximumIntegrationStep"
+                            number_of_elements="1"
+                            panel_visibility="advanced">
+        <DoubleRangeDomain name="range" />
+        <Documentation>When using the Runge-Kutta 4-5 integrator, this property
+        specifies the maximum integration step size.</Documentation>
+      </DoubleVectorProperty>
+      <IntVectorProperty command="SetMaximumNumberOfSteps"
+                         default_values="2000"
+                         label="Maximum Steps"
+                         name="MaximumNumberOfSteps"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <IntRangeDomain name="range" />
+        <Documentation>This property specifies the maximum number of steps,
+        beyond which streamline integration is terminated.</Documentation>
+      </IntVectorProperty>
+      <DoubleVectorProperty command="SetTerminalSpeed"
+                            default_values="0.000000000001"
+                            label="Terminal Speed"
+                            name="TerminalSpeed"
+                            number_of_elements="1"
+                            panel_visibility="advanced" >
+        <DoubleRangeDomain name="range" />
+        <Documentation>This property specifies the terminal speed, below which
+        particle advection/integration is terminated.</Documentation>
+      </DoubleVectorProperty>
+      <DoubleVectorProperty command="SetMaximumError"
+                            default_values="0.000001"
+                            name="MaximumError"
+                            number_of_elements="1"
+                            panel_visibility="advanced" >
+        <DoubleRangeDomain name="range" />
+        <Documentation>This property specifies the maximum error (for
+        Runge-Kutta 4-5) tolerated throughout streamline integration. The
+        Runge-Kutta 4-5 integrator tries to adjust the step size such that the
+        estimated error is less than this threshold.</Documentation>
+      </DoubleVectorProperty>
+
+      <Hints>
+        <RepresentationType view="RenderView" type="Wireframe"/>
+        <ShowInMenu category="Electromagnetism" />
+        <Visibility replace_input="2" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ElectromagnetismStreamTraceur/plugin/paraview.plugin b/src/ElectromagnetismStreamTraceur/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..019d0a5
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismStreamTraceur
+DESCRIPTION
+  This plugin provides ...
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  VTK::FiltersGeneral
+  VTK::FiltersFlowPaths
+  VTK::FiltersFlowPaths
\ No newline at end of file
diff --git a/src/ElectromagnetismStreamTraceur/scripts/generate.py b/src/ElectromagnetismStreamTraceur/scripts/generate.py
new file mode 100644 (file)
index 0000000..e340760
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+
+arr = DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10])
+m = MEDCouplingCMesh()
+m.setCoords(arr,arr,arr)
+m = m.buildUnstructured()
+#m.simplexize(0)
+m.changeSpaceDimension(3,0.)
+m.setName("mesh")
+f = MEDCouplingFieldDouble(ON_CELLS)
+f.setMesh(m)
+f.setName("field")
+arrf = DataArrayDouble(10*10*10,3)
+arrf[:,0] = 1 ; arrf[:,1] = 0 ; arrf[:,2] = 0
+f.setArray( arrf )
+f.getArray().setInfoOnComponents(["X","Y","Z"])
+f.checkConsistencyLight()
+f.write("test.med")
+f2 = f.deepCopy()
+arrf2 = DataArrayDouble(10*10*10,3)
+arrf2[:,0] = 0 ; arrf2[:,1] = 1 ; arrf2[:,2] = 0
+f2.setArray( arrf2 )
+f2.setName("field2")
+WriteFieldUsingAlreadyWrittenMesh("test.med",f2)
diff --git a/src/ElectromagnetismStreamTraceur/scripts/test_stream.py b/src/ElectromagnetismStreamTraceur/scripts/test_stream.py
new file mode 100644 (file)
index 0000000..7d76a70
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from paraview.simple import *
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+def MyAssert(clue):
+    if not clue:
+        raise RuntimeError("Assertion failed !")
+
+testmed = MEDReader(FileName='test.med')
+testmed.AllArrays = ['TS0/mesh/ComSup0/field@@][@@P0', 'TS0/mesh/ComSup0/field2@@][@@P0', 'TS0/mesh/ComSup0/mesh@@][@@P0']
+testmed.AllTimeSteps = ['0000']
+streamTraceur1 = LigneDeChamp(Input=testmed,SeedType='Point Source')
+streamTraceur1.SeedType.Radius = 1
+streamTraceur1.SeedType.Center = [ 7.23,7.26,3.42 ]
+streamTraceur1.Vectors = ['CELLS', "field"] #OrientationArray
+streamTraceur1.UpdatePipeline()
+ds0 = servermanager.Fetch(streamTraceur1)
+MyAssert(ds0.GetNumberOfCells()==200)
diff --git a/src/ElectromagnetismVecteur/CMakeLists.txt b/src/ElectromagnetismVecteur/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fc12318
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ElectromagnetismVecteur)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ElectromagnetismVecteur/plugin/CMakeLists.txt b/src/ElectromagnetismVecteur/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..76ef1e2
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(ElectromagnetismVecteur
+  VERSION "1.0"
+  MODULES ElectromagnetismVecteurFilters
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/VecteurFilters/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ElectromagnetismVecteur
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ElectromagnetismVecteur/plugin/VecteurFilters/CMakeLists.txt b/src/ElectromagnetismVecteur/plugin/VecteurFilters/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c6b5b87
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkElectromagnetismVecteur
+)
+
+vtk_module_add_module(ElectromagnetismVecteurFilters
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtk.module b/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtk.module
new file mode 100644 (file)
index 0000000..7a18930
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismVecteurFilters
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeometry
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsFiltersGeneral
+  ParaView::VTKExtensionsMisc
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
+  VTK::IOInfovis
diff --git a/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.cxx b/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.cxx
new file mode 100644 (file)
index 0000000..3590898
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkElectromagnetismVecteur.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkNew.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkCellCenters.h>
+#include <vtkGlyphSource2D.h>
+
+//-----------------------------------------------------------------------------
+vtkStandardNewMacro(vtkElectromagnetismVecteur);
+
+const char vtkElectromagnetismVecteur::NAME_COLOR_ARRAY[] = "Quantity To Display";
+
+const char *vtkElectromagnetismVecteur::GetColorArrayName()
+{
+  return NAME_COLOR_ARRAY;
+}
+
+ vtkElectromagnetismVecteur::vtkElectromagnetismVecteur():GlyphMode(ALL_POINTS)
+  , MaximumNumberOfSamplePoints(5000)
+  , Seed(1)
+  , Stride(1)
+  {
+  }
+
+// general_filters.xml : 1670
+//-----------------------------------------------------------------------------
+int vtkElectromagnetismVecteur::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  
+  vtkDataArray *arr(this->GetInputArrayToProcess(1,inputVector));
+  if(!arr)
+  {
+    vtkErrorMacro("No vector field selected in input !");
+    return 0;
+  }
+  vtkInformation *inInfo( inputVector[0]->GetInformationObject(0) );
+  vtkDataSet *input( vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())) );
+  const char *ArrayForGlyph(arr->GetName());
+  vtkInformation *outInfo(outputVector->GetInformationObject(0));
+  vtkPolyData *output(vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+  //
+  vtkNew<vtkCellCenters> cc;
+  cc->SetInputData(input);
+  cc->Update();
+  //
+  vtkNew<vtkPVGlyphFilter> glyph;
+  glyph->SetInputConnection(cc->GetOutputPort());
+  glyph->SetGlyphMode(this->GlyphMode);       // vtkPVGlyphFilter::ALL_POINTS
+  glyph->SetMaximumNumberOfSamplePoints(this->MaximumNumberOfSamplePoints);
+  glyph->SetSeed(this->Seed);
+  glyph->SetStride(this->Stride);
+  glyph->SetVectorScaleMode(0); // vtkPVGlyphFilter::SCALE_BY_MAGNITUDE
+  //
+  vtkNew<vtkGlyphSource2D> arrow;
+  arrow->SetGlyphTypeToArrow();
+  arrow->SetFilled(false);
+  glyph->SetSourceConnection(arrow->GetOutputPort());
+  // idx,port,connection,fieldAssociation,name
+  glyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, ""); // idx==0 -> scaleArray. "" means no scale array
+  glyph->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, ArrayForGlyph); // idx==1 -> orientationArray
+  glyph->SetScaleFactor(this->ScaleFactor);
+  //
+  glyph->Update();
+  //
+  output->ShallowCopy(glyph->GetOutput());
+  //
+  vtkDataArray *arrToBeUsedToColor(output->GetPointData()->GetArray(ArrayForGlyph));
+  vtkSmartPointer<vtkDataArray> arrColor(arrToBeUsedToColor->NewInstance());
+  arrColor->ShallowCopy(arrToBeUsedToColor);
+  arrColor->SetName(GetColorArrayName());
+  int idx(output->GetPointData()->AddArray(arrColor));
+  output->GetPointData()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+void vtkElectromagnetismVecteur::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.h b/src/ElectromagnetismVecteur/plugin/VecteurFilters/vtkElectromagnetismVecteur.h
new file mode 100644 (file)
index 0000000..47f9824
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkElectromagnetismVecteur_h__
+#define __vtkElectromagnetismVecteur_h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+#include <vtkSmartPointer.h>
+
+#include <string>
+#include <vector>
+
+class vtkDoubleArray;
+class vtkUnstructuredGrid;
+
+class VTK_EXPORT vtkElectromagnetismVecteur : public vtkPolyDataAlgorithm
+{
+public:
+  enum GlyphModeType
+  {
+    ALL_POINTS,
+    EVERY_NTH_POINT,
+    SPATIALLY_UNIFORM_DISTRIBUTION,
+    SPATIALLY_UNIFORM_INVERSE_TRANSFORM_SAMPLING_SURFACE,
+    SPATIALLY_UNIFORM_INVERSE_TRANSFORM_SAMPLING_VOLUME
+  };
+public:
+  static vtkElectromagnetismVecteur* New();
+  vtkTypeMacro(vtkElectromagnetismVecteur, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  vtkGetMacro(ScaleFactor, double);
+  vtkSetMacro(ScaleFactor, double);
+
+  vtkSetClampMacro(GlyphMode, int, ALL_POINTS, SPATIALLY_UNIFORM_INVERSE_TRANSFORM_SAMPLING_VOLUME);
+  vtkGetMacro(GlyphMode, int);
+
+  vtkSetClampMacro(Stride, int, 1, VTK_INT_MAX);
+  vtkGetMacro(Stride, int);
+
+  vtkSetMacro(Seed, int);
+  vtkGetMacro(Seed, int);
+
+  vtkSetClampMacro(MaximumNumberOfSamplePoints, int, 1, VTK_INT_MAX);
+  vtkGetMacro(MaximumNumberOfSamplePoints, int);
+
+protected:
+  vtkElectromagnetismVecteur();
+  ~vtkElectromagnetismVecteur() override = default;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  static const char *GetColorArrayName();
+
+  double ScaleFactor;
+
+  int GlyphMode;
+  int MaximumNumberOfSamplePoints;
+  int Seed;
+  int Stride;
+
+private:
+  vtkElectromagnetismVecteur(const vtkElectromagnetismVecteur&) = delete;
+  void operator=(const vtkElectromagnetismVecteur&) = delete;
+
+  static const char NAME_COLOR_ARRAY[];
+};
+
+#endif
diff --git a/src/ElectromagnetismVecteur/plugin/filters.xml b/src/ElectromagnetismVecteur/plugin/filters.xml
new file mode 100644 (file)
index 0000000..9877144
--- /dev/null
@@ -0,0 +1,163 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy class="vtkElectromagnetismVecteur"
+                 name="Vecteur">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid"/>
+        </DataTypeDomain>
+
+        <InputArrayDomain name="vector_array"
+                          number_of_components="3"
+                          optional="1" />
+
+        <Documentation short_help= "Affiche les vecteurs sur champ aux cellules."
+                       long_help = "Affiche les vecteurs sur champ aux cellules.">
+        </Documentation>
+      </InputProperty>
+      <DoubleVectorProperty command="SetScaleFactor"
+                            default_values="1.0"
+                            name="ScaleFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <BoundsDomain mode="scaled_extent" name="bounds" scale_factor="0.1">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+          </RequiredProperties>
+        </BoundsDomain>
+        <ArrayRangeDomain name="scalar_range">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="ArraySelection" name="ScaleArray" />
+          </RequiredProperties>
+        </ArrayRangeDomain>
+        <ArrayRangeDomain name="vector_range">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="ArraySelection" name="OrientationArray" />
+          </RequiredProperties>
+        </ArrayRangeDomain>
+        <Documentation>This property specifies the scale factor applied to the length of arrow.
+        </Documentation>
+      </DoubleVectorProperty>
+
+      <IntVectorProperty command="SetGlyphMode"
+                         default_values="0"
+                         name="GlyphMode"
+                         number_of_elements="1"
+                         panel_visibility="default">
+        <EnumerationDomain name="enum">
+          <Entry text="All Points" value="0"/>
+          <Entry text="Every Nth Point" value="1"/>
+          <Entry text="Uniform Spatial Distribution (Bounds Based)" value="2"/>
+          <Entry text="Uniform Spatial Distribution (Surface Sampling)" value="3"/>
+          <Entry text="Uniform Spatial Distribution (Volume Sampling)" value="4"/>
+        </EnumerationDomain>
+        <Documentation>
+This property indicates the mode that will be used to generate
+glyphs from the dataset.
+        </Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetMaximumNumberOfSamplePoints"
+                        number_of_elements="1"
+                        default_values="5000"
+                        name="MaximumNumberOfSamplePoints">
+        <IntRangeDomain min="1" name="range" />
+        <Documentation>
+This property specifies the maximum number of sample points to use
+when sampling the space when Uniform Spatial Distribution is used.
+        </Documentation>
+        <Hints>
+          <PropertyWidgetDecorator type="CompositeDecorator">
+            <Expression type="or">
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="2" inverse="0" />
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="3" inverse="0" />
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="4" inverse="0" />
+            </Expression>
+          </PropertyWidgetDecorator>
+          <!-- show this widget when GlyphMode==2||3||4 -->
+        </Hints>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetSeed"
+                        number_of_elements="1"
+                        default_values="10339"
+                        name="Seed">
+        <IntRangeDomain min="1" name="range"/>
+        <Documentation>
+This property specifies the seed that will be used for generating a
+uniform distribution of glyph points when a Uniform Spatial
+Distribution is used.
+        </Documentation>
+        <Hints>
+          <PropertyWidgetDecorator type="CompositeDecorator">
+            <Expression type="or">
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="2" inverse="0" />
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="3" inverse="0" />
+              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="4" inverse="0" />
+            </Expression>
+          </PropertyWidgetDecorator>
+          <!-- show this widget when GlyphMode==2||3||4 -->
+        </Hints>
+      </IntVectorProperty>
+
+      <IntVectorProperty command="SetStride"
+                         number_of_elements="1"
+                         default_values="1"
+                         name="Stride">
+        <IntRangeDomain min="1" name="range"/>
+        <Documentation>
+This property specifies the stride that will be used when glyphing by
+Every Nth Point.
+        </Documentation>
+        <Hints>
+          <PropertyWidgetDecorator type="GenericDecorator"
+                                   mode="visibility"
+                                   property="GlyphMode"
+                                   value="1" />
+          <!-- show this widget when GlyphMode==1 -->
+        </Hints>
+     </IntVectorProperty>
+
+      <StringVectorProperty command="SetInputArrayToProcess"
+                            default_values="1"
+                            element_types="0 0 0 0 2"
+                            name="OrientationArray"
+                            number_of_elements="5">
+        <!-- default value=1 so normals go to the right place -->
+        <ArrayListDomain attribute_type="Vectors"
+                         input_domain_name="vector_array"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>
+Select the input array to use for orienting the glyphs.
+        </Documentation>
+      </StringVectorProperty>
+      
+    <StringVectorProperty
+        name="ColorArrayName"
+        command="GetColorArrayName"
+        number_of_elements="1"
+        animateable="0"
+        information_only="1">
+        <Documentation>
+          This readonly property gives the name of array used to color the default active array for auto selection for Color in render view.
+        </Documentation>
+      </StringVectorProperty>
+
+      <Hints>
+        <RepresentationType view="RenderView" type="Wireframe"/>
+        <ShowInMenu category="Electromagnetism" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ElectromagnetismVecteur/plugin/paraview.plugin b/src/ElectromagnetismVecteur/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..55390f7
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ElectromagnetismVecteur
+DESCRIPTION
+  This plugin provides ...
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/ElectromagnetismVecteur/scripts/generate.py b/src/ElectromagnetismVecteur/scripts/generate.py
new file mode 100644 (file)
index 0000000..bf04b7c
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+
+arr = DataArrayDouble([0,1,2])
+m = MEDCouplingCMesh()
+m.setCoords(arr,arr)
+m = m.buildUnstructured()
+#m.simplexize(0)
+m.changeSpaceDimension(3,0.)
+m.setName("mesh")
+f = MEDCouplingFieldDouble(ON_CELLS)
+f.setMesh(m)
+f.setName("field")
+f.setArray( DataArrayDouble([(1,1,0), (2,-2,0), (-3,3,0), (-4,-4,0)]) )
+f.getArray().setInfoOnComponents(["X","Y","Z"])
+f.checkConsistencyLight()
+f.write("test.med")
+f2 = f.deepCopy()
+f2.setArray( DataArrayDouble([(1,0,0), (0,-2,0), (-3,0,0), (0,4,0)]) )
+f2.setName("field2")
+WriteFieldUsingAlreadyWrittenMesh("test.med",f2)
diff --git a/src/ExtractComponentsPlugin/CMakeLists.txt b/src/ExtractComponentsPlugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b7e553a
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ExtractComponents)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ExtractComponentsPlugin/ExtractCompo.med b/src/ExtractComponentsPlugin/ExtractCompo.med
new file mode 100644 (file)
index 0000000..48a5f4a
Binary files /dev/null and b/src/ExtractComponentsPlugin/ExtractCompo.med differ
diff --git a/src/ExtractComponentsPlugin/plugin/CMakeLists.txt b/src/ExtractComponentsPlugin/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..02352c6
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(interfaces)
+set(sources)
+if(PARAVIEW_USE_QT)
+  paraview_plugin_add_property_widget(
+    KIND        WIDGET
+    TYPE        LinkedLineEdit
+    CLASS_NAME  pqLinkedLineEdit
+    INTERFACES  interfaces
+    SOURCES     sources
+  )
+  list(APPEND sources
+    pqLinkedLineEdit.cxx
+    pqLinkedLineEdit.h
+  )
+endif()
+
+paraview_add_plugin(ExtractComponents
+  VERSION "1.0"
+  UI_INTERFACES ${interfaces}
+  SOURCES ${sources}
+  MODULES ExtractComponentsModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ExtractComponentsModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ExtractComponents
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/CMakeLists.txt b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..016b7ae
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkExtractComponents
+  vtkSMMyNumberOfComponentsDomain
+)
+
+vtk_module_add_module(ExtractComponentsModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtk.module b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtk.module
new file mode 100644 (file)
index 0000000..ccec980
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ExtractComponentsModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  ParaView::RemotingCore
+  ParaView::RemotingServerManager
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.cxx b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.cxx
new file mode 100644 (file)
index 0000000..b253bde
--- /dev/null
@@ -0,0 +1,206 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkExtractComponents.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+#include "vtkExtractComponents.h"
+
+#include <vtkCellData.h>
+#include <vtkDataArray.h>
+#include <vtkDataSet.h>
+#include <vtkFieldData.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkSmartPointer.h>
+#ifdef WIN32
+ #define NOMINMAX
+ #include <algorithm>
+#endif
+
+vtkStandardNewMacro(vtkExtractComponents);
+
+//----------------------------------------------------------------------------
+vtkExtractComponents::vtkExtractComponents()
+{
+}
+
+//----------------------------------------------------------------------------
+vtkExtractComponents::~vtkExtractComponents()
+{
+  this->SetOutputArrayName(nullptr);
+  this->ClearComponents();
+}
+
+//----------------------------------------------------------------------------
+int vtkExtractComponents::FillInputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
+  return 1;
+}
+
+void vtkExtractComponents::SetGenerateVector(bool gvs)
+{
+  if (_gvs != gvs)
+  {
+    _gvs = gvs;
+    this->Modified();
+  }
+}
+
+//----------------------------------------------------------------------------
+int vtkExtractComponents::RequestData(vtkInformation *vtkNotUsed(request),
+                                      vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  // get the output info object
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+  vtkDataSet *output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkDataSet *input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  output->ShallowCopy(input);
+
+  vtkDataArray *inputArray = this->GetInputArrayToProcess(0, inputVector);
+  vtkInformation *info = this->GetInputArrayInformation(0);
+  int fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_POINTS;
+  if (info && info->Has(vtkDataObject::FIELD_ASSOCIATION()))
+  {
+    fieldAssociation = info->Get(vtkDataObject::FIELD_ASSOCIATION());
+  }
+
+  if (!inputArray)
+  {
+    vtkErrorMacro(<< "No data to extract");
+    return 0;
+  }
+
+  if (this->InputArrayComponents.size() == 0)
+  {
+    return 1;
+  }
+
+  std::set<int>::const_iterator it = this->InputArrayComponents.begin();
+  for (; it != this->InputArrayComponents.end(); ++it)
+  {
+    if (*it >= inputArray->GetNumberOfComponents() || *it < 0)
+    {
+      vtkErrorMacro(<< "Invalid component");
+      return 0;
+    }
+  }
+
+  if (!this->OutputArrayName)
+  {
+    vtkErrorMacro(<< "No output array name");
+    return 0;
+  }
+
+  vtkSmartPointer<vtkDataArray> outputArray = inputArray->NewInstance();
+  outputArray->SetName(this->OutputArrayName);
+  int nbCompo(_gvs ? 3 : this->InputArrayComponents.size());
+  outputArray->SetNumberOfComponents(nbCompo);
+  outputArray->SetNumberOfTuples(inputArray->GetNumberOfTuples());
+  outputArray->CopyInformation(input->GetInformation());
+
+  it = this->InputArrayComponents.begin();
+  int imax(-1);
+  for (int i = 0; it != this->InputArrayComponents.end(); ++it, i++)
+  {
+    if (!_gvs || i < 3)
+    {
+      imax = i;
+      outputArray->CopyComponent(i, inputArray, *it);
+      outputArray->SetComponentName(i, inputArray->GetComponentName(*it));
+    }
+  }
+  if (_gvs)
+  {
+    for (int i = imax + 1; i < 3; i++)
+    {
+      vtkSmartPointer<vtkDataArray> tmpArray = inputArray->NewInstance();
+      tmpArray->SetNumberOfComponents(1);
+      tmpArray->SetNumberOfTuples(inputArray->GetNumberOfTuples());
+      tmpArray->Fill(0.);
+      outputArray->CopyComponent(i, tmpArray, 0);
+    }
+    imax = 3;
+  }
+  imax = std::max(0, imax);
+  if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
+  {
+    std::cerr << output->GetPointData()->GetNumberOfArrays() << std::endl;
+    int idx(output->GetPointData()->AddArray(outputArray));
+    output->GetPointData()->SetActiveAttribute(idx, imax > 1 ? vtkDataSetAttributes::VECTORS : vtkDataSetAttributes::SCALARS);
+  }
+  else if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_CELLS)
+  {
+    int idx(output->GetCellData()->AddArray(outputArray));
+    output->GetCellData()->SetActiveAttribute(idx, imax > 1 ? vtkDataSetAttributes::VECTORS : vtkDataSetAttributes::SCALARS);
+  }
+  else if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_NONE)
+  {
+    output->GetFieldData()->AddArray(outputArray);
+  }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractComponents::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+
+  os << indent << "InputArrayComponents: ";
+  std::set<int>::iterator it;
+  for (it = this->InputArrayComponents.begin(); it != this->InputArrayComponents.end(); ++it)
+  {
+    os << *it << " ";
+  }
+  os << std::endl;
+
+  os << indent << "OutputArrayName: " << this->OutputArrayName << endl;
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractComponents::AddComponent(int component)
+{
+  this->InputArrayComponents.insert(component);
+  this->Modified();
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractComponents::ClearComponents()
+{
+  this->InputArrayComponents.clear();
+  this->Modified();
+}
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.h b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkExtractComponents.h
new file mode 100644 (file)
index 0000000..8260935
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkExtractComponents.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkExtractComponents
+ * @brief   Extract a component of an attribute.
+ *
+ * vtkExtractComponents Extract a component of an attribute.
+*/
+
+#ifndef vtkExtractComponents_h
+#define vtkExtractComponents_h
+
+#include <vtkDataSetAlgorithm.h>
+
+#include <set>
+
+class VTK_EXPORT vtkExtractComponents : public vtkDataSetAlgorithm
+{
+public:
+  static vtkExtractComponents *New();
+  vtkTypeMacro(vtkExtractComponents, vtkDataSetAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  void AddComponent(int);
+  void ClearComponents();
+
+  vtkSetStringMacro(OutputArrayName);
+  vtkGetStringMacro(OutputArrayName);
+
+  void SetGenerateVector(bool gvs);
+
+protected:
+  vtkExtractComponents();
+  ~vtkExtractComponents() override;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+
+  virtual int FillInputPortInformation(int port, vtkInformation *info) override;
+
+  std::set<int> InputArrayComponents;
+  char *OutputArrayName = nullptr;
+  bool _gvs = false;
+
+private:
+  vtkExtractComponents(const vtkExtractComponents &) = delete;
+  void operator=(const vtkExtractComponents &) = delete;
+};
+
+#endif
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.cxx b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.cxx
new file mode 100644 (file)
index 0000000..c24bc34
--- /dev/null
@@ -0,0 +1,198 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkSMMyNumberOfComponentsDomain.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+#include "vtkSMMyNumberOfComponentsDomain.h"
+
+#include <vtkObjectFactory.h>
+#include <vtkPVArrayInformation.h>
+#include <vtkPVDataInformation.h>
+#include <vtkPVDataSetAttributesInformation.h>
+#include <vtkSMDomainIterator.h>
+#include <vtkSMInputArrayDomain.h>
+#include <vtkSMInputProperty.h>
+#include <vtkSMSourceProxy.h>
+#include <vtkSMStringVectorProperty.h>
+
+#include <sstream>
+
+vtkStandardNewMacro(vtkSMMyNumberOfComponentsDomain);
+//----------------------------------------------------------------------------
+vtkSMMyNumberOfComponentsDomain::vtkSMMyNumberOfComponentsDomain()
+{
+}
+
+//----------------------------------------------------------------------------
+vtkSMMyNumberOfComponentsDomain::~vtkSMMyNumberOfComponentsDomain()
+{
+}
+
+//----------------------------------------------------------------------------
+void vtkSMMyNumberOfComponentsDomain::Update(vtkSMProperty*)
+{
+  vtkSMProxyProperty* ip = vtkSMProxyProperty::SafeDownCast(this->GetRequiredProperty("Input"));
+  vtkSMStringVectorProperty* svp =
+    vtkSMStringVectorProperty::SafeDownCast(this->GetRequiredProperty("ArraySelection"));
+  if (!ip || !svp)
+  {
+    // Missing required properties.
+    this->RemoveAllEntries();
+    this->DomainModified();
+    return;
+  }
+
+ /* if (svp->GetNumberOfUncheckedElements() != 5 && svp->GetNumberOfUncheckedElements() != 2 &&
+    svp->GetNumberOfUncheckedElements() != 1)
+  {
+    // We can only handle array selection properties with 5, 2 or 1 elements.
+    // For 5 elements the array name is at indices [4]; for 2
+    // elements it's at [1], while for 1 elements, it's at [0].
+    this->RemoveAllEntries();
+    return;
+  }*/
+
+  int index = svp->GetNumberOfUncheckedElements() - 1;
+  const char* arrayName = svp->GetUncheckedElement(index);
+  int arrayType = atoi(svp->GetUncheckedElement(index - 1));
+  if (!arrayName || arrayName[0] == 0)
+  {
+    // No array choosen.
+    this->RemoveAllEntries();
+    this->DomainModified();
+    return;
+  }
+
+  vtkSMInputArrayDomain* iad = nullptr;
+  vtkSMDomainIterator* di = ip->NewDomainIterator();
+  di->Begin();
+  while (!di->IsAtEnd())
+  {
+    // We have to figure out whether we are working with cell data,
+    // point data or both.
+    iad = vtkSMInputArrayDomain::SafeDownCast(di->GetDomain());
+    if (iad)
+    {
+      break;
+    }
+    di->Next();
+  }
+  di->Delete();
+  if (!iad)
+  {
+    // Failed to locate a vtkSMInputArrayDomain on the input property, which is
+    // required.
+    this->RemoveAllEntries();
+    this->DomainModified();
+    return;
+  }
+
+  vtkSMInputProperty* inputProp = vtkSMInputProperty::SafeDownCast(ip);
+  unsigned int numProxs = ip->GetNumberOfUncheckedProxies();
+  for (unsigned int i = 0; i < numProxs; i++)
+  {
+    // Use the first input
+    vtkSMSourceProxy* source = vtkSMSourceProxy::SafeDownCast(ip->GetUncheckedProxy(i));
+    if (source)
+    {
+      this->Update(arrayName, arrayType, source, iad,
+        (inputProp ? inputProp->GetUncheckedOutputPortForConnection(i) : 0));
+      return;
+    }
+  }
+}
+
+//---------------------------------------------------------------------------
+void vtkSMMyNumberOfComponentsDomain::Update(
+  const char* arrayName, int arrayType, vtkSMSourceProxy* sp,
+  vtkSMInputArrayDomain* iad, int outputport)
+{
+  // Make sure the outputs are created.
+  sp->CreateOutputPorts();
+  this->RemoveAllEntries();
+  vtkPVDataInformation* info = sp->GetDataInformation(outputport);
+  if (!info)
+  {
+    this->DomainModified();
+    return;
+  }
+
+  vtkPVArrayInformation* ai = 0;
+  if (arrayType == vtkDataObject::FIELD_ASSOCIATION_POINTS)
+  {
+    ai = info->GetPointDataInformation()->GetArrayInformation(arrayName);
+  }
+  else if (arrayType == vtkDataObject::FIELD_ASSOCIATION_CELLS)
+  {
+    ai = info->GetCellDataInformation()->GetArrayInformation(arrayName);
+  }
+  else if (arrayType == vtkDataObject::FIELD_ASSOCIATION_VERTICES)
+  {
+    ai = info->GetVertexDataInformation()->GetArrayInformation(arrayName);
+  }
+  else if (arrayType == vtkDataObject::FIELD_ASSOCIATION_EDGES)
+  {
+    ai = info->GetEdgeDataInformation()->GetArrayInformation(arrayName);
+  }
+  else if (arrayType == vtkDataObject::FIELD_ASSOCIATION_ROWS)
+  {
+    ai = info->GetRowDataInformation()->GetArrayInformation(arrayName);
+  }
+  else if (arrayType == vtkDataObject::FIELD_ASSOCIATION_NONE)
+  {
+    ai = info->GetFieldDataInformation()->GetArrayInformation(arrayName);
+  }
+
+  if (ai)
+  {
+    for (int i = 0; i < ai->GetNumberOfComponents(); i++)
+    {
+      const char* name = ai->GetComponentName(i);
+      std::ostringstream cname;
+      if (!name || name[0] == 0)
+      {
+        cname << i;
+      }
+      else
+      {
+        cname << name;
+      }
+      this->AddEntry(cname.str().c_str(), i);
+    }
+  }
+  this->DomainModified();
+}
+
+//----------------------------------------------------------------------------
+void vtkSMMyNumberOfComponentsDomain::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.h b/src/ExtractComponentsPlugin/plugin/ExtractComponentsModule/vtkSMMyNumberOfComponentsDomain.h
new file mode 100644 (file)
index 0000000..1b7db9b
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkSMMyNumberOfComponentsDomain.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkSMMyNumberOfComponentsDomain
+ * @brief   int range domain based on the number of
+ * components available in a particular data array.
+ *
+ * vtkSMMyNumberOfComponentsDomain is used for properties that allow the user to
+ * choose the component number (or associated name) to process for the choosen array.
+ * It needs two required properties with following functions:
+ * * Input -- input property for the filter.
+ * * ArraySelection -- string vector property used to select the array.
+ * This domain will not work if either of the required properties is missing.
+*/
+
+#ifndef vtkSMMyNumberOfComponentsDomain_h
+#define vtkSMMyNumberOfComponentsDomain_h
+
+#include <vtkSMEnumerationDomain.h>
+
+class vtkSMSourceProxy;
+class vtkSMInputArrayDomain;
+
+class VTK_EXPORT vtkSMMyNumberOfComponentsDomain : public vtkSMEnumerationDomain
+{
+public:
+  static vtkSMMyNumberOfComponentsDomain* New();
+  vtkTypeMacro(vtkSMMyNumberOfComponentsDomain, vtkSMEnumerationDomain);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  /**
+   * Updates the range based on the scalar range of the currently selected
+   * array. This requires Input (vtkSMProxyProperty) and ArraySelection
+   * (vtkSMStringVectorProperty) properties. Currently, this uses
+   * only the first component of the array.
+   */
+  virtual void Update(vtkSMProperty* prop);
+
+protected:
+  vtkSMMyNumberOfComponentsDomain();
+  ~vtkSMMyNumberOfComponentsDomain() override;
+
+  /**
+   * Internal update method doing the actual work.
+   */
+  void Update(
+    const char* arrayname, int arrayType, vtkSMSourceProxy* sp, vtkSMInputArrayDomain* iad, int outputport);
+
+private:
+  vtkSMMyNumberOfComponentsDomain(const vtkSMMyNumberOfComponentsDomain&) = delete;
+  void operator=(const vtkSMMyNumberOfComponentsDomain&) = delete;
+};
+
+#endif
diff --git a/src/ExtractComponentsPlugin/plugin/filters.xml b/src/ExtractComponentsPlugin/plugin/filters.xml
new file mode 100644 (file)
index 0000000..bfe85bc
--- /dev/null
@@ -0,0 +1,80 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <!-- ==================================================================== -->
+     <SourceProxy class="vtkExtractComponents"
+                 name="ExtractComponents"
+                 label="Extract Components">
+      <Documentation long_help="This filter extracts some components of a multi-component attribute array."
+                     short_help="Extract Multiple Component."/>
+      <InputProperty command="SetInputConnection"
+                     name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet" />
+        </DataTypeDomain>
+        <InputArrayDomain name="input_array"
+                          attribute_type="any">
+        </InputArrayDomain>
+        <Documentation>
+          This property specifies the input of the Extract Component filter.
+        </Documentation>
+      </InputProperty>
+      <StringVectorProperty name="SelectInputArray"
+                            label="Input Array"
+                            command="SetInputArrayToProcess"
+                            element_types="0 0 0 0 2"
+                            number_of_elements="5">
+        <ArrayListDomain name="array_list"
+                         input_domain_name="input_array_any">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>
+          This property indicates the name of the array to be extracted.
+        </Documentation>
+      </StringVectorProperty>
+      <StringVectorProperty name="OutputArrayName"
+                            label="Output Array Name"
+                            command="SetOutputArrayName"
+                            default_values=""
+                            number_of_elements="1"
+                            panel_widget="LinkedLineEdit">
+        <Documentation>
+          This property indicates the name of the output scalar array.
+        </Documentation>
+      </StringVectorProperty>
+      <IntVectorProperty name="Components"
+                         animateable="0"
+                         clean_command="ClearComponents"
+                         command="AddComponent"
+                         number_of_elements_per_command="1"
+                         repeat_command="1">
+        <MyNumberOfComponentsDomain name="comps">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+            <Property function="ArraySelection"
+                      name="SelectInputArray" />
+          </RequiredProperties>
+        </MyNumberOfComponentsDomain>
+        <Documentation>
+          This property indicates the components of the array to be extracted.
+        </Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetGenerateVector"
+                         default_values="0"
+                         name="GenerateVector"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Documentation>Specify if output array is clamped/ to 3 components array in order to be connected downstream to WrapByVector filter for example. Disabled by default.</Documentation>
+      </IntVectorProperty>
+      <!-- End ExtractComponents -->
+    </SourceProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ExtractComponentsPlugin/plugin/paraview.plugin b/src/ExtractComponentsPlugin/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..3e98e9d
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ExtractComponents
+DESCRIPTION
+  This plugin provides the ExtractComponents filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  ParaView::RemotingCore
+  ParaView::RemotingServerManager
diff --git a/src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.cxx b/src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.cxx
new file mode 100644 (file)
index 0000000..0e564fb
--- /dev/null
@@ -0,0 +1,151 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2.
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#include "pqLinkedLineEdit.h"
+
+#include <pqLineEdit.h>
+#include <pqPipelineSource.h>
+#include <pqServerManagerModel.h>
+
+#include <vtkSMStringVectorProperty.h>
+#include <vtkSMPropertyHelper.h>
+
+#include <QHBoxLayout>
+#include <QLabel>
+
+#include <vtkEventQtSlotConnect.h>
+
+//-----------------------------------------------------------------------------
+pqLinkedLineEdit::pqLinkedLineEdit(
+  vtkSMProxy* smproxy, vtkSMProperty* smproperty, QWidget* parentObject)
+  : Superclass(smproxy, parentObject)
+{
+  this->setProperty(smproperty);
+  this->setShowLabel(false);
+  this->setChangeAvailableAsChangeFinished(true);
+
+  // Creating the QLineEdit
+  this->LineEdit = new pqLineEdit(this);
+  this->LineEdit->setObjectName(smproxy->GetPropertyName(smproperty));
+  this->addPropertyLink(this->LineEdit, "text", SIGNAL(textChanged(const QString&)), smproperty);
+  this->connect(
+    this->LineEdit, SIGNAL(textChangedAndEditingFinished()), this, SIGNAL(changeFinished()));
+
+  // Creating the QLabel
+  QLabel* label = new QLabel(this);
+  label->setObjectName(QString("_labelFor") + smproxy->GetPropertyName(smproperty));
+  label->setText(smproperty->GetXMLLabel());
+  label->setWordWrap(true);
+
+  QHBoxLayout* hbox = new QHBoxLayout(this);
+  hbox->setMargin(0);
+  hbox->setSpacing(0);
+
+  // Adding everything to the layout
+  hbox->addWidget(label);
+  hbox->addWidget(this->LineEdit);
+  this->setLayout(hbox);
+
+  this->PreviousArrayName = "";
+
+  // Listen for changes of the input array property
+  this->Connect = vtkEventQtSlotConnect::New();
+  this->Connect->Connect(
+    smproxy->GetProperty("SelectInputArray"), vtkCommand::UncheckedPropertyModifiedEvent,
+    this, SLOT(onInputArrayModified()));
+
+  vtkSMPropertyHelper helper(this->property(), true);
+  helper.SetUseUnchecked(true);
+  QString arrayName = QString::fromLocal8Bit(helper.GetAsString());
+  if (arrayName == "")
+  {
+    // If property is not initialized yet (eg. when loading a PVSM),
+    // set its value to the input array name
+    this->onInputArrayModified();
+  }
+}
+
+//-----------------------------------------------------------------------------
+pqLinkedLineEdit::~pqLinkedLineEdit()
+{
+  this->Connect->Delete();
+}
+
+//-----------------------------------------------------------------------------
+void pqLinkedLineEdit::updateWidget(bool showing_advanced_properties)
+{
+  // The property changed, let's rebuild the UI
+  // TODO: this code seems useless after all
+  vtkSMPropertyHelper helper(this->property(), true);
+  helper.SetUseUnchecked(true);
+  QString arrayName = QString::fromLocal8Bit(helper.GetAsString());
+  if (this->LineEdit->text() != arrayName)
+  {
+    this->LineEdit->setText(arrayName);
+    emit changeAvailable();
+  }
+}
+
+//-----------------------------------------------------------------------------
+void pqLinkedLineEdit::onInputArrayModified()
+{
+  // Input array property changed, let's update our line edit if property value
+  // has not yet been considered.
+  vtkSMPropertyHelper helper(this->proxy(), "SelectInputArray", true);
+  helper.SetUseUnchecked(true);
+  QString arrayName = QString::fromLocal8Bit(helper.GetAsString(4));
+  if (arrayName != this->PreviousArrayName)
+  {
+    this->LineEdit->setText(arrayName);
+    this->PreviousArrayName = arrayName;
+
+    emit changeAvailable();
+  }
+}
diff --git a/src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.h b/src/ExtractComponentsPlugin/plugin/pqLinkedLineEdit.h
new file mode 100644 (file)
index 0000000..c936f87
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2.
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#ifndef pqLinkedLineEdit_h
+#define pqLinkedLineEdit_h
+
+#include <pqPropertyWidget.h>
+
+class QLineEdit;
+class vtkEventQtSlotConnect;
+
+class pqLinkedLineEdit : public pqPropertyWidget
+{
+  Q_OBJECT
+  typedef pqPropertyWidget Superclass;
+
+public:
+  pqLinkedLineEdit(
+    vtkSMProxy* smproxy, vtkSMProperty* smproperty, QWidget* parentObject = nullptr);
+  virtual ~pqLinkedLineEdit();
+
+  void updateWidget(bool showing_advanced_properties = false);
+
+public slots:
+  void onInputArrayModified();
+
+signals:
+  void textChanged(const QString&);
+  void inputArrayModified();
+
+protected:
+  QLineEdit* LineEdit;
+  QString PreviousArrayName;
+  vtkEventQtSlotConnect* Connect;
+
+private:
+  Q_DISABLE_COPY(pqLinkedLineEdit)
+};
+
+#endif
diff --git a/src/ExtractThreeD/CMakeLists.txt b/src/ExtractThreeD/CMakeLists.txt
new file mode 100644 (file)
index 0000000..28a4565
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ExtractThreeDimPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ExtractThreeD/plugin/CMakeLists.txt b/src/ExtractThreeD/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..443eb1b
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+CMAKE_POLICY(SET CMP0071 NEW)
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+# Common CMake macros
+# ===================
+SET(TMP_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+SET(MEDCOUPLING_ROOT_DIR $ENV{MEDCOUPLING_ROOT_DIR} CACHE PATH "Path to the MEDCoupling tool")
+IF(EXISTS ${MEDCOUPLING_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${MEDCOUPLING_ROOT_DIR}/cmake_files")
+ENDIF()
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
+LIST(APPEND CMAKE_MODULE_PATH ${TMP_CMAKE_MODULE_PATH})
+
+INCLUDE(SalomeSetupPlatform)
+SET(BUILD_SHARED_LIBS TRUE)
+
+FIND_PACKAGE(SalomeHDF5 REQUIRED)
+FIND_PACKAGE(SalomeMEDCoupling REQUIRED)
+
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}
+                                                 ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON})
+SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS})
+SALOME_ACCUMULATE_ENVIRONMENT(PV_PLUGIN_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/lib/paraview)
+
+paraview_add_plugin(ExtractThreeDimPlugin
+  VERSION "1.0"
+  MODULES ExtractThreeDModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ExtractThreeDModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ExtractThreeDimPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ExtractThreeD/plugin/ExtractThreeDModule/CMakeLists.txt b/src/ExtractThreeD/plugin/ExtractThreeDModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..acd980d
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkExtractThreeD
+)
+
+vtk_module_add_module(ExtractThreeDModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
+
+target_include_directories(ExtractThreeDModule PRIVATE ${MEDCOUPLING_INCLUDE_DIRS})
+
+if(HDF5_IS_PARALLEL)
+  target_link_libraries(ExtractThreeDModule PRIVATE ${MEDCoupling_paramedloader})
+else()
+  target_link_libraries(ExtractThreeDModule PRIVATE ${MEDCoupling_medloader})
+endif()
diff --git a/src/ExtractThreeD/plugin/ExtractThreeDModule/vtk.module b/src/ExtractThreeD/plugin/ExtractThreeDModule/vtk.module
new file mode 100644 (file)
index 0000000..827952d
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ExtractThreeDModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
diff --git a/src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.cxx b/src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.cxx
new file mode 100644 (file)
index 0000000..208c6f3
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#include "vtkExtractThreeD.h"
+
+#include <NormalizedGeometricTypes>
+#include <CellModel.hxx>
+#include <InterpKernelException.hxx>
+#include <MEDFileFieldOverView.hxx>
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCellData.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataArrayTemplate.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkThreshold.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+
+#include <deque>
+#include <map>
+#include <sstream>
+
+vtkStandardNewMacro(vtkExtractThreeD);
+
+///////////////////
+
+class vtkExtractThreeD::vtkExtractThreeDInternal
+{
+public:
+  vtkExtractThreeDInternal() {}
+  std::vector<int> getIdsToKeep() const { return _types; }
+  void setIdsToKeep(const std::vector<int> &types) { _types = types; }
+
+private:
+  std::vector<int> _types;
+};
+
+vtkExtractThreeD::vtkExtractThreeD() : Internal(new vtkExtractThreeDInternal)
+{
+}
+
+vtkExtractThreeD::~vtkExtractThreeD()
+{
+  delete this->Internal;
+}
+
+int vtkExtractThreeD::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  try
+  {
+    //std::cerr << "########################################## vtkExtractThreeD::RequestInformation ##########################################" << std::endl;
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
+    vtkDataSet *input(0);
+    {
+      vtkDataObject *inp(inputInfo->Get(vtkDataObject::DATA_OBJECT()));
+      if (vtkDataSet::SafeDownCast(inp))
+        input = vtkDataSet::SafeDownCast(inp);
+      else
+      {
+        vtkMultiBlockDataSet *inputTmp(vtkMultiBlockDataSet::SafeDownCast(inp));
+        if (inputTmp)
+        {
+          if (inputTmp->GetNumberOfBlocks() != 1)
+          {
+            vtkDebugMacro("vtkExtractThreeD::RequestInformation : input vtkMultiBlockDataSet must contain exactly 1 block !");
+            return 0;
+          }
+          vtkDataSet *blk0(vtkDataSet::SafeDownCast(inputTmp->GetBlock(0)));
+          if (!blk0)
+          {
+            vtkDebugMacro("vtkExtractThreeD::RequestInformation : the single block in input vtkMultiBlockDataSet must be a vtkDataSet instance !");
+            return 0;
+          }
+          input = blk0;
+        }
+        else
+        {
+          vtkDebugMacro("vtkExtractThreeD::RequestInformation : supported input are vtkDataSet or vtkMultiBlockDataSet !");
+          return 0;
+        }
+      }
+    }
+    {
+      vtkIdType nbOfCells(input->GetNumberOfCells());
+      std::map<int, INTERP_KERNEL::NormalizedCellType> m;
+      std::set<int> typesToKeep;
+      for (vtkIdType cellId = 0; cellId < nbOfCells; cellId++)
+      {
+        int vtkCt(input->GetCellType(cellId));
+        const std::map<int, INTERP_KERNEL::NormalizedCellType>::const_iterator it(m.find(vtkCt));
+        if (it == m.end())
+        {
+          const unsigned char *pos(std::find(MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE, MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE + MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH, vtkCt));
+          if (pos == MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE + MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH)
+          {
+            vtkDebugMacro("vtkExtractThreeD::RequestInformation : cell #" << cellId << " has unrecognized type !");
+            return 0;
+          }
+          INTERP_KERNEL::NormalizedCellType mcCtype((INTERP_KERNEL::NormalizedCellType)std::distance(MEDCoupling::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE, pos));
+          const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel(mcCtype));
+          if (cm.getDimension() == 3)
+            typesToKeep.insert(vtkCt);
+        }
+      }
+      std::vector<int> typesToKeep2(typesToKeep.begin(), typesToKeep.end());
+      this->Internal->setIdsToKeep(typesToKeep2);
+    }
+  }
+  catch (INTERP_KERNEL::Exception &e)
+  {
+    std::cerr << "Exception has been thrown in vtkExtractThreeD::RequestInformation : " << e.what() << std::endl;
+    return 0;
+  }
+  return 1;
+}
+
+vtkDataSet *FilterFamilies(vtkDataSet *input, const std::vector<int> &idsToKeep)
+{
+  const int VTK_DATA_ARRAY_DELETE = vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
+  const char ZE_SELECTION_ARR_NAME[] = "@@ZeSelection@@";
+  vtkDataSet *output(input->NewInstance());
+  output->ShallowCopy(input);
+  vtkSmartPointer<vtkThreshold> thres(vtkSmartPointer<vtkThreshold>::New());
+  thres->SetInputData(output);
+  vtkDataSetAttributes *dscIn(input->GetCellData()), *dscIn2(input->GetPointData());
+  vtkDataSetAttributes *dscOut(output->GetCellData()), *dscOut2(output->GetPointData());
+  //
+  double vMin(1.), vMax(2.);
+  thres->ThresholdBetween(vMin, vMax);
+  // OK for the output
+  vtkIdType nbOfCells(input->GetNumberOfCells());
+  vtkCharArray *zeSelection(vtkCharArray::New());
+  zeSelection->SetName(ZE_SELECTION_ARR_NAME);
+  zeSelection->SetNumberOfComponents(1);
+  char *pt(new char[nbOfCells]);
+  zeSelection->SetArray(pt, nbOfCells, 0, VTK_DATA_ARRAY_DELETE);
+  std::fill(pt, pt + nbOfCells, 0);
+  std::vector<bool> pt2(nbOfCells, false);
+  for (std::vector<int>::const_iterator it = idsToKeep.begin(); it != idsToKeep.end(); it++)
+  {
+    for (vtkIdType ii = 0; ii < nbOfCells; ii++)
+    {
+      if (input->GetCellType(ii) == *it)
+        pt2[ii] = true;
+    }
+  }
+  for (int ii = 0; ii < nbOfCells; ii++)
+    if (pt2[ii])
+      pt[ii] = 2;
+  int idx(output->GetCellData()->AddArray(zeSelection));
+  output->GetCellData()->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
+  output->GetCellData()->CopyScalarsOff();
+  zeSelection->Delete();
+  //
+  thres->SetInputArrayToProcess(idx, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_CELLS", ZE_SELECTION_ARR_NAME);
+  thres->Update();
+  vtkUnstructuredGrid *zeComputedOutput(thres->GetOutput());
+  zeComputedOutput->GetCellData()->RemoveArray(idx);
+  output->Delete();
+  zeComputedOutput->Register(0);
+  return zeComputedOutput;
+}
+
+int vtkExtractThreeD::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  try
+  {
+    //std::cerr << "########################################## vtkExtractThreeD::RequestData        ##########################################" << std::endl;
+    vtkInformation *inputInfo = inputVector[0]->GetInformationObject(0);
+    vtkDataSet *input(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+    vtkInformation *info(input->GetInformation());
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkDataSet *output(vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    std::vector<int> idsToKeep(this->Internal->getIdsToKeep());
+    vtkDataSet *tryOnCell(FilterFamilies(input, idsToKeep));
+    // first shrink the input
+    output->ShallowCopy(tryOnCell);
+    tryOnCell->Delete();
+  }
+  catch (INTERP_KERNEL::Exception &e)
+  {
+    std::cerr << "Exception has been thrown in vtkExtractThreeD::RequestData : " << e.what() << std::endl;
+    return 0;
+  }
+  return 1;
+}
+
+void vtkExtractThreeD::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.h b/src/ExtractThreeD/plugin/ExtractThreeDModule/vtkExtractThreeD.h
new file mode 100644 (file)
index 0000000..ed442d8
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay
+
+#ifndef vtkExtractThreeD_h__
+#define vtkExtractThreeD_h__
+
+#include <vtkDataSetAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkExtractThreeD : public vtkDataSetAlgorithm
+{
+public:
+  static vtkExtractThreeD *New();
+  vtkTypeMacro(vtkExtractThreeD, vtkDataSetAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+protected:
+  vtkExtractThreeD();
+  ~vtkExtractThreeD();
+
+  int RequestInformation(vtkInformation *request,
+                         vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector) override;
+
+  class vtkExtractThreeDInternal;
+  vtkExtractThreeDInternal *Internal;
+
+private:
+  vtkExtractThreeD(const vtkExtractThreeD &) = delete;
+  void operator=(const vtkExtractThreeD &) = delete;
+};
+
+#endif
diff --git a/src/ExtractThreeD/plugin/filters.xml b/src/ExtractThreeD/plugin/filters.xml
new file mode 100644 (file)
index 0000000..0b7f791
--- /dev/null
@@ -0,0 +1,21 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="ExtractThreeDim"
+                 class="vtkExtractThreeD"
+                 label="Extract Three Dim">
+     <InputProperty name="Input"
+                    command="SetInputConnection">
+       <ProxyGroupDomain name="groups">
+         <Group name="sources"/>
+         <Group name="filters"/>
+       </ProxyGroupDomain>
+       <DataTypeDomain name="input_type">
+         <DataType value="vtkDataSet"/>
+       </DataTypeDomain>
+       <Documentation>
+         This property specifies the input to the Level Scalars filter.
+       </Documentation>
+     </InputProperty>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ExtractThreeD/plugin/paraview.plugin b/src/ExtractThreeD/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..d0d9f3a
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ExtractThreeDimPlugin
+DESCRIPTION
+  This plugin provides the ExtractThreeDim filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/GlyphCIH/CMakeLists.txt b/src/GlyphCIH/CMakeLists.txt
new file mode 100644 (file)
index 0000000..67bf2c7
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(GlyphCIH)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/GlyphCIH/plugin/CMakeLists.txt b/src/GlyphCIH/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2f52875
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(GlyphCIH
+  VERSION "1.0"
+  MODULES GlyphCIHFilters
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/GlyphCIHFilters/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS GlyphCIH
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/GlyphCIH/plugin/GlyphCIHFilters/CMakeLists.txt b/src/GlyphCIH/plugin/GlyphCIHFilters/CMakeLists.txt
new file mode 100644 (file)
index 0000000..06cf636
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkGlyphCIH
+)
+
+vtk_module_add_module(GlyphCIHFilters
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/GlyphCIH/plugin/GlyphCIHFilters/vtk.module b/src/GlyphCIH/plugin/GlyphCIHFilters/vtk.module
new file mode 100644 (file)
index 0000000..bf9c08f
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  GlyphCIHFilters
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeometry
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  VTK::FiltersVerdict
+  ParaView::VTKExtensionsFiltersGeneral
+  ParaView::VTKExtensionsMisc
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
+  VTK::IOInfovis
diff --git a/src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.cxx b/src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.cxx
new file mode 100644 (file)
index 0000000..5a9b025
--- /dev/null
@@ -0,0 +1,379 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkGlyphCIH.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataSetSurfaceFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkLineSource.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkRibbonFilter.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkTable.h>
+#include <vtkTessellatorFilter.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariant.h>
+#include <vtkVariantArray.h>
+#include <vtkMeshQuality.h>
+#include <vtkCellCenters.h>
+
+#include <cmath>
+#include <sstream>
+
+class MyGlyphException : public std::exception
+{
+public:
+  MyGlyphException(const std::string& s):_reason(s) { }
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MyGlyphException() throw() { }
+private:
+  std::string _reason;
+};
+
+//-----------------------------------------------------------------------------
+void vtkGlyphCIH::ExtractInfo(
+  vtkInformationVector* inputVector, vtkSmartPointer<vtkUnstructuredGrid>& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input(0);
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+  {
+    input = input0;
+  }
+  else
+  {
+    if (!input1)
+    {
+      vtkErrorMacro("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+      return;
+    }
+    if (input1->GetNumberOfBlocks() != 1)
+    {
+      vtkErrorMacro("Input dataSet is a multiblock dataset with not exactly one block ! Use "
+                    "MergeBlocks or ExtractBlocks filter before calling this filter !");
+      return;
+    }
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+    {
+      vtkErrorMacro("Input dataSet is a multiblock dataset with exactly one block but this single "
+                    "element is NULL !");
+      return;
+    }
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+    {
+      vtkErrorMacro(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      return;
+    }
+    input = input2c;
+  }
+
+  if (!input)
+  {
+    vtkErrorMacro("Input data set is NULL !");
+    return;
+  }
+
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+  {
+    if (!input1)
+    {
+      vtkNew<vtkMultiBlockDataGroupFilter> mb;
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+      mb->AddInputData(input);
+      cd->SetInputConnection(mb->GetOutputPort());
+      cd->SetMergePoints(0);
+      cd->Update();
+      usgIn = cd->GetOutput();
+    }
+    else
+    {
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> filter;
+      filter->SetMergePoints(0);
+      filter->SetInputData(input1);
+      filter->Update();
+      usgIn = filter->GetOutput();
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+vtkStandardNewMacro(vtkGlyphCIH);
+
+int vtkGlyphCIH::FillInputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
+  return 1;
+}
+
+int vtkGlyphCIH::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
+  return 1;
+}
+
+constexpr double radius_base = 0.03;
+constexpr double radius_pointe = 0.1;
+constexpr double z_base_pointe = 0.65;
+constexpr double hauteur_pointe = 1.0 - z_base_pointe;
+const double sqrt3Over2 = sqrt(3.) / 2;
+const std::vector<double> fleche_base= {
+  0.0,1.0,
+  -sqrt3Over2,0.5,
+  -sqrt3Over2,-0.5,
+  0.0,-1.0,
+  sqrt3Over2,-0.5,
+  sqrt3Over2,0.5
+  };
+constexpr std::size_t N_CONN = 44;
+constexpr std::size_t N_COORDS = 12;
+constexpr std::size_t NB_CELL = 8;
+constexpr std::size_t N_CONN_EFF = N_CONN-NB_CELL;
+constexpr vtkIdType N_ACTIVE_CONN[N_CONN_EFF]={
+  1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13,// 2 hexa
+  15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27, 28, 30, 31, 32, 33, 35, 36, 37, 38, 40, 41, 42, 43// 6 quad4
+};
+constexpr vtkIdType N_CONN_STATIC[NB_CELL]={0, 7, 14, 19, 24, 29, 34, 39};
+constexpr vtkIdType ref_conn[N_CONN]={6,0,1,2,3,4,5, 6,6,7,8,9,10,11, 4,0,1,7,6, 4,1,2,8,7, 4,2,3,9,8, 4,3,4,10,9, 4,4,5,11,10, 4,5,0,6,11};
+
+double signOf(double val) { return val>=0?1.:-1.; }
+
+template<class T>
+void Algo(double widthFactor, vtkIdType inNbOfPts, double inNormMax, double scaleFactor, const double *inPts, double *coordsPtr, const T *inFieldDataPtr, vtkIdType *connPtr, T *fieldDataPtr)
+{
+  double sign(signOf(scaleFactor));
+  scaleFactor = std::abs(scaleFactor);
+  for(vtkIdType iPt = 0 ; iPt < inNbOfPts ; ++iPt, coordsPtr+=3*N_COORDS, connPtr+=N_CONN, fieldDataPtr+=3*NB_CELL)
+    {
+      for(auto i = 0 ; i < NB_CELL ; ++i)
+        connPtr[N_CONN_STATIC[i]] = ref_conn[N_CONN_STATIC[i]];
+      for(auto i = 0 ; i < N_CONN_EFF ; ++i)
+        connPtr[N_ACTIVE_CONN[i]] = iPt*N_COORDS + ref_conn[N_ACTIVE_CONN[i]];
+      T norm(vtkMath::Norm(inFieldDataPtr+3*iPt,3));
+      //
+      double mainZ[3] = {inFieldDataPtr[3*iPt+0]/norm,inFieldDataPtr[3*iPt+1]/norm,inFieldDataPtr[3*iPt+2]/norm};
+      double mainX[3],mainY[3];
+      vtkMath::Perpendiculars(mainZ,mainY,mainX,0.);
+      double radiusBase(widthFactor*radius_base);
+      double normRel(norm/inNormMax);
+      // normRel entre 0. et 1.. 0 -> Pas de base de fleche. 1 fleche au taquet.
+      /*
+      double zPosBasePointe(normRel*scaleFactor*inNormMax-widthFactor*hauteur_pointe);
+      double radiusPointe(widthFactor*radius_pointe);
+      if(zPosBasePointe < 0.)
+      {
+        radiusPointe = (normRel*scaleFactor*inNormMax)/hauteur_pointe*radius_pointe;
+        radiusBase = std::min(radiusBase,radiusPointe);
+        zPosBasePointe = 0.0;
+      }*/
+      for(int i = 0 ; i < 6 ; ++i)
+      {
+        coordsPtr[3*i+0] = radiusBase*fleche_base[2*i+0]; coordsPtr[3*i+1] = radiusBase*fleche_base[2*i+1]; coordsPtr[3*i+2] = 0.0;
+      }
+      for(int i = 0 ; i < 6 ; ++i)
+      {
+        coordsPtr[6*3+3*i+0] = radiusBase*fleche_base[2*i+0]; coordsPtr[6*3+3*i+1] = radiusBase*fleche_base[2*i+1]; coordsPtr[6*3+3*i+2] = normRel*scaleFactor*inNormMax;//zPosBasePointe;
+      }
+      /*for(int i = 0 ; i < 6 ; ++i)
+      {
+        coordsPtr[12*3+3*i+0] = radiusPointe*fleche_base[2*i+0]; coordsPtr[12*3+3*i+1] = radiusPointe*fleche_base[2*i+1]; coordsPtr[12*3+3*i+2] = zPosBasePointe;
+      }
+      coordsPtr[18*3+0] = 0.; coordsPtr[18*3+1] = 0.; coordsPtr[18*3+2] = normRel*scaleFactor*inNormMax;*/
+      // rotation
+      for(auto i = 0 ; i < N_COORDS ; ++i )
+        {
+          double tmp[3] = {
+            sign*(coordsPtr[i*3]*mainX[0]+coordsPtr[i*3+1]*mainY[0]+coordsPtr[i*3+2]*mainZ[0]),
+            sign*(coordsPtr[i*3]*mainX[1]+coordsPtr[i*3+1]*mainY[1]+coordsPtr[i*3+2]*mainZ[1]),
+            sign*(coordsPtr[i*3]*mainX[2]+coordsPtr[i*3+1]*mainY[2]+coordsPtr[i*3+2]*mainZ[2])
+          };
+          std::copy(tmp,tmp+3,coordsPtr+i*3);
+        }
+      // translation
+      for(auto i = 0 ; i < N_COORDS ; ++i )
+        { coordsPtr[i*3+0] += inPts[3*iPt+0]; coordsPtr[i*3+1] += inPts[3*iPt+1]; coordsPtr[i*3+2] += inPts[3*iPt+2]; }
+      // field
+      for(auto i = 0 ; i < NB_CELL ; ++i)
+        { std::copy(inFieldDataPtr+3*iPt,inFieldDataPtr+3*(iPt+1),fieldDataPtr+i*3); }
+    }
+}
+
+template<class T>
+struct Traits
+{
+  using EltType = T;
+};
+
+template<>
+struct Traits<double>
+{
+  using ArrayType = vtkDoubleArray;
+};
+
+template<>
+struct Traits<float>
+{
+  using ArrayType = vtkFloatArray;
+};
+
+
+template<class T>
+void Algo2(double widthFactor, double scaleFactor, vtkIdType inNbOfPts, const double *inPts, double *coordsPtr, vtkIdType *connPtr, typename Traits<T>::ArrayType *inFieldData, vtkDataArray *fieldData)
+{
+  
+  const T *inFieldDataPtr(inFieldData->GetPointer(0));
+  T *fieldDataPtr(reinterpret_cast<T *>(fieldData->GetVoidPointer(0)));
+  //
+  double inNormMin(std::numeric_limits<double>::max()),inNormMax(-std::numeric_limits<double>::max());
+  for(vtkIdType i = 0 ; i < inNbOfPts ; ++i)
+  {
+    double norm(vtkMath::Norm(inFieldDataPtr+3*i,3));
+    inNormMin = std::min(inNormMin,norm);
+    inNormMax = std::max(inNormMax,norm);
+  }
+  //
+  if(inNormMin == 0.)
+    throw MyGlyphException("Norm min is null !");
+  //
+  Algo<T>(widthFactor,inNbOfPts,inNormMax,scaleFactor,inPts,coordsPtr,inFieldDataPtr,connPtr,fieldDataPtr);
+}
+
+void vtkGlyphCIH::SetInputArrayToProcess(int idx, int port, int connection, int ff, const char* name)
+{
+  if (idx == 0)
+    this->FieldName = name;
+  vtkPointSetAlgorithm::SetInputArrayToProcess(idx, port, connection, ff, name);
+}
+
+//-----------------------------------------------------------------------------
+int vtkGlyphCIH::RequestData(vtkInformation* vtkNotUsed(request),vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  try
+  {
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    vtkPointSet* output(vtkPointSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    vtkSmartPointer<vtkUnstructuredGrid> usgIn;
+    this->ExtractInfo(inputVector[0], usgIn);
+    //
+    vtkNew<vtkCellCenters> cc;
+    cc->SetInputData(usgIn);
+    cc->Update();
+    vtkDataArray *inFieldDataGen(cc->GetOutput()->GetPointData()->GetArray(this->FieldName.c_str()));
+    vtkIdType inNbOfPts(cc->GetOutput()->GetNumberOfPoints());
+    const double *inPts(static_cast<double *>(cc->GetOutput()->GetPoints()->GetData()->GetVoidPointer(0)));
+    //
+    if(!inFieldDataGen)
+    {
+      std::ostringstream oss; oss << "No such point field with name \"" << this->FieldName << "\" !";
+      throw MyGlyphException(oss.str());
+    }
+    vtkSmartPointer<vtkDataArray> fieldData;
+    fieldData.TakeReference(inFieldDataGen->NewInstance());
+    fieldData->SetName(this->FieldName.c_str());
+    for(int i=0;i<3;i++)
+      fieldData->SetComponentName(i,inFieldDataGen->GetComponentName(i));
+    fieldData->SetNumberOfComponents(3);
+    fieldData->SetNumberOfTuples(inNbOfPts*NB_CELL);
+    //
+    vtkNew<vtkDoubleArray> coords;
+    coords->SetNumberOfComponents(3);
+    coords->SetNumberOfTuples(inNbOfPts*N_COORDS);
+    vtkNew<vtkIdTypeArray> conn;
+    conn->SetNumberOfComponents(1);
+    conn->SetNumberOfTuples(inNbOfPts*N_CONN);
+    double *coordsPtr(coords->GetPointer(0));
+    vtkIdType *connPtr(conn->GetPointer(0));
+    //
+    /*double inMaxCellSize(0);
+    {
+      vtkNew<vtkMeshQuality> mq;
+      mq->SetTriangleQualityMeasureToArea();
+      mq->SetQuadQualityMeasureToArea();
+      mq->SetInputData(usgIn);
+      mq->Update();
+      vtkDoubleArray *area(vtkDoubleArray::SafeDownCast(mq->GetOutput()->GetCellData()->GetArray("Quality")));
+      inMaxCellSize = area->GetMaxNorm();
+    }*/
+    //
+    if(vtkDoubleArray::SafeDownCast(inFieldDataGen))
+    {
+      vtkDoubleArray *inFieldData = vtkDoubleArray::SafeDownCast(inFieldDataGen);
+      Algo2<double>(this->WidthFactor,this->ScaleFactor,inNbOfPts,inPts,coordsPtr,connPtr,inFieldData,fieldData);
+    }
+    else if(vtkFloatArray::SafeDownCast(inFieldDataGen))
+    {
+      vtkFloatArray *inFieldData = vtkFloatArray::SafeDownCast(inFieldDataGen);
+      Algo2<float>(this->WidthFactor,this->ScaleFactor,inNbOfPts,inPts,coordsPtr,connPtr,inFieldData,fieldData);
+    }
+    else
+    {
+      throw MyGlyphException("Only float64 and float32 managed for input point field !");
+    }
+    //
+    vtkNew<vtkPolyData> pd;
+    vtkNew<vtkCellArray> cb;
+    cb->SetCells(inNbOfPts*NB_CELL,conn);
+    pd->SetPolys(cb);
+    //
+    vtkNew<vtkPoints> pts;
+    pts->SetData(coords);
+    pd->SetPoints(pts);
+    // on ajoute tous les pointsarrays
+    vtkCellData *pdc(pd->GetCellData());
+    pdc->AddArray(fieldData);
+    //
+    output->ShallowCopy(pd);
+  }
+  catch(MyGlyphException& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkComplexMode::RequestInformation : " << e.what() << std::endl;
+    if(this->HasObserver("ErrorEvent") )
+      this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+  }
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+void vtkGlyphCIH::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.h b/src/GlyphCIH/plugin/GlyphCIHFilters/vtkGlyphCIH.h
new file mode 100644 (file)
index 0000000..8a5fce2
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkGlyphCIH_h__
+#define __vtkGlyphCIH_h__
+
+#include <vtkPointSetAlgorithm.h>
+
+#include <vtkSmartPointer.h>
+#include <vtkUnstructuredGrid.h>
+
+#include <string>
+#include <vector>
+
+class vtkDoubleArray;
+
+class VTK_EXPORT vtkGlyphCIH : public vtkPointSetAlgorithm
+{
+public:
+  static vtkGlyphCIH* New();
+  vtkTypeMacro(vtkGlyphCIH, vtkPointSetAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  vtkGetMacro(ScaleFactor, double);
+  vtkSetMacro(ScaleFactor, double);
+
+  vtkGetMacro(WidthFactor, double);
+  vtkSetMacro(WidthFactor, double);
+
+  int FillInputPortInformation(int vtkNotUsed(port), vtkInformation *info) override;
+  int FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info) override;
+  
+  void SetInputArrayToProcess(int idx, int port, int connection, int fieldAssociation, const char* name) override;
+
+protected:
+  vtkGlyphCIH() = default;
+  ~vtkGlyphCIH() override = default;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  void ExtractInfo(vtkInformationVector* inputVector, vtkSmartPointer<vtkUnstructuredGrid>& usgIn);
+
+  double ScaleFactor;
+  double WidthFactor;
+  int TypeOfDisplay;
+  std::string FieldName;
+
+private:
+  vtkGlyphCIH(const vtkGlyphCIH&) = delete;
+  void operator=(const vtkGlyphCIH&) = delete;
+};
+
+#endif
diff --git a/src/GlyphCIH/plugin/filters.xml b/src/GlyphCIH/plugin/filters.xml
new file mode 100644 (file)
index 0000000..e388b48
--- /dev/null
@@ -0,0 +1,64 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy class="vtkGlyphCIH"
+                 name="Glyph Tangent">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation short_help= "Affiche des fleches a epaisseur constante."
+                       long_help = "Affiche des fleches a epaisseur constante.">
+        </Documentation>
+      </InputProperty>
+      <DoubleVectorProperty command="SetScaleFactor"
+                            default_values="1"
+                            name="ScaleFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <Documentation>This property specifies the scale factor applied to the length of arrows.
+        </Documentation>
+      </DoubleVectorProperty>
+      <DoubleVectorProperty command="SetWidthFactor"
+                            default_values="1"
+                            name="WidthFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <DoubleRangeDomain min="0.1" max="10.0" name="range" />
+        <Documentation>This property specifies the width of arrows.
+        </Documentation>
+      </DoubleVectorProperty>
+
+      <StringVectorProperty command="SetInputArrayToProcess"
+                           default_values="0;0;0;3"
+                           default_values_delimiter=";"
+                           element_types="0 0 0 0 2"
+                           name="Mode Array Selection"
+                           number_of_elements="5">
+        <!-- default value=1 so normals go to the right place -->
+        <ArrayListDomain attribute_type="Vectors"
+                         input_domain_name="input_array2"
+                         name="array_list">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="Input" />
+          </RequiredProperties>
+        </ArrayListDomain>
+        <Documentation>
+          Select the array that represents the requested mode.
+        </Documentation>
+      </StringVectorProperty>
+
+      <Hints>
+        <RepresentationType view="RenderView" type="Surface"/>
+        <ShowInMenu category="Mechanics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/GlyphCIH/plugin/paraview.plugin b/src/GlyphCIH/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..d734433
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  GlyphCIH
+DESCRIPTION
+  This plugin provides Glyph custom
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/MoveZCote/CMakeLists.txt b/src/MoveZCote/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af2acba
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(MoveZCotePlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/MoveZCote/MobileMesh.xml b/src/MoveZCote/MobileMesh.xml
new file mode 100644 (file)
index 0000000..01747ac
--- /dev/null
@@ -0,0 +1,93 @@
+<CustomFilterDefinitions>
+  <CustomProxyDefinition name="MobileMesh" group="filters">
+    <CompoundSourceProxy id="4863" servers="1">
+      <Proxy group="filters" type="Calculator" id="4401" servers="1" compound_name="Calculator1">
+        <Property name="AttributeMode" id="4401.AttributeMode" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="enum" id="4401.AttributeMode.enum">
+            <Entry value="1" text="Point Data"/>
+            <Entry value="2" text="Cell Data"/>
+          </Domain>
+        </Property>
+        <Property name="CoordinateResults" id="4401.CoordinateResults" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.CoordinateResults.bool"/>
+        </Property>
+        <Property name="Function" id="4401.Function" number_of_elements="1">
+          <Element index="0" value="COTE Z-coordsZ"/>
+        </Property>
+        <Property name="Input" id="4401.Input" number_of_elements="1">
+          <Domain name="groups" id="4401.Input.groups"/>
+          <Domain name="input_array" id="4401.Input.input_array"/>
+          <Domain name="input_type" id="4401.Input.input_type"/>
+        </Property>
+        <Property name="ReplaceInvalidValues" id="4401.ReplaceInvalidValues" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="4401.ReplaceInvalidValues.bool"/>
+        </Property>
+        <Property name="ReplacementValue" id="4401.ReplacementValue" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="range" id="4401.ReplacementValue.range"/>
+        </Property>
+        <Property name="ResultArrayName" id="4401.ResultArrayName" number_of_elements="1">
+          <Element index="0" value="DisplacementsZ"/>
+        </Property>
+        <Property name="ResultNormals" id="4401.ResultNormals" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.ResultNormals.bool"/>
+        </Property>
+        <Property name="ResultTCoords" id="4401.ResultTCoords" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4401.ResultTCoords.bool"/>
+        </Property>
+      </Proxy>
+      <Proxy group="filters" type="WarpScalar" id="4636" servers="1" compound_name="WarpByScalar1">
+        <Property name="Input" id="4636.Input" number_of_elements="1">
+          <Proxy value="4401" output_port="0"/>
+          <Domain name="groups" id="4636.Input.groups"/>
+          <Domain name="input_array" id="4636.Input.input_array"/>
+          <Domain name="input_type" id="4636.Input.input_type"/>
+        </Property>
+        <Property name="Normal" id="4636.Normal" number_of_elements="3">
+          <Element index="0" value="0"/>
+          <Element index="1" value="0"/>
+          <Element index="2" value="1"/>
+          <Domain name="range" id="4636.Normal.range"/>
+        </Property>
+        <Property name="ScaleFactor" id="4636.ScaleFactor" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="range" id="4636.ScaleFactor.range"/>
+        </Property>
+        <Property name="SelectInputScalars" id="4636.SelectInputScalars" number_of_elements="5">
+          <Element index="0" value=""/>
+          <Element index="1" value=""/>
+          <Element index="2" value=""/>
+          <Element index="3" value="0"/>
+          <Element index="4" value="DisplacementsZ"/>
+          <Domain name="array_list" id="4636.SelectInputScalars.array_list">
+            <String text="COTE Z"/>
+            <String text="DisplacementsZ"/>
+            <String text="VITESSE U"/>
+            <String text="VITESSE V"/>
+            <String text="VITESSE W"/>
+          </Domain>
+        </Property>
+        <Property name="UseNormal" id="4636.UseNormal" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4636.UseNormal.bool"/>
+        </Property>
+        <Property name="XYPlane" id="4636.XYPlane" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="4636.XYPlane.bool"/>
+        </Property>
+      </Proxy>
+      <ExposedProperties>
+        <Property name="Input" proxy_name="Calculator1" exposed_name="Input"/>
+      </ExposedProperties>
+      <OutputPort name="Output" proxy="WarpByScalar1" port_index="0"/>
+      <Hints>
+        <ShowInMenu/>
+      </Hints>
+    </CompoundSourceProxy>
+  </CustomProxyDefinition>
+</CustomFilterDefinitions>
diff --git a/src/MoveZCote/MoveMesh.py b/src/MoveZCote/MoveMesh.py
new file mode 100644 (file)
index 0000000..0966452
--- /dev/null
@@ -0,0 +1,62 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#### import the simple module from the paraview
+from paraview.simple import *
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'MED Reader'
+#f3d_gouttedomed = MEDReader(FileName='/home/H87074/TMP52/f3d_gouttedo.med')
+#f3d_gouttedomed.AllArrays = ['TS0/MESH/ComSup0/COTE Z@@][@@P1', 'TS0/MESH/ComSup0/VITESSE U@@][@@P1', 'TS0/MESH/ComSup0/VITESSE V@@][@@P1', 'TS0/MESH/ComSup0/VITESSE W@@][@@P1']
+#f3d_gouttedomed.AllTimeSteps = ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '00010']
+
+source = GetActiveSource()
+renderView1 = GetActiveViewOrCreate('RenderView')
+# get animation scene
+animationScene1 = GetAnimationScene()
+
+# update animation scene based on data timesteps
+animationScene1.UpdateAnimationUsingDataTimeSteps()
+
+# create a new 'Calculator'
+calculator1 = Calculator(Input=source)
+
+# Properties modified on calculator1
+calculator1.ResultArrayName = 'DisplacementsZ'
+calculator1.Function = 'COTE Z-coordsZ'
+
+# get color transfer function/color map for 'DisplacementsZ'
+displacementsZLUT = GetColorTransferFunction('DisplacementsZ')
+
+# show data in view
+#calculator1Display = Show(calculator1, renderView1)
+
+# hide data in view
+Hide(source, renderView1)
+
+# show color bar/color legend
+#calculator1Display.SetScalarBarVisibility(renderView1, True)
+
+# get opacity transfer function/opacity map for 'DisplacementsZ'
+
+# create a new 'Warp By Scalar'
+warpByScalar1 = WarpByScalar(Input=calculator1)
+warpByScalar1.Scalars = ['POINTS', 'DisplacementsZ']
+
diff --git a/src/MoveZCote/plugin/CMakeLists.txt b/src/MoveZCote/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e26d260
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(MoveZCotePlugin
+  VERSION "1.0"
+  MODULES MoveZCoteModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/MoveZCoteModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+install(TARGETS MoveZCotePlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/MoveZCote/plugin/MoveZCoteModule/CMakeLists.txt b/src/MoveZCote/plugin/MoveZCoteModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f782371
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkMoveZCote
+)
+
+vtk_module_add_module(MoveZCoteModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/MoveZCote/plugin/MoveZCoteModule/vtk.module b/src/MoveZCote/plugin/MoveZCoteModule/vtk.module
new file mode 100644 (file)
index 0000000..28ff90b
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  MoveZCoteModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.cxx b/src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.cxx
new file mode 100644 (file)
index 0000000..6c6a23b
--- /dev/null
@@ -0,0 +1,241 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkMoveZCote.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCellData.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+
+#include <deque>
+#include <map>
+#include <sstream>
+
+vtkStandardNewMacro(vtkMoveZCote);
+
+static const char ZE_ARRAY_NAME[] = "COTE Z";
+
+static const char ZE_DISPLACEMENT_NAME[] = "@@DisplacementZ?@@";
+
+///////////////////
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string &s) : _reason(s) {}
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *&usgIn, vtkDoubleArray *&arr)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw MZCException("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject *input2(input1->GetBlock(0));
+    if (!input2)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+    vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw MZCException("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+  vtkPointData *att(usgIn->GetPointData());
+  if (!att)
+    throw MZCException("Input dataset has no point data attribute ! Impossible to move mesh !");
+  vtkDataArray *zeArr(0);
+  for (int i = 0; i < att->GetNumberOfArrays(); i++)
+  {
+    vtkDataArray *locArr(att->GetArray(i));
+    std::string s(locArr->GetName());
+    if (s == ZE_ARRAY_NAME)
+    {
+      zeArr = locArr;
+      break;
+    }
+  }
+  if (!zeArr)
+  {
+    std::ostringstream oss;
+    oss << "Impossible to locate the array called \"" << ZE_ARRAY_NAME << "\" used to move mesh !";
+    throw MZCException(oss.str());
+  }
+  arr = vtkDoubleArray::SafeDownCast(zeArr);
+  if (!arr)
+  {
+    std::ostringstream oss;
+    oss << "Array called \"" << ZE_ARRAY_NAME << "\" has been located but this is NOT a float64 array !";
+    throw MZCException(oss.str());
+  }
+  if (arr->GetNumberOfComponents() != 1)
+  {
+    std::ostringstream oss;
+    oss << "Float64 array called \"" << ZE_ARRAY_NAME << "\" has been located but this array has not exactly 1 components as it should !";
+    throw MZCException(oss.str());
+  }
+  if (arr->GetNumberOfTuples() != usgIn->GetNumberOfPoints())
+  {
+    std::ostringstream oss;
+    oss << "Float64-1 components array called \"" << ZE_ARRAY_NAME << "\" has been located but the number of tuples is invalid ! Should be " << usgIn->GetNumberOfPoints() << " instead of " << arr->GetNumberOfTuples() << " !";
+    throw MZCException(oss.str());
+  }
+}
+
+////////////////////
+int vtkMoveZCote::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkMoveZCote::RequestInformation ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    vtkDoubleArray *arr(0);
+    ExtractInfo(inputVector[0], usgIn, arr);
+  }
+  catch (MZCException &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkMoveZCote::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+    {
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    }
+    else
+    {
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    }
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+int vtkMoveZCote::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkMoveZCote::RequestData        ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    vtkDoubleArray *arr(0);
+    ExtractInfo(inputVector[0], usgIn, arr);
+    //
+    int nbPts(usgIn->GetNumberOfPoints());
+    vtkSmartPointer<vtkUnstructuredGrid> step1(vtkSmartPointer<vtkUnstructuredGrid>::New());
+    step1->DeepCopy(usgIn);
+    vtkSmartPointer<vtkDoubleArray> arr1(vtkSmartPointer<vtkDoubleArray>::New());
+    arr1->SetName(ZE_DISPLACEMENT_NAME);
+    arr1->SetNumberOfComponents(1);
+    arr1->SetNumberOfTuples(nbPts);
+    double *ptToFeed(arr1->Begin());
+    vtkDataArray *coords(usgIn->GetPoints()->GetData());
+    vtkDoubleArray *coords2(vtkDoubleArray::SafeDownCast(coords));
+    if (!coords2)
+    {
+      throw MZCException("Input coordinates are not float64 !");
+    }
+    if (coords2->GetNumberOfComponents() != 3)
+    {
+      throw MZCException("Input coordinates do not have 3 components as it should !");
+    }
+    const double *srcPt1(arr->Begin()), *srcPt2(coords2->Begin());
+    for (int i = 0; i < nbPts; i++, ptToFeed++)
+    {
+      *ptToFeed = srcPt1[i] - srcPt2[3 * i + 2];
+    }
+    int idx(step1->GetPointData()->AddArray(arr1));
+    step1->GetPointData()->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
+    //
+    vtkSmartPointer<vtkWarpScalar> ws(vtkSmartPointer<vtkWarpScalar>::New());
+    ws->SetInputData(step1);
+    ws->SetScaleFactor(1);
+    ws->SetInputArrayToProcess(idx, 0, 0, "vtkDataObject::FIELD_ASSOCIATION_POINTS", ZE_DISPLACEMENT_NAME);
+    ws->Update();
+    vtkSmartPointer<vtkDataSet> ds(ws->GetOutput());
+    //
+    ds->GetPointData()->RemoveArray(idx);
+    //
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    //
+    output->ShallowCopy(ds);
+  }
+  catch (MZCException &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkMoveZCote::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+    {
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    }
+    else
+    {
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    }
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void vtkMoveZCote::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.h b/src/MoveZCote/plugin/MoveZCoteModule/vtkMoveZCote.h
new file mode 100644 (file)
index 0000000..8e55e1b
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkMoveZCote_h__
+#define vtkMoveZCote_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkMoveZCote : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkMoveZCote *New();
+  vtkTypeMacro(vtkMoveZCote, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+protected:
+  vtkMoveZCote() = default;
+  ~vtkMoveZCote() override = default;
+
+  int RequestInformation(vtkInformation *request,
+                         vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector) override;
+
+private:
+  vtkMoveZCote(const vtkMoveZCote &) = delete;
+  void operator=(const vtkMoveZCote &) = delete;
+};
+
+#endif
diff --git a/src/MoveZCote/plugin/filters.xml b/src/MoveZCote/plugin/filters.xml
new file mode 100644 (file)
index 0000000..d75e846
--- /dev/null
@@ -0,0 +1,24 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="MoveZCote"
+                 class="vtkMoveZCote"
+                 label="Move Z Cote">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+      <Hints>
+        <ShowInMenu category="Hydraulics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/MoveZCote/plugin/paraview.plugin b/src/MoveZCote/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..a07759e
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  MoveZCotePlugin
+DESCRIPTION
+  This plugin provides the MoveZCote filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/ProbePointOverTime/CMakeLists.txt b/src/ProbePointOverTime/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ee42308
--- /dev/null
@@ -0,0 +1,23 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#
+# Author : Anthony Geay (EDF R&D)
+cmake_minimum_required(VERSION 3.8)
+project(ProbePointOverTime)
+install(FILES ProbePointOverTimePlugin.xml DESTINATION lib/paraview )
diff --git a/src/ProbePointOverTime/HowtoTest.txt b/src/ProbePointOverTime/HowtoTest.txt
new file mode 100644 (file)
index 0000000..a05f88e
--- /dev/null
@@ -0,0 +1,3 @@
+1 - Read example.med
+2 - choose a cell
+3 - Probe Point Over Time
diff --git a/src/ProbePointOverTime/ProbePointOverTimePlugin.xml b/src/ProbePointOverTime/ProbePointOverTimePlugin.xml
new file mode 100644 (file)
index 0000000..2d684ce
--- /dev/null
@@ -0,0 +1,304 @@
+<ServerManagerConfiguration>
+
+  <ProxyGroup name="edf_internal_sources">
+    <!-- Copied from utilities.xml to use InteractiveHandle instead of InteractiveSphere -->
+    <SourceProxy class="vtkPointSource"
+                 label="Fixed Radius Point Source"
+                 name="FixedRadiusPointSource">
+      <DoubleVectorProperty animateable="1"
+                            command="SetCenter"
+                            default_values="0.0 0.0 0.0"
+                            name="Center"
+                            number_of_elements="3">
+        <BoundsDomain default_mode="mid"
+                      mode="normal"
+                      name="range">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="DummyInput" />
+          </RequiredProperties>
+        </BoundsDomain>
+      </DoubleVectorProperty>
+      <IntVectorProperty animateable="1"
+                         command="SetNumberOfPoints"
+                         default_values="1"
+                         name="NumberOfPoints"
+                         panel_visibility="never"
+                         number_of_elements="1">
+        <IntRangeDomain min="1"
+                        name="range" />
+      </IntVectorProperty>
+      <DoubleVectorProperty animateable="1"
+                            command="SetRadius"
+                            default_values="0.0"
+                            name="Radius"
+                            panel_visibility="never"
+                            number_of_elements="1">
+        <DoubleRangeDomain min="0.0"
+                           name="range" />
+      </DoubleVectorProperty>
+      <InputProperty is_internal="1"
+                     name="DummyInput">
+        <!-- Used when this source is added to a proxy list domain. -->
+      </InputProperty>
+      <PropertyGroup label="Point Parameters" panel_widget="InteractiveHandle">
+        <Property function="WorldPosition" name="Center" />
+        <!-- <Property function="Radius" name="Radius" /> -->
+        <Property function="Input" name="DummyInput" />
+      </PropertyGroup>
+      <Hints>
+        <ProxyList>
+          <Link name="DummyInput" with_property="Input" />
+        </ProxyList>
+      </Hints>
+      <!-- End internal FixedRadiusPointSource -->
+    </SourceProxy>
+  </ProxyGroup>
+
+  <ProxyGroup name="edf_internal_filters">
+    <!-- Copied from filters.xml in order to use point source as InputConnection -->
+    <SourceProxy class="vtkResampleWithDataSet"
+                 label="Resample With Dataset"
+                 name="ResampleWithDataset">
+      <Documentation short_help="Sample data attributes at the points of a dataset.">
+          This filter takes two inputs - Input and Source, and samples the
+          point and cell values of Input on to the point locations of Source.
+          The output has the same structure as Source but its point data
+          have the resampled values from Input."
+      </Documentation>
+      <InputProperty command="SetSourceConnection" name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet" />
+          <DataType value="vtkCompositeDataSet" />
+        </DataTypeDomain>
+        <Documentation>This property specifies the dataset from which to obtain
+        probe values. The data attributes come from this dataset.</Documentation>
+      </InputProperty>
+
+      <!-- original InputProperty -->
+      <!--<InputProperty command="SetInputConnection" name="Source">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet" />
+          <DataType value="vtkCompositeDataSet" />
+        </DataTypeDomain>
+        <Documentation>This property specifies the dataset whose geometry will
+        be used in determining positions to probe. The mesh comes from this
+        dataset.</Documentation>
+      </InputProperty> -->
+      <!-- Custom InputProperty -->
+      <InputProperty command="SetInputConnection"
+                     label="Seed Type"
+                     name="Source"
+                     panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="edf_internal_sources" name="FixedRadiusPointSource"/>
+        </ProxyListDomain>
+        <Documentation>The value of this property determines how the seeds for
+        the streamlines will be generated.</Documentation>
+      </InputProperty>
+
+      <IntVectorProperty command="SetCategoricalData"
+                         default_values="0"
+                         name="CategoricalData"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <BooleanDomain name="bool" />
+        <Documentation>Control whether the source point data is to be
+        treated as categorical. If the data is categorical, then the
+        resultant data will be determined by a nearest neighbor
+        interpolation scheme rather than by linear interpolation.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetPassCellArrays"
+                         default_values="0"
+                         name="PassCellArrays"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <Documentation>
+        When set the input's cell data arrays are shallow copied to the output.
+        </Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+      <IntVectorProperty command="SetPassPointArrays"
+                         default_values="0"
+                         name="PassPointArrays"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <Documentation>
+        When set the input's point data arrays are shallow copied to the output.
+        </Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+
+      <IntVectorProperty command="SetPassFieldArrays"
+                         default_values="1"
+                         name="PassFieldArrays"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <Documentation>
+        Set whether to pass the field-data arrays from the Input i.e. the input
+        providing the geometry to the output. On by default.
+        </Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+
+      <IntVectorProperty command="SetComputeTolerance"
+                         default_values="1"
+                         name="ComputeTolerance"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <Documentation>
+        Set whether to compute the tolerance or to use a user provided
+        value. On by default.
+        </Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+      <DoubleVectorProperty command="SetTolerance"
+                            default_values="2.2204460492503131e-16"
+                            name="Tolerance"
+                            number_of_elements="1"
+                            panel_visibility="advanced">
+        <DoubleRangeDomain min="2.2204460492503131e-16"
+                           name="range" />
+        <Hints>
+          <PropertyWidgetDecorator type="ShowWidgetDecorator">
+            <Property name="ComputeTolerance" function="boolean_invert" />
+          </PropertyWidgetDecorator>
+        </Hints>
+        <Documentation>Set the tolerance to use for
+        vtkDataSet::FindCell</Documentation>
+      </DoubleVectorProperty>
+
+      <IntVectorProperty command="SetMarkBlankPointsAndCells"
+                         default_values="0"
+                         name="MarkBlankPointsAndCells"
+                         number_of_elements="1"
+                         panel_visibility="advanced">
+        <Documentation>
+        When set, points that did not get valid values during resampling, and
+        cells containing such points, are marked as blank.
+        </Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+
+      <!-- cell locator begin -->
+      <ProxyProperty command="SetCellLocatorPrototype"
+                     label="Cell Locator"
+                     name="CellLocator"
+                     panel_visibility="advanced">
+        <ProxyGroupDomain name="groups">
+          <Group name="cell_locators" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="cell_locators"
+                 name="StaticCellLocator" />
+          <Proxy group="cell_locators"
+                 name="CellTreeLocator" />
+          <Proxy group="cell_locators"
+                 name="CellLocator" />
+        </ProxyListDomain>
+        <Documentation>The cell locator to use for finding cells for probing.
+        </Documentation>
+      </ProxyProperty>
+      <!-- cell locator end -->
+      <!-- End internal ResampleWithDataset -->
+    </SourceProxy>
+  </ProxyGroup>
+
+  <ProxyGroup name="filters">
+    <CompoundSourceProxy name="ProbePointOverTime" label="Probe Point Over Time" id="7625" servers="1">
+      <Hints>
+        <ShowInMenu category="CFD" />
+      </Hints>
+      <Proxy group="edf_internal_filters" type="ResampleWithDataset" id="7400" servers="1" compound_name="ResampleWithDataset1">
+        <Property name="CategoricalData" id="7400.CategoricalData" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="7400.CategoricalData.bool"/>
+        </Property>
+        <Property name="CellLocator" id="7400.CellLocator" number_of_elements="1">
+          <Proxy value="7397"/>
+          <Domain name="groups" id="7400.CellLocator.groups"/>
+          <Domain name="proxy_list" id="7400.CellLocator.proxy_list">
+            <Proxy value="7397"/>
+            <Proxy value="7398"/>
+            <Proxy value="7399"/>
+          </Domain>
+        </Property>
+        <Property name="ComputeTolerance" id="7400.ComputeTolerance" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="7400.ComputeTolerance.bool"/>
+        </Property>
+        <Property name="Input" id="7400.Input" number_of_elements="1">
+          <Domain name="groups" id="7400.Input.groups"/>
+          <Domain name="input_type" id="7400.Input.input_type"/>
+        </Property>
+        <Property name="MarkBlankPointsAndCells" id="7400.MarkBlankPointsAndCells" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="7400.MarkBlankPointsAndCells.bool"/>
+        </Property>
+        <Property name="PassCellArrays" id="7400.PassCellArrays" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="7400.PassCellArrays.bool"/>
+        </Property>
+        <Property name="PassFieldArrays" id="7400.PassFieldArrays" number_of_elements="1">
+          <Element index="0" value="1"/>
+          <Domain name="bool" id="7400.PassFieldArrays.bool"/>
+        </Property>
+        <Property name="PassPointArrays" id="7400.PassPointArrays" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="7400.PassPointArrays.bool"/>
+        </Property>
+        <Property name="Tolerance" id="7400.Tolerance" number_of_elements="1">
+          <Element index="0" value="2.220446049250313e-16"/>
+          <Domain name="range" id="7400.Tolerance.range"/>
+        </Property>
+      </Proxy>
+      <Proxy group="cell_locators" type="StaticCellLocator" id="7397" servers="1" compound_name="auto_7397"/>
+      <Proxy group="filters" type="PlotDataOverTime" id="20248" servers="1" compound_name="PlotDataOverTime1">
+        <Property name="FieldAssociation" id="20248.FieldAssociation" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="enum" id="20248.FieldAssociation.enum">
+            <Entry value="0" text="Points"/>
+            <Entry value="1" text="Cells"/>
+            <Entry value="4" text="Vertices"/>
+            <Entry value="5" text="Edges"/>
+            <Entry value="6" text="Rows"/>
+          </Domain>
+        </Property>
+        <Property name="Input" id="20248.Input" number_of_elements="1">
+          <Proxy value="7400" output_port="0"/>
+          <Domain name="groups" id="20248.Input.groups"/>
+          <Domain name="input_type" id="20248.Input.input_type"/>
+        </Property>
+        <Property name="Only Report Selection Statistics" id="20248.Only Report Selection Statistics" number_of_elements="1">
+          <Element index="0" value="0"/>
+          <Domain name="bool" id="20248.Only Report Selection Statistics.bool"/>
+        </Property>
+      </Proxy>
+      <ExposedProperties>
+        <Property name="Input" proxy_name="ResampleWithDataset1" exposed_name="Input"/>
+        <Property name="Source" proxy_name="ResampleWithDataset1" exposed_name="Source"/>
+      </ExposedProperties>
+      <OutputPort name="Output" proxy="PlotDataOverTime1" port_index="0"/>
+      <Hints>
+        <View type="QuartileChartView" />
+        <WarnOnCreate title="Potentially slow operation">
+          **Plot Selection Over Time** filter needs to process all timesteps
+          available in your dataset and can potentially take a long time to complete.
+          Do you want to continue?
+        </WarnOnCreate>
+        <ShowInMenu/>
+      </Hints>
+    </CompoundSourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ProbePointOverTime/example.med b/src/ProbePointOverTime/example.med
new file mode 100644 (file)
index 0000000..2384856
Binary files /dev/null and b/src/ProbePointOverTime/example.med differ
diff --git a/src/QuadraticToLinear/CMakeLists.txt b/src/QuadraticToLinear/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b9a9435
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(QuadraticToLinearPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/QuadraticToLinear/TestCase.py b/src/QuadraticToLinear/TestCase.py
new file mode 100644 (file)
index 0000000..b02b1e6
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDLoader import *
+
+fname="quadratic.med"
+meshName="mesh"
+coo=DataArrayDouble([(0,-1,0),(1,-1,0),(2,-1,0),#0->3
+                     (-1,0,0),(0,0,0),(1,0,0),(2,0,0),#3->7
+                     (2,1,0),(1,1,0),(0,1,0),#7->10
+                     (-1,0,1),(0,0,1),(1,0,1),#10->13
+                     (0,1,1),(1,1,1)#
+                 ])
+m0=MEDCouplingUMesh(meshName,3) ; m0.setCoords(coo)
+m0.allocateCells()
+m0.insertNextCell(NORM_TETRA4,[5,6,7,12])
+m0.insertNextCell(NORM_PENTA6,[3,9,4,10,13,11])
+m0.insertNextCell(NORM_HEXA8,[4,9,8,5,11,13,14,12]) ; m0.zipCoords()
+m0.convertLinearCellsToQuadratic()
+#
+m1=MEDCouplingUMesh(meshName,2) ; m1.setCoords(coo)
+m1.allocateCells()
+m1.insertNextCell(NORM_TRI3,[3,4,0])
+m1.insertNextCell(NORM_QUAD4,[0,4,5,1]) ; m1.zipCoords()
+m1.convertLinearCellsToQuadratic()
+#
+m2=MEDCouplingUMesh(meshName,1) ; m2.setCoords(coo)
+m2.allocateCells()
+m2.insertNextCell(NORM_SEG2,[1,2]) ; m2.zipCoords()
+m2.convertLinearCellsToQuadratic()
+#
+coos=[m0.getCoords(),m1.getCoords(),m2.getCoords()]
+ncoos=[len(cooElt) for cooElt in coos]
+arr=DataArrayDouble.Aggregate(coos)
+a,b=arr.findCommonTuples(1e-12)
+o2n,newNbNodes=DataArrayInt.ConvertIndexArrayToO2N(len(arr),a,b)
+newArr=arr[o2n.invertArrayO2N2N2O(newNbNodes)]
+#
+m0.renumberNodesInConn(o2n) ; m0.setCoords(newArr)
+m1.renumberNodesInConn(o2n[sum(ncoos[:1]):]) ; m1.setCoords(newArr)
+m2.renumberNodesInConn(o2n[sum(ncoos[:2]):]) ; m2.setCoords(newArr)
+a,b=newArr.areIncludedInMe(coo,1e-12)
+assert(a) ; b.sort()
+nodeIdsNotLinear=b.buildComplement(len(newArr))
+#
+mm=MEDFileUMesh()
+mm[0]=m0 ; mm[-1]=m1 ; mm[-2]=m2
+mm.write(fname,2)
+
+#
+centerOfCloud=[newArr[:,i].accumulate(0)/len(newArr) for i in xrange(newArr.getNumberOfComponents())]
+farr=(newArr-centerOfCloud).magnitude()
+farr[nodeIdsNotLinear]=0.
+zeMax=farr.getMaxValue()[0]
+#
+fieldName="Field"
+ff=MEDFileField1TS()
+f=MEDCouplingFieldDouble(ON_NODES) ; f.setMesh(m0) ; f.setArray(farr) ; f.setName(fieldName) ; f.setTime(0.,0,0)
+ff.setFieldNoProfileSBT(f)
+ff.write(fname,0)
+farr-=zeMax ; farr.abs() ; farr[nodeIdsNotLinear]=0.
+farr.reverse() ; f.setTime(1.,1,0)
+ff.setFieldNoProfileSBT(f)
+ff.write(fname,0)
diff --git a/src/QuadraticToLinear/plugin/CMakeLists.txt b/src/QuadraticToLinear/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a041af6
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(QuadraticToLinearPlugin
+  VERSION "1.0"
+  MODULES QuadraticToLinearModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/QuadraticToLinearModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS QuadraticToLinearPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/QuadraticToLinear/plugin/QuadraticToLinearModule/CMakeLists.txt b/src/QuadraticToLinear/plugin/QuadraticToLinearModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fe7965e
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkQuadraticToLinear
+)
+
+vtk_module_add_module(QuadraticToLinearModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtk.module b/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtk.module
new file mode 100644 (file)
index 0000000..1213ba9
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  QuadraticToLinearModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
diff --git a/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.cxx b/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.cxx
new file mode 100644 (file)
index 0000000..4f86402
--- /dev/null
@@ -0,0 +1,402 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkQuadraticToLinear.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+
+#include <deque>
+#include <map>
+#include <sstream>
+
+vtkStandardNewMacro(vtkQuadraticToLinear);
+
+constexpr int NB_QUAD_TO_LINEAR_1 = 7;
+
+constexpr VTKCellType QUAD_TO_LINEAR_QUAD1[NB_QUAD_TO_LINEAR_1] = {VTK_QUADRATIC_EDGE, VTK_QUADRATIC_TRIANGLE, VTK_QUADRATIC_QUAD, VTK_QUADRATIC_TETRA, VTK_QUADRATIC_WEDGE, VTK_QUADRATIC_PYRAMID, VTK_QUADRATIC_HEXAHEDRON};
+
+constexpr VTKCellType QUAD_TO_LINEAR_LIN1[NB_QUAD_TO_LINEAR_1] = {VTK_LINE, VTK_TRIANGLE, VTK_QUAD, VTK_TETRA, VTK_WEDGE, VTK_PYRAMID, VTK_HEXAHEDRON};
+
+constexpr int NB_QUAD_TO_LINEAR_2 = 4;
+
+constexpr VTKCellType QUAD_TO_LINEAR_QUAD2[NB_QUAD_TO_LINEAR_2] = {VTK_BIQUADRATIC_TRIANGLE, VTK_BIQUADRATIC_QUAD, VTK_BIQUADRATIC_QUADRATIC_WEDGE, VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON};
+
+constexpr VTKCellType QUAD_TO_LINEAR_LIN2[NB_QUAD_TO_LINEAR_2] = {VTK_TRIANGLE, VTK_QUAD, VTK_WEDGE, VTK_HEXAHEDRON};
+
+constexpr int NB_NB_NODES_PER_CELL = 7;
+
+constexpr VTKCellType NB_NODES_PER_CELL_1[NB_NB_NODES_PER_CELL] = {VTK_LINE, VTK_TRIANGLE, VTK_QUAD, VTK_TETRA, VTK_WEDGE, VTK_PYRAMID, VTK_HEXAHEDRON};
+
+constexpr int NB_NODES_PER_CELL_2[NB_NB_NODES_PER_CELL] = {2, 3, 4, 4, 6, 5, 8};
+
+///////////////////
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T *ptr = 0) : _ptr(ptr) {}
+  ~AutoPtr() { destroyPtr(); }
+  AutoPtr &operator=(T *ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T *operator->() { return _ptr; }
+  const T *operator->() const { return _ptr; }
+  T &operator*() { return *_ptr; }
+  const T &operator*() const { return *_ptr; }
+  operator T *() { return _ptr; }
+  operator const T *() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T *_ptr;
+};
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string &s) : _reason(s) {}
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *&usgIn)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw MZCException("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject *input2(input1->GetBlock(0));
+    if (!input2)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+    vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw MZCException("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+}
+
+vtkSmartPointer<vtkDataArray> Reduce(const int *new2Old, int newNbPts, vtkDataArray *array)
+{
+  if (!array)
+    throw MZCException("Reduce : null input vector !");
+  int nbOfCompo(array->GetNumberOfComponents());
+  vtkSmartPointer<vtkDataArray> zeRet;
+  if (vtkDoubleArray::SafeDownCast(array))
+  {
+    vtkSmartPointer<vtkFloatArray> ret(vtkSmartPointer<vtkFloatArray>::New());
+    zeRet = ret;
+    ret->SetNumberOfComponents(nbOfCompo);
+    ret->SetNumberOfTuples(newNbPts);
+    vtkDoubleArray *array1(vtkDoubleArray::SafeDownCast(array));
+    if (array1)
+    {
+      const double *inpCoords(array1->GetPointer(0));
+      float *outCoords(ret->GetPointer(0));
+      for (int i = 0; i < newNbPts; i++, outCoords += nbOfCompo)
+        std::copy(inpCoords + new2Old[i] * nbOfCompo, inpCoords + (new2Old[i] + 1) * nbOfCompo, outCoords);
+    }
+    else
+    {
+      std::ostringstream oss;
+      oss << "Only Double array managed for the moment in input !" << array->GetName();
+      throw MZCException(oss.str());
+    }
+  }
+  else if (vtkIntArray::SafeDownCast(array))
+  {
+    vtkSmartPointer<vtkIntArray> ret(vtkSmartPointer<vtkIntArray>::New());
+    zeRet = ret;
+    ret->SetNumberOfComponents(nbOfCompo);
+    ret->SetNumberOfTuples(newNbPts);
+    vtkIntArray *array1(vtkIntArray::SafeDownCast(array));
+    if (array1)
+    {
+      const int *inpCoords(array1->GetPointer(0));
+      int *outCoords(ret->GetPointer(0));
+      for (int i = 0; i < newNbPts; i++, outCoords += nbOfCompo)
+        std::copy(inpCoords + new2Old[i] * nbOfCompo, inpCoords + (new2Old[i] + 1) * nbOfCompo, outCoords);
+    }
+    else
+    {
+      std::ostringstream oss;
+      oss << "Only int32 array managed for the moment in input !" << array->GetName();
+      throw MZCException(oss.str());
+    }
+  }
+  else
+    throw MZCException("Reduce : unmanaged type !");
+  for (int i = 0; i < nbOfCompo; i++)
+  {
+    const char *compoName(array->GetComponentName(i));
+    zeRet->SetComponentName(i, compoName);
+  }
+  return zeRet;
+}
+
+vtkSmartPointer<vtkUnstructuredGrid> ComputeQuadToLinear(vtkUnstructuredGrid *usg)
+{
+  std::map<VTKCellType, VTKCellType> linToQuad;
+  std::map<VTKCellType, vtkIdType> nbNodesPerType;
+  for (int i = 0; i < NB_QUAD_TO_LINEAR_1; i++)
+    linToQuad[QUAD_TO_LINEAR_QUAD1[i]] = QUAD_TO_LINEAR_LIN1[i];
+  for (int i = 0; i < NB_QUAD_TO_LINEAR_2; i++)
+    linToQuad[QUAD_TO_LINEAR_QUAD2[i]] = QUAD_TO_LINEAR_LIN2[i];
+  for (int i = 0; i < NB_NB_NODES_PER_CELL; i++)
+    nbNodesPerType[NB_NODES_PER_CELL_1[i]] = NB_NODES_PER_CELL_2[i];
+  if (!usg)
+    throw MZCException("ComputeQuadToLinear : null input pointer !");
+  vtkIdType nbPts = usg->GetNumberOfPoints();
+  vtkIdType nbOfCells = usg->GetNumberOfCells();
+  vtkIdType maxNbOfNodesPerCell = 0;
+  std::vector<bool> old2NewVB(nbPts, false);
+  for (vtkIdType i = 0; i < nbOfCells; i++)
+  {
+    vtkCell *cell(usg->GetCell(i));
+    VTKCellType ct((VTKCellType)cell->GetCellType());
+    std::map<VTKCellType, VTKCellType>::const_iterator it(linToQuad.find(ct));
+    if (it != linToQuad.end())
+    {
+      std::map<VTKCellType, vtkIdType>::const_iterator it2(nbNodesPerType.find((*it).second));
+      maxNbOfNodesPerCell = std::max(it2->second, maxNbOfNodesPerCell);
+      for (vtkIdType j = 0; j < (*it2).second; j++)
+      {
+        vtkIdType ptId(cell->GetPointId(j));
+        old2NewVB[ptId] = true;
+      }
+    }
+    else
+    {
+      if (ct != VTK_POLYHEDRON)
+      {
+        vtkIdType nbPtsOfCell = cell->GetNumberOfPoints();
+        maxNbOfNodesPerCell = std::max(nbPtsOfCell, maxNbOfNodesPerCell);
+        for (vtkIdType j = 0; j < nbPtsOfCell; j++)
+        {
+          vtkIdType ptId = cell->GetPointId(j);
+          old2NewVB[ptId] = true;
+        }
+      }
+      else
+        throw MZCException("ComputeQuadToLinear : polyhedrons are not managed yet !");
+    }
+  }
+  int newNbPts(std::count(old2NewVB.begin(), old2NewVB.end(), true));
+  AutoPtr<int> new2Old(new int[newNbPts]), old2New(new int[nbPts]);
+  struct Renumberer
+  {
+    Renumberer(int *pt) : _cnt(0), _pt(pt) {}
+    void operator()(bool v)
+    {
+      if (v)
+      {
+        *(_pt++) = _cnt;
+      }
+      _cnt++;
+    }
+
+  private:
+    int _cnt;
+    int *_pt;
+  };
+  struct RenumbererR
+  {
+    RenumbererR(int *pt) : _cnt(0), _pt(pt) {}
+    void operator()(bool v)
+    {
+      *_pt++ = _cnt;
+      if (v)
+        _cnt++;
+    }
+
+  private:
+    int _cnt;
+    int *_pt;
+  };
+  std::for_each(old2NewVB.begin(), old2NewVB.end(), Renumberer(new2Old));
+  std::for_each(old2NewVB.begin(), old2NewVB.end(), RenumbererR(old2New));
+  //
+  vtkNew<vtkUnstructuredGrid> ret;
+  vtkNew<vtkPoints> pts;
+  // deal with coordinates
+  vtkSmartPointer<vtkDataArray> newCoords(Reduce(new2Old, newNbPts, usg->GetPoints()->GetData()));
+  //
+  ret->Initialize();
+  ret->Allocate(nbOfCells);
+  { // deal with connectivity
+    AutoPtr<vtkIdType> connOfCellTmp(new vtkIdType[maxNbOfNodesPerCell]);
+    for (vtkIdType i = 0; i < nbOfCells; i++)
+    {
+      vtkCell *cell(usg->GetCell(i));
+      VTKCellType ct((VTKCellType)cell->GetCellType());
+      std::map<VTKCellType, VTKCellType>::const_iterator it(linToQuad.find(ct));
+      if (it != linToQuad.end())
+      {
+        std::map<VTKCellType, vtkIdType>::const_iterator it2(nbNodesPerType.find(it->second));
+        for (vtkIdType j = 0; j < it2->second; j++)
+          connOfCellTmp[j] = old2New[cell->GetPointId(j)];
+        ret->InsertNextCell(it->second, it2->second, connOfCellTmp);
+      }
+      else
+      {
+        vtkIdType nbPtsOfCell(cell->GetNumberOfPoints());
+        for (vtkIdType j = 0; j < nbPtsOfCell; j++)
+          connOfCellTmp[j] = old2New[cell->GetPointId(j)];
+        ret->InsertNextCell(ct, nbPtsOfCell, connOfCellTmp);
+      }
+    }
+  }
+  ret->SetPoints(pts);
+  pts->SetData(newCoords);
+  // Deal with cell fields
+  if (usg->GetCellData())
+  {
+    ret->GetCellData()->ShallowCopy(usg->GetCellData());
+  }
+  if (usg->GetPointData())
+  {
+    vtkPointData *pd(usg->GetPointData());
+    for (int i = 0; i < pd->GetNumberOfArrays(); i++)
+    {
+      vtkSmartPointer<vtkDataArray> arr(Reduce(new2Old, newNbPts, pd->GetArray(i)));
+      arr->SetName(pd->GetArray(i)->GetName());
+      ret->GetPointData()->AddArray(arr);
+    }
+  }
+  //
+  return ret;
+}
+
+////////////////////
+
+int vtkQuadraticToLinear::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkQuadraticToLinear::RequestInformation ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+  }
+  catch (MZCException &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkQuadraticToLinear::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+int vtkQuadraticToLinear::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkQuadraticToLinear::RequestData        ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkSmartPointer<vtkUnstructuredGrid> ret(ComputeQuadToLinear(usgIn));
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    output->ShallowCopy(ret);
+  }
+  catch (MZCException &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkQuadraticToLinear::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void vtkQuadraticToLinear::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+/*
+(cd /home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501 ; export CURRENT_SOFTWARE_SRC_DIR=/home/H87074/salome/DEV/tools/src/PARAVISADDONS ; export CURRENT_SOFTWARE_BUILD_DIR=/home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501 ; export CURRENT_SOFTWARE_INSTALL_DIR=/home/H87074/salome/DEV/tools/install/Paravisaddons-master-cm302-pv501 ; export PYTHON_VERSION="2.7" ; . /home/H87074/salome/DEV/salome_modules.sh >/dev/null 2>&1 ; . /home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501/.yamm/env_build.sh >/dev/null 2>&1 ; . /home/H87074/salome/DEV/salome_prerequisites.sh >/dev/null 2>&1 ; cmake -DCMAKE_INSTALL_PREFIX=/home/H87074/salome/DEV/tools/install/Paravisaddons-master-cm302-pv501   -DCMAKE_MODULE_PATH=${CONFIGURATION_CMAKE_DIR}   -DCMAKE_BUILD_TYPE=Debug  /home/H87074/salome/DEV/tools/src/PARAVISADDONS )
+
+(cd /home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501/QuadraticToLinear ; export CURRENT_SOFTWARE_SRC_DIR=/home/H87074/salome/DEV/tools/src/PARAVISADDONS ; export CURRENT_SOFTWARE_BUILD_DIR=/home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501 ; export CURRENT_SOFTWARE_INSTALL_DIR=/home/H87074/salome/DEV/tools/install/Paravisaddons-master-cm302-pv501 ; export PYTHON_VERSION="2.7" ; . /home/H87074/salome/DEV/salome_modules.sh >/dev/null 2>&1 ; . /home/H87074/salome/DEV/tools/build/Paravisaddons-master-cm302-pv501/.yamm/env_build.sh >/dev/null 2>&1 ; . /home/H87074/salome/DEV/salome_prerequisites.sh >/dev/null 2>&1 ; make -j8 install )
+
+/home/H87074/salome/prerequisites/src/ParaView/VTK/Common/DataModel/vtkCellType.h:87
+*/
diff --git a/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.h b/src/QuadraticToLinear/plugin/QuadraticToLinearModule/vtkQuadraticToLinear.h
new file mode 100644 (file)
index 0000000..6f732ea
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkQuadraticToLinear_h__
+#define vtkQuadraticToLinear_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkQuadraticToLinear : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkQuadraticToLinear *New();
+  vtkTypeMacro(vtkQuadraticToLinear, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+protected:
+  vtkQuadraticToLinear() = default;
+  ~vtkQuadraticToLinear() override = default;
+
+  int RequestInformation(vtkInformation *request,
+                         vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
+
+  int RequestData(vtkInformation *request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector) override;
+
+private:
+  vtkQuadraticToLinear(const vtkQuadraticToLinear &) = delete;
+  void operator=(const vtkQuadraticToLinear &) = delete;
+};
+
+#endif
diff --git a/src/QuadraticToLinear/plugin/filters.xml b/src/QuadraticToLinear/plugin/filters.xml
new file mode 100644 (file)
index 0000000..8897072
--- /dev/null
@@ -0,0 +1,21 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="QuadraticToLinear"
+                 class="vtkQuadraticToLinear"
+                 label="Quadratic To Linear">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid"/>
+        </DataTypeDomain>
+        <Documentation>
+         This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/QuadraticToLinear/plugin/paraview.plugin b/src/QuadraticToLinear/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..c52e04b
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  QuadraticToLinearPlugin
+DESCRIPTION
+  This plugin provides the QuadraticToLinear filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/RateOfFlowThroughSection/CMakeLists.txt b/src/RateOfFlowThroughSection/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f8b150e
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(RateOfFlowThroughSection)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set(PARAVIEW_PLUGIN_ENABLE_RateOfFlowThroughSection TRUE)
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/RateOfFlowThroughSection/plugin/CMakeLists.txt b/src/RateOfFlowThroughSection/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bb43260
--- /dev/null
@@ -0,0 +1,60 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Common CMake macros
+# ===================
+SET(TMP_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+SET(MEDCOUPLING_ROOT_DIR $ENV{MEDCOUPLING_ROOT_DIR} CACHE PATH "Path to the MEDCoupling tool")
+IF(EXISTS ${MEDCOUPLING_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${MEDCOUPLING_ROOT_DIR}/cmake_files")
+ENDIF()
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
+LIST(APPEND CMAKE_MODULE_PATH ${TMP_CMAKE_MODULE_PATH})
+
+INCLUDE(SalomeSetupPlatform)
+SET(BUILD_SHARED_LIBS TRUE)
+
+FIND_PACKAGE(SalomeHDF5 REQUIRED)
+FIND_PACKAGE(SalomeMEDCoupling REQUIRED)
+
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}
+                                                 ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON})
+SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS})
+SALOME_ACCUMULATE_ENVIRONMENT(PV_PLUGIN_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/lib/paraview)
+
+paraview_add_plugin(RateOfFlowThroughSectionPlugin
+  VERSION "1.0"
+  MODULES RateOfFlowThroughSectionModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/RateOfFlowThroughSectionModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+install(TARGETS RateOfFlowThroughSectionPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/CMakeLists.txt b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4a38fcb
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkRateOfFlowThroughSection
+  vtkExplodePolyLine
+  vtkSedimentDeposit
+  VTKToMEDMem
+)
+
+vtk_module_add_module(RateOfFlowThroughSectionModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
+
+target_include_directories(RateOfFlowThroughSectionModule PUBLIC ${MEDCOUPLING_INCLUDE_DIRS})
+
+if(HDF5_IS_PARALLEL)
+  target_link_libraries(RateOfFlowThroughSectionModule PRIVATE ${MEDCoupling_paramedloader})
+else()
+  target_link_libraries(RateOfFlowThroughSectionModule PRIVATE ${MEDCoupling_medloader})
+endif()
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKMEDTraits.hxx b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKMEDTraits.hxx
new file mode 100644 (file)
index 0000000..4c7832d
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __VTKMEDTRAITS_HXX__
+#define __VTKMEDTRAITS_HXX__
+
+class vtkIntArray;
+class vtkLongArray;
+#ifdef WIN32
+class vtkLongLongArray;
+#endif
+class vtkFloatArray;
+class vtkDoubleArray;
+
+template<class T>
+class MEDFileVTKTraits
+{
+public:
+  typedef void VtkType;
+  typedef void MCType;
+};
+
+template<>
+class MEDFileVTKTraits<int>
+{
+public:
+  typedef vtkIntArray VtkType;
+  typedef MEDCoupling::DataArrayInt32 MCType;
+};
+
+template<>
+#ifdef WIN32
+class MEDFileVTKTraits<long long>
+#else 
+class MEDFileVTKTraits<long>
+#endif
+#
+{
+public:
+#ifdef WIN32
+  typedef vtkLongLongArray VtkType;
+#else
+  typedef vtkLongArray VtkType;
+#endif
+  typedef MEDCoupling::DataArrayInt64 MCType;
+};
+
+template<>
+class MEDFileVTKTraits<float>
+{
+public:
+  typedef vtkFloatArray VtkType;
+  typedef MEDCoupling::DataArrayFloat MCType;
+};
+
+template<>
+class MEDFileVTKTraits<double>
+{
+public:
+  typedef vtkDoubleArray VtkType;
+  typedef MEDCoupling::DataArrayDouble MCType;
+};
+
+#endif
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.cxx b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.cxx
new file mode 100644 (file)
index 0000000..5792221
--- /dev/null
@@ -0,0 +1,962 @@
+// Copyright (C) 2017-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "VTKToMEDMem.h"
+
+#include "vtkAdjacentVertexIterator.h"
+#include "vtkIntArray.h"
+#include "vtkLongArray.h"
+#include "vtkCellData.h"
+#include "vtkPointData.h"
+#include "vtkFloatArray.h"
+#include "vtkCellArray.h"
+
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkInformationDataObjectMetaDataKey.h"
+#include "vtkUnstructuredGrid.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkRectilinearGrid.h"
+#include "vtkInformationStringKey.h"
+#include "vtkAlgorithmOutput.h"
+#include "vtkObjectFactory.h"
+#include "vtkMutableDirectedGraph.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkPolyData.h"
+#include "vtkDataSet.h"
+#include "vtkInformationVector.h"
+#include "vtkInformation.h"
+#include "vtkDataArraySelection.h"
+#include "vtkTimeStamp.h"
+#include "vtkInEdgeIterator.h"
+#include "vtkInformationDataObjectKey.h"
+#include "vtkExecutive.h"
+#include "vtkVariantArray.h"
+#include "vtkStringArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkCharArray.h"
+#include "vtkUnsignedCharArray.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkDemandDrivenPipeline.h"
+#include "vtkDataObjectTreeIterator.h"
+#include "vtkWarpScalar.h"
+
+#include <map>
+#include <deque>
+#include <sstream>
+#include <cstring>
+
+using VTKToMEDMem::Grp;
+using VTKToMEDMem::Fam;
+
+using MEDCoupling::MEDFileData;
+using MEDCoupling::MEDFileMesh;
+using MEDCoupling::MEDFileCMesh;
+using MEDCoupling::MEDFileUMesh;
+using MEDCoupling::MEDFileFields;
+using MEDCoupling::MEDFileMeshes;
+
+using MEDCoupling::MEDFileInt32Field1TS;
+using MEDCoupling::MEDFileInt64Field1TS;
+using MEDCoupling::MEDFileField1TS;
+using MEDCoupling::MEDFileIntFieldMultiTS;
+using MEDCoupling::MEDFileFieldMultiTS;
+using MEDCoupling::MEDFileAnyTypeFieldMultiTS;
+using MEDCoupling::DataArray;
+using MEDCoupling::DataArrayInt32;
+using MEDCoupling::DataArrayInt64;
+using MEDCoupling::DataArrayFloat;
+using MEDCoupling::DataArrayDouble;
+using MEDCoupling::MEDCouplingMesh;
+using MEDCoupling::MEDCouplingUMesh;
+using MEDCoupling::MEDCouplingCMesh;
+using MEDCoupling::MEDCouplingFieldDouble;
+using MEDCoupling::MEDCouplingFieldFloat;
+using MEDCoupling::MEDCouplingFieldInt;
+using MEDCoupling::MEDCouplingFieldInt64;
+using MEDCoupling::MCAuto;
+using MEDCoupling::Traits;
+using MEDCoupling::MLFieldTraits;
+
+///////////////////
+
+Fam::Fam(const std::string& name)
+{
+  static const char ZE_SEP[]="@@][@@";
+  std::size_t pos(name.find(ZE_SEP));
+  std::string name0(name.substr(0,pos)),name1(name.substr(pos+strlen(ZE_SEP)));
+  std::istringstream iss(name1);
+  iss >> _id;
+  _name=name0;
+}
+
+///////////////////
+
+#include "VTKMEDTraits.hxx"
+
+std::map<int,int> ComputeMapOfType()
+{
+  std::map<int,int> ret;
+  int nbOfTypesInMC(sizeof(MEDCOUPLING2VTKTYPETRADUCER)/sizeof( decltype(MEDCOUPLING2VTKTYPETRADUCER[0]) ));
+  for(int i=0;i<nbOfTypesInMC;i++)
+    {
+      auto vtkId(MEDCOUPLING2VTKTYPETRADUCER[i]);
+      if(vtkId!=MEDCOUPLING2VTKTYPETRADUCER_NONE)
+        ret[vtkId]=i;
+    }
+  return ret;
+}
+
+std::string GetMeshNameWithContext(const std::vector<int>& context)
+{
+  static const char DFT_MESH_NAME[]="Mesh";
+  if(context.empty())
+    return DFT_MESH_NAME;
+  std::ostringstream oss; oss << DFT_MESH_NAME;
+  for(std::vector<int>::const_iterator it=context.begin();it!=context.end();it++)
+    oss << "_" << *it;
+  return oss.str();
+}
+
+DataArrayIdType *ConvertVTKArrayToMCArrayInt(vtkDataArray *data)
+{
+  if(!data)
+    throw MZCException("ConvertVTKArrayToMCArrayInt : internal error !");
+  int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
+  std::size_t nbElts(nbTuples*nbComp);
+  MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
+  ret->alloc(nbTuples,nbComp);
+  for(int i=0;i<nbComp;i++)
+    {
+      const char *comp(data->GetComponentName(i));
+      if(comp)
+        ret->setInfoOnComponent(i,comp);
+    }
+  mcIdType *ptOut(ret->getPointer());
+  vtkIntArray *d0(vtkIntArray::SafeDownCast(data));
+  if(d0)
+    {
+      const int *pt(d0->GetPointer(0));
+      std::copy(pt,pt+nbElts,ptOut);
+      return ret.retn();
+    }
+  vtkLongArray *d1(vtkLongArray::SafeDownCast(data));
+  if(d1)
+    {
+      const long *pt(d1->GetPointer(0));
+      std::copy(pt,pt+nbElts,ptOut);
+      return ret.retn();
+    }
+  vtkIdTypeArray *d3(vtkIdTypeArray::SafeDownCast(data));
+  if(d3)
+    {
+      const vtkIdType *pt(d3->GetPointer(0));
+      std::copy(pt,pt+nbElts,ptOut);
+      return ret.retn();
+    }
+  vtkUnsignedCharArray *d2(vtkUnsignedCharArray::SafeDownCast(data));
+  if(d2)
+    {
+      const unsigned char *pt(d2->GetPointer(0));
+      std::copy(pt,pt+nbElts,ptOut);
+      return ret.retn();
+    }
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArrayInt : unrecognized array \"" << typeid(*data).name() << "\" type !";
+  throw MZCException(oss.str());
+}
+
+template<class T>
+typename Traits<T>::ArrayType *ConvertVTKArrayToMCArrayDouble(vtkDataArray *data)
+{
+  if(!data)
+    throw MZCException("ConvertVTKArrayToMCArrayDouble : internal error !");
+  int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
+  std::size_t nbElts(nbTuples*nbComp);
+  MCAuto< typename Traits<T>::ArrayType > ret(Traits<T>::ArrayType::New());
+  ret->alloc(nbTuples,nbComp);
+  for(int i=0;i<nbComp;i++)
+    {
+      const char *comp(data->GetComponentName(i));
+      if(comp)
+        ret->setInfoOnComponent(i,comp);
+      else
+        {
+          if(nbComp>1 && nbComp<=3)
+            {
+              char tmp[2];
+              tmp[0]=(char)('X'+i); tmp[1]='\0';
+              ret->setInfoOnComponent(i,tmp);
+            }
+        }
+    }
+  T *ptOut(ret->getPointer());
+  typename MEDFileVTKTraits<T>::VtkType *d0(MEDFileVTKTraits<T>::VtkType::SafeDownCast(data));
+  if(d0)
+    {
+      const T *pt(d0->GetPointer(0));
+      for(std::size_t i=0;i<nbElts;i++)
+        ptOut[i]=(T)pt[i];
+      return ret.retn();
+    }
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << data->GetClassName() << "\" type !";
+  throw MZCException(oss.str());
+}
+
+DataArrayDouble *ConvertVTKArrayToMCArrayDoubleForced(vtkDataArray *data)
+{
+  if(!data)
+    throw MZCException("ConvertVTKArrayToMCArrayDoubleForced : internal error 0 !");
+  vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
+  if(d0)
+    {
+      MCAuto<DataArrayFloat> ret(ConvertVTKArrayToMCArrayDouble<float>(data));
+      MCAuto<DataArrayDouble> ret2(ret->convertToDblArr());
+      return ret2.retn();
+    }
+  vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
+  if(d1)
+    return ConvertVTKArrayToMCArrayDouble<double>(data);
+  throw MZCException("ConvertVTKArrayToMCArrayDoubleForced : unrecognized type of data for double !");
+}
+
+DataArray *ConvertVTKArrayToMCArray(vtkDataArray *data)
+{
+  if(!data)
+    throw MZCException("ConvertVTKArrayToMCArray : internal error !");
+  vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
+  if(d0)
+    return ConvertVTKArrayToMCArrayDouble<float>(data);
+  vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
+  if(d1)
+    return ConvertVTKArrayToMCArrayDouble<double>(data);
+  vtkIntArray *d2(vtkIntArray::SafeDownCast(data));
+  vtkLongArray *d3(vtkLongArray::SafeDownCast(data));
+  vtkUnsignedCharArray *d4(vtkUnsignedCharArray::SafeDownCast(data));
+  vtkIdTypeArray *d5(vtkIdTypeArray::SafeDownCast(data));
+  if(d2 || d3 || d4 || d5)
+    return ConvertVTKArrayToMCArrayInt(data);
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArray : unrecognized array \"" << typeid(*data).name() << "\" type !";
+  throw MZCException(oss.str());
+}
+
+MEDCouplingUMesh *BuildMeshFromCellArray(vtkCellArray *ca, DataArrayDouble *coords, int meshDim, INTERP_KERNEL::NormalizedCellType type)
+{
+  MCAuto<MEDCouplingUMesh> subMesh(MEDCouplingUMesh::New("",meshDim));
+  subMesh->setCoords(coords); subMesh->allocateCells();
+  int nbCells(ca->GetNumberOfCells());
+  if(nbCells==0)
+    return 0;
+  //vtkIdType nbEntries(ca->GetNumberOfConnectivityEntries()); // todo: unused
+  const vtkIdType *conn(ca->GetData()->GetPointer(0));
+  for(int i=0;i<nbCells;i++)
+    {
+      mcIdType sz(ToIdType(*conn++));
+      std::vector<mcIdType> conn2(sz);
+      for(int jj=0;jj<sz;jj++)
+        conn2[jj]=ToIdType(conn[jj]);
+      subMesh->insertNextCell(type,sz,&conn2[0]);
+      conn+=sz;
+    }
+  return subMesh.retn();
+}
+
+MEDCouplingUMesh *BuildMeshFromCellArrayTriangleStrip(vtkCellArray *ca, DataArrayDouble *coords, MCAuto<DataArrayIdType>& ids)
+{
+  MCAuto<MEDCouplingUMesh> subMesh(MEDCouplingUMesh::New("",2));
+  subMesh->setCoords(coords); subMesh->allocateCells();
+  int nbCells(ca->GetNumberOfCells());
+  if(nbCells==0)
+    return 0;
+  //vtkIdType nbEntries(ca->GetNumberOfConnectivityEntries()); // todo: unused
+  const vtkIdType *conn(ca->GetData()->GetPointer(0));
+  ids=DataArrayIdType::New() ; ids->alloc(0,1);
+  for(int i=0;i<nbCells;i++)
+    {
+      int sz(*conn++);
+      int nbTri(sz-2);
+      if(nbTri>0)
+        {
+          for(int j=0;j<nbTri;j++,conn++)
+            {
+              mcIdType conn2[3]; conn2[0]=conn[0] ; conn2[1]=conn[1] ; conn2[2]=conn[2];
+              subMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn2);
+              ids->pushBackSilent(i);
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "BuildMeshFromCellArrayTriangleStrip : on cell #" << i << " the triangle stip looks bab !";
+          throw MZCException(oss.str());
+        }
+      conn+=sz;
+    }
+  return subMesh.retn();
+}
+
+class MicroField
+{
+public:
+  MicroField(const MCAuto<MEDCouplingUMesh>& m, const std::vector<MCAuto<DataArray> >& cellFs):_m(m),_cellFs(cellFs) { }
+  MicroField(const std::vector< MicroField >& vs);
+  void setNodeFields(const std::vector<MCAuto<DataArray> >& nf) { _nodeFs=nf; }
+  MCAuto<MEDCouplingUMesh> getMesh() const { return _m; }
+  std::vector<MCAuto<DataArray> > getCellFields() const { return _cellFs; }
+private:
+  MCAuto<MEDCouplingUMesh> _m;
+  std::vector<MCAuto<DataArray> > _cellFs;
+  std::vector<MCAuto<DataArray> > _nodeFs;
+};
+
+MicroField::MicroField(const std::vector< MicroField >& vs)
+{
+  std::size_t sz(vs.size());
+  std::vector<const MEDCouplingUMesh *> vs2(sz);
+  std::vector< std::vector< MCAuto<DataArray> > > arrs2(sz);
+  int nbElts(-1);
+  for(std::size_t ii=0;ii<sz;ii++)
+    {
+      vs2[ii]=vs[ii].getMesh();
+      arrs2[ii]=vs[ii].getCellFields();
+      if(nbElts<0)
+        nbElts=(int)arrs2[ii].size();
+      else
+        if((int)arrs2[ii].size()!=nbElts)
+          throw MZCException("MicroField cstor : internal error !");
+    }
+  _cellFs.resize(nbElts);
+  for(int ii=0;ii<nbElts;ii++)
+    {
+      std::vector<const DataArray *> arrsTmp(sz);
+      for(std::size_t jj=0;jj<sz;jj++)
+        {
+          arrsTmp[jj]=arrs2[jj][ii];
+        }
+      _cellFs[ii]=DataArray::Aggregate(arrsTmp);
+    }
+  _m=MEDCouplingUMesh::MergeUMeshesOnSameCoords(vs2);
+}
+
+template<class T>
+void AppendToFields(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, const DataArrayIdType *n2oPtr, typename MEDFileVTKTraits<T>::MCType *dadPtr, MEDFileFields *fs, double timeStep, int tsId)
+{
+  std::string fieldName(dadPtr->getName());
+  MCAuto< typename Traits<T>::FieldType > f(Traits<T>::FieldType::New(tf));
+  f->setTime(timeStep,tsId,0);
+  {
+    std::string fieldNameForChuckNorris(MEDCoupling::MEDFileAnyTypeField1TSWithoutSDA::FieldNameToMEDFileConvention(fieldName));
+    f->setName(fieldNameForChuckNorris);
+  }
+  if(!n2oPtr)
+    f->setArray(dadPtr);
+  else
+    {
+      MCAuto< typename Traits<T>::ArrayType > dad2(dadPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
+      f->setArray(dad2);
+    }
+  f->setMesh(mesh);
+  MCAuto< typename MLFieldTraits<T>::FMTSType > fmts(MLFieldTraits<T>::FMTSType::New());
+  MCAuto< typename MLFieldTraits<T>::F1TSType > f1ts(MLFieldTraits<T>::F1TSType::New());
+  f1ts->setFieldNoProfileSBT(f);
+  fmts->pushBackTimeStep(f1ts);
+  fs->pushField(fmts);
+}
+
+void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFileData *mfd, MCAuto<DataArray> da, const DataArrayIdType *n2oPtr, double timeStep, int tsId)
+{
+  static const char FAMFIELD_FOR_CELLS[]="FamilyIdCell";
+  static const char FAMFIELD_FOR_NODES[]="FamilyIdNode";
+  if(!da || !mesh || !mfd)
+    throw MZCException("AppendMCFieldFrom : internal error !");
+  MEDFileFields *fs(mfd->getFields());
+  MEDFileMeshes *ms(mfd->getMeshes());
+  if(!fs || !ms)
+    throw MZCException("AppendMCFieldFrom : internal error 2 !");
+  MCAuto<DataArrayDouble> dad(MEDCoupling::DynamicCast<DataArray,DataArrayDouble>(da));
+  if(dad.isNotNull())
+    {
+      AppendToFields<double>(tf,mesh,n2oPtr,dad,fs,timeStep,tsId);
+      return ;
+    }
+  MCAuto<DataArrayFloat> daf(MEDCoupling::DynamicCast<DataArray,DataArrayFloat>(da));
+  if(daf.isNotNull())
+    {
+      AppendToFields<float>(tf,mesh,n2oPtr,daf,fs,timeStep,tsId);
+      return ;
+    }
+  MCAuto<DataArrayInt> dai(MEDCoupling::DynamicCast<DataArray,DataArrayInt>(da));
+  MCAuto<DataArrayIdType> daId(MEDCoupling::DynamicCast<DataArray,DataArrayIdType>(da));
+  if(dai.isNotNull() || daId.isNotNull())
+    {
+      std::string fieldName(da->getName());
+      if((fieldName!=FAMFIELD_FOR_CELLS || tf!=MEDCoupling::ON_CELLS) && (fieldName!=FAMFIELD_FOR_NODES || tf!=MEDCoupling::ON_NODES))
+        {
+          if(!dai)
+            AppendToFields<mcIdType>(tf,mesh,n2oPtr,daId,fs,timeStep,tsId);
+          else
+            AppendToFields<int>(tf,mesh,n2oPtr,dai,fs,timeStep,tsId);
+          return ;
+        }
+      else if(fieldName==FAMFIELD_FOR_CELLS && tf==MEDCoupling::ON_CELLS)
+        {
+          MEDFileMesh *mm(ms->getMeshWithName(mesh->getName()));
+          if(!mm)
+            throw MZCException("AppendMCFieldFrom : internal error 3 !");
+          if(!daId)
+            throw MZCException("AppendMCFieldFrom : internal error 3 (not mcIdType) !");
+          if(!n2oPtr)
+            mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),daId);
+          else
+            {
+              MCAuto<DataArrayIdType> dai2(daId->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
+              mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),dai2);
+            }
+        }
+      else if(fieldName==FAMFIELD_FOR_NODES || tf==MEDCoupling::ON_NODES)
+        {
+          MEDFileMesh *mm(ms->getMeshWithName(mesh->getName()));
+          if(!mm)
+            throw MZCException("AppendMCFieldFrom : internal error 4 !");
+          if(!daId)
+            throw MZCException("AppendMCFieldFrom : internal error 4 (not mcIdType) !");
+          if(!n2oPtr)
+            mm->setFamilyFieldArr(1,daId);
+          else
+            {
+              MCAuto<DataArrayIdType> dai2(daId->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
+              mm->setFamilyFieldArr(1,dai2);
+            }
+        }
+    }
+}
+
+void PutAtLevelDealOrder(MEDFileData *mfd, int meshDimRel, const MicroField& mf, double timeStep, int tsId)
+{
+  if(!mfd)
+    throw MZCException("PutAtLevelDealOrder : internal error !");
+  MEDFileMesh *mm(mfd->getMeshes()->getMeshAtPos(0));
+  MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
+  if(!mmu)
+    throw MZCException("PutAtLevelDealOrder : internal error 2 !");
+  MCAuto<MEDCouplingUMesh> mesh(mf.getMesh());
+  mesh->setName(mfd->getMeshes()->getMeshAtPos(0)->getName());
+  MCAuto<DataArrayIdType> o2n(mesh->sortCellsInMEDFileFrmt());
+  //const DataArrayIdType *o2nPtr(o2n); // todo: unused
+  MCAuto<DataArrayIdType> n2o;
+  mmu->setMeshAtLevel(meshDimRel,mesh);
+  const DataArrayIdType *n2oPtr(0);
+  if(o2n)
+    {
+      n2o=o2n->invertArrayO2N2N2O(mesh->getNumberOfCells());
+      n2oPtr=n2o;
+      if(n2oPtr && n2oPtr->isIota(mesh->getNumberOfCells()))
+        n2oPtr=0;
+      if(n2oPtr)
+        mm->setRenumFieldArr(meshDimRel,n2o);
+    }
+  //
+  std::vector<MCAuto<DataArray> > cells(mf.getCellFields());
+  for(std::vector<MCAuto<DataArray> >::const_iterator it=cells.begin();it!=cells.end();it++)
+    {
+      MCAuto<DataArray> da(*it);
+      AppendMCFieldFrom(MEDCoupling::ON_CELLS,mesh,mfd,da,n2oPtr,timeStep,tsId);
+    }
+}
+
+void AssignSingleGTMeshes(MEDFileData *mfd, const std::vector< MicroField >& ms, double timeStep, int tsId)
+{
+  if(!mfd)
+    throw MZCException("AssignSingleGTMeshes : internal error !");
+  MEDFileMesh *mm0(mfd->getMeshes()->getMeshAtPos(0));
+  MEDFileUMesh *mm(dynamic_cast<MEDFileUMesh *>(mm0));
+  if(!mm)
+    throw MZCException("AssignSingleGTMeshes : internal error 2 !");
+  int meshDim(-std::numeric_limits<int>::max());
+  std::map<int, std::vector< MicroField > > ms2;
+  for(std::vector< MicroField >::const_iterator it=ms.begin();it!=ms.end();it++)
+    {
+      const MEDCouplingUMesh *elt((*it).getMesh());
+      if(elt)
+        {
+          int myMeshDim(elt->getMeshDimension());
+          meshDim=std::max(meshDim,myMeshDim);
+          ms2[myMeshDim].push_back(*it);
+        }
+    }
+  if(ms2.empty())
+    return ;
+  for(std::map<int, std::vector< MicroField > >::const_iterator it=ms2.begin();it!=ms2.end();it++)
+    {
+      const std::vector< MicroField >& vs((*it).second);
+      if(vs.size()==1)
+        {
+          PutAtLevelDealOrder(mfd,(*it).first-meshDim,vs[0],timeStep,tsId);
+        }
+      else
+        {
+          MicroField merge(vs);
+          PutAtLevelDealOrder(mfd,(*it).first-meshDim,merge,timeStep,tsId);
+        }
+    }
+}
+
+DataArrayDouble *BuildCoordsFrom(vtkPointSet *ds)
+{
+  if(!ds)
+    throw MZCException("BuildCoordsFrom : internal error !");
+  vtkPoints *pts(ds->GetPoints());
+  if(!pts)
+    throw MZCException("BuildCoordsFrom : internal error 2 !");
+  vtkDataArray *data(pts->GetData());
+  if(!data)
+    throw MZCException("BuildCoordsFrom : internal error 3 !");
+  return ConvertVTKArrayToMCArrayDoubleForced(data);
+}
+
+void AddNodeFields(MEDFileData *mfd, vtkDataSetAttributes *dsa, double timeStep, int tsId)
+{
+  if(!mfd || !dsa)
+    throw MZCException("AddNodeFields : internal error !");
+  MEDFileMesh *mm(mfd->getMeshes()->getMeshAtPos(0));
+  MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
+  if(!mmu)
+    throw MZCException("AddNodeFields : internal error 2 !");
+  MCAuto<MEDCouplingUMesh> mesh;
+  if(!mmu->getNonEmptyLevels().empty())
+    mesh=mmu->getMeshAtLevel(0);
+  else
+    {
+      mesh=MEDCouplingUMesh::Build0DMeshFromCoords(mmu->getCoords());
+      mesh->setName(mmu->getName());
+    }
+  int nba(dsa->GetNumberOfArrays());
+  for(int i=0;i<nba;i++)
+    {
+      vtkDataArray *arr(dsa->GetArray(i));
+      const char *name(arr->GetName());
+      if(!arr)
+        continue;
+      MCAuto<DataArray> da(ConvertVTKArrayToMCArray(arr));
+      da->setName(name);
+      AppendMCFieldFrom(MEDCoupling::ON_NODES,mesh,mfd,da,NULL,timeStep,tsId);
+    }
+}
+
+std::vector<MCAuto<DataArray> > AddPartFields(const DataArrayIdType *part, vtkDataSetAttributes *dsa)
+{
+  std::vector< MCAuto<DataArray> > ret;
+  if(!dsa)
+    return ret;
+  int nba(dsa->GetNumberOfArrays());
+  for(int i=0;i<nba;i++)
+    {
+      vtkDataArray *arr(dsa->GetArray(i));
+      if(!arr)
+        continue;
+      const char *name(arr->GetName());
+      //int nbCompo(arr->GetNumberOfComponents()); // todo: unused
+      //vtkIdType nbTuples(arr->GetNumberOfTuples()); // todo: unused
+      MCAuto<DataArray> mcarr(ConvertVTKArrayToMCArray(arr));
+      if(part)
+        mcarr=mcarr->selectByTupleId(part->begin(),part->end());
+      mcarr->setName(name);
+      ret.push_back(mcarr);
+    }
+  return ret;
+}
+
+std::vector<MCAuto<DataArray> > AddPartFields2(int bg, int end, vtkDataSetAttributes *dsa)
+{
+  std::vector< MCAuto<DataArray> > ret;
+  if(!dsa)
+    return ret;
+  int nba(dsa->GetNumberOfArrays());
+  for(int i=0;i<nba;i++)
+    {
+      vtkDataArray *arr(dsa->GetArray(i));
+      if(!arr)
+        continue;
+      const char *name(arr->GetName());
+      //int nbCompo(arr->GetNumberOfComponents()); // todo: unused
+      //vtkIdType nbTuples(arr->GetNumberOfTuples()); // todo: unused
+      MCAuto<DataArray> mcarr(ConvertVTKArrayToMCArray(arr));
+      mcarr=mcarr->selectByTupleIdSafeSlice(bg,end,1);
+      mcarr->setName(name);
+      ret.push_back(mcarr);
+    }
+  return ret;
+}
+
+void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const std::vector<int>& context, double timeStep, int tsId)
+{
+  if(!ds || !ret)
+    throw MZCException("ConvertFromRectilinearGrid : internal error !");
+  //
+  MCAuto<MEDFileMeshes> meshes(MEDFileMeshes::New());
+  ret->setMeshes(meshes);
+  MCAuto<MEDFileFields> fields(MEDFileFields::New());
+  ret->setFields(fields);
+  //
+  MCAuto<MEDFileCMesh> cmesh(MEDFileCMesh::New());
+  meshes->pushMesh(cmesh);
+  MCAuto<MEDCouplingCMesh> cmeshmc(MEDCouplingCMesh::New());
+  vtkDataArray *cx(ds->GetXCoordinates()),*cy(ds->GetYCoordinates()),*cz(ds->GetZCoordinates());
+  if(cx)
+    {
+      MCAuto<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDoubleForced(cx));
+      cmeshmc->setCoordsAt(0,arr);
+    }
+  if(cy)
+    {
+      MCAuto<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDoubleForced(cy));
+      cmeshmc->setCoordsAt(1,arr);
+    }
+  if(cz)
+    {
+      MCAuto<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDoubleForced(cz));
+      cmeshmc->setCoordsAt(2,arr);
+    }
+  std::string meshName(GetMeshNameWithContext(context));
+  cmeshmc->setName(meshName);
+  cmesh->setMesh(cmeshmc);
+  std::vector<MCAuto<DataArray> > cellFs(AddPartFields(0,ds->GetCellData()));
+  for(std::vector<MCAuto<DataArray> >::const_iterator it=cellFs.begin();it!=cellFs.end();it++)
+    {
+      MCAuto<DataArray> da(*it);
+      AppendMCFieldFrom(MEDCoupling::ON_CELLS,cmeshmc,ret,da,NULL,timeStep,tsId);
+    }
+  std::vector<MCAuto<DataArray> > nodeFs(AddPartFields(0,ds->GetPointData()));
+  for(std::vector<MCAuto<DataArray> >::const_iterator it=nodeFs.begin();it!=nodeFs.end();it++)
+    {
+      MCAuto<DataArray> da(*it);
+      AppendMCFieldFrom(MEDCoupling::ON_NODES,cmeshmc,ret,da,NULL,timeStep,tsId);
+    }
+}
+
+void ConvertFromPolyData(MEDFileData *ret, vtkPolyData *ds, const std::vector<int>& context, double timeStep, int tsId)
+{
+  if(!ds || !ret)
+    throw MZCException("ConvertFromPolyData : internal error !");
+  //
+  MCAuto<MEDFileMeshes> meshes(MEDFileMeshes::New());
+  ret->setMeshes(meshes);
+  MCAuto<MEDFileFields> fields(MEDFileFields::New());
+  ret->setFields(fields);
+  //
+  MCAuto<MEDFileUMesh> umesh(MEDFileUMesh::New());
+  meshes->pushMesh(umesh);
+  MCAuto<DataArrayDouble> coords(BuildCoordsFrom(ds));
+  umesh->setCoords(coords);
+  umesh->setName(GetMeshNameWithContext(context));
+  //
+  int offset(0);
+  std::vector< MicroField > ms;
+  vtkCellArray *cd(ds->GetVerts());
+  if(cd)
+    {
+      MCAuto<MEDCouplingUMesh> subMesh(BuildMeshFromCellArray(cd,coords,0,INTERP_KERNEL::NORM_POINT1));
+      if((const MEDCouplingUMesh *)subMesh)
+        {
+          std::vector<MCAuto<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
+          offset+=subMesh->getNumberOfCells();
+          ms.push_back(MicroField(subMesh,cellFs));
+        }
+    }
+  vtkCellArray *cc(ds->GetLines());
+  if(cc)
+    {
+      MCAuto<MEDCouplingUMesh> subMesh;
+      try
+        {
+          subMesh=BuildMeshFromCellArray(cc,coords,1,INTERP_KERNEL::NORM_SEG2);
+        }
+      catch(INTERP_KERNEL::Exception& e)
+        {
+          std::ostringstream oss; oss << "MEDWriter does not manage polyline cell type because MED file format does not support it ! Maybe it is the source of the problem ? The cause of this exception was " << e.what() << std::endl;
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      if((const MEDCouplingUMesh *)subMesh)
+        {
+          std::vector<MCAuto<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
+          offset+=subMesh->getNumberOfCells();
+          ms.push_back(MicroField(subMesh,cellFs));
+        }
+    }
+  vtkCellArray *cb(ds->GetPolys());
+  if(cb)
+    {
+      MCAuto<MEDCouplingUMesh> subMesh(BuildMeshFromCellArray(cb,coords,2,INTERP_KERNEL::NORM_POLYGON));
+      if((const MEDCouplingUMesh *)subMesh)
+        {
+          std::vector<MCAuto<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
+          offset+=subMesh->getNumberOfCells();
+          ms.push_back(MicroField(subMesh,cellFs));
+        }
+    }
+  vtkCellArray *ca(ds->GetStrips());
+  if(ca)
+    {
+      MCAuto<DataArrayIdType> ids;
+      MCAuto<MEDCouplingUMesh> subMesh(BuildMeshFromCellArrayTriangleStrip(ca,coords,ids));
+      if((const MEDCouplingUMesh *)subMesh)
+        {
+          std::vector<MCAuto<DataArray> > cellFs(AddPartFields(ids,ds->GetCellData()));
+          offset+=subMesh->getNumberOfCells();
+          ms.push_back(MicroField(subMesh,cellFs));
+        }
+    }
+  AssignSingleGTMeshes(ret,ms,timeStep,tsId);
+  AddNodeFields(ret,ds->GetPointData(),timeStep,tsId);
+}
+
+void ConvertFromUnstructuredGrid(MEDFileData *ret, vtkUnstructuredGrid *ds, const std::vector<int>& context, double timeStep, int tsId)
+{
+  if(!ds || !ret)
+    throw MZCException("ConvertFromUnstructuredGrid : internal error !");
+  //
+  MCAuto<MEDFileMeshes> meshes(MEDFileMeshes::New());
+  ret->setMeshes(meshes);
+  MCAuto<MEDFileFields> fields(MEDFileFields::New());
+  ret->setFields(fields);
+  //
+  MCAuto<MEDFileUMesh> umesh(MEDFileUMesh::New());
+  meshes->pushMesh(umesh);
+  MCAuto<DataArrayDouble> coords(BuildCoordsFrom(ds));
+  umesh->setCoords(coords);
+  umesh->setName(GetMeshNameWithContext(context));
+  vtkIdType nbCells(ds->GetNumberOfCells());
+  vtkCellArray *ca(ds->GetCells());
+  if(!ca)
+    return ;
+  //vtkIdType nbEnt(ca->GetNumberOfConnectivityEntries()); // todo: unused
+  //vtkIdType *caPtr(ca->GetData()->GetPointer(0)); // todo: unused
+  vtkUnsignedCharArray *ct(ds->GetCellTypesArray());
+  if(!ct)
+    throw MZCException("ConvertFromUnstructuredGrid : internal error");
+  vtkIdTypeArray *cla(ds->GetCellLocationsArray());
+  //const vtkIdType *claPtr(cla->GetPointer(0)); // todo: unused
+  if(!cla)
+    throw MZCException("ConvertFromUnstructuredGrid : internal error 2");
+  const unsigned char *ctPtr(ct->GetPointer(0));
+  std::map<int,int> m(ComputeMapOfType());
+  MCAuto<DataArrayInt> lev(DataArrayInt::New()) ;  lev->alloc(nbCells,1);
+  int *levPtr(lev->getPointer());
+  for(vtkIdType i=0;i<nbCells;i++)
+    {
+      std::map<int,int>::iterator it(m.find(ctPtr[i]));
+      if(it!=m.end())
+        {
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)(*it).second));
+          levPtr[i]=cm.getDimension();
+        }
+      else
+        {
+          if(ctPtr[i]==VTK_POLY_VERTEX)
+            {
+              const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_POINT1));
+              levPtr[i]=cm.getDimension();
+            }
+          else
+            {
+              std::ostringstream oss; oss << "ConvertFromUnstructuredGrid : at pos #" << i << " unrecognized VTK cell with type =" << ctPtr[i];
+              throw MZCException(oss.str());
+            }
+        }
+    }
+  MCAuto<DataArrayInt> levs(lev->getDifferentValues());
+  std::vector< MicroField > ms;
+  //vtkIdTypeArray *faces(ds->GetFaces()),*faceLoc(ds->GetFaceLocations()); // todo: unused
+  for(const int *curLev=levs->begin();curLev!=levs->end();curLev++)
+    {
+      MCAuto<MEDCouplingUMesh> m0(MEDCouplingUMesh::New("",*curLev));
+      m0->setCoords(coords); m0->allocateCells();
+      MCAuto<DataArrayIdType> cellIdsCurLev(lev->findIdsEqual(*curLev));
+      for(const mcIdType *cellId=cellIdsCurLev->begin();cellId!=cellIdsCurLev->end();cellId++)
+        {
+          int vtkType(ds->GetCellType(*cellId));
+          std::map<int,int>::iterator it(m.find(vtkType));
+          INTERP_KERNEL::NormalizedCellType ct=it!=m.end()?(INTERP_KERNEL::NormalizedCellType)((*it).second):INTERP_KERNEL::NORM_POINT1;
+          if(ct!=INTERP_KERNEL::NORM_POLYHED && vtkType!=VTK_POLY_VERTEX)
+            {
+              vtkIdType sz(0);
+              const vtkIdType *pts(nullptr);
+              ds->GetCellPoints(*cellId, sz, pts);
+              std::vector<mcIdType> conn2(pts,pts+sz);
+              m0->insertNextCell(ct,sz,conn2.data());
+            }
+          else if(ct==INTERP_KERNEL::NORM_POLYHED)
+            {
+              // # de faces du polyèdre
+              vtkIdType nbOfFaces(0);
+              // connectivé des faces (numFace0Pts, id1, id2, id3, numFace1Pts,id1, id2, id3, ...)
+              const vtkIdType *facPtr(nullptr);
+              ds->GetFaceStream(*cellId, nbOfFaces, facPtr);
+              std::vector<mcIdType> conn;
+              for(vtkIdType k=0;k<nbOfFaces;k++)
+                {
+                  vtkIdType nbOfNodesInFace(*facPtr++);
+                  std::copy(facPtr,facPtr+nbOfNodesInFace,std::back_inserter(conn));
+                  if(k<nbOfFaces-1)
+                    conn.push_back(-1);
+                  facPtr+=nbOfNodesInFace;
+                }
+              m0->insertNextCell(ct,ToIdType(conn.size()),&conn[0]);
+            }
+          else
+            {
+              vtkIdType sz(0);
+              const vtkIdType *pts(nullptr);
+              ds->GetCellPoints(*cellId, sz, pts);
+              if(sz!=1)
+                throw MZCException("ConvertFromUnstructuredGrid : non single poly vertex not managed by MED !");
+              m0->insertNextCell(ct,1,(const mcIdType*)pts);
+            }
+        }
+      std::vector<MCAuto<DataArray> > cellFs(AddPartFields(cellIdsCurLev,ds->GetCellData()));
+      ms.push_back(MicroField(m0,cellFs));
+    }
+  AssignSingleGTMeshes(ret,ms,timeStep,tsId);
+  AddNodeFields(ret,ds->GetPointData(),timeStep,tsId);
+}
+
+///////////////////
+
+void WriteMEDFileFromVTKDataSet(MEDFileData *mfd, vtkDataSet *ds, const std::vector<int>& context, double timeStep, int tsId)
+{
+  if(!ds || !mfd)
+    throw MZCException("Internal error in WriteMEDFileFromVTKDataSet.");
+  vtkPolyData *ds2(vtkPolyData::SafeDownCast(ds));
+  vtkUnstructuredGrid *ds3(vtkUnstructuredGrid::SafeDownCast(ds));
+  vtkRectilinearGrid *ds4(vtkRectilinearGrid::SafeDownCast(ds));
+  if(ds2)
+    {
+      ConvertFromPolyData(mfd,ds2,context,timeStep,tsId);
+    }
+  else if(ds3)
+    {
+      ConvertFromUnstructuredGrid(mfd,ds3,context,timeStep,tsId);
+    }
+  else if(ds4)
+    {
+      ConvertFromRectilinearGrid(mfd,ds4,context,timeStep,tsId);
+    }
+  else
+    throw MZCException("Unrecognized vtkDataSet ! Sorry ! Try to convert it to UnstructuredGrid to be able to write it !");
+}
+
+void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, const std::vector<int>& context, double timeStep, int tsId)
+{
+  if(!ds || !mfd)
+    throw MZCException("Internal error in WriteMEDFileFromVTKMultiBlock.");
+  int nbBlocks(ds->GetNumberOfBlocks());
+  if(nbBlocks==1 && context.empty())
+    {
+      vtkDataObject *uniqueElt(ds->GetBlock(0));
+      if(!uniqueElt)
+        throw MZCException("Unique elt in multiblock is NULL !");
+      vtkDataSet *uniqueEltc(vtkDataSet::SafeDownCast(uniqueElt));
+      if(uniqueEltc)
+        {
+          WriteMEDFileFromVTKDataSet(mfd,uniqueEltc,context,timeStep,tsId);
+          return ;
+        }
+    }
+  for(int i=0;i<nbBlocks;i++)
+    {
+      vtkDataObject *elt(ds->GetBlock(i));
+      std::vector<int> context2;
+      context2.push_back(i);
+      if(!elt)
+        {
+          std::ostringstream oss; oss << "In context ";
+          std::copy(context.begin(),context.end(),std::ostream_iterator<int>(oss," "));
+          oss << " at pos #" << i << " elt is NULL !";
+          throw MZCException(oss.str());
+        }
+      vtkDataSet *elt1(vtkDataSet::SafeDownCast(elt));
+      if(elt1)
+        {
+          WriteMEDFileFromVTKDataSet(mfd,elt1,context,timeStep,tsId);
+          continue;
+        }
+      vtkMultiBlockDataSet *elt2(vtkMultiBlockDataSet::SafeDownCast(elt));
+      if(elt2)
+        {
+          WriteMEDFileFromVTKMultiBlock(mfd,elt2,context,timeStep,tsId);
+          continue;
+        }
+      std::ostringstream oss; oss << "In context ";
+      std::copy(context.begin(),context.end(),std::ostream_iterator<int>(oss," "));
+      oss << " at pos #" << i << " elt not recognized data type !";
+      throw MZCException(oss.str());
+    }
+}
+
+void WriteMEDFileFromVTKGDS(MEDFileData *mfd, vtkDataObject *input, double timeStep, int tsId)
+{
+  if(!input || !mfd)
+    throw MZCException("WriteMEDFileFromVTKGDS : internal error !");
+  std::vector<int> context;
+  vtkDataSet *input1(vtkDataSet::SafeDownCast(input));
+  if(input1)
+    {
+      WriteMEDFileFromVTKDataSet(mfd,input1,context,timeStep,tsId);
+      return ;
+    }
+  vtkMultiBlockDataSet *input2(vtkMultiBlockDataSet::SafeDownCast(input));
+  if(input2)
+    {
+      WriteMEDFileFromVTKMultiBlock(mfd,input2,context,timeStep,tsId);
+      return ;
+    }
+  throw MZCException("WriteMEDFileFromVTKGDS : not recognized data type !");
+}
+
+void PutFamGrpInfoIfAny(MEDFileData *mfd, const std::string& meshName, const std::vector<Grp>& groups, const std::vector<Fam>& fams)
+{
+  if(!mfd)
+    return ;
+  if(meshName.empty())
+    return ;
+  MEDFileMeshes *meshes(mfd->getMeshes());
+  if(!meshes)
+    return ;
+  if(meshes->getNumberOfMeshes()!=1)
+    return ;
+  MEDFileMesh *mm(meshes->getMeshAtPos(0));
+  if(!mm)
+    return ;
+  mm->setName(meshName);
+  for(std::vector<Fam>::const_iterator it=fams.begin();it!=fams.end();it++)
+    mm->setFamilyId((*it).getName(),(*it).getID());
+  for(std::vector<Grp>::const_iterator it=groups.begin();it!=groups.end();it++)
+    mm->setFamiliesOnGroup((*it).getName(),(*it).getFamilies());
+  MEDFileFields *fields(mfd->getFields());
+  if(!fields)
+    return ;
+  for(int i=0;i<fields->getNumberOfFields();i++)
+    {
+      MEDFileAnyTypeFieldMultiTS *fmts(fields->getFieldAtPos(i));
+      if(!fmts)
+        continue;
+      fmts->setMeshName(meshName);
+    }
+}
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.h b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/VTKToMEDMem.h
new file mode 100644 (file)
index 0000000..7cf1544
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2017-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __VTKTOMEDMEM_HXX__
+#define __VTKTOMEDMEM_HXX__
+
+#include "vtkSystemIncludes.h" //needed for exports
+
+#include "MEDCouplingRefCountObject.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingFieldFloat.hxx"
+#include "MEDCouplingFieldInt.hxx"
+#include "MEDCouplingFieldInt64.hxx"
+#include "MEDFileData.hxx"
+#include "MEDFileField.hxx"
+#include "MEDFileMesh.hxx"
+#include "MEDLoaderTraits.hxx"
+
+#include <exception>
+#include <string>
+
+///////////////////
+
+class vtkDataSet;
+
+class VTK_EXPORT MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s):_reason(s) { }
+  virtual const char *what() const noexcept { return _reason.c_str(); }
+  virtual ~MZCException() noexcept { }
+private:
+  std::string _reason;
+};
+
+namespace VTKToMEDMem
+{
+  class VTK_EXPORT Grp
+  {
+  public:
+    Grp(const std::string& name):_name(name) { }
+    void setFamilies(const std::vector<std::string>& fams) { _fams=fams; }
+    std::string getName() const { return _name; }
+    std::vector<std::string> getFamilies() const { return _fams; }
+  private:
+    std::string _name;
+    std::vector<std::string> _fams;
+  };
+
+  class VTK_EXPORT Fam
+  {
+  public:
+    Fam(const std::string& name);
+    std::string getName() const { return _name; }
+    int getID() const { return _id; }
+  private:
+    std::string _name;
+    int _id;
+  };
+}
+
+class vtkDataObject;
+
+void VTK_EXPORT WriteMEDFileFromVTKDataSet(MEDCoupling::MEDFileData *mfd, vtkDataSet *ds, const std::vector<int>& context, double timeStep, int tsId);
+
+void VTK_EXPORT WriteMEDFileFromVTKGDS(MEDCoupling::MEDFileData *mfd, vtkDataObject *input, double timeStep, int tsId);
+  
+void VTK_EXPORT PutFamGrpInfoIfAny(MEDCoupling::MEDFileData *mfd, const std::string& meshName, const std::vector<VTKToMEDMem::Grp>& groups, const std::vector<VTKToMEDMem::Fam>& fams);
+
+#endif
+
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtk.module b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtk.module
new file mode 100644 (file)
index 0000000..3d39df7
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  RateOfFlowThroughSectionModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral  
+  VTK::FiltersSources
+  VTK::FiltersGeometry
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
+  ParaView::VTKExtensionsMisc
+  ParaView::VTKExtensionsFiltersRendering
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.cxx b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.cxx
new file mode 100644 (file)
index 0000000..a1a2060
--- /dev/null
@@ -0,0 +1,156 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkExplodePolyLine.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataSetSurfaceFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkLineSource.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkRibbonFilter.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkTable.h>
+#include <vtkTessellatorFilter.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariant.h>
+#include <vtkVariantArray.h>
+#include <vtkMeshQuality.h>
+#include <vtkCellCenters.h>
+
+#include <cmath>
+#include <sstream>
+vtkStandardNewMacro(vtkExplodePolyLine);
+
+class MyException : public std::exception
+{
+public:
+  MyException(const std::string& s):_reason(s) { }
+  virtual const char *what() const throw() { return _reason.c_str(); }
+  virtual ~MyException() throw() { }
+private:
+  std::string _reason;
+};
+
+//-----------------------------------------------------------------------------
+void vtkExplodePolyLine::ExtractInfo(vtkInformationVector* inputVector, vtkSmartPointer<vtkPolyData>& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkPolyData* input(vtkPolyData::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (!input)
+  {
+    vtkUnstructuredGrid* input2(vtkUnstructuredGrid::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+    if(!input2)
+      vtkErrorMacro("Input data set is not vtkPolyData !");
+
+    vtkNew<vtkDataSetSurfaceFilter> surface;
+
+    surface->SetNonlinearSubdivisionLevel(0);
+    surface->SetInputData(input2);
+    surface->Update();
+    usgIn = surface->GetOutput();
+    return;
+  }
+  usgIn = vtkPolyData::SafeDownCast(input);
+}
+
+
+int vtkExplodePolyLine::FillInputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
+  return 1;
+}
+
+int vtkExplodePolyLine::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
+  return 1;
+}
+
+int vtkExplodePolyLine::RequestData(vtkInformation* vtkNotUsed(request),vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  try
+  {
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    vtkPointSet* output(vtkPointSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    vtkSmartPointer<vtkPolyData> usgIn;
+    this->ExtractInfo(inputVector[0], usgIn);
+    vtkCellArray *cc(usgIn->GetLines());
+    vtkIdType nbEntries(cc->GetNumberOfConnectivityEntries());
+    const vtkIdType *conn(cc->GetData()->GetPointer(0));
+    vtkNew<vtkPolyData> pd;
+    vtkNew<vtkCellArray> cb;
+    if(nbEntries<1)
+    {
+      throw MyException("Input PolyData looks empty !");
+    }
+    if(conn[0] == nbEntries-1)
+    {
+      vtkIdType nbCells(nbEntries-2);
+      vtkNew<vtkIdTypeArray> connOut;
+      connOut->SetNumberOfComponents(1);
+      connOut->SetNumberOfTuples(3*nbCells);
+      vtkIdType *connOutPtr(connOut->GetPointer(0));
+      for( auto iCell = 0 ; iCell < nbCells ; ++iCell, connOutPtr+=3 )
+      {
+        connOutPtr[0] = 2;
+        connOutPtr[1] = conn[1+iCell];
+        connOutPtr[2] = conn[1+iCell+1];
+      }
+      cb->SetCells(nbCells,connOut);
+    }
+    else if(nbEntries == 3*cc->GetNumberOfCells())
+    {
+      output->ShallowCopy(usgIn);
+      return 1;
+    }
+    else
+    {
+      throw MyException("Input PolyData is not containing only lines as required as precondition !");
+    }
+    pd->SetLines(cb);
+    vtkNew<vtkPoints> pts;
+    // here DeepCopy is required, because GetMeshMTime of input PolyData is modified and generate useless computation afterwards in the pipeline. Bug ?
+    pts->DeepCopy(usgIn->GetPoints());
+    pd->SetPoints(pts);
+    output->ShallowCopy(pd);
+  }
+  catch(MyException& e)
+  {
+    vtkErrorMacro("Exception has been thrown in vtkComplexMode::RequestInformation : " << e.what());
+  }
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+void vtkExplodePolyLine::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.h b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkExplodePolyLine.h
new file mode 100644 (file)
index 0000000..74882d9
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkExplodePolyLine_h__
+#define __vtkExplodePolyLine_h__
+
+#include <vtkPointSetAlgorithm.h>
+
+#include <vtkSmartPointer.h>
+#include <vtkPolyData.h>
+#include <vtkDataSetSurfaceFilter.h>
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataSetSurfaceFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkLineSource.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkRibbonFilter.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkTable.h>
+#include <vtkTessellatorFilter.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariant.h>
+#include <vtkVariantArray.h>
+#include <vtkMeshQuality.h>
+#include <vtkCellCenters.h>
+
+#include <string>
+#include <vector>
+
+class vtkDoubleArray;
+
+class VTK_EXPORT vtkExplodePolyLine : public vtkPointSetAlgorithm
+{
+public:
+  static vtkExplodePolyLine* New();
+  vtkTypeMacro(vtkExplodePolyLine, vtkPointSetAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  int FillInputPortInformation(int vtkNotUsed(port), vtkInformation *info) override;
+  int FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info) override;
+
+protected:
+  vtkExplodePolyLine() = default;
+  ~vtkExplodePolyLine() override = default;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  void ExtractInfo(vtkInformationVector* inputVector, vtkSmartPointer<vtkPolyData>& usgIn);
+
+private:
+  vtkExplodePolyLine(const vtkExplodePolyLine&) = delete;
+  void operator=(const vtkExplodePolyLine&) = delete;
+};
+
+#endif
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.cxx b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.cxx
new file mode 100644 (file)
index 0000000..7fbdb89
--- /dev/null
@@ -0,0 +1,567 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkRateOfFlowThroughSection.h"
+#include "vtkExplodePolyLine.h"
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkDoubleArray.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkResampleWithDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+
+#include "VTKToMEDMem.h"
+
+#include <map>
+#include <deque>
+#include <sstream>
+
+vtkStandardNewMacro(vtkRateOfFlowThroughSection);
+
+///////////////////
+
+static vtkDataSet *SplitSingleMultiBloc(vtkDataObject *ds)
+{
+  if(!ds)
+    throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr !");
+  vtkMultiBlockDataSet *ds0(vtkMultiBlockDataSet::SafeDownCast(ds));
+  if(!ds0)
+  {
+    vtkDataSet *ds00(vtkDataSet::SafeDownCast(ds));
+    if(!ds00)
+      throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : neither a vtkMultiBlockDataSet nor a vtkDataSet !");
+    return ds00;
+  }
+  if(ds0->GetNumberOfBlocks() != 1)
+  {
+    std::ostringstream oss; oss << "vtkSedimentDeposit  SplitSingleMultiBloc : presence of multiblock dataset with not exactly one dataset in it ! (" << ds0->GetNumberOfBlocks() << ") !";
+    throw INTERP_KERNEL::Exception(oss.str());
+  }
+  vtkDataObject *ds1(ds0->GetBlock(0));
+  vtkDataSet *ds1c(vtkDataSet::SafeDownCast(ds1));
+  if(!ds1c)
+    throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr inside single multiblock element !");
+  return ds1c;
+}
+
+static void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *&usgIn)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input(0);
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw INTERP_KERNEL::Exception("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject *input2(input1->GetBlock(0));
+    if (!input2)
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+    vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw INTERP_KERNEL::Exception("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw INTERP_KERNEL::Exception("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+}
+
+////////////////////
+
+void vtkRateOfFlowThroughSection::vtkInternal::fillTable(vtkTable *table) const
+{
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    timeArr->SetName("Time");
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val = this->_data[tmp++].first; });
+    }
+    table->AddColumn(timeArr);
+  }
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    timeArr->SetName("Rate of flow");
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val = this->_data[tmp++].second; });
+    }
+    table->AddColumn(timeArr);
+  }
+}
+
+void vtkRateOfFlowThroughSection::vtkInternal::analyzeInputDataSets(vtkUnstructuredGrid *ds1, vtkDataSet *ds2)
+{
+  _recomputationOfMatrixNeeded = false;
+  if (_mt1 != ds1->GetMeshMTime())
+  {
+    _mt1 = ds1->GetMeshMTime();
+    _recomputationOfMatrixNeeded = true;
+  }
+  vtkUnstructuredGrid *ds2_0(vtkUnstructuredGrid::SafeDownCast(ds2));
+  vtkPolyData *ds2_1(vtkPolyData::SafeDownCast(ds2));
+  if (!ds2_0 && !ds2_1)
+    throw INTERP_KERNEL::Exception("analyzeInputDataSets : unexpected source !");
+  if (ds2_0)
+    if (_mt2 != ds2_0->GetMeshMTime())
+    {
+      _mt2 = ds2_0->GetMeshMTime();
+      _recomputationOfMatrixNeeded = true;
+    }
+  if (ds2_1)
+    if (_mt2 != ds2_1->GetMeshMTime())
+    {
+      _mt2 = ds2_1->GetMeshMTime();
+      _recomputationOfMatrixNeeded = true;
+    }
+}
+
+////////////////////
+
+vtkRateOfFlowThroughSection::vtkRateOfFlowThroughSection() : NumberOfTimeSteps(0), CurrentTimeIndex(0), IsExecuting(false), Internal(nullptr)
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfOutputPorts(1);
+}
+
+vtkRateOfFlowThroughSection::~vtkRateOfFlowThroughSection()
+{
+}
+
+int vtkRateOfFlowThroughSection::RequestUpdateExtent(vtkInformation *, vtkInformationVector **inputVector, vtkInformationVector *vtkNotUsed(outputVector))
+{
+  // vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  vtkInformation *inInfo1 = inputVector[0]->GetInformationObject(0);
+
+  // get the requested update extent
+  double *inTimes = inInfo1->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  if (inTimes)
+  {
+    double timeReq = inTimes[this->CurrentTimeIndex];
+    inInfo1->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), timeReq);
+  }
+
+  return 1;
+}
+
+int vtkRateOfFlowThroughSection::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkRateOfFlowThroughSection::RequestInformation ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation *info(outputVector->GetInformationObject(0));
+    vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+    if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      this->NumberOfTimeSteps = inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    else
+    {
+      this->NumberOfTimeSteps = 0;
+    }
+    // The output of this filter does not contain a specific time, rather
+    // it contains a collection of time steps. Also, this filter does not
+    // respond to time requests. Therefore, we remove all time information
+    // from the output.
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
+    }
+  }
+  catch (INTERP_KERNEL::Exception &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkRateOfFlowThroughSection::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+static MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> ToMedcoupling(MEDCoupling::MCAuto<MEDCoupling::MEDFileData> &mfd, vtkDataSet *usgIn)
+{
+  WriteMEDFileFromVTKDataSet(mfd, usgIn, {}, 0., 0);
+  MEDCoupling::MEDFileMeshes *ms(mfd->getMeshes());
+  if (ms->getNumberOfMeshes() != 1)
+    throw INTERP_KERNEL::Exception("Unexpected number of meshes !");
+  MEDCoupling::MEDFileMesh *mm(ms->getMeshAtPos(0));
+  MEDCoupling::MEDFileUMesh *mmu(dynamic_cast<MEDCoupling::MEDFileUMesh *>(mm));
+  if (!mmu)
+    throw INTERP_KERNEL::Exception("Expecting unstructured one !");
+  return mmu->getMeshAtLevel(0);
+}
+
+static void MyAssert(bool status, const std::string &message)
+{
+  if (!status)
+    throw INTERP_KERNEL::Exception(message);
+}
+
+bool IsNameIn(const std::string& name, const std::vector<std::string>& namesPossible)
+{
+  for(auto np : namesPossible)
+    {
+      std::size_t pos( name.find(np) );
+      if(pos==std::string::npos)
+        continue;
+      std::string nameCpy(name);
+      std::string tmp(nameCpy.replace(pos,np.length(),std::string()));
+      if( tmp.find_first_not_of(" \t") == std::string::npos )
+        return true;
+    }
+  return false;
+}
+
+vtkDataArray *FindArrayHavingNameIn(vtkPointData *pd, const std::vector<std::string>& namesPossible, std::function<bool(vtkDataArray *)> func)
+{
+  vtkDataArray *ret(nullptr);
+  for(auto i = 0; i < pd->GetNumberOfArrays() ; ++i )
+    {
+      vtkDataArray *arr(pd->GetArray(i));
+      std::string name(arr->GetName());
+      if(IsNameIn(name,namesPossible))
+        {
+          if( func(arr) )
+            {
+              ret = arr;
+              break;
+            }
+        }
+    }
+  return ret;
+}
+
+int vtkRateOfFlowThroughSection::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkRateOfFlowThroughSection::RequestData        ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(nullptr);
+    ExtractInfo(inputVector[0], usgIn);
+    // is this the first request
+    if (!this->IsExecuting)
+    {
+      request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+      this->IsExecuting = true;
+      delete this->Internal;
+      this->Internal = new vtkInternal;
+    }
+    //
+    vtkInformation *sourceInfo(inputVector[1]->GetInformationObject(0));
+    vtkDataObject *source(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+    vtkDataSet *source1(SplitSingleMultiBloc(source));
+    //
+    vtkNew<vtkExplodePolyLine> epl;
+    epl->SetInputData(source1);
+    epl->Update();
+    vtkDataSet *source2(epl->GetOutput());
+    //
+    this->Internal->analyzeInputDataSets(usgIn, source1);
+    ///////////////////////
+    //////////////////////
+    /////////////////////
+    //
+    std::vector<std::map<int, double>> &matrix(this->Internal->getMatrix());
+    if (this->Internal->computationNeeded())
+    {
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> m, sec;
+      MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd(MEDCoupling::MEDFileData::New());
+      m = ToMedcoupling(mfd, usgIn);
+      {
+        MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfdSec(MEDCoupling::MEDFileData::New());
+        sec = ToMedcoupling(mfd, source2);
+      }
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(m->getCoords()->keepSelectedComponents({2}));
+        MyAssert(arr->isUniform(0, 1e-12), "Expected coords array equal to 0 for Z axis.");
+      }
+      m->changeSpaceDimension(2, 0.);
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(sec->getCoords()->keepSelectedComponents({2}));
+        MyAssert(arr->isUniform(0, 1e-12), "Expected coords array equal to 0 for Z axis.");
+      }
+      sec->changeSpaceDimension(2, 0.);
+      // sec peut etre completement merdique avec des pts dupliques alors on filtre
+      {
+        bool tmp;
+        mcIdType tmpp;
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> tmppp(sec->mergeNodes(1e-12, tmp, tmpp));
+      }
+      sec->zipCoords();
+      sec->removeDegenerated1DCells();
+      //
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> line_inter;
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> cellid_in_2d, cellid_in1d;
+      {
+        MEDCoupling::MEDCouplingUMesh *tmp(nullptr), *tmp2(nullptr);
+        MEDCoupling::DataArrayIdType *tmp3(nullptr), *tmp4(nullptr);
+        MEDCoupling::MEDCouplingUMesh::Intersect2DMeshWith1DLine(m, sec, 1e-12, tmp, tmp2, tmp3, tmp4);
+        tmp->decrRef();
+        line_inter = tmp2;
+        cellid_in_2d = tmp3;
+        cellid_in1d = tmp4;
+      }
+      line_inter->zipCoords();
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> TwoDcells(MEDCoupling::DataArrayIdType::New());
+      TwoDcells->alloc(line_inter->getNumberOfCells(), 1);
+      {
+        auto t(cellid_in1d->begin());
+        auto TwoDcellsPtr(TwoDcells->getPointer());
+        for (std::size_t i = 0; i < cellid_in1d->getNumberOfTuples(); i++, t += 2, TwoDcellsPtr++)
+        {
+          int zeValue(-1);
+          std::for_each(t, t + 2, [&zeValue](const int &v) { if(v!=-1 && zeValue==-1) zeValue=v; });
+          *TwoDcellsPtr = zeValue;
+        }
+      }
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> notFreeStyle1DCells(TwoDcells->findIdsNotEqual(-1));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> n2oCells(TwoDcells->selectByTupleId(notFreeStyle1DCells->begin(), notFreeStyle1DCells->end()));
+      TwoDcells = cellid_in_2d->selectByTupleId(n2oCells->begin(), n2oCells->end());
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> effective_line1d(line_inter->buildPartOfMySelf(notFreeStyle1DCells->begin(), notFreeStyle1DCells->end()));
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> effective_2d_cells(m->buildPartOfMySelf(TwoDcells->begin(), TwoDcells->end()));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> o2n(effective_2d_cells->zipCoordsTraducer());
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> n2o(o2n->invertArrayO2N2N2O(effective_2d_cells->getNumberOfNodes()));
+      MEDCoupling::MCAuto<MEDCoupling::MEDCoupling1SGTUMesh> effective_line1d_2(MEDCoupling::MEDCoupling1SGTUMesh::New(effective_line1d));     // change format of umesh to ease alg
+      MEDCoupling::MCAuto<MEDCoupling::MEDCoupling1SGTUMesh> effective_2d_cells_2(MEDCoupling::MEDCoupling1SGTUMesh::New(effective_2d_cells)); // change format of umesh to ease alg
+      MyAssert(effective_2d_cells_2->getCellModelEnum() == INTERP_KERNEL::NORM_TRI3, "Only TRI3 are expected as input");
+
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> conn1d(effective_line1d_2->getNodalConnectivity()->deepCopy());
+      conn1d->rearrange(2);
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> conn2d(effective_2d_cells_2->getNodalConnectivity()->deepCopy());
+      conn2d->rearrange(3);
+      const MEDCoupling::DataArrayDouble *coo1d(effective_line1d->getCoords()), *coo2d(effective_2d_cells->getCoords());
+      MyAssert(conn2d->getNumberOfTuples() == conn1d->getNumberOfTuples(), "Internal error !");
+
+      matrix.resize(effective_line1d->getNumberOfCells());
+      {
+        const mcIdType *t1(conn1d->begin()), *t2(conn2d->begin());
+        const double *coo1dPtr(coo1d->begin()), *coo2dPtr(coo2d->begin());
+        double seg2[4], tri3[6];
+        for (std::size_t i = 0; i < effective_line1d->getNumberOfCells(); i++, t1 += 2, t2 += 3)
+        {
+          double baryInfo[3];
+          double length;
+          seg2[0] = coo1dPtr[2 * t1[0]];
+          seg2[1] = coo1dPtr[2 * t1[0] + 1];
+          seg2[2] = coo1dPtr[2 * t1[1]];
+          seg2[3] = coo1dPtr[2 * t1[1] + 1];
+          tri3[0] = coo2dPtr[2 * t2[0]];
+          tri3[1] = coo2dPtr[2 * t2[0] + 1];
+          tri3[2] = coo2dPtr[2 * t2[1]];
+          tri3[3] = coo2dPtr[2 * t2[1] + 1];
+          tri3[4] = coo2dPtr[2 * t2[2]];
+          tri3[5] = coo2dPtr[2 * t2[2] + 1];
+          MEDCoupling::DataArrayDouble::ComputeIntegralOfSeg2IntoTri3(seg2, tri3, baryInfo, length);
+          std::map<int, double> &row(matrix[i]);
+          row[n2o->getIJ(t2[0], 0)] = baryInfo[0];
+          row[n2o->getIJ(t2[1], 0)] = baryInfo[1];
+          row[n2o->getIJ(t2[2], 0)] = baryInfo[2];
+        }
+      }
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> orthoField;
+      const MEDCoupling::DataArrayDouble *ortho(nullptr);
+      {
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> tmp(effective_line1d->buildUnstructured());
+        orthoField = tmp->buildOrthogonalField();
+        this->Internal->setOrtho(orthoField->getArray());
+      }
+      {
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> measure(effective_line1d->getMeasureField(true));
+        this->Internal->setMeasure(measure->getArray());
+      }
+    }
+    const MEDCoupling::DataArrayDouble *ortho(this->Internal->getOrtho()), *measure_arr(this->Internal->getMeasure());
+    ///////////////////////
+    //////////////////////
+    /////////////////////
+    constexpr char SEARCHED_FIELD_HAUTEUR[]="HAUTEUR D'EAU";
+    constexpr char SEARCHED_FIELD_HAUTEUR2[]="WATER DEPTH";
+    constexpr char SEARCHED_FIELD_SPEED[]="VITESSE *";
+    constexpr char SEARCHED_FIELD_SPEED2[]="VELOCITY *";
+
+    vtkPointData *pd(usgIn->GetPointData());
+    vtkDataArray *h_water_tmp(FindArrayHavingNameIn(pd,{ SEARCHED_FIELD_HAUTEUR, SEARCHED_FIELD_HAUTEUR2 },[](vtkDataArray *arr) { return arr->GetNumberOfComponents()==1; }));
+    vtkDataArray *speed_tmp(FindArrayHavingNameIn(pd,{ "VITESSE *", "VELOCITY *" },[](vtkDataArray *arr) { return arr->GetNumberOfComponents()>1; }));
+    vtkDoubleArray *h_water(vtkDoubleArray::SafeDownCast(h_water_tmp)), *speed(vtkDoubleArray::SafeDownCast(speed_tmp));
+    std::ostringstream oss;
+    oss << "Expecting presence of float32 following fields : \"" << SEARCHED_FIELD_HAUTEUR << "\" or \"" << SEARCHED_FIELD_HAUTEUR2 << "\"and \"" << SEARCHED_FIELD_SPEED << "\" or \"" << SEARCHED_FIELD_SPEED2 << " \"";
+    MyAssert(h_water && speed, oss.str());
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayFloat> speed2(MEDCoupling::DataArrayFloat::New());
+    speed2->alloc(speed->GetNumberOfTuples(), speed->GetNumberOfComponents());
+    std::copy(speed->GetPointer(0), speed->GetPointer(0) + speed2->getNbOfElems(), speed2->rwBegin());
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> speed_arr(speed2->convertToDblArr());
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayFloat> h_water_arrf(MEDCoupling::DataArrayFloat::New());
+    h_water_arrf->alloc(h_water->GetNumberOfTuples(), 1);
+    std::copy(h_water->GetPointer(0), h_water->GetPointer(0) + h_water_arrf->getNbOfElems(), h_water_arrf->rwBegin());
+    /*MEDCoupling::MEDFileFloatField1TS *speed(nullptr),*h_water(nullptr);
+      {
+        MEDCoupling::MEDFileFields *fields(mfd->getFields());
+        MyAssert(fields,"No arrays found in the input dataset !");
+        MEDCoupling::MEDFileAnyTypeFieldMultiTS *speed_mts(fields->getFieldWithName(SEARCHED_FIELD_SPEED));
+        MEDCoupling::MEDFileAnyTypeFieldMultiTS *h_water_mts(fields->getFieldWithName(SEARCHED_FIELD_HAUTEUR));
+        std::ostringstream oss; oss << "Expecting single time step for following fields : \"" << SEARCHED_FIELD_HAUTEUR << "\" and \"" <<  SEARCHED_FIELD_SPEED << "\"";
+        MyAssert(speed_mts->getNumberOfTS()==1 && h_water_mts->getNumberOfTS()==1,oss.str());
+        MEDCoupling::MEDFileFloatFieldMultiTS *speed_mts_2(dynamic_cast<MEDCoupling::MEDFileFloatFieldMultiTS *>(speed_mts));
+        MEDCoupling::MEDFileFloatFieldMultiTS *h_water_mts_2(dynamic_cast<MEDCoupling::MEDFileFloatFieldMultiTS *>(h_water_mts));
+        std::ostringstream oss2; oss2 << "Expecting presence of float32 following fields : \"" << SEARCHED_FIELD_HAUTEUR << "\" and \"" <<  SEARCHED_FIELD_SPEED << "\"";
+        MyAssert(!speed_mts_2 || !h_water_mts_2,oss2.str());
+        speed=speed_mts_2->getTimeStepAtPos(0); h_water=h_water_mts_2->getTimeStepAtPos(0);
+      }
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> speed_arr(speed->getUndergroundDataArray()->convertToDblArr());*/
+    {
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(speed_arr->keepSelectedComponents({2}));
+      MyAssert(arr->isUniform(0, 1e-12), "Expected speed array equal to 0 for Z axis.");
+    }
+    speed_arr = speed_arr->keepSelectedComponents({0, 1});
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> h_water_arr(h_water_arrf->convertToDblArr());
+    const double *speed_ptr(speed_arr->begin()), *ortho_ptr(ortho->begin());
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> h_out(MEDCoupling::DataArrayDouble::New());
+    h_out->alloc(matrix.size(), 1);
+    h_out->fillWithZero();
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> v_out(MEDCoupling::DataArrayDouble::New());
+    v_out->alloc(matrix.size(), 1);
+    v_out->fillWithZero();
+    const double *orthoPtr(ortho->begin());
+    for (std::size_t i = 0; i < matrix.size(); i++, speed_ptr += 2, ortho_ptr += 2)
+    {
+      const std::map<int, double> &row(matrix[i]);
+      double h_out_value(0.), speed[2] = {0., 0.};
+      for (auto it : row)
+      {
+        h_out_value += it.second * h_water_arr->getIJ(it.first, 0);
+        speed[0] += it.second * speed_arr->getIJ(it.first, 0);
+        speed[1] += it.second * speed_arr->getIJ(it.first, 1);
+      }
+      h_out->setIJ(i, 0, h_out_value);
+      v_out->setIJ(i, 0, speed[0]*orthoPtr[2*i+0] +speed[1]*orthoPtr[2*i+1] );
+    }
+    double zeValue(0.);
+    {
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp1(MEDCoupling::DataArrayDouble::Multiply(h_out, v_out));
+      tmp1 = MEDCoupling::DataArrayDouble::Multiply(tmp1, measure_arr);
+      zeValue = std::abs(tmp1->accumulate((std::size_t)0));
+    }
+    double timeStep;
+    {
+      vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+      vtkDataObject *input(vtkDataObject::GetData(inInfo));
+      timeStep = input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP());
+    }
+    this->Internal->pushData(timeStep, zeValue);
+    this->CurrentTimeIndex++;
+    if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+      vtkInformation *outInfo(outputVector->GetInformationObject(0));
+      vtkTable *output(vtkTable::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      vtkNew<vtkTable> table;
+      this->Internal->fillTable(table);
+      output->ShallowCopy(table);
+    }
+  }
+  catch (INTERP_KERNEL::Exception& e)
+  {
+    if (this->IsExecuting)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+    }
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkRateOfFlowThroughSection::RequestData : " << e.what() << std::endl;
+    vtkErrorMacro(<< oss.str());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkRateOfFlowThroughSection::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkRateOfFlowThroughSection::SetSourceData(vtkDataObject *input)
+{
+  this->SetInputData(1, input);
+}
+
+void vtkRateOfFlowThroughSection::SetSourceConnection(vtkAlgorithmOutput *algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+int vtkRateOfFlowThroughSection::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTable");
+  return 1;
+}
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.h b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkRateOfFlowThroughSection.h
new file mode 100644 (file)
index 0000000..f9b45e8
--- /dev/null
@@ -0,0 +1,133 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkRateOfFlowThroughSection_h__
+#define vtkRateOfFlowThroughSection_h__
+
+#include <vtkDataObjectAlgorithm.h>
+#include "vtkExplodePolyLine.h"
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkDoubleArray.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkResampleWithDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+#include <vtkSetGet.h>
+
+#include "VTKToMEDMem.h"
+
+#include <map>
+#include <deque>
+#include <sstream>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkRateOfFlowThroughSection : public vtkDataObjectAlgorithm
+{
+public:
+  static vtkRateOfFlowThroughSection *New();
+  vtkTypeMacro(vtkRateOfFlowThroughSection, vtkDataObjectAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  void SetSourceData(vtkDataObject *input);
+
+  void SetSourceConnection(vtkAlgorithmOutput *algOutput);
+
+  int FillOutputPortInformation(int, vtkInformation *) override;
+
+protected:
+  vtkRateOfFlowThroughSection();
+  ~vtkRateOfFlowThroughSection() override;
+
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+  int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+
+  int NumberOfTimeSteps;
+  int CurrentTimeIndex;
+  bool IsExecuting;
+  class  VTK_EXPORT vtkInternal {
+  public:
+    vtkInternal() {};
+    void pushData(double timeStep, double value) { _data.emplace_back(timeStep, value); }
+    void fillTable(vtkTable *table) const;
+    void analyzeInputDataSets(vtkUnstructuredGrid *ds1, vtkDataSet *ds2);
+    bool computationNeeded() const
+    {
+      if (_recomputationOfMatrixNeeded)
+      {
+        _matrix.clear();
+      }
+      return _recomputationOfMatrixNeeded;
+    };
+    std::vector<std::map<int, double>> &getMatrix() { return _matrix; }
+    void setOrtho(const MEDCoupling::DataArrayDouble *ortho) { _ortho.takeRef(ortho); }
+    const MEDCoupling::DataArrayDouble *getOrtho() const { return (const MEDCoupling::DataArrayDouble *)_ortho; }
+    void setMeasure(const MEDCoupling::DataArrayDouble *measure) { _measure.takeRef(measure); }
+    const MEDCoupling::DataArrayDouble *getMeasure() { return (const MEDCoupling::DataArrayDouble *)_measure; }
+
+  private:
+    std::vector<std::pair<double, double>> _data;
+    vtkMTimeType _mt1 = 0;
+    vtkMTimeType _mt2 = 0;
+    mutable std::vector<std::map<int, double>> _matrix;
+    bool _recomputationOfMatrixNeeded = true;
+    MEDCoupling::MCConstAuto<MEDCoupling::DataArrayDouble> _ortho;
+    MEDCoupling::MCConstAuto<MEDCoupling::DataArrayDouble> _measure;
+  };
+
+  vtkInternal *Internal;
+
+private:
+  vtkRateOfFlowThroughSection(const vtkRateOfFlowThroughSection &) = delete;
+  void operator=(const vtkRateOfFlowThroughSection &) = delete;
+};
+
+#endif
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.cxx b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.cxx
new file mode 100644 (file)
index 0000000..7395c10
--- /dev/null
@@ -0,0 +1,632 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkSedimentDeposit.h"
+#include "vtkExplodePolyLine.h"
+#include <vtkSetGet.h>
+
+
+vtkStandardNewMacro(vtkSedimentDeposit);
+
+///////////////////
+
+static int GetNumberOfBlocs(vtkDataObject *ds)
+{
+  if(!ds)
+    throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr !");
+  vtkMultiBlockDataSet *ds0(vtkMultiBlockDataSet::SafeDownCast(ds));
+  if(!ds0)
+  {
+    vtkDataSet *ds00(vtkDataSet::SafeDownCast(ds));
+    if(!ds00)
+      throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : neither a vtkMultiBlockDataSet nor a vtkDataSet !");
+    return 1;
+  }
+  return ds0->GetNumberOfBlocks();
+}
+
+static vtkDataSet *SplitSingleMultiBloc(vtkDataObject *ds, int blockId)
+{
+  if(!ds)
+    throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr !");
+  vtkMultiBlockDataSet *ds0(vtkMultiBlockDataSet::SafeDownCast(ds));
+  if(!ds0)
+  {
+    vtkDataSet *ds00(vtkDataSet::SafeDownCast(ds));
+    if(!ds00)
+      throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : neither a vtkMultiBlockDataSet nor a vtkDataSet !");
+    if(blockId != 0)
+      throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : 0 expected !");
+    return ds00;
+  }
+  if( blockId >= ds0->GetNumberOfBlocks() )
+  {
+    std::ostringstream oss; oss << "vtkSedimentDeposit  SplitSingleMultiBloc : presence of multiblock dataset with not exactly one dataset in it ! (" << ds0->GetNumberOfBlocks() << ") !";
+    throw INTERP_KERNEL::Exception(oss.str());
+  }
+  vtkDataObject *ds1(ds0->GetBlock(blockId));
+  vtkDataSet *ds1c(vtkDataSet::SafeDownCast(ds1));
+  if(!ds1c)
+    throw INTERP_KERNEL::Exception("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr inside single multiblock element !");
+  return ds1c;
+}
+
+static void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *&usgIn)
+{
+  vtkInformation *inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet *input = nullptr;
+  vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+  {
+    input = input0;
+  }
+  else
+  {
+    if (!input1)
+    {
+      throw INTERP_KERNEL::Exception("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    }
+    if (input1->GetNumberOfBlocks() != 1)
+    {
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    }
+    vtkDataObject *input2(input1->GetBlock(0));
+    if (!input2)
+    {
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
+    }
+    vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+    {
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    }
+    input = input2c;
+  }
+  if (!input)
+  {
+    throw INTERP_KERNEL::Exception("Input data set is NULL !");
+  }
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+  {
+    throw INTERP_KERNEL::Exception("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
+  }
+}
+
+std::string vtkSedimentDeposit::vtkInternal::getReprDependingPos(const std::string& origName) const
+{
+  if( _nb_of_curves == 1 )
+    return origName;
+  std::ostringstream oss;
+  oss << origName << "_" << _curve_id;
+  return oss.str();
+}
+
+void vtkSedimentDeposit::vtkInternal::fillTable(vtkTable *table) const
+{
+  if( _curve_id == 0 )
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    std::string name(getReprDependingPos("Time"));
+    timeArr->SetName(name.c_str());
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val = std::get<0>(this->_data[tmp++]); });
+    }
+    table->AddColumn(timeArr);
+  }
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    std::string name(getReprDependingPos("Total"));
+    timeArr->SetName(name.c_str());
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val=std::get<1>(this->_data[tmp])+std::get<2>(this->_data[tmp]); tmp++; });
+    }
+    table->AddColumn(timeArr);
+  }
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    std::string name(getReprDependingPos("Positif"));
+    timeArr->SetName(name.c_str());
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val = std::get<1>(this->_data[tmp++]); });
+    }
+    table->AddColumn(timeArr);
+  }
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    std::string name(getReprDependingPos("Negatif"));
+    timeArr->SetName(name.c_str());
+    timeArr->SetNumberOfTuples(_data.size());
+    double *pt(timeArr->GetPointer(0));
+    {
+      std::size_t tmp(0);
+      std::for_each(pt, pt + _data.size(), [this, &tmp](double &val) { val = std::get<2>(this->_data[tmp++]); });
+    }
+    table->AddColumn(timeArr);
+  }
+}
+
+void vtkSedimentDeposit::vtkInternal::analyzeInputDataSets(vtkUnstructuredGrid *ds1, vtkDataSet *ds2)
+{
+  _recomputationOfMatrixNeeded = false;
+  if (_mt1 != ds1->GetMeshMTime())
+  {
+    _mt1 = ds1->GetMeshMTime();
+    _recomputationOfMatrixNeeded = true;
+  }
+  vtkUnstructuredGrid *ds2_0(vtkUnstructuredGrid::SafeDownCast(ds2));
+  vtkPolyData *ds2_1(vtkPolyData::SafeDownCast(ds2));
+  if (!ds2_0 && !ds2_1)
+    throw INTERP_KERNEL::Exception("analyzeInputDataSets : unexpected source !");
+  if (ds2_0)
+    if (_mt2 != ds2_0->GetMeshMTime())
+    {
+      _mt2 = ds2_0->GetMeshMTime();
+      _recomputationOfMatrixNeeded = true;
+    }
+  if (ds2_1)
+    if (_mt2 != ds2_1->GetMeshMTime())
+    {
+      _mt2 = ds2_1->GetMeshMTime();
+      _recomputationOfMatrixNeeded = true;
+    }
+}
+
+static std::string Strip(const std::string& ins)
+{
+  std::string::size_type pos(ins.find_last_not_of(" \t"));
+  return ins.substr(0,pos+1);
+}
+
+static vtkDataArray *FindFieldWithNameStripped(vtkFieldData *fd, const char *fieldNameToSearch)
+{
+  std::string keyToSearch(fieldNameToSearch);
+  std::vector<std::string> candidates;
+  if(!fd)
+    throw INTERP_KERNEL::Exception("FindFieldWithNameStripped : nullptr instance !");
+  auto nbArrays(fd->GetNumberOfArrays());
+  for(auto i = 0 ; i < nbArrays ; ++i)
+  {
+    std::string arrName(fd->GetArrayName(i));
+    if(Strip(arrName) == keyToSearch)
+      candidates.push_back(arrName);
+  }
+  if(candidates.size()!=1)
+    {
+      std::ostringstream oss; oss << "FindFieldWithNameStripped : not exactly one candidate for \"" << fieldNameToSearch << "\" !";
+      throw INTERP_KERNEL::Exception(oss.str());
+    }
+  return fd->GetArray(candidates[0].c_str());
+}
+
+////////////////////
+
+vtkSedimentDeposit::vtkSedimentDeposit() : NumberOfTimeSteps(0), CurrentTimeIndex(0), IsExecuting(false)
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfOutputPorts(1);
+}
+
+int vtkSedimentDeposit::RequestUpdateExtent(vtkInformation *info, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  // vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  vtkInformation *inInfo1 = inputVector[0]->GetInformationObject(0);
+
+  // get the requested update extent
+  double *inTimes = inInfo1->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  if (inTimes)
+  {
+    double timeReq = inTimes[this->CurrentTimeIndex];
+    inInfo1->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), timeReq);
+  }
+
+  return 1;
+  //return vtkDataObjectAlgorithm::RequestUpdateExtent(info,inputVector,outputVector);
+}
+
+int vtkSedimentDeposit::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkSedimentDeposit::RequestInformation ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation *info(outputVector->GetInformationObject(0));
+    vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+    if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      this->NumberOfTimeSteps = inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    else
+    {
+      this->NumberOfTimeSteps = 0;
+    }
+    // The output of this filter does not contain a specific time, rather
+    // it contains a collection of time steps. Also, this filter does not
+    // respond to time requests. Therefore, we remove all time information
+    // from the output.
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
+    }
+  }
+  catch (INTERP_KERNEL::Exception &e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkSedimentDeposit::RequestInformation : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char *>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+static MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> ToMedcoupling(MEDCoupling::MCAuto<MEDCoupling::MEDFileData> &mfd, vtkDataSet *usgIn)
+{
+  WriteMEDFileFromVTKDataSet(mfd, usgIn, {}, 0., 0);
+  MEDCoupling::MEDFileMeshes *ms(mfd->getMeshes());
+  if (ms->getNumberOfMeshes() != 1)
+    throw INTERP_KERNEL::Exception("Unexpected number of meshes !");
+  MEDCoupling::MEDFileMesh *mm(ms->getMeshAtPos(0));
+  MEDCoupling::MEDFileUMesh *mmu(dynamic_cast<MEDCoupling::MEDFileUMesh *>(mm));
+  if (!mmu)
+    throw INTERP_KERNEL::Exception("Expecting unstructured one !");
+  return mmu->getMeshAtLevel(0);
+}
+
+static void MyAssert(bool status, const std::string &message)
+{
+  if (!status)
+  {
+    throw INTERP_KERNEL::Exception(message);
+  }
+}
+
+int vtkSedimentDeposit::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  //std::cerr << "########################################## vtkSedimentDeposit::RequestData        ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid *usgIn(nullptr);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation *sourceInfo(inputVector[1]->GetInformationObject(0));
+    vtkDataObject *source(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+    int nbOfBlocks(GetNumberOfBlocs(source));
+    // is this the first request
+    if (!this->IsExecuting)
+    {
+      request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+      this->IsExecuting = true;
+      this->Internal2.resize(nbOfBlocks);
+      int rk(0);
+      std::for_each(this->Internal2.begin(),this->Internal2.end(),[&rk,nbOfBlocks](std::unique_ptr< vtkInternal >& elt) { elt.reset(new vtkInternal(rk++,nbOfBlocks)); });
+    }
+    //
+    this->CurrentTimeIndex++;
+    vtkNew<vtkTable> table;
+    //
+    for(int blockId = 0 ; blockId < nbOfBlocks ; ++blockId)
+    {
+      vtkDataSet *source1(SplitSingleMultiBloc(source,blockId));
+      //
+      vtkNew<vtkExplodePolyLine> epl;
+      epl->SetInputData(source1);
+      epl->Update();
+      vtkDataSet *source2(epl->GetOutput());
+      //
+      this->Internal2[blockId]->analyzeInputDataSets(usgIn, source1);
+      ///////////////////////
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> &meshorig(this->Internal2[blockId]->meshOrigin());
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> &untouched_2d_cells(this->Internal2[blockId]->untouched2DCells());
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> &cells_at_boundary_origin(this->Internal2[blockId]->cellsAtBoundary());
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> &centers(this->Internal2[blockId]->centers());
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> &vol(this->Internal2[blockId]->measure());
+      if (this->Internal2[blockId]->computationNeeded())
+      {
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> mesh, polygon;
+        MEDCoupling::MCAuto<MEDCoupling::MEDFileData> data(MEDCoupling::MEDFileData::New());
+        meshorig = ToMedcoupling(data, usgIn);
+        meshorig->changeSpaceDimension(2, 0.);
+        mesh = meshorig->deepCopy(); //uncouple data and mesh
+        {
+          MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmp(MEDCoupling::MEDFileData::New());
+          polygon = ToMedcoupling(tmp, source2);
+        }
+        {
+          MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(polygon->getCoords()->keepSelectedComponents({2}));
+          if(!arr->isUniform(0, 1e-12))
+            std::cerr << "Expected coords array equal to 0 for Z axis... Ignored" << std::endl;
+        }
+        polygon->changeSpaceDimension(2, 0.);
+        {
+          bool tmp;
+          mcIdType tmpp;
+          MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> tmppp(polygon->mergeNodes(1e-12, tmp, tmpp));
+        }
+        MEDCoupling::MCAuto<MEDCoupling::MEDCoupling1SGTUMesh> polygon_1sgt(MEDCoupling::MEDCoupling1SGTUMesh::New(polygon));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> conn(polygon_1sgt->getNodalConnectivity()->deepCopy());
+        conn->rearrange(2);
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> notNullCellsPolygon;
+        {
+          MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> conn0(conn->keepSelectedComponents({0})), conn1(conn->keepSelectedComponents({1}));
+          MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> delta(MEDCoupling::DataArrayIdType::Substract(conn0, conn1));
+          notNullCellsPolygon = delta->findIdsNotEqual(0);
+        }
+        {
+          MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> tmp(polygon_1sgt->buildUnstructured());
+          polygon = tmp->buildPartOfMySelf(notNullCellsPolygon->begin(), notNullCellsPolygon->end());
+        }
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> polygon_2d(MEDCoupling::MEDCouplingUMesh::New("mesh", 2));
+        {
+          MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> coo(polygon->getCoords()->deepCopy());
+          polygon_2d->setCoords(coo);
+        }
+        polygon_2d->allocateCells();
+        {
+          MEDCoupling::MCAuto<MEDCoupling::MEDCoupling1SGTUMesh> tmp(MEDCoupling::MEDCoupling1SGTUMesh::New(polygon));
+          conn.takeRef(tmp->getNodalConnectivity());
+        }
+        conn->rearrange(2);
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> conn2(conn->fromLinkedListOfPairToList());
+        MyAssert(conn2->front() == conn2->back(), "Expected closed wire as input");
+        conn2->popBackSilent();
+        polygon_2d->insertNextCell(INTERP_KERNEL::NORM_POLYGON, conn2->getNbOfElems(), conn2->begin());
+        bool clockWise(false);
+        //
+        {//false is very important to state if input polygon is clockwise (>0) or not (<0)
+          MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> area(polygon_2d->getMeasureField(false));
+          clockWise = area->getIJ(0,0) > 0.0;
+        }
+        //
+        double bbox[4];
+        mesh->getBoundingBox(bbox);
+        double TmpCenter[2] = {(bbox[0] + bbox[1]) / 2., (bbox[2] + bbox[3]) / 2.};
+        double Tmpalpha = 1. / std::max(bbox[1] - bbox[0], bbox[3] - bbox[2]);
+        double MinusTmpCenter[2] = {-TmpCenter[0], -TmpCenter[1]}, Origin[2] = {0., 0.};
+        mesh->translate(MinusTmpCenter);
+        mesh->scale(Origin, Tmpalpha);
+        polygon->translate(MinusTmpCenter);
+        polygon->scale(Origin, Tmpalpha);
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> mesh2, line_inter;
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> cellid_in_2d, cellid_in1d;
+        {
+          MEDCoupling::MEDCouplingUMesh *tmp(nullptr), *tmp2(nullptr);
+          MEDCoupling::DataArrayIdType *tmp3(nullptr), *tmp4(nullptr);
+          MEDCoupling::MEDCouplingUMesh::Intersect2DMeshWith1DLine(mesh, polygon, 1e-12, tmp, tmp2, tmp3, tmp4);
+          mesh2 = tmp;
+          line_inter = tmp2;
+          cellid_in_2d = tmp3;
+          cellid_in1d = tmp4;
+        }
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> coo2(mesh2->getCoords()->deepCopy());
+        coo2->applyLin(1. / Tmpalpha, 0.);
+        coo2->applyLin(1., TmpCenter[0], 0);
+        coo2->applyLin(1., TmpCenter[1], 1);
+        mesh2->setCoords(coo2);
+
+        std::size_t side = clockWise?1:0;
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> twodcells_to_remove(cellid_in1d->keepSelectedComponents({side}));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> twodcells_to_keep(cellid_in1d->keepSelectedComponents({(side + 1) % 2}));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> ids(twodcells_to_keep->findIdsNotEqual(-1));
+        twodcells_to_keep = twodcells_to_keep->selectByTupleId(ids->begin(), ids->end());
+        int hotspot(twodcells_to_keep->front());
+        twodcells_to_remove = twodcells_to_remove->selectByTupleId(ids->begin(), ids->end());
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> allcells(twodcells_to_remove->buildComplement(mesh2->getNumberOfCells()));
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> mesh2_without_cells_around_polygon(mesh2->buildPartOfMySelf(allcells->begin(), allcells->end()));
+        std::vector<MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType>> grps;
+        {
+          std::vector<MEDCoupling::DataArrayIdType *> tmp(mesh2_without_cells_around_polygon->partitionBySpreadZone());
+          std::for_each(tmp.begin(), tmp.end(), [&grps](MEDCoupling::DataArrayIdType *grp) { grps.emplace_back(grp); });
+        }
+        std::for_each(grps.begin(), grps.end(), [allcells](MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> &grp) { grp = allcells->selectByTupleId(grp->begin(), grp->end()); });
+        MyAssert(grps.size() == 2, "Expecting 2 groups, 1 inside, 1 outside !");
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> zeGrp;
+        if (grps[0]->presenceOfValue(hotspot) && !grps[1]->presenceOfValue(hotspot))
+          zeGrp.takeRef(grps[0]);
+        if (grps[1]->presenceOfValue(hotspot) && !grps[0]->presenceOfValue(hotspot))
+          zeGrp.takeRef(grps[1]);
+        if (zeGrp.isNull())
+        {
+          throw INTERP_KERNEL::Exception("Internal error : partitioning failed !");
+        }
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> mesh3(mesh2->buildPartOfMySelf(zeGrp->begin(), zeGrp->end()));
+        double totVol(0.), refVol(0.);
+        {
+          MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> tmp(mesh3->getMeasureField(true)), tmp2(polygon_2d->getMeasureField(true));
+          totVol = tmp->accumulate(0);
+          refVol = tmp2->accumulate(0);
+        }
+        MyAssert(std::abs(totVol - refVol) / refVol < 1e-6, "The test of area conservation failed !");
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> original_cell_ids_2d(cellid_in_2d->selectByTupleId(zeGrp->begin(), zeGrp->end()));
+        original_cell_ids_2d->sort(); // les cells dans le referentiel original 2D
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> all_cut_2d_cells(cellid_in1d->deepCopy());
+        all_cut_2d_cells->rearrange(1);
+        all_cut_2d_cells->sort();
+        all_cut_2d_cells = all_cut_2d_cells->buildUnique(); // les cells qui ont subit un split dans le referentiel de sortie 2D
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> all_cut_2d_cells_origin(cellid_in_2d->selectByTupleId(all_cut_2d_cells->begin(), all_cut_2d_cells->end()));
+        untouched_2d_cells = original_cell_ids_2d->buildSubstraction(all_cut_2d_cells_origin);
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> cells_at_boundary(all_cut_2d_cells->buildIntersection(zeGrp)); // les cellules decoupees dans le referentiel de sortie 2D
+        cells_at_boundary_origin = cellid_in_2d->selectByTupleId(cells_at_boundary->begin(), cells_at_boundary->end());
+        mesh3 = mesh2->buildPartOfMySelf(cells_at_boundary->begin(), cells_at_boundary->end());
+        {
+          MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> tmp(mesh3->getMeasureField(true));
+          vol.takeRef(tmp->getArray());
+        }
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> tmp0(mesh->buildPartOfMySelf(untouched_2d_cells->begin(), untouched_2d_cells->end()));
+        mesh3->getBoundingBox(bbox);
+        double MinusZeCenter[2] = {-(bbox[0] + bbox[1]) / 2., -(bbox[2] + bbox[3]) / 2.};
+        double alpha(1. / std::max(bbox[1] - bbox[0], bbox[3] - bbox[2]));
+        mesh3->translate(MinusZeCenter);
+        mesh3->scale(Origin, alpha);
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> centers_around_zero(mesh3->computeCellCenterOfMass());
+        centers = centers_around_zero->deepCopy();
+        centers->applyLin(1. / alpha, -MinusZeCenter[0], 0);
+        centers->applyLin(1. / alpha, -MinusZeCenter[1], 1);
+      }
+      constexpr char SEARCHED_FIELD_EVOLUTION[] = "EVOLUTION";
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f(MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_NODES));
+      {
+        vtkPointData *pd(usgIn->GetPointData());
+        vtkDataArray *evolution_tmp(FindFieldWithNameStripped(pd,SEARCHED_FIELD_EVOLUTION));
+        vtkDoubleArray *evolution_tmp2(vtkDoubleArray::SafeDownCast(evolution_tmp));
+        if (!evolution_tmp2)
+        {
+          std::ostringstream oss;
+          oss << "Internal error : " << SEARCHED_FIELD_EVOLUTION << " is expected to be of type float32 !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+        MyAssert(evolution_tmp2->GetNumberOfTuples() == meshorig->getNumberOfNodes(), "Mismatch of sizes !");
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(MEDCoupling::DataArrayDouble::New());
+        arr->alloc(meshorig->getNumberOfNodes(), 1);
+        std::copy(evolution_tmp2->GetPointer(0), evolution_tmp2->GetPointer(meshorig->getNumberOfNodes()), arr->getPointer());
+        f->setArray(arr);
+        f->setMesh(meshorig);
+        f->checkConsistencyLight();
+      }
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f_easy(f->buildSubPart(untouched_2d_cells->begin(), untouched_2d_cells->end()));
+      //f_easy->setName("easy");
+      //f_easy->writeVTK("easy.vtu");
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> weights;
+      {
+        MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> tmp(f_easy->getDiscretization()->getMeasureField(f_easy->getMesh(), true));
+        weights.takeRef(tmp->getArray());
+      }
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> positive_ids(f_easy->getArray()->findIdsGreaterThan(0.));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> negative_ids(positive_ids->buildComplement(f_easy->getMesh()->getNumberOfNodes()));
+      double positive_part(0.), negative_part(0.);
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp(f_easy->getArray()->selectByTupleId(positive_ids->begin(), positive_ids->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp2(weights->selectByTupleId(positive_ids->begin(), positive_ids->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp3(MEDCoupling::DataArrayDouble::Multiply(tmp, tmp2));
+        positive_part = tmp3->accumulate((std::size_t)0);
+      }
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp(f_easy->getArray()->selectByTupleId(negative_ids->begin(), negative_ids->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp2(weights->selectByTupleId(negative_ids->begin(), negative_ids->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp3(MEDCoupling::DataArrayDouble::Multiply(tmp, tmp2));
+        negative_part = tmp3->accumulate((std::size_t)0);
+      }
+      MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f_hard(f->buildSubPart(cells_at_boundary_origin->begin(), cells_at_boundary_origin->end()));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> hard_part(f_hard->getValueOnMulti(centers->begin(), centers->getNumberOfTuples()));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> positive_ids_hard(hard_part->findIdsGreaterThan(0.));
+      MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> negative_ids_hard(positive_ids_hard->buildComplement(cells_at_boundary_origin->getNumberOfTuples()));
+      double positive_part_hard(0.), negative_part_hard(0.);
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp(hard_part->selectByTupleId(positive_ids_hard->begin(), positive_ids_hard->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp2(vol->selectByTupleId(positive_ids_hard->begin(), positive_ids_hard->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp3(MEDCoupling::DataArrayDouble::Multiply(tmp, tmp2));
+        positive_part_hard = tmp3->accumulate((std::size_t)0);
+      }
+      {
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp(hard_part->selectByTupleId(negative_ids_hard->begin(), negative_ids_hard->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp2(vol->selectByTupleId(negative_ids_hard->begin(), negative_ids_hard->end()));
+        MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> tmp3(MEDCoupling::DataArrayDouble::Multiply(tmp, tmp2));
+        negative_part_hard = tmp3->accumulate((std::size_t)0);
+      }
+      double timeStep;
+      {
+        vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
+        vtkDataObject *input(vtkDataObject::GetData(inInfo));
+        timeStep = input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP());
+      }
+      this->Internal2[blockId]->pushData(timeStep, positive_part + positive_part_hard, negative_part + negative_part_hard);
+      if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
+      {
+        this->Internal2[blockId]->fillTable(table);
+      }
+    }
+    if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
+      {
+        request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+        this->CurrentTimeIndex = 0;
+        this->IsExecuting = false;
+      }
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkTable *output(vtkTable::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    output->ShallowCopy(table);
+  }
+  catch (INTERP_KERNEL::Exception &e)
+  {
+    if (this->IsExecuting)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+    }
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkSedimentDeposit::RequestData : " << e.what() << std::endl;
+    vtkErrorMacro(<< oss.str());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkSedimentDeposit::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkSedimentDeposit::SetSourceData(vtkDataObject *input)
+{
+  this->SetInputData(1, input);
+}
+
+void vtkSedimentDeposit::SetSourceConnection(vtkAlgorithmOutput *algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+int vtkSedimentDeposit::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation *info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTable");
+  return 1;
+}
+
+bool vtkSedimentDeposit::vtkInternal::computationNeeded() const
+{
+       if (_recomputationOfMatrixNeeded)
+       {
+               _meshorig.nullify();
+               _untouched_2d_cells.nullify();
+               _cells_at_boundary_origin.nullify();
+               _centers.nullify();
+               _vol.nullify();
+       }
+       return _recomputationOfMatrixNeeded;
+}
+
diff --git a/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.h b/src/RateOfFlowThroughSection/plugin/RateOfFlowThroughSectionModule/vtkSedimentDeposit.h
new file mode 100644 (file)
index 0000000..0a7ec61
--- /dev/null
@@ -0,0 +1,131 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkSedimentDeposit_h__
+#define vtkSedimentDeposit_h__
+
+#include <vtkDataObjectAlgorithm.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkSetGet.h>
+#include <vtkDataSet.h>
+#include <vtkTable.h>
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkDoubleArray.h>
+#include <vtkInEdgeIterator.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkResampleWithDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include <vtkWarpScalar.h>
+
+#include "VTKToMEDMem.h"
+
+#include <vector>
+#include <deque>
+#include <map>
+#include <sstream>
+#include <memory>
+
+class VTK_EXPORT vtkSedimentDeposit : public vtkDataObjectAlgorithm
+{
+public:
+  static vtkSedimentDeposit *New();
+  vtkTypeMacro(vtkSedimentDeposit, vtkDataObjectAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  void SetSourceData(vtkDataObject *input);
+  void SetSourceConnection(vtkAlgorithmOutput *algOutput);
+
+  int FillOutputPortInformation(int, vtkInformation *) override;
+
+protected:
+  vtkSedimentDeposit();
+  ~vtkSedimentDeposit() override = default;
+
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+  int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+
+  int NumberOfTimeSteps;
+  int CurrentTimeIndex;
+  bool IsExecuting;
+  class  VTK_EXPORT vtkInternal
+  {
+  public:
+    vtkInternal(int curveId, int nbOfCurves) :_curve_id(curveId), _nb_of_curves(nbOfCurves) {}
+    void pushData(double timeStep, double positiveValue, double negativeValue) { _data.emplace_back(timeStep, positiveValue, negativeValue); }
+    void fillTable(vtkTable *table) const;
+    void analyzeInputDataSets(vtkUnstructuredGrid *ds1, vtkDataSet *ds2);
+    bool computationNeeded() const;
+    MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> &meshOrigin() { return _meshorig; }
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> &untouched2DCells() { return _untouched_2d_cells; }
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> &cellsAtBoundary() { return _cells_at_boundary_origin; }
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> &centers() { return _centers; }
+    MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> &measure() { return _vol; }
+    std::string getReprDependingPos(const std::string& origName) const;
+
+  private:
+    std::vector<std::tuple<double, double, double>> _data;
+    vtkMTimeType _mt1 = 0;
+    vtkMTimeType _mt2 = 0;
+    int _curve_id;
+    int _nb_of_curves;
+    bool _recomputationOfMatrixNeeded = true;
+    mutable MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> _meshorig;
+    mutable MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> _untouched_2d_cells;
+    mutable MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> _cells_at_boundary_origin;
+    mutable MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> _centers;
+    mutable MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> _vol;
+  };
+  std::vector< std::unique_ptr< vtkInternal > > Internal2;
+
+private:
+  vtkSedimentDeposit(const vtkSedimentDeposit &) = delete;
+  void operator=(const vtkSedimentDeposit &) = delete;
+};
+
+#endif
diff --git a/src/RateOfFlowThroughSection/plugin/filters.xml b/src/RateOfFlowThroughSection/plugin/filters.xml
new file mode 100644 (file)
index 0000000..7099009
--- /dev/null
@@ -0,0 +1,99 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="RateOfFlowThroughSection"
+                 class="vtkRateOfFlowThroughSection"
+                 label="Rate Of Flow Through Section">
+
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+
+      <InputProperty command="SetSourceConnection" label="Source" name="Source" panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+        <Documentation>
+          The value of this property determines a polyline through which the rate of flow will be computed.
+        </Documentation>
+      </InputProperty>
+
+      <Hints>
+        <ShowInMenu category="Hydraulics" />
+      </Hints>
+
+      <Hints>
+        <View type="XYChartView" />
+      </Hints>
+    </SourceProxy>
+
+    <SourceProxy class="vtkExplodePolyLine" name="Explode PolyLine">
+    <InputProperty name="Input" command="SetInputConnection">
+      <ProxyGroupDomain name="groups">
+        <Group name="sources"/>
+        <Group name="filters"/>
+      </ProxyGroupDomain>
+      <DataTypeDomain name="input_type">
+        <DataType value="vtkDataSet"/>
+      </DataTypeDomain>
+      <Documentation short_help= "Explose les polylines en lines" 
+                    long_help = "Explose les polylines en lines">
+      </Documentation>
+    </InputProperty>
+    <Hints>
+      <RepresentationType view="RenderView" type="Surface"/>
+      <ShowInMenu category="Hydraulics" />
+    </Hints>
+  </SourceProxy>
+
+  <SourceProxy name="SedimentDeposit"
+              class="vtkSedimentDeposit"
+              label="Sediment Deposit">
+  <InputProperty name="Input"
+                command="SetInputConnection">
+    <ProxyGroupDomain name="groups">
+      <Group name="sources"/>
+      <Group name="filters"/>
+    </ProxyGroupDomain>
+    <DataTypeDomain name="input_type">
+      <DataType value="vtkDataSet"/>
+    </DataTypeDomain>
+    <Documentation>
+      This property specifies the input to the Level Scalars filter.
+    </Documentation>
+  </InputProperty>
+
+  <InputProperty command="SetSourceConnection"
+                label="Source"
+                name="Source"
+                panel_visibility="default">
+    <ProxyGroupDomain name="groups">
+      <Group name="sources" />
+    </ProxyGroupDomain>
+    <Documentation>
+      The value of this property determines a closed polyline inside which the deposite will be computed.
+    </Documentation>
+  </InputProperty>
+
+  <Hints>
+    <ShowInMenu category="Hydraulics" />
+  </Hints>
+
+  <Hints>
+    <View type="XYChartView" />
+  </Hints>
+
+</SourceProxy>
+
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/RateOfFlowThroughSection/plugin/paraview.plugin b/src/RateOfFlowThroughSection/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..6164e54
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  RateOfFlowThroughSectionPlugin
+DESCRIPTION
+  This plugin provides the RateOfFlowThroughSection filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  VTK::FiltersSources
+  VTK::FiltersGeneral
diff --git a/src/RateOfFlowThroughSection/script/TestCase.py b/src/RateOfFlowThroughSection/script/TestCase.py
new file mode 100644 (file)
index 0000000..a51bada
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDLoader import *
+
+fname="hydrau_test1.med"
+meshName="mesh"
+arr=DataArrayDouble([0,1,2,3,4,5])
+m=MEDCouplingCMesh()
+m.setCoords(arr,arr)
+m=m.buildUnstructured()
+m.setName(meshName)
+m.simplexize(0)
+WriteMesh(fname,m,True)
+#
+f=MEDCouplingFieldDouble(ON_NODES)
+f.setMesh(m)
+f.setName("Field")
+arr=m.getCoords().magnitude()
+f.setArray(arr)
+for i in range(10):
+    arr+=0.1
+    f.setTime(float(i),i,0)
+    WriteFieldUsingAlreadyWrittenMesh(fname,f)
+    pass
+
diff --git a/src/RateOfFlowThroughSection/script/calcul_3.py b/src/RateOfFlowThroughSection/script/calcul_3.py
new file mode 100644 (file)
index 0000000..ae25c85
--- /dev/null
@@ -0,0 +1,140 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+
+resu = "resu.med"
+suffix_section = "5"
+section = "section_{}.med".format(suffix_section)
+
+print("Working with {}".format(section))
+mm=MEDFileMesh.New(resu)
+m=mm[0]
+sec=ReadMeshFromFile(section)
+assert(m.getCoords()[:,2].isUniform(0,1e-12))
+m.setCoords(m.getCoords()[:,[0,1]])
+assert(sec.getCoords()[:,2].isUniform(0,1e-12))
+sec.setCoords(sec.getCoords()[:,[0,1]])
+sec.mergeNodes(1e-12)
+sec.zipCoords()
+sec.removeDegenerated1DCells()
+_,line_inter,cellid_in_2d,cellid_in1d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m,sec,1e-6)
+line_inter.zipCoords()
+#
+TwoDcells=DataArrayInt(line_inter.getNumberOfCells())
+for i,t in enumerate(cellid_in1d):
+    candidates = [elt for elt in list(t) if elt != -1]
+    if len(candidates)==0:
+        TwoDcells[i]=-1
+    TwoDcells[i]=candidates[0]
+    pass
+notFreeStyle1DCells = TwoDcells.findIdsNotEqual(-1)
+n2oCells = TwoDcells[notFreeStyle1DCells]
+TwoDcells=cellid_in_2d[n2oCells]
+#
+effective_line1d=line_inter[notFreeStyle1DCells]
+# effective_2d_cells - maillage contenant pour chaque cellule du maillage 1D coupé la cellule 2D de resu qui la contient
+effective_2d_cells=m[TwoDcells]
+o2n=effective_2d_cells.zipCoordsTraducer()
+n2o=o2n.invertArrayO2N2N2O(effective_2d_cells.getNumberOfNodes())
+#
+effective_line1d=MEDCoupling1SGTUMesh(effective_line1d) # change format of umesh to ease alg
+effective_2d_cells=MEDCoupling1SGTUMesh(effective_2d_cells) # change format of umesh to ease alg
+assert(effective_2d_cells.getCellModelEnum()==NORM_TRI3)
+#
+conn1d=effective_line1d.getNodalConnectivity()[:] ; conn1d.rearrange(2)
+conn2d=effective_2d_cells.getNodalConnectivity()[:] ; conn2d.rearrange(3)
+coo1d=effective_line1d.getCoords()
+coo2d=effective_2d_cells.getCoords()
+assert(len(conn2d)==len(conn1d))
+# coeffs coeffs_integ and n2o are elements for matrix
+h_water_mts=MEDFileFloatFieldMultiTS(resu,"HAUTEUR D\'EAU",False)
+speed_mts=MEDFileFloatFieldMultiTS(resu,"VITESSE",False)
+assert(len(h_water_mts.getPflsReallyUsed())==0)
+assert(len(speed_mts.getPflsReallyUsed())==0)
+
+h_out=DataArrayDouble(effective_line1d.getNumberOfCells()) ; h_out[:]=0.
+v_out=DataArrayDouble(effective_line1d.getNumberOfCells()) ; v_out[:]=0.
+# on calcule la matrice qui pour chaque cellule du la line 1D decoupee, donne 
+# la contribution de chacun des nodes de la cell 2D a laquelle elle appartient.
+matrix=effective_line1d.getNumberOfCells()*[None]
+
+for i,(t1,t2) in enumerate(zip(conn1d,conn2d)):
+    seg2=coo1d[list(t1)]
+    tri3=coo2d[list(t2)]
+    baryInfo,length=DataArrayDouble.ComputeIntegralOfSeg2IntoTri3(seg2,tri3)
+    matrix[i]=[(n2o[i],j) for i,j in zip(list(t2),baryInfo)]
+    pass
+ortho=effective_line1d.buildUnstructured().buildOrthogonalField().getArray()
+
+for ts in range(1):
+    coeffs_integ=DataArrayDouble(effective_2d_cells.getNumberOfNodes()) ; coeffs_integ[:]=0
+    h_water=h_water_mts[ts] ; h_water.loadArrays()
+    speed=speed_mts[ts] ; speed.loadArrays()
+    h_water_arr=h_water.getUndergroundDataArray()
+    speed_arr=speed.getUndergroundDataArray().convertToDblArr()
+    assert(speed_arr[:,2].isUniform(0,1e-12))
+    speed_arr=speed_arr[:,[0,1]]
+    for i in range(effective_line1d.getNumberOfCells()):
+        row=matrix[i]
+        h_out[i]=sum([b*h_water_arr[a] for a,b in row])
+        speed=sum([b*speed_arr[a] for a,b in row])
+        v_out[i] = float(DataArrayDouble.Dot(speed,ortho[i])[0])
+        pass
+    zeValue = abs((h_out*v_out*effective_line1d.getMeasureField(True).getArray()).accumulate()[0])
+    print("ts %d (%d) = %lf"%(ts,int(h_water.getTime()[-1]),zeValue))
+    pass
+# Bug 21733
+# Avant 1 == 1487.5
+#       5 == 1434.8
+# Apres 1 == 1600.814665
+#       5 == 1600.837195
+"""h_f=MEDCouplingFieldDouble(ON_CELLS) ; h_f.setMesh(effective_line1d)
+h_f.setArray(h_out)
+h_f.setName("HAUTEUR")
+#
+v_f=MEDCouplingFieldDouble(ON_CELLS) ; v_f.setMesh(effective_line1d)
+v_f.setArray(v_out)
+v_f.setName("VITESSE")
+effective_line1d.write("line1d.med")
+WriteFieldUsingAlreadyWrittenMesh("line1d.med",h_f)
+WriteFieldUsingAlreadyWrittenMesh("line1d.med",v_f)"""
+
+"""# avec calcul_2
+ts 0 (0) = 1606.649455
+ts 1 (7200) = 1534.516771
+ts 2 (14400) = 1549.476531
+ts 3 (21600) = 1551.205389
+ts 4 (28800) = 1550.100327
+ts 5 (36000) = 1547.519873
+ts 6 (43200) = 1542.625840
+ts 7 (50400) = 1540.418416
+ts 8 (57600) = 1539.691491
+ts 9 (64800) = 1542.502136
+ts 10 (72000) = 1536.397618
+ts 11 (79200) = 1536.609661
+ts 12 (86400) = 1535.983922
+ts 13 (93600) = 1537.728434
+ts 14 (100800) = 1537.462885
+ts 15 (108000) = 1537.290268
+ts 16 (115200) = 1537.143315
+ts 17 (122400) = 1537.037729
+ts 18 (129600) = 1536.967132
+ts 19 (136800) = 1536.924427
+ts 20 (144000) = 1536.905037"""
diff --git a/src/RateOfFlowThroughSection/script/calcul_sediment_deposit.py b/src/RateOfFlowThroughSection/script/calcul_sediment_deposit.py
new file mode 100644 (file)
index 0000000..13c1709
--- /dev/null
@@ -0,0 +1,138 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+
+data_file="Res_sisy.med"
+poly_file="contour.med"
+cutoff=0.
+
+polygon=ReadMeshFromFile(poly_file)
+data=MEDFileMesh.New(data_file)
+mesh=data[0]
+mesh.changeSpaceDimension(2,0.)
+mesh=mesh.deepCopy()
+assert(polygon.getCoords()[:,2].isUniform(0,1e-12))
+polygon.changeSpaceDimension(2,0.)
+polygon.mergeNodes(1e-12) #
+polygon_1sgt=MEDCoupling1SGTUMesh(polygon)
+conn=polygon_1sgt.getNodalConnectivity().deepCopy()
+conn.rearrange(2)
+notNullCellsPolygon=(conn[:,0]-conn[:,1]).findIdsNotEqual(0)
+polygon=polygon_1sgt.buildUnstructured()[notNullCellsPolygon]
+polygon_2d=MEDCouplingUMesh("mesh",2)
+polygon_2d.setCoords(polygon.getCoords().deepCopy())
+polygon_2d.allocateCells()
+conn=MEDCoupling1SGTUMesh(polygon).getNodalConnectivity()
+conn.rearrange(2)
+conn2=conn.fromLinkedListOfPairToList()
+assert(conn2[0]==conn2[-1])
+conn2.popBackSilent()
+polygon_2d.insertNextCell(NORM_POLYGON,conn2.getValues())
+clockWise = polygon_2d.getMeasureField(False).getIJ(0,0) > 0.
+#
+side={True : 1 , False : 0}[clockWise]
+
+(Xmin,Xmax),(Ymin,Ymax)=mesh.getBoundingBox()
+TmpCenter=( (Xmin+Xmax)/2., (Ymin+Ymax)/2. )
+Tmpalpha=1/max(Xmax-Xmin,Ymax-Ymin)
+mesh.translate(-DataArrayDouble(TmpCenter,1,2))
+mesh.scale([0.,0.],Tmpalpha)
+polygon.translate(-DataArrayDouble(TmpCenter,1,2))
+polygon.scale([0.,0.],Tmpalpha)
+mesh2,line_inter,cellid_in_2d,cellid_in1d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(mesh,polygon,1e-12)
+coo=mesh2.getCoords().deepCopy()
+coo2=coo*(1/Tmpalpha)+TmpCenter
+mesh2.setCoords(coo2)
+
+twodcells_to_remove = cellid_in1d[:,side]
+twodcells_to_keep = cellid_in1d[:,(side+1)%2]
+ids=twodcells_to_keep.findIdsNotEqual(-1)
+twodcells_to_keep=twodcells_to_keep[ids]
+hotspot = twodcells_to_keep[0]
+
+twodcells_to_keep = twodcells_to_keep[ids] # les cells2D de bord du domaine dans le referentiel de sortie 2D
+twodcells_to_remove.sort()
+ids=twodcells_to_remove.findIdsNotEqual(-1)
+twodcells_to_remove=twodcells_to_remove[ids]
+allcells=twodcells_to_remove.buildComplement(mesh2.getNumberOfCells())
+mesh2_without_cells_around_polygon=mesh2[allcells]
+grps=mesh2_without_cells_around_polygon.partitionBySpreadZone()
+grps=[allcells[elt] for elt in grps]
+assert(len(grps)==2)
+zeGrp = None
+if (hotspot in grps[0]) and (hotspot not in grps[1]):
+    zeGrp = grps[0]
+if (hotspot not in grps[0]) and (hotspot in grps[1]):
+    zeGrp = grps[1]
+if not zeGrp:
+    raise RuntimeError("Ooops")
+    pass
+mesh3 = mesh2[zeGrp]
+totVol = mesh3.getMeasureField(True).accumulate()[0]
+refVol = polygon_2d.getMeasureField(True).accumulate()[0]
+assert(abs((totVol-refVol)/refVol)<1e-6)
+#
+original_cell_ids_2d=cellid_in_2d[zeGrp] ; original_cell_ids_2d.sort() # les cells dans le referentiel original 2D
+all_cut_2d_cells=cellid_in1d[:]
+all_cut_2d_cells.rearrange(1)
+all_cut_2d_cells.sort()
+all_cut_2d_cells=all_cut_2d_cells.buildUnique() # les cells qui ont subit un split dans le referentiel de sortie 2D
+
+all_cut_2d_cells_origin=cellid_in_2d[all_cut_2d_cells]
+untouched_2d_cells=original_cell_ids_2d.buildSubstraction(all_cut_2d_cells_origin)
+
+cells_at_boundary=all_cut_2d_cells.buildIntersection(zeGrp) # les cellules decoupées dans le referentiel de sortie 2D
+cells_at_boundary_origin=cellid_in_2d[cells_at_boundary]
+mesh3=mesh2[cells_at_boundary]
+vol = mesh3.getMeasureField(True).getArray()
+#volRef = mesh[cells_at_boundary_origin].getMeasureField(True).getArray()
+#centers=mesh3.computeCellCenterOfMass()
+#
+tmp0=mesh[untouched_2d_cells]
+(Xmin,Xmax),(Ymin,Ymax)=mesh3.getBoundingBox()
+ZeCenter=( (Xmin+Xmax)/2., (Ymin+Ymax)/2. )
+alpha=1/max(Xmax-Xmin,Ymax-Ymin)
+mesh3.translate(-DataArrayDouble(ZeCenter,1,2))
+mesh3.scale([0.,0.],alpha)
+centers_around_zero=mesh3.computeCellCenterOfMass()
+centers=centers_around_zero*(1/alpha)+ZeCenter
+# 
+evolution_multiTS=MEDFileFloatFieldMultiTS(data_file,"EVOLUTION",False)
+for ts in range(10):
+    evolution_1TS=evolution_multiTS[ts]
+    evolution_1TS.loadArrays()
+    f=evolution_1TS.field(data).convertToDblField()
+    f_easy=f[untouched_2d_cells]
+    f_easy.write("f_easy.med") #
+    weights = f_easy.getDiscretization().getMeasureField(f_easy.getMesh(),True).getArray()
+    positive_ids = f_easy.getArray().findIdsGreaterThan(cutoff)
+    negative_ids = positive_ids.buildComplement(f_easy.getMesh().getNumberOfNodes())
+    positive_part = (f_easy.getArray()[positive_ids]*weights[positive_ids]).accumulate(0)
+    negative_part = (f_easy.getArray()[negative_ids]*weights[negative_ids]).accumulate(0)
+    #
+    f_hard = f[cells_at_boundary_origin]
+    hard_part = f_hard.getValueOnMulti(centers)
+    positive_ids_hard = hard_part.findIdsGreaterThan(cutoff)
+    negative_ids_hard = positive_ids_hard.buildComplement(len(cells_at_boundary_origin))
+    positive_part_hard=(hard_part[positive_ids_hard]*vol[positive_ids_hard]).accumulate(0)
+    negative_part_hard=(hard_part[negative_ids_hard]*vol[negative_ids_hard]).accumulate(0)
+    print("Time step %d (%ld)"%(ts,evolution_1TS.getTime()[-1]),positive_part+positive_part_hard+negative_part+negative_part_hard)
+    evolution_1TS.unloadArrays()
+    pass
diff --git a/src/RateOfFlowThroughSection/script/test_sediment_deposit.py b/src/RateOfFlowThroughSection/script/test_sediment_deposit.py
new file mode 100644 (file)
index 0000000..3953b20
--- /dev/null
@@ -0,0 +1,224 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# trace generated using paraview version 5.6.0-RC1-3-g7bafc2b
+
+#### import the simple module from the paraview
+from paraview.simple import *
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'SerafinReader'
+res_sisy_total_Tronqueres = SerafinReader(FileName='/home/H87074/TMP168_HYDRAU/17372_SEDIMENTS/Res_sisy_total_Tronque.res')
+
+# get animation scene
+animationScene1 = GetAnimationScene()
+
+# update animation scene based on data timesteps
+animationScene1.UpdateAnimationUsingDataTimeSteps()
+
+# get active view
+renderView1 = GetActiveViewOrCreate('RenderView')
+# uncomment following to set a specific view size
+# renderView1.ViewSize = [1268, 607]
+
+# show data in view
+res_sisy_total_TronqueresDisplay = Show(res_sisy_total_Tronqueres, renderView1)
+
+# trace defaults for the display properties.
+res_sisy_total_TronqueresDisplay.Representation = 'Surface'
+res_sisy_total_TronqueresDisplay.ColorArrayName = [None, '']
+res_sisy_total_TronqueresDisplay.OSPRayScaleArray = 'EVOLUTION      '
+res_sisy_total_TronqueresDisplay.OSPRayScaleFunction = 'PiecewiseFunction'
+res_sisy_total_TronqueresDisplay.SelectOrientationVectors = 'EVOLUTION      '
+res_sisy_total_TronqueresDisplay.ScaleFactor = 466.36875000000003
+res_sisy_total_TronqueresDisplay.SelectScaleArray = 'EVOLUTION      '
+res_sisy_total_TronqueresDisplay.GlyphType = 'Arrow'
+res_sisy_total_TronqueresDisplay.GlyphTableIndexArray = 'EVOLUTION      '
+res_sisy_total_TronqueresDisplay.GaussianRadius = 23.3184375
+res_sisy_total_TronqueresDisplay.SetScaleArray = ['POINTS', 'EVOLUTION      ']
+res_sisy_total_TronqueresDisplay.ScaleTransferFunction = 'PiecewiseFunction'
+res_sisy_total_TronqueresDisplay.OpacityArray = ['POINTS', 'EVOLUTION      ']
+res_sisy_total_TronqueresDisplay.OpacityTransferFunction = 'PiecewiseFunction'
+res_sisy_total_TronqueresDisplay.DataAxesGrid = 'GridAxesRepresentation'
+res_sisy_total_TronqueresDisplay.SelectionCellLabelFontFile = ''
+res_sisy_total_TronqueresDisplay.SelectionPointLabelFontFile = ''
+res_sisy_total_TronqueresDisplay.PolarAxes = 'PolarAxesRepresentation'
+res_sisy_total_TronqueresDisplay.ScalarOpacityUnitDistance = 173.44832869720128
+
+# init the 'GridAxesRepresentation' selected for 'DataAxesGrid'
+res_sisy_total_TronqueresDisplay.DataAxesGrid.XTitleFontFile = ''
+res_sisy_total_TronqueresDisplay.DataAxesGrid.YTitleFontFile = ''
+res_sisy_total_TronqueresDisplay.DataAxesGrid.ZTitleFontFile = ''
+res_sisy_total_TronqueresDisplay.DataAxesGrid.XLabelFontFile = ''
+res_sisy_total_TronqueresDisplay.DataAxesGrid.YLabelFontFile = ''
+res_sisy_total_TronqueresDisplay.DataAxesGrid.ZLabelFontFile = ''
+
+# init the 'PolarAxesRepresentation' selected for 'PolarAxes'
+res_sisy_total_TronqueresDisplay.PolarAxes.PolarAxisTitleFontFile = ''
+res_sisy_total_TronqueresDisplay.PolarAxes.PolarAxisLabelFontFile = ''
+res_sisy_total_TronqueresDisplay.PolarAxes.LastRadialAxisTextFontFile = ''
+res_sisy_total_TronqueresDisplay.PolarAxes.SecondaryRadialAxesTextFontFile = ''
+
+# reset view to fit data
+renderView1.ResetCamera()
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# create a new 'ShapeReader'
+contourVolume1shp = ShapeReader(FileName='/home/H87074/TMP168_HYDRAU/17372_SEDIMENTS/ContourVolume1.shp')
+
+# show data in view
+contourVolume1shpDisplay = Show(contourVolume1shp, renderView1)
+
+# trace defaults for the display properties.
+contourVolume1shpDisplay.Representation = 'Surface'
+contourVolume1shpDisplay.ColorArrayName = [None, '']
+contourVolume1shpDisplay.OSPRayScaleFunction = 'PiecewiseFunction'
+contourVolume1shpDisplay.SelectOrientationVectors = 'None'
+contourVolume1shpDisplay.ScaleFactor = 28.764741869986757
+contourVolume1shpDisplay.SelectScaleArray = 'None'
+contourVolume1shpDisplay.GlyphType = 'Arrow'
+contourVolume1shpDisplay.GlyphTableIndexArray = 'None'
+contourVolume1shpDisplay.GaussianRadius = 1.4382370934993378
+contourVolume1shpDisplay.SetScaleArray = [None, '']
+contourVolume1shpDisplay.ScaleTransferFunction = 'PiecewiseFunction'
+contourVolume1shpDisplay.OpacityArray = [None, '']
+contourVolume1shpDisplay.OpacityTransferFunction = 'PiecewiseFunction'
+contourVolume1shpDisplay.DataAxesGrid = 'GridAxesRepresentation'
+contourVolume1shpDisplay.SelectionCellLabelFontFile = ''
+contourVolume1shpDisplay.SelectionPointLabelFontFile = ''
+contourVolume1shpDisplay.PolarAxes = 'PolarAxesRepresentation'
+
+# init the 'GridAxesRepresentation' selected for 'DataAxesGrid'
+contourVolume1shpDisplay.DataAxesGrid.XTitleFontFile = ''
+contourVolume1shpDisplay.DataAxesGrid.YTitleFontFile = ''
+contourVolume1shpDisplay.DataAxesGrid.ZTitleFontFile = ''
+contourVolume1shpDisplay.DataAxesGrid.XLabelFontFile = ''
+contourVolume1shpDisplay.DataAxesGrid.YLabelFontFile = ''
+contourVolume1shpDisplay.DataAxesGrid.ZLabelFontFile = ''
+
+# init the 'PolarAxesRepresentation' selected for 'PolarAxes'
+contourVolume1shpDisplay.PolarAxes.PolarAxisTitleFontFile = ''
+contourVolume1shpDisplay.PolarAxes.PolarAxisLabelFontFile = ''
+contourVolume1shpDisplay.PolarAxes.LastRadialAxisTextFontFile = ''
+contourVolume1shpDisplay.PolarAxes.SecondaryRadialAxesTextFontFile = ''
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# create a new 'Transform'
+transform1 = Transform(Input=contourVolume1shp)
+transform1.Transform = 'Transform'
+
+# Properties modified on transform1.Transform
+transform1.Transform.Translate = [800000.0, 6500000.0, 0.0]
+
+# Properties modified on transform1.Transform
+transform1.Transform.Translate = [800000.0, 6500000.0, 0.0]
+
+# show data in view
+transform1Display = Show(transform1, renderView1)
+
+# trace defaults for the display properties.
+transform1Display.Representation = 'Surface'
+transform1Display.ColorArrayName = [None, '']
+transform1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+transform1Display.SelectOrientationVectors = 'None'
+transform1Display.ScaleFactor = 28.764741869986757
+transform1Display.SelectScaleArray = 'None'
+transform1Display.GlyphType = 'Arrow'
+transform1Display.GlyphTableIndexArray = 'None'
+transform1Display.GaussianRadius = 1.4382370934993378
+transform1Display.SetScaleArray = [None, '']
+transform1Display.ScaleTransferFunction = 'PiecewiseFunction'
+transform1Display.OpacityArray = [None, '']
+transform1Display.OpacityTransferFunction = 'PiecewiseFunction'
+transform1Display.DataAxesGrid = 'GridAxesRepresentation'
+transform1Display.SelectionCellLabelFontFile = ''
+transform1Display.SelectionPointLabelFontFile = ''
+transform1Display.PolarAxes = 'PolarAxesRepresentation'
+
+# init the 'GridAxesRepresentation' selected for 'DataAxesGrid'
+transform1Display.DataAxesGrid.XTitleFontFile = ''
+transform1Display.DataAxesGrid.YTitleFontFile = ''
+transform1Display.DataAxesGrid.ZTitleFontFile = ''
+transform1Display.DataAxesGrid.XLabelFontFile = ''
+transform1Display.DataAxesGrid.YLabelFontFile = ''
+transform1Display.DataAxesGrid.ZLabelFontFile = ''
+
+# init the 'PolarAxesRepresentation' selected for 'PolarAxes'
+transform1Display.PolarAxes.PolarAxisTitleFontFile = ''
+transform1Display.PolarAxes.PolarAxisLabelFontFile = ''
+transform1Display.PolarAxes.LastRadialAxisTextFontFile = ''
+transform1Display.PolarAxes.SecondaryRadialAxesTextFontFile = ''
+
+# hide data in view
+Hide(contourVolume1shp, renderView1)
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# set active source
+SetActiveSource(res_sisy_total_Tronqueres)
+
+# create a new 'Sediment Deposit'
+sedimentDeposit1 = SedimentDeposit(Input=res_sisy_total_Tronqueres,
+    Source=transform1)
+
+#### saving camera placements for all active views
+
+# current camera placement for renderView1
+renderView1.InteractionMode = '2D'
+renderView1.CameraPosition = [487587.4375, 6685895.75, 9562.2955669413]
+renderView1.CameraFocalPoint = [487587.4375, 6685895.75, 0.0]
+renderView1.CameraParallelScale = 2474.9042076238147
+
+#### uncomment the following to render all views
+# RenderAllViews()
+# alternatively, if you want to write images, you can use SaveScreenshot(...).
+
+# Create a new 'Line Chart View'
+lineChartView1 = CreateView('XYChartView')
+lineChartView1.ViewSize = [735, 607]
+lineChartView1.ChartTitleFontFile = ''
+lineChartView1.LeftAxisTitleFontFile = ''
+lineChartView1.LeftAxisLabelFontFile = ''
+lineChartView1.BottomAxisTitleFontFile = ''
+lineChartView1.BottomAxisLabelFontFile = ''
+lineChartView1.RightAxisLabelFontFile = ''
+lineChartView1.TopAxisTitleFontFile = ''
+lineChartView1.TopAxisLabelFontFile = ''
+
+# get layout
+layout1 = GetLayout()
+
+# place view in the layout
+layout1.AssignView(2, lineChartView1)
+
+# show data in view
+rateOfFlowThroughSection1Display = Show(sedimentDeposit1, lineChartView1)
+
+# trace defaults for the display properties.
+rateOfFlowThroughSection1Display.CompositeDataSetIndex = [0]
+rateOfFlowThroughSection1Display.SeriesLabelPrefix = ''
+
+# update the view to ensure updated data information
+lineChartView1.Update()
diff --git a/src/RosetteCIH/CMakeLists.txt b/src/RosetteCIH/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ac9df2e
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(RosetteCIH)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/RosetteCIH/plugin/CMakeLists.txt b/src/RosetteCIH/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b74f6e8
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(RosetteCIH
+  VERSION "1.0"
+  MODULES RosetteCIHFilters
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/RosetteCIHFilters/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS RosetteCIH
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/RosetteCIH/plugin/RosetteCIHFilters/CMakeLists.txt b/src/RosetteCIH/plugin/RosetteCIHFilters/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fee6269
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkRosetteCIH
+)
+
+vtk_module_add_module(RosetteCIHFilters
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/RosetteCIH/plugin/RosetteCIHFilters/vtk.module b/src/RosetteCIH/plugin/RosetteCIHFilters/vtk.module
new file mode 100644 (file)
index 0000000..8e10a07
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  RosetteCIHFilters
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeometry
+  VTK::FiltersModeling
+  VTK::FiltersSources
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+  ParaView::VTKExtensionsFiltersGeneral
+  ParaView::VTKExtensionsMisc
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
+  VTK::IOInfovis
diff --git a/src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.cxx b/src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.cxx
new file mode 100644 (file)
index 0000000..8f38c11
--- /dev/null
@@ -0,0 +1,523 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkRosetteCIH.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataSetSurfaceFilter.h>
+#include <vtkDoubleArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkLineSource.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkRibbonFilter.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkTable.h>
+#include <vtkTessellatorFilter.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariant.h>
+#include <vtkVariantArray.h>
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::ExtractInfo(
+  vtkInformationVector* inputVector, vtkSmartPointer<vtkUnstructuredGrid>& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input(0);
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+  {
+    input = input0;
+  }
+  else
+  {
+    if (!input1)
+    {
+      vtkErrorMacro("Input dataSet must be a DataSet or single elt multi block dataset expected !");
+      return;
+    }
+    if (input1->GetNumberOfBlocks() != 1)
+    {
+      vtkErrorMacro("Input dataSet is a multiblock dataset with not exactly one block ! Use "
+                    "MergeBlocks or ExtractBlocks filter before calling this filter !");
+      return;
+    }
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+    {
+      vtkErrorMacro("Input dataSet is a multiblock dataset with exactly one block but this single "
+                    "element is NULL !");
+      return;
+    }
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+    {
+      vtkErrorMacro(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+      return;
+    }
+    input = input2c;
+  }
+
+  if (!input)
+  {
+    vtkErrorMacro("Input data set is NULL !");
+    return;
+  }
+
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+  {
+    if (!input1)
+    {
+      vtkNew<vtkMultiBlockDataGroupFilter> mb;
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+      mb->AddInputData(input);
+      cd->SetInputConnection(mb->GetOutputPort());
+      cd->SetMergePoints(0);
+      cd->Update();
+      usgIn = cd->GetOutput();
+    }
+    else
+    {
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> filter;
+      filter->SetMergePoints(0);
+      filter->SetInputData(input1);
+      filter->Update();
+      usgIn = filter->GetOutput();
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+vtkStandardNewMacro(vtkRosetteCIH);
+
+//-----------------------------------------------------------------------------
+vtkSmartPointer<vtkDataSet> vtkRosetteCIH::GenerateGlyphLinesFor(vtkUnstructuredGrid* usgIn,
+  const char* keyPoint, const char COMPRESS_TRACTION[])
+{
+  vtkFieldData* dsa(usgIn->GetCellData());
+  std::string arrayForGlyph(this->RetrieveFieldForGlyph(usgIn, keyPoint));
+  int compoId(-1);
+  vtkDoubleArray* arrayForPosNeg2(RetrieveFieldForPost(usgIn, keyPoint, compoId));
+  // vtkAbstractArray *arrayForPosNeg(dsa->GetAbstractArray(FIELD_NAME_2));
+  // vtkDoubleArray *arrayForPosNeg2(vtkDoubleArray::SafeDownCast(arrayForPosNeg));
+  int nbCompo(arrayForPosNeg2->GetNumberOfComponents());
+  vtkIdType nbTuples(arrayForPosNeg2->GetNumberOfTuples());
+  vtkNew<vtkDoubleArray> compressionOrTraction;
+  compressionOrTraction->SetNumberOfComponents(1);
+  compressionOrTraction->SetNumberOfTuples(nbTuples);
+  compressionOrTraction->SetName(COMPRESS_TRACTION);
+  const double* pt(arrayForPosNeg2->GetPointer(0));
+  double* ptOut(compressionOrTraction->GetPointer(0));
+  for (vtkIdType i = 0; i < nbTuples; i++)
+  {
+    if (pt[i * nbCompo + compoId] > 0.)
+      ptOut[i] = 1.;
+    else
+      ptOut[i] = -1.;
+  }
+  int arrId(dsa->AddArray(compressionOrTraction));
+  //
+  vtkNew<vtkPVGlyphFilter> glyph;
+  glyph->SetInputData(usgIn);
+  glyph->SetGlyphMode(0);       // vtkPVGlyphFilter::ALL_POINTS
+  glyph->SetVectorScaleMode(0); // vtkPVGlyphFilter::SCALE_BY_MAGNITUDE
+
+  //
+  vtkNew<vtkLineSource> arrow;
+  glyph->SetSourceConnection(arrow->GetOutputPort());
+  // idx,port,connection,fieldAssociation,name
+  glyph->SetInputArrayToProcess(
+    0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, arrayForGlyph.c_str()); // idx==0 -> scaleArray
+  glyph->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS,
+    arrayForGlyph.c_str()); // idx==1 -> orientationArray
+  glyph->SetScaleFactor(this->ScaleFactor);
+  glyph->Update();
+
+  return vtkSmartPointer<vtkDataSet>(glyph->GetOutput());
+}
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::PostTraitementT1etT2(
+  vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output)
+{
+  constexpr char COMPRESS_TRACTION[] = "CompressionOrTraction";
+  // "RESUNL__SIRO_ELEM_T1_Vector" , "RESUNL__SIRO_ELEM_T1"
+  vtkSmartPointer<vtkDataSet> gl1 =
+    this->GenerateGlyphLinesFor(usgIn, "T1", COMPRESS_TRACTION);
+  vtkSmartPointer<vtkDataSet> gl2 =
+    this->GenerateGlyphLinesFor(usgIn, "T2", COMPRESS_TRACTION);
+  //
+  vtkNew<vtkMultiBlockDataGroupFilter> mb;
+  vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+  mb->AddInputData(gl1);
+  mb->AddInputData(gl2);
+  cd->SetInputConnection(mb->GetOutputPort());
+  cd->SetMergePoints(0);
+  cd->Update();
+  //
+  output->ShallowCopy(cd->GetOutput());
+  //
+  vtkFieldData* dsa(output->GetPointData());
+  int nbOfArrays(dsa->GetNumberOfArrays());
+  for (int i = nbOfArrays - 1; i >= 0; i--)
+  {
+    const char* arrName(dsa->GetArrayName(i));
+    if (std::string(arrName) != COMPRESS_TRACTION)
+    {
+      dsa->RemoveArray(i);
+    }
+  }
+  output->GetPointData()->SetActiveAttribute(0, vtkDataSetAttributes::SCALARS);
+}
+
+//-----------------------------------------------------------------------------
+int vtkRosetteCIH::ComponentIdOfArray(vtkAbstractArray* array, const std::string& compoName)
+{
+  int nbCompo(array->GetNumberOfComponents());
+  int ret(-1);
+  for (int i = 0; i < nbCompo; i++)
+  {
+    if (compoName == array->GetComponentName(i))
+    {
+      if (ret != -1)
+      {
+        vtkErrorMacro("ComponentIdOfArray : already found !");
+        return ret;
+      }
+      ret = i;
+    }
+  }
+  if (ret == -1)
+  {
+    vtkErrorMacro(
+      "ComponentIdOfArray : component " << compoName << " in array " << array->GetName() << " !");
+  }
+  return ret;
+}
+
+//-----------------------------------------------------------------------------
+std::string vtkRosetteCIH::GenerateAValidFieldForGlyph(
+  vtkUnstructuredGrid* usgInCpy, const std::string& arrayName, const char* keyPoint)
+{
+  vtkFieldData* dsa(usgInCpy->GetCellData());
+  vtkAbstractArray* array(dsa->GetAbstractArray(arrayName.c_str()));
+  vtkDoubleArray* array2(vtkDoubleArray::SafeDownCast(array));
+  //
+  std::string ret(arrayName);
+  ret += std::string("_vveeccttoorr");
+  int compoIds[3] = { -1, -1, -1 };
+  for (int i = 0; i < 3; i++)
+  {
+    std::string compoName("SIG_");
+    compoName += keyPoint;
+    compoName += 'X' + i;
+    compoIds[i] = ComponentIdOfArray(array, compoName);
+  }
+  //
+  vtkIdType nbTuples(array2->GetNumberOfTuples());
+  int nbCompo(array2->GetNumberOfComponents());
+  vtkNew<vtkDoubleArray> vect;
+  vect->SetNumberOfComponents(3);
+  vect->SetNumberOfTuples(nbTuples);
+  vect->SetName(ret.c_str());
+
+  const double* pt(array2->GetPointer(0));
+  double* ptOut(vect->GetPointer(0));
+  for (vtkIdType i = 0; i < nbTuples; i++)
+  {
+    for (int j = 0; j < 3; j++)
+    {
+      ptOut[3 * i + j] = pt[nbCompo * i + compoIds[j]];
+    }
+  }
+  //
+  dsa->AddArray(vect);
+  return ret;
+}
+
+//-----------------------------------------------------------------------------
+bool vtkRosetteCIH::EndWith(const std::string& arrayName, const std::string& end)
+{
+  std::size_t lenOfLastChance(end.length());
+  if (arrayName.length() < lenOfLastChance)
+  {
+    return false;
+  }
+
+  std::string endOfArrayName(arrayName.substr(arrayName.length() - lenOfLastChance));
+  return endOfArrayName == end;
+}
+
+//-----------------------------------------------------------------------------
+bool vtkRosetteCIH::IsFirstChance(const std::string& arrayName, const char* keyPoint)
+{
+  std::string PATTERN("SIRO_ELEM");
+  PATTERN += std::string("_") + keyPoint;
+  return this->EndWith(arrayName, PATTERN);
+}
+
+//-----------------------------------------------------------------------------
+bool vtkRosetteCIH::IsLastChanceArray(const std::string& arrayName)
+{
+  return this->EndWith(arrayName, "SIRO_ELEM");
+}
+
+//-----------------------------------------------------------------------------
+std::string vtkRosetteCIH::GetFieldName(vtkUnstructuredGrid* usgInCpy, const char* keyPoint)
+{
+  vtkFieldData* dsa(usgInCpy->GetCellData());
+  std::string arrayNameOK;
+  int nbOfArrays(dsa->GetNumberOfArrays());
+  bool found(false);
+  for (int i = 0; i < nbOfArrays; ++i)
+  {
+    vtkAbstractArray* arrayAbstract(dsa->GetAbstractArray(i));
+    std::string arrayName(arrayAbstract->GetName());
+    if (this->IsFirstChance(arrayName, keyPoint) || this->IsLastChanceArray(arrayName))
+    {
+      if (found)
+      {
+        vtkErrorMacro("GetFieldName : already found !");
+      }
+      arrayNameOK = arrayName;
+      found = true;
+    }
+  }
+  if (!found)
+  {
+    vtkErrorMacro("GetFieldName : Impossible to find a valid array !");
+  }
+  return arrayNameOK;
+}
+
+//-----------------------------------------------------------------------------
+std::string vtkRosetteCIH::RetrieveFieldForGlyph(
+  vtkUnstructuredGrid* usgInCpy, const char* keyPoint)
+{
+  std::string arrayNameOK(this->GetFieldName(usgInCpy, keyPoint));
+  return this->GenerateAValidFieldForGlyph(usgInCpy, arrayNameOK, keyPoint);
+}
+
+//-----------------------------------------------------------------------------
+vtkDoubleArray* vtkRosetteCIH::RetrieveFieldForPost(
+  vtkUnstructuredGrid* usgInCpy, const char* keyPoint, int& compId)
+{
+  std::string FIELD_NAME_2(this->GetFieldName(usgInCpy, keyPoint));
+  vtkFieldData* dsa(usgInCpy->GetCellData());
+  vtkAbstractArray* arrayForPosNeg(dsa->GetAbstractArray(FIELD_NAME_2.c_str()));
+  vtkDoubleArray* arrayForPosNeg2(vtkDoubleArray::SafeDownCast(arrayForPosNeg));
+  std::string compoToFind("SIG_");
+  compoToFind += keyPoint;
+  compId = this->ComponentIdOfArray(arrayForPosNeg, compoToFind);
+  return arrayForPosNeg2;
+}
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::PostTraitementOnlyOneCompo(vtkUnstructuredGrid* usgIn,
+  vtkUnstructuredGrid* output, const char* keyPoint,
+  const char* COMPRESS_TRACTION)
+{
+  vtkNew<vtkUnstructuredGrid> usgInCpy;
+  usgInCpy->DeepCopy(usgIn);
+  //
+  vtkFieldData* dsa(usgInCpy->GetCellData());
+  int compId(-1);
+  // vtkAbstractArray *arrayForPosNeg(dsa->GetAbstractArray(FIELD_NAME_2));
+  std::string arrayForGlyph(this->RetrieveFieldForGlyph(usgInCpy, keyPoint));
+  vtkDoubleArray* arrayForPosNeg2(this->RetrieveFieldForPost(usgInCpy, keyPoint, compId));
+  // vtkDoubleArray::SafeDownCast(arrayForPosNeg);
+  int nbCompo(arrayForPosNeg2->GetNumberOfComponents());
+  vtkIdType nbTuples(arrayForPosNeg2->GetNumberOfTuples());
+
+  vtkNew<vtkDoubleArray> compressionOrTraction;
+  compressionOrTraction->SetNumberOfComponents(1);
+  compressionOrTraction->SetNumberOfTuples(nbTuples);
+  compressionOrTraction->SetName(COMPRESS_TRACTION);
+
+  const double* pt(arrayForPosNeg2->GetPointer(0));
+  double* ptOut(compressionOrTraction->GetPointer(0));
+  double valMin(std::numeric_limits<double>::max());
+  double valMax(-std::numeric_limits<double>::max());
+
+  for (vtkIdType i = 0; i < nbTuples; i++)
+  {
+    double val(pt[i * nbCompo + compId]);
+    valMin = std::min(valMin, val);
+    valMax = std::max(valMax, val);
+    ptOut[i] = val;
+  }
+  //
+  for (int i = dsa->GetNumberOfArrays() - 1; i >= 0; i--)
+  {
+    if (arrayForGlyph != dsa->GetAbstractArray(i)->GetName())
+    {
+      dsa->RemoveArray(i);
+    }
+  }
+  int arrId(dsa->AddArray(compressionOrTraction));
+
+  vtkNew<vtkLineSource> arrow;
+
+  vtkNew<vtkDataSetSurfaceFilter> surface;
+  surface->SetNonlinearSubdivisionLevel(0);
+  surface->SetInputData(usgInCpy);
+
+  vtkNew<vtkPolyDataNormals> normals;
+  normals->ComputeCellNormalsOn();
+  normals->ComputePointNormalsOff();
+  normals->SplittingOff();
+  normals->SetInputConnection(surface->GetOutputPort());
+  normals->Update();
+
+  // for some reasons, the glyph filter removes scalars and normals, we have to duplicate them
+  vtkDataArray* normalsArray = normals->GetOutput()->GetCellData()->GetNormals();
+
+  vtkSmartPointer<vtkDataArray> savedNormalsArray;
+  savedNormalsArray.TakeReference(normalsArray->NewInstance());
+  savedNormalsArray->DeepCopy(normalsArray);
+  savedNormalsArray->SetName("CellNormals");
+
+  normals->GetOutput()->GetCellData()->AddArray(savedNormalsArray);
+
+  vtkNew<vtkPVGlyphFilter> glyph;
+  glyph->SetInputConnection(normals->GetOutputPort());
+  glyph->SetGlyphMode(0);       // vtkPVGlyphFilter::ALL_POINTS
+  glyph->SetVectorScaleMode(0); // vtkPVGlyphFilter::SCALE_BY_MAGNITUDE
+  glyph->SetSourceConnection(arrow->GetOutputPort());
+  // idx,port,connection,fieldAssociation,name
+  glyph->SetInputArrayToProcess(
+    0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, arrayForGlyph.c_str()); // idx==0 -> scaleArray
+  glyph->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS,
+    arrayForGlyph.c_str()); // idx==1 -> orientationArray
+  glyph->SetScaleFactor(this->ScaleFactor);
+
+  vtkNew<vtkRibbonFilter> ribbon;
+  ribbon->SetWidth(this->WidthFactor);
+  ribbon->VaryWidthOff();
+  ribbon->UseDefaultNormalOff();
+  ribbon->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "CellNormals");
+  ribbon->SetInputConnection(glyph->GetOutputPort());
+  ribbon->Update();
+
+  vtkDataSet* ret = ribbon->GetOutput();
+
+  vtkFieldData* fieldData = ret->GetPointData();
+  for (int i = fieldData->GetNumberOfArrays() - 1; i >= 0; i--)
+  {
+    fieldData->RemoveArray(i);
+  }
+
+  fieldData = ret->GetCellData();
+  for (int i = fieldData->GetNumberOfArrays() - 1; i >= 0; i--)
+  {
+    fieldData->RemoveArray(i);
+  }
+
+  vtkNew<vtkDoubleArray> compressionOrTractionNaN;
+  compressionOrTractionNaN->SetNumberOfComponents(1);
+  compressionOrTractionNaN->SetNumberOfTuples(ret->GetNumberOfCells());
+  compressionOrTractionNaN->SetName(COMPRESS_TRACTION);
+  compressionOrTractionNaN->Fill(NAN);
+  fieldData->AddArray(compressionOrTractionNaN);
+
+  vtkNew<vtkTessellatorFilter> tesselator;
+  tesselator->SetOutputDimension(1);
+  tesselator->SetInputData(usgInCpy);
+  tesselator->Update();
+
+  vtkNew<vtkMultiBlockDataGroupFilter> mb;
+  mb->AddInputData(tesselator->GetOutput());
+  mb->AddInputData(ret);
+
+  vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+  cd->SetInputConnection(mb->GetOutputPort());
+  cd->SetMergePoints(0);
+  cd->Update();
+
+  output->ShallowCopy(cd->GetOutput());
+
+  int arrayId;
+  output->GetCellData()->GetAbstractArray(COMPRESS_TRACTION, arrayId);
+  output->GetCellData()->SetActiveAttribute(arrayId, vtkDataSetAttributes::SCALARS);
+}
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::PostTraitementT1(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output)
+{
+  // constexpr char FIELD_NAME[]="RESUNL__SIRO_ELEM_T1_Vector";
+  // constexpr char FIELD_NAME_2[]="RESUNL__SIRO_ELEM_T1";
+  constexpr char COMPRESS_TRACTION[] = "Contrainte specifique 1";
+  this->PostTraitementOnlyOneCompo(usgIn, output, "T1", COMPRESS_TRACTION);
+}
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::PostTraitementT2(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output)
+{
+  // constexpr char FIELD_NAME[]="RESUNL__SIRO_ELEM_T2_Vector";
+  // constexpr char FIELD_NAME_2[]="RESUNL__SIRO_ELEM_T2";
+  constexpr char COMPRESS_TRACTION[] = "Contrainte specifique 3";
+  this->PostTraitementOnlyOneCompo(usgIn, output, "T2", COMPRESS_TRACTION);
+}
+
+//-----------------------------------------------------------------------------
+int vtkRosetteCIH::RequestData(vtkInformation* vtkNotUsed(request),
+  vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  vtkInformation* outInfo(outputVector->GetInformationObject(0));
+  vtkUnstructuredGrid* output(
+    vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+  //
+  vtkSmartPointer<vtkUnstructuredGrid> usgIn;
+  this->ExtractInfo(inputVector[0], usgIn);
+  switch (this->TypeOfDisplay)
+  {
+    case 0:
+      this->PostTraitementT1etT2(usgIn, output);
+      break;
+    case 1:
+      this->PostTraitementT1(usgIn, output);
+      break;
+    case 2:
+      this->PostTraitementT2(usgIn, output);
+      break;
+    default:
+      vtkErrorMacro("GetFieldName : Impossible to find a valid array !");
+  }
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+void vtkRosetteCIH::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.h b/src/RosetteCIH/plugin/RosetteCIHFilters/vtkRosetteCIH.h
new file mode 100644 (file)
index 0000000..c184e44
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkRosetteCIH_h__
+#define __vtkRosetteCIH_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+#include <vtkSmartPointer.h>
+
+#include <string>
+#include <vector>
+
+class vtkDoubleArray;
+
+class VTK_EXPORT vtkRosetteCIH : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkRosetteCIH* New();
+  vtkTypeMacro(vtkRosetteCIH, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  vtkGetMacro(ScaleFactor, double);
+  vtkSetMacro(ScaleFactor, double);
+
+  vtkGetMacro(WidthFactor, double);
+  vtkSetMacro(WidthFactor, double);
+
+  vtkGetMacro(TypeOfDisplay, int);
+  vtkSetMacro(TypeOfDisplay, int);
+
+protected:
+  vtkRosetteCIH() = default;
+  ~vtkRosetteCIH() override = default;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  void ExtractInfo(vtkInformationVector* inputVector, vtkSmartPointer<vtkUnstructuredGrid>& usgIn);
+
+  vtkSmartPointer<vtkDataSet> GenerateGlyphLinesFor(
+    vtkUnstructuredGrid* usgIn, const char* keyPoint, const char COMPRESS_TRACTION[]);
+
+  void PostTraitementT1etT2(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output);
+
+  int ComponentIdOfArray(vtkAbstractArray* array, const std::string& compoName);
+
+  std::string GenerateAValidFieldForGlyph(
+    vtkUnstructuredGrid* usgInCpy, const std::string& arrayName, const char* keyPoint);
+
+  bool EndWith(const std::string& arrayName, const std::string& end);
+
+  bool IsFirstChance(const std::string& arrayName, const char* keyPoint);
+  bool IsLastChanceArray(const std::string& arrayName);
+
+  std::string GetFieldName(vtkUnstructuredGrid* usgInCpy, const char* keyPoint);
+
+  std::string RetrieveFieldForGlyph(vtkUnstructuredGrid* usgInCpy, const char* keyPoint);
+
+  vtkDoubleArray* RetrieveFieldForPost(
+    vtkUnstructuredGrid* usgInCpy, const char* keyPoint, int& compId);
+
+  void PostTraitementOnlyOneCompo(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output,
+    const char* keyPoint, const char* COMPRESS_TRACTION);
+
+  void PostTraitementT1(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output);
+  void PostTraitementT2(vtkUnstructuredGrid* usgIn, vtkUnstructuredGrid* output);
+
+  double ScaleFactor;
+  double WidthFactor;
+  int TypeOfDisplay;
+
+private:
+  vtkRosetteCIH(const vtkRosetteCIH&) = delete;
+  void operator=(const vtkRosetteCIH&) = delete;
+};
+
+#endif
diff --git a/src/RosetteCIH/plugin/filters.xml b/src/RosetteCIH/plugin/filters.xml
new file mode 100644 (file)
index 0000000..1c3d6ae
--- /dev/null
@@ -0,0 +1,54 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy class="vtkRosetteCIH"
+                 name="Rosettes de contrainte">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid"/>
+        </DataTypeDomain>
+        <Documentation short_help= "Affiche les rosettes de contraintes."
+                       long_help = "Affiche les rosettes de contraintes.">
+        </Documentation>
+      </InputProperty>
+      <DoubleVectorProperty command="SetScaleFactor"
+                            default_values="1e-6"
+                            name="ScaleFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <Documentation>This property specifies the scale factor applied to the length of the ribbon.
+        </Documentation>
+      </DoubleVectorProperty>
+      <DoubleVectorProperty command="SetWidthFactor"
+                            default_values="0.1"
+                            name="WidthFactor"
+                            number_of_elements="1"
+                            animateable="1"
+                            panel_visibility="default">
+        <Documentation>This property specifies the width factor applied to the ribbon.
+        </Documentation>
+      </DoubleVectorProperty>
+      <IntVectorProperty command="SetTypeOfDisplay"
+                         default_values="0"
+                         name="TypeOfDisplay"
+                         number_of_elements="1">
+        <EnumerationDomain name="enum">
+          <Entry text="T1 et T2 compression/traction" value="0" />
+          <Entry text="T1 only" value="1" />
+          <Entry text="T2 only" value="2" />
+        </EnumerationDomain>
+        <Documentation>Property pour specifier l'une des 3 visus liées aux rosettes.
+        </Documentation>
+      </IntVectorProperty>
+      <Hints>
+        <RepresentationType view="RenderView" type="Wireframe"/>
+        <ShowInMenu category="Mechanics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/RosetteCIH/plugin/paraview.plugin b/src/RosetteCIH/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..e87df62
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  RosetteCIH
+DESCRIPTION
+  This plugin provides ...
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/SerafinReader/CMakeLists.txt b/src/SerafinReader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bbbc3e9
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(SerafinReader)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/SerafinReader/geo_TW.slf b/src/SerafinReader/geo_TW.slf
new file mode 100644 (file)
index 0000000..058d01f
Binary files /dev/null and b/src/SerafinReader/geo_TW.slf differ
diff --git a/src/SerafinReader/plugin/CMakeLists.txt b/src/SerafinReader/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2687b3b
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(SerafinReader
+  VERSION "1.0"
+  MODULES SerafinReaderModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/SerafinReaderModule/vtk.module"
+  SERVER_MANAGER_XML sources.xml
+)
+
+install(TARGETS SerafinReader
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/CMakeLists.txt b/src/SerafinReader/plugin/SerafinReaderModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fc8f2c4
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkSerafinReader
+)
+
+vtk_module_add_module(SerafinReaderModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/FFileReader.h b/src/SerafinReader/plugin/SerafinReaderModule/FFileReader.h
new file mode 100644 (file)
index 0000000..d8ab149
--- /dev/null
@@ -0,0 +1,195 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    $RCSfile: FFileReader.h,v $
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+////// Reader for files generated by The  TELEMAC modelling system \\\\\
+// Module developped by herve ozdoba - Sept 2008 ( herve-externe.ozdoba at edf.fr / herve at ozdoba.fr )
+// Please address all comments to Regina Nebauer ( regina.nebauer at edf.fr )
+// >>> Test version
+
+#ifndef __FFileReader_h__
+#define __FFileReader_h__
+
+/** -- Inclusions issues de la bibliothèque standard du C++ -- */
+
+#include <fstream>
+#include <string>
+#include <cstdio>
+#include <iostream>
+#include <cstring>
+#include <stdint.h>   // need 64bit file position variables
+
+using namespace std;
+
+#include "vtkStringArray.h"
+
+/** ********************************************************************************************************* **/
+/** -- Definition de la classe abstraite de lecture des fichiers issus du langage de programmation Fortran -- **/
+/** ********************************************************************************************************* **/
+
+/// Cette classe, destinée uniquement à lire un fichier Serafin écrit par Telemac sous Fortran, permet de simplifier la lecture
+/// des données binaires en prenant en charge les systèmes d'écriture big/little endian spécifiques à certaine architecture .
+
+// Passe de quatre octets à la lecture d'un flux
+#define skipReadingHeader(stream) (stream->seekg (sizeof(int), ios_base::cur ))
+
+class FFileReader
+{
+public:
+
+  // Simple constructeur (flux en argument)
+  FFileReader(ifstream* stream);
+
+  // Simple constructeur (nom de fichier en argument)
+  FFileReader(const vtkStdString& filename);// non implémentée
+
+  // Destructeur de base
+  ~FFileReader();
+
+  // [inline] Retourne true si le fichier est écrit en big endian, cette fonction utilise la taille maximum du titre de la simu pour
+  // déterminer cette propriété (donc cette classe ne peut en aucun être utilisée hors de son domaine actuel d'utilisation)
+  // TODO Modifier le nom de cette méthode, elle n'indique pas le système d'écriture mais uniquement la nécessité d'inverser ou non l'ordre des bytes à
+  // la lecture du fichier .
+  bool    IsBigEndian(){return this->BigEndian;};
+
+  // [inline] Déplace le pointeur de lecture du fichier vers le bloc d'écriture suivant dans le fichier fortran et retourne la position actuelle .
+  int    GoToNextBloc()
+  {
+    FileStream->seekg (GetBlocSize() + 2*sizeof(int), ios_base::cur);
+    if (IsBigEndian()) s_readBlocSize ();else  ns_readBlocSize ();
+
+    return FileStream->tellg();
+  };
+
+  // [inline] Retourne la taille du bloc d'écriture actuel .
+  int    GetBlocSize(){return this->BlocSize;};
+        // float size - allow for 32 or 64 bit floats
+
+  // Lit et stocke des tableaux sous différents formats (la taille est spécifiée en second argument)
+        // these functions return a file position
+  int64_t    (FFileReader:: *readIntArray)    (int* , const int);
+  int64_t    (FFileReader:: *readFloatArray)  (double*, const int);
+  int64_t    (FFileReader:: *readStringArray) (vtkStringArray*, const int); // nom implémentée
+
+  // Quelques macros pour simplification d'écriture sur pointeur de fonction
+  // TODO Redefinir les macros, elle ne sont plus valables ...  à dédéfinir du type '(*this.*readFloatArray)' pour utilisation ultérieure .
+  #define ReadIntArray (*readIntArray)
+  #define ReadFloatArray (*readFloatArray)
+  /*#define ReadStringArray (*ReadStringArray)*/
+
+  // [inline] Lit une chaîne de caractères en fonction de la taille passée en argument et se déplace sur le bloc suivant
+  int64_t    ReadString(char* s, int size)
+  {
+    skipReadingHeader(FileStream);
+    FileStream->read  (s, size);
+    skipReadingHeader(FileStream);
+    readBlocSize ();
+    // if (IsBigEndian()) s_readBlocSize ();else  ns_readBlocSize ();
+
+    return FileStream->tellg();
+  };
+
+  // lecture de tableaux avec inversion des octets ou non
+  int64_t s_readInt32Array(int* arr, const int size);
+  int64_t ns_readInt32Array(int* arr, const int size);
+  int64_t g_readInt32Array(int* arr, const int size);
+
+  int64_t s_readFloat32Array(double* arr, const int size);
+  int64_t ns_readFloat32Array(double* arr, const int size);
+  int64_t g_readFloat32Array(double* arr, const int size);
+
+  int64_t s_readInt64Array(int64_t* arr, const int size);
+  int64_t ns_readInt64Array(int64_t* arr, const int size);
+  int64_t g_readInt64Array(int64_t* arr, const int size);
+
+  int64_t s_readFloat64Array(double* arr, const int size);
+  int64_t ns_readFloat64Array(double* arr, const int size);
+  int64_t g_readFloat64Array(double* arr, const int size);
+  // Retourne la taille du fichier
+  // TODO A placer en protected par la suite
+  int64_t GetFileSize()
+  {
+    // sauvegarder la position courante
+    int64_t pos = FileStream->tellg();
+
+    // se placer en fin de fichier
+    FileStream->seekg( 0 , std::ios_base::end );
+
+    // récupérer la nouvelle position = la taille du fichier
+    int64_t size = FileStream->tellg() ;
+
+    // restaurer la position initiale du fichier
+    FileStream->seekg( pos,  std::ios_base::beg ) ;
+
+    return size ;
+  };
+
+
+protected:
+
+  FFileReader(); // Non-implémentée
+
+  bool    BigEndian; // Système d'écriture du fichier
+  int    BlocSize;  // Taille du bloc d'écriture suivant
+
+  ifstream *FileStream;  // Le flux d'entrée du fichier
+
+  // [inline] Lecture d'un entête avec ou sans swap (indicateur par préfixe)
+  void     s_readBlocSize ()  {ns_readBlocSize (); Swap32((char*)(&BlocSize));};
+  void     ns_readBlocSize () {FileStream->read ((char*)(&BlocSize), sizeof(int));FileStream->seekg ( -sizeof(int), ios_base::cur );};
+
+  void     readBlocSize()
+  {
+    FileStream->read ((char*)(&BlocSize), sizeof(int));
+    // always reposition it back to its start .....
+    FileStream->seekg ( -sizeof(int), ios_base::cur );
+    if ( this->BigEndian) {
+      Swap32((char*)(&BlocSize));
+    }
+
+  };
+
+private:
+  //[inline] Gestion des swaps pour la prise en charge l/ge
+  #define Intervert(i,j) {one_byte = data[i]; data[i] = data[j]; data[j] = one_byte;}
+  void Swap32   (char* data)      {char one_byte;Intervert(0,3);Intervert(1,2);}
+  void Swap32Array (const long int size, char* data)  {long int indent;for(indent = 0; indent!= size; indent++) Swap32(&data[indent*4]);};
+  void Swap64   (char* data)      {char one_byte;Intervert(0,7);Intervert(1,6);Intervert(2,5);Intervert(3,4);}
+  void Swap64Array (const long int size, char* data)  {long int indent;for(indent = 0; indent!= size; indent++) Swap64(&data[indent*8]);};
+
+  FFileReader(const FFileReader&);  // Pas implémentée
+  void operator=(const FFileReader&);    // Pas implémentée
+
+}; /* class_FFileReader */
+
+#endif
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/stdSerafinReader.h b/src/SerafinReader/plugin/SerafinReaderModule/stdSerafinReader.h
new file mode 100644 (file)
index 0000000..e068209
--- /dev/null
@@ -0,0 +1,443 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    $RCSfile: stdSerafinReader.h,v $
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+////// Reader for files generated by The  TELEMAC modelling system \\\\\
+// Module developped by herve ozdoba - Sept 2008 ( herve-externe.ozdoba at edf.fr / herve at ozdoba.fr )
+// Please address all comments to Regina Nebauer ( regina.nebauer at edf.fr )
+// >>> Test version
+
+#ifndef __stdSerafinReader_h__
+#define __stdSerafinReader_h__
+
+/** -- Inclusions issues de la bibliothèque standard du C++ -- */
+
+#include "FFileReader.h"
+
+#include <fstream>
+#include <string>
+#include <cstdio>
+#include <iostream>
+#include <cstring>
+
+using namespace std;
+
+#include "vtkStringArray.h"
+#include "vtkIntArray.h"
+#include "vtkFloatArray.h"
+#include "vtkStdString.h"
+#include "vtkDoubleArray.h"
+#include "vtkIntArray.h"
+#include "vtkCellArray.h"
+
+/** ***************************************** **/
+/** ********** A définir pour test ********** **/
+/** ***************************************** **/
+
+/// Veuillez décommentez la ligne suivante et compiler en mode exécutable pour effectuer des tests ///
+
+#define   ___SIMPLE_READER_TEST_EXE___
+
+/** -- Quelques définitions inhérantes au format Serafin standard -- **/
+
+// Nombre maximum de caractères que peut avoir le titre d'une simulation sous Telemac.
+#define   TITLE_MAX_SIZE   80
+
+// Taille du bloc de description des discrétisations.
+#define   VAR_DESC_SIZE    16
+
+// Taille du bloc de définition des paramètres dans le fichier .
+#define   PARAM_NUMBER     10
+
+// Taille du bloc de définition des dates dans le fichier .
+#define   DATE_NUMBER     6
+
+//Taille des informations relatives aux discrétisations
+#define   DISC_DESC_SIZE  4
+
+/** ********************************************************************************* **/
+/** -- Definition des type utilisés pour la classe de lecture des fichiers Serafin -- **/
+/** ********************************************************************************* **/
+
+/// ci-dessous, voici une liste de types définis afin de faciliter le stockage des informations d'entête
+/// d'un fichier Serafin en lecture .
+
+// Définit le type de discrétisation utilisé dans le fichier
+// TODO A revoir pour la dénormination
+typedef enum
+{
+  P0_Elem = 0, // >>> Serafin
+  P1_Elem = 1, // >>> Volfin
+  P2_Elem = 2  // Pas encore implémenté
+
+} SerafinDiscretizationType;/* enum_DiscretizationType */
+
+// Définit les informations sur une variables ;
+typedef struct
+{
+  char name[VAR_DESC_SIZE] ;
+  char unit[VAR_DESC_SIZE] ;
+  int ncomp; // Number of coponent
+  int icomp; // Id of component
+
+} SerafinVar;/* struct_Var */
+
+// Définit les informations relatives à une date précise
+typedef struct
+{
+  int  day  ;  int  month ;  int  year ;
+  int  hour ;  int  min   ;  int  sec  ;
+
+} SerafinDate;/* struct_Date */
+
+// Définit une structure standard pour les meta-données (en considérant une seule discrétisation par fichier)
+typedef struct
+{
+  char    Title[TITLE_MAX_SIZE] ;     // le titre
+  int     VarNumber ;         // le nombre de variables
+  char*   VarList ;         // Un pointeur vers la liste des variables
+  SerafinVar* nVarList ;         // Un pointeur vers la liste des variables
+  int  IParam[PARAM_NUMBER] ;      // l'information IParam
+  int  Date[DATE_NUMBER] ;      // La date du début de la simulation
+  int  DiscretizationInfo[DISC_DESC_SIZE] ;  // Le informations de discrétisation (nombre d'éléments, nombre de points, ...)
+
+} SerafinMetaData; /* struct_MetaData */
+
+// Définit l'index général d'un fichier serafin pour faciliter le positionnement la de la lecture
+typedef struct
+{
+  int64_t FileSize ;      // taille du fichier
+  int64_t MetaSize ;      // taille des metadonnées
+  int64_t DataSize ;      // Taille totale des blocs de données
+  int64_t DataBlocSize ;    // Taille d'un bloc de données
+  int64_t FloatSize ;     // Taille des reels 4 ou 8
+  int64_t IntSize ;     // Taille des reels 4 ou 8
+  int64_t TagSize ;     // Taille des reels 4 ou 8
+  int64_t FieldSize; // Taille d'un champ
+  int64_t TimeSize; // Taille d'un temps
+
+  int64_t ConnectivityPosition ;  // La position dans le fichier de la table de connectivité
+  int64_t XPosition;      // La position dans le fichier de la table des valeurs de X
+  int64_t YPosition;      // La position dans le fichier de la table des valeurs de Y
+  int64_t DataPosision;    // La position dans le fichier des blocs de données
+
+  int NumberOfDate ;    // Information sur le temps étudié
+
+  // TODO La variable suivante n'a rien à faire dans cette stucture à mon avis mais je la laisse en attendant
+  // Elle décrit le type de discrétisation qui est affecté lors de la création de l'index du fichier, d'où sa présence ici
+  SerafinDiscretizationType discretizationtype ;
+
+} SerafinIndexInfo; /* struct_IndexInfo */
+
+/** ********************************************************************************************* **/
+/** -- Definition de la classe générique de traitement des fichiers externes au format Serafin -- **/
+/** ********************************************************************************************* **/
+
+/// Classe de lecture de fichier Serafin utilisée par le lecteur Serafin .
+/// Elle parse l'entête du fichier pour recueillir les informations le concernant puis créer une table d'index qui
+/// permet la lecture des informations souhaitées .
+
+// TODO Normaliser l'écriture des fonction avec un premier caractère en majuscule (pb mineur)
+
+// Supprime les espaces à la fin d'une chaine
+#define DeleteBlank(string, maxsize) \
+  {int compteur = maxsize ; while(isspace(string[compteur-1])&&(compteur!= 0)) compteur --; string[compteur] = '\0';}
+
+class stdSerafinReader : public FFileReader
+{
+public:
+  // Simple constructeur (flux en argument)
+  stdSerafinReader(ifstream* stream);
+
+  // Destructeur de base
+  ~stdSerafinReader() {
+    // remove cache values
+    delete XValues, YValues;
+  }
+
+  // Renvoie 1 si le fichier est un fichier serafin 3D
+
+  int Is3D = 0;
+
+  int Is3Dfile ()
+  {
+    if (this->Is3D == 0) {
+      int id;
+      char name[VAR_DESC_SIZE+1];
+      this->Is3D = 0;
+      for (id=0; id<GetNumberOfVars(); id++) {
+        GetVarNameById(id,&name[0]);
+        if (strstr ( name, "ELEVATION") != NULL \
+            ||  strstr (name, "COTE Z") != NULL ) {
+          this->Is3D = 1;
+          return this->Is3D;
+        }
+      }
+   }
+   return this->Is3D;
+  };
+
+  // Renvoie la variable associée à un identifiant dans la liste stockée dans le fichier Serafin
+  void GetVarById(const int id, SerafinVar* var)
+  {
+    int icomp, ncomp;
+    if (id > GetNumberOfVars()) return;
+    strncpy(metadata->nVarList[id].name, var->name, VAR_DESC_SIZE+1);
+    strncpy(metadata->nVarList[id].unit, var->unit, VAR_DESC_SIZE+1);
+    metadata->nVarList[id].ncomp = var->ncomp;
+    metadata->nVarList[id].icomp = var->icomp;
+  };
+
+  // Associe le nom de la variable selon le rang dans la table (name doit avoir 17 caractères disponibles )
+  void GetVarNameById(const int id, char* name)
+  {
+    if (id > GetNumberOfVars()) return;
+    memcpy ( name, metadata->nVarList[id].name, VAR_DESC_SIZE );
+    name[VAR_DESC_SIZE] = '\0' ;
+  };
+
+  // Associe l'unité de la variable selon le rang dans la table (unit doit avoir 17 caractère disponibles )
+  void GetVarUnitById(const int id, char* unit)
+  {
+    if (id > GetNumberOfVars()) return;
+    memcpy ( unit, metadata->nVarList[id].unit, VAR_DESC_SIZE );
+    unit[VAR_DESC_SIZE] = '\0' ;
+  };
+
+  // Retourne le nombre de variables ( X e t Y exceptés )
+  int         GetNumberOfVars()     {return this->metadata->VarNumber;};
+
+  // Associe le nom de la simulation à l'argument name .
+  void        GetTitle(char* name)    {strcpy(name, this->metadata->Title);};
+
+  // Retourne 1 si la date de début de la simulation est connue
+  int        HasDate()      {return (this->metadata->IParam[9] == 1);};
+
+  // Associe la date de début de simulation
+  void        GetDate(SerafinDate* date)
+  {
+    date->day   = this->metadata->Date[2];  date->month = this->metadata->Date[1];  date->year  = this->metadata->Date[0];
+    date->hour  = this->metadata->Date[3];  date->min   = this->metadata->Date[4];  date->sec   = this->metadata->Date[5];
+  };
+
+  // Simplifie la lecture des informations de discrétisation
+  int         GetNodeByElements()     {return this->metadata->DiscretizationInfo[2];};
+  int         GetNumberOfNodes()     {return this->metadata->DiscretizationInfo[1];};
+  int        GetNumberOfElement()     {return this->metadata->DiscretizationInfo[0];};
+
+  // Retourne le nombre de pas de temps
+  int GetTotalTime() {return this->index->NumberOfDate;};
+
+  // Retourne une date selon l'identifiant 'timeid' spécifié en argument
+  double GetTime(int timeid)
+  {
+    double value = 0;
+    FileStream->seekg( this->index->DataPosision + this->index->DataBlocSize * timeid ,  std::ios_base::beg ) ;
+    skipReadingHeader(FileStream);
+    (*this.*readFloatArray)(&(value), 1);
+    return value;
+  };
+
+
+  // Lit les valeurs d'abscisse et les copie dans la table 'values' à partir de la position 'id' pour une taille 'size'
+  int GetXValues(const int id, const int size, double* values)
+  {
+    GoToXPosition (id);(*this.*readFloatArray)(values, size);
+    return FileStream->tellg();
+  };
+
+  // Lit les valeurs d'ordonnée et les copie dans la table 'values' à partir de la position 'id' pour une taille 'size'
+  int GetYValues(const int id, const int size, double* values)
+  {
+    GoToYPosition (id);(*this.*readFloatArray)(values, size);
+    return FileStream->tellg();
+  };
+
+  // Lit les valeurs de côte et les copie dans la table 'values' à partir de la position 'id' pour une taille 'size' à un temps 'time'
+  // Retourne 0 et ne fait rien s'il s'agit d'un fichier 2D
+  int GetZValues(const int id, const int size, double* values, int time)
+  {
+    if(!Is3Dfile ()) return 0;
+    GoToData(time, 0, id);(*this.*readFloatArray)(values, size);
+    return FileStream->tellg();
+  }
+
+  // cache xy values - dont change with time
+  double* XValues = NULL;
+  double* YValues = NULL;
+
+  void WriteCoord(double *coords, const int time)
+  {
+    int i = 0;
+    const int size = this->GetNumberOfNodes();
+    double* arr = new double[size];
+
+    // Ecriture des valeurs X
+
+    if (XValues == NULL) {
+      XValues = new double[size];
+      this->GetXValues(0, size, XValues);
+      //vtkDebugMacro( << "Caching XValues\n");
+    }
+    for (i=0;i<size;i++){coords[3*i] = XValues[i];}
+
+    // Ecriture des valeurs Y
+    if (YValues == NULL) {
+      YValues = new double[size];
+      this->GetYValues(0, size, YValues);
+      //vtkDebugMacro( << "Caching YValues\n");
+    }
+    for (i=0;i<size;i++){coords[3*i+1] = YValues[i];}
+
+    // Ecriture des valeurs Z
+    this->GetZValues(0, size, arr, time);
+    if (this->Is3Dfile ()) {
+      for (i=0;i<size;i++) {
+        coords[3*i+2] = arr[i];
+      }
+    } else {
+      for (i=0;i<size;i++){coords[3*i+2] = 0;}
+    }
+    //vtkDebugMacro( << "Caching ZValues\n");
+  }
+
+  void GetVarRangeValues(const int size, const int range, const int varid, double *coords, const int time)
+  {
+    // retrieve vector components - assumes that components are output sequentially
+    int i = 0, j=0;
+    double* arr = new double[size];
+
+    //vtkDebugMacro( << "GetVarRangeValues: " << varid << "\n");
+    for (int i=0; i<range; i++)
+    {
+      this->GetVarValues(time, varid+i, 0, arr, size);
+      for (j=0;j<size;j++){coords[3*j+i] = arr[j];}
+    }
+
+    // if not 3 components fill rest with zeros
+    if(range<3)
+      for (j=0;j<size;j++){coords[3*j+2] = 0;}
+  }
+
+  void WriteConnectivity(int *values)
+  {
+    this->GoToConnectivityPosition (0);
+    (*this.*readIntArray)(values, this->GetNodeByElements()*this->GetNumberOfElement());
+  }
+
+  // Lit les valeurs de la variable de discrétisation identifiée par 'idvar' et les copie dans la table 'values' à partir de la position 'id'
+  // pour une taille 'size' à un temps 'time'
+  int GetVarValues(const int time, const int idvar, const int id, double* values, const int size)
+  {
+    GoToData(time, idvar, id);
+    (*this.*readFloatArray)(values, size);
+    return FileStream->tellg();
+  };
+
+
+  // TODO A terme, placer ces variables en protected
+  SerafinMetaData* metadata ;
+  SerafinIndexInfo* index ;
+
+protected:
+  stdSerafinReader(); // Non implementée ;
+
+  // Lit l'ensemble des metadonnées et  retourne la position actuelle
+  // Cette méthode est appelée dès l'instanciation pour gérer une bonne fois pour toutes les métadonnées
+  int readMetaData ();
+
+  // Créer l'index du fichier Serafin
+  void createIndex ();
+
+       // Identify vector info for each variable
+       void ComputeVarInfo ();
+  ////// Ensemble de fonction de lecture de la table d'index \\\\\\
+
+  // [fixés] Déplace la tête de lecture sur la positon id dans la table des valeurs de X ou Y
+  int64_t GoToXPosition (const int id) {
+    FileStream->seekg( this->index->XPosition +this->index->FloatSize*id+this->index->TagSize,  std::ios_base::beg ) ;
+    return FileStream->tellg();
+  }
+  int64_t GoToYPosition (const int id) {
+     FileStream->seekg( this->index->YPosition +this->index->FloatSize*id+this->index->TagSize,  std::ios_base::beg ) ;
+     return FileStream->tellg();
+  }
+
+  // [fixé] Déplace la tête de lecture sur l'élément N dans la table de connectivité
+  int64_t GoToConnectivityPosition (const int N)
+  {
+    FileStream->seekg( this->index->ConnectivityPosition +this->index->IntSize * (1+N*GetNodeByElements()),  std::ios_base::beg ) ;
+    return FileStream->tellg();
+  };
+
+  // TODO Améliorer les trois méthodes ci-dessous
+
+  // Déplace la tête de lecture sur un bloc de données en fonction du temps spécifié en argument
+  int64_t GoToData(const int time)
+  {
+    if (time >= GetTotalTime()) return 0 ;
+    FileStream->seekg( this->index->DataPosision + this->index->DataBlocSize * time + this->index->TimeSize,  std::ios_base::beg ) ;
+    return FileStream->tellg();
+  };
+
+  // Déplace la tête de lecture sur un bloc de données en fonction du temps et de l'identifiant de variable spécifiés en argument
+  int64_t GoToData(const int time, const int idvar)
+  {
+    int blocNode = this->index->FloatSize * GetNumberOfNodes() + 2*this->index->TagSize ;
+
+    GoToData(time);
+    if (idvar >= GetNumberOfVars()) return 0 ;
+
+    FileStream->seekg( blocNode * idvar,  std::ios_base::cur ) ;
+
+    return FileStream->tellg();
+  };
+
+  // Déplace la tête de lecture sur un bloc de données en fonction du temps, de l'identifiant de variable et du point spécifiés en argument
+  int64_t GoToData(const int time, const int idvar, const int id)
+  {
+    GoToData(time, idvar);
+    FileStream->seekg( this->index->FloatSize*id+this->index->TagSize,  std::ios_base::cur ) ;
+    return FileStream->tellg();
+  };
+
+
+
+private :
+
+  stdSerafinReader(const stdSerafinReader&);  // Pas implémentée
+  void operator=(const stdSerafinReader&);    // Pas implémentée
+
+}; /* class_stdSerafinReader */
+
+#endif
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/vtk.module b/src/SerafinReader/plugin/SerafinReaderModule/vtk.module
new file mode 100644 (file)
index 0000000..4cfe9b2
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SerafinReaderModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+  VTK::IOCore
+  VTK::IOGeometry
+  VTK::IOXML
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
+  VTK::RenderingCore
+  VTK::vtksys
+  VTK::zlib
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.cxx b/src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.cxx
new file mode 100644 (file)
index 0000000..8a086ac
--- /dev/null
@@ -0,0 +1,666 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    $RCSfile: vtkSerafinReader.cxx,v $
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+////// Reader for files 2D/3D generated by The  TELEMAC modelling system \\\\\
+// Module developped by herve ozdoba - Sept 2008 ( herve-externe.ozdoba at edf.fr / herve at ozdoba.fr )
+// Please address all comments to Regina Nebauer ( regina.nebauer at edf.fr )
+// >>> Test version
+
+#include "FFileReader.h"
+#include "stdSerafinReader.h"
+#include "vtkSerafinReader.h"
+
+#include "vtkErrorCode.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkUnstructuredGrid.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkPointData.h"
+#include "vtkCellData.h"
+#include "vtkDoubleArray.h"
+#include "vtkIntArray.h"
+#include "vtkCellArray.h"
+#include "vtkNew.h"
+
+#include <iostream>
+#include <list>
+#ifdef WIN32
+#define NOMINMAX
+#endif
+
+class vtkSerafinReader::vtkInternal
+{
+public:
+  vtkInternal() { }
+  vtkUnstructuredGrid *getPointer() const { return _usg.GetPointer(); }
+  void geometryHasBeenRead() { _geometry_read=true; }
+  bool hasGeometryAlreadyRead() const { return _geometry_read; }
+private:
+  bool _geometry_read = false;
+  vtkNew<vtkUnstructuredGrid> _usg;
+};
+
+/** +++++++++++++++++ Définition des méthodes de la classe FFileReader +++++++++++++++++ **/
+
+/* ******************* Constructeur *******************
+ * Ce constructeur reçoit un flux de lecture de fichier en argument .
+ * Gloabalement, les initialisations sont effectuée ici et le premier entier est lu pour
+ * déterminer dans quelle configuration d'écriture on se place en association avec le fichier .
+ * La différenciation petit/grand boutien est faite à la lecture du premier entier
+ * qui doit valoir la taille maximale du titre soit 80 caractères (à l'heure où j'écris ces lignes) .
+ */
+FFileReader :: FFileReader(ifstream* stream)
+{
+  // différentes initialisations
+  this->BigEndian  = false ;
+  this->BlocSize   = 0 ;
+  this->FileStream = stream;
+
+  // lecture de l'entête
+  readBlocSize ();
+  //vtkDebugMacro( << "BlocSize Little Endian " << BlocSize << "\n");
+  if (this->BlocSize != TITLE_MAX_SIZE) // pas d'échange d'octet à la lecture
+  {
+    this->BigEndian = true ;
+    // Relecture de l'entête
+    readBlocSize ();
+    //vtkDebugMacro( << "BlocSize Big Endian " << BlocSize << "\n");
+  }
+
+  // The float reader will be set later when we identify if single or double
+  FFileReader::readIntArray   = &FFileReader::g_readInt32Array   ;
+};
+
+/* Lecture d'un tableau d'entier arr de taille size avec inversion de octets */
+int64_t FFileReader :: s_readInt32Array(int* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(int)*size);
+  Swap32Array (size, (char*)(arr));
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau d'entier arr de taille size sans inversion de octets */
+int64_t FFileReader :: ns_readInt32Array(int* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(int)*size);
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau de flottants arr de taille size avec inversion de octets */
+int64_t FFileReader :: s_readFloat32Array(double* arr, const int size)
+{
+  float *tmp = new float[size];
+  FileStream->read ((char*)(tmp), sizeof(float)*size);
+  Swap32Array (size, (char*)(tmp));
+  for(int i; i<size; i++) arr[i] = (double) tmp[i];
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau de flottants arr de taille size sans inversion de octets */
+int64_t FFileReader :: ns_readFloat32Array(double* arr, const int size)
+{
+  float *tmp = new float[size];
+  FileStream->read ((char*)(tmp), sizeof(float)*size);
+  for(int i; i<size; i++) arr[i] = (double) tmp[i];
+  return FileStream->tellg();
+};
+// generic single entry read functions
+int64_t FFileReader :: g_readInt32Array(int* arr, const int size)
+{
+  if ( this->BigEndian ) {
+    return s_readInt32Array(arr, size);
+  }
+  return ns_readInt32Array(arr, size);
+};
+
+int64_t FFileReader :: g_readFloat32Array(double* arr, const int size)
+{
+  if ( this->BigEndian ) {
+    return s_readFloat32Array(arr, size);
+  }
+  return ns_readFloat32Array(arr, size);
+};
+
+/* Lecture d'un tableau d'entier arr de taille size avec inversion de octets */
+int64_t FFileReader :: s_readInt64Array(int64_t* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(int64_t)*size);
+  Swap64Array (size, (char*)(arr));
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau d'entier arr de taille size sans inversion de octets */
+int64_t FFileReader :: ns_readInt64Array(int64_t* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(int64_t)*size);
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau de flottants arr de taille size avec inversion de octets */
+int64_t FFileReader :: s_readFloat64Array(double* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(double)*size);
+  Swap64Array (size, (char*)(arr));
+  return FileStream->tellg();
+};
+
+/* Lecture d'un tableau de flottants arr de taille size sans inversion de octets */
+int64_t FFileReader :: ns_readFloat64Array(double* arr, const int size)
+{
+  FileStream->read ((char*)(arr), sizeof(double)*size);
+  return FileStream->tellg();
+};
+// generic single entry read functions
+int64_t FFileReader :: g_readInt64Array(int64_t* arr, const int size)
+{
+  if ( this->BigEndian ) {
+    return s_readInt64Array(arr, size);
+  }
+  return ns_readInt64Array(arr, size);
+};
+
+int64_t FFileReader :: g_readFloat64Array(double* arr, const int size)
+{
+  if ( this->BigEndian ) {
+    return s_readFloat64Array(arr, size);
+  }
+  return ns_readFloat64Array(arr, size);
+};
+
+/* ******************* Destructeur ***************** */
+// TODO compléter cette méthode !!!
+FFileReader :: ~FFileReader()
+{
+  // Ne rien faire pour le moment
+};
+
+/** +++++++++++++++++ Définition des méthodes de la classe stdSerafinReader +++++++++++++++++ **/
+
+/* ******************* Constructeur ***************** */
+stdSerafinReader :: stdSerafinReader(ifstream* stream) : FFileReader(stream)
+{
+  // TODO Initialisation des variables
+  this->metadata  = new SerafinMetaData();
+  this->index  = new SerafinIndexInfo();
+
+  // Lecture des metadonnée
+  //vtkDebugMacro( << "Reafin metadata" << endl);
+  this->readMetaData ();
+
+  //Création de l'index
+  //vtkDebugMacro( << "Creating Index" << endl);
+  this->createIndex ();
+
+  // Identify variable vector
+  //vtkDebugMacro( << "Computing Var Infor" << endl);
+  this->ComputeVarInfo();
+};
+
+/* ******************* Destructeur ***************** */
+// TODO compléter cette méthode !!!
+//stdSerafinReader :: ~stdSerafinReader()
+//{
+//  // Ne rien faire pour le moment, provoque une 'legere fuite memoire' maitrisee
+//};
+void stdSerafinReader::ComputeVarInfo()
+{
+  int pos, ncomp;
+  int found;
+
+  if (Is3Dfile())
+    ncomp = 3;
+  else
+    ncomp = 2;
+
+  for( int i; i < this->metadata->VarNumber ; i++) {
+      // must read full buffer as each varaible is a file record
+    string name(metadata->nVarList[i].name);
+    list<string> vec0 {" U ", " X ", "QX ", "U0 "};
+    list<string> vec1 {" V ", " Y ", "QY ", "V0 "};
+    list<string> vec2 {" W ", " Z ", "QZ ", "W0 "};
+    list<list<string>> vec {vec0, vec1, vec2};
+
+    pos = name.find("COTE Z");
+    if (pos != std::string::npos){
+      metadata->nVarList[i].ncomp = 0;
+      metadata->nVarList[i].icomp = 0;
+      continue;
+    }
+
+    found = 0;
+    int k = 0;
+    for(auto const &veci : vec){
+      for(auto const &str : veci){
+        pos = name.find(str);
+        if (pos != std::string::npos){
+          metadata->nVarList[i].ncomp = ncomp;
+          metadata->nVarList[i].icomp = k;
+          metadata->nVarList[i].name[pos+1] = '*';
+          if (str[0] != ' ') metadata->nVarList[i].name[pos] = '*';
+          found = 1;
+          break;
+        };
+      }
+      k++;
+      if (found != 0) break;
+    }
+    // Found a vector go to next variable
+    if (found != 0) continue;
+    // Default values
+    metadata->nVarList[i].ncomp = 0;
+    metadata->nVarList[i].icomp = 0;
+  }
+};
+
+/* ******************* createIndex ***************** */
+/* Cette méthode crée un index de taille et de position à partir des informations meta
+ * afin de faciliter la lecture du fichier serafin .
+ */
+void stdSerafinReader :: createIndex ()
+{
+  int tag = 0 ;
+  int nnodes = GetNumberOfNodes();
+  int ndp = GetNodeByElements();
+  int nelem = GetNumberOfElement();
+
+  // TODO: Identify FloatSize (read tag of coordinates)
+  this->index->IntSize = sizeof(int) ;
+  this->index->TagSize = sizeof(int) ;
+
+  this->index->FileSize = GetFileSize();
+  this->index->MetaSize = FileStream->tellg();
+
+  this->index->ConnectivityPosition  = this->index->MetaSize;
+
+  this->index->XPosition = (this->index->MetaSize) +
+                           (this->index->IntSize*nnodes+2*this->index->TagSize) +
+                           (this->index->IntSize*ndp*nelem+2*this->index->TagSize);
+
+  // Identifying float precision from tag of coordinates
+  FileStream->seekg( this->index->XPosition);
+  (*this.*readIntArray)(&tag, 1);
+  this->index->FloatSize = int(tag/nnodes) ;
+  //vtkDebugMacro( << "Float Size: " << this->index->FloatSize << endl);
+  if (this->index->FloatSize == 4){
+    FFileReader::readFloatArray = &FFileReader::g_readFloat32Array ;
+  }else{
+    FFileReader::readFloatArray = &FFileReader::g_readFloat64Array ;
+  }
+
+  // Size of a time info
+  this->index->TimeSize     = 2*this->index->TagSize + this->index->FloatSize;
+  // Size of a Field
+  this->index->FieldSize    = this->index->FloatSize*nnodes+2*this->index->TagSize;
+
+  // Size of the whole data
+  this->index->DataSize     = (this->index->FileSize)
+                              - (index->MetaSize)
+                              - (this->index->IntSize*nnodes+2*this->index->TagSize)
+                              - 2*index->FieldSize
+                              - (this->index->IntSize*ndp*nelem+2*this->index->TagSize);
+  // Index to data
+  this->index->DataPosision = (this->index->FileSize) - (this->index->DataSize);
+
+  // Index of Y coordinates
+  this->index->YPosition = this->index->XPosition + this->index->FieldSize;
+  // Size of data bloc for one time step
+  this->index->DataBlocSize = this->index->TimeSize + GetNumberOfVars()*this->index->FieldSize;
+
+  /*............................................................................................*/
+
+
+  this->index->NumberOfDate     = (this->index->DataSize)/(this->index->DataBlocSize);
+  //vtkDebugMacro(<< "Number of Date: " << this->index->NumberOfDate << endl);
+
+};
+
+/* ******************* readMetaData ***************** */
+/* Cette methode permet de de lire les métadata dans le but de recueillir les informations
+ * essentielles incluses dans le fichier . Globalement, la demarche sequentielle est la suivante :
+ *   -  lecture du titre et suppression des espaces en fin de chaine s'il y en a
+ *   -  lecture du nombre de variables
+ *   -  lecture du nom des variables et des leurs unités respectives
+ *   -  lecture des paramamètres
+ *  -  lecture des informations de discrétisation
+ */
+int stdSerafinReader :: readMetaData ()
+{
+
+  //Lecture du titre
+  if (ReadString(metadata->Title, TITLE_MAX_SIZE) != 88) return 0;// metadata->Title[TITLE_MAX_SIZE]='\0';
+  DeleteBlank(metadata->Title, TITLE_MAX_SIZE-8);
+
+  //lecture du nombre de variables (on passe les entete)
+  skipReadingHeader(FileStream);   //skip reclen
+  // read linear varsno
+  if ((*this.*readIntArray)(&(metadata->VarNumber), 1) != 96) return 0;
+  skipReadingHeader(FileStream);  // skip quad varno
+  skipReadingHeader(FileStream);  // skip reclen
+
+  //lecture des variables
+  metadata->VarList = (char *)new SerafinVar[metadata->VarNumber];
+  metadata->nVarList = new SerafinVar[metadata->VarNumber];
+
+  //vtkDebugMacro( << "nVarList Size " << sizeof(metadata->nVarList) << "\n");
+
+  {
+    int compteur = 0 ;
+    char buffer[VAR_DESC_SIZE*2];
+    for( compteur; compteur < metadata->VarNumber ; compteur++) {
+      // must read full buffer as each varaible is a file record
+      ReadString(&buffer[0], VAR_DESC_SIZE*2);
+      strncpy(metadata->nVarList[compteur].name, &buffer[0], VAR_DESC_SIZE);
+      strncpy(metadata->nVarList[compteur].unit, &buffer[VAR_DESC_SIZE], VAR_DESC_SIZE);
+      metadata->nVarList[compteur].name[VAR_DESC_SIZE]='\0';
+      metadata->nVarList[compteur].unit[VAR_DESC_SIZE]='\0';
+    }
+  };
+
+  // Lecture des parametres et, si necessaire, de la date de simu
+  skipReadingHeader(FileStream);
+  (*this.*readIntArray)(metadata->IParam, PARAM_NUMBER);
+  skipReadingHeader(FileStream);
+
+  if (metadata->IParam[9] == 1)// Si la date est indiquée
+  {
+    skipReadingHeader(FileStream);
+    (*this.*readIntArray)(metadata->Date, DATE_NUMBER);
+    skipReadingHeader(FileStream);
+  };
+
+  //lecture des information de discrietisation
+  skipReadingHeader(FileStream);
+  (*this.*readIntArray)(metadata->DiscretizationInfo, DISC_DESC_SIZE);
+  skipReadingHeader(FileStream);
+
+  // On lit l'entete du bloc de lecture pour connaitre la taille de la table de connectivite
+  if (IsBigEndian()) s_readBlocSize ();else  ns_readBlocSize ();
+
+
+  return FileStream->tellg();
+};
+
+/** +++++++++++++++++ Définition des méthodes de la classe vtkSerafinReader +++++++++++++++++ **/
+
+#include "vtkObjectFactory.h"
+
+//vtkCxxRevisionMacro(vtkSerafinReader, "$Revision: 0.2 $");
+vtkStandardNewMacro(vtkSerafinReader);
+
+vtkSerafinReader::vtkSerafinReader():Internal(nullptr)
+{
+
+  //vtkDebugMacro( << "Instanciation du lecteur Serafin");
+
+  this->FileName    = NULL;
+  this->FileStream  = NULL;
+  this->Reader      = NULL;
+  this->TimeStep    = 0;
+  this->Internal=new vtkInternal;
+
+  this->SetNumberOfInputPorts(0);
+};
+
+vtkSerafinReader::~vtkSerafinReader()
+{
+  if (this->FileName)
+  {
+    this->SetFileName(0);
+  }
+  delete this->Internal;
+
+}
+void vtkSerafinReader::SetTimeUnit(int value)
+{
+  cerr << "TimeUnit " << value << endl;
+}
+
+int vtkSerafinReader::RequestInformation(vtkInformation *vtkNotUsed(request),
+           vtkInformationVector **vtkNotUsed(inputVector),
+           vtkInformationVector *outputVector)
+{
+  vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  //outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),1);
+
+  if ( !this->FileName )
+  {
+    vtkErrorMacro("No filename specified");
+    return 0;
+  }
+
+  this->FileStream = new ifstream(this->FileName, ifstream::binary|ifstream::in);
+
+  if (this->FileStream->fail())
+  {
+    this->SetErrorCode(vtkErrorCode::FileNotFoundError);
+    delete this->FileStream;
+    this->FileStream = NULL;
+    vtkErrorMacro("Specified filename not found");
+    return 0;
+  }
+
+  this->Reader   = new stdSerafinReader( FileStream);
+
+  {//Gestion du temps
+    const int totime = this->Reader->GetTotalTime();
+    if (totime > 1)
+    {
+      int i=0;
+      double* TimeValues = new double[totime];
+
+      for (i=0; i<totime ;i++) {TimeValues[i] = this->Reader->GetTime(i) ;}
+
+      outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &TimeValues[0],  totime);
+
+      double timeRange[2];
+      timeRange[0] = TimeValues[0];
+      timeRange[1] = TimeValues[totime-1];
+      outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),  timeRange, 2);
+
+    };
+  }
+  return 1;
+}
+
+int vtkSerafinReader::RequestData(vtkInformation *vtkNotUsed(request),
+          vtkInformationVector **vtkNotUsed(inputVector),
+          vtkInformationVector *outputVector)
+{
+  int totime = this->Reader->GetTotalTime();
+  vtkInformation     *outInfo = outputVector->GetInformationObject(0);
+  vtkUnstructuredGrid   *output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+  int tsLength = outInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  double *steps =   outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  double requestedTimeSteps = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
+
+  if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()) && tsLength>0)
+  {
+    // Get the requested time step. We only support requests of a single time
+    // step in this reader right now
+    double requestedTimeSteps = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
+
+    // find the first time value larger than requested time value
+    // this logic could be improved
+    int cnt = 0;
+    while (cnt < tsLength-1 && steps[cnt] < requestedTimeSteps)
+    {
+      cnt++;
+    }
+
+    this->TimeStep = cnt;
+  }
+
+  //vtkDebugMacro( << "Serafin steps <" << steps << ">..." << requestedTimeSteps << this->TimeStep);
+
+  if ( outInfo->Has( vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP() ) )
+  {
+    double* steps = outInfo->Get( vtkStreamingDemandDrivenPipeline::TIME_STEPS() );
+  };
+
+
+  if ( this->FileStream == NULL )
+  {
+    return 0;
+  }
+
+  //vtkDebugMacro( << "Reading Time " << this->TimeStep << endl);
+
+  // Lecture de la geometrie
+  if(!this->Internal->hasGeometryAlreadyRead())
+    this->ReadGeometry(Internal->getPointer(), this->TimeStep);
+  Internal->geometryHasBeenRead();
+  output->ShallowCopy(Internal->getPointer());
+
+  // Lecture des donnees
+  //vtkDebugMacro( << "Reading Data " << this->TimeStep << endl);
+  this->ReadData(output,  this->TimeStep);
+  //vtkDebugMacro( << "Request done" << endl);
+
+  return 1;
+}
+
+void vtkSerafinReader::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "File Name: "           << (this->FileName ? this->FileName : "(none)") << endl;
+  os << indent << "Number Of Nodes: "     << this->Reader->GetNumberOfNodes()    << endl;
+  os << indent << "Number Of Node Fields: "     << this->Reader->GetNumberOfVars()     << endl;
+  os << indent << "Number Of Cells: "     << this->Reader->GetNumberOfElement()     << endl;
+}
+
+void vtkSerafinReader::ReadGeometry(vtkUnstructuredGrid *output, int time)
+{
+  vtkDoubleArray *coords = vtkDoubleArray::New();
+  coords->SetNumberOfComponents(3);
+  coords->SetNumberOfTuples(this->Reader->GetNumberOfNodes());
+
+  //vtkDebugMacro( << "Reading coordinates" << endl);
+  this->Reader->WriteCoord(coords->GetPointer (0), time);
+
+  //Lecture de la table de connectivite
+  //vtkDebugMacro( << "Reading connectivity" << endl);
+  {
+    int i = 0, k = 0, l = 0;
+    vtkIdType list[27];
+    const int size = this->Reader->GetNodeByElements()*this->Reader->GetNumberOfElement();
+    int* arr = new int[size];
+
+    switch(this->Reader->GetNodeByElements())
+    {
+      case 3 : l = VTK_TRIANGLE ; break;
+      case 4 : l = (this->Reader->Is3Dfile())? VTK_TETRA : VTK_QUAD ;  break;
+      case 5 : l = VTK_PYRAMID; break;
+      case 6 : l = VTK_WEDGE;  break;
+      case 8 : l = VTK_HEXAHEDRON ;break;
+      default:
+      {
+        vtkErrorMacro( << "cell type is not supported\n");return;
+      }
+    }
+
+    //vtkDebugMacro( << "Writting connectivity\n");
+    this->Reader->WriteConnectivity(arr);
+    output->Allocate(this->Reader->GetNumberOfNodes(), this->Reader->GetNumberOfNodes());
+
+    for(i = 0; i < this->Reader->GetNumberOfElement(); i++)
+    {
+      for(k = 0; k < this->Reader->GetNodeByElements(); k++)
+        list[k] = arr[this->Reader->GetNodeByElements()*i+k]-1;
+
+      output->InsertNextCell(l, this->Reader->GetNodeByElements(), list);
+    };
+
+    delete[] arr;
+  };
+
+  //vtkDebugMacro( << "Setting points\n");
+  vtkPoints *points = vtkPoints::New();
+  points->SetData(coords);
+  coords->Delete();
+
+  output->SetPoints(points);
+  points->Delete();
+  //vtkDebugMacro( << "Read Geometry done\n");
+
+}
+
+
+
+void vtkSerafinReader::ReadData(vtkUnstructuredGrid *output, int time)
+{
+  int i = 0, dim = 1;int vel =0 ;
+  char name[VAR_DESC_SIZE+1];
+
+  const int size = this->Reader->GetNumberOfNodes();
+
+  const int ideb = 0;
+  const int ifin = this->Reader->GetNumberOfVars();
+  SerafinVar * var ;
+
+  for (i = ideb ; i<ifin ; i++)
+  {
+    var = &(this->Reader->metadata->nVarList[i]);
+    //vtkDebugMacro( << "ReadData varname" << endl);
+    //vtkDebugMacro( << "  id: " << i << endl);
+    //vtkDebugMacro( << "  name: *" << var->name << "*\n");
+    //vtkDebugMacro( << "  icomp/ncomp: " << var->icomp << "/" << var->ncomp << endl);
+    vtkDoubleArray *data = vtkDoubleArray::New();
+    std::string name(var->name);
+    name = name.substr(0, name.find_last_not_of(" \n")+1);
+
+    // TODO: Creating vector for VELOCITY and stuff
+    if (var->ncomp != 0){
+      data->SetName(name.c_str());
+      data->SetNumberOfComponents(3);
+      data->SetNumberOfTuples(size);
+      this->Reader->GetVarRangeValues(size, var->ncomp, i, data->GetPointer(0), time);
+      i+= var->ncomp-1;
+
+    }else{
+      data->SetName(name.c_str());
+      data->SetNumberOfComponents(1);
+      data->SetNumberOfTuples(size);
+      this->Reader->GetVarValues(time, i, 0, data->GetPointer (0), size);
+    }
+
+    {//Stockage des donnees
+    };
+    output->GetPointData()->AddArray(data);
+
+    data->Delete();
+
+  }
+}
diff --git a/src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.h b/src/SerafinReader/plugin/SerafinReaderModule/vtkSerafinReader.h
new file mode 100644 (file)
index 0000000..d4f9616
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    $RCSfile: vtkSerafinReader.h,v $
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+////// Reader for files generated by The  TELEMAC modelling system \\\\\
+// Module developped by herve ozdoba - Sept 2008 ( herve-externe.ozdoba at edf.fr / herve at ozdoba.fr )
+// Please address all comments to Regina Nebauer ( regina.nebauer at edf.fr )
+// >>> Test version
+
+#ifndef __vtkSerafinReader_h__
+#define __vtkSerafinReader_h__
+
+/** -- Inclusions issues de la bibliotheque standard du C++ -- */
+
+#include <fstream>
+#include <string>
+#include <cstdio>
+#include <iostream>
+#include <cstring>
+
+using namespace std;
+
+/** -- Inclusion des entetes de la bibliotheque vtk -- **/
+
+#include "vtkUnstructuredGridAlgorithm.h"
+
+#include "vtkStringArray.h"
+
+
+#include "stdSerafinReader.h"
+
+#include "vtkIntArray.h"
+#include "vtkFloatArray.h"
+#include "vtkStdString.h"
+#include "vtkDoubleArray.h"
+#include "vtkIntArray.h"
+#include "vtkCellArray.h"
+
+
+/** ********************************************************************************************* **/
+/** -- Definition de la classe de lecture des fichiers externes au format Serafin pour Telemac -- **/
+/** ********************************************************************************************* **/
+
+class VTK_EXPORT vtkSerafinReader  : public vtkUnstructuredGridAlgorithm
+{
+public:
+
+  static vtkSerafinReader *New();
+
+  vtkTypeMacro(vtkSerafinReader,vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  void SetTimeUnit(int);
+
+  vtkSetStringMacro(FileName);
+  vtkGetStringMacro(FileName);
+
+  vtkSetMacro(TimeStep, int);
+  vtkGetMacro(TimeStep, int);
+
+protected:
+
+  // Implementation du constructeur associe a la classe
+  vtkSerafinReader();
+
+  // Implementation du descructeur
+  ~vtkSerafinReader();
+
+  int RequestInformation  (vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  int RequestData    (vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+
+  // Lecture de la geometrie du maillage
+  void ReadGeometry   (vtkUnstructuredGrid *output, int time);
+
+  // Lecture des donnees de la simulation au niveau des noeuds et des cellules.
+  void ReadData   (vtkUnstructuredGrid *output, int time);
+
+  char    *FileName;   // Nom du fichier ouvert par le logiciel Paraview
+  ifstream *FileStream;// Flux de lecture du fichier
+
+  int TimeStep;
+
+  stdSerafinReader* Reader; /** /!\ Instance de lecture du fichier Serafin **/
+
+  class vtkInternal;
+  vtkInternal *Internal;
+
+private:
+  vtkSerafinReader(const vtkSerafinReader&);  // Pas implemente
+  void operator=(const vtkSerafinReader&);    // Pas implemente
+
+}; /* class_vtkSerafinReader */
+
+#endif
diff --git a/src/SerafinReader/plugin/paraview.plugin b/src/SerafinReader/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..4b89fe1
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SerafinReader
+DESCRIPTION
+  This plugin provides ...
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/SerafinReader/plugin/sources.xml b/src/SerafinReader/plugin/sources.xml
new file mode 100644 (file)
index 0000000..32f6b49
--- /dev/null
@@ -0,0 +1,58 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="sources">
+
+    <SourceProxy class="vtkSerafinReader"
+                 name="SerafinReader">
+
+      <Documentation short_help= "Read a serafin/selafin file."
+                               long_help = "Read a serafin file into a vtkUnstructuredGrid.">
+                                       The SERAFIN reader reads a binary file creating a vtkUnstructuredGrid.
+                                       The default file extension is .srf for this software.
+      </Documentation>
+
+      <StringVectorProperty number_of_elements="1"
+                            animateable="0"
+                            name="FileName"
+                            command="SetFileName">
+        <FileListDomain name="files" />
+        <Documentation>
+                                               This property specifies the file name for the SERAFIN reader.
+        </Documentation>
+      </StringVectorProperty>
+
+      <DoubleVectorProperty name="TimestepValues"
+                            repeatable="1"
+                            information_only="1">
+        <TimeStepsInformationHelper/>
+      </DoubleVectorProperty>
+
+      <DoubleVectorProperty name="TimeRange"
+                            information_only="1">
+        <TimeRangeInformationHelper/>
+      </DoubleVectorProperty>
+
+      <IntVectorProperty name="Time Units"
+                         command="SetTimeUnit"
+                         number_of_elements="1"
+                         default_values="1">
+        <EnumerationDomain name="enum">
+          <Entry value="1" text="Seconds"/>
+          <Entry value="2" text="Hours"/>
+          <Entry value="3" text="Days"/>
+          <Entry value="4" text="Years"/>
+        </EnumerationDomain>
+        <Documentation>
+          This property indicates which transform mode will be used.
+        </Documentation>
+      </IntVectorProperty>
+
+      <Hints>
+        <ReaderFactory extensions="slf srf res res3d ser r2d spe"
+                       file_description="serafin files (Plugin)" />
+      </Hints>
+
+    </SourceProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
+
diff --git a/src/SinusXReader/CMakeLists.txt b/src/SinusXReader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c2567cf
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(SinusXReader)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/SinusXReader/LigneDEau.sx b/src/SinusXReader/LigneDEau.sx
new file mode 100644 (file)
index 0000000..ddbedd7
--- /dev/null
@@ -0,0 +1,32 @@
+C      Fichier g?n?r? par Fudaa
+C      Version 2.1 - Date 2017-7-13  15:48:39
+C
+C
+C
+B N +0.000000E+00 +0.000000E+00 +0.000000E+00 +1.000000E+00 +1.000000E+00 +1.000000E+00 1
+CN polyligne 1-1
+CP 0 1
+CP +0.000000E00
+CP 0
+ +3331.001943348042 2662.8766934197047 0.0 A
+ +3251.6311188826576 2628.5541747319708 0.0 A
+ +3137.9377757295388 2572.7800818644027 0.0 A
+ +2897.6801449154004 2469.8125258012005 0.0 A
+ +2805.4383759421153 2454.796423875317 0.0 A
+ +2687.454717953029 2409.748118097666 0.0 A
+ +2472.938976154691 2308.9257194524475 0.0 A
+ +2331.3585865677887 2214.5387930611787 0.0 A
+ +2241.2619750124863 2133.0228111778106 0.0 A
+ +2056.7784370659156 2055.797144130409 0.0 A
+ +1988.1333996904477 2040.7810422045256 0.0 A
+ +1887.3110010452287 2045.0713570404928 0.0 A
+ +1724.279037278492 1961.4102177391408 0.0 A
+ +1674.9404166648744 1879.8942358557724 0.0 A
+ +1366.037748475268 1746.894475940803 0.0 A
+ +1145.08653442298 1637.4914476236506 0.0 A
+ +1018.5222467619608 1633.201132787684 0.0 A
+ +949.8772093864927 1618.1850308617993 0.0 A
+ +891.9579591009415 1583.8625121740656 0.0 A
+ +840.4741810693404 1500.2013728727136 0.0 A
+ +643.1196986148697 1418.6853909893455 0.0 A
+ +657.4611628222997 1424.6090392489361 0.0 A
diff --git a/src/SinusXReader/plugin/CMakeLists.txt b/src/SinusXReader/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c018761
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(SinusXReader
+  VERSION "1.0"
+  MODULES SinusXReaderModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/SinusXReaderModule/vtk.module"
+  SERVER_MANAGER_XML sources.xml
+)
+
+install(TARGETS SinusXReader
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/SinusXReader/plugin/SinusXReaderModule/CMakeLists.txt b/src/SinusXReader/plugin/SinusXReaderModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..24a640a
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkSinusXReader
+)
+
+vtk_module_add_module(SinusXReaderModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/SinusXReader/plugin/SinusXReaderModule/vtk.module b/src/SinusXReader/plugin/SinusXReaderModule/vtk.module
new file mode 100644 (file)
index 0000000..34325d6
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SinusXReaderModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::IOCore
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.cxx b/src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.cxx
new file mode 100644 (file)
index 0000000..f103b6a
--- /dev/null
@@ -0,0 +1,276 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "vtkSinusXReader.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkDoubleArray.h>
+#include <vtkErrorCode.h>
+#include <vtkIdTypeArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+
+#include <exception>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+class MyException : public std::exception
+{
+public:
+  MyException(const char *what) : _what(what) {}
+  MyException(const std::string &what) : _what(what) {}
+  ~MyException() throw() {}
+  const char *what() const throw() { return _what.c_str(); }
+
+private:
+  std::string _what;
+};
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T *ptr = nullptr) : _ptr(ptr) {}
+  ~AutoPtr() { destroyPtr(); }
+  bool isNull() const { return _ptr == 0; }
+  bool isNotNull() const { return !isNull(); }
+  AutoPtr &operator=(T *ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T *operator->() { return _ptr; }
+  const T *operator->() const { return _ptr; }
+  T &operator*() { return *_ptr; }
+  const T &operator*() const { return *_ptr; }
+  operator T *() { return _ptr; }
+  operator const T *() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T *_ptr;
+};
+
+bool isFloat(const std::string &st, double &val)
+{
+  if (st == "NaN")
+  {
+    val = 0.;
+    return true;
+  }
+  std::istringstream iss(st);
+  iss >> val;
+  return iss.eof() && !iss.fail() && !iss.bad();
+}
+
+bool FindPart(const std::string &st, std::size_t &work, double &val)
+{
+  std::string part0;
+  std::size_t pos0(st.find_first_not_of(" \t", work));
+  if (pos0 == std::string::npos)
+    return false;
+  std::size_t pos1(st.find_first_of(" \t", pos0));
+  if (pos1 == std::string::npos)
+    return false;
+  part0 = st.substr(pos0, pos1 - pos0);
+  if (!isFloat(part0, val))
+    return false;
+  work = pos1;
+  return true;
+}
+
+bool isDataLine(const char *line, std::streamsize szOfLine, double &val0, double &val1, double &val2)
+{
+  if (szOfLine < 1)
+    return false;
+  std::string st(line, szOfLine - 1);
+  std::size_t work(0);
+  if (!FindPart(st, work, val0))
+    return false;
+  if (!FindPart(st, work, val1))
+    return false;
+  if (!FindPart(st, work, val2))
+    return false;
+  std::size_t pos0(st.find_first_not_of(" \t", work));
+  if (pos0 == std::string::npos)
+    return false;
+  std::size_t pos1(st.find_first_of(" \t", pos0));
+  if (pos1 != std::string::npos)
+    return false;
+  std::string endOfLine(st.substr(pos0));
+  if (endOfLine.length() != 1)
+    return false;
+  const char c(endOfLine[0]);
+  if (c < 'A' || c > 'Z')
+    return false;
+  return true;
+}
+
+std::vector<double> readSinusX(const char *fileName)
+{
+  std::ifstream ifs(fileName);
+  if (!ifs)
+  {
+    std::ostringstream oss;
+    oss << "readSinusX : Error while opening \"" << fileName << "\" file !";
+    throw MyException(oss.str());
+  }
+  ifs.seekg(0, ifs.end);
+  std::streampos length(ifs.tellg());
+  ifs.seekg(0, ifs.beg);
+  AutoPtr<char> data(new char[length]);
+  std::vector<double> ret;
+  while (!ifs.eof())
+  {
+    ifs.getline(data, length);
+    std::streamsize szOfLine(ifs.gcount());
+    double vals[3];
+    if (isDataLine(data, szOfLine, vals[0], vals[1], vals[2]))
+      ret.insert(ret.end(), vals, vals + 3);
+  }
+  return ret;
+}
+
+void performSubDiv(std::vector<double> &data, int nbOfSubDiv)
+{
+  constexpr int SPACEDIM = 3;
+  if (nbOfSubDiv <= 1)
+    return;
+  if (data.size() % SPACEDIM != 0)
+    throw MyException("Internal error : invalid size of data !");
+  std::size_t nbPts(data.size() / SPACEDIM);
+  if (nbPts <= 1)
+    return;
+  std::size_t newNbPts((nbOfSubDiv - 1) * (nbPts - 1) + nbPts);
+  std::vector<double> newData(newNbPts * SPACEDIM);
+  const double *inPt(data.data());
+  double *pt(newData.data());
+  for (auto i = 0; i < nbPts - 1; i++, inPt += SPACEDIM)
+  {
+    pt = std::copy(inPt, inPt + SPACEDIM, pt);
+    const double *inPtNext(inPt + SPACEDIM);
+    for (auto j = 1; j < nbOfSubDiv; j++)
+    {
+      double ratio((double)j / (double)nbOfSubDiv);
+      pt = std::transform(inPt, inPt + SPACEDIM, inPtNext, pt, [ratio](const double &a, const double &b) { return a + ratio * (b - a); });
+    }
+  }
+  pt = std::copy(inPt, inPt + SPACEDIM, pt);
+  data = std::move(newData);
+}
+
+vtkStandardNewMacro(vtkSinusXReader);
+
+vtkSinusXReader::vtkSinusXReader()
+{
+  this->SetNumberOfInputPorts(0);
+}
+
+int vtkSinusXReader::RequestInformation(vtkInformation *vtkNotUsed(request),
+                                        vtkInformationVector **vtkNotUsed(inputVector),
+                                        vtkInformationVector *outputVector)
+{
+  return 1;
+}
+
+int vtkSinusXReader::RequestData(vtkInformation *vtkNotUsed(request),
+                                 vtkInformationVector **vtkNotUsed(inputVector),
+                                 vtkInformationVector *outputVector)
+{
+  vtkInformation *outInfo(outputVector->GetInformationObject(0));
+  vtkPolyData *output(vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+  //
+  try
+  {
+    vtkNew<vtkPolyData> ret;
+    if (!this->FileName)
+      return 0;
+    std::vector<double> data(readSinusX(this->FileName));
+    performSubDiv(data, this->NumberOfSubdiv);
+    if (data.size() % 3 != 0)
+      throw MyException("Internal error : invalid size of data !");
+    std::size_t nbPts(data.size() / 3);
+    vtkNew<vtkDoubleArray> arr;
+    arr->SetNumberOfComponents(3);
+    arr->SetNumberOfTuples(nbPts);
+    std::copy(data.begin(), data.end(), arr->GetPointer(0));
+    vtkNew<vtkPoints> pts;
+    pts->SetData(arr);
+    ret->SetPoints(pts);
+    vtkNew<vtkCellArray> verts;
+    {
+      vtkNew<vtkIdTypeArray> conn;
+      conn->SetNumberOfComponents(1);
+      conn->SetNumberOfTuples(2 * nbPts);
+      vtkIdType *pt(conn->GetPointer(0));
+      for (vtkIdType i = 0; i < nbPts; i++)
+      {
+        pt[2 * i] = 1;
+        pt[2 * i + 1] = i;
+      }
+      verts->SetCells(nbPts, conn);
+    }
+    ret->SetVerts(verts);
+    if (nbPts >= 1)
+    {
+      vtkNew<vtkCellArray> lines;
+      {
+        vtkNew<vtkIdTypeArray> conn;
+        conn->SetNumberOfComponents(1);
+        conn->SetNumberOfTuples(3 * (nbPts - 1));
+        vtkIdType *pt(conn->GetPointer(0));
+        for (vtkIdType i = 0; i < nbPts - 1; i++)
+        {
+          pt[3 * i] = 2;
+          pt[3 * i + 1] = i;
+          pt[3 * i + 2] = i + 1;
+        }
+        lines->SetCells(nbPts - 1, conn);
+      }
+      ret->SetLines(lines);
+    }
+    output->ShallowCopy(ret);
+  }
+  catch (MyException &e)
+  {
+    vtkErrorMacro(<< "vtkSinusXReader::RequestData : during read of " << this->FileName << " : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkSinusXReader::PrintSelf(ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.h b/src/SinusXReader/plugin/SinusXReaderModule/vtkSinusXReader.h
new file mode 100644 (file)
index 0000000..0de1ebe
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __vtkSinusXReader_h__
+#define __vtkSinusXReader_h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+class VTK_EXPORT vtkSinusXReader : public vtkPolyDataAlgorithm
+{
+public:
+  static vtkSinusXReader *New();
+  vtkTypeMacro(vtkSinusXReader, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream &os, vtkIndent indent) override;
+
+  vtkSetStringMacro(FileName);
+  vtkGetStringMacro(FileName);
+
+  vtkSetMacro(NumberOfSubdiv, int);
+  vtkGetMacro(NumberOfSubdiv, int);
+
+protected:
+  vtkSinusXReader();
+  ~vtkSinusXReader() override = default;
+
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
+
+  char *FileName = nullptr;
+  int NumberOfSubdiv = 1;
+
+private:
+  vtkSinusXReader(const vtkSinusXReader &) = delete;
+  void operator=(const vtkSinusXReader &) = delete;
+};
+
+#endif
diff --git a/src/SinusXReader/plugin/paraview.plugin b/src/SinusXReader/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..58c1f0a
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SinusXReader
+DESCRIPTION
+  This plugin provides reader for SinusX file format.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/SinusXReader/plugin/sources.xml b/src/SinusXReader/plugin/sources.xml
new file mode 100644 (file)
index 0000000..bce8322
--- /dev/null
@@ -0,0 +1,24 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="sources">
+    <SourceProxy class="vtkSinusXReader"
+                 name="SinusXReader">
+      <Documentation short_help="Read a Sinus X file."
+                     long_help="Read a Sinus X file into as a vtkUnstructuredGrid.">
+      </Documentation>
+      <StringVectorProperty number_of_elements="1"
+                            animateable="0"
+                            name="FileName"
+                            command="SetFileName">
+        <FileListDomain name="files" />
+        <Documentation>
+          This property specifies the file name for the Sinus X reader.
+        </Documentation>
+      </StringVectorProperty>
+
+      <Hints>
+        <ReaderFactory extensions="sx" file_description="Sinus X files (Plugin)" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
+
diff --git a/src/SpatialPfl/CMakeLists.txt b/src/SpatialPfl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ae83916
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(SpatialPfl)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/SpatialPfl/TestCase.py b/src/SpatialPfl/TestCase.py
new file mode 100644 (file)
index 0000000..a51bada
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDLoader import *
+
+fname="hydrau_test1.med"
+meshName="mesh"
+arr=DataArrayDouble([0,1,2,3,4,5])
+m=MEDCouplingCMesh()
+m.setCoords(arr,arr)
+m=m.buildUnstructured()
+m.setName(meshName)
+m.simplexize(0)
+WriteMesh(fname,m,True)
+#
+f=MEDCouplingFieldDouble(ON_NODES)
+f.setMesh(m)
+f.setName("Field")
+arr=m.getCoords().magnitude()
+f.setArray(arr)
+for i in range(10):
+    arr+=0.1
+    f.setTime(float(i),i,0)
+    WriteFieldUsingAlreadyWrittenMesh(fname,f)
+    pass
+
diff --git a/src/SpatialPfl/plugin/CMakeLists.txt b/src/SpatialPfl/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6faaa60
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(BUILD_SHARED_LIBS TRUE)
+
+paraview_add_plugin(SpatialPfl
+  VERSION "1.0"
+  MODULES SpatialPflModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/SpatialPflModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS SpatialPfl
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/SpatialPfl/plugin/SpatialPflModule/CMakeLists.txt b/src/SpatialPfl/plugin/SpatialPflModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ada5525
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkSpatialPfl
+)
+
+vtk_module_add_module(SpatialPflModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/SpatialPfl/plugin/SpatialPflModule/vtk.module b/src/SpatialPfl/plugin/SpatialPflModule/vtk.module
new file mode 100644 (file)
index 0000000..b824326
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SpatialPflModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersSources
+ VTK::FiltersGeneral
diff --git a/src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.cxx b/src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.cxx
new file mode 100644 (file)
index 0000000..2c2233a
--- /dev/null
@@ -0,0 +1,576 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkSpatialPfl.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkLineSource.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkResampleWithDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkVariantArray.h>
+#include "vtkPolyData.h"
+
+#include <deque>
+#include <map>
+#include <sstream>
+
+vtkStandardNewMacro(vtkSpatialPfl);
+
+///////////////////
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T* ptr = nullptr)
+    : _ptr(ptr)
+  {
+  }
+  ~AutoPtr() { destroyPtr(); }
+  AutoPtr& operator=(T* ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T* operator->() { return _ptr; }
+  const T* operator->() const { return _ptr; }
+  T& operator*() { return *_ptr; }
+  const T& operator*() const { return *_ptr; }
+  operator T*() { return _ptr; }
+  operator const T*() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T* _ptr;
+};
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s)
+    : _reason(s)
+  {
+  }
+  virtual const char* what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+void ExtractInfo(vtkInformationVector* inputVector, vtkUnstructuredGrid*& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input = nullptr;
+  vtkDataSet* input0 = vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkMultiBlockDataSet* input1 = vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT()));
+  if (input0)
+  {
+    input = input0;
+  }
+  else
+  {
+    if (!input1)
+    {
+      throw MZCException(
+        "Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    }
+    if (input1->GetNumberOfBlocks() != 1)
+    {
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use "
+                         "MergeBlocks or ExtractBlocks filter before calling this filter !");
+    }
+    vtkDataObject* input2 = input1->GetBlock(0);
+    if (!input2)
+    {
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this "
+                         "single element is NULL !");
+    }
+    vtkDataSet* input2c = vtkDataSet::SafeDownCast(input2);
+    if (!input2c)
+    {
+      throw MZCException(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    }
+    input = input2c;
+  }
+  if (!input)
+  {
+    throw MZCException("Input data set is NULL !");
+  }
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+  {
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on "
+                       "unstructured meshes !");
+  }
+}
+
+////////////////////
+
+vtkSpatialPfl::vtkSpatialPfl()
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfOutputPorts(1);
+}
+
+int vtkSpatialPfl::RequestInformation(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkSpatialPfl::RequestInformation
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid* usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation* info(outputVector->GetInformationObject(0));
+  }
+  catch (MZCException& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkSpatialPfl::RequestInformation : " << e.what()
+        << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+    {
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    }
+    else
+    {
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    }
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void buildTableFrom(vtkPolyData* table, const std::vector<std::vector<double> >& valuesByColumn, const std::vector<std::string>& columnNames)
+{
+  vtkPointData *pd(table->GetPointData());
+  std::size_t sz(valuesByColumn.size());
+  if (sz != columnNames.size())
+  {
+    throw MZCException("Sizes of vectors mismatches !");
+  }
+  if (sz == 0)
+  {
+    return;
+  }
+  std::size_t nbSamples(valuesByColumn[0].size());
+  for (int i = 0; i < sz; i++)
+  {
+    vtkSmartPointer<vtkDoubleArray> arr(vtkSmartPointer<vtkDoubleArray>::New());
+    arr->SetName(columnNames[i].c_str());
+    if (nbSamples != valuesByColumn[i].size())
+    {
+      std::ostringstream oss;
+      oss << "Sizes of vectors " << i << " mismatches with size of others " << nbSamples << " !";
+      throw MZCException(oss.str());
+    }
+    arr->SetNumberOfTuples(nbSamples);
+    arr->SetNumberOfComponents(1);
+    double* pt(arr->GetPointer(0));
+    std::copy(valuesByColumn[i].begin(), valuesByColumn[i].end(), pt);
+    pd->AddArray(arr);
+  }
+}
+template<class T>
+struct VTKArrayTraits
+{
+};
+
+template<>
+struct VTKArrayTraits<double>
+{
+  using Type = vtkDoubleArray;
+};
+
+template<>
+struct VTKArrayTraits<float>
+{
+  using Type = vtkFloatArray;
+};
+
+template<class T>
+void FromVTKArrayComputeCurvAbsInternal(typename VTKArrayTraits<T>::Type *data, std::vector<double>& ret, std::vector<double>& Xcoords, std::vector<double>& Ycoords)
+{
+  vtkIdType nbTuples(data->GetNumberOfTuples()), nbComp(data->GetNumberOfComponents());
+  ret.resize(nbTuples); Xcoords.resize(nbTuples); Ycoords.resize(nbTuples);
+  const T* pt(data->GetPointer(0));
+  ret[0] = 0.; Xcoords[0] = pt[0]; Ycoords[0] = pt[1];
+  for (vtkIdType i = 1; i < nbTuples; i++)
+  {
+    double val(0.);
+    for (vtkIdType j = 0; j < nbComp; j++)
+    {
+      double delta(pt[nbComp * (i - 1) + j] - pt[nbComp * i + j]);
+      val += delta * delta;
+    }
+    Xcoords[i] = pt[nbComp * i + 0]; Ycoords[i] = pt[nbComp * i + 1];
+    ret[i] = ret[i - 1] + sqrt(val);
+  }
+}
+
+std::vector<double> FromVTKArrayComputeCurvAbs(vtkDataArray* data, std::vector<double>& Xcoords, std::vector<double>& Ycoords)
+{
+  vtkIdType nbTuples(data->GetNumberOfTuples()), nbComp(data->GetNumberOfComponents());
+  if (nbTuples < 1)
+  {
+    throw MZCException("FromVTKArrayComputeCurvAbs : internal error 1 !");
+  }
+  std::vector<double> ret;
+  vtkDoubleArray* d1(vtkDoubleArray::SafeDownCast(data));
+  if (d1)
+  {
+    FromVTKArrayComputeCurvAbsInternal<double>(d1,ret,Xcoords,Ycoords);
+    return ret;
+  }
+  vtkFloatArray* d2(vtkFloatArray::SafeDownCast(data));
+  if (d2)
+  {
+    FromVTKArrayComputeCurvAbsInternal<float>(d2,ret,Xcoords,Ycoords);
+    return ret;
+  }
+  throw MZCException("FromVTKArrayComputeCurvAbs : internal error 2 !");
+}
+
+static std::string GetReprDependingPos(const std::string& origName, int blockId, int nbBlocks)
+{
+  if( nbBlocks == 1 )
+    return origName;
+  std::ostringstream oss;
+  oss << origName << "_" << blockId;
+  return oss.str();
+}
+
+void FillPolyDataInstance(vtkPolyData *ds, const std::vector<double>& xs, const std::vector<double>& ys)
+{
+  vtkNew<vtkDoubleArray> coords;
+  std::size_t nbPts(xs.size());
+  coords->SetNumberOfComponents(3);
+  coords->SetNumberOfTuples(nbPts);
+  double *coordsPt(coords->GetPointer(0));
+  vtkNew<vtkPoints> pts;
+  pts->SetData(coords);
+  ds->SetPoints(pts);
+  //
+  vtkNew<vtkCellArray> cc;
+  cc->AllocateExact(1,nbPts);
+  std::unique_ptr<vtkIdType[]> conn(new vtkIdType[nbPts]);
+  //
+  for(std::size_t iPt = 0 ; iPt < nbPts ; ++iPt)
+    {
+      coordsPt[3*iPt] = xs[iPt] ; coordsPt[3*iPt+1] = ys[iPt] ; coordsPt[3*iPt+2] = 0.;
+      conn[iPt] = iPt;
+    }
+  //
+  cc->InsertNextCell(nbPts,conn.get());
+  ds->SetLines(cc);
+}
+
+void buildTableFromPolyData(vtkMultiBlockDataSet* table, vtkPolyData* ds, int blockId, int nbBlocks)
+{
+  vtkNew<vtkPolyData> eltInTable;
+  vtkPoints* pts(ds->GetPoints());
+  if (!pts)
+  {
+    throw MZCException("buildTableFromPolyData : internal error 2 !");
+  }
+  vtkDataArray* data(pts->GetData());
+  if (!data)
+  {
+    throw MZCException("buildTableFromPolyData : internal error 3 !");
+  }
+  //
+  std::vector<double> Xcoords, Ycoords;
+  std::vector<double> xs(FromVTKArrayComputeCurvAbs(data, Xcoords, Ycoords));
+  //
+  FillPolyDataInstance(eltInTable,Xcoords,Ycoords);
+  //
+  vtkCellArray *cd(ds->GetVerts()), *cc(ds->GetLines());
+  //
+  vtkDataSetAttributes* dsa(ds->GetPointData());
+  if (!dsa)
+  {
+    throw MZCException("buildTableFromPolyData : no point data !");
+  }
+  int nba = dsa->GetNumberOfArrays();
+  //
+  std::vector<std::vector<double> > valuesByColumn(1);
+  std::vector<std::string> columnNames(1);
+  valuesByColumn[0] = xs;
+  columnNames[0] = "Curv Abscissa";
+  //
+  for (int i = 0; i < nba; i++)
+  {
+    vtkDataArray* arr(dsa->GetArray(i));
+    std::vector<double> tmp(arr->GetNumberOfTuples());
+    if (arr->GetNumberOfComponents() != 1)
+    {
+      continue;
+    }
+    std::string name(GetReprDependingPos(arr->GetName(),blockId,nbBlocks));
+    vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+    if (!arr1)
+    {
+      vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+      if (!arr2)
+      {
+        continue;
+      }
+      const float* pt(arr2->GetPointer(0));
+      std::copy(pt, pt + arr->GetNumberOfTuples(), tmp.begin());
+    }
+    else
+    {
+      const double* pt(arr1->GetPointer(0));
+      std::copy(pt, pt + arr1->GetNumberOfTuples(), tmp.begin());
+    }
+    valuesByColumn.push_back(tmp);
+    columnNames.push_back(name);
+  }
+  // EDF21757 - Ajout de X et Y
+  valuesByColumn.push_back(Xcoords); columnNames.push_back("X");
+  valuesByColumn.push_back(Ycoords); columnNames.push_back("Y");
+  //
+  buildTableFrom(eltInTable, valuesByColumn, columnNames);
+  table->SetBlock(blockId,eltInTable);
+}
+
+vtkPolyData *ExtractTo(vtkDataObject *source)
+{
+  vtkMultiBlockDataSet *sourceMB(vtkMultiBlockDataSet::SafeDownCast(source));
+  if(sourceMB)
+  {
+    if(sourceMB->GetNumberOfBlocks() != 1)
+    {
+      std::ostringstream oss; oss << "Internal error ! Number of blocks of MultiBlockDataSet source must be equal to 1 ! Here : " << sourceMB->GetNumberOfBlocks();
+      throw MZCException(oss.str());
+    }
+    vtkDataObject *source20(sourceMB->GetBlock(0));
+    vtkPolyData *source20c(vtkPolyData::SafeDownCast(source20));
+    if(!source20c)
+    {
+      throw MZCException("Internal error ! source is a mono block MultiBlockDataSet but this block is not a vtkDataSet !");
+    }
+    return source20c;
+  }
+  vtkPolyData* source2(vtkPolyData::SafeDownCast(source));
+  return source2;
+}
+
+static int GetNumberOfBlocs(vtkDataObject *ds)
+{
+  if(!ds)
+    throw MZCException("vtkSedimentDeposit  SplitSingleMultiBloc : nullptr !");
+  vtkMultiBlockDataSet *ds0(vtkMultiBlockDataSet::SafeDownCast(ds));
+  if(!ds0)
+  {
+    vtkPolyData *ds00(vtkPolyData::SafeDownCast(ds));
+    if(!ds00)
+      throw MZCException("vtkSedimentDeposit  SplitSingleMultiBloc : neither a vtkMultiBlockDataSet nor a vtkPolyData !");
+    return 1;
+  }
+  return ds0->GetNumberOfBlocks();
+}
+
+static vtkPolyData *SplitSingleMultiBloc(vtkDataObject *res, int blockId)
+{
+  vtkPolyData* res2(vtkPolyData::SafeDownCast(res));
+  if (!res2)
+  {
+    vtkMultiBlockDataSet *res2c(vtkMultiBlockDataSet::SafeDownCast(res));
+    if(!res2c)
+    {
+      throw MZCException("Internal error ! unexpected returned of resample filter !");
+    }
+    if(blockId >= res2c->GetNumberOfBlocks())
+    {
+      std::ostringstream oss; oss << "Internal error ! Number of blocks of MultiBlockDataSet must be equal < " << blockId << " ! Here : " << res2c->GetNumberOfBlocks();
+      throw MZCException(oss.str());
+    }
+    vtkDataObject *res20(res2c->GetBlock(blockId));
+    vtkPolyData *res20c(vtkPolyData::SafeDownCast(res20));
+    if(!res20c)
+    {
+      throw MZCException("Internal error ! resample filter returned a mono block MultiBlockDataSet but this block is not a vtkPolyData !");
+    }
+    return res20c;
+  }
+  if(blockId!=0)
+    throw MZCException("Internal error ! 0 expected !");
+  return res2;
+}
+
+int vtkSpatialPfl::RequestData(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkSpatialPfl::RequestData
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid* usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    //
+    vtkInformation* sourceInfo(inputVector[1]->GetInformationObject(0));
+    vtkDataObject* source(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+    vtkDataSet* source2(vtkDataSet::SafeDownCast(source));
+
+    int nbBlocks2(GetNumberOfBlocs(source));
+    vtkNew<vtkMultiBlockDataSet> sampleLineMB;
+    sampleLineMB->SetNumberOfBlocks(nbBlocks2);
+
+    //vtkSmartPointer<vtkDataSet> sampleLine;
+    if (this->ResampleInput)
+    {
+      for(int iBlock = 0 ; iBlock < nbBlocks2 ; ++iBlock)
+      {
+        vtkPolyData* pl = SplitSingleMultiBloc(source,iBlock);
+        if (!pl)
+        {
+          vtkErrorMacro("The second input of this filter must be of type vtkPolyData.");
+          return 1;
+        }
+        vtkSmartPointer<vtkDataSet> sampleLine;
+        sampleLine.TakeReference(this->ResamplePolyLine(pl));
+        sampleLineMB->SetBlock(iBlock,sampleLine);
+      }
+    }
+    else
+    {
+      for(int iBlock = 0 ; iBlock < nbBlocks2 ; ++iBlock)
+      {
+        //sampleLine = ExtractTo(source);
+        sampleLineMB->SetBlock(iBlock,SplitSingleMultiBloc(source,iBlock));
+      }
+    }
+    //
+    vtkNew<vtkResampleWithDataSet> probeFilter;
+    probeFilter->SetInputData(sampleLineMB);
+    probeFilter->SetSourceData(usgIn);
+    probeFilter->Update();
+    vtkDataObject* res(probeFilter->GetOutput());
+    //
+    int nbBlocks(GetNumberOfBlocs(res));
+    vtkNew<vtkTable> table;
+    vtkInformation* outInfo = outputVector->GetInformationObject(0);
+    vtkMultiBlockDataSet *output ( vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())) );
+    output->SetNumberOfBlocks(nbBlocks);
+    for(int blockId = 0 ; blockId < nbBlocks ; ++blockId)
+    {
+      vtkPolyData *res2(SplitSingleMultiBloc(res,blockId));
+      buildTableFromPolyData(output, res2, blockId, nbBlocks);
+    }
+  }
+  catch (MZCException& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkSpatialPfl::RequestData : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+    {
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    }
+    else
+    {
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    }
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void vtkSpatialPfl::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkSpatialPfl::SetSourceData(vtkDataObject* input)
+{
+  this->SetInputData(1, input);
+}
+
+void vtkSpatialPfl::SetSourceConnection(vtkAlgorithmOutput* algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+int vtkSpatialPfl::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
+  return 1;
+}
+
+vtkPolyData* vtkSpatialPfl::ResamplePolyLine(vtkPolyData* pl)
+{
+  vtkPolyData* res = vtkPolyData::New();
+
+  vtkNew<vtkLineSource> subdivision;
+  subdivision->SetPoints(pl->GetPoints());
+  subdivision->SetResolution(this->NumberOfSamples);
+  subdivision->Update();
+  res->ShallowCopy(subdivision->GetOutputDataObject(0));
+
+  return res;
+}
+
+/*<Hints>
+        <!-- View can be used to specify the preferred view for the proxy -->
+        <View type="QuartileChartView" />
+        </Hints>*/
+
+//   /opt/cmake/3.6.2/bin/cmake -DCMAKE_INSTALL_PREFIX=/home/H87074/TMP117_HYDRAU/SpatialPfl_install
+//   -DCONFIGURATION_ROOT_DIR=/opt/salome-conf/8.3.0 -DCMAKE_BUILD_TYPE=Debug
+//   -DPYTHON_INCLUDE_DIR=/usr/include/python2.7
+//   -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so ../SpatialPfl
+/*
+export LD_LIBRARY_PATH=/home/H87074/TMP117_HYDRAU/SpatialPfl_install/lib:${LD_LIBRARY_PATH}
+export PV_PLUGIN_PATH=/home/H87074/TMP117_HYDRAU/SpatialPfl_install/lib:${PV_PLUGIN_PATH}
+*/
diff --git a/src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.h b/src/SpatialPfl/plugin/SpatialPflModule/vtkSpatialPfl.h
new file mode 100644 (file)
index 0000000..d84a01f
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#pragma once
+
+#include "vtkDataObjectAlgorithm.h"
+
+class vtkPolyData;
+
+class VTK_EXPORT vtkSpatialPfl : public vtkDataObjectAlgorithm
+{
+public:
+  static vtkSpatialPfl* New();
+  vtkTypeMacro(vtkSpatialPfl, vtkDataObjectAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  void SetSourceData(vtkDataObject* input);
+
+  void SetSourceConnection(vtkAlgorithmOutput* algOutput);
+
+  //@{
+  /**
+   * Set/Get the number of points that will be considered along the polyline source
+   * before the probing.
+   */
+  vtkGetMacro(ResampleInput, bool);
+  vtkSetMacro(ResampleInput, bool);
+  vtkBooleanMacro(ResampleInput, bool);
+  //@}
+
+  //@{
+  /**
+   * Set/Get the number of points that will be considered along the polyline source
+   * before the probing.
+   */
+  vtkGetMacro(NumberOfSamples, int);
+  vtkSetMacro(NumberOfSamples, int);
+  //@}
+
+  int FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info) override;
+
+protected:
+  vtkSpatialPfl();
+  ~vtkSpatialPfl() override = default;
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  vtkPolyData* ResamplePolyLine(vtkPolyData* pl);
+
+  bool ResampleInput = false;
+  int NumberOfSamples = 0;
+
+private:
+  vtkSpatialPfl(const vtkSpatialPfl&) = delete;
+  void operator=(const vtkSpatialPfl&) = delete;
+};
diff --git a/src/SpatialPfl/plugin/filters.xml b/src/SpatialPfl/plugin/filters.xml
new file mode 100644 (file)
index 0000000..4d87321
--- /dev/null
@@ -0,0 +1,143 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="SpatialPfl"
+                 class="vtkSpatialPfl"
+                 label="Spatial Profile">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+
+      <InputProperty command="SetSourceConnection"
+                     label="Source"
+                     name="Source"
+                     panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+        <ProxyListDomain name="proxy_list">
+          <Proxy group="extended_sources"
+                 name="PolyLineSource" />
+        </ProxyListDomain>
+        <Documentation>The value of this property determines the points where probe will be done.</Documentation>
+      </InputProperty>
+
+      <IntVectorProperty name="ResampleInput"
+                         command="SetResampleInput"
+                         label="Subdivide Input Polyline"
+                         number_of_elements="1"
+                         default_values="0"
+                         panel_visibility="default">
+        <BooleanDomain name="bool" />
+          <Documentation>
+            If this entry is checked, the user can specify the level of
+            subdivision applied to each segment of the input polyline.
+          </Documentation>
+      </IntVectorProperty>
+
+      <IntVectorProperty name="NumberOfSamples"
+                         command="SetNumberOfSamples"
+                         label="Level of subdivision"
+                         number_of_elements="1"
+                         default_values="50"
+                         panel_visibility="default">
+          <IntRangeDomain name="range" min="1" max="100" />
+          <Hints>
+            <PropertyWidgetDecorator type="ShowWidgetDecorator">
+              <Property name="ResampleInput" function="boolean" />
+            </PropertyWidgetDecorator>
+          </Hints>
+          <Documentation>
+            The value of this property determines the level of subdivision
+            applied to each segment of the input polyline.
+          </Documentation>
+      </IntVectorProperty>
+
+      <Hints>
+        <ShowInMenu category="Hydraulics" />
+      </Hints>
+
+      <Hints>
+        <View type="XYChartView" />
+      </Hints>
+
+    </SourceProxy>
+
+    <SourceProxy name="SpatialPflWithSource"
+                  class="vtkSpatialPfl"
+                  label="Spatial Profile With Source">
+    <InputProperty name="Input" command="SetInputConnection">
+      <ProxyGroupDomain name="groups">
+        <Group name="sources"/>
+        <Group name="filters"/>
+      </ProxyGroupDomain>
+      <DataTypeDomain name="input_type">
+        <DataType value="vtkDataSet"/>
+      </DataTypeDomain>
+      <Documentation>
+        This property specifies the input to the Level Scalars filter.
+      </Documentation>
+    </InputProperty>
+
+    <InputProperty command="SetSourceConnection"
+                    label="Source"
+                    name="Source"
+                    panel_visibility="default">
+      <ProxyGroupDomain name="groups">
+        <Group name="sources" />
+      </ProxyGroupDomain>
+      <Documentation>The value of this property determines the points where probe will be done.</Documentation>
+    </InputProperty>
+
+    <IntVectorProperty name="ResampleInput"
+                        command="SetResampleInput"
+                        label="Subdivide Input Polyline"
+                        number_of_elements="1"
+                        default_values="0"
+                        panel_visibility="default">
+      <BooleanDomain name="bool" />
+        <Documentation>
+          If this entry is checked, the user can specify the level of
+          subdivision applied to each segment of the input polyline.
+        </Documentation>
+    </IntVectorProperty>
+
+    <IntVectorProperty name="NumberOfSamples"
+                        command="SetNumberOfSamples"
+                        label="Level of subdivision"
+                        number_of_elements="1"
+                        default_values="50"
+                        panel_visibility="default">
+        <IntRangeDomain name="range" min="1" max="100" />
+        <Hints>
+          <PropertyWidgetDecorator type="ShowWidgetDecorator">
+            <Property name="ResampleInput" function="boolean" />
+          </PropertyWidgetDecorator>
+        </Hints>
+        <Documentation>
+          The value of this property determines the level of subdivision
+          applied to each segment of the input polyline.
+        </Documentation>
+    </IntVectorProperty>
+
+    <Hints>
+      <ShowInMenu category="Hydraulics" />
+    </Hints>
+
+    <Hints>
+      <View type="XYChartView" />
+    </Hints>
+
+  </SourceProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/SpatialPfl/plugin/paraview.plugin b/src/SpatialPfl/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..73cd445
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SpatialPfl
+DESCRIPTION
+  This plugin provides the SpatialPfl filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::IOCore
+  VTK::FiltersCore
+  VTK::FiltersSources
+  VTK::FiltersGeneral
diff --git a/src/SphereAlongLines/CMakeLists.txt b/src/SphereAlongLines/CMakeLists.txt
new file mode 100644 (file)
index 0000000..01b2213
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(SphereAlongLinesPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/SphereAlongLines/Test/test_dev_surface.py b/src/SphereAlongLines/Test/test_dev_surface.py
new file mode 100644 (file)
index 0000000..1675518
--- /dev/null
@@ -0,0 +1,161 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#### import the simple module from the paraview
+from paraview.simple import *
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'MED Reader'
+multiTSmed = MEDReader(FileName='multiTS.med')
+multiTSmed.AllArrays = ['TS0/Mesh/ComSup0/Pressure@@][@@P0']
+multiTSmed.AllTimeSteps = ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009']
+
+# get animation scene
+animationScene1 = GetAnimationScene()
+
+# update animation scene based on data timesteps
+animationScene1.UpdateAnimationUsingDataTimeSteps()
+
+# get active view
+renderView1 = GetActiveViewOrCreate('RenderView')
+# uncomment following to set a specific view size
+# renderView1.ViewSize = [1499, 582]
+
+# show data in view
+multiTSmedDisplay = Show(multiTSmed, renderView1)
+
+# trace defaults for the display properties.
+multiTSmedDisplay.Representation = 'Surface'
+multiTSmedDisplay.ColorArrayName = [None, '']
+multiTSmedDisplay.OSPRayScaleArray = 'FamilyIdNode'
+multiTSmedDisplay.OSPRayScaleFunction = 'PiecewiseFunction'
+multiTSmedDisplay.SelectOrientationVectors = 'FamilyIdNode'
+multiTSmedDisplay.ScaleFactor = 0.07399989366531372
+multiTSmedDisplay.SelectScaleArray = 'FamilyIdNode'
+multiTSmedDisplay.GlyphType = 'Arrow'
+multiTSmedDisplay.GlyphTableIndexArray = 'FamilyIdNode'
+multiTSmedDisplay.DataAxesGrid = 'GridAxesRepresentation'
+multiTSmedDisplay.PolarAxes = 'PolarAxesRepresentation'
+multiTSmedDisplay.ScalarOpacityUnitDistance = 0.017316274962626298
+multiTSmedDisplay.GaussianRadius = 0.03699994683265686
+multiTSmedDisplay.SetScaleArray = ['POINTS', 'FamilyIdNode']
+multiTSmedDisplay.ScaleTransferFunction = 'PiecewiseFunction'
+multiTSmedDisplay.OpacityArray = ['POINTS', 'FamilyIdNode']
+multiTSmedDisplay.OpacityTransferFunction = 'PiecewiseFunction'
+multiTSmedDisplay.InputVectors = [None, '']
+multiTSmedDisplay.SelectInputVectors = [None, '']
+multiTSmedDisplay.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+multiTSmedDisplay.ScaleTransferFunction.Points = [0.0, 0.0, 0.5, 0.0, 1.1757813367477812e-38, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+multiTSmedDisplay.OpacityTransferFunction.Points = [0.0, 0.0, 0.5, 0.0, 1.1757813367477812e-38, 1.0, 0.5, 0.0]
+
+# reset view to fit data
+renderView1.ResetCamera()
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# create a new 'Developed Surface'
+developedSurface1 = DevelopedSurface(Input=multiTSmed)
+developedSurface1.SliceType = 'Cylinder'
+
+# init the 'Cylinder' selected for 'SliceType'
+developedSurface1.SliceType.Center = [0.0, 0.0, 0.05000000074505806]
+developedSurface1.SliceType.Radius = 0.3699994683265686
+
+# Properties modified on developedSurface1.SliceType
+developedSurface1.SliceType.Center = [0.0, 0.0, 0.05]
+developedSurface1.SliceType.Axis = [0.0, 0.0, 1.0]
+developedSurface1.SliceType.Radius = 0.07
+
+# Properties modified on developedSurface1.SliceType
+developedSurface1.SliceType.Center = [0.0, 0.0, 0.05]
+developedSurface1.SliceType.Axis = [0.0, 0.0, 1.0]
+developedSurface1.SliceType.Radius = 0.07
+
+# show data in view
+developedSurface1Display = Show(developedSurface1, renderView1)
+
+# trace defaults for the display properties.
+developedSurface1Display.Representation = 'Surface'
+developedSurface1Display.ColorArrayName = [None, '']
+developedSurface1Display.OSPRayScaleArray = 'FamilyIdNode'
+developedSurface1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+developedSurface1Display.SelectOrientationVectors = 'FamilyIdNode'
+developedSurface1Display.ScaleFactor = 0.043982297150257116
+developedSurface1Display.SelectScaleArray = 'FamilyIdNode'
+developedSurface1Display.GlyphType = 'Arrow'
+developedSurface1Display.GlyphTableIndexArray = 'FamilyIdNode'
+developedSurface1Display.DataAxesGrid = 'GridAxesRepresentation'
+developedSurface1Display.PolarAxes = 'PolarAxesRepresentation'
+developedSurface1Display.GaussianRadius = 0.021991148575128558
+developedSurface1Display.SetScaleArray = ['POINTS', 'FamilyIdNode']
+developedSurface1Display.ScaleTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.OpacityArray = ['POINTS', 'FamilyIdNode']
+developedSurface1Display.OpacityTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.InputVectors = [None, '']
+developedSurface1Display.SelectInputVectors = [None, '']
+developedSurface1Display.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+developedSurface1Display.ScaleTransferFunction.Points = [0.0, 0.0, 0.5, 0.0, 1.1757813367477812e-38, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+developedSurface1Display.OpacityTransferFunction.Points = [0.0, 0.0, 0.5, 0.0, 1.1757813367477812e-38, 1.0, 0.5, 0.0]
+
+# hide data in view
+Hide(multiTSmed, renderView1)
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+#change interaction mode for render view
+renderView1.InteractionMode = '2D'
+
+# toggle 3D widget visibility (only when running from the GUI)
+Hide3DWidgets(proxy=developedSurface1.SliceType)
+
+# set scalar coloring
+ColorBy(developedSurface1Display, ('CELLS', 'Pressure'))
+
+# rescale color and/or opacity maps used to include current data range
+developedSurface1Display.RescaleTransferFunctionToDataRange(True, False)
+
+# show color bar/color legend
+developedSurface1Display.SetScalarBarVisibility(renderView1, True)
+
+# get color transfer function/color map for 'Pressure'
+pressureLUT = GetColorTransferFunction('Pressure')
+
+#### saving camera placements for all active views
+
+# current camera placement for renderView1
+renderView1.InteractionMode = '2D'
+renderView1.CameraPosition = [0.18935662797765695, 0.01726656182167085, 2.08092363470839]
+renderView1.CameraFocalPoint = [0.18935662797765695, 0.01726656182167085, 0.05000000074505806]
+renderView1.CameraParallelScale = 0.16748564967020724
+
+#### uncomment the following to render all views
+# RenderAllViews()
+# alternatively, if you want to write images, you can use SaveScreenshot(...).
+Render()
diff --git a/src/SphereAlongLines/Test/test_dev_surface2.py b/src/SphereAlongLines/Test/test_dev_surface2.py
new file mode 100644 (file)
index 0000000..3d7e85e
--- /dev/null
@@ -0,0 +1,169 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#### import the simple module from the paraview
+from paraview.simple import *
+from math import pi
+TMPFileName="test2.med"
+
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'Mandelbrot'
+mandelbrot1 = Mandelbrot()
+
+# Properties modified on mandelbrot1
+mandelbrot1.WholeExtent = [0, 50, 0, 50, 0, 50]
+
+# get active view
+renderView1 = GetActiveViewOrCreate('RenderView')
+# uncomment following to set a specific view size
+# renderView1.ViewSize = [1017, 317]
+
+# show data in view
+mandelbrot1Display = Show(mandelbrot1, renderView1)
+
+# trace defaults for the display properties.
+mandelbrot1Display.Representation = 'Outline'
+mandelbrot1Display.ColorArrayName = ['POINTS', '']
+mandelbrot1Display.OSPRayScaleArray = 'Iterations'
+mandelbrot1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+mandelbrot1Display.SelectOrientationVectors = 'Iterations'
+mandelbrot1Display.ScaleFactor = 0.25
+mandelbrot1Display.SelectScaleArray = 'Iterations'
+mandelbrot1Display.GlyphType = 'Arrow'
+mandelbrot1Display.GlyphTableIndexArray = 'Iterations'
+mandelbrot1Display.DataAxesGrid = 'GridAxesRepresentation'
+mandelbrot1Display.PolarAxes = 'PolarAxesRepresentation'
+mandelbrot1Display.ScalarOpacityUnitDistance = 0.08124038404635964
+mandelbrot1Display.Slice = 25
+mandelbrot1Display.GaussianRadius = 0.125
+mandelbrot1Display.SetScaleArray = ['POINTS', 'Iterations']
+mandelbrot1Display.ScaleTransferFunction = 'PiecewiseFunction'
+mandelbrot1Display.OpacityArray = ['POINTS', 'Iterations']
+mandelbrot1Display.OpacityTransferFunction = 'PiecewiseFunction'
+mandelbrot1Display.InputVectors = [None, '']
+mandelbrot1Display.SelectInputVectors = [None, '']
+mandelbrot1Display.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+mandelbrot1Display.ScaleTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+mandelbrot1Display.OpacityTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# reset view to fit data
+renderView1.ResetCamera()
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# create a new 'Developed Surface'
+developedSurface1 = DevelopedSurface(Input=mandelbrot1)
+developedSurface1.SliceType = 'Cylinder'
+
+# init the 'Cylinder' selected for 'SliceType'
+developedSurface1.SliceType.Center = [-0.5, 0.0, 1.0]
+developedSurface1.SliceType.Radius = 0.5 #1.25
+
+# show data in view
+developedSurface1Display = Show(developedSurface1, renderView1)
+
+# get color transfer function/color map for 'Iterations'
+iterationsLUT = GetColorTransferFunction('Iterations')
+
+# trace defaults for the display properties.
+developedSurface1Display.Representation = 'Surface'
+developedSurface1Display.ColorArrayName = ['POINTS', 'Iterations']
+developedSurface1Display.LookupTable = iterationsLUT
+developedSurface1Display.OSPRayScaleArray = 'Iterations'
+developedSurface1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+developedSurface1Display.SelectOrientationVectors = 'Iterations'
+developedSurface1Display.ScaleFactor = 0.7853981633974483
+developedSurface1Display.SelectScaleArray = 'Iterations'
+developedSurface1Display.GlyphType = 'Arrow'
+developedSurface1Display.GlyphTableIndexArray = 'Iterations'
+developedSurface1Display.DataAxesGrid = 'GridAxesRepresentation'
+developedSurface1Display.PolarAxes = 'PolarAxesRepresentation'
+developedSurface1Display.GaussianRadius = 0.39269908169872414
+developedSurface1Display.SetScaleArray = ['POINTS', 'Iterations']
+developedSurface1Display.ScaleTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.OpacityArray = ['POINTS', 'Iterations']
+developedSurface1Display.OpacityTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.InputVectors = [None, '']
+developedSurface1Display.SelectInputVectors = [None, '']
+developedSurface1Display.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+developedSurface1Display.ScaleTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+developedSurface1Display.OpacityTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# hide data in view
+Hide(mandelbrot1, renderView1)
+
+# show color bar/color legend
+developedSurface1Display.SetScalarBarVisibility(renderView1, True)
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# toggle 3D widget visibility (only when running from the GUI)
+Hide3DWidgets(proxy=developedSurface1.SliceType)
+
+#### saving camera placements for all active views
+
+# current camera placement for renderView1
+renderView1.CameraPosition = [4.090024784500779, -0.15919161102314858, 7.485304552729019]
+renderView1.CameraFocalPoint = [4.090024784500779, -0.15919161102314858, 1.0]
+renderView1.CameraParallelScale = 2.03100960115899
+
+#### uncomment the following to render all views
+# RenderAllViews()
+# alternatively, if you want to write images, you can use SaveScreenshot(...).
+
+mand=servermanager.Fetch(mandelbrot1)
+axisId=1
+high_out=mand.GetSpacing()[axisId]*(mand.GetExtent()[2*axisId+1]-mand.GetExtent()[2*axisId+0])
+
+vtp=servermanager.Fetch(developedSurface1)
+arr=vtp.GetPointData().GetArray(0)
+assert(arr.GetName()=="Iterations")
+a,b=arr.GetRange()
+assert(a>=1 and a<=2)
+assert(b==100.)
+SaveData(TMPFileName, proxy=developedSurface1)
+from MEDLoader import *
+
+mm=MEDFileMesh.New(TMPFileName)
+m0=mm[0]
+area=m0.getMeasureField(True).getArray().accumulate()[0]
+
+zeResu0=area/high_out/developedSurface1.SliceType.Radius
+assert(abs(zeResu0-2*pi)<1e-5)
+
+fs=MEDFileFields(TMPFileName)
+f=fs["Iterations"][0].field(mm)
+nodeIds=f.getArray().convertToDblArr().findIdsInRange(99.,101.)
+cellIds=m0.getCellIdsLyingOnNodes(nodeIds,True)
+zeResu1=m0[cellIds].getMeasureField(True).getArray().accumulate()[0]
+
+assert(abs(zeResu1-1.1427)<1e-2)
+
diff --git a/src/SphereAlongLines/Test/test_dev_surface3.py b/src/SphereAlongLines/Test/test_dev_surface3.py
new file mode 100644 (file)
index 0000000..c4b1b36
--- /dev/null
@@ -0,0 +1,165 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+#### import the simple module from the paraview
+from paraview.simple import *
+from math import pi
+TMPFileName="test3.med"
+
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+
+# create a new 'Mandelbrot'
+mandelbrot1 = Mandelbrot()
+
+# Properties modified on mandelbrot1
+mandelbrot1.WholeExtent = [0, 50, 0, 50, 0, 50]
+
+# get active view
+renderView1 = GetActiveViewOrCreate('RenderView')
+# uncomment following to set a specific view size
+# renderView1.ViewSize = [1017, 317]
+
+# show data in view
+mandelbrot1Display = Show(mandelbrot1, renderView1)
+
+# trace defaults for the display properties.
+mandelbrot1Display.Representation = 'Outline'
+mandelbrot1Display.ColorArrayName = ['POINTS', '']
+mandelbrot1Display.OSPRayScaleArray = 'Iterations'
+mandelbrot1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+mandelbrot1Display.SelectOrientationVectors = 'Iterations'
+mandelbrot1Display.ScaleFactor = 0.25
+mandelbrot1Display.SelectScaleArray = 'Iterations'
+mandelbrot1Display.GlyphType = 'Arrow'
+mandelbrot1Display.GlyphTableIndexArray = 'Iterations'
+mandelbrot1Display.DataAxesGrid = 'GridAxesRepresentation'
+mandelbrot1Display.PolarAxes = 'PolarAxesRepresentation'
+mandelbrot1Display.ScalarOpacityUnitDistance = 0.08124038404635964
+mandelbrot1Display.Slice = 25
+mandelbrot1Display.GaussianRadius = 0.125
+mandelbrot1Display.SetScaleArray = ['POINTS', 'Iterations']
+mandelbrot1Display.ScaleTransferFunction = 'PiecewiseFunction'
+mandelbrot1Display.OpacityArray = ['POINTS', 'Iterations']
+mandelbrot1Display.OpacityTransferFunction = 'PiecewiseFunction'
+mandelbrot1Display.InputVectors = [None, '']
+mandelbrot1Display.SelectInputVectors = [None, '']
+mandelbrot1Display.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+mandelbrot1Display.ScaleTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+mandelbrot1Display.OpacityTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# reset view to fit data
+renderView1.ResetCamera()
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# create a new 'Developed Surface'
+developedSurface1 = DevelopedSurface(Input=mandelbrot1)
+developedSurface1.SliceType = 'Cylinder'
+
+# init the 'Cylinder' selected for 'SliceType'
+developedSurface1.SliceType.Center = [-0.5, 0.0, 1.0]
+developedSurface1.SliceType.Radius = 0.5 #1.25
+developedSurface1.SliceType.Axis = [-0.5065630563269753, -0.6288876685363318, -0.5898255422814533]
+
+# show data in view
+developedSurface1Display = Show(developedSurface1, renderView1)
+
+# get color transfer function/color map for 'Iterations'
+iterationsLUT = GetColorTransferFunction('Iterations')
+
+# trace defaults for the display properties.
+developedSurface1Display.Representation = 'Surface'
+developedSurface1Display.ColorArrayName = ['POINTS', 'Iterations']
+developedSurface1Display.LookupTable = iterationsLUT
+developedSurface1Display.OSPRayScaleArray = 'Iterations'
+developedSurface1Display.OSPRayScaleFunction = 'PiecewiseFunction'
+developedSurface1Display.SelectOrientationVectors = 'Iterations'
+developedSurface1Display.ScaleFactor = 0.7853981633974483
+developedSurface1Display.SelectScaleArray = 'Iterations'
+developedSurface1Display.GlyphType = 'Arrow'
+developedSurface1Display.GlyphTableIndexArray = 'Iterations'
+developedSurface1Display.DataAxesGrid = 'GridAxesRepresentation'
+developedSurface1Display.PolarAxes = 'PolarAxesRepresentation'
+developedSurface1Display.GaussianRadius = 0.39269908169872414
+developedSurface1Display.SetScaleArray = ['POINTS', 'Iterations']
+developedSurface1Display.ScaleTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.OpacityArray = ['POINTS', 'Iterations']
+developedSurface1Display.OpacityTransferFunction = 'PiecewiseFunction'
+developedSurface1Display.InputVectors = [None, '']
+developedSurface1Display.SelectInputVectors = [None, '']
+developedSurface1Display.WriteLog = ''
+
+# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction'
+developedSurface1Display.ScaleTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction'
+developedSurface1Display.OpacityTransferFunction.Points = [1.0, 0.0, 0.5, 0.0, 100.0, 1.0, 0.5, 0.0]
+
+# hide data in view
+Hide(mandelbrot1, renderView1)
+
+# show color bar/color legend
+developedSurface1Display.SetScalarBarVisibility(renderView1, True)
+
+# update the view to ensure updated data information
+renderView1.Update()
+
+# toggle 3D widget visibility (only when running from the GUI)
+Hide3DWidgets(proxy=developedSurface1.SliceType)
+
+#### saving camera placements for all active views
+
+# current camera placement for renderView1
+renderView1.CameraPosition = [4.090024784500779, -0.15919161102314858, 7.485304552729019]
+renderView1.CameraFocalPoint = [4.090024784500779, -0.15919161102314858, 1.0]
+renderView1.CameraParallelScale = 2.03100960115899
+
+#### uncomment the following to render all views
+# RenderAllViews()
+# alternatively, if you want to write images, you can use SaveScreenshot(...).
+
+
+vtp=servermanager.Fetch(developedSurface1)
+arr=vtp.GetPointData().GetArray(0)
+assert(arr.GetName()=="Iterations")
+a,b=arr.GetRange()
+assert(a>=1 and a<=2)
+assert(b==100.)
+SaveData(TMPFileName, proxy=developedSurface1)
+from MEDLoader import *
+
+mm=MEDFileMesh.New(TMPFileName)
+m0=mm[0]
+area=m0.getMeasureField(True).getArray().accumulate()[0]
+
+
+fs=MEDFileFields(TMPFileName)
+f=fs["Iterations"][0].field(mm)
+nodeIds=f.getArray().convertToDblArr().findIdsInRange(99.,101.)
+cellIds=m0.getCellIdsLyingOnNodes(nodeIds,True)
+zeResu1=m0[cellIds].getMeasureField(True).getArray().accumulate()[0]
+
+assert(abs(zeResu1-1.3564)<1e-2)
+
diff --git a/src/SphereAlongLines/plugin/CMakeLists.txt b/src/SphereAlongLines/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bbf2f2f
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+paraview_add_plugin(SphereAlongLinesPlugin
+  VERSION "1.0"
+  MODULES SphereAlongLinesModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/SphereAlongLinesModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS SphereAlongLinesPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/SphereAlongLines/plugin/SphereAlongLinesModule/CMakeLists.txt b/src/SphereAlongLines/plugin/SphereAlongLinesModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..75e4e10
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkSphereAlongLines
+)
+
+vtk_module_add_module(SphereAlongLinesModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtk.module b/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtk.module
new file mode 100644 (file)
index 0000000..6d2af88
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SphereAlongLinesModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.cxx b/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.cxx
new file mode 100644 (file)
index 0000000..f1f3887
--- /dev/null
@@ -0,0 +1,714 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkSphereAlongLines.h"
+
+#include <vtkAlgorithmOutput.h>
+#include <vtkCellData.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkUnstructuredGrid.h>
+
+#include <algorithm>
+#include <deque>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+
+vtkStandardNewMacro(vtkSphereAlongLines);
+
+template <class T>
+struct VTKTraits
+{
+};
+
+template <>
+struct VTKTraits<float>
+{
+  using VtkType = vtkFloatArray;
+};
+
+template <>
+struct VTKTraits<double>
+{
+  using VtkType = vtkDoubleArray;
+};
+
+constexpr const char INTEGRATIONTIME_ARR_NAME[] = "IntegrationTime";
+
+///////////////////
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s)
+    : _reason(s)
+  {
+  }
+  virtual const char* what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+void ExtractInfo(vtkInformationVector* inputVector, vtkPolyData*& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input(0);
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw MZCException(
+        "Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use "
+                         "MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this "
+                         "single element is NULL !");
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw MZCException(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw MZCException("Input data set is NULL !");
+  vtkPointData* att(input->GetPointData());
+  vtkPolyData* zeInput(vtkPolyData::SafeDownCast(input));
+  if (!zeInput)
+    throw MZCException("Input dataSet is not a polydata as expected !");
+  usgIn = zeInput;
+}
+
+vtkDataArray* GetCoords(vtkPointSet* ds)
+{
+  vtkPoints* pts(ds->GetPoints());
+  if (!pts)
+    throw MZCException("GetCoords : internal error 2 !");
+  vtkDataArray* data(pts->GetData());
+  if (!data)
+    throw MZCException("GetCoords : internal error 3 !");
+  if (data->GetNumberOfComponents() != 3)
+    throw MZCException("GetCoords : internal error 4 !");
+  return data;
+}
+
+vtkDoubleArray* GetIntegrationTime(vtkPointSet* ds)
+{
+  vtkDataSetAttributes* dsa(ds->GetPointData());
+  if (!dsa)
+    throw MZCException(
+      "GetIntegrationTime : no point data ! Is the input data comes from Stream Tracer !");
+  int idx(0);
+  vtkAbstractArray* arr(dsa->GetAbstractArray(INTEGRATIONTIME_ARR_NAME, idx));
+  if (!arr)
+  {
+    std::ostringstream oss;
+    oss << "GetIntegrationTime : no such " << INTEGRATIONTIME_ARR_NAME
+        << " array in input dataset !";
+    throw MZCException(oss.str());
+  }
+  vtkDoubleArray* ret(vtkDoubleArray::SafeDownCast(arr));
+  if (!ret)
+  {
+    std::ostringstream oss;
+    oss << "GetIntegrationTime :" << INTEGRATIONTIME_ARR_NAME << " array expected to be float64 !";
+    throw MZCException(oss.str());
+  }
+  if (ret->GetNumberOfComponents() != 1)
+  {
+    std::ostringstream oss;
+    oss << "GetIntegrationTime :" << INTEGRATIONTIME_ARR_NAME
+        << " array expected to be single compo !";
+    throw MZCException(oss.str());
+  }
+  return ret;
+}
+
+template <class T>
+void RearrangeIfNecessaryImpl(typename VTKTraits<T>::VtkType* coords, vtkDoubleArray* intTime,
+  std::vector<std::vector<vtkIdType> >& connect, double eps)
+{
+  std::size_t nbCells(connect.size());
+  if (nbCells % 2 != 0)
+    return;
+  std::size_t nbCellsCand(nbCells / 2);
+  const double* intTimePtr(intTime->GetPointer(0));
+  const T* coordsPtr(coords->GetPointer(0));
+  T distance[3];
+  std::vector<std::vector<vtkIdType> > connectOut(nbCellsCand);
+  for (std::size_t i = 0; i < nbCellsCand; i++)
+  {
+    const std::vector<vtkIdType>& elt0(connect[i]);
+    const std::vector<vtkIdType>& elt1(connect[i + nbCellsCand]);
+    if (elt0.empty() || elt1.empty())
+      return;
+    vtkIdType pt0(elt0[0]), pt1(elt1[0]);
+    if (pt0 == pt1)
+      continue;
+    if (std::abs(intTimePtr[pt0]) > eps || std::abs(intTimePtr[pt1]) > eps)
+      return;
+    std::transform(coordsPtr + 3 * pt0, coordsPtr + 3 * (pt0 + 1), coordsPtr + 3 * pt1, distance,
+      [](T a, T b) { return b - a; });
+    if (std::sqrt(
+          distance[0] * distance[0] + distance[1] * distance[1] + distance[2] * distance[2]) > eps)
+      return;
+    std::vector<vtkIdType>& tab(connectOut[i]);
+    tab.insert(tab.end(), elt1.rbegin(), elt1.rend());
+    tab.back() = elt0[0];
+    tab.insert(tab.end(), elt0.begin() + 1, elt0.end());
+  }
+  connect = connectOut;
+}
+
+void RearrangeIfNecessary(vtkDataArray* coords, vtkDoubleArray* intTime,
+  std::vector<std::vector<vtkIdType> >& connect, double eps)
+{
+  vtkFloatArray* c0(vtkFloatArray::SafeDownCast(coords));
+  if (c0)
+  {
+    RearrangeIfNecessaryImpl<float>(c0, intTime, connect, eps);
+    return;
+  }
+  vtkDoubleArray* c1(vtkDoubleArray::SafeDownCast(coords));
+  if (c1)
+  {
+    RearrangeIfNecessaryImpl<double>(c1, intTime, connect, eps);
+    return;
+  }
+  throw MZCException("Not recognized type of data for coordinates !");
+}
+
+class vtkSphereAlongLines::vtkInternals
+{
+  friend class CurvAbsPathWalker;
+
+  class PathWalker
+  {
+  protected:
+    PathWalker(const vtkSphereAlongLines::vtkInternals* intern)
+      : _internal(intern)
+    {
+    }
+
+  public:
+    virtual double getTimeFrom(std::size_t pathId, double absTime2) const = 0;
+    virtual bool isInside(std::size_t pathId, double realTime, vtkIdType& a, vtkIdType& b,
+      double& aw, double& bw) const = 0;
+
+  protected:
+    const vtkSphereAlongLines::vtkInternals* _internal;
+  };
+
+  class IntTimeGlobPathWalker : public PathWalker
+  {
+  public:
+    IntTimeGlobPathWalker(const vtkSphereAlongLines::vtkInternals* intern)
+      : PathWalker(intern)
+    {
+    }
+    double getTimeFrom(std::size_t pathId, double absTime2) const;
+    bool isInside(std::size_t pathId, double realTime, vtkIdType& a, vtkIdType& b, double& aw,
+      double& bw) const override;
+  };
+
+  class LocalPathWalker : public PathWalker
+  {
+  protected:
+    LocalPathWalker(const vtkSphereAlongLines::vtkInternals* intern)
+      : PathWalker(intern)
+    {
+    }
+    bool isInside(std::size_t pathId, double realTime, vtkIdType& a, vtkIdType& b, double& aw,
+      double& bw) const override;
+    double getTimeFrom(std::size_t pathId, double absTime2) const override;
+    virtual const std::vector<double>& getRankingArray(std::size_t pathId) const = 0;
+  };
+
+  class IntTimeLocPathWalker : public LocalPathWalker
+  {
+  public:
+    IntTimeLocPathWalker(const vtkSphereAlongLines::vtkInternals* intern)
+      : LocalPathWalker(intern)
+    {
+    }
+    const std::vector<double>& getRankingArray(std::size_t pathId) const override
+    {
+      return _internal->_integration_time_along_pathes[pathId];
+    }
+  };
+
+  class CurvAbsPathWalker : public LocalPathWalker
+  {
+  public:
+    CurvAbsPathWalker(const vtkSphereAlongLines::vtkInternals* intern)
+      : LocalPathWalker(intern)
+    {
+    }
+    const std::vector<double>& getRankingArray(std::size_t pathId) const override
+    {
+      return _internal->_curv_absc_along_pathes[pathId];
+    }
+  };
+
+public:
+  void initCacheIfNeeded(vtkPolyData* ds);
+  vtkSmartPointer<vtkPolyData> dataSetAtNormalizedTime(
+    vtkPolyData* ds, double absTime, int walkType) const;
+  std::unique_ptr<PathWalker> buildPathWalker(int walkType) const;
+
+private:
+  void initCacheForce(vtkPolyData* ds);
+
+private:
+  vtkMTimeType _input_DS_time = 0;
+  std::vector<std::vector<vtkIdType> > _connectivity;
+  //! for each path it stores the integration time the corresponding time. Every array is expected
+  //! to be in ascending order
+  std::vector<std::vector<double> > _integration_time_along_pathes;
+  //! for each path it stores curv abscissa along pathes
+  std::vector<std::vector<double> > _curv_absc_along_pathes;
+  std::vector<std::pair<double, double> > _time_range_per_path;
+  std::vector<std::pair<double, double> > _ca_range_per_path;
+  double _abs_min = std::numeric_limits<double>::max();
+  double _abs_max = -std::numeric_limits<double>::max();
+};
+
+double vtkSphereAlongLines::vtkInternals::IntTimeGlobPathWalker::getTimeFrom(
+  std::size_t, double absTime2) const
+{
+  return _internal->_abs_min + absTime2 * (_internal->_abs_max - _internal->_abs_min);
+}
+
+bool vtkSphereAlongLines::vtkInternals::IntTimeGlobPathWalker::isInside(
+  std::size_t pathId, double realTime, vtkIdType& a, vtkIdType& b, double& aw, double& bw) const
+{
+  const std::pair<double, double>& pathRange(_internal->_time_range_per_path[pathId]);
+  if (realTime < pathRange.first || realTime > pathRange.second)
+    return false;
+  const std::vector<double>& timeAlongPath(_internal->_integration_time_along_pathes[pathId]);
+  const std::vector<vtkIdType>& associatedNodes(_internal->_connectivity[pathId]);
+  std::vector<double>::const_iterator it(std::find_if(timeAlongPath.begin(), timeAlongPath.end(),
+    [realTime](const double& val) -> bool { return realTime < val; }));
+  std::size_t pos(std::distance(timeAlongPath.begin(), it));
+  pos = std::min(pos, timeAlongPath.size() - 1);
+  if (*it != realTime)
+  {
+    a = associatedNodes[pos - 1];
+    b = associatedNodes[pos];
+    aw = (timeAlongPath[pos] - realTime) / (timeAlongPath[pos] - timeAlongPath[pos - 1]);
+    bw = 1. - aw;
+  }
+  else
+  {
+    a = associatedNodes[pos];
+    b = a;
+    aw = 1.;
+    bw = 0.;
+  }
+  return true;
+}
+
+bool vtkSphereAlongLines::vtkInternals::LocalPathWalker::isInside(
+  std::size_t pathId, double realTime, vtkIdType& a, vtkIdType& b, double& aw, double& bw) const
+{
+  const std::vector<double>& timeAlongPath(getRankingArray(pathId));
+  const std::vector<vtkIdType>& associatedNodes(_internal->_connectivity[pathId]);
+  std::vector<double>::const_iterator it(std::find_if(timeAlongPath.begin(), timeAlongPath.end(),
+    [realTime](const double& val) -> bool { return realTime <= val; }));
+  std::size_t pos(std::distance(timeAlongPath.begin(), it));
+  pos = std::min(pos, timeAlongPath.size() - 1);
+  if (*it != realTime)
+  {
+    a = associatedNodes[pos - 1];
+    b = associatedNodes[pos];
+    aw = (timeAlongPath[pos] - realTime) / (timeAlongPath[pos] - timeAlongPath[pos - 1]);
+    bw = 1. - aw;
+  }
+  else
+  {
+    a = associatedNodes[pos];
+    b = a;
+    aw = 1.;
+    bw = 0.;
+  }
+  return true;
+}
+
+double vtkSphereAlongLines::vtkInternals::LocalPathWalker::getTimeFrom(
+  std::size_t pathId, double absTime2) const
+{
+  double realTime(std::numeric_limits<double>::max());
+  {
+    const std::vector<double>& timeAlongPath(getRankingArray(pathId));
+    realTime = timeAlongPath.front() + absTime2 * (timeAlongPath.back() - timeAlongPath.front());
+    realTime = std::max(realTime, timeAlongPath.front());
+    realTime = std::min(realTime, timeAlongPath.back());
+  }
+  return realTime;
+}
+
+std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker>
+vtkSphereAlongLines::vtkInternals::buildPathWalker(int walkType) const
+{
+  switch (walkType)
+  {
+    case 0:
+      return std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker>(
+        new IntTimeGlobPathWalker(this));
+    case 1:
+      return std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker>(
+        new IntTimeLocPathWalker(this));
+    case 2:
+      return std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker>(
+        new CurvAbsPathWalker(this));
+    default:
+      return std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker>(
+        new CurvAbsPathWalker(this));
+  }
+}
+
+void vtkSphereAlongLines::vtkInternals::initCacheIfNeeded(vtkPolyData* ds)
+{
+  vtkMTimeType mtime(ds->GetMTime());
+  if (ds->GetMTime() == _input_DS_time)
+    return;
+  initCacheForce(ds);
+  _input_DS_time = mtime;
+}
+
+void vtkSphereAlongLines::vtkInternals::initCacheForce(vtkPolyData* ds)
+{
+  // std::cout << "Force cache" << std::endl;
+  _abs_min = std::numeric_limits<double>::max();
+  _abs_max = -std::numeric_limits<double>::max();
+  _connectivity.clear();
+  _integration_time_along_pathes.clear();
+  _curv_absc_along_pathes.clear();
+  _time_range_per_path.clear();
+  _ca_range_per_path.clear();
+  // to Improve
+  vtkDataArray* cooInBase(GetCoords(ds));
+  vtkFloatArray* cooIn(vtkFloatArray::SafeDownCast(cooInBase));
+  //
+  if ((ds->GetPolys() && ds->GetPolys()->GetNumberOfCells() > 0) ||
+    (ds->GetStrips() && ds->GetStrips()->GetNumberOfCells() > 0) ||
+    (ds->GetVerts() && ds->GetVerts()->GetNumberOfCells() > 0))
+    throw MZCException(
+      "Presence of strips/vertices/polygons in input polydata ! Invalid with this type of filter!");
+  vtkCellArray* cc(ds->GetLines());
+  if (!cc)
+    throw MZCException("No polylines in input polydata ! Difficult to build something on it !");
+  vtkIdType nbCells(cc->GetNumberOfCells());
+  _connectivity.resize(nbCells);
+  vtkIdType npts;
+  const vtkIdType* pts;
+  cc->InitTraversal();
+  for (vtkIdType i = 0; cc->GetNextCell(npts, pts); i++)
+  {
+    std::vector<vtkIdType>& conn2(_connectivity[i]);
+    conn2.insert(conn2.end(), pts, pts + npts);
+  }
+  cc->InitTraversal();
+  vtkDoubleArray* ita(GetIntegrationTime(ds));
+  RearrangeIfNecessary(GetCoords(ds), ita, _connectivity, 1e-5);
+  const double* itaPtr(ita->GetPointer(0));
+  std::size_t nbCellsEff(_connectivity.size());
+  _integration_time_along_pathes.resize(nbCellsEff);
+  _curv_absc_along_pathes.resize(nbCellsEff);
+  _time_range_per_path.resize(nbCellsEff);
+  _ca_range_per_path.resize(nbCellsEff);
+  for (std::size_t i = 0; i < nbCellsEff; i++)
+  {
+    const std::vector<vtkIdType>& conn2(_connectivity[i]);
+    std::vector<double>& vals(_integration_time_along_pathes[i]);
+    std::vector<double>& absCurv(_curv_absc_along_pathes[i]);
+    std::transform(conn2.begin(), conn2.end(), std::back_inserter(vals),
+      [itaPtr](vtkIdType nodeId) { return itaPtr[nodeId]; });
+    float lastVal(0.);
+    const float* cooInPtr(cooIn->GetPointer(conn2[0] * 3));
+    std::transform(conn2.begin(), conn2.end(), std::back_inserter(absCurv),
+      [cooIn, &cooInPtr, &lastVal](vtkIdType nodeId) {
+        const float* pt(cooIn->GetPointer(nodeId * 3));
+        lastVal += sqrt((cooInPtr[0] - pt[0]) * (cooInPtr[0] - pt[0]) +
+          (cooInPtr[1] - pt[1]) * (cooInPtr[1] - pt[1]) +
+          (cooInPtr[2] - pt[2]) * (cooInPtr[2] - pt[2]));
+        cooInPtr = pt;
+        return lastVal;
+      });
+    _time_range_per_path[i].first = vals.front();
+    _time_range_per_path[i].second = vals.back();
+    _ca_range_per_path[i].first = absCurv.front();
+    _ca_range_per_path[i].second = absCurv.back();
+    _abs_min = std::min(_abs_min, vals.front());
+    _abs_max = std::max(_abs_max, vals.back());
+    // std::cout << "cell " << i << " -> "; std::for_each(conn2.begin(),conn2.end(),[](vtkIdType
+    // elt) { std::cout << elt << " "; }); std::cout << std::endl; std::cout << "cell " << i << " ->
+    // "; std::for_each(absCurv.begin(),absCurv.end(),[](double elt) { std::cout << elt << " "; });
+    // std::cout << std::endl;
+  }
+  // std::cerr << _abs_min << " - " << _abs_max << std::endl;
+}
+
+template <class VTKDATAARRAY>
+void dealWith(
+  VTKDATAARRAY* arr1, vtkDataArray* arrOut, vtkIdType a, double aw, vtkIdType b, double bw)
+{
+  int nbCompo(arr1->GetNumberOfComponents());
+  using VT = typename VTKDATAARRAY::ValueType;
+  VT *tupleA(arr1->GetPointer(nbCompo * a)), *tupleB(arr1->GetPointer(b * nbCompo));
+  {
+    VT* tmpData = new VT[nbCompo];
+    std::transform(tupleA, tupleA + nbCompo, tupleB, tmpData,
+      [aw, bw](VT a, VT b) -> VT { return VT(a) * VT(aw) + VT(b) * VT(bw); });
+    arrOut->InsertNextTuple(tmpData);
+    delete[] tmpData;
+  }
+}
+
+class CooAssign
+{
+public:
+  virtual void apply(
+    vtkIdType a, double aw, vtkIdType b, double bw, vtkDoubleArray* cooOut) const = 0;
+};
+
+template <class T>
+class CooAssignT : public CooAssign
+{
+public:
+  using VtkType = typename VTKTraits<T>::VtkType;
+  CooAssignT(VtkType* arr)
+    : _coo_in(arr->GetPointer(0))
+  {
+  }
+  void apply(vtkIdType a, double aw, vtkIdType b, double bw, vtkDoubleArray* cooOut) const override
+  {
+    const T *pt0(_coo_in + 3 * a), *pt1(_coo_in + 3 * b);
+    std::transform(pt0, pt0 + 3, pt1, ptToAdd, [aw, bw](T elt0, T elt1) -> double {
+      return double(elt0) * double(aw) + double(elt1) * double(bw);
+    });
+    cooOut->InsertNextTuple(ptToAdd);
+  }
+
+private:
+  const T* _coo_in;
+  T tmp[3];
+  mutable double ptToAdd[3];
+};
+
+vtkSmartPointer<vtkPolyData> vtkSphereAlongLines::vtkInternals::dataSetAtNormalizedTime(
+  vtkPolyData* ds, double absTime, int walkType) const
+{
+  double absTime2(std::min(std::max(absTime, 0.), 1.));
+  std::size_t maxNbOfPts(_integration_time_along_pathes.size());
+  std::vector<vtkSmartPointer<vtkDataArray> > outArrays;
+  std::vector<vtkDataArray*> inArrays;
+  {
+    vtkDataSetAttributes* dsa(ds->GetPointData());
+    for (int i = 0; i < dsa->GetNumberOfArrays(); i++)
+    {
+      vtkDataArray* arr(dsa->GetArray(i));
+      if (!arr)
+        continue;
+      vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+      if (arr1)
+      {
+        vtkSmartPointer<vtkDoubleArray> outArray(vtkDoubleArray::New());
+        outArray->SetName(arr->GetName());
+        outArray->SetNumberOfComponents(arr->GetNumberOfComponents());
+        outArray->SetNumberOfTuples(0);
+        outArrays.push_back(outArray);
+        inArrays.push_back(arr);
+        continue;
+      }
+      vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+      if (arr2)
+      {
+        vtkSmartPointer<vtkFloatArray> outArray(vtkFloatArray::New());
+        outArray->SetName(arr->GetName());
+        outArray->SetNumberOfComponents(arr->GetNumberOfComponents());
+        outArray->SetNumberOfTuples(0);
+        outArrays.push_back(outArray);
+        inArrays.push_back(arr);
+        continue;
+      }
+    }
+  }
+  std::size_t nbArrays(outArrays.size());
+  vtkDataArray* cooInBase(GetCoords(ds));
+  std::unique_ptr<CooAssign> cooInDS;
+  vtkFloatArray* cooIn(vtkFloatArray::SafeDownCast(cooInBase));
+  if (cooIn)
+  {
+    std::unique_ptr<CooAssignT<float> > tmp(new CooAssignT<float>(cooIn));
+    cooInDS = std::move(tmp);
+  }
+  vtkDoubleArray* cooIn2(vtkDoubleArray::SafeDownCast(cooInBase));
+  if (cooIn2)
+  {
+    std::unique_ptr<CooAssignT<double> > tmp(new CooAssignT<double>(cooIn2));
+    cooInDS = std::move(tmp);
+  }
+  const float* cooInPtr(cooIn->GetPointer(0));
+  // TODO : improve
+  vtkSmartPointer<vtkPolyData> outDS(vtkPolyData::New());
+  vtkSmartPointer<vtkDoubleArray> cooOut(vtkDoubleArray::New());
+  cooOut->SetNumberOfComponents(3);
+  cooOut->SetNumberOfTuples(0);
+  {
+    vtkNew<vtkPoints> pts;
+    pts->SetData(cooOut);
+    outDS->SetPoints(pts);
+  }
+  vtkNew<vtkCellArray> verts;
+  vtkNew<vtkIdTypeArray> conn;
+  conn->SetNumberOfComponents(1);
+  vtkIdType nbOfPts(0);
+  vtkIdType connToAdd[2];
+  connToAdd[0] = 1;
+  std::vector<vtkIdType> connv;
+  std::unique_ptr<vtkSphereAlongLines::vtkInternals::PathWalker> pw(buildPathWalker(walkType));
+  for (std::size_t i = 0; i < maxNbOfPts; i++)
+  {
+    vtkIdType a, b;
+    double aw, bw;
+    double realTime(pw->getTimeFrom(i, absTime2));
+    if (pw->isInside(i, realTime, a, b, aw, bw))
+    {
+      // std::cout << i << " - " << a << " - " << b << " * " << aw << " * " << bw << std::endl;
+      cooInDS->apply(a, aw, b, bw, cooOut);
+      connToAdd[1] = nbOfPts++;
+      connv.insert(connv.end(), connToAdd, connToAdd + 2);
+      for (std::size_t j = 0; j < nbArrays; j++)
+      {
+        vtkDataArray* arr(inArrays[j]);
+        vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+        if (arr1)
+        {
+          dealWith(arr1, outArrays[j], a, aw, b, bw);
+          continue;
+        }
+        vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+        if (arr2)
+        {
+          dealWith(arr2, outArrays[j], a, aw, b, bw);
+          continue;
+        }
+      }
+    }
+  }
+  conn->SetNumberOfTuples(connv.size());
+  std::copy(connv.begin(), connv.end(), conn->GetPointer(0));
+  verts->SetCells(nbOfPts, conn);
+  outDS->SetVerts(verts);
+  {
+    vtkDataSetAttributes* dsa(outDS->GetPointData());
+    for (auto arr : outArrays)
+    {
+      dsa->AddArray(arr);
+    }
+  }
+  return outDS;
+}
+
+////////////////////
+
+vtkSphereAlongLines::vtkSphereAlongLines()
+  : Internal(new vtkInternals)
+  , AnimationTime(0.)
+  , WalkType(2)
+{
+}
+
+vtkSphereAlongLines::~vtkSphereAlongLines()
+{
+  delete this->Internal;
+}
+
+int vtkSphereAlongLines::RequestInformation(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "##########################################
+  // vtkSphereAlongLines::RequestInformation ##########################################" <<
+  // std::endl;
+  try
+  {
+    vtkPolyData* ds(nullptr);
+    ExtractInfo(inputVector[0], ds);
+  }
+  catch (MZCException& e)
+  {
+    vtkErrorMacro(<< "Exception has been thrown in vtkSphereAlongLines::RequestInformation : "
+                  << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+int vtkSphereAlongLines::RequestData(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkSphereAlongLines::RequestData
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkPolyData* ds(nullptr);
+    ExtractInfo(inputVector[0], ds);
+    this->Internal->initCacheIfNeeded(ds);
+    vtkSmartPointer<vtkPolyData> pts(
+      this->Internal->dataSetAtNormalizedTime(ds, this->AnimationTime, this->WalkType));
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    vtkPolyData* output(vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    output->ShallowCopy(pts);
+  }
+  catch (MZCException& e)
+  {
+    vtkErrorMacro(<< "Exception has been thrown in vtkSphereAlongLines::Data : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkSphereAlongLines::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.h b/src/SphereAlongLines/plugin/SphereAlongLinesModule/vtkSphereAlongLines.h
new file mode 100644 (file)
index 0000000..28e45a7
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkSphereAlongLines_h__
+#define vtkSphereAlongLines_h__
+
+#include <vtkPolyDataAlgorithm.h>
+
+class VTK_EXPORT vtkSphereAlongLines : public vtkPolyDataAlgorithm
+{
+public:
+  static vtkSphereAlongLines* New();
+  vtkTypeMacro(vtkSphereAlongLines, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  vtkGetMacro(AnimationTime, double);
+  vtkSetClampMacro(AnimationTime, double, 0., 1.);
+
+  vtkGetMacro(WalkType, int);
+  vtkSetMacro(WalkType, int);
+
+protected:
+  vtkSphereAlongLines();
+  ~vtkSphereAlongLines() override;
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  class vtkInternals;
+  vtkInternals* Internal;
+  double AnimationTime;
+  int WalkType;
+
+private:
+  vtkSphereAlongLines(const vtkSphereAlongLines&) = delete;
+  void operator=(const vtkSphereAlongLines&) = delete;
+};
+
+#endif
diff --git a/src/SphereAlongLines/plugin/filters.xml b/src/SphereAlongLines/plugin/filters.xml
new file mode 100644 (file)
index 0000000..86c7087
--- /dev/null
@@ -0,0 +1,51 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="SphereAlongLines"
+                 class="vtkSphereAlongLines"
+                 label="Sphere Along Lines">
+
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkPolyData"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Sphere Along Lines filter.
+        </Documentation>
+      </InputProperty>
+
+      <DoubleVectorProperty animateable="1"
+                            command="SetAnimationTime"
+                            default_values="0"
+                            name="AnimationTime"
+                            number_of_elements="1">
+        <DoubleRangeDomain max="1" min="0" name="range" />
+        <Documentation>The value of this property allows to animate spheres along input pathes. This value is expected to be inside [0,1]  range.</Documentation>
+      </DoubleVectorProperty>
+
+      <IntVectorProperty command="SetWalkType"
+                         default_values="0"
+                         name="WalkType"
+                         number_of_elements="1">
+        <EnumerationDomain name="enum">
+          <Entry text="INTEGRATION TIME WHOLE"
+                 value="0" />
+          <Entry text="INTAGRATION TIME"
+                 value="1" />
+          <Entry text="CURVE ABSICSSA"
+                 value="2" />
+        </EnumerationDomain>
+        <Documentation>This property determines in which direction(s) a
+        streamline is generated.</Documentation>
+      </IntVectorProperty>
+
+      <Hints>
+         <ShowInMenu category="CFD" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/SphereAlongLines/plugin/paraview.plugin b/src/SphereAlongLines/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..e04b8c5
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  SphereAlongLinesPlugin
+DESCRIPTION
+  This plugin provides the SphereAlongLines filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/TemporalOnPoint/CMakeLists.txt b/src/TemporalOnPoint/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c54bec3
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(TemporalOnPointPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/TemporalOnPoint/TestCase.py b/src/TemporalOnPoint/TestCase.py
new file mode 100644 (file)
index 0000000..07a9dcf
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDLoader import *
+
+fname="hydrau_test3.med"
+meshName="mesh"
+arr=DataArrayDouble([0,1,2,3,4,5])
+m=MEDCouplingCMesh()
+m.setCoords(arr,arr)
+m=m.buildUnstructured()
+m.setName(meshName)
+m.simplexize(0)
+WriteMesh(fname,m,True)
+#
+f=MEDCouplingFieldDouble(ON_NODES)
+f.setMesh(m)
+f.setName("Field")
+arr=m.getCoords().magnitude()
+f.setArray(arr)
+for i in range(10):
+    arr+=0.1
+    f.setTime(float(i)+0.2,i,0)
+    WriteFieldUsingAlreadyWrittenMesh(fname,f)
+    pass
+
diff --git a/src/TemporalOnPoint/plugin/CMakeLists.txt b/src/TemporalOnPoint/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f0910b8
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(BUILD_SHARED_LIBS TRUE)
+
+paraview_add_plugin(TemporalOnPointPlugin
+  VERSION "1.0"
+  MODULES TemporalOnPointModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/TemporalOnPointModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS TemporalOnPointPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/TemporalOnPoint/plugin/TemporalOnPointModule/CMakeLists.txt b/src/TemporalOnPoint/plugin/TemporalOnPointModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3d4dc40
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkTemporalOnPoint
+)
+
+vtk_module_add_module(TemporalOnPointModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtk.module b/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtk.module
new file mode 100644 (file)
index 0000000..a0c1a0c
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  TemporalOnPointModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersModeling
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.cxx b/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.cxx
new file mode 100644 (file)
index 0000000..ee1a9b8
--- /dev/null
@@ -0,0 +1,586 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkTemporalOnPoint.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCompositeDataProbeFilter.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkTable.h>
+#include <vtkTimeStamp.h>
+#include <vtkUnstructuredGrid.h>
+
+#include <deque>
+#include <map>
+#include <set>
+#include <sstream>
+
+vtkStandardNewMacro(vtkTemporalOnPoint);
+
+///////////////////
+
+template <class T>
+class AutoPtr
+{
+public:
+  AutoPtr(T* ptr = nullptr)
+    : _ptr(ptr)
+  {
+  }
+  ~AutoPtr() { destroyPtr(); }
+  AutoPtr& operator=(T* ptr)
+  {
+    if (_ptr != ptr)
+    {
+      destroyPtr();
+      _ptr = ptr;
+    }
+    return *this;
+  }
+  T* operator->() { return _ptr; }
+  const T* operator->() const { return _ptr; }
+  T& operator*() { return *_ptr; }
+  const T& operator*() const { return *_ptr; }
+  operator T*() { return _ptr; }
+  operator const T*() const { return _ptr; }
+
+private:
+  void destroyPtr() { delete[] _ptr; }
+
+private:
+  T* _ptr;
+};
+
+class MZCException : public std::exception
+{
+public:
+  MZCException(const std::string& s)
+    : _reason(s)
+  {
+  }
+  virtual const char* what() const throw() { return _reason.c_str(); }
+  virtual ~MZCException() throw() {}
+
+private:
+  std::string _reason;
+};
+
+class vtkTemporalOnPoint::vtkInternal
+{
+public:
+  vtkInternal()
+    : _isInit(true)
+  {
+    _Z = std::numeric_limits<double>::max();
+  }
+  void operate(double timeStep, vtkUnstructuredGrid* usgIn, vtkPolyData* source);
+  void pushData(double timeStep, vtkPolyData* data);
+  void fillTable(vtkTable* table) const;
+  void scanCoordsOfDS(vtkUnstructuredGrid* usg);
+  static std::size_t CheckPts(vtkPointSet* usg, vtkDataArray*& arr);
+
+private:
+  void pushDataInit(double timeStep, vtkDataSetAttributes* dsa);
+  void pushDataStd(double timeStep, vtkDataSetAttributes* dsa);
+
+private:
+  double _Z;
+  bool _isInit;
+  std::vector<std::string> _columnNames;
+  std::vector<double> _time;
+  // First level of _data is for curves series.
+  // Second level of _data is for curve. Foreach i sizeof(_data[i]) must be equal to
+  // sizeof(_columName) Third level of _data is for time. Foreach i,j sizeof(_data[i][j]) must be
+  // equal to sizeof(_time)
+  std::vector<std::vector<std::vector<double> > > _data;
+};
+
+void ExtractInfo(vtkInformationVector* inputVector, vtkUnstructuredGrid*& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input(0);
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw MZCException(
+        "Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw MZCException("Input dataSet is a multiblock dataset with not exactly one block ! Use "
+                         "MergeBlocks or ExtractBlocks filter before calling this filter !");
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+      throw MZCException("Input dataSet is a multiblock dataset with exactly one block but this "
+                         "single element is NULL !");
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw MZCException(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw MZCException("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw MZCException("Input data set is not an unstructured mesh ! This filter works only on "
+                       "unstructured meshes !");
+}
+
+////////////////////
+
+vtkTemporalOnPoint::vtkTemporalOnPoint()
+  : NumberOfTimeSteps(0)
+  , IsExecuting(false)
+  , CurrentTimeIndex(0)
+  , Internal(nullptr)
+{
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfOutputPorts(1);
+}
+
+vtkTemporalOnPoint::~vtkTemporalOnPoint()
+{
+  delete this->Internal;
+  this->Internal = nullptr;
+}
+
+int vtkTemporalOnPoint::RequestInformation(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkTemporalOnPoint::RequestInformation
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid* usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    vtkInformation* inInfo(inputVector[0]->GetInformationObject(0));
+    if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      this->NumberOfTimeSteps = inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    else
+    {
+      this->NumberOfTimeSteps = 0;
+    }
+    // The output of this filter does not contain a specific time, rather
+    // it contains a collection of time steps. Also, this filter does not
+    // respond to time requests. Therefore, we remove all time information
+    // from the output.
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+    }
+    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
+    {
+      outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
+    }
+    return 1;
+  }
+  catch (MZCException& e)
+  {
+    vtkErrorMacro(<< "Exception has been thrown in vtkTemporalOnPoint::RequestInformation : "
+                  << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+int vtkTemporalOnPoint::RequestUpdateExtent(vtkInformation*, vtkInformationVector** inputVector,
+  vtkInformationVector* vtkNotUsed(outputVector))
+{
+  // vtkInformation* outInfo = outputVector->GetInformationObject(0);
+  vtkInformation* inInfo1 = inputVector[0]->GetInformationObject(0);
+
+  // get the requested update extent
+  double* inTimes = inInfo1->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
+  if (inTimes)
+  {
+    double timeReq = inTimes[this->CurrentTimeIndex];
+    inInfo1->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), timeReq);
+  }
+
+  return 1;
+}
+
+std::string buildNameOfEntryFrom(const std::string& name, std::size_t id, std::size_t nbOfElt)
+{
+  if (nbOfElt == 0)
+    throw MZCException("buildNameOfEntryFrom : nbElt == 0 !");
+  if (nbOfElt == 1)
+    return name;
+  std::ostringstream oss;
+  oss << name << "_" << id;
+  return oss.str();
+}
+
+void buildTableFrom(vtkTable* table,
+  const std::vector<std::vector<std::vector<double> > >& valuesByColumn,
+  const std::vector<double> zeTimes, const std::vector<std::string>& columnNames)
+{
+  {
+    vtkNew<vtkDoubleArray> timeArr;
+    timeArr->SetName("Time");
+    timeArr->SetNumberOfTuples(zeTimes.size());
+    double* pt(timeArr->GetPointer(0));
+    std::copy(zeTimes.begin(), zeTimes.end(), pt);
+    table->AddColumn(timeArr);
+  }
+  std::size_t nbOfSeries(valuesByColumn.size()), nbCols(columnNames.size());
+  for (std::size_t i = 0; i < nbOfSeries; i++)
+  {
+    for (std::size_t j = 0; j < nbCols; j++)
+    {
+      vtkNew<vtkDoubleArray> arr;
+      std::string name(buildNameOfEntryFrom(columnNames[j], i, nbOfSeries));
+      arr->SetName(name.c_str());
+      arr->SetNumberOfTuples(zeTimes.size());
+      double* pt(arr->GetPointer(0));
+      std::copy(valuesByColumn[i][j].begin(), valuesByColumn[i][j].end(), pt);
+      table->AddColumn(arr);
+    }
+  }
+}
+
+void vtkTemporalOnPoint::vtkInternal::operate(
+  double timeStep, vtkUnstructuredGrid* usgIn, vtkPolyData* source)
+{
+  vtkNew<vtkPolyData> sourceCpy;
+  sourceCpy->DeepCopy(source);
+  vtkDataArray* arr(0);
+  std::size_t nbPts(CheckPts(sourceCpy, arr));
+  if (_Z != std::numeric_limits<double>::max())
+  {
+    vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+    vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+    if (arr1)
+    {
+      double* pt(arr1->GetPointer(0));
+      for (std::size_t i = 0; i < nbPts; i++)
+        pt[3 * i + 2] = _Z;
+    }
+    else
+    {
+      float* pt(arr2->GetPointer(0));
+      for (std::size_t i = 0; i < nbPts; i++)
+        pt[3 * i + 2] = _Z;
+    }
+  }
+  //
+  vtkNew<vtkCompositeDataProbeFilter> probeFilter;
+  probeFilter->SetInputData(sourceCpy);
+  probeFilter->SetSourceData(usgIn);
+  probeFilter->Update();
+  vtkDataObject* res(probeFilter->GetOutput());
+  vtkPolyData* res2(vtkPolyData::SafeDownCast(res));
+  if (!res2)
+  {
+    std::ostringstream oss;
+    oss << "Internal error ! unexpected returned of resample filter !";
+    throw MZCException(oss.str());
+  }
+  pushData(timeStep, res2);
+}
+
+void vtkTemporalOnPoint::vtkInternal::pushData(double timeStep, vtkPolyData* ds)
+{
+  if (!ds)
+    throw MZCException("pushData : no  data !");
+  vtkDataSetAttributes* dsa(ds->GetPointData());
+  if (!dsa)
+    throw MZCException("pushData : no point data !");
+  _time.push_back(timeStep);
+  if (_isInit)
+    pushDataInit(timeStep, dsa);
+  else
+    pushDataStd(timeStep, dsa);
+  _isInit = false;
+}
+
+void vtkTemporalOnPoint::vtkInternal::pushDataInit(double timeStep, vtkDataSetAttributes* dsa)
+{
+  std::size_t nbOfItems(std::numeric_limits<std::size_t>::max());
+  int nba(dsa->GetNumberOfArrays());
+  for (int i = 0; i < nba; i++)
+  {
+    vtkDataArray* arr(dsa->GetArray(i));
+    if (!arr)
+      continue;
+    if (arr->GetNumberOfComponents() != 1)
+      continue;
+    std::size_t tmp(arr->GetNumberOfTuples());
+    if (tmp == 0)
+      continue;
+    if (nbOfItems == std::numeric_limits<std::size_t>::max())
+    {
+      nbOfItems = tmp;
+      _data.resize(nbOfItems);
+    }
+    if (tmp != nbOfItems)
+      continue;
+    const char* name(arr->GetName());
+    if (!name)
+      continue;
+    vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+    vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+    if (!arr1 && !arr2)
+      continue;
+    _columnNames.push_back(name);
+    if (arr1)
+    {
+      const double* pt(arr1->GetPointer(0));
+      for (std::size_t j = 0; j < nbOfItems; j++)
+      {
+        _data[j].resize(_columnNames.size());
+        _data[j][_columnNames.size() - 1].push_back(pt[j]);
+      }
+      continue;
+    }
+    if (arr2)
+    {
+      const float* pt(arr2->GetPointer(0));
+      for (std::size_t j = 0; j < nbOfItems; j++)
+      {
+        _data[j].resize(_columnNames.size());
+        _data[j][_columnNames.size() - 1].push_back(pt[j]);
+      }
+      continue;
+    }
+  }
+}
+
+void vtkTemporalOnPoint::vtkInternal::pushDataStd(double timeStep, vtkDataSetAttributes* dsa)
+{
+  std::set<std::string> cnsRef(_columnNames.begin(), _columnNames.end()), cns;
+  std::size_t nbOfItems(_data.size());
+  int nba(dsa->GetNumberOfArrays());
+  for (int i = 0; i < nba; i++)
+  {
+    vtkDataArray* arr(dsa->GetArray(i));
+    if (!arr)
+      continue;
+    if (arr->GetNumberOfComponents() != 1)
+      continue;
+    if (arr->GetNumberOfTuples() != nbOfItems)
+      continue;
+    const char* name(arr->GetName());
+    if (!name)
+      continue;
+    vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+    vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+    if (!arr1 && !arr2)
+      continue;
+    std::string nameCpp(name);
+    std::vector<std::string>::iterator it(
+      std::find(_columnNames.begin(), _columnNames.end(), nameCpp));
+    if (it == _columnNames.end())
+      continue;
+    std::size_t columnId(std::distance(_columnNames.begin(), it));
+    cns.insert(nameCpp);
+    if (arr1)
+    {
+      const double* pt(arr1->GetPointer(0));
+      for (std::size_t j = 0; j < nbOfItems; j++)
+        _data[j][columnId].push_back(pt[j]);
+      continue;
+    }
+    if (arr2)
+    {
+      const float* pt(arr2->GetPointer(0));
+      for (std::size_t j = 0; j < nbOfItems; j++)
+        _data[j][columnId].push_back(pt[j]);
+      continue;
+    }
+  }
+  if (cnsRef != cns)
+    throw MZCException("Some float arrays are not present along time !");
+}
+
+void vtkTemporalOnPoint::vtkInternal::fillTable(vtkTable* table) const
+{
+  buildTableFrom(table, _data, _time, _columnNames);
+}
+
+std::size_t vtkTemporalOnPoint::vtkInternal::CheckPts(vtkPointSet* usg, vtkDataArray*& arr)
+{
+  if (!usg)
+    throw MZCException("CheckPts : expect an unstucturedgrid !");
+  vtkPoints* pts(usg->GetPoints());
+  if (!pts)
+    throw MZCException("CheckPts : no points in grid !");
+  arr = pts->GetData();
+  if (!arr)
+    throw MZCException("CheckPts : no data in points in grid !");
+  if (arr->GetNumberOfComponents() != 3)
+    throw MZCException("CheckPts : 3D expected !");
+  std::size_t nbPts(arr->GetNumberOfTuples());
+  if (nbPts < 1)
+    throw MZCException("CheckPts : no input point !");
+  vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+  vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+  if (!arr1 && !arr2)
+    throw MZCException("scanCoordsOfDS : for coords expected FLOAT32 or FLOAT64 !");
+  return nbPts;
+}
+
+void vtkTemporalOnPoint::vtkInternal::scanCoordsOfDS(vtkUnstructuredGrid* usg)
+{
+  vtkDataArray* arr(0);
+  std::size_t nbPts(CheckPts(usg, arr));
+  vtkDoubleArray* arr1(vtkDoubleArray::SafeDownCast(arr));
+  vtkFloatArray* arr2(vtkFloatArray::SafeDownCast(arr));
+  if (arr1)
+  {
+    const double* pt(arr1->GetPointer(0));
+    double ref(pt[2]);
+    for (std::size_t i = 1; i < nbPts; i++)
+      if (pt[3 * i + 2] != ref)
+      {
+        _Z = std::numeric_limits<double>::max();
+        return;
+      }
+    _Z = ref;
+  }
+  else
+  {
+    const float* pt(arr2->GetPointer(0));
+    float ref(pt[2]);
+    for (std::size_t i = 1; i < nbPts; i++)
+      if (pt[3 * i + 2] != ref)
+      {
+        _Z = std::numeric_limits<double>::max();
+        return;
+      }
+    _Z = ref;
+  }
+  // std::cerr << "Is 2D ?  " << _Z << std::endl;
+}
+
+int vtkTemporalOnPoint::RequestData(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkTemporalOnPoint::RequestData
+  // ##########################################" << std::endl;
+  try
+  {
+    //
+    if (this->NumberOfTimeSteps == 0)
+    {
+      vtkErrorMacro("No time steps in input data!");
+      return 0;
+    }
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    vtkUnstructuredGrid* usgIn(0);
+    ExtractInfo(inputVector[0], usgIn);
+    // is this the first request
+    if (!this->IsExecuting)
+    {
+      request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
+      this->IsExecuting = true;
+      delete this->Internal;
+      this->Internal = new vtkInternal;
+      this->Internal->scanCoordsOfDS(usgIn);
+    }
+    //
+    // do something
+    {
+      vtkInformation* sourceInfo(inputVector[1]->GetInformationObject(0));
+      vtkDataObject* source(sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
+      vtkPolyData* source2(vtkPolyData::SafeDownCast(source));
+      if (!source2)
+        throw MZCException("vtkPolyData expected as source !");
+      double timeStep;
+      {
+        vtkInformation* inInfo(inputVector[0]->GetInformationObject(0));
+        vtkDataObject* input(vtkDataObject::GetData(inInfo));
+        timeStep = input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP());
+      }
+      this->Internal->operate(timeStep, usgIn, source2);
+    }
+    //
+    this->CurrentTimeIndex++;
+    if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+      vtkInformation* outInfo(outputVector->GetInformationObject(0));
+      vtkTable* output(vtkTable::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      vtkNew<vtkTable> table;
+      this->Internal->fillTable(table);
+      output->ShallowCopy(table);
+    }
+  }
+  catch (MZCException& e)
+  {
+    if (this->IsExecuting)
+    {
+      request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
+      this->CurrentTimeIndex = 0;
+      this->IsExecuting = false;
+    }
+    vtkErrorMacro(<< "Exception has been thrown in vtkTemporalOnPoint::RequestData : " << e.what());
+    return 0;
+  }
+  return 1;
+}
+
+void vtkTemporalOnPoint::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkTemporalOnPoint::SetSourceData(vtkDataObject* input)
+{
+  this->SetInputData(1, input);
+}
+
+void vtkTemporalOnPoint::SetSourceConnection(vtkAlgorithmOutput* algOutput)
+{
+  this->SetInputConnection(1, algOutput);
+}
+
+int vtkTemporalOnPoint::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTable");
+  return 1;
+}
diff --git a/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.h b/src/TemporalOnPoint/plugin/TemporalOnPointModule/vtkTemporalOnPoint.h
new file mode 100644 (file)
index 0000000..2bc68af
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkTemporalOnPoint_h__
+#define vtkTemporalOnPoint_h__
+
+#include <vtkDataObjectAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkTemporalOnPoint : public vtkDataObjectAlgorithm
+{
+public:
+  static vtkTemporalOnPoint* New();
+  vtkTypeMacro(vtkTemporalOnPoint, vtkDataObjectAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  void SetSourceData(vtkDataObject* input);
+
+  void SetSourceConnection(vtkAlgorithmOutput* algOutput);
+
+  int FillOutputPortInformation(int, vtkInformation*) override;
+
+protected:
+  vtkTemporalOnPoint();
+  ~vtkTemporalOnPoint() override;
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestUpdateExtent(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  int NumberOfTimeSteps;
+  bool IsExecuting;
+  int CurrentTimeIndex;
+  class vtkInternal;
+  vtkInternal* Internal;
+
+private:
+  vtkTemporalOnPoint(const vtkTemporalOnPoint&) = delete;
+  void operator=(const vtkTemporalOnPoint&) = delete;
+};
+
+#endif
diff --git a/src/TemporalOnPoint/plugin/filters.xml b/src/TemporalOnPoint/plugin/filters.xml
new file mode 100644 (file)
index 0000000..66b4c74
--- /dev/null
@@ -0,0 +1,106 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="seed_sources">
+    <SourceProxy class="vtkPointSource"
+                 label="Small Point Source"
+                 name="SmallPointSource">
+      <DoubleVectorProperty animateable="1"
+                            command="SetCenter"
+                            default_values="0.0 0.0 0.0"
+                            name="Center"
+                            number_of_elements="3">
+        <BoundsDomain default_mode="mid"
+                      mode="normal"
+                      name="range">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="DummyInput" />
+          </RequiredProperties>
+        </BoundsDomain>
+      </DoubleVectorProperty>
+      <IntVectorProperty animateable="1"
+                         command="SetNumberOfPoints"
+                         default_values="1"
+                         name="NumberOfPoints"
+                         number_of_elements="1">
+        <IntRangeDomain min="1"
+                        name="range" />
+      </IntVectorProperty>
+      <DoubleVectorProperty animateable="1"
+                            command="SetRadius"
+                            default_values="1.0"
+                            name="Radius"
+                            number_of_elements="1">
+        <BoundsDomain mode="scaled_extent"
+                      name="range"
+                      scale_factor="0.001">
+          <RequiredProperties>
+            <Property function="Input"
+                      name="DummyInput" />
+          </RequiredProperties>
+        </BoundsDomain>
+      </DoubleVectorProperty>
+      <InputProperty is_internal="1"
+                     name="DummyInput">
+        <!-- Used when this source is added to a proxy list domain. -->
+      </InputProperty>
+      <PropertyGroup label="Sphere Parameters"
+                     panel_widget="InteractiveSphere">
+        <Property function="Center"
+                  name="Center" />
+        <Property function="Radius"
+                  name="Radius" />
+        <Property function="Input"
+                  name="DummyInput" />
+      </PropertyGroup>
+      <Hints>
+        <ProxyList>
+          <Link name="DummyInput" with_property="Input" />
+        </ProxyList>
+      </Hints>
+      <!-- End PointSource -->
+    </SourceProxy>
+  </ProxyGroup>
+  <ProxyGroup name="filters">
+    <SourceProxy name="TemporalOnPoint"
+                 class="vtkTemporalOnPoint"
+                 label="Temporal On Point">
+     <InputProperty name="Input"
+                    command="SetInputConnection">
+       <ProxyGroupDomain name="groups">
+         <Group name="sources"/>
+         <Group name="filters"/>
+       </ProxyGroupDomain>
+       <DataTypeDomain name="input_type">
+         <DataType value="vtkDataSet"/>
+       </DataTypeDomain>
+       <Documentation>
+         This property specifies the input to the Level Scalars filter.
+       </Documentation>
+     </InputProperty>
+
+     <InputProperty command="SetSourceConnection"
+                     label="Source"
+                     name="Source"
+                     panel_visibility="default">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+        </ProxyGroupDomain>
+       <ProxyListDomain name="proxy_list">
+          <Proxy group="seed_sources"
+                 name="SmallPointSource" />
+        </ProxyListDomain>
+        <Documentation>This property specifies the dataset whose geometry will
+        be used in determining positions to probe.</Documentation>
+     </InputProperty>
+
+     <Hints>
+        <ShowInMenu category="Hydraulics" />
+     </Hints>
+
+     <Hints>
+        <View type="XYChartView" />
+     </Hints>
+
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/TemporalOnPoint/plugin/paraview.plugin b/src/TemporalOnPoint/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..a8b596b
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  TemporalOnPointPlugin
+DESCRIPTION
+  This plugin provides the TemporalOnPoint filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
diff --git a/src/Tools/Clean.py b/src/Tools/Clean.py
new file mode 100644 (file)
index 0000000..85a92b3
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from glob import glob
+import os
+from datetime import datetime
+
+fis=glob("*.txt")+glob("*.cmake")
+fis2=[elt for elt in fis if datetime.fromtimestamp(os.stat(elt).st_mtime) > datetime(2018,1,12,7,33,0)]
+for elt in fis2:
+    print(elt)
+    #os.remove(elt)
+    pass
diff --git a/src/TorseurCIH/CMakeLists.txt b/src/TorseurCIH/CMakeLists.txt
new file mode 100644 (file)
index 0000000..11c2b52
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(TorseurCIH)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/TorseurCIH/Test.py b/src/TorseurCIH/Test.py
new file mode 100644 (file)
index 0000000..dfff8c4
--- /dev/null
@@ -0,0 +1,122 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+import math
+
+def ReturnInertia(p,OM,area_field):
+    base_X = DataArrayDouble(len(OM),3) ; base_X[:]=p
+    dist_to_base_X = (OM-DataArrayDouble.Dot(OM,base_X)*base_X).magnitude()
+    inertia = (dist_to_base_X*dist_to_base_X*area_field).accumulate()[0]
+    return inertia
+
+def fffff(initialVect,normalFace,OM,area_field, posToIterate):
+    li=[]
+    for zePos in posToIterate:
+        p = initialVect.deepCopy()
+        MEDCouplingPointSet.Rotate3DAlg([0,0,0],normalFace.getValues(),zePos/float(180)*math.pi,p)
+        inertia = ReturnInertia(p,OM,area_field)
+        li.append((zePos,p.deepCopy(),inertia))
+    return max(li,key=lambda x:x[2])
+
+def fff(initialVect,normalFace,OM,area_field):
+    pos = fffff(initialVect,normalFace,OM,area_field,[i*float(10) for i in range(18)])[0]
+    for expo in range(5):
+        pos,p,v = fffff(initialVect,normalFace,OM,area_field,[pos+i*(10**-expo) for i in range(-9,10)])
+    return pos,p,v
+    
+fname = "slice.med"
+mm=MEDFileMesh.New(fname)
+m=mm[0]
+f1ts = MEDFileField1TS(fname,"RESUME__SIEF_NOEU")
+f = f1ts.field(mm)
+m = f.getMesh()
+area_field = m.getMeasureField(True)
+area = area_field.accumulate()[0] # 1
+centerOfMassField = m.computeCellCenterOfMass()
+centerOfMass = DataArrayDouble([elt/area for elt in (centerOfMassField*area_field.getArray()).accumulate()],1,3) # 2
+m.unPolyze()
+tri = MEDCoupling1SGTUMesh(m)
+assert(tri.getCellModelEnum()==NORM_TRI3)
+#
+fCell = f.nodeToCellDiscretization()
+(fCell.getArray()[:,[0,1,2]]*area).accumulate()
+ids = area_field.getArray().findIdsLowerThan(1e-7).buildComplement(m.getNumberOfCells())
+#fCell[ids]
+eqn = m[ids].computePlaneEquationOf3DFaces()[:,:3]
+eqn /= eqn.magnitude()
+area_vector = eqn*area_field.getArray()[ids]
+matrix = fCell[ids].getArray()
+#
+F_x = matrix[:,0]*eqn[:,0] + matrix[:,3]*eqn[:,1] + matrix[:,4]*eqn[:,2]
+F_y = matrix[:,3]*eqn[:,0] + matrix[:,1]*eqn[:,1] + matrix[:,5]*eqn[:,2]
+F_z = matrix[:,4]*eqn[:,0] + matrix[:,5]*eqn[:,1] + matrix[:,2]*eqn[:,2]
+#
+F = DataArrayDouble.Meld([F_x,F_y,F_z])
+#
+ZeForce = DataArrayDouble(F.accumulate(),1,3)
+normalFace = DataArrayDouble(eqn.accumulate(),1,3)
+normalFace /= normalFace.magnitude()[0]
+ForceNormale = DataArrayDouble.Dot(ZeForce,normalFace)[0]*normalFace # 3
+TangentForce = ZeForce-ForceNormale # 4
+#
+bary = m[ids].computeCellCenterOfMass()
+OM = bary-centerOfMass
+momentum = DataArrayDouble(DataArrayDouble.CrossProduct(OM,F).accumulate(),1,3) # 5
+# Inertie
+InertiaNormale = (DataArrayDouble.Dot(OM,OM)*area_field.getArray()[ids]).accumulate()[0] # 6_A
+base = DataArrayDouble(DataArrayDouble.GiveBaseForPlane(normalFace),3,3)
+angle, tangentPrincipal, inertiaPrincipal = fff(base[0],normalFace,OM,area_field.getArray()[ids])
+tangentOther = DataArrayDouble.CrossProduct(normalFace,tangentPrincipal)
+inertiaOther = ReturnInertia(tangentOther,OM,area_field.getArray()[ids])
+"""
+base_X = DataArrayDouble(len(ids),3) ; base_X[:]=base[0]
+base_Y = DataArrayDouble(len(ids),3) ; base_Y[:]=base[1]
+dist_to_base_X = (OM-DataArrayDouble.Dot(OM,base_X)*base_X).magnitude()
+dist_to_base_Y = (OM-DataArrayDouble.Dot(OM,base_Y)*base_Y).magnitude()
+inertia_mat_0 = (dist_to_base_Y*dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+inertia_mat_1 = (dist_to_base_X*dist_to_base_X*area_field.getArray()[ids]).accumulate()[0]
+inertia_mat_01 = -(dist_to_base_X*dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+from numpy import linalg as LA
+import numpy as np
+mat = np.matrix([[inertia_mat_0, inertia_mat_01], [inertia_mat_01, inertia_mat_1]])
+v,w = LA.eig(mat)
+pos_of_max = max([(i,elt) for (i,elt) in enumerate(v)],key=lambda x: x[1])[0]
+u0 = DataArrayDouble(np.array(w[:,pos_of_max])) ; u0.rearrange(2)
+v0 = DataArrayDouble(np.array(w[:,1-pos_of_max])) ; v0.rearrange(2)
+#
+I_new_base_0 = v[pos_of_max] # 6_B
+new_base_0 = u0[0,0]*base[0]+u0[0,1]*base[1] # 6_B
+#new_base_1 = v0[0,0]*base[0]+v0[0,1]*base[1]
+new_base_1 = DataArrayDouble.CrossProduct(normalFace,new_base_0)
+new_base_Y = DataArrayDouble(len(ids),3) ; new_base_Y[:]=new_base_1
+new_dist_to_base_Y = (OM-DataArrayDouble.Dot(OM,new_base_Y)*new_base_Y).magnitude()
+I_new_base_1 = (new_dist_to_base_Y*new_dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+"""
+"""
+new_base_X = DataArrayDouble(len(ids),3) ; new_base_X[:]=new_base_0
+new_dist_to_base_X = (OM-DataArrayDouble.Dot(OM,new_base_X)*new_base_X).magnitude()
+I_new_base_0 = (new_dist_to_base_X*new_dist_to_base_X*area_field.getArray()[ids]).accumulate()[0]
+tmp=m[ids] ; tmp.zipCoords()
+f=MEDCouplingFieldDouble(ON_CELLS)
+f.setMesh(tmp)
+f.setArray(new_dist_to_base_X)
+f.setName("dist")
+f.writeVTK("distEig.vtu")"""
+#mat*w[:,0]
diff --git a/src/TorseurCIH/plugin/CMakeLists.txt b/src/TorseurCIH/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0dd36dc
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+CMAKE_POLICY(SET CMP0071 NEW)
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+# Common CMake macros
+# ===================
+SET(TMP_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+SET(MEDCOUPLING_ROOT_DIR $ENV{MEDCOUPLING_ROOT_DIR} CACHE PATH "Path to the MEDCoupling tool")
+IF(EXISTS ${MEDCOUPLING_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${MEDCOUPLING_ROOT_DIR}/cmake_files")
+ENDIF()
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
+LIST(APPEND CMAKE_MODULE_PATH ${TMP_CMAKE_MODULE_PATH})
+
+INCLUDE(SalomeSetupPlatform)
+SET(BUILD_SHARED_LIBS TRUE)
+
+FIND_PACKAGE(SalomeHDF5 REQUIRED)
+FIND_PACKAGE(SalomeMEDCoupling REQUIRED)
+
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}
+                                                 ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON})
+SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS})
+SALOME_ACCUMULATE_ENVIRONMENT(PV_PLUGIN_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/lib/paraview)
+
+paraview_add_plugin(TorseurCIH
+  VERSION "1.0"
+  MODULES TorseurCIHModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/TorseurCIHModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS TorseurCIH
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/TorseurCIH/plugin/TorseurCIHModule/CMakeLists.txt b/src/TorseurCIH/plugin/TorseurCIHModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3b62afe
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+IF(WIN32)
+ADD_COMPILE_DEFINITIONS(_USE_MATH_DEFINES)
+ENDIF(WIN32)
+
+set(classes
+  vtkTorseurCIH
+)
+
+vtk_module_add_module(TorseurCIHModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
+
+target_include_directories(TorseurCIHModule PRIVATE ${MEDCOUPLING_INCLUDE_DIRS})
+
+if(HDF5_IS_PARALLEL)
+  target_link_libraries(TorseurCIHModule PRIVATE ${MEDCoupling_paramedloader})
+else()
+  target_link_libraries(TorseurCIHModule PRIVATE ${MEDCoupling_medloader})
+endif()
diff --git a/src/TorseurCIH/plugin/TorseurCIHModule/vtk.module b/src/TorseurCIH/plugin/TorseurCIHModule/vtk.module
new file mode 100644 (file)
index 0000000..91072d1
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  TorseurCIHModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeneral
+  ParaView::RemotingCore
+  VTK::IOLegacy
+PRIVATE_DEPENDS
+  ParaView::VTKExtensionsMisc
+  ParaView::VTKExtensionsFiltersRendering
+
diff --git a/src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.cxx b/src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.cxx
new file mode 100644 (file)
index 0000000..9ac9f26
--- /dev/null
@@ -0,0 +1,886 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkTorseurCIH.h"
+
+#include <vtkCell.h>
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkIdTypeArray.h>
+#include <vtkIntArray.h>
+#include <vtkPointData.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationDataObjectMetaDataKey.h>
+#include <vtkInformationDoubleVectorKey.h>
+#include <vtkInformationQuadratureSchemeDefinitionVectorKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkLongArray.h>
+#include <vtkMultiBlockDataGroupFilter.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkObjectFactory.h>
+#include <vtkQuadratureSchemeDefinition.h>
+#include <vtkStringArray.h>
+#include <vtkTable.h>
+#include <vtkUnsignedCharArray.h>
+
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGaussCoords.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingUMesh.hxx"
+
+#include <deque>
+#include <map>
+#include <set>
+#include <sstream>
+
+using MEDCoupling::DataArray;
+using MEDCoupling::DataArrayDouble;
+using MEDCoupling::DataArrayInt;
+using MEDCoupling::DataArrayInt64;
+using MEDCoupling::DynamicCastSafe;
+using MEDCoupling::MCAuto;
+using MEDCoupling::MEDCouplingFieldDouble;
+using MEDCoupling::MEDCouplingMesh;
+using MEDCoupling::MEDCouplingUMesh;
+using MEDCoupling::ON_GAUSS_PT;
+
+vtkStandardNewMacro(vtkTorseurCIH);
+///////////////////
+
+std::map<int, int> ComputeMapOfType()
+{
+  std::map<int, int> ret;
+  int nbOfTypesInMC(sizeof(MEDCOUPLING2VTKTYPETRADUCER) / sizeof(int));
+  for (int i = 0; i < nbOfTypesInMC; i++)
+  {
+    int vtkId(MEDCOUPLING2VTKTYPETRADUCER[i]);
+    if (vtkId != -1)
+      ret[vtkId] = i;
+  }
+  return ret;
+}
+
+std::map<int, int> ComputeRevMapOfType()
+{
+  std::map<int, int> ret;
+  int nbOfTypesInMC(sizeof(MEDCOUPLING2VTKTYPETRADUCER) / sizeof(int));
+  for (int i = 0; i < nbOfTypesInMC; i++)
+  {
+    int vtkId(MEDCOUPLING2VTKTYPETRADUCER[i]);
+    if (vtkId != -1)
+      ret[i] = vtkId;
+  }
+  return ret;
+}
+
+///////////////////
+
+void ExtractInfo(vtkInformationVector* inputVector, vtkSmartPointer<vtkUnstructuredGrid>& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input = nullptr;
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or "
+        "ExtractBlocks filter before calling this filter !");
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block "
+                                     "but this single element is NULL !");
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw INTERP_KERNEL::Exception("Input data set is NULL !");
+  usgIn.TakeReference(vtkUnstructuredGrid::SafeDownCast(input));
+  if (!usgIn.Get())
+  {
+    if (!input1)
+    {
+      vtkNew<vtkMultiBlockDataGroupFilter> mb;
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+      mb->AddInputData(input);
+      cd->SetInputConnection(mb->GetOutputPort());
+      cd->SetMergePoints(0);
+      cd->Update();
+      usgIn = cd->GetOutput();
+    }
+    else
+    {
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> filter;
+      filter->SetMergePoints(0);
+      filter->SetInputData(input1);
+      filter->Update();
+      vtkUnstructuredGrid* res(filter->GetOutput());
+      usgIn.TakeReference(res);
+      if (res)
+        res->Register(nullptr);
+    }
+  }
+  else
+    usgIn->Register(nullptr);
+}
+
+DataArrayInt* ConvertVTKArrayToMCArrayInt(vtkDataArray* data)
+{
+  if (!data)
+    throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArrayInt : internal error !");
+  int nbTuples(data->GetNumberOfTuples()), nbComp(data->GetNumberOfComponents());
+  std::size_t nbElts(nbTuples * nbComp);
+  MCAuto<DataArrayInt> ret(DataArrayInt::New());
+  ret->alloc(nbTuples, nbComp);
+  for (int i = 0; i < nbComp; i++)
+  {
+    const char* comp(data->GetComponentName(i));
+    if (comp)
+      ret->setInfoOnComponent(i, comp);
+  }
+  int* ptOut(ret->getPointer());
+  vtkIntArray* d0(vtkIntArray::SafeDownCast(data));
+  if (d0)
+  {
+    const int* pt(d0->GetPointer(0));
+    std::copy(pt, pt + nbElts, ptOut);
+    return ret.retn();
+  }
+  vtkLongArray* d1(vtkLongArray::SafeDownCast(data));
+  if (d1)
+  {
+    const long* pt(d1->GetPointer(0));
+    std::copy(pt, pt + nbElts, ptOut);
+    return ret.retn();
+  }
+  vtkIdTypeArray* d2(vtkIdTypeArray::SafeDownCast(data));
+  if (d2)
+  {
+    const vtkIdType* pt(d2->GetPointer(0));
+    std::copy(pt, pt + nbElts, ptOut);
+    return ret.retn();
+  }
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArrayInt : unrecognized array \"" << typeid(*data).name()
+      << "\" type !";
+  throw INTERP_KERNEL::Exception(oss.str());
+}
+
+DataArrayDouble* ConvertVTKArrayToMCArrayDouble(vtkDataArray* data)
+{
+  if (!data)
+    throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArrayDouble : internal error !");
+  int nbTuples(data->GetNumberOfTuples()), nbComp(data->GetNumberOfComponents());
+  std::size_t nbElts(nbTuples * nbComp);
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+  ret->alloc(nbTuples, nbComp);
+  for (int i = 0; i < nbComp; i++)
+  {
+    const char* comp(data->GetComponentName(i));
+    if (comp)
+      ret->setInfoOnComponent(i, comp);
+  }
+  double* ptOut(ret->getPointer());
+  vtkFloatArray* d0(vtkFloatArray::SafeDownCast(data));
+  if (d0)
+  {
+    const float* pt(d0->GetPointer(0));
+    for (std::size_t i = 0; i < nbElts; i++)
+      ptOut[i] = pt[i];
+    return ret.retn();
+  }
+  vtkDoubleArray* d1(vtkDoubleArray::SafeDownCast(data));
+  if (d1)
+  {
+    const double* pt(d1->GetPointer(0));
+    std::copy(pt, pt + nbElts, ptOut);
+    return ret.retn();
+  }
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << typeid(*data).name()
+      << "\" type !";
+  throw INTERP_KERNEL::Exception(oss.str());
+}
+
+DataArray* ConvertVTKArrayToMCArray(vtkDataArray* data)
+{
+  if (!data)
+    throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArray : internal error !");
+  vtkFloatArray* d0(vtkFloatArray::SafeDownCast(data));
+  vtkDoubleArray* d1(vtkDoubleArray::SafeDownCast(data));
+  if (d0 || d1)
+    return ConvertVTKArrayToMCArrayDouble(data);
+  vtkIntArray* d2(vtkIntArray::SafeDownCast(data));
+  vtkLongArray* d3(vtkLongArray::SafeDownCast(data));
+  if (d2 || d3)
+    return ConvertVTKArrayToMCArrayInt(data);
+  std::ostringstream oss;
+  oss << "ConvertVTKArrayToMCArray : unrecognized array \"" << typeid(*data).name() << "\" type !";
+  throw INTERP_KERNEL::Exception(oss.str());
+}
+
+DataArrayDouble* BuildCoordsFrom(vtkPointSet* ds)
+{
+  if (!ds)
+    throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error !");
+  vtkPoints* pts(ds->GetPoints());
+  if (!pts)
+    throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error 2 !");
+  vtkDataArray* data(pts->GetData());
+  if (!data)
+    throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error 3 !");
+  MCAuto<DataArrayDouble> coords(ConvertVTKArrayToMCArrayDouble(data));
+  return coords.retn();
+}
+
+void ConvertFromUnstructuredGrid(vtkUnstructuredGrid* ds,
+  std::vector<MCAuto<MEDCouplingUMesh> >& ms, std::vector<MCAuto<DataArrayIdType> >& ids)
+{
+  MCAuto<DataArrayDouble> coords(BuildCoordsFrom(ds));
+  vtkIdType nbCells(ds->GetNumberOfCells());
+  vtkUnsignedCharArray* ct(ds->GetCellTypesArray());
+  if (!ct)
+    throw INTERP_KERNEL::Exception("ConvertFromUnstructuredGrid : internal error");
+  const unsigned char* ctPtr(ct->GetPointer(0));
+  std::map<int, int> m(ComputeMapOfType());
+  MCAuto<DataArrayIdType> lev(DataArrayIdType::New());
+  lev->alloc(nbCells, 1);
+  mcIdType* levPtr(lev->getPointer());
+  for (vtkIdType i = 0; i < nbCells; i++)
+  {
+    std::map<int, int>::iterator it(m.find(ctPtr[i]));
+    if (it != m.end())
+    {
+      const INTERP_KERNEL::CellModel& cm(
+        INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)(*it).second));
+      levPtr[i] = cm.getDimension();
+    }
+    else
+    {
+      std::ostringstream oss;
+      oss << "ConvertFromUnstructuredGrid : at pos #" << i
+          << " unrecognized VTK cell with type =" << ctPtr[i];
+      throw INTERP_KERNEL::Exception(oss.str());
+    }
+  }
+  MCAuto<DataArrayIdType> levs(lev->getDifferentValues());
+  vtkIdTypeArray *faces(ds->GetFaces()), *faceLoc(ds->GetFaceLocations());
+  for (const mcIdType* curLev = levs->begin(); curLev != levs->end(); curLev++)
+  {
+    MCAuto<MEDCouplingUMesh> m0(MEDCouplingUMesh::New("", *curLev));
+    m0->setCoords(coords);
+    m0->allocateCells();
+    MCAuto<DataArrayIdType> cellIdsCurLev(lev->findIdsEqual(*curLev));
+    for (const mcIdType* cellId = cellIdsCurLev->begin(); cellId != cellIdsCurLev->end(); cellId++)
+    {
+      std::map<int, int>::iterator it(m.find(ctPtr[*cellId]));
+      vtkIdType sz;
+      vtkIdType const* pts;
+      ds->GetCellPoints(*cellId, sz, pts);
+      INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)(*it).second);
+      if (ct != INTERP_KERNEL::NORM_POLYHED)
+      {
+        std::vector<mcIdType> conn2(sz);
+        for (int kk = 0; kk < sz; kk++)
+          conn2[kk] = pts[kk];
+        m0->insertNextCell(ct, sz, &conn2[0]);
+      }
+      else
+      {
+        if (!faces || !faceLoc)
+          throw INTERP_KERNEL::Exception(
+            "ConvertFromUnstructuredGrid : faces are expected when there are polyhedra !");
+        const vtkIdType *facPtr(faces->GetPointer(0)), *facLocPtr(faceLoc->GetPointer(0));
+        std::vector<mcIdType> conn;
+        int off0(facLocPtr[*cellId]);
+        int nbOfFaces(facPtr[off0++]);
+        for (int k = 0; k < nbOfFaces; k++)
+        {
+          int nbOfNodesInFace(facPtr[off0++]);
+          std::copy(facPtr + off0, facPtr + off0 + nbOfNodesInFace, std::back_inserter(conn));
+          off0 += nbOfNodesInFace;
+          if (k < nbOfFaces - 1)
+            conn.push_back(-1);
+        }
+        m0->insertNextCell(ct, conn.size(), conn.data());
+      }
+    }
+    ms.push_back(m0);
+    ids.push_back(cellIdsCurLev);
+  }
+}
+
+vtkSmartPointer<vtkUnstructuredGrid> ConvertUMeshFromMCToVTK(const MEDCouplingUMesh* mVor)
+{
+  std::map<int, int> zeMapRev(ComputeRevMapOfType());
+  int nbCells(mVor->getNumberOfCells());
+  vtkSmartPointer<vtkUnstructuredGrid> ret(vtkSmartPointer<vtkUnstructuredGrid>::New());
+  ret->Initialize();
+  ret->Allocate();
+  vtkSmartPointer<vtkPoints> points(vtkSmartPointer<vtkPoints>::New());
+  {
+    const DataArrayDouble* vorCoords(mVor->getCoords());
+    vtkSmartPointer<vtkDoubleArray> da(vtkSmartPointer<vtkDoubleArray>::New());
+    da->SetNumberOfComponents(vorCoords->getNumberOfComponents());
+    da->SetNumberOfTuples(vorCoords->getNumberOfTuples());
+    std::copy(vorCoords->begin(), vorCoords->end(), da->GetPointer(0));
+    points->SetData(da);
+  }
+  mVor->checkConsistencyLight();
+  switch (mVor->getMeshDimension())
+  {
+    case 3:
+    {
+      vtkIdType *cPtr(nullptr), *dPtr(nullptr);
+      unsigned char* aPtr(nullptr);
+      vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
+      {
+        cellTypes->SetNumberOfComponents(1);
+        cellTypes->SetNumberOfTuples(nbCells);
+        aPtr = cellTypes->GetPointer(0);
+      }
+      vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        cellLocations->SetNumberOfComponents(1);
+        cellLocations->SetNumberOfTuples(nbCells);
+        cPtr = cellLocations->GetPointer(0);
+      }
+      vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        MCAuto<DataArrayIdType> tmp2(mVor->computeEffectiveNbOfNodesPerCell());
+        cells->SetNumberOfComponents(1);
+        cells->SetNumberOfTuples(tmp2->accumulate((std::size_t)0) + nbCells);
+        dPtr = cells->GetPointer(0);
+      }
+      const mcIdType *connPtr(mVor->getNodalConnectivity()->begin()),
+        *connIPtr(mVor->getNodalConnectivityIndex()->begin());
+      int k(0), kk(0);
+      std::vector<vtkIdType> ee, ff;
+      for (int i = 0; i < nbCells; i++, connIPtr++)
+      {
+        INTERP_KERNEL::NormalizedCellType ct(
+          static_cast<INTERP_KERNEL::NormalizedCellType>(connPtr[connIPtr[0]]));
+        *aPtr++ = zeMapRev[connPtr[connIPtr[0]]];
+        if (ct != INTERP_KERNEL::NORM_POLYHED)
+        {
+          int sz(connIPtr[1] - connIPtr[0] - 1);
+          *dPtr++ = sz;
+          dPtr = std::copy(connPtr + connIPtr[0] + 1, connPtr + connIPtr[1], dPtr);
+          *cPtr++ = k;
+          k += sz + 1;
+          ee.push_back(kk);
+        }
+        else
+        {
+          std::set<mcIdType> s(connPtr + connIPtr[0] + 1, connPtr + connIPtr[1]);
+          s.erase(-1);
+          int nbFace(std::count(connPtr + connIPtr[0] + 1, connPtr + connIPtr[1], -1) + 1);
+          ff.push_back(nbFace);
+          const mcIdType* work(connPtr + connIPtr[0] + 1);
+          for (int j = 0; j < nbFace; j++)
+          {
+            const mcIdType* work2 = std::find(work, connPtr + connIPtr[1], -1);
+            ff.push_back(std::distance(work, work2));
+            ff.insert(ff.end(), work, work2);
+            work = work2 + 1;
+          }
+          *dPtr++ = (int)s.size();
+          dPtr = std::copy(s.begin(), s.end(), dPtr);
+          *cPtr++ = k;
+          k += (int)s.size() + 1;
+          ee.push_back(kk);
+          kk += connIPtr[1] - connIPtr[0] + 1;
+        }
+      }
+      //
+      vtkSmartPointer<vtkIdTypeArray> faceLocations(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        faceLocations->SetNumberOfComponents(1);
+        faceLocations->SetNumberOfTuples(ee.size());
+        std::copy(ee.begin(), ee.end(), faceLocations->GetPointer(0));
+      }
+      vtkSmartPointer<vtkIdTypeArray> faces(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        faces->SetNumberOfComponents(1);
+        faces->SetNumberOfTuples(ff.size());
+        std::copy(ff.begin(), ff.end(), faces->GetPointer(0));
+      }
+      vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
+      cells2->SetCells(nbCells, cells);
+      ret->SetCells(cellTypes, cellLocations, cells2, faceLocations, faces);
+      break;
+    }
+    case 2:
+    {
+      vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
+      {
+        cellTypes->SetNumberOfComponents(1);
+        cellTypes->SetNumberOfTuples(nbCells);
+        unsigned char* ptr(cellTypes->GetPointer(0));
+        std::fill(ptr, ptr + nbCells, zeMapRev[(int)INTERP_KERNEL::NORM_POLYGON]);
+      }
+      vtkIdType *cPtr(nullptr), *dPtr(nullptr);
+      vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        cellLocations->SetNumberOfComponents(1);
+        cellLocations->SetNumberOfTuples(nbCells);
+        cPtr = cellLocations->GetPointer(0);
+      }
+      vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        cells->SetNumberOfComponents(1);
+        cells->SetNumberOfTuples(mVor->getNodalConnectivity()->getNumberOfTuples());
+        dPtr = cells->GetPointer(0);
+      }
+      const mcIdType *connPtr(mVor->getNodalConnectivity()->begin()),
+        *connIPtr(mVor->getNodalConnectivityIndex()->begin());
+      mcIdType k(0);
+      for (mcIdType i = 0; i < nbCells; i++, connIPtr++)
+      {
+        *dPtr++ = connIPtr[1] - connIPtr[0] - 1;
+        dPtr = std::copy(connPtr + connIPtr[0] + 1, connPtr + connIPtr[1], dPtr);
+        *cPtr++ = k;
+        k += connIPtr[1] - connIPtr[0];
+      }
+      vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
+      cells2->SetCells(nbCells, cells);
+      ret->SetCells(cellTypes, cellLocations, cells2);
+      break;
+    }
+    case 1:
+    {
+      vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
+      {
+        cellTypes->SetNumberOfComponents(1);
+        cellTypes->SetNumberOfTuples(nbCells);
+        unsigned char* ptr(cellTypes->GetPointer(0));
+        std::fill(ptr, ptr + nbCells, zeMapRev[(int)INTERP_KERNEL::NORM_SEG2]);
+      }
+      vtkIdType *cPtr(nullptr), *dPtr(nullptr);
+      vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        cellLocations->SetNumberOfComponents(1);
+        cellLocations->SetNumberOfTuples(nbCells);
+        cPtr = cellLocations->GetPointer(0);
+      }
+      vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
+      {
+        cells->SetNumberOfComponents(1);
+        cells->SetNumberOfTuples(mVor->getNodalConnectivity()->getNumberOfTuples());
+        dPtr = cells->GetPointer(0);
+      }
+      const mcIdType *connPtr(mVor->getNodalConnectivity()->begin()),
+        *connIPtr(mVor->getNodalConnectivityIndex()->begin());
+      for (int i = 0; i < nbCells; i++, connIPtr++)
+      {
+        *dPtr++ = 2;
+        dPtr = std::copy(connPtr + connIPtr[0] + 1, connPtr + connIPtr[1], dPtr);
+        *cPtr++ = 3 * i;
+      }
+      vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
+      cells2->SetCells(nbCells, cells);
+      ret->SetCells(cellTypes, cellLocations, cells2);
+      break;
+    }
+    default:
+      throw INTERP_KERNEL::Exception("Not implemented yet !");
+  }
+  ret->SetPoints(points);
+  return ret;
+}
+
+MCAuto<DataArrayDouble> ForceBuilder(const std::vector<std::size_t>& TAB, const DataArrayDouble* matrix, const DataArrayDouble* eqn)
+{
+  MCAuto<DataArrayDouble> tmp0, tmp1, ret;
+  tmp0 = matrix->keepSelectedComponents({ TAB[0] });
+  tmp1 = eqn->keepSelectedComponents({ 0 });
+  MCAuto<DataArrayDouble> p0(DataArrayDouble::Multiply(tmp0, tmp1));
+  tmp0 = matrix->keepSelectedComponents({ TAB[1] });
+  tmp1 = eqn->keepSelectedComponents({ 1 });
+  MCAuto<DataArrayDouble> p1(DataArrayDouble::Multiply(tmp0, tmp1));
+  ret = DataArrayDouble::Add(p0, p1);
+  tmp0 = matrix->keepSelectedComponents({ TAB[2] });
+  tmp1 = eqn->keepSelectedComponents({ 2 });
+  MCAuto<DataArrayDouble> p2(DataArrayDouble::Multiply(tmp0, tmp1));
+  ret = DataArrayDouble::Add(ret, p2);
+  return ret;
+}
+
+double ReturnInertia(
+  const double pOut[3], const DataArrayDouble* OM, const DataArrayDouble* area_field_ids)
+{
+  MCAuto<DataArrayDouble> base_X(DataArrayDouble::New());
+  base_X->alloc(OM->getNumberOfTuples(), 3);
+  base_X->setPartOfValuesSimple1(pOut[0], 0, OM->getNumberOfTuples(), 1, 0, 1, 1);
+  base_X->setPartOfValuesSimple1(pOut[1], 0, OM->getNumberOfTuples(), 1, 1, 2, 1);
+  base_X->setPartOfValuesSimple1(pOut[2], 0, OM->getNumberOfTuples(), 1, 2, 3, 1);
+  MCAuto<DataArrayDouble> dist_to_base_X;
+  {
+    MCAuto<DataArrayDouble> tmp(DataArrayDouble::Dot(OM, base_X));
+    tmp = DataArrayDouble::Multiply(tmp, base_X);
+    tmp = DataArrayDouble::Substract(OM, tmp);
+    dist_to_base_X = tmp->magnitude();
+  }
+  MCAuto<DataArrayDouble> inertiaArr;
+  {
+    MCAuto<DataArrayDouble> tmp(DataArrayDouble::Multiply(dist_to_base_X, dist_to_base_X));
+    inertiaArr = DataArrayDouble::Multiply(tmp, area_field_ids);
+  }
+  double inertiaTmp;
+  inertiaArr->accumulate(&inertiaTmp);
+  return inertiaTmp;
+}
+
+void FindPrincipalAxeInternal(const double startVector[3], const double normalFace[3],
+  const DataArrayDouble* OM, const DataArrayDouble* area_field_ids,
+  const std::vector<double>& posToIterate, double& angleDegree, double outputAxis[3],
+  double& inertia)
+{
+  constexpr double CENTER[3] = { 0, 0, 0 };
+  inertia = -std::numeric_limits<double>::max();
+  for (auto zePos : posToIterate)
+  {
+    double p[3] = { startVector[0], startVector[1], startVector[2] }, pOut[3];
+    DataArrayDouble::Rotate3DAlg(CENTER, normalFace, zePos / 180. * M_PI, 1, p, pOut);
+    double inertiaTmp = ReturnInertia(pOut, OM, area_field_ids);
+    if (inertiaTmp > inertia)
+    {
+      inertia = inertiaTmp;
+      std::copy(pOut, pOut + 3, outputAxis);
+      angleDegree = zePos;
+    }
+  }
+}
+
+void FindPrincipalAxe(const double startVector[3], const double normalFace[3],
+  const DataArrayDouble* OM, const DataArrayDouble* area_field_ids, double& angleDegree,
+  double outputAxis[3], double& inertia)
+{
+  std::vector<double> R(
+    { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170 });
+  FindPrincipalAxeInternal(
+    startVector, normalFace, OM, area_field_ids, R, angleDegree, outputAxis, inertia);
+  for (int i = 0; i < 5; ++i)
+  {
+    std::vector<double> Q({ -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+    const double CST(std::pow((double)10., (double)-i));
+    std::for_each(Q.begin(), Q.end(), [angleDegree, CST](double& v) { v = CST * v + angleDegree; });
+    FindPrincipalAxeInternal(
+      startVector, normalFace, OM, area_field_ids, Q, angleDegree, outputAxis, inertia);
+  }
+}
+
+vtkSmartPointer<vtkTable> ComputeTorseurCIH(vtkUnstructuredGrid* usgIn)
+{
+  std::vector<MCAuto<MEDCouplingUMesh> > m;
+  {
+    std::vector<MCAuto<DataArrayIdType> > ids;
+    ConvertFromUnstructuredGrid(usgIn, m, ids);
+  }
+  vtkDataArray* sief(nullptr);
+  {
+    int nArrays(usgIn->GetPointData()->GetNumberOfArrays());
+    for (int i = 0; i < nArrays; i++)
+    {
+      vtkDataArray* array(usgIn->GetPointData()->GetArray(i));
+      if (!array)
+        continue;
+      std::string name(array->GetName());
+      if (name.find("SIEF") != std::string::npos)
+        if (array->GetNumberOfComponents() == 6)
+        {
+          if (sief)
+          {
+            std::ostringstream oss;
+            oss << "ComputeTorseurCIH : several candidates for SIEF field !";
+            throw INTERP_KERNEL::Exception(oss.str());
+          }
+          sief = array;
+        }
+    }
+  }
+  if (!sief)
+    throw INTERP_KERNEL::Exception("ComputeTorseurCIH : unable to find a field for SIEF!");
+  MCAuto<MEDCouplingFieldDouble> area_field(m[0]->getMeasureField(true));
+  double area;
+  area_field->accumulate(&area); // 1
+  MCAuto<DataArrayDouble> centerOfMassField(m[0]->computeCellCenterOfMass());
+  double centerOfMass[3];
+  {
+    MCAuto<DataArrayDouble> tmp(
+      DataArrayDouble::Multiply(centerOfMassField, area_field->getArray()));
+    tmp->accumulate(centerOfMass);
+    std::for_each(centerOfMass, centerOfMass + 3, [area](double& v) { v /= area; });
+  } // 2
+  m[0]->unPolyze();
+  std::set<INTERP_KERNEL::NormalizedCellType> s(m[0]->getAllGeoTypes());
+  if (s.size() != 1)
+  {
+    std::ostringstream oss;
+    oss << "ComputeTorseurCIH : Only TRI3 are supported !";
+    throw INTERP_KERNEL::Exception(oss.str());
+  }
+  if (*(s.begin()) != INTERP_KERNEL::NORM_TRI3)
+  {
+    std::ostringstream oss;
+    oss << "ComputeTorseurCIH : Only TRI3 are supported !";
+    throw INTERP_KERNEL::Exception(oss.str());
+  }
+  MCAuto<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(MEDCoupling::ON_NODES));
+  {
+    f->setMesh(m[0]);
+    MCAuto<DataArrayDouble> tmp(ConvertVTKArrayToMCArrayDouble(sief));
+    f->setArray(tmp);
+  }
+  MCAuto<MEDCouplingFieldDouble> fCell(f->nodeToCellDiscretization());
+  MCAuto<DataArrayIdType> ids;
+  {
+    MCAuto<DataArrayIdType> tmp(area_field->getArray()->findIdsLowerThan(1e-7));
+    ids = tmp->buildComplement(m[0]->getNumberOfCells());
+  }
+  MCAuto<MEDCouplingUMesh> m_ids(m[0]->buildPartOfMySelf(ids->begin(), ids->end()));
+  MCAuto<DataArrayDouble> eqn;
+  {
+    MCAuto<DataArrayDouble> tmp(m_ids->computePlaneEquationOf3DFaces());
+    eqn = tmp->keepSelectedComponents({ 0, 1, 2 });
+    tmp = eqn->magnitude();
+    eqn = DataArrayDouble::Divide(eqn, tmp);
+  }
+  MCAuto<DataArrayDouble> area_field_ids(
+    area_field->getArray()->selectByTupleId(ids->begin(), ids->end()));
+  MCAuto<DataArrayDouble> area_vector(DataArrayDouble::Multiply(eqn, area_field_ids));
+  MCAuto<DataArrayDouble> matrix(fCell->getArray()->selectByTupleId(ids->begin(), ids->end()));
+  MCAuto<DataArrayDouble> F_x, F_y, F_z;
+  {
+    F_x = ForceBuilder({ 0, 3, 4 }, matrix, eqn);
+    F_y = ForceBuilder({ 3, 1, 5 }, matrix, eqn);
+    F_z = ForceBuilder({ 4, 5, 2 }, matrix, eqn);
+  }
+  MCAuto<DataArrayDouble> F(DataArrayDouble::Meld({ F_x, F_y, F_z }));
+  double ZeForce[3], normalFace[3];
+  F->accumulate(ZeForce);
+  eqn->accumulate(normalFace);
+  {
+    double normalFaceNorm(sqrt(normalFace[0] * normalFace[0] + normalFace[1] * normalFace[1] +
+      normalFace[2] * normalFace[2]));
+    std::for_each(normalFace, normalFace + 3, [normalFaceNorm](double& v) { v /= normalFaceNorm; });
+  }
+  double ForceNormale[3]; // 3
+  {
+    double tmp(
+      ZeForce[0] * normalFace[0] + ZeForce[1] * normalFace[1] + ZeForce[2] * normalFace[2]);
+    ForceNormale[0] = tmp * normalFace[0];
+    ForceNormale[1] = tmp * normalFace[1];
+    ForceNormale[2] = tmp * normalFace[2];
+  }
+  double TangentForce[3] = { ZeForce[0] - ForceNormale[0], ZeForce[1] - ForceNormale[1],
+    ZeForce[2] - ForceNormale[2] }; // 4
+  MCAuto<DataArrayDouble> bary(m_ids->computeCellCenterOfMass());
+  MCAuto<DataArrayDouble> OM;
+  {
+    MCAuto<DataArrayDouble> centerOfMass2(DataArrayDouble::New());
+    centerOfMass2->alloc(1, 3);
+    std::copy(centerOfMass, centerOfMass + 3, centerOfMass2->getPointer());
+    OM = DataArrayDouble::Substract(bary, centerOfMass2);
+  }
+  double momentum[3]; // 5
+  {
+    MCAuto<DataArrayDouble> tmp(DataArrayDouble::CrossProduct(OM, F));
+    tmp->accumulate(momentum);
+  }
+  double InertiaNormale(ReturnInertia(normalFace, OM, area_field_ids)); // 6
+  double base[9];
+  DataArrayDouble::GiveBaseForPlane(normalFace, base);
+  double angleDegree, outputAxis[3], inertia;
+  FindPrincipalAxe(base, normalFace, OM, area_field_ids, angleDegree, outputAxis, inertia);
+  double tangentOther[3] = { normalFace[1] * outputAxis[2] - normalFace[2] * outputAxis[1],
+    normalFace[2] * outputAxis[0] - normalFace[0] * outputAxis[2],
+    normalFace[0] * outputAxis[1] - normalFace[1] * outputAxis[0] };
+  double inertiaOther(ReturnInertia(tangentOther, OM, area_field_ids));
+  vtkSmartPointer<vtkTable> ret(vtkSmartPointer<vtkTable>::New());
+  vtkSmartPointer<vtkStringArray> col0(vtkSmartPointer<vtkStringArray>::New());
+  constexpr int NB_ROWS = 11;
+  col0->SetNumberOfComponents(1);
+  col0->SetNumberOfTuples(NB_ROWS);
+  col0->SetName("Grandeur");
+  // scalaire
+  col0->SetValue(0, strdup("Aire"));
+  col0->SetValue(1, strdup("Inertie Normal"));
+  col0->SetValue(2, strdup("Inertie Tangentielle principale"));
+  col0->SetValue(3, strdup("Inertie Tangentielle secondaire"));
+  // vectoriel
+  col0->SetValue(4, strdup("Position du centre de gravite"));
+  col0->SetValue(5, strdup("Effort Normal"));
+  col0->SetValue(6, strdup("Effort Tangentiel"));
+  col0->SetValue(7, strdup("Axe Normal"));
+  col0->SetValue(8, strdup("Axe Tangentiel principal"));
+  col0->SetValue(9, strdup("Axe Tangentiel secondaire"));
+  col0->SetValue(10, strdup("Moment au centre de gravite"));
+  ret->AddColumn(col0);
+  //
+  vtkSmartPointer<vtkDoubleArray> col1(vtkSmartPointer<vtkDoubleArray>::New());
+  col1->SetName("X");
+  col1->SetNumberOfComponents(1);
+  col1->SetNumberOfTuples(NB_ROWS);
+  col1->SetValue(0, area);
+  col1->SetValue(1, InertiaNormale);
+  col1->SetValue(2, inertia);
+  col1->SetValue(3, inertiaOther);
+  col1->SetValue(4, centerOfMass[0]);
+  col1->SetValue(5, ForceNormale[0]);
+  col1->SetValue(6, TangentForce[0]);
+  col1->SetValue(7, normalFace[0]);
+  col1->SetValue(8, outputAxis[0]);
+  col1->SetValue(9, tangentOther[0]);
+  col1->SetValue(10, momentum[0]);
+  ret->AddColumn(col1);
+  //
+  vtkSmartPointer<vtkDoubleArray> col2(vtkSmartPointer<vtkDoubleArray>::New());
+  col2->SetName("Y");
+  col2->SetNumberOfComponents(1);
+  col2->SetNumberOfTuples(NB_ROWS);
+  col2->SetValue(0, 0.);
+  col2->SetValue(1, 0.);
+  col2->SetValue(2, 0.);
+  col2->SetValue(3, 0.);
+  col2->SetValue(4, centerOfMass[1]);
+  col2->SetValue(5, ForceNormale[1]);
+  col2->SetValue(6, TangentForce[1]);
+  col2->SetValue(7, normalFace[1]);
+  col2->SetValue(8, outputAxis[1]);
+  col2->SetValue(9, tangentOther[1]);
+  col2->SetValue(10, momentum[1]);
+  ret->AddColumn(col2);
+  //
+  vtkSmartPointer<vtkDoubleArray> col3(vtkSmartPointer<vtkDoubleArray>::New());
+  col3->SetName("Z");
+  col3->SetNumberOfComponents(1);
+  col3->SetNumberOfTuples(NB_ROWS);
+  col3->SetValue(0, 0.);
+  col3->SetValue(1, 0.);
+  col3->SetValue(2, 0.);
+  col3->SetValue(3, 0.);
+  col3->SetValue(4, centerOfMass[2]);
+  col3->SetValue(5, ForceNormale[2]);
+  col3->SetValue(6, TangentForce[2]);
+  col3->SetValue(7, normalFace[2]);
+  col3->SetValue(8, outputAxis[2]);
+  col3->SetValue(9, tangentOther[2]);
+  col3->SetValue(10, momentum[2]);
+  ret->AddColumn(col3);
+  return ret;
+}
+
+////////////////////
+
+int vtkTorseurCIH::FillOutputPortInformation(int vtkNotUsed(port), vtkInformation* info)
+{
+  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTable");
+  return 1;
+}
+
+int vtkTorseurCIH::RequestInformation(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkTorseurCIH::RequestInformation
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkSmartPointer<vtkUnstructuredGrid> usgIn;
+    ExtractInfo(inputVector[0], usgIn);
+  }
+  catch (INTERP_KERNEL::Exception& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkTorseurCIH::RequestInformation : " << e.what()
+        << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+int vtkTorseurCIH::RequestData(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkTorseurCIH::RequestData
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkSmartPointer<vtkUnstructuredGrid> usgIn;
+    ExtractInfo(inputVector[0], usgIn);
+    //
+    vtkSmartPointer<vtkTable> ret(ComputeTorseurCIH(usgIn));
+    vtkInformation* inInfo(inputVector[0]->GetInformationObject(0));
+    vtkInformation* outInfo(outputVector->GetInformationObject(0));
+    vtkTable* output(vtkTable::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    output->ShallowCopy(ret);
+  }
+  catch (INTERP_KERNEL::Exception& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkTorseurCIH::RequestData : " << e.what() << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void vtkTorseurCIH::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.h b/src/TorseurCIH/plugin/TorseurCIHModule/vtkTorseurCIH.h
new file mode 100644 (file)
index 0000000..c6b5a97
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkTorseurCIH_h__
+#define vtkTorseurCIH_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+class vtkMutableDirectedGraph;
+
+class VTK_EXPORT vtkTorseurCIH : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkTorseurCIH* New();
+  vtkTypeMacro(vtkTorseurCIH, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  int FillOutputPortInformation(int port, vtkInformation* info) override;
+
+protected:
+  vtkTorseurCIH() = default;
+  ~vtkTorseurCIH() override = default;
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+private:
+  vtkTorseurCIH(const vtkTorseurCIH&) = delete;
+  void operator=(const vtkTorseurCIH&) = delete;
+};
+
+#endif
diff --git a/src/TorseurCIH/plugin/filters.xml b/src/TorseurCIH/plugin/filters.xml
new file mode 100644 (file)
index 0000000..4d26596
--- /dev/null
@@ -0,0 +1,24 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="TorseurCIH"
+                 class="vtkTorseurCIH"
+                 label="Torseur CIH">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+          This property specifies the input to the Level Scalars filter.
+        </Documentation>
+      </InputProperty>
+      <Hints>
+        <ShowInMenu category="Mechanics" />
+      </Hints>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/TorseurCIH/plugin/paraview.plugin b/src/TorseurCIH/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..23769d7
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  TorseurCIH
+DESCRIPTION
+  This plugin provides the TorseurCIH filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  VTK::FiltersGeneral
diff --git a/src/TorseurCIH/script/Test.py b/src/TorseurCIH/script/Test.py
new file mode 100644 (file)
index 0000000..dfff8c4
--- /dev/null
@@ -0,0 +1,122 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from medcoupling import *
+import math
+
+def ReturnInertia(p,OM,area_field):
+    base_X = DataArrayDouble(len(OM),3) ; base_X[:]=p
+    dist_to_base_X = (OM-DataArrayDouble.Dot(OM,base_X)*base_X).magnitude()
+    inertia = (dist_to_base_X*dist_to_base_X*area_field).accumulate()[0]
+    return inertia
+
+def fffff(initialVect,normalFace,OM,area_field, posToIterate):
+    li=[]
+    for zePos in posToIterate:
+        p = initialVect.deepCopy()
+        MEDCouplingPointSet.Rotate3DAlg([0,0,0],normalFace.getValues(),zePos/float(180)*math.pi,p)
+        inertia = ReturnInertia(p,OM,area_field)
+        li.append((zePos,p.deepCopy(),inertia))
+    return max(li,key=lambda x:x[2])
+
+def fff(initialVect,normalFace,OM,area_field):
+    pos = fffff(initialVect,normalFace,OM,area_field,[i*float(10) for i in range(18)])[0]
+    for expo in range(5):
+        pos,p,v = fffff(initialVect,normalFace,OM,area_field,[pos+i*(10**-expo) for i in range(-9,10)])
+    return pos,p,v
+    
+fname = "slice.med"
+mm=MEDFileMesh.New(fname)
+m=mm[0]
+f1ts = MEDFileField1TS(fname,"RESUME__SIEF_NOEU")
+f = f1ts.field(mm)
+m = f.getMesh()
+area_field = m.getMeasureField(True)
+area = area_field.accumulate()[0] # 1
+centerOfMassField = m.computeCellCenterOfMass()
+centerOfMass = DataArrayDouble([elt/area for elt in (centerOfMassField*area_field.getArray()).accumulate()],1,3) # 2
+m.unPolyze()
+tri = MEDCoupling1SGTUMesh(m)
+assert(tri.getCellModelEnum()==NORM_TRI3)
+#
+fCell = f.nodeToCellDiscretization()
+(fCell.getArray()[:,[0,1,2]]*area).accumulate()
+ids = area_field.getArray().findIdsLowerThan(1e-7).buildComplement(m.getNumberOfCells())
+#fCell[ids]
+eqn = m[ids].computePlaneEquationOf3DFaces()[:,:3]
+eqn /= eqn.magnitude()
+area_vector = eqn*area_field.getArray()[ids]
+matrix = fCell[ids].getArray()
+#
+F_x = matrix[:,0]*eqn[:,0] + matrix[:,3]*eqn[:,1] + matrix[:,4]*eqn[:,2]
+F_y = matrix[:,3]*eqn[:,0] + matrix[:,1]*eqn[:,1] + matrix[:,5]*eqn[:,2]
+F_z = matrix[:,4]*eqn[:,0] + matrix[:,5]*eqn[:,1] + matrix[:,2]*eqn[:,2]
+#
+F = DataArrayDouble.Meld([F_x,F_y,F_z])
+#
+ZeForce = DataArrayDouble(F.accumulate(),1,3)
+normalFace = DataArrayDouble(eqn.accumulate(),1,3)
+normalFace /= normalFace.magnitude()[0]
+ForceNormale = DataArrayDouble.Dot(ZeForce,normalFace)[0]*normalFace # 3
+TangentForce = ZeForce-ForceNormale # 4
+#
+bary = m[ids].computeCellCenterOfMass()
+OM = bary-centerOfMass
+momentum = DataArrayDouble(DataArrayDouble.CrossProduct(OM,F).accumulate(),1,3) # 5
+# Inertie
+InertiaNormale = (DataArrayDouble.Dot(OM,OM)*area_field.getArray()[ids]).accumulate()[0] # 6_A
+base = DataArrayDouble(DataArrayDouble.GiveBaseForPlane(normalFace),3,3)
+angle, tangentPrincipal, inertiaPrincipal = fff(base[0],normalFace,OM,area_field.getArray()[ids])
+tangentOther = DataArrayDouble.CrossProduct(normalFace,tangentPrincipal)
+inertiaOther = ReturnInertia(tangentOther,OM,area_field.getArray()[ids])
+"""
+base_X = DataArrayDouble(len(ids),3) ; base_X[:]=base[0]
+base_Y = DataArrayDouble(len(ids),3) ; base_Y[:]=base[1]
+dist_to_base_X = (OM-DataArrayDouble.Dot(OM,base_X)*base_X).magnitude()
+dist_to_base_Y = (OM-DataArrayDouble.Dot(OM,base_Y)*base_Y).magnitude()
+inertia_mat_0 = (dist_to_base_Y*dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+inertia_mat_1 = (dist_to_base_X*dist_to_base_X*area_field.getArray()[ids]).accumulate()[0]
+inertia_mat_01 = -(dist_to_base_X*dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+from numpy import linalg as LA
+import numpy as np
+mat = np.matrix([[inertia_mat_0, inertia_mat_01], [inertia_mat_01, inertia_mat_1]])
+v,w = LA.eig(mat)
+pos_of_max = max([(i,elt) for (i,elt) in enumerate(v)],key=lambda x: x[1])[0]
+u0 = DataArrayDouble(np.array(w[:,pos_of_max])) ; u0.rearrange(2)
+v0 = DataArrayDouble(np.array(w[:,1-pos_of_max])) ; v0.rearrange(2)
+#
+I_new_base_0 = v[pos_of_max] # 6_B
+new_base_0 = u0[0,0]*base[0]+u0[0,1]*base[1] # 6_B
+#new_base_1 = v0[0,0]*base[0]+v0[0,1]*base[1]
+new_base_1 = DataArrayDouble.CrossProduct(normalFace,new_base_0)
+new_base_Y = DataArrayDouble(len(ids),3) ; new_base_Y[:]=new_base_1
+new_dist_to_base_Y = (OM-DataArrayDouble.Dot(OM,new_base_Y)*new_base_Y).magnitude()
+I_new_base_1 = (new_dist_to_base_Y*new_dist_to_base_Y*area_field.getArray()[ids]).accumulate()[0]
+"""
+"""
+new_base_X = DataArrayDouble(len(ids),3) ; new_base_X[:]=new_base_0
+new_dist_to_base_X = (OM-DataArrayDouble.Dot(OM,new_base_X)*new_base_X).magnitude()
+I_new_base_0 = (new_dist_to_base_X*new_dist_to_base_X*area_field.getArray()[ids]).accumulate()[0]
+tmp=m[ids] ; tmp.zipCoords()
+f=MEDCouplingFieldDouble(ON_CELLS)
+f.setMesh(tmp)
+f.setArray(new_dist_to_base_X)
+f.setName("dist")
+f.writeVTK("distEig.vtu")"""
+#mat*w[:,0]
diff --git a/src/TorseurCIH/script/slice.med b/src/TorseurCIH/script/slice.med
new file mode 100644 (file)
index 0000000..167c676
Binary files /dev/null and b/src/TorseurCIH/script/slice.med differ
diff --git a/src/TorseurCIH/slice.med b/src/TorseurCIH/slice.med
new file mode 100644 (file)
index 0000000..167c676
Binary files /dev/null and b/src/TorseurCIH/slice.med differ
diff --git a/src/View/CMakeLists.txt b/src/View/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d34cbcb
--- /dev/null
@@ -0,0 +1,73 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.12)
+
+INCLUDE(UseQtExt)
+
+# create a plugin with a custom view that shows up in ParaView's multi-view
+# manager.  this plugin also contains a custom display panel
+
+# moc the Qt based .h files
+QT_WRAP_MOC(MOC_SRCS MyView.h MyDisplay.h MyViewActiveOptions.h MyViewOptions.h)
+
+# invoke macro to create sources for our custom view and display panel
+ADD_PARAVIEW_VIEW_MODULE(
+                         # returns the interfaces defined (pass in
+                         # GUI_INTERFACES parameter)
+                         IFACES  
+                         # returns a list of source files for this interface
+                         IFACE_SRCS 
+                         # give the view type 
+                         # With MyView.h implementing a
+                         # pqGenericViewModule and MyView being the XML name
+                         # for the view on the server side
+                         VIEW_TYPE MyView 
+                         # the XML group of the view in the server manager xml
+                         VIEW_XML_GROUP views
+                         # the XML name of the display for this view
+                         DISPLAY_XML MyDisplay 
+                         # the name of the display panel for this display
+                         # With MyDisplay.h implementing pqDisplayPanel
+                         DISPLAY_PANEL MyDisplay)
+
+
+ADD_PARAVIEW_VIEW_OPTIONS(OPTIONS_IFACE OPTIONS_IFACE_SRCS
+                          VIEW_TYPE MyView ACTIVE_VIEW_OPTIONS MyViewActiveOptions)
+
+# create a GUI side plugin with the GUI side code
+#ADD_PARAVIEW_PLUGIN(GUISampleView "1.0" GUI_INTERFACES ${IFACES} ${OPTIONS_IFACE}
+#                    GUI_SOURCES MyView.cxx MyDisplay.cxx MyViewActiveOptions.cxx MyViewOptions.cxx
+#                    ${MOC_SRCS} ${IFACE_SRCS} ${OPTIONS_IFACE_SRCS})
+
+# create a server side plugin with the server side code
+#ADD_PARAVIEW_PLUGIN(SMSampleView "1.0" SERVER_MANAGER_XML MyViewSM.xml)
+
+  ADD_PARAVIEW_PLUGIN(GUISampleView "1.0"
+    SERVER_MANAGER_XML MyViewSM.xml
+    GUI_INTERFACES ${IFACES} ${OPTIONS_IFACE}
+    GUI_SOURCES MyView.cxx MyDisplay.cxx MyViewActiveOptions.cxx MyViewOptions.cxx
+    ${MOC_SRCS} ${IFACE_SRCS} ${OPTIONS_IFACE_SRCS} )
+# one could combine the two plugins into one if desired
+
+INSTALL(TARGETS GUISampleView
+       DESTINATION lib/paraview
+       LIBRARY DESTINATION lib/paraview
+       ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/View/MyDisplay.cxx b/src/View/MyDisplay.cxx
new file mode 100644 (file)
index 0000000..77b6318
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MyDisplay.h"
+
+#include <QVBoxLayout>
+#include <QLabel>
+
+MyDisplay::MyDisplay(pqRepresentation* d, QWidget* p)
+  : pqDisplayPanel(d,p)
+{
+  // just make a label that shows we made it in the GUI
+  QVBoxLayout* l = new QVBoxLayout(this);
+  l->addWidget(new QLabel("From Plugin", this));
+}
+
+MyDisplay::~MyDisplay()
+{
+}
+
diff --git a/src/View/MyDisplay.h b/src/View/MyDisplay.h
new file mode 100644 (file)
index 0000000..04ea437
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef MyDisplay_h
+#define MyDisplay_h
+
+#include "pqDisplayPanel.h"
+
+/// a simple display panel widget
+class MyDisplay : public pqDisplayPanel
+{
+  Q_OBJECT
+public:
+
+    /// constructor
+  MyDisplay(pqRepresentation* display, QWidget* p = NULL);
+  ~MyDisplay();
+
+};
+
+#endif // MyDisplay_h
+
diff --git a/src/View/MyView.cxx b/src/View/MyView.cxx
new file mode 100644 (file)
index 0000000..2fa721e
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "MyView.h"
+
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QWidget>
+#include <vtkSMProxy.h>
+
+#include <pqOutputPort.h>
+#include <pqPipelineSource.h>
+#include <pqRepresentation.h>
+#include <pqServer.h>
+
+MyView::MyView(const QString& viewmoduletype, 
+       const QString& group, 
+       const QString& name, 
+       vtkSMViewProxy* viewmodule, 
+       pqServer* server, 
+       QObject* p)
+ : pqView(viewmoduletype, group, name, viewmodule, server, p)
+{
+  // our view is just a simple QWidget
+  this->MyWidget = new QWidget;
+  this->MyWidget->setAutoFillBackground(true);
+  new QVBoxLayout(this->MyWidget);
+
+  // connect to display creation so we can show them in our view
+  this->connect(this, SIGNAL(representationAdded(pqRepresentation*)),
+    SLOT(onRepresentationAdded(pqRepresentation*)));
+  this->connect(this, SIGNAL(representationRemoved(pqRepresentation*)),
+    SLOT(onRepresentationRemoved(pqRepresentation*)));
+}
+
+MyView::~MyView()
+{
+  delete this->MyWidget;
+}
+
+
+QWidget* MyView::getWidget()
+{
+  return this->MyWidget;
+}
+
+void MyView::onRepresentationAdded(pqRepresentation* d)
+{
+  // add a label with the display id
+  QLabel* l = new QLabel(
+    QString("Display (%1)").arg(d->getProxy()->GetSelfIDAsString()), 
+    this->MyWidget);
+  this->MyWidget->layout()->addWidget(l);
+  this->Labels.insert(d, l);
+}
+
+void MyView::onRepresentationRemoved(pqRepresentation* d)
+{
+  // remove the label
+  QLabel* l = this->Labels.take(d);
+  if(l)
+    {
+    this->MyWidget->layout()->removeWidget(l);
+    delete l;
+    }
+}
+
+void MyView::setBackground(const QColor& c)
+{
+  QPalette p = this->MyWidget->palette();
+  p.setColor(QPalette::Window, c);
+  this->MyWidget->setPalette(p);
+}
+
+QColor MyView::background() const
+{
+  return this->MyWidget->palette().color(QPalette::Window);
+}
+
+bool MyView::canDisplay(pqOutputPort* opPort) const
+{
+  pqPipelineSource* source = opPort? opPort->getSource() : 0;
+  // check valid source and server connections
+  if(!source ||
+     this->getServer()->GetConnectionID() !=
+     source->getServer()->GetConnectionID())
+    {
+    return false;
+    }
+
+  // we can show MyExtractEdges as defined in the server manager xml
+  if(QString("MyExtractEdges") == source->getProxy()->GetXMLName())
+    {
+    return true;
+    }
+
+  return false;
+}
+
+
diff --git a/src/View/MyView.h b/src/View/MyView.h
new file mode 100644 (file)
index 0000000..d2b8b96
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _MyView_h
+#define _MyView_h
+
+#include "pqView.h"
+#include <QMap>
+#include <QColor>
+class QLabel;
+
+/// a simple view that shows a QLabel with the display's name in the view
+class MyView : public pqView
+{
+  Q_OBJECT
+public:
+    /// constructor takes a bunch of init stuff and must have this signature to 
+    /// satisfy pqView
+  MyView(const QString& viewtypemodule, 
+         const QString& group, 
+         const QString& name, 
+         vtkSMViewProxy* viewmodule, 
+         pqServer* server, 
+         QObject* p);
+  ~MyView();
+
+  /// don't support save images
+  bool saveImage(int, int, const QString& ) { return false; }
+  vtkImageData* captureImage(int) { return NULL; }
+  vtkImageData* captureImage(const QSize&) { return NULL; }
+
+  /// return the QWidget to give to ParaView's view manager
+  QWidget* getWidget();
+
+  /// returns whether this view can display the given source
+  bool canDisplay(pqOutputPort* opPort) const;
+
+  /// set the background color of this view
+  void setBackground(const QColor& col);
+  QColor background() const;
+
+protected slots:
+  /// helper slots to create labels
+  void onRepresentationAdded(pqRepresentation*);
+  void onRepresentationRemoved(pqRepresentation*);
+
+protected:
+
+  QWidget* MyWidget;
+  QMap<pqRepresentation*, QLabel*> Labels;
+
+};
+
+#endif // _MyView_h
+
diff --git a/src/View/MyViewActiveOptions.cxx b/src/View/MyViewActiveOptions.cxx
new file mode 100755 (executable)
index 0000000..1e8b6aa
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2. 
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+
+#include "MyViewActiveOptions.h"
+
+#include "MyViewOptions.h"
+
+#include "pqOptionsDialog.h"
+
+MyViewActiveOptions::MyViewActiveOptions(QObject *parentObject)
+  : pqActiveViewOptions(parentObject)
+{
+}
+
+MyViewActiveOptions::~MyViewActiveOptions()
+{
+}
+
+void MyViewActiveOptions::showOptions(pqView *view, const QString &page,
+    QWidget *widgetParent)
+{
+  if(!this->Dialog)
+    {
+    this->Dialog = new pqOptionsDialog(widgetParent);
+    this->Dialog->setApplyNeeded(true);
+    this->Dialog->setObjectName("ActiveMyViewOptions");
+    this->Dialog->setWindowTitle("My View Options");
+    this->Options = new MyViewOptions;
+    this->Dialog->addOptions(this->Options);
+    if(page.isEmpty())
+      {
+      QStringList pages = this->Options->getPageList();
+      if(pages.size())
+        {
+        this->Dialog->setCurrentPage(pages[0]);
+        }
+      }
+    else
+      {
+      this->Dialog->setCurrentPage(page);
+      }
+    
+    this->connect(this->Dialog, SIGNAL(finished(int)),
+        this, SLOT(finishDialog()));
+    }
+
+  this->changeView(view);
+  this->Dialog->show();
+}
+
+void MyViewActiveOptions::changeView(pqView *view)
+{
+  this->Options->setView(view);
+}
+
+void MyViewActiveOptions::closeOptions()
+{
+  if(this->Dialog)
+    {
+    this->Dialog->accept();
+    }
+}
+
+void MyViewActiveOptions::finishDialog()
+{
+  emit this->optionsClosed(this);
+}
+
+
diff --git a/src/View/MyViewActiveOptions.h b/src/View/MyViewActiveOptions.h
new file mode 100755 (executable)
index 0000000..f79dfba
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2. 
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+
+#ifndef _MyViewActiveOptions_h
+#define _MyViewActiveOptions_h
+
+
+#include "pqActiveViewOptions.h"
+#include <QPointer>
+class pqOptionsDialog;
+class MyViewOptions;
+
+class MyViewActiveOptions : public pqActiveViewOptions
+{
+  Q_OBJECT
+
+public:
+  ///   Creates a MyView view options instance.
+  MyViewActiveOptions(QObject *parent=0);
+  virtual ~MyViewActiveOptions();
+
+  /// pqActiveViewOptions Methods
+  //@{
+  virtual void showOptions(pqView *view, const QString &page,
+      QWidget *parent=0);
+  virtual void changeView(pqView *view);
+  virtual void closeOptions();
+  //@}
+
+protected slots:
+  void finishDialog();
+
+protected:
+  QPointer<pqOptionsDialog> Dialog;
+  QPointer<MyViewOptions> Options;
+};
+
+#endif
diff --git a/src/View/MyViewOptions.cxx b/src/View/MyViewOptions.cxx
new file mode 100755 (executable)
index 0000000..3da5fba
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2. 
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+
+#include "MyViewOptions.h"
+
+#include <QHBoxLayout>
+#include "pqColorChooserButton.h"
+#include "MyView.h"
+
+//----------------------------------------------------------------------------
+MyViewOptions::MyViewOptions(QWidget *widgetParent)
+  : pqOptionsContainer(widgetParent)
+{
+  QHBoxLayout* l = new QHBoxLayout(this);
+  this->ColorChooser = new pqColorChooserButton(this);
+  l->addWidget(this->ColorChooser);
+  QObject::connect(this->ColorChooser, SIGNAL(chosenColorChanged(QColor)), 
+                   this, SIGNAL(changesAvailable()));
+}
+
+MyViewOptions::~MyViewOptions()
+{
+}
+
+void MyViewOptions::setPage(const QString&)
+{
+}
+
+QStringList MyViewOptions::getPageList()
+{
+  QStringList ret;
+  ret << "My View";
+  return ret;
+}
+  
+void MyViewOptions::setView(pqView* view)
+{
+  this->View = qobject_cast<MyView*>(view);
+  if(this->View)
+    {
+    this->ColorChooser->setChosenColor(this->View->background());
+    this->ColorChooser->setEnabled(true);
+    }
+  else
+    {
+    this->ColorChooser->setEnabled(false);
+    }
+}
+
+void MyViewOptions::applyChanges()
+{
+  if(!this->View)
+    {
+    return;
+    }
+
+  this->View->setBackground(this->ColorChooser->chosenColor());
+}
+
+void MyViewOptions::resetChanges()
+{
+}
+
diff --git a/src/View/MyViewOptions.h b/src/View/MyViewOptions.h
new file mode 100755 (executable)
index 0000000..a3418c9
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+   Program: ParaView
+   Module:    $RCSfile$
+
+   Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
+   All rights reserved.
+
+   ParaView is a free software; you can redistribute it and/or modify it
+   under the terms of the ParaView license version 1.2. 
+
+   See License_v1.2.txt for the full ParaView license.
+   A copy of this license can be obtained by contacting
+   Kitware Inc.
+   28 Corporate Drive
+   Clifton Park, NY 12065
+   USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================*/
+
+#ifndef _MyViewOptions_h
+#define _MyViewOptions_h
+
+#include "pqOptionsContainer.h"
+#include <QPointer>
+
+class MyView;
+class pqView;
+class pqColorChooserButton;
+
+/// options container for pages of my view options
+class MyViewOptions : public pqOptionsContainer
+{
+  Q_OBJECT
+
+public:
+  MyViewOptions(QWidget *parent=0);
+  virtual ~MyViewOptions();
+
+  // set the view to show options for
+  void setView(pqView* view);
+
+  // set the current page
+  virtual void setPage(const QString &page);
+  // return a list of strings for pages we have
+  virtual QStringList getPageList();
+
+  // apply the changes
+  virtual void applyChanges();
+  // reset the changes
+  virtual void resetChanges();
+
+  // tell pqOptionsDialog that we want an apply button
+  virtual bool isApplyUsed() const { return true; }
+
+protected:
+  QPointer<MyView> View;
+  pqColorChooserButton* ColorChooser;
+};
+
+#endif
diff --git a/src/View/MyViewSM.xml b/src/View/MyViewSM.xml
new file mode 100644 (file)
index 0000000..0ac91be
--- /dev/null
@@ -0,0 +1,38 @@
+<ServerManagerConfiguration>
+ <ProxyGroup name="representations">
+   <ClientDeliveryRepresentationProxy name="MyDisplay"
+     base_proxygroup="representations" base_proxyname="ClientDeliveryRepresentationBase">
+      <InputProperty name="Input"
+          command="SetInput-not-used"
+          update_self="1">
+      </InputProperty>
+   </ClientDeliveryRepresentationProxy>
+ </ProxyGroup>
+
+ <ProxyGroup name="views">
+   <ViewProxy name="MyView"
+     base_proxygroup="views" base_proxyname="ViewBase"
+     representation_name="MyDisplay">
+   </ViewProxy>
+ </ProxyGroup>
+
+ <ProxyGroup name="filters">
+   <SourceProxy name="MyExtractEdges" class="vtkExtractEdges"
+     label="My Extract Edges">
+     <InputProperty
+       name="Input"
+       command="SetInputConnection">
+         <ProxyGroupDomain name="groups">
+           <Group name="sources"/>
+           <Group name="filters"/>
+         </ProxyGroupDomain>
+         <DataTypeDomain name="input_type">
+           <DataType value="vtkDataSet"/>
+         </DataTypeDomain>
+     </InputProperty>
+     <Hints>
+       <View type="MyView"/>
+     </Hints>
+   </SourceProxy>
+ </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/XYChartRepresentationColumns/CMakeLists.txt b/src/XYChartRepresentationColumns/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4d33eff
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(XYChartRepresentationColumnsPlugin)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan (
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS plugins
+  REQUIRES_MODULES required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/XYChartRepresentationColumns/plugin/CMakeLists.txt b/src/XYChartRepresentationColumns/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1b6be4b
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(XYChartRepresentationColumnsPlugin)
+find_package(ParaView REQUIRED)
+
+set(BUILD_SHARED_LIBS ON)
+
+paraview_add_plugin(XYChartRepresentationColumns
+  VERSION "1.0"
+  MODULES XYChartRepresentationColumnsModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/XYChartRepresentationColumnsModule/vtk.module"
+  SERVER_MANAGER_XML views.xml
+  XML_DOCUMENTATION OFF
+)
+
+set_target_properties (XYChartRepresentationColumns PROPERTIES POSITION_INDEPENDENT_CODE ON)
+install(TARGETS XYChartRepresentationColumns
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/CMakeLists.txt b/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..67abf55
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkXYChartRepresentationColumns
+)
+
+vtk_module_add_module(XYChartRepresentationColumnsModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
diff --git a/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtk.module b/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtk.module
new file mode 100644 (file)
index 0000000..369cd5c
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  XYChartRepresentationColumnsModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  ParaView::RemotingViews
+PRIVATE_DEPENDS
+  VTK::CommonMisc
+  VTK::CommonSystem
+  VTK::FiltersGeneral
diff --git a/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.cxx b/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.cxx
new file mode 100644 (file)
index 0000000..3184a51
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkXYChartRepresentationColumns.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+#include "vtkXYChartRepresentationColumns.h"
+
+#include <vtkObjectFactory.h>
+#include <vtkChartXY.h>
+
+vtkStandardNewMacro(vtkXYChartRepresentationColumns);
+
+//----------------------------------------------------------------------------
+void vtkXYChartRepresentationColumns::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+//----------------------------------------------------------------------------
+void vtkXYChartRepresentationColumns::PrepareForRendering()
+{
+  this->Superclass::PrepareForRendering();
+  vtkChartXY* chartXY = this->GetChart();
+  chartXY->SetSelectionMethod(vtkChart::SELECTION_COLUMNS);
+}
diff --git a/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.h b/src/XYChartRepresentationColumns/plugin/XYChartRepresentationColumnsModule/vtkXYChartRepresentationColumns.h
new file mode 100644 (file)
index 0000000..cf48c64
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+/*=========================================================================
+
+  Program:   ParaView
+  Module:    vtkXYChartRepresentationColumns.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+/**
+ * @class   vtkXYChartRepresentationColumns
+ *
+ * vtkXYChartRepresentationColumns is a specialisation of vtkXYChartRepresentation
+ * that supports column selection.
+ */
+
+#ifndef vtkXYChartRepresentationColumns_h
+#define vtkXYChartRepresentationColumns_h
+
+#include <vtkXYChartRepresentation.h>
+
+class VTK_EXPORT vtkXYChartRepresentationColumns : public vtkXYChartRepresentation
+{
+public:
+  static vtkXYChartRepresentationColumns* New();
+  vtkTypeMacro(vtkXYChartRepresentationColumns, vtkXYChartRepresentation);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+protected:
+  vtkXYChartRepresentationColumns() = default;
+  ~vtkXYChartRepresentationColumns() override = default;
+
+  void PrepareForRendering() override;
+
+private:
+  vtkXYChartRepresentationColumns(const vtkXYChartRepresentationColumns&) = delete;
+  void operator=(const vtkXYChartRepresentationColumns&) = delete;
+};
+
+#endif // vtkXYChartRepresentationColumns_h
diff --git a/src/XYChartRepresentationColumns/plugin/paraview.plugin b/src/XYChartRepresentationColumns/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..35637fa
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  XYChartRepresentationColumns
+DESCRIPTION
+  Provides a new representation
+REQUIRES_MODULES
+  ParaView::RemotingViews
diff --git a/src/XYChartRepresentationColumns/plugin/views.xml b/src/XYChartRepresentationColumns/plugin/views.xml
new file mode 100644 (file)
index 0000000..e419c9b
--- /dev/null
@@ -0,0 +1,327 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="views">
+    <ContextViewProxy base_proxygroup="internal_views"
+                      base_proxyname="XYChartViewBase4Axes"
+                      class="vtkPVXYChartView"
+                      name="XYChartViewColumns"
+                      label="Line Chart View Columns"
+                      processes="client|renderserver|dataserver"
+                      representation_name="XYChartRepresentationColumns"
+                      post_creation="SetChartTypeToLine" >
+      <Documentation>This is the proxy for the XY line chart
+      view that support column selection.</Documentation>
+    </ContextViewProxy>
+  </ProxyGroup>
+  <ProxyGroup name="representations">
+    <ChartRepresentationProxy base_proxygroup="representations"
+                              class="vtkXYChartRepresentationColumns"
+                              name="XYChartRepresentationColumns"
+                              processes="client|dataserver|renderserver">
+      <Documentation>API for representations used by XYChartView and XYBarChartView.
+      </Documentation>
+      <InputProperty command="SetInputConnection"
+                     name="Input">
+        <Documentation>Data input for the representation.</Documentation>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataObject" />
+        </DataTypeDomain>
+      </InputProperty>
+      <IntVectorProperty command="SetVisibility"
+                         default_values="1"
+                         name="Visibility"
+                         number_of_elements="1"
+                         panel_visibility="never">
+        <BooleanDomain name="bool" />
+        <Documentation>Visibility of the representation.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetForceUseCache"
+                         default_values="0"
+                         is_internal="1"
+                         name="ForceUseCache"
+                         number_of_elements="1">
+        <BooleanDomain name="bool" />
+        <Documentation>Typically UseCache and CacheKey are updated by the View
+        and representations cache based on what the view tells it. However in
+        some cases we may want to force a representation to cache irrespective
+        of the view (e.g. comparative views). In which case these ivars can up
+        set. If ForcedCacheKey is true, it overrides UseCache and CacheKey.
+        Instead, ForcedCacheKey is used.</Documentation>
+      </IntVectorProperty>
+      <DoubleVectorProperty command="SetForcedCacheKey"
+                            default_values="none"
+                            is_internal="1"
+                            name="ForcedCacheKey"
+                            number_of_elements="1">
+        <DoubleRangeDomain name="range" />
+        <Documentation>Typically UseCache and CacheKey are updated by the View
+        and representations cache based on what the view tells it. However in
+        some cases we may want to force a representation to cache irrespective
+        of the view (e.g. comparative views). In which case these ivars can up
+        set. If ForcedCacheKey is true, it overrides UseCache and CacheKey.
+        Instead, ForcedCacheKey is used.</Documentation>
+      </DoubleVectorProperty>
+      <IntVectorProperty clean_command="ResetCompositeDataSetIndices"
+                         command="AddCompositeDataSetIndex"
+                         default_values="1"
+                         number_of_elements="1"
+                         name="CompositeDataSetIndex"
+                         number_of_elements_per_command="1"
+                         panel_visibility="default"
+                         repeat_command="1">
+        <CompositeTreeDomain mode="leaves" name="tree">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+          </RequiredProperties>
+        </CompositeTreeDomain>
+        <Documentation>This property lists the ids of the blocks to extract
+        from the input multiblock dataset.</Documentation>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetFieldAssociation"
+                         default_values="0"
+                         name="AttributeType"
+                         number_of_elements="1">
+        <Documentation>Select the attribute data to render.</Documentation>
+        <FieldDataDomain enable_field_data="1"
+                         name="enum">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+          </RequiredProperties>
+        </FieldDataDomain>
+      </IntVectorProperty>
+      <IntVectorProperty command="SetUseIndexForXAxis"
+                         default_values="1"
+                         name="UseIndexForXAxis"
+                         number_of_elements="1">
+        <ChartUseIndexForAxisDomain name="bool">
+          <RequiredProperties>
+            <Property function="ArraySelection" name="XArrayName" />
+          </RequiredProperties>
+        </ChartUseIndexForAxisDomain>
+        <Documentation>When set, the array index will be used for X axis,
+        otherwise the array identified by XArrayName will be
+        used.</Documentation>
+      </IntVectorProperty>
+      <StringVectorProperty command="SetXAxisSeriesName"
+                            default_values=""
+                            name="XArrayName"
+                            number_of_elements="1">
+        <Documentation>Set the array to use on X axis. This is used only when
+        UseIndexForXAxis is set to 0.</Documentation>
+        <ChartSeriesListDomain name="array_list"
+                              hide_partial_arrays="1">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+          </RequiredProperties>
+        </ChartSeriesListDomain>
+        <Hints>
+          <!-- the widget for this property is only enabled, when
+          UseIndexForXAxis is unchecked. -->
+          <PropertyWidgetDecorator type="EnableWidgetDecorator">
+            <Property name="UseIndexForXAxis" function="boolean_invert" />
+          </PropertyWidgetDecorator>
+        </Hints>
+      </StringVectorProperty>
+      <PropertyGroup label="X Axis Parameters">
+        <Property name="UseIndexForXAxis" />
+        <Property name="XArrayName" />
+      </PropertyGroup>
+      <StringVectorProperty command="SetSeriesVisibility"
+                            element_types="2 0"
+                            name="SeriesVisibility"
+                            number_of_elements_per_command="2"
+                            repeat_command="1"
+                            clean_command="ClearSeriesVisibilities">
+        <Documentation>Set the series visibility.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="visibility">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+        <Hints>
+          <!-- when present, the SeriesEditor widget will allow user to
+          re-order the series which will affect the rendered plot -->
+          <SeriesEditor supports_reordering="1" />
+        </Hints>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetLabel"
+                            clean_command="ClearLabels"
+                            element_types="2 2"
+                            name="SeriesLabel"
+                            number_of_elements_per_command="2"
+                            repeat_command="1">
+        <Documentation>Set the series labels.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="label">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetColor"
+                            clean_command="ClearColors"
+                            element_types="2 1 1 1"
+                            name="SeriesColor"
+                            number_of_elements_per_command="4"
+                            repeat_command="1">
+        <Documentation>Set the series line/bar color.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="color">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetAxisCorner"
+                            clean_command="ClearAxisCorners"
+                            element_types="2 0"
+                            name="SeriesPlotCorner"
+                            number_of_elements_per_command="2"
+                            repeat_command="1">
+        <Documentation>Set the series axis corner.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="value"
+                                    default_value="0">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+      <!--
+          Set the palette SelectionColor color to all the plots in the chart.
+        -->
+      <DoubleVectorProperty command="SetSelectionColor"
+                            default_values="1.0 0.0 1.0"
+                            name="Color"
+                            number_of_elements="3"
+                            panel_visibility="never">
+        <DoubleRangeDomain max="1 1 1"
+                           min="0 0 0"
+                           name="range" />
+        <Hints>
+          <PropertyLink group="settings" proxy="ColorPalette" property="SelectionColor"
+            unlink_if_modified="1" />
+        </Hints>
+      </DoubleVectorProperty>
+      <SubProxy command="SetSelectionRepresentation">
+        <!--
+          SelectionRepresentation proxy is used to convey the selection to view.
+          We keep this separate as subproxy so that when the selection is
+          modified, we don't have to update the representation as well, we can
+          only update the SelectionRepresentation.
+        -->
+        <RepresentationProxy name="SelectionRepresentation"
+               class="vtkChartSelectionRepresentation"
+               processes="client|dataserver|renderserver">
+          <InputProperty command="SetInputConnection"
+                         name="OriginalSelectionInput"/>
+        </RepresentationProxy>
+      </SubProxy>
+
+      <StringVectorProperty command="SetSeriesLabelPrefix"
+                            name="SeriesLabelPrefix"
+                            number_of_elements="1"
+                            default_value=""
+                            panel_visibility="advanced">
+      <Documentation>
+        Specify a string to prefix to the **SeriesLabel** (**Legend Name**) for each
+        of series being plotted. This will get prefixed to the labels (legend names) specified
+        for each of the series individually via the **Series Parameters**.
+      </Documentation>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetLineStyle"
+                            clean_command="ClearLineStyles"
+                            element_types="2 0"
+                            name="SeriesLineStyle"
+                            number_of_elements_per_command="2"
+                            repeat_command="1">
+        <Documentation>Set the series line style.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="value"
+                                    default_value="1">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetLineThickness"
+                            clean_command="ClearLineThicknesses"
+                            element_types="2 0"
+                            name="SeriesLineThickness"
+                            number_of_elements_per_command="2"
+                            repeat_command="1">
+        <Documentation>Set the series line thickness.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="value"
+                                    default_value="2">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+      <StringVectorProperty command="SetMarkerStyle"
+                            clean_command="ClearMarkerStyles"
+                            element_types="2 0"
+                            name="SeriesMarkerStyle"
+                            number_of_elements_per_command="2"
+                            repeat_command="1">
+        <Documentation>Set the series marker style.</Documentation>
+        <ChartSeriesSelectionDomain name="array_list"
+                                    hide_partial_arrays="0"
+                                    default_mode="value"
+                                    default_value="0">
+          <RequiredProperties>
+            <Property function="Input" name="Input" />
+            <Property function="FieldDataSelection" name="AttributeType" />
+            <Property function="CompositeIndexSelection" name="CompositeDataSetIndex" />
+          </RequiredProperties>
+        </ChartSeriesSelectionDomain>
+      </StringVectorProperty>
+
+      <PropertyGroup label="Series Parameters"
+                     panel_widget="SeriesEditor"
+                     panel_visibility="default" >
+        <Property name="SeriesVisibility"
+                  function="SeriesVisibility" />
+        <Property name="SeriesColor"
+                  function="SeriesColor" />
+        <Property name="SeriesLineThickness"
+                  function="SeriesLineThickness" />
+        <Property name="SeriesLineStyle"
+                  function="SeriesLineStyle" />
+        <Property name="SeriesLabel"
+                  function="SeriesLabel" />
+        <Property name="SeriesMarkerStyle"
+                  function="SeriesMarkerStyle" />
+        <Property name="SeriesPlotCorner"
+                  function="SeriesPlotCorner"/>
+      </PropertyGroup>
+
+      <Hints>
+        <InitializationHelper class="vtkSMXYChartRepresentationInitializationHelper" />
+      </Hints>
+
+      <!-- End of XYChartRepresentationBase -->
+    </ChartRepresentationProxy>
+
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ZJFilter/CMakeLists.txt b/src/ZJFilter/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a1aafd9
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+cmake_minimum_required(VERSION 3.8)
+project(ZJFilter)
+find_package(ParaView REQUIRED)
+
+include(GNUInstallDirs)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
+
+set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON)
+paraview_plugin_scan(
+  ENABLE_BY_DEFAULT YES
+  PLUGIN_FILES      "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
+  PROVIDES_PLUGINS  plugins
+  REQUIRES_MODULES  required_modules)
+
+foreach(module IN LISTS required_modules)
+  if(NOT TARGET "${module}")
+    message("Missing required module: ${module}")
+    return()
+  endif()
+endforeach()
+
+set(BUILD_SHARED_LIBS ON)
+paraview_plugin_build(
+  RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
+  LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+  LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
+  PLUGINS ${plugins}
+  AUTOLOAD ${plugins})
diff --git a/src/ZJFilter/TestCase.py b/src/ZJFilter/TestCase.py
new file mode 100644 (file)
index 0000000..50d2f83
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+print("To be done...")
diff --git a/src/ZJFilter/plugin/CMakeLists.txt b/src/ZJFilter/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..83a4f18
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+CMAKE_POLICY(SET CMP0071 NEW)
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+# Common CMake macros
+# ===================
+SET(TMP_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake")
+  INCLUDE(SalomeMacros)
+ELSE()
+  MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
+ENDIF()
+
+SET(MEDCOUPLING_ROOT_DIR $ENV{MEDCOUPLING_ROOT_DIR} CACHE PATH "Path to the MEDCoupling tool")
+IF(EXISTS ${MEDCOUPLING_ROOT_DIR})
+  LIST(APPEND CMAKE_MODULE_PATH "${MEDCOUPLING_ROOT_DIR}/cmake_files")
+ENDIF()
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules")
+LIST(APPEND CMAKE_MODULE_PATH ${TMP_CMAKE_MODULE_PATH})
+
+INCLUDE(SalomeSetupPlatform)
+SET(BUILD_SHARED_LIBS TRUE)
+
+FIND_PACKAGE(SalomeHDF5 REQUIRED)
+FIND_PACKAGE(SalomeMEDCoupling REQUIRED)
+
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS}
+                                                 ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON})
+SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS})
+SALOME_ACCUMULATE_ENVIRONMENT(PV_PLUGIN_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/lib/paraview)
+
+paraview_add_plugin(ZJFilterPlugin
+  VERSION "1.0"
+  MODULES ZJFilterModule
+  MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ZJFilterModule/vtk.module"
+  SERVER_MANAGER_XML filters.xml
+)
+
+install(TARGETS ZJFilterPlugin
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+)
diff --git a/src/ZJFilter/plugin/ZJFilterModule/CMakeLists.txt b/src/ZJFilter/plugin/ZJFilterModule/CMakeLists.txt
new file mode 100644 (file)
index 0000000..184a8e2
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+set(classes
+  vtkZJFilter
+)
+
+vtk_module_add_module(ZJFilterModule
+  FORCE_STATIC
+  CLASSES ${classes}
+)
+
+target_include_directories(ZJFilterModule PRIVATE ${MEDCOUPLING_INCLUDE_DIRS})
+
+if(HDF5_IS_PARALLEL)
+  target_link_libraries(ZJFilterModule PRIVATE ${MEDCoupling_paramedloader})
+else()
+  target_link_libraries(ZJFilterModule PRIVATE ${MEDCoupling_medloader})
+endif()
diff --git a/src/ZJFilter/plugin/ZJFilterModule/vtk.module b/src/ZJFilter/plugin/ZJFilterModule/vtk.module
new file mode 100644 (file)
index 0000000..d8b1cc5
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ZJFilterModule
+DEPENDS
+  VTK::CommonCore
+  VTK::CommonDataModel
+  VTK::CommonExecutionModel
+  VTK::FiltersCore
+  VTK::FiltersGeneral
+  ParaView::RemotingCore
+  VTK::IOLegacy
+PRIVATE_DEPENDS
+  VTK::IOLegacy
+  ParaView::VTKExtensionsMisc
+  ParaView::VTKExtensionsFiltersRendering
+
diff --git a/src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.cxx b/src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.cxx
new file mode 100644 (file)
index 0000000..803049e
--- /dev/null
@@ -0,0 +1,574 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "vtkZJFilter.h"
+
+#include <vtkAdjacentVertexIterator.h>
+#include <vtkAlgorithmOutput.h>
+#include <vtkCallbackCommand.h>
+#include <vtkCell.h>
+#include <vtkCellData.h>
+#include <vtkCellType.h>
+#include <vtkCharArray.h>
+#include <vtkCompositeDataToUnstructuredGridFilter.h>
+#include <vtkDataArraySelection.h>
+#include <vtkDataArrayTemplate.h>
+#include <vtkDataObjectTreeIterator.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetAttributes.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
+#include <vtkExecutive.h>
+#include <vtkFloatArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationDataObjectKey.h>
+#include <vtkInformationDataObjectMetaDataKey.h>
+#include <vtkInformationStringKey.h>
+#include <vtkInformationVector.h>
+#include <vtkIntArray.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMutableDirectedGraph.h>
+#include <vtkObjectFactory.h>
+#include <vtkPointData.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkStringArray.h>
+#include <vtkThreshold.h>
+#include <vtkUnstructuredGrid.h>
+
+#include "InterpKernelException.hxx"
+#include "MEDCouplingRefCountObject.hxx"
+
+#include <cstdio>
+#include <deque>
+#include <map>
+#include <sstream>
+
+vtkStandardNewMacro(vtkZJFilter);
+
+///////////////////
+
+vtkInformationDataObjectMetaDataKey* GetMEDReaderMetaDataIfAny()
+{
+  static const char ZE_KEY[] = "vtkMEDReader::META_DATA";
+  MEDCoupling::GlobalDict* gd(MEDCoupling::GlobalDict::GetInstance());
+  if (!gd->hasKey(ZE_KEY))
+    return 0;
+  std::string ptSt(gd->value(ZE_KEY));
+  void* pt(0);
+  std::istringstream iss(ptSt);
+  iss >> pt;
+  return reinterpret_cast<vtkInformationDataObjectMetaDataKey*>(pt);
+}
+
+bool IsInformationOK(vtkInformation* info)
+{
+  vtkInformationDataObjectMetaDataKey* key(GetMEDReaderMetaDataIfAny());
+  if (!key)
+    return false;
+  // Check the information contain meta data key
+  if (!info->Has(key))
+    return false;
+  // Recover Meta Data
+  vtkMutableDirectedGraph* sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(key)));
+  if (!sil)
+    return false;
+  int idNames(0);
+  vtkAbstractArray* verticesNames(sil->GetVertexData()->GetAbstractArray("Names", idNames));
+  vtkStringArray* verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
+  if (!verticesNames2)
+    return false;
+  for (int i = 0; i < verticesNames2->GetNumberOfValues(); i++)
+  {
+    vtkStdString& st(verticesNames2->GetValue(i));
+    if (st == "MeshesFamsGrps")
+      return true;
+  }
+  return false;
+}
+
+class Grp
+{
+public:
+  Grp(const std::string& name)
+    : _name(name)
+  {
+  }
+  void setFamilies(const std::vector<std::string>& fams) { _fams = fams; }
+  std::string getName() const { return _name; }
+  std::vector<std::string> getFamilies() const { return _fams; }
+
+private:
+  std::string _name;
+  std::vector<std::string> _fams;
+};
+
+class Fam
+{
+public:
+  Fam(const std::string& name)
+  {
+    constexpr char ZE_SEP[] = "@@][@@";
+    std::size_t pos(name.find(ZE_SEP));
+    std::string name0(name.substr(0, pos)), name1(name.substr(pos + strlen(ZE_SEP)));
+    std::istringstream iss(name1);
+    iss >> _id;
+    _name = name0;
+  }
+  std::string getName() const { return _name; }
+  int getID() const { return _id; }
+
+private:
+  std::string _name;
+  int _id;
+};
+
+void ExtractInfo(vtkInformationVector* inputVector, vtkUnstructuredGrid*& usgIn)
+{
+  vtkInformation* inputInfo(inputVector->GetInformationObject(0));
+  vtkDataSet* input(0);
+  vtkDataSet* input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  vtkMultiBlockDataSet* input1(
+    vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if (input0)
+    input = input0;
+  else
+  {
+    if (!input1)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet must be a DataSet or single elt multi block dataset expected !");
+    if (input1->GetNumberOfBlocks() != 1)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or "
+        "ExtractBlocks filter before calling this filter !");
+    vtkDataObject* input2(input1->GetBlock(0));
+    if (!input2)
+      throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block "
+                                     "but this single element is NULL !");
+    vtkDataSet* input2c(vtkDataSet::SafeDownCast(input2));
+    if (!input2c)
+      throw INTERP_KERNEL::Exception(
+        "Input dataSet is a multiblock dataset with exactly one block but this single element is "
+        "not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
+    input = input2c;
+  }
+  if (!input)
+    throw INTERP_KERNEL::Exception("Input data set is NULL !");
+  usgIn = vtkUnstructuredGrid::SafeDownCast(input);
+  if (!usgIn)
+    throw INTERP_KERNEL::Exception("Input data set is not an unstructured mesh ! This filter works "
+                                   "only on unstructured meshes !");
+}
+
+void LoadFamGrpMapInfo(vtkMutableDirectedGraph* sil, std::string& meshName,
+  std::vector<Grp>& groups, std::vector<Fam>& fams)
+{
+  if (!sil)
+    throw INTERP_KERNEL::Exception("LoadFamGrpMapInfo : internal error !");
+  int idNames(0);
+  vtkAbstractArray* verticesNames(sil->GetVertexData()->GetAbstractArray("Names", idNames));
+  vtkStringArray* verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
+  vtkIdType id0;
+  bool found(false);
+  for (int i = 0; i < verticesNames2->GetNumberOfValues(); i++)
+  {
+    vtkStdString& st(verticesNames2->GetValue(i));
+    if (st == "MeshesFamsGrps")
+    {
+      id0 = i;
+      found = true;
+    }
+  }
+  if (!found)
+    throw INTERP_KERNEL::Exception(
+      "There is an internal error ! The tree on server side has not the expected look !");
+  vtkAdjacentVertexIterator* it0(vtkAdjacentVertexIterator::New());
+  sil->GetAdjacentVertices(id0, it0);
+  int kk(0), ll(0);
+  while (it0->HasNext())
+  {
+    vtkIdType id1(it0->Next());
+    std::string mName((const char*)verticesNames2->GetValue(id1));
+    meshName = mName;
+    vtkAdjacentVertexIterator* it1(vtkAdjacentVertexIterator::New());
+    sil->GetAdjacentVertices(id1, it1);
+    vtkIdType idZeGrps(it1->Next()); // zeGroups
+    vtkAdjacentVertexIterator* itGrps(vtkAdjacentVertexIterator::New());
+    sil->GetAdjacentVertices(idZeGrps, itGrps);
+    while (itGrps->HasNext())
+    {
+      vtkIdType idg(itGrps->Next());
+      Grp grp((const char*)verticesNames2->GetValue(idg));
+      vtkAdjacentVertexIterator* itGrps2(vtkAdjacentVertexIterator::New());
+      sil->GetAdjacentVertices(idg, itGrps2);
+      std::vector<std::string> famsOnGroup;
+      while (itGrps2->HasNext())
+      {
+        vtkIdType idgf(itGrps2->Next());
+        famsOnGroup.push_back(std::string((const char*)verticesNames2->GetValue(idgf)));
+      }
+      grp.setFamilies(famsOnGroup);
+      itGrps2->Delete();
+      groups.push_back(grp);
+    }
+    itGrps->Delete();
+    vtkIdType idZeFams(it1->Next()); // zeFams
+    it1->Delete();
+    vtkAdjacentVertexIterator* itFams(vtkAdjacentVertexIterator::New());
+    sil->GetAdjacentVertices(idZeFams, itFams);
+    while (itFams->HasNext())
+    {
+      vtkIdType idf(itFams->Next());
+      Fam fam((const char*)verticesNames2->GetValue(idf));
+      fams.push_back(fam);
+    }
+    itFams->Delete();
+  }
+  it0->Delete();
+}
+
+std::vector<std::string> FindConds(const std::vector<Grp>& grps)
+{
+  constexpr char PAT[] = "COND_";
+  constexpr std::size_t SZ_PAT(sizeof(PAT) - 1);
+  std::vector<std::string> ret;
+  for (std::vector<Grp>::const_iterator it = grps.begin(); it != grps.end(); it++)
+  {
+    std::string name((*it).getName());
+    std::string part(name.substr(0, SZ_PAT));
+    if (part == PAT)
+      ret.push_back(name.substr(SZ_PAT, std::string::npos));
+  }
+  return ret;
+}
+
+constexpr char EPORT_PAT[] = "EPORT_";
+
+std::vector<std::string> FindEports(
+  const std::string& condEntry, const std::vector<Grp>& grps, std::vector<std::string>& eportsZip)
+{
+  std::vector<std::string> ret;
+  std::string commonPart(std::string(EPORT_PAT) + condEntry);
+  std::size_t commonPart_sz(commonPart.length());
+  for (std::vector<Grp>::const_iterator it = grps.begin(); it != grps.end(); it++)
+  {
+    std::string name((*it).getName());
+    std::string part(name.substr(0, commonPart_sz));
+    if (part == commonPart)
+    {
+      ret.push_back(name);
+      eportsZip.push_back(name.substr(commonPart_sz, std::string::npos));
+    }
+  }
+  return ret;
+}
+
+std::string BigestCommonPart(const std::string& s1, const std::string& s2)
+{
+  std::size_t ls1(s1.length()), ls2(s2.length()), lb(0), lt(0);
+  std::string b, t;
+  if (ls1 >= ls2)
+  {
+    b = s1;
+    t = s2;
+    lb = ls1;
+    lt = ls2;
+  }
+  else
+  {
+    b = s2;
+    t = s1;
+    lb = ls2;
+    lt = ls1;
+  }
+  for (std::size_t l0 = lt; l0 > 0; l0--)
+  {
+    for (std::size_t l1 = 0; l1 < lt - l0 + 1; l1++)
+    {
+      std::string cand(t.substr(l1, l0));
+      if (b.find(cand) != std::string::npos)
+        return cand;
+    }
+  }
+  return std::string();
+}
+
+std::vector<int> DeduceIdsFrom(const std::vector<std::string>& eportsZip)
+{
+  if (eportsZip.empty())
+    return std::vector<int>();
+  std::string ref(eportsZip[0]);
+  std::size_t sz(eportsZip.size());
+  for (std::size_t i = 1; i < sz; i++)
+    ref = BigestCommonPart(ref, eportsZip[i]);
+  std::vector<int> ret(sz);
+  for (std::size_t i = 0; i < sz; i++)
+  {
+    std::size_t pos(eportsZip[i].find(ref));
+    if (pos == std::string::npos)
+      throw INTERP_KERNEL::Exception("DeduceIdsFrom : internal error !");
+    std::string res(
+      eportsZip[i].substr(0, pos) + eportsZip[i].substr(pos + ref.length(), std::string::npos));
+    std::istringstream iss(res);
+    int val(0);
+    iss >> val;
+    ret[i] = val;
+  }
+  return ret;
+}
+
+std::set<int> FamiliesIdsFromGrp(
+  const std::vector<Grp>& grps, const std::vector<Fam>& fams, const std::string& grp)
+{
+  bool found(false);
+  std::vector<std::string> locFams;
+  for (std::vector<Grp>::const_iterator it = grps.begin(); it != grps.end(); it++)
+  {
+    if ((*it).getName() == grp)
+    {
+      locFams = (*it).getFamilies();
+      found = true;
+      break;
+    }
+  }
+  if (!found)
+    throw INTERP_KERNEL::Exception("FamiliesIdsFromGrp : internal error !");
+  std::set<int> ret;
+  for (std::vector<Fam>::const_iterator it = fams.begin(); it != fams.end(); it++)
+  {
+    if (std::find(locFams.begin(), locFams.end(), (*it).getName()) != locFams.end())
+      ret.insert((*it).getID());
+  }
+  return ret;
+}
+
+vtkDataSet* FilterFamilies(vtkZJFilter* zeBoss, vtkDataSet* input, const std::set<int>& idsToKeep)
+{
+  bool catchAll, catchSmth;
+  vtkNew<vtkThreshold> thres;
+  thres->AddObserver(vtkCommand::ProgressEvent, zeBoss->InternalProgressObserver);
+  constexpr int VTK_DATA_ARRAY_DELETE = vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
+  constexpr char ZE_SELECTION_ARR_NAME[] = "@@ZeSelection@@";
+  constexpr char arrNameOfFamilyField[] = "FamilyIdCell";
+  constexpr char associationForThreshold[] = "vtkDataObject::FIELD_ASSOCIATION_CELLS";
+  vtkDataSet* output(input->NewInstance());
+  output->ShallowCopy(input);
+  thres->SetInputData(output);
+  vtkDataSetAttributes *dscIn(input->GetCellData()), *dscIn2(input->GetPointData());
+  vtkDataSetAttributes *dscOut(output->GetCellData()), *dscOut2(output->GetPointData());
+  //
+  constexpr double vMin(1.), vMax(2.);
+  thres->ThresholdBetween(vMin, vMax);
+  // OK for the output
+  //
+  vtkDataArray* da(input->GetCellData()->GetScalars(arrNameOfFamilyField));
+  if (!da)
+    return 0;
+  std::string daName(da->GetName());
+  vtkIntArray* dai(vtkIntArray::SafeDownCast(da));
+  if (daName != arrNameOfFamilyField || !dai)
+    return 0;
+  //
+  int nbOfTuples(dai->GetNumberOfTuples());
+  vtkCharArray* zeSelection(vtkCharArray::New());
+  zeSelection->SetName(ZE_SELECTION_ARR_NAME);
+  zeSelection->SetNumberOfComponents(1);
+  char* pt(new char[nbOfTuples]);
+  zeSelection->SetArray(pt, nbOfTuples, 0, VTK_DATA_ARRAY_DELETE);
+  const int* inPtr(dai->GetPointer(0));
+  std::fill(pt, pt + nbOfTuples, 0);
+  catchAll = true;
+  catchSmth = false;
+  std::vector<bool> pt2(nbOfTuples, false);
+  for (std::set<int>::const_iterator it = idsToKeep.begin(); it != idsToKeep.end(); it++)
+  {
+    bool catchFid(false);
+    for (int i = 0; i < nbOfTuples; i++)
+      if (inPtr[i] == *it)
+      {
+        pt2[i] = true;
+        catchFid = true;
+      }
+    if (!catchFid)
+      catchAll = false;
+    else
+      catchSmth = true;
+  }
+  for (int ii = 0; ii < nbOfTuples; ii++)
+    if (pt2[ii])
+      pt[ii] = 2;
+  int idx(output->GetCellData()->AddArray(zeSelection));
+  output->GetCellData()->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
+  output->GetCellData()->CopyScalarsOff();
+  zeSelection->Delete();
+  //
+  thres->SetInputArrayToProcess(idx, 0, 0, associationForThreshold, ZE_SELECTION_ARR_NAME);
+  thres->Update();
+  vtkUnstructuredGrid* zeComputedOutput(thres->GetOutput());
+  zeComputedOutput->GetCellData()->RemoveArray(idx);
+  output->Delete();
+  zeComputedOutput->Register(0);
+  thres->RemoveObserver(zeBoss->InternalProgressObserver);
+  return zeComputedOutput;
+}
+
+////////////////////
+
+vtkZJFilter::vtkZJFilter()
+  : InternalProgressObserver(0)
+{
+  this->InternalProgressObserver = vtkCallbackCommand::New();
+  this->InternalProgressObserver->SetCallback(&vtkZJFilter::InternalProgressCallbackFunction);
+  this->InternalProgressObserver->SetClientData(this);
+}
+
+vtkZJFilter::~vtkZJFilter()
+{
+  this->InternalProgressObserver->Delete();
+}
+
+void vtkZJFilter::InternalProgressCallbackFunction(
+  vtkObject* arg, unsigned long, void* clientdata, void*)
+{
+  reinterpret_cast<vtkZJFilter*>(clientdata)
+    ->InternalProgressCallback(static_cast<vtkAlgorithm*>(arg));
+}
+
+void vtkZJFilter::InternalProgressCallback(vtkAlgorithm* algorithm)
+{
+  /*this->UpdateProgress(algorithm->GetProgress()); // To intercept progression of Threshold filters
+  if (this->AbortExecute)
+    {
+      algorithm->SetAbortExecute(1);
+      }*/
+}
+
+int vtkZJFilter::RequestInformation(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkZJFilter::RequestInformation
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkUnstructuredGrid* usgIn = nullptr;
+    ExtractInfo(inputVector[0], usgIn);
+  }
+  catch (INTERP_KERNEL::Exception& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkZJFilter::RequestInformation : " << e.what()
+        << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+    {
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    }
+    else
+    {
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    }
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+int vtkZJFilter::RequestData(
+  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // std::cerr << "########################################## vtkZJFilter::RequestData
+  // ##########################################" << std::endl;
+  try
+  {
+    vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
+    vtkInformation *outInfo(outputVector->GetInformationObject(0));
+    vtkUnstructuredGrid* usgIn(nullptr);
+    ExtractInfo(inputVector[0], usgIn);
+    std::string meshName;
+    std::vector<Grp> groups;
+    std::vector<Fam> fams;
+    if (IsInformationOK(inputInfo))
+    {
+      vtkMutableDirectedGraph* famGrpGraph(
+        vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(GetMEDReaderMetaDataIfAny())));
+      LoadFamGrpMapInfo(famGrpGraph, meshName, groups, fams);
+    }
+    std::vector<std::string> conds(FindConds(groups));
+    vtkUnstructuredGrid* output(
+      vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+    vtkNew<vtkMultiBlockDataSet> mb2;
+    std::size_t iblock(0);
+    for (std::vector<std::string>::const_iterator it = conds.begin(); it != conds.end();
+         it++, iblock++)
+    {
+      std::vector<std::string> eports2;
+      std::vector<std::string> eports(FindEports(*it, groups, eports2));
+      std::vector<int> ids(DeduceIdsFrom(eports2));
+      vtkNew<vtkMultiBlockDataSet> mb;
+      std::size_t sz(eports.size());
+      for (std::size_t i = 0; i < sz; i++)
+      {
+        std::set<int> zeIds(FamiliesIdsFromGrp(groups, fams, eports[i]));
+        //
+        vtkSmartPointer<vtkDataSet> ds(FilterFamilies(this, usgIn, zeIds));
+        {
+          vtkNew<vtkIntArray> arr;
+          arr->SetName((*it).c_str());
+          arr->SetNumberOfComponents(1);
+          int nbTuples(ds->GetNumberOfCells());
+          arr->SetNumberOfTuples(nbTuples);
+          int* pt(arr->GetPointer(0));
+          std::fill(pt, pt + nbTuples, ids[i]);
+          ds->GetCellData()->AddArray(arr);
+        }
+        this->UpdateProgress(double(i) / double(sz));
+        mb->SetBlock(i, ds);
+      }
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd;
+      cd->SetInputData(mb);
+      cd->SetMergePoints(0);
+      cd->Update();
+      mb2->SetBlock(iblock, cd->GetOutput());
+    }
+    {
+      vtkNew<vtkCompositeDataToUnstructuredGridFilter> cd2;
+      cd2->SetInputData(mb2);
+      cd2->SetMergePoints(0);
+      cd2->Update();
+      output->ShallowCopy(cd2->GetOutput());
+    }
+  }
+  catch (INTERP_KERNEL::Exception& e)
+  {
+    std::ostringstream oss;
+    oss << "Exception has been thrown in vtkZJFilter::RequestInformation : " << e.what()
+        << std::endl;
+    if (this->HasObserver("ErrorEvent"))
+      this->InvokeEvent("ErrorEvent", const_cast<char*>(oss.str().c_str()));
+    else
+      vtkOutputWindowDisplayErrorText(const_cast<char*>(oss.str().c_str()));
+    vtkObject::BreakOnError();
+    return 0;
+  }
+  return 1;
+}
+
+void vtkZJFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
diff --git a/src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.h b/src/ZJFilter/plugin/ZJFilterModule/vtkZJFilter.h
new file mode 100644 (file)
index 0000000..5cfc537
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2021  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef vtkZJFilter_h__
+#define vtkZJFilter_h__
+
+#include <vtkUnstructuredGridAlgorithm.h>
+
+class vtkCallbackCommand;
+
+class VTK_EXPORT vtkZJFilter : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkZJFilter* New();
+  vtkTypeMacro(vtkZJFilter, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+
+  vtkCallbackCommand* InternalProgressObserver;
+
+protected:
+  vtkZJFilter();
+  ~vtkZJFilter() override;
+
+  int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+  static void InternalProgressCallbackFunction(vtkObject*, unsigned long, void*, void*);
+  void InternalProgressCallback(vtkAlgorithm* algorithm);
+
+private:
+  vtkZJFilter(const vtkZJFilter&) = delete;
+  void operator=(const vtkZJFilter&) = delete;
+};
+
+#endif
diff --git a/src/ZJFilter/plugin/filters.xml b/src/ZJFilter/plugin/filters.xml
new file mode 100644 (file)
index 0000000..9fc528c
--- /dev/null
@@ -0,0 +1,21 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy name="ZJFilter"
+                 class="vtkZJFilter"
+                 label="ZJ Filter">
+      <InputProperty name="Input"
+                     command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkDataSet"/>
+        </DataTypeDomain>
+        <Documentation>
+         This property specifies the input to the ZJ filter.
+        </Documentation>
+      </InputProperty>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/ZJFilter/plugin/paraview.plugin b/src/ZJFilter/plugin/paraview.plugin
new file mode 100644 (file)
index 0000000..ef6ff03
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2021  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+NAME
+  ZJFilterPlugin
+DESCRIPTION
+  This plugin provides the ZJFilter filter.
+REQUIRES_MODULES
+  VTK::CommonCore
+  VTK::IOCore
+  VTK::FiltersCore
+  VTK::FiltersGeneral