Salome HOME
New 2 useful filters in MEDReader plugin : vtkUgSelectCellIds and vtkGroupAsMultiBlock
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 7 Aug 2020 09:27:55 +0000 (11:27 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Mon, 10 Aug 2020 07:30:15 +0000 (09:30 +0200)
src/Plugins/MEDReader/plugin/MEDLoaderForPV/CMakeLists.txt
src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.cxx [new file with mode: 0644]
src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.h [new file with mode: 0644]
src/Plugins/MEDReader/plugin/MEDReaderIO/CMakeLists.txt
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkExtractGroup.cxx
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.cxx [new file with mode: 0644]
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.h [new file with mode: 0644]
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.cxx [new file with mode: 0644]
src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.h [new file with mode: 0644]
src/Plugins/MEDReader/plugin/ParaViewPlugin/Resources/MEDReaderServer.xml

index 6cbbdd87b3a94e3f5aba93211b0084534c0ab9db..ce109aeef0f63f73a47f1b46fc9b82c114ac08c4 100644 (file)
@@ -17,7 +17,7 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-add_library(MEDLoaderForPV SHARED MEDFileFieldRepresentationTree.cxx  MEDTimeReq.cxx  MEDUtilities.cxx  vtkGenerateVectors.cxx)
+add_library(MEDLoaderForPV SHARED MEDFileFieldRepresentationTree.cxx  MEDTimeReq.cxx  MEDUtilities.cxx  vtkGenerateVectors.cxx ExtractGroupHelper.cxx)
 target_include_directories(MEDLoaderForPV PRIVATE . ${MEDCOUPLING_INCLUDE_DIRS})
 
 target_link_libraries(MEDLoaderForPV VTK::CommonCore VTK::CommonDataModel VTK::IOXML ${MEDFILE_C_LIBRARIES})
diff --git a/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.cxx b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.cxx
new file mode 100644 (file)
index 0000000..562a5c1
--- /dev/null
@@ -0,0 +1,352 @@
+// Copyright (C) 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 "ExtractGroupHelper.h"
+#include "MEDFileFieldRepresentationTree.hxx"
+
+#include "vtkInformation.h"
+#include "vtkInformationDataObjectMetaDataKey.h"
+#include "vtkAdjacentVertexIterator.h"
+#include "vtkMutableDirectedGraph.h"
+#include "vtkDataSetAttributes.h"
+#include "vtkStringArray.h"
+
+#include <cstring>
+
+const char ExtractGroupGrp::START[]="GRP_";
+
+const char ExtractGroupFam::START[]="FAM_";
+
+ExtractGroupStatus::ExtractGroupStatus(const char *name):_status(false),_name(name)
+{
+}
+
+void ExtractGroupStatus::printMySelf(std::ostream& os) const
+{
+  os << "      -" << _ze_key_name << "(";
+  if(_status)
+    os << "X";
+  else
+    os << " ";
+  os << ")" << std::endl;
+}
+
+bool ExtractGroupStatus::isSameAs(const ExtractGroupStatus& other) const
+{
+  return _name==other._name && _ze_key_name==other._ze_key_name;
+}
+
+bool ExtractGroupGrp::isSameAs(const ExtractGroupGrp& other) const
+{
+  bool ret(ExtractGroupStatus::isSameAs(other));
+  if(ret)
+    return _fams==other._fams;
+  else
+    return false;
+}
+
+ExtractGroupFam::ExtractGroupFam(const char *name):ExtractGroupStatus(name),_id(0)
+{
+  std::size_t pos(_name.find(MEDFileFieldRepresentationLeavesArrays::ZE_SEP));
+  std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(MEDFileFieldRepresentationLeavesArrays::ZE_SEP)));
+  std::istringstream iss(name1);
+  iss >> _id;
+  std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
+}
+
+bool ExtractGroupFam::isSameAs(const ExtractGroupFam& other) const
+{
+  bool ret(ExtractGroupStatus::isSameAs(other));
+  if(ret)
+    return _id==other._id;
+  else
+    return false;
+}
+
+void ExtractGroupFam::printMySelf(std::ostream& os) const
+{
+  os << "      -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
+  if(_status)
+    os << "X";
+  else
+    os << " ";
+  os << ")" << std::endl;
+}
+
+void ExtractGroupFam::fillIdsToKeep(std::set<int>& s) const
+{
+  s.insert(_id);
+}
+///////////////////
+
+bool ExtractGroupInternal::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 *ExtractGroupInternal::getMeshName() const
+{
+  return this->_mesh_name.c_str();
+}
+
+void ExtractGroupInternal::loadFrom(vtkMutableDirectedGraph *sil)
+{
+  std::vector<ExtractGroupGrp> oldGrps(_groups); _groups.clear();
+  std::vector<ExtractGroupFam> 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());
+          ExtractGroupGrp 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());
+          ExtractGroupFam fam((const char *)verticesNames2->GetValue(idf));
+          _fams.push_back(fam);
+        }
+      itFams->Delete();
+    }
+  it0->Delete();
+  //
+  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 ExtractGroupInternal::getNumberOfEntries() const
+{
+  std::size_t sz0(_groups.size()),sz1(_fams.size());
+  return (int)(sz0+sz1);
+}
+
+const char *ExtractGroupInternal::getKeyOfEntry(int i) const
+{
+  int sz0((int)_groups.size());
+  if(i>=0 && i<sz0)
+    return _groups[i].getKeyOfEntry();
+  else
+    return _fams[i-sz0].getKeyOfEntry();
+}
+
+bool ExtractGroupInternal::getStatusOfEntryStr(const char *entry) const
+{
+  const ExtractGroupStatus& elt(getEntry(entry));
+  return elt.getStatus();
+}
+
+void ExtractGroupInternal::setStatusOfEntryStr(const char *entry, bool status)
+{
+  _selection.emplace_back(entry,status);
+}
+
+const ExtractGroupStatus& ExtractGroupInternal::getEntry(const char *entry) const
+{
+  std::string entryCpp(entry);
+  for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+ExtractGroupStatus& ExtractGroupInternal::getEntry(const char *entry)
+{
+  std::string entryCpp(entry);
+  for(std::vector<ExtractGroupGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  for(std::vector<ExtractGroupFam>::iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    if(entryCpp==(*it0).getKeyOfEntry())
+      return *it0;
+  std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
+  throw INTERP_KERNEL::Exception(oss.str().c_str());
+}
+
+void ExtractGroupInternal::printMySelf(std::ostream& os) const
+{
+  os << "Groups :" << std::endl;
+  for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
+    (*it0).printMySelf(os);
+  os << "Families :" << std::endl;
+  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    (*it0).printMySelf(os);
+}
+
+int ExtractGroupInternal::getIdOfFamily(const std::string& famName) const
+{
+  for(std::vector<ExtractGroupFam>::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> ExtractGroupInternal::getIdsToKeep() const
+{
+  for(auto it: _selection)
+    {
+      const ExtractGroupStatus& 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<ExtractGroupGrp>::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<ExtractGroupFam>::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 ExtractGroupInternal *_egi = nullptr;
+  const std::vector<std::string> *_fams = nullptr;
+public:
+  explicit FamilyIterator(long num , const ExtractGroupInternal *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> > > ExtractGroupInternal::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));
+        std::pair<std::string,std::vector<int> > elt(grp.getName(),std::move(famIds));
+        ret.emplace_back(std::move(elt));
+    }
+    return ret;
+}
+
+void ExtractGroupInternal::clearSelection() const
+{
+  _selection.clear();
+  for(auto it : _groups)
+    it.resetStatus();
+  for(auto it : _fams)
+    it.resetStatus();
+}
+
+std::map<std::string,int> ExtractGroupInternal::computeFamStrIdMap() const
+{
+  std::map<std::string,int> ret;
+  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
+    ret[(*it0).getName()]=(*it0).getId();
+  return ret;
+}
diff --git a/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.h b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.h
new file mode 100644 (file)
index 0000000..c687b65
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 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)
+
+#pragma once
+
+#include <sstream>
+#include <vector>
+#include <set>
+#include <map>
+
+
+class ExtractGroupStatus
+{
+public:
+  ExtractGroupStatus():_status(false) { }
+  ExtractGroupStatus(const char *name);
+  bool getStatus() const { return _status; }
+  void setStatus(bool status) const { _status=status; }
+  void cpyStatusFrom(const ExtractGroupStatus& 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 ExtractGroupStatus& other) const;
+protected:
+mutable bool _status;
+std::string _name;
+std::string _ze_key_name;
+};
+
+class ExtractGroupGrp : public ExtractGroupStatus
+{
+public:
+  ExtractGroupGrp(const char *name):ExtractGroupStatus(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 ExtractGroupGrp& other) const;
+public:
+  static const char START[];
+  std::vector<std::string> _fams;
+};
+
+class ExtractGroupFam : public ExtractGroupStatus
+{
+public:
+  ExtractGroupFam(const char *name);
+  void printMySelf(std::ostream& os) const;
+  void fillIdsToKeep(std::set<int>& s) const;
+  int getId() const { return _id; }
+  bool isSameAs(const ExtractGroupFam& other) const;
+public:
+  static const char START[];
+private:
+  int _id;
+};
+
+class vtkInformationDataObjectMetaDataKey;
+class vtkMutableDirectedGraph;
+class vtkInformation;
+
+class ExtractGroupInternal
+{
+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::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 ExtractGroupStatus& getEntry(const char *entry) const;
+  ExtractGroupStatus& getEntry(const char *entry);
+private:
+  std::vector<ExtractGroupGrp> _groups;
+  std::vector<ExtractGroupFam> _fams;
+  mutable std::vector< std::pair<std::string,bool> > _selection;
+  std::string _mesh_name;
+};
+
index e901595382ce0ae3d90da6120f45e4f001b822f1..6d671f2bd06df78e8a3fd6d8bb52f8926153619e 100644 (file)
@@ -26,6 +26,8 @@ set(classes
   vtkMEDQuadraturePointsGenerator
   vtkMEDReader
   vtkPVMetaDataInformation
+  vtkGroupAsMultiBlock
+  vtkUgSelectCellIds
 )
 
 vtk_module_add_module(MEDReaderIO
index 8f41041b9bc7ec93a10783395554ba892433a149..0406578baaaa017c43e6bdd3722bd8b59d7e4736 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "vtkExtractGroup.h"
 #include "MEDFileFieldRepresentationTree.hxx"
+#include "ExtractGroupHelper.h"
 #include "vtkMEDReader.h"
 #include "VTKMEDTraits.hxx"
 
 
 vtkStandardNewMacro(vtkExtractGroup);
 
-///////////////////
-
-class ExtractGroupStatus
-{
-public:
-  ExtractGroupStatus():_status(false) { }
-  ExtractGroupStatus(const char *name);
-  bool getStatus() const { return _status; }
-  void setStatus(bool status) const { _status=status; }
-  void cpyStatusFrom(const ExtractGroupStatus& 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 ExtractGroupStatus& other) const;
-protected:
-mutable bool _status;
-std::string _name;
-std::string _ze_key_name;
-};
-
-class ExtractGroupGrp : public ExtractGroupStatus
-{
-public:
-  ExtractGroupGrp(const char *name):ExtractGroupStatus(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 ExtractGroupGrp& other) const;
-public:
-  static const char START[];
-  std::vector<std::string> _fams;
-};
-
-class ExtractGroupFam : public ExtractGroupStatus
+class vtkExtractGroup::vtkExtractGroupInternal : public ExtractGroupInternal
 {
-public:
-  ExtractGroupFam(const char *name);
-  void printMySelf(std::ostream& os) const;
-  void fillIdsToKeep(std::set<int>& s) const;
-  int getId() const { return _id; }
-  bool isSameAs(const ExtractGroupFam& other) const;
-public:
-  static const char START[];
-private:
-  int _id;
 };
 
-class vtkExtractGroup::vtkExtractGroupInternal
-{
-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::set<int> getIdsToKeep() const;
-  void clearSelection() const;
-  int getIdOfFamily(const std::string& famName) const;
-  static bool IsInformationOK(vtkInformation *info);
-private:
-  std::map<std::string,int> computeFamStrIdMap() const;
-  const ExtractGroupStatus& getEntry(const char *entry) const;
-  ExtractGroupStatus& getEntry(const char *entry);
-private:
-  std::vector<ExtractGroupGrp> _groups;
-  std::vector<ExtractGroupFam> _fams;
-  mutable std::vector< std::pair<std::string,bool> > _selection;
-  std::string _mesh_name;
-};
-
-const char ExtractGroupGrp::START[]="GRP_";
-
-const char ExtractGroupFam::START[]="FAM_";
-
-ExtractGroupStatus::ExtractGroupStatus(const char *name):_status(false),_name(name)
-{
-}
-
-void ExtractGroupStatus::printMySelf(std::ostream& os) const
-{
-  os << "      -" << _ze_key_name << "(";
-  if(_status)
-    os << "X";
-  else
-    os << " ";
-  os << ")" << std::endl;
-}
-
-bool ExtractGroupStatus::isSameAs(const ExtractGroupStatus& other) const
-{
-  return _name==other._name && _ze_key_name==other._ze_key_name;
-}
-
-bool ExtractGroupGrp::isSameAs(const ExtractGroupGrp& other) const
-{
-  bool ret(ExtractGroupStatus::isSameAs(other));
-  if(ret)
-    return _fams==other._fams;
-  else
-    return false;
-}
-
-bool vtkExtractGroup::vtkExtractGroupInternal::IsInformationOK(vtkInformation *info)
-{
-  // Check the information contain meta data key
-  if(!info->Has(vtkMEDReader::META_DATA()))
-    return false;
-
-  // Recover Meta Data
-  vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(vtkMEDReader::META_DATA())));
-  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* vtkExtractGroup::GetGrpStart()
-{
-  return ExtractGroupGrp::START;
-}
-
-const char* vtkExtractGroup::GetFamStart()
-{
-  return ExtractGroupFam::START;
-}
-
-const char *vtkExtractGroup::vtkExtractGroupInternal::getMeshName() const
-{
-  return this->_mesh_name.c_str();
-}
-
-void vtkExtractGroup::vtkExtractGroupInternal::loadFrom(vtkMutableDirectedGraph *sil)
-{
-  std::vector<ExtractGroupGrp> oldGrps(_groups); _groups.clear();
-  std::vector<ExtractGroupFam> 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());
-          ExtractGroupGrp 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());
-          ExtractGroupFam fam((const char *)verticesNames2->GetValue(idf));
-          _fams.push_back(fam);
-        }
-      itFams->Delete();
-    }
-  it0->Delete();
-  //
-  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 vtkExtractGroup::vtkExtractGroupInternal::getNumberOfEntries() const
-{
-  std::size_t sz0(_groups.size()),sz1(_fams.size());
-  return (int)(sz0+sz1);
-}
-
-const char *vtkExtractGroup::vtkExtractGroupInternal::getKeyOfEntry(int i) const
-{
-  int sz0((int)_groups.size());
-  if(i>=0 && i<sz0)
-    return _groups[i].getKeyOfEntry();
-  else
-    return _fams[i-sz0].getKeyOfEntry();
-}
-
-bool vtkExtractGroup::vtkExtractGroupInternal::getStatusOfEntryStr(const char *entry) const
-{
-  const ExtractGroupStatus& elt(getEntry(entry));
-  return elt.getStatus();
-}
-
-void vtkExtractGroup::vtkExtractGroupInternal::setStatusOfEntryStr(const char *entry, bool status)
-{
-  _selection.emplace_back(entry,status);
-}
-
-const ExtractGroupStatus& vtkExtractGroup::vtkExtractGroupInternal::getEntry(const char *entry) const
-{
-  std::string entryCpp(entry);
-  for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
-    if(entryCpp==(*it0).getKeyOfEntry())
-      return *it0;
-  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
-    if(entryCpp==(*it0).getKeyOfEntry())
-      return *it0;
-  std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
-  throw INTERP_KERNEL::Exception(oss.str().c_str());
-}
-
-ExtractGroupStatus& vtkExtractGroup::vtkExtractGroupInternal::getEntry(const char *entry)
-{
-  std::string entryCpp(entry);
-  for(std::vector<ExtractGroupGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
-    if(entryCpp==(*it0).getKeyOfEntry())
-      return *it0;
-  for(std::vector<ExtractGroupFam>::iterator it0=_fams.begin();it0!=_fams.end();it0++)
-    if(entryCpp==(*it0).getKeyOfEntry())
-      return *it0;
-  std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
-  throw INTERP_KERNEL::Exception(oss.str().c_str());
-}
-
-void vtkExtractGroup::vtkExtractGroupInternal::printMySelf(std::ostream& os) const
-{
-  os << "Groups :" << std::endl;
-  for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
-    (*it0).printMySelf(os);
-  os << "Families :" << std::endl;
-  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
-    (*it0).printMySelf(os);
-}
-
-int vtkExtractGroup::vtkExtractGroupInternal::getIdOfFamily(const std::string& famName) const
-{
-  for(std::vector<ExtractGroupFam>::const_iterator it=_fams.begin();it!=_fams.end();it++)
-    {
-      if((*it).getName()==famName)
-        return (*it).getId();
-    }
-  return std::numeric_limits<int>::max();
-}
-
-ExtractGroupFam::ExtractGroupFam(const char *name):ExtractGroupStatus(name),_id(0)
-{
-  std::size_t pos(_name.find(MEDFileFieldRepresentationLeavesArrays::ZE_SEP));
-  std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(MEDFileFieldRepresentationLeavesArrays::ZE_SEP)));
-  std::istringstream iss(name1);
-  iss >> _id;
-  std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
-}
-
-bool ExtractGroupFam::isSameAs(const ExtractGroupFam& other) const
-{
-  bool ret(ExtractGroupStatus::isSameAs(other));
-  if(ret)
-    return _id==other._id;
-  else
-    return false;
-}
-
-void ExtractGroupFam::printMySelf(std::ostream& os) const
-{
-  os << "      -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
-  if(_status)
-    os << "X";
-  else
-    os << " ";
-  os << ")" << std::endl;
-}
-
-void ExtractGroupFam::fillIdsToKeep(std::set<int>& s) const
-{
-  s.insert(_id);
-}
-
-std::set<int> vtkExtractGroup::vtkExtractGroupInternal::getIdsToKeep() const
-{
-  for(auto it: _selection)
-    {
-      const ExtractGroupStatus& 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<ExtractGroupGrp>::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<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
-    if((*it0).getStatus())
-      (*it0).fillIdsToKeep(s);
-  return s;
-}
-
-void vtkExtractGroup::vtkExtractGroupInternal::clearSelection() const
-{
-  _selection.clear();
-  for(auto it : _groups)
-    it.resetStatus();
-  for(auto it : _fams)
-    it.resetStatus();
-}
-
-std::map<std::string,int> vtkExtractGroup::vtkExtractGroupInternal::computeFamStrIdMap() const
-{
-  std::map<std::string,int> ret;
-  for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
-    ret[(*it0).getName()]=(*it0).getId();
-  return ret;
-}
-
 ////////////////////
 
 vtkExtractGroup::vtkExtractGroup():SIL(NULL),Internal(new vtkExtractGroupInternal),InsideOut(0)
@@ -472,7 +102,7 @@ int vtkExtractGroup::RequestInformation(vtkInformation *request, vtkInformationV
 //      request->Print(cout);
       vtkInformation *outInfo(outputVector->GetInformationObject(0));
       vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
-      if(!vtkExtractGroup::vtkExtractGroupInternal::IsInformationOK(inputInfo))
+      if(!ExtractGroupInternal::IndependantIsInformationOK(vtkMEDReader::META_DATA(),inputInfo))
         {
         vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
         return 0;
@@ -699,6 +329,16 @@ int vtkExtractGroup::GetSILUpdateStamp()
   return (int)this->SILTime;
 }
 
+const char* vtkExtractGroup::GetGrpStart()
+{
+  return ExtractGroupGrp::START;
+}
+
+const char* vtkExtractGroup::GetFamStart()
+{
+  return ExtractGroupFam::START;
+}
+
 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
 {
   this->Superclass::PrintSelf(os, indent);
diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.cxx b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.cxx
new file mode 100644 (file)
index 0000000..e116e31
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright (C) 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 "vtkGroupAsMultiBlock.h"
+#include "ExtractGroupHelper.h"
+#include "vtkMEDReader.h"
+#include "vtkUgSelectCellIds.h"
+#include "MEDFileFieldRepresentationTree.hxx"
+#include "VTKMEDTraits.hxx"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include "vtkMutableDirectedGraph.h"
+#include "vtkInformationDataObjectMetaDataKey.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>
+
+class vtkGroupAsMultiBlockInternal : public ExtractGroupInternal
+{
+};
+
+vtkStandardNewMacro(vtkGroupAsMultiBlock);
+
+vtkGroupAsMultiBlock::vtkGroupAsMultiBlock():Internal(new ExtractGroupInternal)
+{
+}
+
+vtkGroupAsMultiBlock::~vtkGroupAsMultiBlock()
+{
+  delete this->Internal;
+}
+
+int vtkGroupAsMultiBlock::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkInformation *outInfo(outputVector->GetInformationObject(0));
+  vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
+  if(!ExtractGroupInternal::IndependantIsInformationOK(vtkMEDReader::META_DATA(),inputInfo))
+  {
+    vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
+    return 0;
+  }
+  vtkMutableDirectedGraph *mdg(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(vtkMEDReader::META_DATA())));
+  this->Internal->loadFrom(mdg);
+  return 1;
+}
+
+int vtkGroupAsMultiBlock::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
+  vtkMultiBlockDataSet *inputMB(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if(inputMB->GetNumberOfBlocks()!=1)
+  {
+    vtkErrorMacro("vtkGroupAsMultiBlock::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())));
+  if(!output)
+  {
+    vtkErrorMacro("vtkGroupAsMultiBlock::RequestData : something wrong !");
+    return 0; 
+  }
+  //
+  vtkUnstructuredGrid *inputc(vtkUnstructuredGrid::SafeDownCast(input));
+  if(!inputc)
+  {
+    vtkErrorMacro("vtkGroupAsMultiBlock::RequestData : Only implemented for vtkUnstructuredGrid !");
+    return 0; 
+  }
+  //
+  vtkDataArray *famIdsGen(inputc->GetCellData()->GetScalars(MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME));
+  if(!famIdsGen)
+  {
+    vtkErrorMacro(<< "vtkGroupAsMultiBlock::RequestData : Fail to locate " << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME << " array !");
+    return 0;
+  }
+  using vtkMCIdTypeArray = MEDFileVTKTraits<mcIdType>::VtkType;
+  vtkMCIdTypeArray *famIdsArr(vtkMCIdTypeArray::SafeDownCast(famIdsGen));
+  if(!famIdsArr)
+  {
+    vtkErrorMacro(<< "vtkGroupAsMultiBlock::RequestData : cell array " << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME << " is exepected to be IdType !");
+    return 0; 
+  }
+  // Let's go !
+  vtkIdType inputNbCell(famIdsArr->GetNumberOfTuples());
+  std::vector< std::pair<std::string,std::vector<int> > > allGroups(this->Internal->getAllGroups());
+  output->SetNumberOfBlocks(allGroups.size());
+  int blockId(0);
+  for(const auto& grp : allGroups)
+  {
+    std::vector<vtkIdType> ids;
+    // iterate on all families on current group grp
+    for(const auto& famId : grp.second)
+    {// for each family of group grp locate cells in input lying on that group
+      vtkIdType pos(0);
+      std::for_each(famIdsArr->GetPointer(0),famIdsArr->GetPointer(inputNbCell),[&pos,&ids,famId](vtkIdType curFamId) { if(curFamId == famId) { ids.push_back(pos); } pos++; });
+    }
+    std::sort(ids.begin(),ids.end());
+    vtkNew<vtkIdTypeArray> idsVTK;
+    idsVTK->SetNumberOfComponents(1); idsVTK->SetNumberOfTuples(ids.size());
+    std::copy(ids.begin(),ids.end(),idsVTK->GetPointer(0));
+    vtkNew<vtkUgSelectCellIds> cellSelector;
+    cellSelector->SetIds(idsVTK);
+    cellSelector->SetInputData(inputc);
+    cellSelector->Update();
+    output->SetBlock(blockId++,cellSelector->GetOutput());
+  }
+  return 1;
+}
diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.h b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.h
new file mode 100644 (file)
index 0000000..ccb266e
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 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)
+
+#pragma once
+
+#include "vtkMultiBlockDataSetAlgorithm.h"
+
+class ExtractGroupInternal;
+
+class vtkGroupAsMultiBlock : public vtkMultiBlockDataSetAlgorithm
+{
+public:
+    static vtkGroupAsMultiBlock *New();
+    vtkTypeMacro(vtkGroupAsMultiBlock, vtkMultiBlockDataSetAlgorithm);
+protected:
+    vtkGroupAsMultiBlock();
+    ~vtkGroupAsMultiBlock();
+    int RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
+    int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+private:
+    ExtractGroupInternal *Internal;
+};
diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.cxx b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.cxx
new file mode 100644 (file)
index 0000000..a92ec28
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (C) 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 "vtkUgSelectCellIds.h"
+
+#include "vtkCellArray.h"
+#include "vtkUnstructuredGrid.h"
+#include "vtkInformationVector.h"
+#include "vtkUnsignedCharArray.h"
+#include "vtkInformation.h"
+#include "vtkCellData.h"
+#include "vtkPointData.h"
+
+vtkStandardNewMacro(vtkUgSelectCellIds);
+
+void vtkUgSelectCellIds::SetIds(vtkIdTypeArray *ids)
+{
+  _ids = ids;
+}
+
+int vtkUgSelectCellIds::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
+  vtkUnstructuredGrid *ds(vtkUnstructuredGrid::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+  if(!ds)
+  {
+    vtkErrorMacro("vtkUgSelectCellIds::RequestData : input is expected to be an unstructuredgrid !");
+    return 0;
+  }
+  if( ! this->_ids.Get() )
+  {
+    vtkErrorMacro("vtkUgSelectCellIds::RequestData : not initialized array !");
+    return 0;
+  }
+  vtkInformation *outInfo(outputVector->GetInformationObject(0));
+  vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+  output->SetPoints(ds->GetPoints());
+  vtkNew<vtkCellArray> outCellArray;
+  vtkNew<vtkIdTypeArray> outConn;
+  vtkCellData *inputCellData(ds->GetCellData());
+  vtkPointData *inputPointData(ds->GetPointData());
+  // Finish the parlote : feed data arrays
+  vtkCellData *outCellData(output->GetCellData());
+  vtkPointData *outPointData(output->GetPointData());
+  vtkIdType inpNbCells( ds->GetNumberOfCells() );
+  vtkIdType outputNbCells( _ids->GetNumberOfTuples() );
+  vtkNew<vtkIdTypeArray> outNodalConn;
+  vtkNew<vtkUnsignedCharArray> outCellTypes;
+  outCellTypes->SetNumberOfComponents(1); outCellTypes->SetNumberOfTuples(outputNbCells);
+  vtkNew<vtkIdTypeArray> outCellLocations;
+  outCellLocations->SetNumberOfComponents(1); outCellLocations->SetNumberOfTuples(outputNbCells);
+  vtkIdType outConnLgth(0);
+  for( const vtkIdType *cellId = _ids->GetPointer(0) ; cellId != _ids->GetPointer(outputNbCells) ; ++cellId )
+  {
+    if( *cellId >=0 && *cellId < inpNbCells )
+    {
+      vtkIdType npts;
+      const vtkIdType *pts;
+      ds->GetCellPoints(*cellId, npts, pts);
+      outConnLgth += 1+npts;
+    }
+    else
+    {
+      vtkErrorMacro(<< "vtkUgSelectCellIds::RequestData : presence of " << *cellId << " in array must be in [0," << inpNbCells << "[ !");
+      return 0;
+    } 
+  }
+  outNodalConn->SetNumberOfComponents(1); outNodalConn->SetNumberOfTuples(outConnLgth);
+  vtkIdType *outConnPt(outNodalConn->GetPointer(0)),*outCellLocPt(outCellLocations->GetPointer(0));
+  vtkIdType outCurCellLoc = 0;
+  unsigned char *outCellTypePt(outCellTypes->GetPointer(0));
+  for( const vtkIdType *cellId = _ids->GetPointer(0) ; cellId != _ids->GetPointer(outputNbCells) ; ++cellId )
+  {
+      outCellLocPt[0] = outCurCellLoc;
+      vtkIdType npts;
+      const vtkIdType *pts;
+      ds->GetCellPoints(*cellId, npts, pts);
+      *outConnPt++ = npts;
+      outConnPt = std::copy(pts,pts+npts,outConnPt);
+      *outCellTypePt++ = ds->GetCellType(*cellId);
+      outCurCellLoc += npts+1;//not sure
+  }
+  for( int cellFieldId = 0 ; cellFieldId < inputCellData->GetNumberOfArrays() ; ++cellFieldId )
+  {
+    vtkDataArray *array( inputCellData->GetArray(cellFieldId) );
+    vtkSmartPointer<vtkDataArray> outArray;
+    outArray.TakeReference( array->NewInstance() );
+    outArray->SetNumberOfComponents(array->GetNumberOfComponents()); outArray->SetNumberOfTuples(outputNbCells);
+    outArray->SetName(array->GetName());
+    vtkIdType pos(0);
+    for( const vtkIdType *cellId = _ids->GetPointer(0) ; cellId != _ids->GetPointer(outputNbCells) ; ++cellId )
+    {
+      outArray->SetTuple(pos++,*cellId,array);
+    }
+    outCellData->AddArray(outArray);
+  }
+  for( int pointFieldId = 0 ; pointFieldId < inputPointData->GetNumberOfArrays() ; ++pointFieldId )
+  {
+    vtkDataArray *array( inputPointData->GetArray(pointFieldId) );
+    vtkSmartPointer<vtkDataArray> outArray;
+    outArray.TakeReference( array->NewInstance() );
+    outArray->ShallowCopy(array);
+    outPointData->AddArray(outArray);
+  }
+  //
+  outCellArray->SetCells(outputNbCells,outNodalConn);
+  output->SetCells(outCellTypes,outCellLocations,outCellArray);
+  //
+  return 1;
+}
diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.h b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.h
new file mode 100644 (file)
index 0000000..acff0c5
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 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)
+
+#pragma once
+
+#include <vtkUnstructuredGridAlgorithm.h>
+#include <vtkSmartPointer.h>
+#include <vtkIdTypeArray.h>
+
+/*!
+ * Class taking only specified cellIds of input vtkUnstructuredGrid dataset
+ * For performance reasons orphan nodes are not removed here.
+ * The output vtkUnstructuredGrid is lying on the same points than input one.
+ */
+class vtkUgSelectCellIds : public vtkUnstructuredGridAlgorithm
+{
+public:
+    static vtkUgSelectCellIds* New();
+    vtkTypeMacro(vtkUgSelectCellIds, vtkUnstructuredGridAlgorithm);
+    void SetIds(vtkIdTypeArray *ids);
+    vtkUgSelectCellIds() = default;
+    ~vtkUgSelectCellIds() override = default;
+protected:
+    int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+private:
+    vtkSmartPointer<vtkIdTypeArray> _ids;
+};
index 807df5382d80977551fddb75c96dc9545307dcce..44cdcba47ffa44d79278e513fb5924f0b7d115c5 100644 (file)
       </StringVectorProperty>
 
     </SourceProxy>
+
+    <SourceProxy name="GroupAsMultiBlock" class="vtkGroupAsMultiBlock" label="Groups As MultiBlocks">
+      <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>
 
   <ProxyGroup name="filters">