--- /dev/null
+# 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)
--- /dev/null
+// 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__
--- /dev/null
+**************************
+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.
--- /dev/null
+***********************************
+SALOME PARAVISADDONS Documentation
+***********************************
+
--- /dev/null
+# 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})
--- /dev/null
+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.
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
+)
--- /dev/null
+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.
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
+
--- /dev/null
+# 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
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+# 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)
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+ )
--- /dev/null
+# 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
+
+
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+<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>
--- /dev/null
+# 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']
+
--- /dev/null
+<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">
+ 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
+ </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">
+ 8DkAAAAAAAB2bea6vTOkvkQ3tdyBZpM+yk9bV2XCcrcSl4dqKS2LPuaZJTMt77c+GpJZliGcM7b25kpsZ0yUvsuSdwCzi5A+XNlarqsyabefoyFYJS2LPjhy457t7bc+6o8pGDiFXLZ5ncCaqGRlPoMWmTOOkIo+5aN9yJx8izekrEnjni2LPrCb1jpC7Lc+9nHXbMWE3LYQ5tGAUnicum6ySSw+n6K6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYpOJ4ntqhPpyvF0s3RYE+Prodk28biDeIFuTmqeqHPpsTejscI7Q+9tuMjx5/NDe+zm0iWwuwPk47h4DaZHE+xfJQmZ+5f7cZHsfOmh6DPgeAv7AxNK0+00uLYmiB/LY1Q7+QA4u1Pqb0Ss2W0UU+MYEvxGAzkbed1obTWzeAPiC2C6G2hKY+GykS9FLvGLd0AnWfD2m5PiQGJgxDO2K+9og/rmbpkrdkCLGoNtF3PtwYMBcDXZk+PytTTNfNITdzrUZ9fJW6Pg/i+RKju2u+wcd2tmkWozezERzlevZxPhk+kmzKSIg+c1/4+g/ZMjfUjixIUXq7PkJ+YOzEHXO+jhlsHRsOVzdqTCbL9ptxPit7gpAHroY+fabOYgtj67b7+juTbP+7PigK8Pd4UXa+x2g3tkrHtDcPp9kvIF5xPs2p26QDlIU+ZoQoRrD5L7dPcbXu+2u8PmatcCsK4ni+JNjdv5+OareDpUgDgAlxPphkacZzFIQ+9uqlbo/ACzd4YO+5jj69PvIzY2uARH6+Rbf/kezxkDcajQ1ZOidwPvMZahdZJIA+yoeqJPZTJ7faDBixL4O9PuprI0ldJoC+f7upo6GuSjcxeFM2RKtvPu698nfLfn0+shOIAF28KjfdNeVY4ga+PukrRtj2goK+pdJMe2rHgTfMMrkmCgpuPm2vR5d3hXY+CnPCPYUBWrcoE7pWymW+Plm4KzNwvYS+fhRVfiPwhrfsf6obpEhsPvm8rMzni24+Dfw4dAnUC7e9zmfS+YO+Po/QesEzsIW+kYp/2zckhjeAZyBGehZrPswc3vUq9WQ+nzAL242gRLf2+12VPZ2+PnR+ijTtuoe+yTUkTs+TWbdH1xrYK9JnPpFKWP1HokG++0JLa4zzyzaKfBnylJS+PuJslZx2d4i+wyT8WJ4Isjfq5qo3oX1mPglVbXJ60Fy+vN+kFR4cI7cIGqU7z3K+PiojwQWDkYm+/PUe36SAPjdj1FSdfb1kPvJeiI5HOGu+lhOpoySbMzedGAYNfDu+Pr6ZWtPlk4q+SdkkQ66Tp7e1DVcmh/BiPmSouaDZ+XO+IWKbIWbUMLfsWVhCSQy+PjVYqB7hJou+ajHb4v99cDcwOJpm+4FhPrlG1J2w5Hi+zI6WpFM0Kjc2OhecCme9Pq1M1Zc8Y4y+PYerE3RVc7f1UeIMIY5bPuCg/++ImYK+6xXmYhmlIzcRwiAc6w29PoCHSqFr04y+lc7vY40Wsrdey3NGiKZYPtunNYdd5IS+5jXD0lHqPDdserNKCS68Poj18TyLq42+IyaNcpO0dzfdIB7XRhlUPjy9AeYYTYi+IEU6+cX2YLf2RAk/Dyu7Ph7NRUMHVI6+/Ta0IF1hZLc4zfveFPNOPhRCQvBifYu+aE/gEIEc4rZV1I7sL7K6PjgeHtGih46+T1Ld38xZizeXQHDrqRdLPpr+s4LAu4y+kVgnmJVuGzdEly0a7l25PobTm036246+GM0p6GzmizfyQqopdV0/PumBq/n5E5C+XOZM6MXoObeWvadKFLi4PsjPzup78Y6+rxZdtWYk0jcyeKjhuDI2PqGp/9eltZC+2AK29rHEZ7cW9DmtI+63PsH5q4f2CI++Iloue23qbTfY3i24pzcuPn4l0WViKZG+QZ3XeP/4ETeljjHCSp22Ph1jqeilF4++9ZqomiyNijfoqTQAEosOPmRmymY4ypG+i5FdS2LqbTd5yGEu6jm1PpCLcmghUI6+Jv9P/g8kijfO3i3up01pvs3iiwu8iJu+BoXSfDElF7dKvPDWJHOxPsq2fNlmX4m+CyJrjYw7lDcfA7FbeFSBvmX/CVNmVqS+mQFaUF8nN7fEeq/EE2KpPlmc1uFxVYC+5nwxS5JmRTe+BpefsA2LvtYHgW0wvae+A/53VTjwGDc2qzWj5q+gPhPMIA3P1WS+mO+HJoKzdbfcCatk1QeUvjr2+fqTs6i+X0w91UK5KjfiXSfZiIyQPuSkC0K2w3M+STsv434DYTfe+78JNdWZvmtAwmzWBqa+zESp03bHITe6YfE2tzCEPkogXw0USYE+xPcSqmJYkjflyHKGmJOavsMH8DpkS6W+cLtxkQmrIrf5eoipE9RmvknMcGYpKJI+VPub4K0bNDeJN2zQ8ISfvs3LhUpax5q+HfnMc0+B7LaYjeAPvg2DvgnNDrD/KZ0+tk7L5rG1cbfBDO1ajO+hvo1cTDC4bG2++65oDN8fcLfXTGWPh4eFviNqNTXP76g+dmEGcQ3dgjdkmExlGEyivkxdmQ9aMWg+8kkD2S3JRzc1CH6U+U54vuXL9QxOK7E+dzX1BdUefTfNAFjbU+uivkTpXHnwHZU+OA16lwJ2MTe9RNdkqSOAPhQ5mewdDLY+L9BDXZOAcLdbvWgmNG6jvgA8Q3mRoKM+KJlzQQBfFbeZ4nYR8XS8OohS645oE6W6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9RNdkqSOAPhM5mewdDLY+CLKE5ugzfzdavWgmNG6jvgE8Q3mRoKM+AdFGRMXOYbce/Agj8KmgPmIwiAUk/Lo+c7sQiDOhfzdQqJ9mLaWivlvh8AXCSqo+g8a6YtHKhTcAwylsiVytPotCn74Rzb4+08kCPPnUZLcRLS/cu4GevlI/rpPUe6w+009Abj4DcLe7KMjw2wS1PitAXdy82MA+OopmklQ8cbcPNA9+3dSSvmgRWV0k9Kk+RcR0DVPngLfBSUrPG6a6PlwSpWBDnME+XGfX6c/YZLdSaVTqvmhcvn8VyxTeK6I+taOdwdtnPLfKDSsmKwS8PrOlQKW2pcE+lFF3FjZEeDds5O5LOm9wPvOXpttszp0+JA79XeuGl7djvXt2m5i8PsibwMAgoME+Y+iTRng7bDed/WhXMzp4PkdR8Rx1iJs+Sa7g9O6qUDdS0hMz5km+PjQhFr1/c8E+mhrp/zWrk7eBxxkRN3qDPty9PyDN85Y++iSQGNrOhLep9JzKFyO/PqWr4e9/TME+Jd1DBvadaLfL8f940oGHPkcPt2ygSJQ+XyBG5j5YhTdoBvswaoW/PuKQJBySNcE+Rq461Q8aMze4ih/L00iJPtOKS6dgEpM+mr4RARMKhrceO3hkhC3APszNxwiV9sA+E8uhXJljdTf649UaYdeMPvthScL2kZA+k6C35i5DcjfD0QiYXtLAPiBMLZkAacA+Q/4aC1vSmze8xJbSpfCQPicbbdJ/pok+aQ87KBV1kLeUJ2C2invBPiDoFcqZ774+tkriU8g+pDe3xpm5q4GTPuIEr+9UeYE+skRbNMytaTf0amjfLLzBPiSkiWqTY74+GrYyJ/ajajcWMJA/VY+UPg2Cb/6K3ns+HHfS459KdLfKnuPTWOrBPqqgJxsC7b0+/ouxcrmWdDdB602YsleVPlVjJKFog3Y+G9MvikRYQzf2qauFZwnCPnH0JylTdr0+eewCenVlwTdEqjEj39eVPoK5gVMVCXM+ZokhCPAbdLd1v/BlJxHCPkMQd36QO70+LYW/q8LVeDcd0EWll/OVPjboCNJpRnI+4LMBLxzxiLc886UpH0TCPqNcJgvNWLs+pWPB1EQlg7fCofYR0K2WPkeB402c8Gk+61aTBjG/WLdnpECsR0nCPncddkIaG7s+j3++FKwPhzeK4CEKZMOWPloOjuP8qmg+crv6COjrK7fXuA+CJWPCPqDCdjNKibo+ZlcZ+cOQcLdpUuBxaViXPsasaK4GiV8+65rUrXNueLdbasTeX4nCPhwYCiI+prk+EAaxMiW4Xbch7t5+WHGYPkHj8J49zyW+qnmzGDgtUjePSgp63JfCPviL46KlCLk+1uQGv+x4eTedPBZ6qgWZPraa3YBKMFW+yPTbrGUldTdrfQOyLZrCPqIZCOZZzbg+/fXbdK1EpDfnHseaxCuZPof7jCQe/Vm+0i3voOtWxTaGaIXDapPCPuU/TUbs2bc+iPV0vpEqyrdHZ0ZUIHeZPqt897ta12G+qS9L7lpHordZ0KnZd5TCPqRnZhhqm7c+2PuCR3aoUzepWB+Me6OZPl7oYOhAv2S+XeWiYZRLYDfqjinsnZfCPjqVj/50Nbc+DtnuJwSCVLfvsIJBRQOaPllGlMm3E2u+lU1dCLzLVLfTO2MhrpvCPgyyr2RbY7Y+NfRWaPgvVjf1feTq0uCaPnrjJalj+XS+wuDkHwS9UbcmI32xOpfCPkokjG1j2LU+m3PrHD8csDfKZUlYuFCbPjNkxj8qy3i+SuGrL8ighrfXrwV3oE/CPhGoW5l3bbM+LYbNJoSpm7e4u4LsXrGbPskd8z1FQXy++IOHBad9YbeU2EtR7j/CPtdKOPuL17I+4ZB0abSWXjdBUVAxHOibPrxt7PUaUn6++Fv5aTsLOTeRT1Do/RvCPk2W1W+pprE+G+a1K4etgzcJHhT46FKcPn+tflVDO4G+WMg2UQ+eJTfB5x6U2evBPit+MLXpVLA+2vUEjMFuXTcjE7jqZ6icPhOtHwce9IK+WGz8J7SBnbc+O87HBm3BPpISAj/w2qo+4lxDoQcGsrfRDomHB/WcPpXEGnUnooS+e4hPvk8JW7e8L8QIMjPBPtycTe/LZag+dtSTHmaVk7fgQjBKxS+dPg5XRjK2C4a+3+M4h6jYZLcOSE5J7tbAPgF56+SB0KQ+KD+esQ3ldrdFdi6bUZadPvvU7h0yqoi+IGOE+VCeNTfhhfCcJpHAPpK8AR+dTKI+JpITMotcrjej20zTrsidPpjcrl2BCoq+j7n/9sSek7dna1wwtMS/PvjYeQ6ThZg+mADjbqxduDcLQCDYFPqdPtx9mrpFmIu+7ni0JI4sbLfZ27nBBQu/PoVq66P8zZI+F7wflbCIVbfpdkAuGiKePkeKNglIGo2+NqxQ1qW0GLdQoG48Hk++PhPCsudp8Io+UiQ2kTiiUzclAEZu60uePhCUAuB53o6+zpV1OpStMbeL6clt9+29PgcCmj8dnIU+FbT8vCtRzbcWmYf0W16ePpbhiRNGu4++q6inGaKXZreib/Ou83e8PiZTLDh52QA+Z1DeXFiwmTdQrEPvtnSePlkqinyZjZC+boMWDWnyUDdAsa+X6QO8Pu36w9JxXmW+iazuE1dwhbeUthmYg4SePql7W4BmRpG+b/jFHMynKbeMqif1eji7PusDUNFsBny+gk75StJASDdwl9CRVJ2ePrxnQwfiqJK+ZTxeyOJZCbdvYjtsxtO6PuTFI5PMQIK+oloCwhlSbrfeDg+2gqWePi8CblynPZO+p6naHY5zQTdyn6Jj75i6Pre6k/XyzIS+qvnrneZAiTfpvVd+pKiePkZ0b39kgZO+mjZlxXIsQzewA5d2E9S5PhhLCoXDI46+GpYky99cqrfYD3rfK6qePmqgFnaH7pO+X6hiBqDWcbdD15hQWpm5PgrMNIzLTZC+6uK2Qn1FpjftbOigl6mePrNfLXoQI5S+pBJi5Ld3Uzfp09S/OOe4Pg1nKOunx5O+78geNj5YlTd7m/eESaSePggsWhZJ6pS+SX8mGJHaWzfh4/8u17q3PjYHgZ2lLJm+175vT726cDfQJ3YbjpCePqaJTNbkUpa+seEYsIuAPTfAzzljm/m2PkilZz1Ro5y+kWw3KKF5wLest8Hm64CePk+OlbdJCZe+qQ4g48buR7e/R4Z2g7i2PiVVonUZ9J2+48u0fH+TZDdKz344LH6ePgVg9kvfIpe+e0ActEfMI7d2jZIzTaO0Po6V9J1HOKS+2FxWKaFombevUdPG9k6ePoNZMr8q3Ze+CPvb7vjklLe1pdMtIF+0PrGkBoZ536S+bQKCFLxTfTcxLG5w9UWePkcd9B5H9Ze+fGvlmgHqTzeKRFDeRq2zPitKHvU3X6a+8IEssdhPjzfk1/3ghhmePgw2gL0yYJi+4CGsM3kqdjfUwrYDCNayPhjPYtNECai+41qRusFgM7ftECQWRc6dPplQTmPV/Zi+anX7jEGmMDe3Ac/NacKxPgUzFsjpF6q+aJDSx9L0nbfM60vuqV+dPlGOWQC1wpm+1L3r+2ocZ7dbAmDZL3utPr1+2cCgLbC+71l0Ji4dnDd2eektwA6cPmgQDNnTNJu+NCRPDwK/crftlZR2m/SoPtzM4JYtR7K+DLkY2Hb0qree8VagkmyaPiWB4bytE5y+5H01IFiRbbcVm2eIenSmPln9j0VBV7O+XjzcCmXrYDePjAGbLhOZPgAfWns6YZy+JPIMBtpAVjeFAqxowWWlPlTgxMEyxLO+0vpc3055kTctJAnfGViYPsUiatMscZy+vVtDb7UGSLe9ZMgopECjPhHgMUeElLS+eo0Z7gmvc7fNy7G46pKWPtlGHwUoZ5y+UE0yWVY1cDdVO5nU+yCfPpthG0fW07W+rG2AMT8kjzcR6q49kOeSPvljODhGpJu+w5TNzj8/Z7efa/cyWemcPkdzruWtJra+rghC2JkdiLfwEe1vw7yQPqeJm9ab4Zq+P/AQCB6XIbfg9T9RZ4iYPhLSnxtppra+VbnwBtREazcy5jsoc2ODPh62asWvy5e+lekkJTWgSreZLE9GRRqPPhFe2QEwtba+sRUuslOlg7fKSAwJpKeHvvlEpVpb3IO+CM/J5JBYRTdlSkdFEbWJPi6XzCyPvbS+YH8d0CdjebdlTAcTqpKhvqg8jcM1zYY+D6LnoK7KUbdO3Dp3cA2WPojv2XbPt66+VDCUxP8TgzdnyBc7OjCwvp/1JHejRKc+f4WilLdnPLdXVDB0zNKhPnKqNv0B/qS+ANwLVgtXmbdUHYnGU12yvgaNqbs+dK0+YgAxVL1WDLc4BxEfgoWqPqZ16Oe5AJS+zTjKrXdIsDeqzra9+Jm0vr3NGXpaU7I+21W+Q+wuXjcb4LGj6Lu5Pr1OSw8ASZ4+SYIllltKtbf1F3HSYNe9vpVUiQPyrsE+k73koGzLQTdYVa6+X4DHPspg+Cxeobg+7kRB1+ZbqzfpjSCwZtPCvi88YUtI9Mk+4HbvAat+PLde8LN4n338upSqPskXpwa7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZVa6+X4DHPspg+Cxeobg+P/Ctm9hXsbfnjSCwZtPCvi48YUtI9Mk+NBs+bQh+jLduRP0wY13VPtMdEtnB+Mg+rYNan6xJubeAlzm4uJDAvlErVsQpBsg+9CqN6PZYhbcdQaNPK3TbPiQtVStEatA+Mqu0qHBNpbekUUIljeyQvhTxv4IGEYU+unu3hS3dozLUeuf65BPbPgmjlazKVNA+APEpTxuU2zcUQ8hf3TbIPgCGjWoZ4NS+WLapFiB4fLcB0H1UtQ3OPmXGbDcrYMI+ITk9wpDdyjdJLCUiigLgPvWgo+N2/Oq+taOdwdtnbLe/7He9sf6/PuuOyXooALQ+Qm65j0iP5Df9t8nu6oLjPk6VxJ7ja/C+soZHo70bdbdf9M5JwKWuPhfTcIM/JKQ+EwJKqhfd0jdeiSKYqa3kPsdmDMsrZvG+8Ecphs8Ndbd7Jz075wbIviGqgBPVp7u+zm07yEo31zfESeveU+jmPqnjfz5fRfO+74ooIsWFgbcV1RR8kwjWvsR7Ja5Ewcm+9GSCoyFBxDewkKih5yToPmidbsLWT/S+VzFhfGDimLfquSSHDkDbvgL2My+d9s++baRpNyoayrdLvWKkprHoPtkKe0ZxxvS+wRyAjjEeoTf9mS7DgibkvrF24P/Xvte+lxt2dQsExrcl7saXTM7pPhuIOgagtvW+Eg3ntBbUm7flH9z9EpPwvh0u5YYsmuO+yR+X4bjH7TfZiCk8OGzrPjqXO2y2FPe+EaL95Zwusze9cnO+tnf6vuK09SlVXO++l+kWJgDl97dsCxkkxiXtPkhuyj1Ti/i+AApXW+mvszfotLLraDX9vq77QFoJUPG+6OjuUQYAwTcufiRWoePtPiW9Cv/CLPm+EX/g0O6klbfLhCF/c3X/vgX61T31pvK+WCC0/T5PrLcgKRzzQnPuPinHhZT7pvm+EtMvikRYgzcqxazdcNUAv8S/haci9/O+WfEqoddfBLhWcAP7kdDuPrQ4fcpv9vm+AzhUYImcnjcmyQHOw2ABvwVL/rCMnPS+Z1ZZMfIs9bc/jHy9/eTuPkbsohLWB/q+mnctvR1RtDdk88q00sYFv19Ms2sg1fm+eOiyniMEsze6uA5aoHjvPkprjrBMh/q+GQEhYH6517dCjDBt6l4Gv/iykVRJifq+jxmg80S7BzjiGaQ5QorvPr2iiPeSlvq+X+BgGK5Rh7cFLXBZTVUIv3WDHDya1/y+mKCiFSW00zekyWWLmvnvPkTz/WUN9/q+NKz5uF85qreU0lFGJJgLv1Vzq0lSVQC/LwXxh9a217e3AdY99lXwPq8DRqWWkfu+xyyed3NioDfZ3PWsEpkNvyqDjJGNggG/Rsdy5aQVorfudLF5vnzwPpUnxuTS1Pu+cJx5B7SC1Dfq8v6yOUMOv6JLPBW15gG/gTpJXmf44LfTvmMwdYXwPqMnrmzv4/u+nC3voOtWVTeIIZ0t4zoQv7zFl7R5MwO/mz8GsshH8LdhxGJTwpPwPmWMb14F/fu+81wPymkFqjcI9JlZk5QQv0u9fwvwnAO/3N6ZaF6a6rdggDitXJrwPnXLILO0CPy+/oaoDq+Gmjd0Xgv9VzMRv82g0dw5VwS/aWe3ozJh3TdipwyHjKbwPpDzk2VaHvy+ZTxeyOJZaTfsHAkN5IMSv2b6N/eg4QW/94xrMpW53De9gDgxBLrwPoSX/6tRQfy+b/jFHMyniTfPSf2ik0sTv5Jug8cJzAa/lIvzBiNUDbhg5xGuDb/wPhaMvq6tSvy+b3/I+NYd7LdfweJcn9oVv8BYszaw0gm/CSNefu1f/DcbmbayP7rwPomGq2FoQ/y+gVpfBzRS1zcR1qy185EWvxYzINc3qgq/4e/UPFTt2rfBj/iUJbLwPmKbHVVMNvy+kqCv9rQm07dS1MkPGgMYvyptDtoEXAy/QwM2VTy38Lc2MTC6g5zwPhtqbD3XEvy+cMCHyqO0eDcVf2WMon4Zv7RiYcTCGg6/2ZbTP/o3LbhrYbSufITwPvAlJh0I6/u+hOW+JXVS8zd2t/sxtFkcv9E5Z1N8vRC/Q138D5ir5jfNoeSFc2LwPuZDA6Nrsvu+bsmaYHfGwjf/Ybk1Up4dvyW+JBWHfBG/K2VVsvOE6TfOp7P8mD3wPiywixz6dPu+BiNl97s2wDehd+4QYXkfv5N5x2qDkxK/Al820kP46jdY5NAMYN/vPpwFcqOl8vq+f0QGiSrinjePP+Zrrlkgv5e3rFA3TBO/nm9wchaD+7eHePNeQYPvPqjZot5rpfq+znd7QQZ28be6oORzEbMhv435kyNE5BS/Nv1ikHO9BjgoD/Q1igjvPofinVCtPvq+kEOmZ6/L5zfI9h8zX1civzmQD3RmpRW/iZWwHLZQ1Te+IREQh37uPh2d4F8vy/m+kE39IQ/m2DcAISpnBO4ivygRfogFVha/InLmrtal1zfvU5zwt9DtPqiTgGKpOfm+2/8+nOcez7dvoTh5Ojcjvxqlu+Lcqxa/YOXeFW/RJ7hNW1vvQXftPrV08K/C7vi+AAAAAAAAAADsZ2Q5Ck8kvwN47lYn9he/3V2hc6PfRbhwC4eZ1dnsPq1VNiQ7a/i+EodT18ON+Dc44Hy+W5Ekv9R6jJGXQxi/C8rH144F7LclcV+VZyTsPgKeJG7I0/e+a7deoMXcnLd7DrWFmvYkvynp7EpKuRi/FNZejSPozbfw/gRIo7vqPg7zHi5Dpva+Xct1eluwj7cTU1NliCYlvxUvdSMT8Ri/7etaqIwuy7euoMx6CR/qPnl8DxA7I/a++yAES0Vpwje2ex+OFkMlv48ed69sEhm/W3J+YJPu47fW22HFXdbpPiQ2tOVj5vW+iE65+jhbxTe+iv5AD6wlvyyWl20Ojhm/S25noXPcPbipzHnc4FrpPi71PBxbf/W+JaludBt/yLfS0JAXK8Ylv0NAv7eRrBm/d0QlEJV+5bdh8a9FzhzpPtgaGY6YS/W+chyT1pMzrTfQMH+VHAwmvyiDbXPg/Rm/xn5PZBIJ7jckwRBmpSroPhqLINqDgfS+v9p+HUIivbfWk1mEJnAmv2KFHkl0cRq/1twz21AMubfYVqnFMl7mPtvVAZXBAPO+c8v9peV2wjcpL7n76q0mv/Z95pX7uBq/y/tKrm3uLLgwTluw/2jlPnd+OgqZM/K+rSh/i+7M0rfYq1JZrsYmv70DZhkO1hq/Z/EQz6WL47fJQXe3aUXlPrwOUSzOFfK++EActEfMc7eComtbQoQnv0SA3YpktBu/bdGrmvCh+rfqzdNlOxLkPjJ21TLfF/G+TkrpoNM+9be0bLT185onvzEXCfL4zhu/zmB+tup98jeNSiHUAuXjPjiBADaU8vC+gwOCbguKgzcXwYiQ2cYnv7RykynCARy/Y6/WrhXr6LeBr0auwxPjPiYq+8D1RfC+2k4k94ootTcT4kE1L/Anv4p3lsT5MBy/EX4sjwnkvLcCRTFTUMzhPofflRdQb+6+bQ24tvIirbfN1EvARx4ovwJer4FBZRy/EKThoAS/ETiTjUbEBBPgPnDqTPIgluu+mwhE89ck6bdGYeViPboov1Fo6Sf0GB2/ka+zCTD5VzcnycmnK7fXPjLNUAugmuS+viyVtJYA0bc7fvnNJQEpv2coC0F6aB2/Bp4gT2HB/bctFk8DusvOPvieS34JZ9u+HrTqjwmGBTgT6HW7yBUpv3SfoqMrfh2/GfuNFCDxyrdrpOC4tQDDPnl4dPvdmdG+kseZfYJje7c5h4YU4xkpv+OAlT7LgR2/4gx3y6cuz7cQSgu7vC+6PlJuiGmMX8m+ivSwpOcN0bdZerhhaxgpv5vALWdifR2/+p1YTcD+0LcYcxKvSb1kvrQ0iOZVR5i+vjC9xIf637cZbrZ3lPYov8re50IxUB2/WP0dF2NA2bcGh09P5+rIvrBX2XJF/9I+DO1BxAZi5Tecvr3rRuIov5Af0BhvNh2/5UFfalgL3jcUV+pDJfzSvpX498Pr590+lrO02fwkbLewZ15w/pwovzNHk3N84By/h8xNd4G97LeCbnyns13jvvajDZZde+8+iS1kde7c0LcCagfpUDMnvx+4JjVaKBu/LRyY6xD96bfpkMYXwSD2vt3UopvJVQI/YGlihhZ2rLcoPa68du4kv9OL2vitbBi/ri9nqbwT/LeaCducUd3/vqOA+gRgmgo/sWk/zn13rLfsUzd+o0ohv1DRDPVeEhS///jhgLRA/LcvwPIdgrsDv9pea28YmRA/f4WilLdnrLfOIkvoooYdv6zRIvSFEBG/SiG0NGaMy7evpQqN7kUEvwGK5BYUGBE/X3iPaQd0y7ecjlFx8V0YvxxenYR1Agy/yFxhEH+r5zdbfGygO2MEv+6QwB3EPRE/Vdhn5WVonDckmYY5RWkOvzvbebuKOQG/mZkELpHE67ei8rFw/GYCv/TBiSR0pw8/zW9zFJjp2Ld3MrN4N+j8vpczzKCdA/C+GAhdfHkh8jevTGdr0nj8vrR7ttyuKgk/DKhU/CLzkLMQlI2CLql3OhdLRKYogQs7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6MrN4N+j8vpYzzKCdA/C+DDypHWwT9jetTGdr0nj8vrJ7ttyuKgk/NBs+bQh+nLenxeWo/w7jvheb1naLptW+RjvCgJJ4A7i0vrZ9DTjzvqZGkzjdxAE/9CqN6PZYlTcTITsjR0ayPsz30WMfoE8+B1BIToht1LeIkxgckJTlvtCyti2Vm/U+009Abj4DoDcSs//pOCLaPt0UhA1WdcI+D8WgoQNX0Dc7L9rp8BvNvj1G/U/Bi+I+wkj/EBhalbeqCj2frYDdPia4Ecwk5b8+KJT0WdW51rcRjo025DHBPhZNl9cJMra+yDo20eRNhTe8kA3DeSDbPmvKeK3TDbc+0LvVi0Pol7dLAIVZnfnLPgUDnAi3KtC+toZHo70bZTdlP34MApDZPsBBBWJE+bE+3h5E6dswzLcZZ58QMRHPPp+36wCPTtO+8kcphs8NdTfoeD1se6jTPrbqQHukGi++sZ1EQIMelTdKmkbwb9jRPsMcSltUR9i+4XfaaTsJfLdfcYHbiJXPPs//L6B7i6a+zXkiUE4l0zdM/e7hjsXSPqIG7o4od9q+Uggy2A3kfjdDXKKa35DLPkbxmN0M+LC+h/q7AJMskLdVv5L66hvTPtVxqTtxUdu+oseZfYJjazcA0SUdr6PBPsmpAkF1yL6+Q9bkir6H7DeP3ftwjqLTPrgqtArZyNy+KWgQMY5kkbejPWJlvH2Jvic5jXIZaMy+Wxraj2+5yLf7SMfj1QHUPl8+FM1ARd6+YHefq7XmezeIprAY2HHNvh4ympbxU9e+cC9kRisD5bcaM5ckLerTPl+RyVvmC9++h/jv1E0arTe46yZ6YszTvlRmB8qPrNq+CirR0H3FvjeGVdxXrLrTPsooWrYRI9++f6nwHLtjl7KTEv6ADtvXvjRr7RFcU92+49GhTkFl2TdBr0S4yY3TPoo3lKShJd++pdjp+DvtoDfG96zKvE/bvrhU0UIYjN++4iurEcBSs7e7HkIgCmzTPrYBQnqLH9++3DYTqYPXVDd9gQW/qK/cvjCewbB4NOC+7hh/1OFzqjcuM89P9WPTPlS6oW0DHd++1XgQbxolrjdetcbLZ87jvh0qISE/neO+beMCUI7JxDfiqZ9ssifTPqsSPMak996+0M+w1Dqyvbdgc0j4UXzkvs1/xeNCCeS+KdJ27Whlybc+jpLnUx/TPnSryb3t8N6+UppdQxHGibf4vGQ+/XrmvnhhMO5DTuW+jB0qz5FWuDfGQmx5M+HSPuoFXTsXvN6+90aJtPXcm7foz6+VHabpvje9aiqtUue+OHcndYIx27czSOjqrF7SPhqbVALZRN6+U38mGJHamzee1voOIJrrvgaHlotdjOi++up5qQF2tbdX+owuqRLSPvFE7h6I+92+pYJLl60/VrfHCn0Lj0Psvq4qWGAx9ei+zdSu1i/Y9bc257LxDv7RPgTB0EYg592+g72ywY7x1LfilP7jyJLuvrp/MzIiWuq+zH3y6uF50LfcpOjNFNPRPmGNvfJuut2+Yvwt0ilHbLPtKXMHW0Hvvm0boSLFxeq+llcY2uVFxLdmxeSGNLjRPpjOOT6and2+UdxFpe3HmLckG907XTbwvpJAYAaUf+u+ZfNtyCTxqTdYNUlBP3zRPpxWThWQXN2+DyDk9IDvijfOHzcWM2vxvlRfBS/E/uy+Rl+KdlonsjfI6GfzcOnQPvQabBdsuty+R3qUFdk9g7ePwj5vdSPyvjQbEOnj3+2+NXx29xrk9rcoLFwRzprQPsLsaIAQYty+Mp1tRtYwmjevI/Wqbar0vmB1qtHbavC+Q7f2UsQIALhIXApS5E3QPj361WStB9y+O8NoWMOZyrd2znFo61P1viwMnbS+z/C+piWoxrN+hDehd4McvBzQPg9nXhnAy9u+HxdD3cHvnjeoHB30M6X2vmrpe3u6l/G+Vr8YSAi/wDdztxMxDW3PPu09unlrTdu+VPqfQtw0zjdqxuBVUwL4vkaXfqLvY/K+fbxmoHhoATjbim95s7rOPiqjOZZ13dq+VstEfD37nzc39nFvdLj6viC7+EG38PO+bhngt52wCziyL4Ch7/3NPv+pjthpY9q+ZNzvKE8gyDfmrdybmt77vhPkc3pQmfS+Jpexpp441DfgUdvhLFPNPknxxzd48tm+17yf4zoDwzeyO6x+roD9vt4Qz2jsh/W+0QeaTDnWojeaDyjawgfMPsX5FzYVFdm+rWym/9Gnn7c1E+aUkJb+vrp3YiNhJPa+iWduaZwV9zcWFz9Em1HLPilsFkpHmti+hy7iV10KjjeU8H2pHIYAv8jfjAf5gPe+4q9+IOowC7j5s0q153TKPh20vBgJA9i+QLxaahSI67e5NERlPRQBv6Cw6p39HPi+k7+uOdQ4y7cFuiHn7o7JPpglX04tY9e+Diq2WJgZprfX/sAocZIBv7exvwnwpfi+EqkeNR59uDd/YJjAHXfIPhtHCWt6n9a+pT5kILIVlTf1I8mhZs8Bv1i5GvNy5/i+KkiJspxY9Lfd9q46eerHPvVB9/GtPNa+4joABcrygjeFQVotccUCv/ExgHZU7vm+3fqvLT4iJjh/GxON0PzGPriCadE2lNW+bIZXA2b70beUd30JofkCvyXQ73yUI/q+TjaKa141o7e4DnyYTvTFPsFuxPxC19S+BaNk+pGqnrev/Q9b2EQDvz23ct+Dbfq+i2w/f9t6uTfgAUTrQO3DPuUg96+tY9O+R+HXOzF9tTfQpYj/d2gDv+rM+Iz+j/q+twj6SbWkoDcVTV/qpA7DPikI/PMBxNK+tlM9h08yYzf/9hJPVn4Dvxm3FCBHpfq+/vE0XJ4eFrgVfYSsBajCPsGU4FxSetK+OUJfbsS02jeklNV1OtUDvxYljcfx+/q+9A+5BX2x97fcxln19vvBPsHucaxk/tG+skVrHkiCnzcddE4xHekDv7U5g3a7Dvu+z613Bx6kmjdZIDj0gabBPp9vX2eywNG+7grddoyNtredFX8EChsEv2cLCB10O/u+mh6GDVPtjreQZVyI81vAPkt5A42x0dC+Awe0TslMhTe/Z4rtNVwEvy0BXpYXcPu+YrhfNjL9q7dX56UHyuC7PvoFtrQ7Ic6+oAuc09tjwLc0Z3vwtYQEvxhuH7LQj/u+9uIDcIlr0jdbPXkOTla5PmGU5QKWSMy+V8ccDipjmrdbdWevipcEvyHRTmVioPu+ZSH97T6jtDfUjereufi4PqpEUB1+BMy+Hd0lufyG0zd3SMoB7CQFvyFmLCg7GPy+WMVlXOLtwbcU027xNt61Poommv4Qw8m+Q53Bni+7nTdO39TveTUFv3z9zV6sJfy+TlKvZ2sVCjgU71NiS2u1Pkq03xdlb8m+P+lumiWElDdRjv90YVAFvwQK7O98Nfy+bhWShWJiujfMGYjw+lqzPg79X1FM7se+rum/kngCrDfnN4AMp2QFv6b5gMPfOfy+pNC/A3I1ozewBUe6jSewPqHm0ScGmMW+D2YEeCzNvjevznct4ncFv9b9EJ3/Nvy+AcBKdO+w3zf57TfMHcanPr3G7pHFeMK+nJ6lBA1kWzesyN5eIM4Fv0FVSmiBUPy+WJpmNmBrx7d4g88lMjB8Po9B5CwoDLa+J+TBNyfT3zctZZPdU+EFvygeZHXVKfy+dOV2VeBqpTdEABhqRWufviPeixX1Op++Ok/FR2KA0TfD5tEwtNkFv2myw7ME/fu+LMf7GlMCt7dDrkOwvPWsvhJvLYWWXoA+9IICDM4C0TciZOAG8dEFvyQyBLku5Pu+KX/Ahm0YqDf1jxxx07+xvqFjkjp7rJs+gAXMOgmYdLeZqYKElbgFv5tWnZEopfu+KG80IPfUszeu9cSwzQ+5vtHCMGy+2LE+jsge6zPWwrfQIhAFYm4Fv3YCE/DHD/u+lQuQxqOpv7fv7TEbnQbDvrQUSubcr8I+Qnu6qJDTrTeqYW8NIE4Fv5XMK+XM1fq+zgTGCnsytTfhICKkGF7GvloSwfWAvcc+quA3e1Jxv7fyNjLK2/EEv0/eB7q/PPq+H4KpViNBwzcR7Egbex/Qvs2OkCrrX9M+8sWNFp9mXLc4jESGUF8Dv8aOaSv41/e+cnNj1CjSozfTC2fhja3bvsQpMmvwmuI+NByWtVPnmDeYyeWKDB0BvwtH0FFCk/S+bxDD3zr60DfMSKAog5nhvq9ifFouqeg+ahmuYmp3jDcsFy9eYK/7vjLcTlQe9+++f7gHXz13xTd/1QxQpzfjvtNATdi5xes+fizHh2Fbpbc1rJ+n6OH0vp+uwLB1sOa+oS0JtKB03reKXVGy9lXhvg7ztI+sCeo+1ZdvZN8fVDPnGIsK0Y/8uvU9KP/yqAS7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1rJ+n6OH0vqGuwLB1sOa+RfgIGfsj+jeJXVGy9lXhvg/ztI+sCeo+lWQxAV/QgTfRK9qdxmTvvpeKbV0O/d++DUssgskl3DdQjh8ypnfbvsGxZjbzuOU+tikgSULMcbeB/T5fyRDovl3VLGiLCNe+tB2lxP63sjcG8Zx82BXWvmQz9Y/PZ+I+juKRNE55jDdmRTftcpvhvn0wkwUsPc++7KgA6DOox7dx53tqVAnRvoLSrhGDW94+CB/egqR5PLd66L5zdrPYvvHuubOlGMS+b8JHiohDp7fKRRRtkTHJvjrjdv5uZtg+ZNRi+M0+jjdH0aaGAG/Svrkck/ozCby+Y0zPT8tm1rdl66BtEXPDvsjEaxL6VdQ++jazfvFkdLceuTfSl7HJviiU5qX1qLG+6b+7/kcRwDceQz7iXvnBviTMTqowPNM+fWAH36pzY7cIVNezElC+vmFCPi9MVqC+hjLAAnSK1DfF8hVEzqbAvln+s1taL9I+oUqs745hLLcczwXRI0WlvitIhM8bX0W+EcWBAYLJtTegIOIqBs23vlfYe4rlKcw+QzY+x9l4PLfy2c9SZ1CdPhYQ371BAJk+FwW6uQO9mjfKwPaIMJutvr5ZuUvMTcM+p3wc9/NuPDeVjsjaV/OnPhjGrjMCzJ4+/DJnfK4+kjfICsAShjmovvzx+ub1SsA+bQ+6SWhUVbd1TWWqtRa2PoVfgPyEeqQ+kFNR7pevn7dAPB18ph+Svq+8OOKgTac+9mWrYPBdRTcE8bunP2TlupGeWFShJc26AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2iKnP+k21Pume6eaUsaU+Y2vdnun5nLdOvGOvVANuPhFCWxwR9pi+CcWhagJyHDey+RszZGuyPgJ4rySNm6Q+BhYntQ5qorcn/8YK9gyCPn4v/7pV/6O+4Ie99cfudLcmndU1/kGwPvPJ665Wo6M+qPKe0ieDh7frLXkJC1mEPm5HFGZpd6W+M8ixlAklPDcSGuFpcIOmPiJNfTq7OaE+wJtmlJubebflCCpuIqaIPuVDwO2Ku6e+H4pg5hyPcjesOZKhfK2XPjE8GjVg15w+n0p00WnInrcRHm1WYRWMPuzp1uQ2zqi+62dCeD9xUzdOa2cPA2lgPoyNKYJ8qJY+Rg0OnMguhzcNsihOXpaOPsfwhzs0rai+sSWwD8XEazfiQwbseU+Svoy6t5dEX5A+A7Q7L3HPcLdhQoZocd6OPh+q7SHWa6i+pxDoOOlY7zI1ErzO2i6jvnIwORuuFYQ+EY7Zxik3mTc8jbsire+OPpb6ZC2Z7qe+aqR8kn1sarfIkUudyfWsvjLuo/fRuW0+ZUX6PuxpZrccOeKe0seOPmrJ6dafNqe+bYDbK7NGWzekdovwFjKzvlYKEpqjeWS+DLQ7L3HPsDfhWjaZs2WOPquY5QnURaa+bYDbK7NGG7cUcWbvULG3vvOZr7zwd4G+lVLv51/OiLdQ7UlaMMmNPrQtIBXhHqW+e/BWkYmvTjc5zlwfgu27viOp52JZhY2+ZUX6PuxplrcewreXM/OMPiYD4LcrxaO+S+gmLpvAcjf+oTl8Ydy/vlF7UI86l5S+9UqPzHgCiTceaL9CrOWLPqZY2GHIPKK+S+gmLpvAUjc9qeVzSLrBvkz2760NLpq+wJR/RMd+RDcGGUxNhaOKPoQUjsJviqC+WqKw+cFwhzfhI53s3lbDvgwE3g5HfJ++1GKcSJHZfrdPgsV2mzCJPsXxKpXjZp2+aYDbK7NGKzcxX8GWX8DEvsq6kLP2O6K+oYg4icm9oDcCvZc6sZGHPq4OxYxOe5m+iB6Qqw8lebevUF8tVPPFviHem1M5i6S+vZFm1UduZ7c5NRKaysyFPhtnQ4ikX5W+IZtjE/z2crfmvRZGNO7Gvh8chtchqaa+g5TX0x5UhjcTsQjR++eDPuRqqW6KIJG+IZtjE/z2crdpwYI6da/HvvkN19yVkqi+INkzEPizjLd/AtVaWuqBPg0hgSM8mIm+27jBLe6eULck/iIbSzbIvobVs30+Raq+AAAAAAAAAACiWZ0qQrd/Ph/SGhEO4oC+0E3+Ef45Z7dFmZC5roLIvlR+FCOYv6u+g5TX0x5UhrfAvRcoO4h7PrjPLtlHeXC+x7p6UQ3pczcAM3vDYZXIviMYQFcAAa2+AAAAAAAAAACfPAibOVl3PmTTkEpztBw+u83kuSilgjfZepLt8G/Ivg8tv4nBCa6+rV4K9O/Vn7cHmQzTrjxzPr21SuWQwnA+jHdEKnNGC7fq2wY0tBTIvimlh70c266+U9NJ8nzxjjfW5uHxd4tuPtnaZks8HIA+JKdLEX9bibfkTuE8zYbHvvbCFiJRd6++AQ8HMRrJgzdGRJv4FRBnPnR6+jvdS4c+aH0F+QlPdTc4XgfvI8rGvsFyaqCh4a++G0KCCUWfojfhdfo1US9gPh9lGohd0o0+UC89mhvBlzfno5TxLHbFvsCuaYHRp6++SoRs1GaYmbdZszcJ+f5fvvb+IwCMC54+8kT0+x9HTLdGBwEHgXDDvpndZY5Srq6+tYWP3pl5mTeWhQTIPcF1vpbQo1K3c6U+/pva8ddwgzfa8yENvtXAvulpp1SZE62+JVcy0FbMdzdrxn62dIOAvlW8WesMtKo+/UVNThBTZLc18ndwSYa7vlPgPuXd9aq+KxPB6IZsqjdRm9bRusuEvsyx6Erkta4+7WdhoyVXXDcaOn/GFRm2via4VsJu46i+BOo8yO3XdLcMAvUYAQ2Lvhmk+z4CVbI+erSmb7Rj9bK5W0zxLmStvnhkKkjh2aW+Q5pbQ4mQmrcP2IepYoSRvhph8PeNR7Y+5wcnJbHLaTck4ARjfYKZvkiZciZcXqK+LZe/jg3xZze5B9QM6Q+TvjUg9icEErg+KbxDSTeTQzdh8OEIRXzMOo+vBLZZC1M6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNX7IygU6RPpqubRVacZy+mJAFeEPqprfboVFPQZKTvjt5uBw+7rg+LHxoT/QgBzevKMYaofGoPtzMCSgpHZa+kJ9zhEAdsLeuJ8mhRe+TvoMLEZ6bTrk+6ghCSuE71bb+a7iFaCaxPjtIhXYecpK+Fy7dVQCixLfdToo6yAOUvvku/XUqXrk+UExYgiURcrdHVVcD9fezPouDa2CDOZC+bF+24AL8p7cVOZqAOwWUvkQyBHwkX7k+Ps9qDhIZyjZ5ObPlc42+PgdumkpnlH++AqAjDzkIsLc4AjcqxAqUvq2KSbd2Yrk++8yMBEvA2zYdWoGvE5PEPimk9l1LxD0+V5C8KbiowbcsXng5qQyUvsTTH4VSY7k+FNV6HHsZ5TY=
+ </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">
+ 6AUAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAABAAAAAQQAAAEIAAABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAASgAAAEsAAABMAAAATQAAAE4AAABPAAAAUAAAAFEAAABSAAAAUwAAAFQAAABVAAAAVgAAAFcAAABYAAAAWQAAAFoAAABbAAAAXAAAAF0AAABeAAAAXwAAAGAAAABhAAAAYgAAAGMAAABkAAAAZQAAAGYAAABnAAAAaAAAAGkAAABqAAAAawAAAGwAAABtAAAAbgAAAG8AAABwAAAAcQAAAHIAAABzAAAAdAAAAHUAAAB2AAAAdwAAAHgAAAB5AAAAegAAAHsAAAB8AAAAfQAAAH4AAAB/AAAAgAAAAIEAAACCAAAAgwAAAIQAAACFAAAAhgAAAIcAAACIAAAAiQAAAIoAAACLAAAAjAAAAI0AAACOAAAAjwAAAJAAAACRAAAAkgAAAJMAAACUAAAAlQAAAJYAAACXAAAAmAAAAJkAAACaAAAAmwAAAJwAAACdAAAAngAAAJ8AAACgAAAAoQAAAKIAAACjAAAApAAAAKUAAACmAAAApwAAAKgAAACpAAAAqgAAAKsAAACsAAAArQAAAK4AAACvAAAAsAAAALEAAACyAAAAswAAALQAAAC1AAAAtgAAALcAAAC4AAAAuQAAALoAAAC7AAAAvAAAAL0AAAC+AAAAvwAAAMAAAADBAAAAwgAAAMMAAADEAAAAxQAAAMYAAADHAAAAyAAAAMkAAADKAAAAywAAAMwAAADNAAAAzgAAAM8AAADQAAAA0QAAANIAAADTAAAA1AAAANUAAADWAAAA1wAAANgAAADZAAAA2gAAANsAAADcAAAA3QAAAN4AAADfAAAA4AAAAOEAAADiAAAA4wAAAOQAAADlAAAA5gAAAOcAAADoAAAA6QAAAOoAAADrAAAA7AAAAO0AAADuAAAA7wAAAPAAAADxAAAA8gAAAPMAAAD0AAAA9QAAAPYAAAD3AAAA+AAAAPkAAAD6AAAA+wAAAPwAAAD9AAAA/gAAAP8AAAAAAQAAAQEAAAIBAAADAQAABAEAAAUBAAAGAQAABwEAAAgBAAAJAQAACgEAAAsBAAAMAQAADQEAAA4BAAAPAQAAEAEAABEBAAASAQAAEwEAABQBAAAVAQAAFgEAABcBAAAYAQAAGQEAABoBAAAbAQAAHAEAAB0BAAAeAQAAHwEAACABAAAhAQAAIgEAACMBAAAkAQAAJQEAACYBAAAnAQAAKAEAACkBAAAqAQAAKwEAACwBAAAtAQAALgEAAC8BAAAwAQAAMQEAADIBAAAzAQAANAEAADUBAAA2AQAANwEAADgBAAA5AQAAOgEAADsBAAA8AQAAPQEAAD4BAAA/AQAAQAEAAEEBAABCAQAAQwEAAEQBAABFAQAARgEAAEcBAABIAQAASQEAAEoBAABLAQAATAEAAE0BAABOAQAATwEAAFABAABRAQAAUgEAAFMBAABUAQAAVQEAAFYBAABXAQAAWAEAAFkBAABaAQAAWwEAAFwBAABdAQAAXgEAAF8BAABgAQAAYQEAAGIBAABjAQAAZAEAAGUBAABmAQAAZwEAAGgBAABpAQAAagEAAGsBAABsAQAAbQEAAG4BAABvAQAAcAEAAHEBAAByAQAAcwEAAHQBAAB1AQAAdgEAAHcBAAB4AQAAeQEAAHoBAAA=
+ </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>
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+ )
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+ )
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+<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>
--- /dev/null
+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
+
+
+
+
+
+
--- /dev/null
+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
+
+
+
+
+
+
--- /dev/null
+# 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)
--- /dev/null
+<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>
--- /dev/null
+<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>
--- /dev/null
+<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
import vtk
from vtk.numpy_interface import dataset_adapter as da

