Version: 9.15.0
AbstractPoint.cxx
Go to the documentation of this file.
1 // Copyright (C) 2015-2025 CEA, EDF
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 
20 #include "AbstractPoint.hxx"
21 #include "LinkedBlocPoint.hxx"
22 #include "ForkBlocPoint.hxx"
23 #include "NotSimpleCasePoint.hxx"
24 #include "SetOfPoints.hxx"
25 #include "BagPoint.hxx"
26 #include "ElementaryPoint.hxx"
27 #include "Node.hxx"
28 #include "Bloc.hxx"
29 
30 #include <algorithm>
31 
32 using namespace YACS::ENGINE;
33 
35 {
36 }
37 
39 {
40  if(_father==0)
41  return this;
42  else
43  return _father->getGodFather();
44 }
45 
47 {
48  Node *beg(getFirstNode());
49  InGate *ing(beg->getInGate());
50  return ing->getBackLinks().empty();
51 }
52 
54 {
55  Node *endd(getLastNode());
56  OutGate *oug(endd->getOutGate());
57  return oug->edSetInGate().empty();
58 }
59 
61 {
62  Node *beg(getFirstNode()),*endd(getLastNode());
63  return isSimplyLinkedBefore(sop,beg) && isSimplyLinkedAfter(sop,endd);
64 }
65 
67 {
68  Node *beg(getFirstNode()),*endd(getLastNode());
69  return IsNoLinksBefore(beg) && isSimplyLinkedAfter(sop,endd);
70 }
71 
73 {
74  Node *beg(getFirstNode()),*endd(getLastNode());
75  return IsNoLinksAfter(endd) && isSimplyLinkedBefore(sop,beg);
76 }
77 
79 {
80  Node *beg(getFirstNode()),*endd(getLastNode());
81  return IsNoLinksBefore(beg) && IsNoLinksAfter(endd);
82 }
83 
88 {
89  Node *bb(getFirstNode()),*ee(getLastNode());
90  std::list<AbstractPoint *> l; l.push_back(this);
91  AbstractPoint *cur2(0);
92  //
93  cur2=sop->getNodeB4(bb);
94  while(cur2)
95  {
96  if(dynamic_cast<NotSimpleCasePoint *>(cur2))
97  continue;
98  Node *cur3(cur2->getFirstNode());
99  if(cur2->isSimplyLinkedBeforeAfter(sop))
100  {
101  l.push_front(cur2);
102  cur2=sop->getNodeB4(cur3);
103  continue;
104  }
105  else if(IsGatherB4Ext(cur3) && isSimplyLinkedAfter(sop,cur2->getLastNode()))
106  {
107  l.push_front(cur2);
108  break;
109  }
110  else
111  break;
112  }
113  //
114  cur2=sop->getNodeAfter(ee);
115  while(cur2)
116  {
117  if(dynamic_cast<NotSimpleCasePoint *>(cur2))
118  continue;
119  Node *cur3(cur2->getLastNode());
120  if(cur2->isSimplyLinkedBeforeAfter(sop))
121  {
122  l.push_back(cur2);
123  cur2=sop->getNodeAfter(cur3);
124  continue;
125  }
126  else if(IsScatterAfterExt(cur3) && isSimplyLinkedBefore(sop,cur2->getFirstNode()))
127  {
128  l.push_back(cur2);
129  break;
130  }
131  else
132  break;
133  }
134  if(l.size()>1)
135  {
136  return new LinkedBlocPoint(l,getFather());
137  }
138  else
139  return nullptr;
140 }
141 
146 {
148  AbstractPoint *bb2(sop->findPointWithNode(bb)),*ee2(sop->findPointWithNode(ee));
149  //
150  const std::list<AbstractPoint *>& lp(sop->getListOfPoints());
151  std::list<AbstractPoint *> l; l.push_back(this);
152  for(std::list<AbstractPoint *>::const_iterator it=lp.begin();it!=lp.end();it++)
153  {
154  if(*it==this)
155  continue;
156  if(dynamic_cast<NotSimpleCasePoint *>(*it))
157  continue;
158  Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode());
159  if(!IsSimplyLinkedBeforeExt(curFirst) || !IsSimplyLinkedAfterExt(curEnd))
160  continue;
161  Node *curbb(GetNodeB4(curFirst)),*curee(GetNodeAfter(curEnd));
162  AbstractPoint *bb3(sop->findPointWithNode(curbb)),*ee3(sop->findPointWithNode(curee));
163  if(bb2==bb3 && ee2==ee3)
164  l.push_back(*it);
165  }
166  if(l.size()>1)
167  {
168  return new ForkBlocPoint(l,getFather());
169  }
170  else
171  return nullptr;
172 }
173 
175 {
177  AbstractPoint *ee2(sop->findPointWithNode(ee));
178  //
179  const std::list<AbstractPoint *>& lp(sop->getListOfPoints());
180  std::list<AbstractPoint *> l; l.push_back(this);
181  for(std::list<AbstractPoint *>::const_iterator it=lp.begin();it!=lp.end();it++)
182  {
183  if(*it==this)
184  continue;
185  if(dynamic_cast<NotSimpleCasePoint *>(*it))
186  continue;
187  Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode());
188  if(!IsNoLinksBefore(curFirst) || !IsSimplyLinkedAfterExt(curEnd))
189  continue;
190  Node *curee(GetNodeAfter(curEnd));
191  AbstractPoint *ee3(sop->findPointWithNode(curee));
192  if(ee2==ee3)
193  l.push_back(*it);
194  }
195  if(l.size()>1)
196  {
197  return new ForkBlocPoint(l,getFather());
198  }
199  else
200  return nullptr;
201 }
202 
204 {
206  AbstractPoint *bb2(sop->findPointWithNode(bb));
207  //
208  const std::list<AbstractPoint *>& lp(sop->getListOfPoints());
209  std::list<AbstractPoint *> l; l.push_back(this);
210  for(std::list<AbstractPoint *>::const_iterator it=lp.begin();it!=lp.end();it++)
211  {
212  if(*it==this)
213  continue;
214  if(dynamic_cast<NotSimpleCasePoint *>(*it))
215  continue;
216  Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode());
217  if(!IsSimplyLinkedBeforeExt(curFirst) || !IsNoLinksAfter(curEnd))
218  continue;
219  Node *curbb(GetNodeB4(curFirst));
220  AbstractPoint *bb3(sop->findPointWithNode(curbb));
221  if(bb2==bb3)
222  l.push_back(*it);
223  }
224  if(l.size()>1)
225  {
226  return new ForkBlocPoint(l,getFather());
227  }
228  else
229  return nullptr;
230 }
231 
233 {
235  AbstractPoint *bb2(sop->findPointWithNode(bb));
236  //
237  const std::list<AbstractPoint *>& lp(sop->getListOfPoints());
238  std::list<AbstractPoint *> l; l.push_back(this);
239  for(std::list<AbstractPoint *>::const_iterator it=lp.begin();it!=lp.end();it++)
240  {
241  if(*it==this)
242  continue;
243  if(dynamic_cast<NotSimpleCasePoint *>(*it))
244  continue;
245  Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode());
246  if(!IsNoLinksBefore(curFirst) || !IsNoLinksAfter(curEnd))
247  continue;
248  Node *curbb(GetNodeB4(curFirst));
249  AbstractPoint *bb3(sop->findPointWithNode(curbb));
250  if(bb2==bb3)
251  l.push_back(*it);
252  }
253  if(l.size()>1)
254  {
255  return new ForkBlocPoint(l,getFather());
256  }
257  else
258  return nullptr;
259 }
260 
261 #include <iostream>
262 
264 {
265 public:
266  Visitor1(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *m):_m(m) { }
272  {
273  std::string nodeName(pt->getNodeName());
274  auto it(_m->find(nodeName));
275  if(it==_m->end())
276  {
277  (*_m)[nodeName] = std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> >(pt,pt->getNode(),std::make_shared<Bloc>(nodeName));
278  }
279  }
283 private:
284  std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *_m;
285 };
286 
290 void AbstractPoint::FeedData(AbstractPoint *ptToBeRewired, std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *m)
291 {
292  Visitor1 vis(m);
293  ptToBeRewired->accept(&vis);
294 }
295 
299 void AbstractPoint::FeedData(const std::list<AbstractPoint *>& ptsToBeRewired, std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *m)
300 {
301  for(auto it : ptsToBeRewired)
302  FeedData(it,m);
303 }
304 
305 bool containsPtsToKill(const std::vector<AbstractPoint *>& ptsToKill, Node *node)
306 {
307  for(auto it : ptsToKill)
308  if(it->contains(node))
309  return true;
310  return false;
311 }
312 
322 void AbstractPoint::Rewire(const std::vector<AbstractPoint *>& ptsToKill, std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *m)
323 {
324  for(auto it : *m)
325  {
326  ElementaryPoint *pt(std::get<0>(it.second));
327  Node *node(std::get<1>(it.second));
328  auto newNode(std::get<2>(it.second).get());
329  pt->setNode(newNode);
330  }
331  for(auto it : *m)
332  {
333  ElementaryPoint *pt(std::get<0>(it.second));
334  Node *node(std::get<1>(it.second));
335  auto newNode(std::get<2>(it.second).get());
336  if(containsPtsToKill(ptsToKill,newNode))
337  continue;
338  for(auto it2 : node->getOutGate()->edSetInGate())
339  {
340  Node *nodeFwd(it2->getNode());
341  std::string nodeFwdName(nodeFwd->getName());
342  auto it3(m->find(nodeFwdName));
343  if(it3!=m->end())
344  {
345  Node *nodeFwdNew = std::get<2>(it3->second).get();
346  if(!containsPtsToKill(ptsToKill,newNode))
347  {
348  newNode->getOutGate()->edAddInGate(nodeFwdNew->getInGate());
349  }
350  //else
351  // node after nodeFwd is not in m fall into \a ptToKill
352  // -> ignore link.
353  }
354  //else
355  // node after nodeFwd is not in m. Typically because nodeFwd has not been put in m
356  // concretely : do not link incoming links to Node * inside ptToKill
357  }
358  }
359 }
360 
365 void AbstractPoint::UnRewire(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > >& m)
366 {
367  for(auto it : m)
368  {
369  ElementaryPoint *pt(std::get<0>(it.second));
370  Node *node(std::get<1>(it.second));
371  pt->setNode(node);
372  }
373 }
374 
375 void AbstractPoint::Display(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > *m)
376 {
377  for(auto it : *m)
378  {
379  ElementaryPoint *pt(std::get<0>(it.second));
380  auto newNode(pt->getNode());
381  for(auto it2 : newNode->getOutGate()->edSetInGate())
382  {
383  std::cerr << pt->getNodeName() << " -> " << it2->getNode()->getName() << " " << newNode->typeName() << std::endl;
384  }
385  }
386 }
387 
396 void AbstractPoint::TryAsNotSimpleCase(AbstractPoint *father, const std::vector<AbstractPoint *>& ptsToKill, std::list<AbstractPoint *>& nodes, bool& somethingDone)
397 {
398  std::list<AbstractPoint *> lp2;
399  for(auto it : nodes)
400  {
401  if(std::find(ptsToKill.cbegin(),ptsToKill.cend(),it)==ptsToKill.cend())
402  lp2.push_back(it->deepCopy(nullptr));
403  }
404  BagPoint *tmp(new BagPoint(lp2,nullptr));
405  for(auto it : lp2)
406  it->setFather(tmp);
407  SetOfPoints sopTest(tmp);
408  std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr<Bloc> > > m;
409  FeedData(tmp,&m);
410  Rewire(ptsToKill,&m);
411  try
412  {
413  sopTest.basicSimplify();
414  }
415  catch(YACS::Exception& ex)
416  {// By removing elements in ptsToKill from this impossible to have a classical case -> un rewire to rollback nodes state
417  UnRewire(m);
418  return ;
419  }
420  AbstractPoint *pt(sopTest.getUniqueAndReleaseIt());
421  pt->setFather(father);
422  UnRewire(m);
423  for(auto it : nodes)
424  if(std::find(ptsToKill.cbegin(),ptsToKill.cend(),it)==ptsToKill.cend())
425  delete it;
426  nodes.clear();
427  nodes.push_back(pt);
428  for(auto it : ptsToKill)
429  {
430  std::list<AbstractPoint *> l; l.push_back(it);
431  nodes.push_back( new NotSimpleCasePoint(l,father) );
432  }
433  somethingDone = true;
434 }
435 
437 {
438  InGate *ing(node->getInGate());
439  return ing->getBackLinks().size()!=1;
440 }
441 
443 {
444  OutGate *oug(node->getOutGate());
445  std::list<InGate *> ings(oug->edSetInGate());
446  if(ings.size()==1)
447  return true;
448  if(ings.size()==0)
449  return false;
450  AbstractPoint *dummy=0;
451  return IsCommonDirectSonOf(sop,ings,dummy);
452 }
453 
455 {
456  OutGate *oug(node->getOutGate());
457  return oug->edSetInGate().size()<=1;
458 }
459 
461 {
462  OutGate *oug(node->getOutGate());
463  return oug->edSetInGate().size()!=1;
464 }
465 
467 {
468  InGate *ing(node->getInGate());
469  std::list<OutGate *> outgs(ing->getBackLinks());
470  if(outgs.size()==1)
471  return true;
472  if(outgs.size()==0)
473  return false;
474  AbstractPoint *dummy=0;
475  return IsCommonDirectSonOf(sop,outgs,dummy);
476 }
477 
479 {
480  InGate *ing(node->getInGate());
481  return ing->getBackLinks().size()<=1;
482 }
483 
485 {
486  InGate *ing(node->getInGate());
487  return ing->getBackLinks().size()==0;
488 }
489 
491 {
492  OutGate *oug(node->getOutGate());
493  return oug->edSetInGate().size()==0;
494 }
495 
497 {
498  InGate *ing(node->getInGate());
499  std::list<OutGate *> bl(ing->getBackLinks());
500  if(bl.size()>1)
501  throw Exception("AbstractPoint::GetNodeB4 : precond not OK !");
502  if(bl.size()==0)
503  return 0;
504  return bl.front()->getNode();
505 }
506 
508 {
509  OutGate *oug(node->getOutGate());
510  std::list<InGate *> fl(oug->edSetInGate());
511  if(fl.size()>1)
512  throw Exception("AbstractPoint::GetNodeAfter : precond not OK !");
513  if(fl.size()==0)
514  return 0;
515  return (*fl.begin())->getNode();
516 }
517 
519 {
520  if(!sonOrLittleSon)
521  throw YACS::Exception("AbstractPoint::GetDirectSonOf : sonOrLittleSon is null !");
522  AbstractPoint *curFath(sonOrLittleSon->getFather()),*cur(sonOrLittleSon);
523  while(curFath && curFath!=refFather)
524  {
525  cur=curFath;
526  curFath=cur->getFather();
527  }
528  if(!curFath)
529  throw YACS::Exception("AbstractPoint::GetDirectSonOf : not in the same family !");
530  return cur;
531 }
532 
533 bool AbstractPoint::IsCommonDirectSonOf(AbstractPoint *refFather, const std::list<OutGate *>& outgs, AbstractPoint *&ret)
534 {
535  if(outgs.size()<1)
536  throw YACS::Exception("AbstractPoint::GetCommonDirectSonOf1 : not enough !");
537  std::list<OutGate *>::const_iterator it(outgs.begin());
538  OutGate *ref(*(it++));
539  AbstractPoint *ref2(GetDirectSonOf(refFather,refFather->findPointWithNode(ref->getNode())));
540  for(;it!=outgs.end();it++)
541  {
542  if(!ref2->contains((*it)->getNode()))
543  return false;
544  }
545  ret=ref2;
546  return true;
547 }
548 
549 bool AbstractPoint::IsCommonDirectSonOf(AbstractPoint *refFather, const std::list<InGate *>& ings, AbstractPoint *&ret)
550 {
551  if(ings.size()<1)
552  throw YACS::Exception("AbstractPoint::GetCommonDirectSonOf2 : not enough !");
553  std::list<InGate *>::const_iterator it(ings.begin());
554  InGate *ref(*(it++));
555  AbstractPoint *ref2(GetDirectSonOf(refFather,refFather->findPointWithNode(ref->getNode())));
556  for(;it!=ings.end();it++)
557  {
558  if(!ref2->contains((*it)->getNode()))
559  return false;
560  }
561  ret=ref2;
562  return true;
563 }
bool containsPtsToKill(const std::vector< AbstractPoint * > &ptsToKill, Node *node)
void endForkBlocPoint(ForkBlocPoint *pt)
void beginForkBlocPoint(ForkBlocPoint *pt)
void endElementaryPoint(ElementaryPoint *pt)
void endNotSimpleCasePoint(NotSimpleCasePoint *pt)
Visitor1(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > *m)
std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > * _m
void beginNotSimpleCasePoint(NotSimpleCasePoint *pt)
void endLinkedBlocPoint(LinkedBlocPoint *pt)
void beginLinkedBlocPoint(LinkedBlocPoint *pt)
void beginElementaryPoint(ElementaryPoint *pt)
virtual Node * getLastNode()=0
static bool IsSimplyLinkedBeforeExt(Node *node)
static bool IsScatterAfterExt(Node *node)
static void Rewire(const std::vector< AbstractPoint * > &ptsToKill, std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > *m)
static void Display(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > *m)
static void UnRewire(std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > &m)
bool isSimplyLinkedAfterNullBefore(BlocPoint *sop)
bool isSimplyLinkedAfter(BlocPoint *sop, Node *node)
static bool IsCommonDirectSonOf(AbstractPoint *refFather, const std::list< OutGate * > &outgs, AbstractPoint *&ret)
LinkedBlocPoint * tryAsLink(BlocPoint *sop)
bool isSimplyLinkedBeforeNullAfter(BlocPoint *sop)
static bool IsNoLinksAfter(Node *node)
virtual AbstractPoint * findPointWithNode(Node *node)=0
static void FeedData(AbstractPoint *ptToBeRewired, std::map< std::string, std::tuple< ElementaryPoint *, Node *, std::shared_ptr< Bloc > > > *m)
virtual void accept(PointVisitor *pv)=0
static bool IsSimplyLinkedAfterExt(Node *node)
AbstractPoint * getFather() const
static Node * GetNodeB4(Node *node)
bool isSimplyLinkedBefore(BlocPoint *sop, Node *node)
static bool IsGatherB4Ext(Node *node)
static Node * GetNodeAfter(Node *node)
ForkBlocPoint * tryAsForkTer(BlocPoint *sop)
AbstractPoint * getGodFather()
ForkBlocPoint * tryAsForkBis(BlocPoint *sop)
virtual bool contains(Node *node) const =0
bool isSimplyLinkedBeforeAfter(BlocPoint *sop)
void setFather(AbstractPoint *father)
bool isNullBeforeNullAfter(BlocPoint *sop)
virtual Node * getFirstNode()=0
static void TryAsNotSimpleCase(AbstractPoint *father, const std::vector< AbstractPoint * > &ptsToKill, std::list< AbstractPoint * > &nodes, bool &somethingDone)
static bool IsNoLinksBefore(Node *node)
ForkBlocPoint * tryAsFork(BlocPoint *sop)
ForkBlocPoint * tryAsForkQuatro(BlocPoint *sop)
static AbstractPoint * GetDirectSonOf(AbstractPoint *refFather, AbstractPoint *sonOrLittleSon)
AbstractPoint * getNodeB4(Node *node)
Definition: BlocPoint.cxx:77
const std::list< AbstractPoint * > & getListOfPoints() const
Definition: BlocPoint.hxx:46
AbstractPoint * getNodeAfter(Node *node)
Definition: BlocPoint.cxx:63
AbstractPoint * findPointWithNode(Node *node)
Definition: BlocPoint.cxx:52
std::list< OutGate * > getBackLinks()
Definition: InGate.cxx:134
Base class for all nodes.
Definition: Node.hxx:70
OutGate * getOutGate()
Definition: Node.hxx:124
InGate * getInGate()
Definition: Node.hxx:123
const std::string & getName() const
Definition: Node.hxx:125
std::list< InGate * > edSetInGate() const
Definition: OutGate.cxx:112
bool edAddInGate(InGate *inGate)
Definition: OutGate.cxx:98
AbstractPoint * getUniqueAndReleaseIt() const
def ref(target, callback=None)
Definition: CONNECTOR.py:120