Salome HOME
Intersec bug fix: point not added properly inserted in splitting.
[tools/medcoupling.git] / src / INTERP_KERNEL / Geometric2D / InterpKernelGeo2DEdge.cxx
index 6d2e6ebee85e9519b9a5cd5e5d3b432ee26d076c..d2a31d0cef8335edfa796785ac762fffb654cbcd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  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
 
 #include <algorithm>
 
+#include <functional>
+
+
 using namespace INTERP_KERNEL;
 
 MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0),
-                           _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0)
+    _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0)
 {
 }
 
@@ -163,22 +166,56 @@ unsigned MergePoints::getNumberOfAssociations() const
   return ret;
 }
 
+void MergePoints::PushInMap(int key, int value, std::map<int,int>& mergedNodes)
+{
+  if(key!=-1 && value!=-1)
+    mergedNodes[key]=value;
+}
+
+void MergePoints::updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map<int,int>& mergedNodes)
+{
+  unsigned subTot(_ass1Start1+_ass1End1+_ass1Start2+_ass1End2);
+  if(subTot!=0)
+    {
+      if(_ass1Start1 && _ass1Start2)
+        PushInMap(e2Start,e1Start,mergedNodes);
+      if(_ass1Start1 && _ass1End2)
+        PushInMap(e2End,e1Start,mergedNodes);
+      if(_ass1End1 && _ass1Start2)
+        PushInMap(e2Start,e1End,mergedNodes);
+      if(_ass1End1 && _ass1End2)
+        PushInMap(e2End,e1End,mergedNodes);
+    }
+  subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2;
+  if(subTot!=0)
+    {
+      if(_ass2Start1 && _ass2Start2)
+        PushInMap(e2Start,e1Start,mergedNodes);
+      if(_ass2Start1 && _ass2End2)
+        PushInMap(e2End,e1Start,mergedNodes);
+      if(_ass2End1 && _ass2Start2)
+        PushInMap(e2Start,e1End,mergedNodes);
+      if(_ass2End1 && _ass2End2)
+        PushInMap(e2End,e1End,mergedNodes);
+    }
+}
+
 IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node
                                    , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2),
-                                                                                     _1E(keepOrder?end1:end2),
-                                                                                     _2S(keepOrder?start2:start1),
-                                                                                     _2E(keepOrder?end2:end1),
-                                                                                     _chararct_val_for_e1(keepOrder?val1:val2),
-                                                                                     _chararct_val_for_e2(keepOrder?val2:val1),
-                                                                                     _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2),
-                                                                                     _e2(keepOrder?e2:e1)
+                                       _1E(keepOrder?end1:end2),
+                                       _2S(keepOrder?start2:start1),
+                                       _2E(keepOrder?end2:end1),
+                                       _chararct_val_for_e1(keepOrder?val1:val2),
+                                       _chararct_val_for_e2(keepOrder?val2:val1),
+                                       _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2),
+                                       _e2(keepOrder?e2:e1)
 {
 }
 
 IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E),
-                                                                  _chararct_val_for_e1(other._chararct_val_for_e1),
-                                                                  _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node),
-                                                                  _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2)
+    _chararct_val_for_e1(other._chararct_val_for_e1),
+    _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node),
+    _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2)
 {
   if(_node)
     _node->incrRef();
@@ -254,7 +291,7 @@ void IntersectElement::performMerging(MergePoints& commonNode) const
 }
 
 /*!
- * This methode is const because 'node' is supposed to be equal geomitrically to _node.
+ * This method is const because 'node' is supposed to be equal geometrically to _node.
  */
 void IntersectElement::setNode(Node *node) const
 {
@@ -302,7 +339,7 @@ bool IntersectElement::isIncludedByBoth() const
 {
   return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2);
 }