####REPERE LOCAL

##deux extremites de la ligne de coupe

P0 = inputs[0].GetPoint(0)
P1 = inputs[0].GetPoint(inputs[0].GetNumberOfPoints() - 1)

R = np.array([[P0[0]-P1[0], P0[1]-P1[1], P0[2]-P1[2]]])
R= R/np.linalg.norm(R)

###vecteur normal au plan
L = np.array([[1,0,0]])
L = L/np.linalg.norm(L)

##complete le triedre
C = np.cross(R,L)

##matrice de passage
BBp = np.concatenate((R,L,C), axis=0).T


M=np.eye(3,3)
B=np.eye(3,3)

siefNoeu = np.array(inputs[0].GetPointData().GetAbstractArray('RESU____SIEF_NOEU'))
arr0 = siefNoeu[:,0]
arr1 = siefNoeu[:,1]
arr2 = siefNoeu[:,2]
arr3 = siefNoeu[:,3]
arr4 = siefNoeu[:,4]
arr5 = siefNoeu[:,5]

arcLength = np.array(inputs[0].GetPointData().GetAbstractArray('arc_length'))

##remove nans
nans = numpy.isnan(arr0)
arr0 = arr0[numpy.logical_not(nans)]
arr1 = arr1[numpy.logical_not(nans)]
arr2 = arr2[numpy.logical_not(nans)]
arr3 = arr3[numpy.logical_not(nans)]
arr4 = arr4[numpy.logical_not(nans)]
arr5 = arr5[numpy.logical_not(nans)]
arcLength = arcLength[numpy.logical_not(nans)]

