1 // Copyright (C) 2020-2021 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "ExtractGroupHelper.h"
22 #include "MEDFileFieldRepresentationTree.hxx"
24 #include "vtkInformation.h"
25 #include "vtkInformationDataObjectMetaDataKey.h"
26 #include "vtkAdjacentVertexIterator.h"
27 #include "vtkMutableDirectedGraph.h"
28 #include "vtkDataSetAttributes.h"
29 #include "vtkStringArray.h"
33 const char ExtractGroupGrp::START[]="GRP_";
35 const char ExtractGroupFam::START[]="FAM_";
37 ExtractGroupStatus::ExtractGroupStatus(const char *name):_status(false),_name(name)
41 void ExtractGroupStatus::printMySelf(std::ostream& os) const
43 os << " -" << _ze_key_name << "(";
48 os << ")" << std::endl;
51 bool ExtractGroupStatus::isSameAs(const ExtractGroupStatus& other) const
53 return _name==other._name && _ze_key_name==other._ze_key_name;
56 bool ExtractGroupGrp::isSameAs(const ExtractGroupGrp& other) const
58 bool ret(ExtractGroupStatus::isSameAs(other));
60 return _fams==other._fams;
65 ExtractGroupFam::ExtractGroupFam(const char *name):ExtractGroupStatus(name),_id(0)
67 std::size_t pos(_name.find(MEDFileFieldRepresentationLeavesArrays::ZE_SEP));
68 std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(MEDFileFieldRepresentationLeavesArrays::ZE_SEP)));
69 std::istringstream iss(name1);
71 std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
74 bool ExtractGroupFam::isSameAs(const ExtractGroupFam& other) const
76 bool ret(ExtractGroupStatus::isSameAs(other));
78 return _id==other._id;
83 void ExtractGroupFam::printMySelf(std::ostream& os) const
85 os << " -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
90 os << ")" << std::endl;
93 void ExtractGroupFam::fillIdsToKeep(std::set<int>& s) const
99 bool ExtractGroupInternal::IndependantIsInformationOK(vtkInformationDataObjectMetaDataKey *medReaderMetaData, vtkInformation *info)
101 // Check the information contain meta data key
102 if(!info->Has(medReaderMetaData))
106 vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(medReaderMetaData)));
110 vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
111 vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
114 for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
116 vtkStdString &st(verticesNames2->GetValue(i));
117 if(st=="MeshesFamsGrps")
123 const char *ExtractGroupInternal::getMeshName() const
125 return this->_mesh_name.c_str();
128 void ExtractGroupInternal::loadFrom(vtkMutableDirectedGraph *sil)
130 std::vector<ExtractGroupGrp> oldGrps(_groups); _groups.clear();
131 std::vector<ExtractGroupFam> oldFams(_fams); _fams.clear();
133 vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
134 vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
137 for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
139 vtkStdString &st(verticesNames2->GetValue(i));
140 if(st=="MeshesFamsGrps")
147 throw INTERP_KERNEL::Exception("There is an internal error ! The tree on server side has not the expected look !");
148 vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
149 sil->GetAdjacentVertices(id0,it0);
150 while(it0->HasNext())
152 vtkIdType id1(it0->Next());
153 std::string meshName((const char *)verticesNames2->GetValue(id1));
154 this->_mesh_name=meshName;
155 vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());
156 sil->GetAdjacentVertices(id1,it1);
157 vtkIdType idZeGrps(it1->Next());//zeGroups
158 vtkAdjacentVertexIterator *itGrps(vtkAdjacentVertexIterator::New());
159 sil->GetAdjacentVertices(idZeGrps,itGrps);
160 while(itGrps->HasNext())
162 vtkIdType idg(itGrps->Next());
163 ExtractGroupGrp grp((const char *)verticesNames2->GetValue(idg));
164 vtkAdjacentVertexIterator *itGrps2(vtkAdjacentVertexIterator::New());
165 sil->GetAdjacentVertices(idg,itGrps2);
166 std::vector<std::string> famsOnGroup;
167 while(itGrps2->HasNext())
169 vtkIdType idgf(itGrps2->Next());
170 famsOnGroup.push_back(std::string((const char *)verticesNames2->GetValue(idgf)));
172 grp.setFamilies(famsOnGroup);
174 _groups.push_back(grp);
177 vtkIdType idZeFams(it1->Next());//zeFams
179 vtkAdjacentVertexIterator *itFams(vtkAdjacentVertexIterator::New());
180 sil->GetAdjacentVertices(idZeFams,itFams);
181 while(itFams->HasNext())
183 vtkIdType idf(itFams->Next());
184 ExtractGroupFam fam((const char *)verticesNames2->GetValue(idf));
185 _fams.push_back(fam);
191 std::size_t szg(_groups.size()),szf(_fams.size());
192 if(szg==oldGrps.size() && szf==oldFams.size())
195 for(std::size_t i=0;i<szg && isSame;i++)
196 isSame=_groups[i].isSameAs(oldGrps[i]);
197 for(std::size_t i=0;i<szf && isSame;i++)
198 isSame=_fams[i].isSameAs(oldFams[i]);
201 for(std::size_t i=0;i<szg;i++)
202 _groups[i].cpyStatusFrom(oldGrps[i]);
203 for(std::size_t i=0;i<szf;i++)
204 _fams[i].cpyStatusFrom(oldFams[i]);
209 int ExtractGroupInternal::getNumberOfEntries() const
211 std::size_t sz0(_groups.size()),sz1(_fams.size());
212 return (int)(sz0+sz1);
215 const char *ExtractGroupInternal::getKeyOfEntry(int i) const
217 int sz0((int)_groups.size());
219 return _groups[i].getKeyOfEntry();
221 return _fams[i-sz0].getKeyOfEntry();
224 bool ExtractGroupInternal::getStatusOfEntryStr(const char *entry) const
226 const ExtractGroupStatus& elt(getEntry(entry));
227 return elt.getStatus();
230 void ExtractGroupInternal::setStatusOfEntryStr(const char *entry, bool status)
232 _selection.emplace_back(entry,status);
235 const ExtractGroupStatus& ExtractGroupInternal::getEntry(const char *entry) const
237 std::string entryCpp(entry);
238 for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
239 if(entryCpp==(*it0).getKeyOfEntry())
241 for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
242 if(entryCpp==(*it0).getKeyOfEntry())
244 std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
245 throw INTERP_KERNEL::Exception(oss.str().c_str());
248 ExtractGroupStatus& ExtractGroupInternal::getEntry(const char *entry)
250 std::string entryCpp(entry);
251 for(std::vector<ExtractGroupGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
252 if(entryCpp==(*it0).getKeyOfEntry())
254 for(std::vector<ExtractGroupFam>::iterator it0=_fams.begin();it0!=_fams.end();it0++)
255 if(entryCpp==(*it0).getKeyOfEntry())
257 std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
258 throw INTERP_KERNEL::Exception(oss.str().c_str());
261 void ExtractGroupInternal::printMySelf(std::ostream& os) const
263 os << "Groups :" << std::endl;
264 for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
265 (*it0).printMySelf(os);
266 os << "Families :" << std::endl;
267 for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
268 (*it0).printMySelf(os);
271 int ExtractGroupInternal::getIdOfFamily(const std::string& famName) const
273 for(std::vector<ExtractGroupFam>::const_iterator it=_fams.begin();it!=_fams.end();it++)
275 if((*it).getName()==famName)
276 return (*it).getId();
278 return std::numeric_limits<int>::max();
281 std::set<int> ExtractGroupInternal::getIdsToKeep() const
283 for(auto it: _selection)
285 const ExtractGroupStatus& elt(getEntry(it.first.c_str()));
286 elt.setStatus(it.second);
288 std::map<std::string,int> m(this->computeFamStrIdMap());
290 for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
292 if((*it0).getStatus())
294 const std::vector<std::string>& fams((*it0).getFamiliesLyingOn());
295 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
297 std::map<std::string,int>::iterator it2(m.find((*it1)));
299 s.insert((*it2).second);
303 for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
304 if((*it0).getStatus())
305 (*it0).fillIdsToKeep(s);
309 // see reference : https://en.cppreference.com/w/cpp/iterator/iterator
310 class FamilyIterator : public std::iterator< std::input_iterator_tag, long, long, int*, int >
313 const ExtractGroupInternal *_egi = nullptr;
314 const std::vector<std::string> *_fams = nullptr;
316 explicit FamilyIterator(long num , const ExtractGroupInternal *egi, const std::vector<std::string>& fams) : _num(num),_egi(egi),_fams(&fams) {}
317 FamilyIterator& operator++() { ++_num; return *this;}
318 bool operator==(const FamilyIterator& other) const {return _num == other._num;}
319 bool operator!=(const FamilyIterator& other) const {return !(*this == other);}
320 reference operator*() const {return _egi->getIdOfFamily((*_fams)[_num]);}
323 std::vector< std::pair<std::string,std::vector<int> > > ExtractGroupInternal::getAllGroups() const
325 std::vector< std::pair<std::string,std::vector<int> > > ret;
326 for(const auto& grp : _groups)
328 const std::vector<std::string>& fams(grp.getFamiliesLyingOn());
329 std::vector<int> famIds(FamilyIterator(0,this,fams),FamilyIterator(fams.size(),this,fams));
330 std::pair<std::string,std::vector<int> > elt(grp.getName(),std::move(famIds));
331 ret.emplace_back(std::move(elt));
336 void ExtractGroupInternal::clearSelection() const
339 for(auto it : _groups)
345 std::map<std::string,int> ExtractGroupInternal::computeFamStrIdMap() const
347 std::map<std::string,int> ret;
348 for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
349 ret[(*it0).getName()]=(*it0).getId();