]> SALOME platform Git repositories - tools/paravisaddons_common.git/blob
Salome HOME
b7c303201cdc7a4f0c9842f3dc02f6692dc7ffdf
[tools/paravisaddons_common.git] /
1 // Copyright (C) 2021  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #include "ElectromagnetismRotationHelper.h"
22
23 #include "InterpKernelException.hxx"
24
25 #include "vtkInformation.h"
26 #include "vtkInformationDataObjectMetaDataKey.h"
27 #include "vtkAdjacentVertexIterator.h"
28 #include "vtkMutableDirectedGraph.h"
29 #include "vtkDataSetAttributes.h"
30 #include "vtkStringArray.h"
31
32 #include <cstring>
33 #include <limits>
34 #include <algorithm>
35
36 const char ZE_SEPP[]="@@][@@";
37
38 const char ElectromagnetismRotationGrp::START[]="GRP_";
39
40 const char ElectromagnetismRotationFam::START[]="FAM_";
41
42 ElectromagnetismRotationStatus::ElectromagnetismRotationStatus(const char *name):_status(false),_name(name)
43 {
44 }
45
46 void ElectromagnetismRotationStatus::printMySelf(std::ostream& os) const
47 {
48   os << "      -" << _ze_key_name << "(";
49   if(_status)
50     os << "X";
51   else
52     os << " ";
53   os << ")" << std::endl;
54 }
55
56 bool ElectromagnetismRotationStatus::isSameAs(const ElectromagnetismRotationStatus& other) const
57 {
58   return _name==other._name && _ze_key_name==other._ze_key_name;
59 }
60
61 bool ElectromagnetismRotationGrp::isSameAs(const ElectromagnetismRotationGrp& other) const
62 {
63   bool ret(ElectromagnetismRotationStatus::isSameAs(other));
64   if(ret)
65     return _fams==other._fams;
66   else
67     return false;
68 }
69
70 ElectromagnetismRotationFam::ElectromagnetismRotationFam(const char *name):ElectromagnetismRotationStatus(name),_id(0)
71 {
72   std::size_t pos(_name.find(ZE_SEPP));
73   std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(ZE_SEPP)));
74   std::istringstream iss(name1);
75   iss >> _id;
76   std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
77 }
78
79 bool ElectromagnetismRotationFam::isSameAs(const ElectromagnetismRotationFam& other) const
80 {
81   bool ret(ElectromagnetismRotationStatus::isSameAs(other));
82   if(ret)
83     return _id==other._id;
84   else
85     return false;
86 }
87
88 void ElectromagnetismRotationFam::printMySelf(std::ostream& os) const
89 {
90   os << "      -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
91   if(_status)
92     os << "X";
93   else
94     os << " ";
95   os << ")" << std::endl;
96 }
97
98 void ElectromagnetismRotationFam::fillIdsToKeep(std::set<int>& s) const
99 {
100   s.insert(_id);
101 }
102 ///////////////////
103
104 bool ElectromagnetismRotationInternal::IndependantIsInformationOK(vtkInformationDataObjectMetaDataKey *medReaderMetaData, vtkInformation *info)
105 {
106   // Check the information contain meta data key
107   if(!info->Has(medReaderMetaData))
108     return false;
109
110   // Recover Meta Data
111   vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(medReaderMetaData)));
112   if(!sil)
113     return false;
114   int idNames(0);
115   vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
116   vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
117   if(!verticesNames2)
118     return false;
119   for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
120     {
121       vtkStdString &st(verticesNames2->GetValue(i));
122       if(st=="MeshesFamsGrps")
123         return true;
124     }
125   return false;
126 }
127
128 const char *ElectromagnetismRotationInternal::getMeshName() const
129 {
130   return this->_mesh_name.c_str();
131 }
132
133 void ElectromagnetismRotationInternal::loadFrom(vtkMutableDirectedGraph *sil)
134 {
135   std::vector<ElectromagnetismRotationGrp> oldGrps(_groups); _groups.clear();
136   std::vector<ElectromagnetismRotationFam> oldFams(_fams); _fams.clear();
137   int idNames(0);
138   vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
139   vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
140   vtkIdType id0;
141   bool found(false);
142   for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
143     {
144       vtkStdString &st(verticesNames2->GetValue(i));
145       if(st=="MeshesFamsGrps")
146         {
147           id0=i;
148           found=true;
149         }
150     }
151   if(!found)
152     throw INTERP_KERNEL::Exception("There is an internal error ! The tree on server side has not the expected look !");
153   vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
154   sil->GetAdjacentVertices(id0,it0);
155   int kk(0),ll(0);
156   while(it0->HasNext())
157     {
158       vtkIdType id1(it0->Next());
159       std::string meshName((const char *)verticesNames2->GetValue(id1));
160       this->_mesh_name=meshName;
161       vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());
162       sil->GetAdjacentVertices(id1,it1);
163       vtkIdType idZeGrps(it1->Next());//zeGroups
164       vtkAdjacentVertexIterator *itGrps(vtkAdjacentVertexIterator::New());
165       sil->GetAdjacentVertices(idZeGrps,itGrps);
166       while(itGrps->HasNext())
167         {
168           vtkIdType idg(itGrps->Next());
169           ElectromagnetismRotationGrp grp((const char *)verticesNames2->GetValue(idg));
170           vtkAdjacentVertexIterator *itGrps2(vtkAdjacentVertexIterator::New());
171           sil->GetAdjacentVertices(idg,itGrps2);
172           std::vector<std::string> famsOnGroup;
173           while(itGrps2->HasNext())
174             {
175               vtkIdType idgf(itGrps2->Next());
176               famsOnGroup.push_back(std::string((const char *)verticesNames2->GetValue(idgf)));
177             }
178           grp.setFamilies(famsOnGroup);
179           itGrps2->Delete();
180           _groups.push_back(grp);
181         }
182       itGrps->Delete();
183       vtkIdType idZeFams(it1->Next());//zeFams
184       it1->Delete();
185       vtkAdjacentVertexIterator *itFams(vtkAdjacentVertexIterator::New());
186       sil->GetAdjacentVertices(idZeFams,itFams);
187       while(itFams->HasNext())
188         {
189           vtkIdType idf(itFams->Next());
190           ElectromagnetismRotationFam fam((const char *)verticesNames2->GetValue(idf));
191           _fams.push_back(fam);
192         }
193       itFams->Delete();
194     }
195   it0->Delete();
196   // filter groups on cells
197   std::vector<ElectromagnetismRotationGrp> groupsToKeep;
198   std::size_t ii(0);
199   for(auto grp : _groups)
200   {
201     std::vector<int> famIds(this->getFamiliesIdsOnGroup(grp.getName()));
202     if ( std::all_of(famIds.begin(), famIds.end(), [](int i){ return i<0; }) )
203       groupsToKeep.emplace_back(std::move(grp));
204   }
205   _groups = std::move(groupsToKeep);
206   //
207   std::size_t szg(_groups.size()),szf(_fams.size());
208   if(szg==oldGrps.size() && szf==oldFams.size())
209     {
210       bool isSame(true);
211       for(std::size_t i=0;i<szg && isSame;i++)
212         isSame=_groups[i].isSameAs(oldGrps[i]);
213       for(std::size_t i=0;i<szf && isSame;i++)
214         isSame=_fams[i].isSameAs(oldFams[i]);
215       if(isSame)
216         {
217           for(std::size_t i=0;i<szg;i++)
218             _groups[i].cpyStatusFrom(oldGrps[i]);
219           for(std::size_t i=0;i<szf;i++)
220             _fams[i].cpyStatusFrom(oldFams[i]);
221         }
222     }
223 }
224
225 int ElectromagnetismRotationInternal::getNumberOfEntries() const
226 {
227   std::size_t sz0(_groups.size());
228   return (int)(sz0);
229 }
230
231 const char *ElectromagnetismRotationInternal::getKeyOfEntry(int i) const
232 {
233   return _groups[i].getKeyOfEntry();
234 }
235
236 bool ElectromagnetismRotationInternal::getStatusOfEntryStr(const char *entry) const
237 {
238   const ElectromagnetismRotationStatus& elt(getEntry(entry));
239   return elt.getStatus();
240 }
241
242 void ElectromagnetismRotationInternal::setStatusOfEntryStr(const char *entry, bool status)
243 {
244   _selection.emplace_back(entry,status);
245 }
246
247 const ElectromagnetismRotationStatus& ElectromagnetismRotationInternal::getEntry(const char *entry) const
248 {
249   std::string entryCpp(entry);
250   for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
251     if(entryCpp==(*it0).getKeyOfEntry())
252       return *it0;
253   std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getEntry : no such entry \"" << entry << "\"!";
254   throw INTERP_KERNEL::Exception(oss.str().c_str());
255 }
256
257 ElectromagnetismRotationStatus& ElectromagnetismRotationInternal::getEntry(const char *entry)
258 {
259   std::string entryCpp(entry);
260   for(std::vector<ElectromagnetismRotationGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
261     if(entryCpp==(*it0).getKeyOfEntry())
262       return *it0;
263   std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getEntry : no such entry \"" << entry << "\"!";
264   throw INTERP_KERNEL::Exception(oss.str().c_str());
265 }
266
267 void ElectromagnetismRotationInternal::printMySelf(std::ostream& os) const
268 {
269   os << "Groups :" << std::endl;
270   for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
271     (*it0).printMySelf(os);
272 }
273
274 std::vector<int> ElectromagnetismRotationInternal::getFamiliesIdsOnGroup(const std::string& groupName) const
275 {
276   for(auto grp : _groups)
277   {
278     if(grp.getName() == groupName)
279     {
280       std::vector<std::string> fams(grp.getFamiliesLyingOn());
281       auto sz(fams.size());
282       std::vector<int> famIds(sz);
283       for(auto i = 0 ; i < sz ; ++i)
284         famIds[i] = this->getIdOfFamily(fams[i]);
285       return famIds;
286     }
287   }
288   std::ostringstream oss; oss << "vtkElectromagnetismRotationInternal::getFamiliesIdsOnGroup : no such group \"" << groupName << "\"!";
289   throw INTERP_KERNEL::Exception(oss.str().c_str());
290 }
291
292 int ElectromagnetismRotationInternal::getIdOfFamily(const std::string& famName) const
293 {
294   for(std::vector<ElectromagnetismRotationFam>::const_iterator it=_fams.begin();it!=_fams.end();it++)
295     {
296       if((*it).getName()==famName)
297         return (*it).getId();
298     }
299   return std::numeric_limits<int>::max();
300 }
301
302 std::set<int> ElectromagnetismRotationInternal::getIdsToKeep() const
303 {
304   for(auto it: _selection)
305     {
306       const ElectromagnetismRotationStatus& elt(getEntry(it.first.c_str()));
307       elt.setStatus(it.second);
308     }
309   std::map<std::string,int> m(this->computeFamStrIdMap());
310   std::set<int> s;
311   for(std::vector<ElectromagnetismRotationGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
312     {
313       if((*it0).getStatus())
314         {
315           const std::vector<std::string>& fams((*it0).getFamiliesLyingOn());
316           for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
317             {
318               std::map<std::string,int>::iterator it2(m.find((*it1)));
319               if(it2!=m.end())
320                 s.insert((*it2).second);
321             }
322         }
323      }
324   for(std::vector<ElectromagnetismRotationFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
325     if((*it0).getStatus())
326       (*it0).fillIdsToKeep(s);
327   return s;
328 }
329
330 // see reference : https://en.cppreference.com/w/cpp/iterator/iterator
331 class FamilyIterator : public std::iterator< std::input_iterator_tag, long, long, int*, int >
332 {
333   long _num = 0;
334   const ElectromagnetismRotationInternal *_egi = nullptr;
335   const std::vector<std::string> *_fams = nullptr;
336 public:
337   explicit FamilyIterator(long num , const ElectromagnetismRotationInternal *egi, const std::vector<std::string>& fams) : _num(num),_egi(egi),_fams(&fams) {}
338   FamilyIterator& operator++() { ++_num; return *this;}
339   bool operator==(const FamilyIterator& other) const {return _num == other._num;}
340   bool operator!=(const FamilyIterator& other) const {return !(*this == other);}
341   reference operator*() const {return _egi->getIdOfFamily((*_fams)[_num]);}
342 };
343
344 std::vector< std::pair<std::string,std::vector<int> > > ElectromagnetismRotationInternal::getAllGroups() const
345 {
346     std::vector< std::pair<std::string,std::vector<int> > > ret;
347     for(const auto&  grp : _groups)
348     {
349         const std::vector<std::string>& fams(grp.getFamiliesLyingOn());
350         std::vector<int> famIds(FamilyIterator(0,this,fams),FamilyIterator(fams.size(),this,fams));
351         if ( std::all_of(famIds.begin(), famIds.end(), [](int i){ return i<0; }) )// only groups on cells considered here
352         {
353           std::pair<std::string,std::vector<int> > elt(grp.getName(),std::move(famIds));
354           ret.emplace_back(std::move(elt));
355         }
356     }
357     return ret;
358 }
359
360 void ElectromagnetismRotationInternal::clearSelection() const
361 {
362   _selection.clear();
363   for(auto it : _groups)
364     it.resetStatus();
365   for(auto it : _fams)
366     it.resetStatus();
367 }
368
369 std::map<std::string,int> ElectromagnetismRotationInternal::computeFamStrIdMap() const
370 {
371   std::map<std::string,int> ret;
372   for(std::vector<ElectromagnetismRotationFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
373     ret[(*it0).getName()]=(*it0).getId();
374   return ret;
375 }