for i in range(size(arr0)):
 S=np.eye(3,3)
 S[0][0] = arr0[i]
 S[0][1] = arr3[i]
 S[0][2] = arr4[i]
 S[1][0] = S[0][1]
 S[1][1] = arr1[i]
 S[1][2] = arr5[i]
 S[2][0] = S[0][2]
 S[2][1] = S[1][2]
 S[2][2] = arr2[i]
 Sp = np.linalg.inv(BBp).dot(S).dot(BBp)
 arr0[i] = Sp[0][0]
 arr3[i] = Sp[0][1] 
 arr4[i] = Sp[0][2]
 arr1[i] = Sp[1][1]
 arr5[i] = Sp[1][2]
 arr2[i] = Sp[2][2]
 
M=np.eye(3,3)
M[0][0] = np.mean(arr0)
M[0][1] = np.mean(arr3)
M[0][2] = np.mean(arr4)
M[1][0] = M[0][1]
M[1][1] = np.mean(arr1)
M[1][2] = np.mean(arr5)
M[2][0] = M[0][2]
M[2][1] = M[1][2]
M[2][2] = np.mean(arr2)

w_m, v_m = np.linalg.eig(M)

PM = np.maximum(np.abs(w_m[0]-w_m[1]),np.abs(w_m[2]-w_m[1]))
PM = np.maximum(PM,np.abs(w_m[0]-w_m[2]))
print("PM :", PM)