-  
+
 bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode)
 {
   std::list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal();
@@ -358,7 +395,7 @@ bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector<Node *>&
  * Locates 'node' regarding edge this->_e1. If node is located close to (with distant lt epsilon) start or end point of _e1,
  * 'node' takes its place. In this case 'obvious' is set to true and 'commonNode' stores information of merge point and finally 'where' is set.
  * Furthermore 'node' is declared as ON LIMIT to indicate in locating process that an absolute location computation will have to be done.
- * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged. 
+ * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged.
  */
 void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const
 {
@@ -438,7 +475,7 @@ void Edge::declareOut() const
 void Edge::fillXfigStreamForLoc(std::ostream& stream) const
 {
   switch(_loc)
-    {
+  {
     case FULL_IN_1:
       stream << '2';//Green
       break;
@@ -450,7 +487,7 @@ void Edge::fillXfigStreamForLoc(std::ostream& stream) const
       break;
     default:
       stream << '0';
-    }
+  }
 }
 
 bool Edge::changeStartNodeWith(Node *otherStartNode) const
@@ -662,7 +699,7 @@ EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2)
   e2->dynCastFunction(tmp1,tmp2);
   type1|=type2;
   switch(type1)
-    {
+  {
     case 1:// Intersection seg/seg
       ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2));
       break;
@@ -675,7 +712,7 @@ EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2)
     default:
       //Should never happen
       throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation.");
-    }
+  }
   return ret;
 }
 
@@ -692,6 +729,11 @@ void Edge::unApplySimilarity(double xBary, double yBary, double dimChar)
   _bounds.unApplySimilarity(xBary,yBary,dimChar);
 }
 
+void Edge::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const
+{
+  return getMiddleOfPoints(p1, p2, mid);
+}
+
 bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
                      ComposedEdge& outValForF1, ComposedEdge& outValForF2)
 {
@@ -707,7 +749,7 @@ bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersecto
   if(intersector->intersect(whereToFind,newNodes,order,commonNode))
     {
       if(newNodes.empty())
-        throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen
+        throw Exception("Internal error occurred - error in intersector implementation!");// This case should never happen
       std::vector<Node *>::iterator iter=newNodes.begin();
       std::vector<Node *>::reverse_iterator iterR=newNodes.rbegin();
       f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1);
@@ -755,48 +797,49 @@ bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *
 {
   Edge *tmp;
   switch(code)
-    {
+  {
     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START:      // OUT_BEFORE - START
     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE
     case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:   // OUT_AFTER - OUT_AFTER
     case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:         // END - OUT_AFTER
     case END*OFFSET_FOR_TYPEOFLOCINEDGE+START:             // END - START
-      return false;
+    return false;
     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:      // INSIDE - OUT_AFTER
-      outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true));
-      tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef();
-      outVal1.pushBack(tmp);
-      outVal2.resize(2);
-      outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn();
-      outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
-      return true;
+    outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true));
+    tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef();
+    outVal1.pushBack(tmp);
+    outVal2.resize(2);
+    outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn();
+    outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
+    return true;
     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:         // INSIDE - INSIDE
-      {
-        if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode()))))
-          {
-            e2->incrRef(); e2->incrRef();
-            outVal1.resize(3);
-            outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS));
-            outVal1.setValueAt(1,const_cast<Edge*>(e2),direction);
-            outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
-            outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
-            return true;
-          }
-        else
-          {
-            outVal1.resize(3);
-            outVal2.resize(3);
-            tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn();
-            outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction);
-            outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS));
-            tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn();
-            outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction);
-            tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode());
-            outVal2.setValueAt(1,tmp,direction);
-            return true;
-          }
-      }
+    {
+      if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode()))))
+        {
+          e2->incrRef(); e2->incrRef();
+          outVal1.resize(3);
+          outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS));
+          outVal1.setValueAt(1,const_cast<Edge*>(e2),direction);
+          outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
+          outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
+          return true;
+        }
+      else
+        {
+          outVal1.resize(3);
+          outVal2.resize(3);
+          tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn();
+          outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction);
+          outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS));
+          tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn();
+          outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction);
+          tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode());
+          outVal2.setValueAt(1,tmp,direction);
+          return true;
+        }
+    }
     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:     // OUT_BEFORE - INSIDE
+    {
       tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef();
       outVal1.pushBack(tmp);
       outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
@@ -804,7 +847,9 @@ bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *
       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction));
       outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn();
       return true;
