From: Anthony Geay Date: Fri, 7 Aug 2020 09:27:55 +0000 (+0200) Subject: New 2 useful filters in MEDReader plugin : vtkUgSelectCellIds and vtkGroupAsMultiBlock X-Git-Tag: V9_6_0a1~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ff8c1f5067a06deed8922d6aee2745a4e370b803;p=modules%2Fparavis.git New 2 useful filters in MEDReader plugin : vtkUgSelectCellIds and vtkGroupAsMultiBlock --- diff --git a/src/Plugins/MEDReader/plugin/MEDLoaderForPV/CMakeLists.txt b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/CMakeLists.txt index 6cbbdd87..ce109aee 100644 --- a/src/Plugins/MEDReader/plugin/MEDLoaderForPV/CMakeLists.txt +++ b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/CMakeLists.txt @@ -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 index 00000000..562a5c11 --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.cxx @@ -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 + +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& 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;iGetNumberOfValues();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 oldGrps(_groups); _groups.clear(); + std::vector 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;iGetNumberOfValues();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 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=0 && i::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + if(entryCpp==(*it0).getKeyOfEntry()) + return *it0; + for(std::vector::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::iterator it0=_groups.begin();it0!=_groups.end();it0++) + if(entryCpp==(*it0).getKeyOfEntry()) + return *it0; + for(std::vector::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::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + (*it0).printMySelf(os); + os << "Families :" << std::endl; + for(std::vector::const_iterator it0=_fams.begin();it0!=_fams.end();it0++) + (*it0).printMySelf(os); +} + +int ExtractGroupInternal::getIdOfFamily(const std::string& famName) const +{ + for(std::vector::const_iterator it=_fams.begin();it!=_fams.end();it++) + { + if((*it).getName()==famName) + return (*it).getId(); + } + return std::numeric_limits::max(); +} + +std::set ExtractGroupInternal::getIdsToKeep() const +{ + for(auto it: _selection) + { + const ExtractGroupStatus& elt(getEntry(it.first.c_str())); + elt.setStatus(it.second); + } + std::map m(this->computeFamStrIdMap()); + std::set s; + for(std::vector::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + { + if((*it0).getStatus()) + { + const std::vector& fams((*it0).getFamiliesLyingOn()); + for(std::vector::const_iterator it1=fams.begin();it1!=fams.end();it1++) + { + std::map::iterator it2(m.find((*it1))); + if(it2!=m.end()) + s.insert((*it2).second); + } + } + } + for(std::vector::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 *_fams = nullptr; +public: + explicit FamilyIterator(long num , const ExtractGroupInternal *egi, const std::vector& 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 > > ExtractGroupInternal::getAllGroups() const +{ + std::vector< std::pair > > ret; + for(const auto& grp : _groups) + { + const std::vector& fams(grp.getFamiliesLyingOn()); + std::vector famIds(FamilyIterator(0,this,fams),FamilyIterator(fams.size(),this,fams)); + std::pair > 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 ExtractGroupInternal::computeFamStrIdMap() const +{ + std::map ret; + for(std::vector::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 index 00000000..c687b650 --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDLoaderForPV/ExtractGroupHelper.h @@ -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 +#include +#include +#include + + +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& fams) { _fams=fams; } + const std::vector& getFamiliesLyingOn() const { return _fams; } + bool isSameAs(const ExtractGroupGrp& other) const; +public: + static const char START[]; + std::vector _fams; +}; + +class ExtractGroupFam : public ExtractGroupStatus +{ +public: + ExtractGroupFam(const char *name); + void printMySelf(std::ostream& os) const; + void fillIdsToKeep(std::set& 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 getIdsToKeep() const; + std::vector< std::pair > > getAllGroups() const; + void clearSelection() const; + int getIdOfFamily(const std::string& famName) const; + static bool IndependantIsInformationOK(vtkInformationDataObjectMetaDataKey *medReaderMetaData, vtkInformation *info); +private: + std::map computeFamStrIdMap() const; + const ExtractGroupStatus& getEntry(const char *entry) const; + ExtractGroupStatus& getEntry(const char *entry); +private: + std::vector _groups; + std::vector _fams; + mutable std::vector< std::pair > _selection; + std::string _mesh_name; +}; + diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/CMakeLists.txt b/src/Plugins/MEDReader/plugin/MEDReaderIO/CMakeLists.txt index e9015953..6d671f2b 100644 --- a/src/Plugins/MEDReader/plugin/MEDReaderIO/CMakeLists.txt +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/CMakeLists.txt @@ -26,6 +26,8 @@ set(classes vtkMEDQuadraturePointsGenerator vtkMEDReader vtkPVMetaDataInformation + vtkGroupAsMultiBlock + vtkUgSelectCellIds ) vtk_module_add_module(MEDReaderIO diff --git a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkExtractGroup.cxx b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkExtractGroup.cxx index 8f41041b..0406578b 100644 --- a/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkExtractGroup.cxx +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkExtractGroup.cxx @@ -20,6 +20,7 @@ #include "vtkExtractGroup.h" #include "MEDFileFieldRepresentationTree.hxx" +#include "ExtractGroupHelper.h" #include "vtkMEDReader.h" #include "VTKMEDTraits.hxx" @@ -68,381 +69,10 @@ 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& fams) { _fams=fams; } - const std::vector& getFamiliesLyingOn() const { return _fams; } - bool isSameAs(const ExtractGroupGrp& other) const; -public: - static const char START[]; - std::vector _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& 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 getIdsToKeep() const; - void clearSelection() const; - int getIdOfFamily(const std::string& famName) const; - static bool IsInformationOK(vtkInformation *info); -private: - std::map computeFamStrIdMap() const; - const ExtractGroupStatus& getEntry(const char *entry) const; - ExtractGroupStatus& getEntry(const char *entry); -private: - std::vector _groups; - std::vector _fams; - mutable std::vector< std::pair > _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;iGetNumberOfValues();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 oldGrps(_groups); _groups.clear(); - std::vector 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;iGetNumberOfValues();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 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=0 && i::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - if(entryCpp==(*it0).getKeyOfEntry()) - return *it0; - for(std::vector::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::iterator it0=_groups.begin();it0!=_groups.end();it0++) - if(entryCpp==(*it0).getKeyOfEntry()) - return *it0; - for(std::vector::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::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - (*it0).printMySelf(os); - os << "Families :" << std::endl; - for(std::vector::const_iterator it0=_fams.begin();it0!=_fams.end();it0++) - (*it0).printMySelf(os); -} - -int vtkExtractGroup::vtkExtractGroupInternal::getIdOfFamily(const std::string& famName) const -{ - for(std::vector::const_iterator it=_fams.begin();it!=_fams.end();it++) - { - if((*it).getName()==famName) - return (*it).getId(); - } - return std::numeric_limits::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& s) const -{ - s.insert(_id); -} - -std::set vtkExtractGroup::vtkExtractGroupInternal::getIdsToKeep() const -{ - for(auto it: _selection) - { - const ExtractGroupStatus& elt(getEntry(it.first.c_str())); - elt.setStatus(it.second); - } - std::map m(this->computeFamStrIdMap()); - std::set s; - for(std::vector::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - { - if((*it0).getStatus()) - { - const std::vector& fams((*it0).getFamiliesLyingOn()); - for(std::vector::const_iterator it1=fams.begin();it1!=fams.end();it1++) - { - std::map::iterator it2(m.find((*it1))); - if(it2!=m.end()) - s.insert((*it2).second); - } - } - } - for(std::vector::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 vtkExtractGroup::vtkExtractGroupInternal::computeFamStrIdMap() const -{ - std::map ret; - for(std::vector::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 index 00000000..e116e31a --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.cxx @@ -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 +#include +#include "vtkMutableDirectedGraph.h" +#include "vtkInformationDataObjectMetaDataKey.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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::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 > > allGroups(this->Internal->getAllGroups()); + output->SetNumberOfBlocks(allGroups.size()); + int blockId(0); + for(const auto& grp : allGroups) + { + std::vector 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 idsVTK; + idsVTK->SetNumberOfComponents(1); idsVTK->SetNumberOfTuples(ids.size()); + std::copy(ids.begin(),ids.end(),idsVTK->GetPointer(0)); + vtkNew 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 index 00000000..ccb266e7 --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkGroupAsMultiBlock.h @@ -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 index 00000000..a92ec286 --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.cxx @@ -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 outCellArray; + vtkNew 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 outNodalConn; + vtkNew outCellTypes; + outCellTypes->SetNumberOfComponents(1); outCellTypes->SetNumberOfTuples(outputNbCells); + vtkNew 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 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 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 index 00000000..acff0c5e --- /dev/null +++ b/src/Plugins/MEDReader/plugin/MEDReaderIO/vtkUgSelectCellIds.h @@ -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 +#include +#include + +/*! + * 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 _ids; +}; diff --git a/src/Plugins/MEDReader/plugin/ParaViewPlugin/Resources/MEDReaderServer.xml b/src/Plugins/MEDReader/plugin/ParaViewPlugin/Resources/MEDReaderServer.xml index 807df538..44cdcba4 100644 --- a/src/Plugins/MEDReader/plugin/ParaViewPlugin/Resources/MEDReaderServer.xml +++ b/src/Plugins/MEDReader/plugin/ParaViewPlugin/Resources/MEDReaderServer.xml @@ -196,6 +196,23 @@ + + + + + + + + + + + + This property specifies the input to the Level Scalars filter. + + + + +