B=np.eye(3,3)

X = arcLength - min(arcLength)


DELTA = max(X) - min(X)

B[0][0] = 6*np.trapz((X-DELTA/2)*arr0,x=(X-DELTA/2))/(DELTA**2)
B[0][1] = 6*np.trapz((X-DELTA/2)*arr3,x=(X-DELTA/2))/(DELTA**2)
B[0][2] = 6*np.trapz((X-DELTA/2)*arr4,x=(X-DELTA/2))/(DELTA**2)
B[1][0] = B[0][1]
B[1][1] = 6*np.trapz((X-DELTA/2)*arr1,x=(X-DELTA/2))/(DELTA**2)
B[1][2] = 6*np.trapz((X-DELTA/2)*arr5,x=(X-DELTA/2))/(DELTA**2)
B[2][0] = B[0][2]
B[2][1] = B[1][2]
B[2][2] = 6*np.trapz((X-DELTA/2)*arr2,x=(arcLength-DELTA/2))/(DELTA**2)

 
w_b, v_b = np.linalg.eig(B)

PB = np.maximum(np.abs(w_b[0]-w_b[1]),np.abs(w_b[2]-w_b[1]))
PB = np.maximum(PB,np.abs(w_b[0]-w_b[2]))
print("PB :", PB)
MB = M + B
w_mb, v_mb = np.linalg.eig(MB)

