Back to index

salome-med  6.5.0
InterpKernelGeo2DEdge.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "InterpKernelGeo2DEdge.hxx"
00021 #include "InterpKernelGeo2DEdgeLin.hxx"
00022 #include "InterpKernelGeo2DEdgeInfLin.hxx"
00023 //#include "EdgeParabol.hxx"
00024 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
00025 #include "InterpKernelException.hxx"
00026 
00027 #include <algorithm>
00028 
00029 using namespace INTERP_KERNEL;
00030 
00031 MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0),
00032                            _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0)
00033 {
00034 }
00035 
00036 void MergePoints::start1Replaced()
00037 {
00038   unsigned nbOfAsso=getNumberOfAssociations();
00039   if(nbOfAsso==0)
00040     _ass1Start1=1;
00041   else
00042     _ass2Start1=1;
00043 }
00044 
00045 void MergePoints::end1Replaced()
00046 {
00047   unsigned nbOfAsso=getNumberOfAssociations();
00048   if(nbOfAsso==0)
00049     _ass1End1=1;
00050   else
00051     _ass2End1=1;
00052 }
00053 
00054 void MergePoints::start1OnStart2()
00055 {
00056   unsigned nbOfAsso=getNumberOfAssociations();
00057   if(nbOfAsso==0)
00058     {
00059       _ass1Start1=1;
00060       _ass1Start2=1;
00061     }
00062   else
00063     {
00064       _ass2Start1=1;
00065       _ass2Start2=1;
00066     }
00067 }
00068 
00069 void MergePoints::start1OnEnd2()
00070 {
00071   unsigned nbOfAsso=getNumberOfAssociations();
00072   if(nbOfAsso==0)
00073     {
00074       _ass1Start1=1;
00075       _ass1End2=1;
00076     }
00077   else
00078     {
00079       _ass2Start1=1;
00080       _ass2End2=1;
00081     }
00082 }
00083 
00084 void MergePoints::end1OnStart2()
00085 {
00086   unsigned nbOfAsso=getNumberOfAssociations();
00087   if(nbOfAsso==0)
00088     {
00089       _ass1End1=1;
00090       _ass1Start2=1;
00091     }
00092   else
00093     {
00094       _ass2End1=1;
00095       _ass2Start2=1;
00096     }
00097 }
00098 
00099 void MergePoints::end1OnEnd2()
00100 {
00101   unsigned nbOfAsso=getNumberOfAssociations();
00102   if(nbOfAsso==0)
00103     {
00104       _ass1End1=1;
00105       _ass1End2=1;
00106     }
00107   else
00108     {
00109       _ass2End1=1;
00110       _ass2End2=1;
00111     }
00112 }
00113 
00114 bool MergePoints::isStart1(unsigned rk) const
00115 {
00116   if(rk==0)
00117     return _ass1Start1;
00118   else
00119     return _ass2Start1;
00120 }
00121 
00122 bool MergePoints::isEnd1(unsigned rk) const
00123 {
00124   if(rk==0)
00125     return _ass1End1;
00126   else
00127     return _ass2End1;
00128 }
00129 
00130 bool MergePoints::isStart2(unsigned rk) const
00131 {
00132   if(rk==0)
00133     return _ass1Start2;
00134   else
00135     return _ass2Start2;
00136 }
00137 
00138 bool MergePoints::isEnd2(unsigned rk) const
00139 {
00140   if(rk==0)
00141     return _ass1End2;
00142   else
00143     return _ass2End2;
00144 }
00145 
00146 void MergePoints::clear()
00147 {
00148   _ass1Start1=0;_ass1End1=0;_ass1Start2=0;_ass1End2=0;
00149   _ass2Start1=0;_ass2End1=0;_ass2Start2=0;_ass2End2=0;
00150 }
00151 
00152 unsigned MergePoints::getNumberOfAssociations() const
00153 {
00154   unsigned ret=0;
00155   unsigned subTot=_ass1Start1+_ass1End1+_ass1Start2+_ass1End2;
00156   if(subTot!=0)
00157     ret++;
00158   subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2;
00159   if(subTot!=0)
00160     ret++;
00161   return ret;
00162 }
00163 
00164 IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node
00165                                    , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2),
00166                                                                                      _1E(keepOrder?end1:end2),
00167                                                                                      _2S(keepOrder?start2:start1),
00168                                                                                      _2E(keepOrder?end2:end1),
00169                                                                                      _chararct_val_for_e1(keepOrder?val1:val2),
00170                                                                                      _chararct_val_for_e2(keepOrder?val2:val1),
00171                                                                                      _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2),
00172                                                                                      _e2(keepOrder?e2:e1)
00173 {
00174 }
00175 
00176 IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E),
00177                                                                   _chararct_val_for_e1(other._chararct_val_for_e1),
00178                                                                   _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node),
00179                                                                   _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2)
00180 {
00181   if(_node)
00182     _node->incrRef();
00183 }
00184 
00185 IntersectElement& IntersectElement::operator=(const IntersectElement& other)
00186 {
00187   _1S=other._1S;_1E=other._1E; _2S=other._2S; _2E=other._2E;
00188   _chararct_val_for_e1=other._chararct_val_for_e1;
00189   _chararct_val_for_e2=other._chararct_val_for_e2;
00190   setNode(other._node);
00191   return *this;
00192 }
00193 
00194 bool IntersectElement::operator<(const IntersectElement& other) const
00195 {
00196   return _e1.isLower(_chararct_val_for_e1,other._chararct_val_for_e1);
00197 }
00198 
00199 IntersectElement::~IntersectElement()
00200 {
00201   if(_node)
00202     _node->decrRef();
00203 }
00204 
00208 bool IntersectElement::isOnMergedExtremity() const
00209 {
00210   if( (_1S && _2S) || (_1S && _2E) || (_1E && _2S) || (_1E && _2E) )
00211     return true;
00212   return false;
00213 }
00214 
00218 void IntersectElement::performMerging(MergePoints& commonNode) const
00219 {
00220   if(_1S && _2S)
00221     {
00222       if(_e1.changeStartNodeWith(_e2.getStartNode()))
00223         {
00224           _e2.getStartNode()->declareOnLim();
00225           commonNode.start1OnStart2();
00226         }
00227     }
00228   else if(_1S && _2E)
00229     {
00230       if(_e1.changeStartNodeWith(_e2.getEndNode()))
00231         {
00232           _e2.getEndNode()->declareOnLim();
00233           commonNode.start1OnEnd2();
00234         }
00235     }
00236   else if(_1E && _2S)
00237     {
00238       if(_e1.changeEndNodeWith(_e2.getStartNode()))
00239         {
00240           _e2.getStartNode()->declareOnLim();
00241           commonNode.end1OnStart2();
00242         }
00243     }
00244   else if(_1E && _2E)
00245     {
00246       if(_e1.changeEndNodeWith(_e2.getEndNode()))
00247         {
00248           _e2.getEndNode()->declareOnLim();
00249           commonNode.end1OnEnd2();
00250         }
00251     }
00252 }
00253 
00257 void IntersectElement::setNode(Node *node) const
00258 {
00259   if(node!=_node)
00260     {
00261       if(_node)
00262         ((Node *)_node)->decrRef();
00263       (const_cast<IntersectElement *>(this))->_node=node;
00264       if(_node)
00265         _node->incrRef();
00266     }
00267 }
00268 
00269 bool IntersectElement::isLowerOnOther(const IntersectElement& other) const
00270 {
00271   return _e2.isLower(_chararct_val_for_e2,other._chararct_val_for_e2);
00272 }
00273 
00274 unsigned IntersectElement::isOnExtrForAnEdgeAndInForOtherEdge() const
00275 {
00276   if(( _1S && !(_2S || _2E) ) || ( _1E && !(_2S || _2E) ))
00277     {
00278       if(_1S && !(_2S || _2E))
00279         setNode(_e1.getStartNode());
00280       else
00281         setNode(_e1.getEndNode());
00282       if(_e2.isIn(_chararct_val_for_e2))
00283         return LIMIT_ON;
00284       return LIMIT_ALONE;
00285     }
00286   if(( _2S && !(_1S || _1E) ) || ( _2E && !(_1S || _1E)))
00287     {
00288       if(_2S && !(_1S || _1E))
00289         setNode(_e2.getStartNode());
00290       else
00291         setNode(_e2.getEndNode());
00292       if(_e1.isIn(_chararct_val_for_e1))
00293         return LIMIT_ON;
00294       return LIMIT_ALONE;
00295     }
00296   return NO_LIMIT;
00297 }
00298 
00299 bool IntersectElement::isIncludedByBoth() const
00300 {
00301   return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2);
00302 }
00303   
00304 bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode)
00305 {
00306   std::list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal();
00307   std::list< IntersectElement >::iterator iter;
00308   for(iter=listOfIntesc.begin();iter!=listOfIntesc.end();)
00309     {
00310       if((*iter).isOnMergedExtremity())
00311         {
00312           (*iter).performMerging(commonNode);
00313           iter=listOfIntesc.erase(iter);
00314           continue;
00315         }
00316       unsigned tmp=(*iter).isOnExtrForAnEdgeAndInForOtherEdge();
00317       if(tmp==IntersectElement::LIMIT_ALONE)
00318         {
00319           iter=listOfIntesc.erase(iter);
00320           continue;
00321         }
00322       else if(tmp==IntersectElement::LIMIT_ON)
00323         {
00324           (*iter).attachLoc();
00325           iter++;
00326           continue;
00327         }
00328       if(!(*iter).isIncludedByBoth())
00329         {
00330           iter=listOfIntesc.erase(iter);
00331           continue;
00332         }
00333       (*iter).attachLoc();
00334       iter++;
00335     }
00336   if(listOfIntesc.size()==0)
00337     return false;
00338   if(listOfIntesc.size()==1)
00339     {
00340       order=true;//useless
00341       newNodes.push_back(listOfIntesc.front().getNodeAndReleaseIt());
00342     }
00343   else
00344     {
00345       std::vector<IntersectElement> vecOfIntesc(listOfIntesc.begin(),listOfIntesc.end());
00346       listOfIntesc.clear();
00347       sort(vecOfIntesc.begin(),vecOfIntesc.end());
00348       for(std::vector<IntersectElement>::iterator iterV=vecOfIntesc.begin();iterV!=vecOfIntesc.end();iterV++)
00349         newNodes.push_back((*iterV).getNodeAndReleaseIt());
00350       order=vecOfIntesc.front().isLowerOnOther(vecOfIntesc.back());
00351     }
00352   return true;
00353 }
00354 
00361 void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const
00362 {
00363   obvious=true;
00364   if(node->isEqual(*_e1.getStartNode()))
00365     {
00366       where=START;
00367       if(_e1.changeStartNodeWith(node))
00368         {
00369           commonNode.start1Replaced();
00370           node->declareOnLim();
00371         }
00372       return ;
00373     }
00374   if(node->isEqual(*_e1.getEndNode()))
00375     {
00376       where=END;
00377       if(_e1.changeEndNodeWith(node))
00378         {
00379           commonNode.end1Replaced();
00380           node->declareOnLim();
00381         }
00382       return ;
00383     }
00384   obvious=false;
00385 }
00386 
00387 Edge::Edge(double sX, double sY, double eX, double eY):_cnt(1),_loc(FULL_UNKNOWN),_start(new Node(sX,sY)),_end(new Node(eX,eY))
00388 {
00389 }
00390 
00391 Edge::~Edge()
00392 {
00393   _start->decrRef();
00394   if(_end)
00395     _end->decrRef();
00396 }
00397 
00398 bool Edge::decrRef()
00399 {
00400   bool ret=(--_cnt==0);
00401   if(ret)
00402     delete this;
00403   return ret;
00404 }
00405 
00406 void Edge::declareOn() const
00407 {
00408   if(_loc==FULL_UNKNOWN)
00409     {
00410       _loc=FULL_ON_1;
00411       _start->declareOn();
00412       _end->declareOn();
00413     }
00414 }
00415 
00416 void Edge::declareIn() const
00417 {
00418   if(_loc==FULL_UNKNOWN)
00419     {
00420       _loc=FULL_IN_1;
00421       _start->declareIn();
00422       _end->declareIn();
00423     }
00424 }
00425 
00426 void Edge::declareOut() const
00427 {
00428   if(_loc==FULL_UNKNOWN)
00429     {
00430       _loc=FULL_OUT_1;
00431       _start->declareOut();
00432       _end->declareOut();
00433     }
00434 }
00435 
00436 void Edge::fillXfigStreamForLoc(std::ostream& stream) const
00437 {
00438   switch(_loc)
00439     {
00440     case FULL_IN_1:
00441       stream << '2';//Green
00442       break;
00443     case FULL_OUT_1:
00444       stream << '1';//Bleue
00445       break;
00446     case FULL_ON_1:
00447       stream << '4';//Red
00448       break;
00449     default:
00450       stream << '0';
00451     }
00452 }
00453 
00454 bool Edge::changeStartNodeWith(Node *otherStartNode) const
00455 {
00456   if(_start==otherStartNode)
00457     return true;
00458   if(_start->isEqual(*otherStartNode))
00459     {
00460       ((const_cast<Edge *>(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above.
00461       ((const_cast<Edge *>(this))->_start)=otherStartNode;
00462       _start->incrRef();
00463       return true;
00464     }
00465   return false;
00466 }
00467 
00468 bool Edge::changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector<Node *>& track) const
00469 {
00470   if(_start==otherStartNode)
00471     return true;
00472   if(_start->isEqualAndKeepTrack(*otherStartNode,track))
00473     {
00474       ((const_cast<Edge *>(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above.
00475       ((const_cast<Edge *>(this))->_start)=otherStartNode;
00476       otherStartNode->incrRef();
00477       return true;
00478     }
00479   return false;
00480 }
00481 
00482 bool Edge::changeEndNodeWith(Node *otherEndNode) const
00483 {
00484   if(_end==otherEndNode)
00485     return true;
00486   if(_end->isEqual(*otherEndNode))
00487     {
00488       ((const_cast<Edge *>(this))->_end)->decrRef();
00489       ((const_cast<Edge *>(this))->_end)=otherEndNode;
00490       _end->incrRef();
00491       return true;
00492     }
00493   return false;
00494 }
00495 
00496 bool Edge::changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const
00497 {
00498   if(_end==otherEndNode)
00499     return true;
00500   if(_end->isEqualAndKeepTrack(*otherEndNode,track))
00501     {
00502       ((const_cast<Edge *>(this))->_end)->decrRef();
00503       ((const_cast<Edge *>(this))->_end)=otherEndNode;
00504       otherEndNode->incrRef();
00505       return true;
00506     }
00507   return false;
00508 }
00509 
00517 void Edge::addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const
00518 {
00519   if((start==_start && end==_start) || (start==_end && end==_end))
00520     return ;
00521   if(start==_start && end==_end)
00522     {
00523       incrRef();
00524       vec.pushBack(const_cast<Edge *>(this));
00525       return ;
00526     }
00527   vec.pushBack(buildEdgeLyingOnMe(start,end,true));
00528 }
00529 
00533 void Edge::getNormalVector(double *vectOutput) const
00534 {
00535   std::copy((const double *)(*_end),(const double *)(*_end)+2,vectOutput);
00536   std::transform(vectOutput,vectOutput+2,(const double *)(*_start),vectOutput,std::minus<double>());
00537   double norm=1./Node::norm(vectOutput);
00538   std::transform(vectOutput,vectOutput+2,vectOutput,bind2nd(std::multiplies<double>(),norm));
00539   double tmp=vectOutput[0];
00540   vectOutput[0]=vectOutput[1];
00541   vectOutput[1]=-tmp;
00542 }
00543 
00544 Edge *Edge::BuildEdgeFrom(Node *start, Node *end)
00545 {
00546   return new EdgeLin(start,end);
00547 }
00548 
00549 Edge *Edge::BuildFromXfigLine(std::istream& str)
00550 {
00551   unsigned char type;
00552   str >> type;
00553   if(type=='2')
00554     return new EdgeLin(str);
00555   else if(type=='5')
00556     return new EdgeArcCircle(str);
00557   else
00558     {
00559       std::cerr << "Unknown line found...";
00560       return 0;
00561     }
00562 }
00563 
00571 bool Edge::intersectWith(const Edge *other, MergePoints& commonNode,
00572                          ComposedEdge& outVal1, ComposedEdge& outVal2) const
00573 {
00574   bool ret=true;
00575   Bounds *merge=_bounds.nearlyAmIIntersectingWith(other->getBounds());
00576   if(!merge)
00577     return false;
00578   delete merge;
00579   merge=0;
00580   EdgeIntersector *intersector=BuildIntersectorWith(this,other);
00581   ret=Intersect(this,other,intersector,merge,commonNode,outVal1,outVal2);
00582   delete intersector;
00583   return ret;
00584 }
00585 
00586 bool Edge::IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
00587                                ComposedEdge& outValForF1, ComposedEdge& outValForF2)
00588 {
00589   bool rev=intersector->haveTheySameDirection();
00590   Node *f2Start=f2->getNode(rev?START:END);
00591   Node *f2End=f2->getNode(rev?END:START);
00592   TypeOfLocInEdge place1, place2;
00593   intersector->getPlacements(f2Start,f2End,place1,place2,commonNode);
00594   int codeForIntersectionCase=CombineCodes(place1,place2);
00595   return SplitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2);
00596 }
00597 
00601 void Edge::Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2, std::map<int, std::map<int,double> >& result)
00602 {
00603   int nbOfV1=distrib1.size()-1;
00604   int nbOfV2=distrib2.size()-1;
00605   Node *n1=new Node(0.,0.); Node *n3=new Node(0.,0.);
00606   Node *n2=new Node(0.,0.); Node *n4=new Node(0.,0.);
00607   MergePoints commonNode;
00608   for(int i=0;i<nbOfV1;i++)
00609     {
00610       std::vector<double>::const_iterator iter=find_if(distrib2.begin()+1,distrib2.end(),bind2nd(std::greater_equal<double>(),distrib1[i]));
00611       if(iter!=distrib2.end())
00612         {
00613           for(int j=(iter-1)-distrib2.begin();j<nbOfV2;j++)
00614             {
00615               if(distrib2[j]<=distrib1[i+1])
00616                 {
00617                   EdgeLin *e1=new EdgeLin(n1,n2); EdgeLin *e2=new EdgeLin(n3,n4);
00618                   n1->setNewCoords(distrib1[i],0.); n2->setNewCoords(distrib1[i+1],0.);
00619                   n3->setNewCoords(distrib2[j],0.); n4->setNewCoords(distrib2[j+1],0.);
00620                   ComposedEdge *f1=new ComposedEdge;
00621                   ComposedEdge *f2=new ComposedEdge;
00622                   SegSegIntersector inters(*e1,*e2);
00623                   bool b1,b2;
00624                   inters.areOverlappedOrOnlyColinears(0,b1,b2);
00625                   if(IntersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2))
00626                     {
00627                       result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength();
00628                     }
00629                   ComposedEdge::Delete(f1); ComposedEdge::Delete(f2);
00630                   e1->decrRef(); e2->decrRef();
00631                 }
00632             }
00633         }
00634     }
00635   n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef();
00636 }
00637 
00638 EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2)
00639 {
00640   EdgeIntersector *ret=0;
00641   const EdgeLin *tmp1=0;
00642   const EdgeArcCircle *tmp2=0;
00643   unsigned char type1=e1->getTypeOfFunc();
00644   e1->dynCastFunction(tmp1,tmp2);
00645   unsigned char type2=e2->getTypeOfFunc();
00646   e2->dynCastFunction(tmp1,tmp2);
00647   type1|=type2;
00648   switch(type1)
00649     {
00650     case 1:// Intersection seg/seg
00651       ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2));
00652       break;
00653     case 5:// Intersection seg/arc of circle
00654       ret=new ArcCSegIntersector(*tmp2,*tmp1,tmp2==e1);
00655       break;
00656     case 4:// Intersection arc/arc of circle
00657       ret=new ArcCArcCIntersector((const EdgeArcCircle &)(*e1),(const EdgeArcCircle &)(*e2));
00658       break;
00659     default:
00660       //Should never happen
00661       throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation.");
00662     }
00663   return ret;
00664 }
00665 
00669 void Edge::applySimilarity(double xBary, double yBary, double dimChar)
00670 {
00671   _bounds.applySimilarity(xBary,yBary,dimChar);
00672 }
00673 
00674 void Edge::unApplySimilarity(double xBary, double yBary, double dimChar)
00675 {
00676   _bounds.unApplySimilarity(xBary,yBary,dimChar);
00677 }
00678 
00679 bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
00680                      ComposedEdge& outValForF1, ComposedEdge& outValForF2)
00681 {
00682   bool obviousNoIntersection;
00683   bool areOverlapped;
00684   intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped);
00685   if(areOverlapped)
00686     return IntersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2);
00687   if(obviousNoIntersection)
00688     return false;
00689   std::vector<Node *> newNodes;
00690   bool order;
00691   if(intersector->intersect(whereToFind,newNodes,order,commonNode))
00692     {
00693       if(newNodes.empty())
00694         throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen
00695       std::vector<Node *>::iterator iter=newNodes.begin();
00696       std::vector<Node *>::reverse_iterator iterR=newNodes.rbegin();
00697       f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1);
00698       f2->addSubEdgeInVector(f2->getStartNode(),order?*iter:*iterR,outValForF2);
00699       for(std::vector<Node *>::iterator iter2=newNodes.begin();iter2!=newNodes.end();iter2++,iterR++)
00700         {
00701           if((iter2+1)==newNodes.end())
00702             {
00703               f1->addSubEdgeInVector(*iter2,f1->getEndNode(),outValForF1);
00704               (*iter2)->decrRef();
00705               f2->addSubEdgeInVector(order?*iter2:*iterR,f2->getEndNode(),outValForF2);
00706             }
00707           else
00708             {
00709               f1->addSubEdgeInVector(*iter2,*(iter2+1),outValForF1);
00710               (*iter2)->decrRef();
00711               f2->addSubEdgeInVector(order?*iter2:*iterR,order?*(iter2+1):*(iterR+1),outValForF2);
00712             }
00713         }
00714       return true;
00715     }
00716   else//no intersection inside whereToFind
00717     return false;
00718 }
00719 
00720 int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2)
00721 {
00722   int ret=(int)code1;
00723   ret*=OFFSET_FOR_TYPEOFLOCINEDGE;
00724   ret+=(int)code2;
00725   return ret;
00726 }
00727 
00737 bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
00738                                 ComposedEdge& outVal1, ComposedEdge& outVal2)
00739 {
00740   Edge *tmp;
00741   switch(code)
00742     {
00743     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START:      // OUT_BEFORE - START
00744     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE
00745     case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:   // OUT_AFTER - OUT_AFTER
00746     case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:         // END - OUT_AFTER
00747     case END*OFFSET_FOR_TYPEOFLOCINEDGE+START:             // END - START
00748       return false;
00749     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:      // INSIDE - OUT_AFTER
00750       outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true));
00751       tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef();
00752       outVal1.pushBack(tmp);
00753       outVal2.resize(2);
00754       outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn();
00755       outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
00756       return true;
00757     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:         // INSIDE - INSIDE
00758       {
00759         if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode()))))
00760           {
00761             e2->incrRef(); e2->incrRef();
00762             outVal1.resize(3);
00763             outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS));
00764             outVal1.setValueAt(1,const_cast<Edge*>(e2),direction);
00765             outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
00766             outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
00767             return true;
00768           }
00769         else
00770           {
00771             outVal1.resize(3);
00772             outVal2.resize(3);
00773             tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn();
00774             outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction);
00775             outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS));
00776             tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn();
00777             outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction);
00778             tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode());
00779             outVal2.setValueAt(1,tmp,direction);
00780             return true;
00781           }
00782       }
00783     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:     // OUT_BEFORE - INSIDE
00784       tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef();
00785       outVal1.pushBack(tmp);
00786       outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
00787       outVal2.resize(2);
00788       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction));
00789       outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn();
00790       return true;
00791     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:  // OUT_BEFORE - OUT_AFTER
00792       e1->incrRef(); e1->incrRef();
00793       outVal1.pushBack(const_cast<Edge*>(e1));
00794       outVal2.resize(3);
00795       outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction));
00796       outVal2.setValueAt(1,const_cast<Edge*>(e1),direction); e1->declareOn();
00797       outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
00798       return true;
00799     case START*OFFSET_FOR_TYPEOFLOCINEDGE+END:             // START - END
00800       e1->incrRef(); e1->incrRef();
00801       outVal1.pushBack(const_cast<Edge*>(e1));
00802       outVal2.pushBack(const_cast<Edge*>(e1),direction); e1->declareOn();
00803       return true;
00804     case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER:       // START - OUT_AFTER
00805       e1->incrRef(); e1->incrRef();
00806       outVal1.pushBack(const_cast<Edge*>(e1));
00807       outVal2.resize(2);
00808       outVal2.setValueAt(direction?0:1,const_cast<Edge*>(e1),direction); e1->declareOn();
00809       outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
00810       return true;
00811     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END:            // INSIDE - END
00812       e2->incrRef(); e2->incrRef();
00813       outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true));
00814       outVal1.pushBack(const_cast<Edge*>(e2),direction);
00815       outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
00816       return true;
00817     case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END:        // OUT_BEFORE - END
00818       e1->incrRef(); e1->incrRef();
00819       outVal1.pushBack(const_cast<Edge*>(e1));
00820       outVal2.resize(2);
00821       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction));
00822       outVal2.setValueAt(direction?1:0,const_cast<Edge*>(e1),direction); e1->declareOn();
00823       return true;
00824     case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:          // START - INSIDE
00825       e2->incrRef(); e2->incrRef();
00826       outVal1.pushBack(const_cast<Edge*>(e2),direction);
00827       outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
00828       outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn();
00829       return true;
00830     case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START:          // INSIDE - START
00831       outVal1.resize(2);
00832       outVal2.resize(2);
00833       tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn();
00834       outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS));
00835       outVal1.setValueAt(1,tmp);
00836       outVal2.setValueAt(direction?0:1,tmp,direction);
00837       outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction));
00838       return true;
00839     case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE:            // END - INSIDE
00840       outVal1.resize(2);
00841       outVal2.resize(2);
00842       tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn();
00843       outVal1.setValueAt(0,tmp);
00844       outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,e1->getEndNode()));
00845       outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction));
00846       outVal2.setValueAt(direction?1:0,tmp,direction);
00847       return true;
00848     default:
00849       throw Exception("Unexpected situation of overlapping edges : internal error occurs ! ");
00850     }
00851 }
00852 
00853 bool Edge::isEqual(const Edge& other) const
00854 {
00855   return _start->isEqual(*other._start) && _end->isEqual(*other._end);
00856 }
00857 
00858 inline bool eqpair(const std::pair<double,Node *>& p1, const std::pair<double,Node *>& p2)
00859 {
00860   return fabs(p1.first-p2.first)<QUADRATIC_PLANAR::_precision;
00861 }
00862 
00863 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)
00864 {
00865   Bounds b;
00866   b.prepareForAggregation();
00867   b.aggregate(getBounds());
00868   double xBary,yBary;
00869   double dimChar=b.getCaracteristicDim();
00870   b.getBarycenter(xBary,yBary);
00871   for(std::vector<Node *>::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++)
00872     (*iter)->applySimilarity(xBary,yBary,dimChar);
00873   applySimilarity(xBary,yBary,dimChar);
00874   _start->applySimilarity(xBary,yBary,dimChar);
00875   _end->applySimilarity(xBary,yBary,dimChar);
00876   std::size_t sz=addNodes.size();
00877   std::vector< std::pair<double,Node *> > an2(sz);
00878   for(std::size_t i=0;i<sz;i++)
00879     an2[i]=std::pair<double,Node *>(getCharactValueBtw0And1(*addNodes[i]),addNodes[i]);
00880   std::sort(an2.begin(),an2.end());
00881   int startId=(*mapp1.find(_start)).second;
00882   int endId=(*mapp1.find(_end)).second;
00883   std::vector<int> tmpp;
00884   std::vector< std::pair<double,Node *> >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair);
00885   for(std::vector< std::pair<double,Node *> >::const_iterator it=an2.begin();it!=itend;it++)
00886     {
00887       int idd=(*mapp2.find((*it).second)).second;
00888       if((*it).first<QUADRATIC_PLANAR::_precision)
00889         {
00890           startId=idd;
00891           continue;
00892         }
00893       if((*it).first>1-QUADRATIC_PLANAR::_precision)
00894         {
00895           endId=idd;
00896           continue;
00897         }
00898       tmpp.push_back(idd);
00899     }
00900   std::vector<int> tmpp2(tmpp.size()+2);
00901   tmpp2[0]=startId;
00902   std::copy(tmpp.begin(),tmpp.end(),tmpp2.begin()+1);
00903   tmpp2[tmpp.size()+1]=endId;
00904   std::vector<int>::iterator itt=std::unique(tmpp2.begin(),tmpp2.end());
00905   tmpp2.resize(std::distance(tmpp2.begin(),itt));
00906   int nbOfEdges=tmpp2.size()-1;
00907   for(int i=0;i<nbOfEdges;i++)
00908     {
00909       edgesThis.push_back(tmpp2[i]);
00910       edgesThis.push_back(tmpp2[i+1]);
00911     }
00912 }