+    }
     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:  // OUT_BEFORE - OUT_AFTER
+    {
       e1->incrRef(); e1->incrRef();
       outVal1.pushBack(const_cast<Edge*>(e1));
       outVal2.resize(3);
@@ -812,38 +857,50 @@ bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *
       outVal2.setValueAt(1,const_cast<Edge*>(e1),direction); e1->declareOn();
       outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
       return true;
+    }
     case START*OFFSET_FOR_TYPEOFLOCINEDGE+END:             // START - END
+    {
       e1->incrRef(); e1->incrRef();
       outVal1.pushBack(const_cast<Edge*>(e1));
       outVal2.pushBack(const_cast<Edge*>(e1),direction); e1->declareOn();
       return true;
+    }
     case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:       // START - OUT_AFTER
+    {
       e1->incrRef(); e1->incrRef();
       outVal1.pushBack(const_cast<Edge*>(e1));
       outVal2.resize(2);
       outVal2.setValueAt(direction?0:1,const_cast<Edge*>(e1),direction); e1->declareOn();
       outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
       return true;
+    }
     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END:            // INSIDE - END
+    {
       e2->incrRef(); e2->incrRef();
       outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true));
       outVal1.pushBack(const_cast<Edge*>(e2),direction);
       outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
       return true;
+    }
     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END:        // OUT_BEFORE - END
+    {
       e1->incrRef(); e1->incrRef();
       outVal1.pushBack(const_cast<Edge*>(e1));
       outVal2.resize(2);
       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction));
       outVal2.setValueAt(direction?1:0,const_cast<Edge*>(e1),direction); e1->declareOn();
       return true;
+    }
     case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:          // START - INSIDE
+    {
       e2->incrRef(); e2->incrRef();
       outVal1.pushBack(const_cast<Edge*>(e2),direction);
       outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
       outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
       return true;
+    }
     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START:          // INSIDE - START
+    {
       outVal1.resize(2);
       outVal2.resize(2);
       tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn();
@@ -852,7 +909,9 @@ bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *
       outVal2.setValueAt(direction?0:1,tmp,direction);
       outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
       return true;
+    }
     case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:            // END - INSIDE
+    {
       outVal1.resize(2);
       outVal2.resize(2);
       tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn();
@@ -861,9 +920,26 @@ bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *
       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction));
       outVal2.setValueAt(direction?1:0,tmp,direction);
       return true;
+    }
     default:
       throw Exception("Unexpected situation of overlapping edges : internal error occurs ! ");
-    }
+  }
+}
+
+void Edge::dumpToCout(const std::map<INTERP_KERNEL::Node *,int>& mapp, int index) const
+{
+  auto sI(mapp.find(getStartNode())), eI(mapp.find(getEndNode()));
+  int start = (sI == mapp.end() ? -1 : sI->second), end = (eI == mapp.end() ? -1 : eI->second);
+  std::string locs;
+  switch (getLoc())
+  {
+    case FULL_IN_1: locs="FULL_IN_1"; break;
+    case FULL_ON_1: locs="FULL_ON_1"; break;
+    case FULL_OUT_1: locs="FULL_OUT_1"; break;
+    case FULL_UNKNOWN: locs="FULL_UNKNOWN"; break;
+    default: locs="oh my God! This is so wrong.";
+  }
+  std::cout << "Edge [" << index << "] : ("<<  std::hex << this << std::dec << ") -> (" << start << ", " << end << ")\t" << locs << std::endl;
 }
 
 bool Edge::isEqual(const Edge& other) const
@@ -871,9 +947,47 @@ bool Edge::isEqual(const Edge& other) const
   return _start->isEqual(*other._start) && _end->isEqual(*other._end);
 }
 