PMB = np.maximum(np.abs(w_mb[0]-w_mb[1]),np.abs(w_mb[2]-w_mb[1]))
PMB = np.maximum(PMB,np.abs(w_mb[0]-w_mb[2]))
print("PMB :", PMB)


MB_ = M - B

w_mb_, v_mb_ = np.linalg.eig(MB_)

PMB_ = np.maximum(np.abs(w_mb_[0]-w_mb_[1]),np.abs(w_mb_[2]-w_mb_[1]))
PMB_ = np.maximum(PMB_,np.abs(w_mb_[0]-w_mb_[2]))
print("PMB_ :", PMB_)


ca = vtk.vtkDoubleArray()
cas = vtk.vtkStringArray()
ca.SetName("Results")
cas.SetName("Names")
ca.SetNumberOfComponents(1)
cas.SetNumberOfComponents(1)
ca.SetNumberOfTuples(4)
cas.SetNumberOfTuples(4)
ca.SetValue(0, PM)
ca.SetValue(1, PB)
ca.SetValue(2, PMB)
ca.SetValue(3, PMB_)
cas.SetValue(0, "PM")
cas.SetValue(1, "PB")
cas.SetValue(2, "PMB")
cas.SetValue(3, "PMB_")
output.AddColumn(cas)
output.AddColumn(ca)

