Back to index

salome-med  6.5.0
InterpKernelGeo2DComposedEdge.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 "InterpKernelGeo2DComposedEdge.hxx"
00021 #include "InterpKernelGeo2DElementaryEdge.hxx"
00022 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
00023 #include "InterpKernelGeo2DEdgeInfLin.hxx"
00024 #include "InterpKernelException.hxx"
00025 
00026 #include <algorithm>
00027 #include <memory>
00028 #include <iterator>
00029 #include <set>
00030 
00031 using namespace INTERP_KERNEL;
00032 
00033 ComposedEdge::ComposedEdge(const ComposedEdge& other)
00034 {
00035   for(std::list<ElementaryEdge *>::const_iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++)
00036     _sub_edges.push_back((*iter)->clone());
00037 }
00038 
00039 ComposedEdge::~ComposedEdge()
00040 {
00041   clearAll(_sub_edges.begin());
00042 }
00043 
00044 void ComposedEdge::setValueAt(int i, Edge *e, bool direction)
00045 {
00046   std::list<ElementaryEdge*>::iterator it=_sub_edges.begin();
00047   for(int j=0;j<i;j++)
00048     it++;
00049   delete *it;
00050   *it=new ElementaryEdge(e,direction);
00051 }
00052 
00053 struct AbsEdgeCmp
00054 {
00055   AbsEdgeCmp(ElementaryEdge *b):_b1(b) { }
00056   bool operator()(ElementaryEdge *a) { return a->getPtr()==_b1->getPtr();}
00057 
00058   ElementaryEdge *_b1;
00059 };
00060 
00061 double ComposedEdge::getCommonLengthWith(const ComposedEdge& other) const
00062 {
00063   double ret=0.;
00064   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00065     {
00066       if(find_if(other._sub_edges.begin(),other._sub_edges.end(),AbsEdgeCmp(*iter))!=other._sub_edges.end())
00067         {
00068           const ElementaryEdge *tmp=static_cast<const ElementaryEdge *>(*iter);
00069           ret+=tmp->getCurveLength();
00070         }
00071     }
00072   return ret;
00073 }
00074 
00075 void ComposedEdge::clear()
00076 {
00077   clearAll(_sub_edges.begin());
00078   _sub_edges.clear();
00079 }
00080 
00081 void ComposedEdge::pushBack(Edge *edge, bool direction)
00082 {
00083   _sub_edges.push_back(new ElementaryEdge(edge,direction));
00084 }
00085 
00086 void ComposedEdge::pushBack(ElementaryEdge *elem)
00087 {
00088   _sub_edges.push_back(elem);
00089 }
00090 
00091 void ComposedEdge::pushBack(ComposedEdge *elem)
00092 {
00093   std::list<ElementaryEdge *> *elemsOfElem=elem->getListBehind();
00094   _sub_edges.insert(_sub_edges.end(),elemsOfElem->begin(),elemsOfElem->end());
00095 }
00096 
00097 ElementaryEdge *ComposedEdge::operator[](int i) const
00098 {
00099   std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();
00100   for(int ii=0;ii<i;ii++)
00101     iter++;
00102   return *iter;
00103 }
00104 
00105 void ComposedEdge::reverse()
00106 {
00107   _sub_edges.reverse();
00108   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00109     (*iter)->reverse();
00110 }
00111 
00112 bool ComposedEdge::presenceOfOn() const
00113 {
00114   bool ret=false;
00115   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++)
00116     ret=((*iter)->getLoc()==FULL_ON_1);
00117   return ret;
00118 }
00119 
00120 bool ComposedEdge::presenceOfQuadraticEdge() const
00121 {
00122   bool ret=false;
00123   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++)
00124     {
00125       Edge *e=(*iter)->getPtr();
00126       if(e)
00127         ret=dynamic_cast<EdgeArcCircle*>(e)!=0;
00128     }
00129   return ret;
00130 }
00131 
00132 void ComposedEdge::initLocations() const
00133 {
00134   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00135     (*iter)->initLocations();
00136 }
00137 
00138 ComposedEdge *ComposedEdge::clone() const
00139 {
00140   return new ComposedEdge(*this);
00141 }
00142 
00143 bool ComposedEdge::isNodeIn(Node *n) const
00144 {
00145   bool ret=false;
00146   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++)
00147     ret=(*iter)->isNodeIn(n);
00148   return ret;
00149 }
00150 
00166 double ComposedEdge::getArea() const
00167 {
00168   double ret=0.;
00169   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00170     ret+=(*iter)->getAreaOfZone();
00171   return ret;
00172 }
00173 
00174 double ComposedEdge::getPerimeter() const
00175 {
00176   double ret=0.;
00177   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00178     ret+=(*iter)->getCurveLength();
00179   return ret;
00180 }
00181 
00182 double ComposedEdge::getHydraulicDiameter() const
00183 {
00184   return 4*fabs(getArea())/getPerimeter();
00185 }
00186 
00206 void ComposedEdge::getBarycenter(double *bary) const
00207 {
00208   bary[0]=0.;
00209   bary[1]=0.;
00210   double area=0.;
00211   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00212     {
00213       (*iter)->getBarycenterOfZone(bary);
00214       area+=(*iter)->getAreaOfZone();
00215     }
00216   bary[0]/=area;
00217   bary[1]/=area;
00218 }
00219 
00223 void ComposedEdge::getBarycenterGeneral(double *bary) const
00224 {
00225   if(_sub_edges.empty())
00226     throw INTERP_KERNEL::Exception("ComposedEdge::getBarycenterGeneral called on an empty polygon !");
00227   if(_sub_edges.size()>2)
00228     return getBarycenter(bary);
00229   double w;
00230   _sub_edges.back()->getBarycenter(bary,w);
00231 }
00232 
00233 double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary)
00234 {
00235   Bounds b;
00236   b.prepareForAggregation();
00237   fillBounds(b); 
00238   other->fillBounds(b);
00239   double dimChar=b.getCaracteristicDim();
00240   b.getBarycenter(xBary,yBary);
00241   applyGlobalSimilarity(xBary,yBary,dimChar);
00242   other->applyGlobalSimilarity(xBary,yBary,dimChar);
00243   return dimChar;
00244 }
00245 
00249 void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact)
00250 {
00251   std::set<Node *> allNodes;
00252   getAllNodes(allNodes);
00253   other.getAllNodes(allNodes);
00254   for(std::set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++)
00255     (*iter)->unApplySimilarity(xBary,yBary,fact);
00256   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00257     (*iter)->unApplySimilarity(xBary,yBary,fact);
00258 }
00259 
00260 double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary)
00261 {
00262   Bounds b;
00263   b.prepareForAggregation();
00264   fillBounds(b); 
00265   other->fillBounds(b);
00266   double dimChar=b.getCaracteristicDim();
00267   b.getBarycenter(xBary,yBary);
00268   applyGlobalSimilarity2(other,xBary,yBary,dimChar);
00269   return dimChar;
00270 }
00271 
00272 void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
00273 {
00274   stream.precision(10);
00275   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00276     (*iter)->dumpInXfigFile(stream,resolution,box);
00277 }
00278 
00279 Node *ComposedEdge::getEndNode() const
00280 {
00281   return _sub_edges.back()->getEndNode();
00282 }
00283 
00284 Node *ComposedEdge::getStartNode() const
00285 {
00286   return _sub_edges.front()->getStartNode();
00287 }
00288 
00289 bool ComposedEdge::changeEndNodeWith(Node *node) const
00290 {
00291   return _sub_edges.back()->changeEndNodeWith(node);
00292 }
00293 
00294 bool ComposedEdge::changeStartNodeWith(Node *node) const
00295 {
00296   return _sub_edges.front()->changeStartNodeWith(node);
00297 }
00298 
00299 void ComposedEdge::fillBounds(Bounds& output) const
00300 {
00301   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00302     (*iter)->fillBounds(output);
00303 }
00304 
00308 void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar)
00309 {
00310   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00311     (*iter)->applySimilarity(xBary,yBary,dimChar);
00312 }
00313 
00317 void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar)
00318 {
00319   std::set<Node *> allNodes;
00320   getAllNodes(allNodes);
00321   for(std::set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++)
00322     (*iter)->applySimilarity(xBary,yBary,dimChar);
00323   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00324     (*iter)->applySimilarity(xBary,yBary,dimChar);
00325 }
00326 
00331 void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar)
00332 {
00333   std::set<Node *> allNodes;
00334   getAllNodes(allNodes);
00335   std::set<Node *> allNodes2;
00336   other->getAllNodes(allNodes2);
00337   for(std::set<Node *>::const_iterator it=allNodes2.begin();it!=allNodes2.end();it++)
00338     if(allNodes.find(*it)!=allNodes.end())
00339       (*it)->declareOn();
00340   allNodes.insert(allNodes2.begin(),allNodes2.end());
00341   for(std::set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++)
00342     (*iter)->applySimilarity(xBary,yBary,dimChar);
00343   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00344     (*iter)->applySimilarity(xBary,yBary,dimChar);
00345   for(std::list<ElementaryEdge *>::iterator iter=other->_sub_edges.begin();iter!=other->_sub_edges.end();iter++)
00346     (*iter)->applySimilarity(xBary,yBary,dimChar);
00347 }
00348 
00353 void ComposedEdge::dispatchPerimeter(double& partConsidered) const
00354 {
00355   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00356     {
00357       TypeOfEdgeLocInPolygon loc=(*iter)->getLoc();
00358       if(loc==FULL_IN_1 || loc==FULL_ON_1)
00359         partConsidered+=(*iter)->getCurveLength();
00360     }
00361 }
00362 
00366 void ComposedEdge::dispatchPerimeterExcl(double& partConsidered, double& commonPart) const
00367 {
00368   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00369     {
00370       TypeOfEdgeLocInPolygon loc=(*iter)->getLoc();
00371       if(loc==FULL_IN_1)
00372         partConsidered+=(*iter)->getCurveLength();
00373       if(loc==FULL_ON_1)
00374         commonPart+=(*iter)->getCurveLength();
00375     }
00376 }
00377 
00378 void ComposedEdge::getAllNodes(std::set<Node *>& output) const
00379 {
00380   std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();
00381   for(;iter!=_sub_edges.end();iter++)
00382     (*iter)->getAllNodes(output);
00383 }
00384 
00385 void ComposedEdge::getBarycenter(double *bary, double& weigh) const
00386 {
00387   weigh=0.; bary[0]=0.; bary[1]=0.;
00388   double tmp1,tmp2[2];
00389   for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00390     {
00391       (*iter)->getBarycenter(tmp2,tmp1);
00392       weigh+=tmp1;
00393       bary[0]+=tmp1*tmp2[0];
00394       bary[1]+=tmp1*tmp2[1];
00395     }
00396   bary[0]/=weigh;
00397   bary[1]/=weigh;
00398 }
00399 
00400 bool ComposedEdge::isInOrOut(Node *nodeToTest) const
00401 {
00402   Bounds b; b.prepareForAggregation();
00403   fillBounds(b);
00404   if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT)
00405     return false;
00406   // searching for e1
00407   std::set<Node *> nodes;
00408   getAllNodes(nodes);
00409   std::set<double> radialDistributionOfNodes;
00410   std::set<Node *>::const_iterator iter;
00411   for(iter=nodes.begin();iter!=nodes.end();iter++)
00412     radialDistributionOfNodes.insert(nodeToTest->getSlope(*(*iter)));
00413   std::vector<double> radialDistrib(radialDistributionOfNodes.begin(),radialDistributionOfNodes.end());
00414   radialDistributionOfNodes.clear();
00415   std::vector<double> radialDistrib2(radialDistrib.size());
00416   copy(radialDistrib.begin()+1,radialDistrib.end(),radialDistrib2.begin());
00417   radialDistrib2.back()=M_PI+radialDistrib.front();
00418   std::vector<double> radialDistrib3(radialDistrib.size());
00419   std::transform(radialDistrib2.begin(),radialDistrib2.end(),radialDistrib.begin(),radialDistrib3.begin(),std::minus<double>());
00420   std::vector<double>::iterator iter3=max_element(radialDistrib3.begin(),radialDistrib3.end());
00421   int i=iter3-radialDistrib3.begin();
00422   // ok for e1 - Let's go.
00423   EdgeInfLin *e1=new EdgeInfLin(nodeToTest,radialDistrib[i]+radialDistrib3[i]/2.);
00424   double ref=e1->getCharactValue(*nodeToTest);
00425   std::set< IntersectElement > inOutSwitch;
00426   for(std::list<ElementaryEdge *>::const_iterator iter4=_sub_edges.begin();iter4!=_sub_edges.end();iter4++)
00427     {
00428       ElementaryEdge *val=(*iter4);
00429       if(val)
00430         {
00431           Edge *e=val->getPtr();
00432           std::auto_ptr<EdgeIntersector> intersc(Edge::BuildIntersectorWith(e1,e));
00433           bool obviousNoIntersection,areOverlapped;
00434           intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped);
00435           if(obviousNoIntersection)
00436             {
00437               continue;
00438             }
00439           if(!areOverlapped)
00440             {
00441               std::list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal();
00442               for(std::list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++)
00443                 if((*iter2).isIncludedByBoth())
00444                   inOutSwitch.insert(*iter2);
00445               }
00446           //if overlapped we can forget
00447         }
00448       else
00449         throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !");
00450     }
00451   e1->decrRef();
00452   bool ret=false;
00453   for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++)
00454     {
00455       if((*iter4).getVal1()<ref)
00456         {
00457           if((*iter4).getNodeOnly()->getLoc()==ON_1)
00458             ret=!ret;
00459         }
00460       else
00461         break;
00462     }
00463   return ret;
00464 }
00465 
00466 /*bool ComposedEdge::isInOrOut(Node *aNodeOn, Node *nodeToTest) const
00467 {
00468   
00469   EdgeInfLin *e1=new EdgeInfLin(aNodeOn,nodeToTest);
00470   double ref=e1->getCharactValue(*nodeToTest);
00471   set< IntersectElement > inOutSwitch;
00472   for(vector<AbstractEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
00473     {
00474       ElementaryEdge *val=dynamic_cast<ElementaryEdge *>(*iter);
00475       if(val)
00476         {
00477           Edge *e=val->getPtr();
00478           auto_ptr<Intersector> intersc(Edge::buildIntersectorWith(e1,e));
00479           bool obviousNoIntersection,areOverlapped;
00480           intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped);
00481           if(obviousNoIntersection)
00482             {
00483               continue;
00484             }
00485           if(!areOverlapped)
00486             {
00487               list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal();
00488               for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++)
00489                 if((*iter2).isIncludedByBoth())
00490                   inOutSwitch.insert(*iter2);
00491               }
00492           //if overlapped we can forget
00493         }
00494       else
00495         throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !");
00496     }
00497   e1->decrRef();
00498   bool ret=false;
00499   for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++)
00500     {
00501       if((*iter).getVal1()<ref)
00502         {
00503           if((*iter).getNodeOnly()->getLoc()==ON_1)
00504             ret=!ret;
00505         }
00506       else
00507         break;
00508     }
00509   return ret;
00510 }*/
00511 
00512 bool ComposedEdge::getDirection() const
00513 {
00514   throw Exception("ComposedEdge::getDirection : no sense");
00515 }
00516 
00517 bool ComposedEdge::intresincEqCoarse(const Edge *other) const
00518 {
00519   if(_sub_edges.size()!=1)
00520     return false;
00521   return _sub_edges.front()->intresincEqCoarse(other);
00522 }
00523 
00524 void ComposedEdge::clearAll(std::list<ElementaryEdge *>::iterator startToDel)
00525 {
00526   for(std::list<ElementaryEdge *>::iterator iter=startToDel;iter!=_sub_edges.end();iter++)
00527     delete (*iter);
00528 }