-inline bool eqpair(const std::pair<double,Node *>& p1, const std::pair<double,Node *>& p2)
+/**
+ * This method takes in input nodes in \a subNodes (using \a coo)
+ *
+ * \param [in,out] subNodes to be sorted
+ * \return true if a reordering was necessary false if not.
+ */
+bool Edge::sortSubNodesAbs(const double *coo, std::vector<int>& subNodes)
 {
-  return fabs(p1.first-p2.first)<QUADRATIC_PLANAR::_precision;
+  Bounds b;
+  b.prepareForAggregation();
+  b.aggregate(getBounds());
+  double xBary,yBary;
+  double dimChar(b.getCaracteristicDim());
+  b.getBarycenter(xBary,yBary);
+  applySimilarity(xBary,yBary,dimChar);
+  _start->applySimilarity(xBary,yBary,dimChar);
+  _end->applySimilarity(xBary,yBary,dimChar);
+  //
+  std::size_t sz(subNodes.size()),i(0);
+  std::vector< std::pair<double,Node *> > an2(sz);
+  std::map<Node *, int> m;
+  for(std::vector<int>::const_iterator it=subNodes.begin();it!=subNodes.end();it++,i++)
+    {
+      Node *n(new Node(coo[2*(*it)],coo[2*(*it)+1]));
+      n->applySimilarity(xBary,yBary,dimChar);
+      m[n]=*it;
+      an2[i]=std::pair<double,Node *>(getCharactValueBtw0And1(*n),n);
+    }
+  std::sort(an2.begin(),an2.end());
+  //
+  bool ret(false);
+  for(i=0;i<sz;i++)
+    {
+      int id(m[an2[i].second]);
+      if(id!=subNodes[i])
+        { subNodes[i]=id; ret=true; }
+    }
+  //
+  for(std::map<INTERP_KERNEL::Node *,int>::const_iterator it2=m.begin();it2!=m.end();it2++)
+    (*it2).first->decrRef();
+  return ret;
 }
 
 /**
@@ -882,6 +996,15 @@ inline bool eqpair(const std::pair<double,Node *>& p1, const std::pair<double,No
 void Edge::sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1,
                       const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis)
 {
+  int startId=(*mapp1.find(_start)).second;
+  int endId=(*mapp1.find(_end)).second;
+  if (! addNodes.size()) // quick way out, no new node to add.
+    {
+      edgesThis.push_back(startId);
+      edgesThis.push_back(endId);
+      return;
+    }
+
   Bounds b;
   b.prepareForAggregation();
   b.aggregate(getBounds());
@@ -898,19 +1021,16 @@ void Edge::sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const
   for(std::size_t i=0;i<sz;i++)
     an2[i]=std::pair<double,Node *>(getCharactValueBtw0And1(*addNodes[i]),addNodes[i]);
   std::sort(an2.begin(),an2.end());
-  int startId=(*mapp1.find(_start)).second;
-  int endId=(*mapp1.find(_end)).second;
   std::vector<int> tmpp;
-  std::vector< std::pair<double,Node *> >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair);
-  for(std::vector< std::pair<double,Node *> >::const_iterator it=an2.begin();it!=itend;it++)
+  for(std::vector< std::pair<double,Node *> >::const_iterator it=an2.begin();it!=an2.end();it++)
     {
       int idd=(*mapp2.find((*it).second)).second;
-      if((*it).first<QUADRATIC_PLANAR::_precision)
+      if((*it).first<QuadraticPlanarPrecision::getPrecision())
         {
           startId=idd;
           continue;
         }
-      if((*it).first>1-QUADRATIC_PLANAR::_precision)
+      if((*it).first>1-QuadraticPlanarPrecision::getPrecision())
         {
           endId=idd;
           continue;
@@ -930,3 +1050,31 @@ void Edge::sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const
       edgesThis.push_back(tmpp2[i+1]);
     }
 }
+
+void Edge::fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
+                                std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const
+{
+  int tmp[2];
+  _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp);
+  _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1);
+  if(direction)
+    {
+      edgesThis.push_back(tmp[0]);
+      edgesThis.push_back(tmp[1]);
+    }
+  else
+    {
+      edgesThis.push_back(tmp[1]);
+      edgesThis.push_back(tmp[0]);
+    }
+}
+
+void Edge::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
+                              unsigned skipStartOrEnd,
+                              std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const
+{
+  if (skipStartOrEnd != 1) // see meaning in splitAbs()
+    _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+  if (skipStartOrEnd != 2)
+  _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther);
+}