"/>
+ </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>
--- /dev/null
+<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
import vtk
from vtk.numpy_interface import dataset_adapter as da

####REPERE LOCAL

##deux extremites de la ligne de coupe

P0 = inputs[0].GetPoint(0)
P1 = inputs[0].GetPoint(inputs[0].GetNumberOfPoints() - 1)

R = np.array([[P0[0]-P1[0], P0[1]-P1[1], P0[2]-P1[2]]])
R= R/np.linalg.norm(R)

###vecteur normal au plan
L = np.array([[1,-1,0]])
L = L/np.linalg.norm(L)

##complete le triedre
C = np.cross(R,L)

##matrice de passage
BBp = np.concatenate((R,L,C), axis=0).T


M=np.eye(3,3)
B=np.eye(3,3)

siefNoeu = np.array(inputs[0].GetPointData().GetAbstractArray('RESU____SIEF_NOEU'))
arr0 = siefNoeu[:,0]
arr1 = siefNoeu[:,1]
arr2 = siefNoeu[:,2]
arr3 = siefNoeu[:,3]
arr4 = siefNoeu[:,4]
arr5 = siefNoeu[:,5]

arcLength = np.array(inputs[0].GetPointData().GetAbstractArray('arc_length'))

##remove nans
nans = numpy.isnan(arr0)
arr0 = arr0[numpy.logical_not(nans)]
arr1 = arr1[numpy.logical_not(nans)]
arr2 = arr2[numpy.logical_not(nans)]
arr3 = arr3[numpy.logical_not(nans)]
arr4 = arr4[numpy.logical_not(nans)]
arr5 = arr5[numpy.logical_not(nans)]
arcLength = arcLength[numpy.logical_not(nans)]

for i in range(size(arr0)):
 S=np.eye(3,3)
 S[0][0] = arr0[i]
 S[0][1] = arr3[i]
 S[0][2] = arr4[i]
 S[1][0] = S[0][1]
 S[1][1] = arr1[i]
 S[1][2] = arr5[i]
 S[2][0] = S[0][2]
 S[2][1] = S[1][2]
 S[2][2] = arr2[i]
 Sp = np.linalg.inv(BBp).dot(S).dot(BBp)
 arr0[i] = Sp[0][0]
 arr3[i] = Sp[0][1] 
 arr4[i] = Sp[0][2]
 arr1[i] = Sp[1][1]
 arr5[i] = Sp[1][2]
 arr2[i] = Sp[2][2]
 
M=np.eye(3,3)
M[0][0] = np.mean(arr0)
M[0][1] = np.mean(arr3)
M[0][2] = np.mean(arr4)
M[1][0] = M[0][1]
M[1][1] = np.mean(arr1)
M[1][2] = np.mean(arr5)
M[2][0] = M[0][2]
M[2][1] = M[1][2]
M[2][2] = np.mean(arr2)

w_m, v_m = np.linalg.eig(M)

PM = np.maximum(np.abs(w_m[0]-w_m[1]),np.abs(w_m[2]-w_m[1]))
PM = np.maximum(PM,np.abs(w_m[0]-w_m[2]))
print("PM :", PM)

B=np.eye(3,3)

X = arcLength - min(arcLength)


DELTA = max(X) - min(X)

B[0][0] = 6*np.trapz(-(X-DELTA/2)*arr0,x=X)/(DELTA**2)
B[0][1] = 6*np.trapz(-(X-DELTA/2)*arr3,x=X)/(DELTA**2)
B[0][2] = 6*np.trapz(-(X-DELTA/2)*arr4,x=X)/(DELTA**2)
B[1][0] = B[0][1]
B[1][1] = 6*np.trapz(-(X-DELTA/2)*arr1,x=X)/(DELTA**2)
B[1][2] = 6*np.trapz(-(X-DELTA/2)*arr5,x=X)/(DELTA**2)
B[2][0] = B[0][2]
B[2][1] = B[1][2]
B[2][2] = 6*np.trapz(-(X-DELTA/2)*arr2,x=X)/(DELTA**2)

 
w_b, v_b = np.linalg.eig(B)

PB = np.maximum(np.abs(w_b[0]-w_b[1]),np.abs(w_b[2]-w_b[1]))
PB = np.maximum(PB,np.abs(w_b[0]-w_b[2]))
print("PB :", PB)
MB = M + B
w_mb, v_mb = np.linalg.eig(MB)

PMB = np.maximum(np.abs(w_mb[0]-w_mb[1]),np.abs(w_mb[2]-w_mb[1]))
PMB = np.maximum(PMB,np.abs(w_mb[0]-w_mb[2]))
print("PMB :", PMB)


MB_ = M - B

w_mb_, v_mb_ = np.linalg.eig(MB_)

PMB_ = np.maximum(np.abs(w_mb_[0]-w_mb_[1]),np.abs(w_mb_[2]-w_mb_[1]))
PMB_ = np.maximum(PMB_,np.abs(w_mb_[0]-w_mb_[2]))
print("PMB_ :", PMB_)


ca = vtk.vtkDoubleArray()
cas = vtk.vtkStringArray()
ca.SetName("Results")
cas.SetName("Names")
ca.SetNumberOfComponents(1)
cas.SetNumberOfComponents(1)
ca.SetNumberOfTuples(4)
cas.SetNumberOfTuples(4)
ca.SetValue(0, PM)
ca.SetValue(1, PB)
ca.SetValue(2, PMB)
ca.SetValue(3, PMB_)
cas.SetValue(0, "PM")
cas.SetValue(1, "PB")
cas.SetValue(2, "PMB")
cas.SetValue(3, "PMB_")
output.AddColumn(cas)
output.AddColumn(ca)

"/>
+ </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>
--- /dev/null
+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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+};
--- /dev/null
+# 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()
--- /dev/null
+# 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")
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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)
+
+
--- /dev/null
+# 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)
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+};
+
--- /dev/null
+// 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
--- /dev/null
+# 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)
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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;
+};
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
+)
--- /dev/null
+<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>
--- /dev/null
+<RCC>
+ <qresource prefix="/ParaViewResources">
+ <file>Icons/pqCellData16.png</file>
+ <file>Icons/pqPointData16.png</file>
+ </qresource>
+</RCC>
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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);
+};
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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);
+};
+
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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;
+};
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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)
--- /dev/null
+# 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)
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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)
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+// 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();
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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()
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+<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>
--- /dev/null
+# 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']
+
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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 )
--- /dev/null
+1 - Read example.med
+2 - choose a cell
+3 - Probe Point Over Time
--- /dev/null
+<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>
--- /dev/null
+# 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})
--- /dev/null
+# 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)
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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
+*/
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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()
--- /dev/null
+// 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
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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
+
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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> ¢ers(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;
+}
+
--- /dev/null
+// 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> ¢ers() { 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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
+
--- /dev/null
+# 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"""
--- /dev/null
+# 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
--- /dev/null
+# 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()
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+// 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();
+
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+<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>
+
--- /dev/null
+# 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})
--- /dev/null
+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
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+<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>
+
--- /dev/null
+# 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})
--- /dev/null
+# 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
+
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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}
+*/
--- /dev/null
+// 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;
+};
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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()
--- /dev/null
+# 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)
+
--- /dev/null
+# 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)
+
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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
+
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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})
--- /dev/null
+# 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]
--- /dev/null
+# 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
+)
--- /dev/null
+# 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()
--- /dev/null
+# 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
+
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+# 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]
--- /dev/null
+# 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
+)
--- /dev/null
+// 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()
+{
+}
+
--- /dev/null
+// 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
+
--- /dev/null
+// 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;
+}
+
+
--- /dev/null
+// 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
+
--- /dev/null
+// 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);
+}
+
+
--- /dev/null
+// 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
--- /dev/null
+// 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()
+{
+}
+
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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})
--- /dev/null
+# 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
+)
--- /dev/null
+# 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}
+)
--- /dev/null
+# 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+# 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
--- /dev/null
+<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>
--- /dev/null
+# 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})
--- /dev/null
+# 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...")
--- /dev/null
+# 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
+)
--- /dev/null
+# 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()
--- /dev/null
+# 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
+
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+<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>
--- /dev/null
+# 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