1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelGeo2DQuadraticPolygon.hxx"
22 #include "InterpKernelGeo2DElementaryEdge.hxx"
23 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
24 #include "InterpKernelGeo2DAbstractEdge.hxx"
25 #include "InterpKernelGeo2DEdgeLin.hxx"
26 #include "InterpKernelGeo2DBounds.hxx"
27 #include "InterpKernelGeo2DEdge.txx"
29 #include "NormalizedUnstructuredMesh.hxx"
37 using namespace INTERP_KERNEL;
39 namespace INTERP_KERNEL
41 const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024;
44 QuadraticPolygon::QuadraticPolygon(const char *file)
46 char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE];
47 std::ifstream stream(file);
48 stream.exceptions(std::ios_base::eofbit);
52 stream.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE);
53 while(strcmp(currentLine,"1200 2")!=0);
56 Edge *newEdge=Edge::BuildFromXfigLine(stream);
58 newEdge->changeStartNodeWith(back()->getEndNode());
63 catch(std::ifstream::failure&)
66 front()->changeStartNodeWith(back()->getEndNode());
69 QuadraticPolygon::~QuadraticPolygon()
73 QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector<Node *>& nodes)
75 QuadraticPolygon *ret(new QuadraticPolygon);
76 std::size_t size=nodes.size();
77 for(std::size_t i=0;i<size;i++)
79 ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%size]));
85 QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector<Node *>& nodes)
87 QuadraticPolygon *ret(new QuadraticPolygon);
88 std::size_t size=nodes.size();
89 for(std::size_t i=0;i<size/2;i++)
93 e1=new EdgeLin(nodes[i],nodes[i+size/2]);
94 e2=new EdgeLin(nodes[i+size/2],nodes[(i+1)%(size/2)]);
95 SegSegIntersector inters(*e1,*e2);
96 bool colinearity=inters.areColinears();
99 ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)]));
101 ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)]));
102 nodes[i]->decrRef(); nodes[i+size/2]->decrRef();
107 Edge *QuadraticPolygon::BuildLinearEdge(std::vector<Node *>& nodes)
110 throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !");
111 Edge *ret(new EdgeLin(nodes[0],nodes[1]));
112 nodes[0]->decrRef(); nodes[1]->decrRef();
116 Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector<Node *>& nodes)
119 throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !");
120 EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1]));
121 SegSegIntersector inters(*e1,*e2);
122 bool colinearity=inters.areColinears();
123 delete e1; delete e2;
126 ret=new EdgeLin(nodes[0],nodes[1]);
128 ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]);
129 nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef();
133 void QuadraticPolygon::BuildDbgFile(const std::vector<Node *>& nodes, const char *fileName)
135 std::ofstream file(fileName);
136 file << std::setprecision(16);
137 file << " double coords[]=" << std::endl << " { ";
138 for(std::vector<Node *>::const_iterator iter=nodes.begin();iter!=nodes.end();iter++)
140 if(iter!=nodes.begin())
141 file << "," << std::endl << " ";
142 file << (*(*iter))[0] << ", " << (*(*iter))[1];
144 file << "};" << std::endl;
147 void QuadraticPolygon::closeMe() const
149 if(!front()->changeStartNodeWith(back()->getEndNode()))
150 throw(Exception("big error: not closed polygon..."));
153 void QuadraticPolygon::circularPermute()
155 if(_sub_edges.size()>1)
157 ElementaryEdge *first=_sub_edges.front();
158 _sub_edges.pop_front();
159 _sub_edges.push_back(first);
163 bool QuadraticPolygon::isButterflyAbs()
165 INTERP_KERNEL::Bounds b;
167 b.prepareForAggregation();
169 double dimChar=b.getCaracteristicDim();
170 b.getBarycenter(xBary,yBary);
171 applyGlobalSimilarity(xBary,yBary,dimChar);
173 return isButterfly();
176 bool QuadraticPolygon::isButterfly() const
178 for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++)
180 Edge *e1=(*it)->getPtr();
181 std::list<ElementaryEdge *>::const_iterator it2=it;
183 for(;it2!=_sub_edges.end();it2++)
185 MergePoints commonNode;
186 ComposedEdge *outVal1=new ComposedEdge;
187 ComposedEdge *outVal2=new ComposedEdge;
188 Edge *e2=(*it2)->getPtr();
189 if(e1->intersectWith(e2,commonNode,*outVal1,*outVal2))
202 void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const
204 std::ofstream file(fileName);
205 const int resolution=1200;
207 box.prepareForAggregation();
209 other.fillBounds(box);
210 dumpInXfigFile(file,resolution,box);
211 other.ComposedEdge::dumpInXfigFile(file,resolution,box);
214 void QuadraticPolygon::dumpInXfigFile(const char *fileName) const
216 std::ofstream file(fileName);
217 const int resolution=1200;
219 box.prepareForAggregation();
221 dumpInXfigFile(file,resolution,box);
224 void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
226 stream << "#FIG 3.2 Produced by xfig version 3.2.5-alpha5" << std::endl;
227 stream << "Landscape" << std::endl;
228 stream << "Center" << std::endl;
229 stream << "Metric" << std::endl;
230 stream << "Letter" << std::endl;
231 stream << "100.00" << std::endl;
232 stream << "Single" << std::endl;
233 stream << "-2" << std::endl;
234 stream << resolution << " 2" << std::endl;
235 ComposedEdge::dumpInXfigFile(stream,resolution,box);
239 * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method.
241 double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other)
243 double ret=0.,xBaryBB,yBaryBB;
244 double fact=normalize(&other,xBaryBB,yBaryBB);
245 std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
246 for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
248 ret+=fabs((*iter)->getArea());
251 return ret*fact*fact;
255 * This method splits 'this' with 'other' into smaller pieces localizable. 'mapThis' is a map that gives the correspondance
256 * between nodes contained in 'this' and node ids in a global mesh.
257 * In the same way, 'mapOther' gives the correspondance between nodes contained in 'other' and node ids in a
258 * global mesh from wich 'other' is extracted.
259 * This method has 1 out paramater : 'edgesThis', After the call of this method, it contains the nodal connectivity (including type)
260 * of 'this' into globlal "this mesh".
261 * This method has 2 in/out parameters : 'subDivOther' and 'addCoo'.'otherEdgeIds' is useful to put values in
262 * 'edgesThis', 'subDivOther' and 'addCoo'.
263 * Size of 'otherEdgeIds' has to be equal to number of ElementaryEdges in 'other'. No check of that will be done.
264 * The term 'abs' in the name recalls that we normalize the mesh (spatially) so that node coordinates fit into [0;1].
265 * @param offset1 is the number of nodes contained in global mesh from which 'this' is extracted.
266 * @param offset2 is the sum of nodes contained in global mesh from which 'this' is extracted and 'other' is extracted.
267 * @param edgesInOtherColinearWithThis will be appended at the end of the vector with colinear edge ids of other (if any)
268 * @param otherEdgeIds is a vector with the same size than other before calling this method. It gives in the same order
269 * the cell id in global other mesh.
271 void QuadraticPolygon::splitAbs(QuadraticPolygon& other,
272 const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther,
273 int offset1, int offset2 ,
274 const std::vector<int>& otherEdgeIds,
275 std::vector<int>& edgesThis, int cellIdThis,
276 std::vector< std::vector<int> >& edgesInOtherColinearWithThis, std::vector< std::vector<int> >& subDivOther,
277 std::vector<double>& addCoo, std::map<int,int>& mergedNodes)
279 double xBaryBB, yBaryBB;
280 double fact=normalizeExt(&other, xBaryBB, yBaryBB);
282 IteratorOnComposedEdge it1(this),it3(&other);
284 ComposedEdge *c1=new ComposedEdge;
285 ComposedEdge *c2=new ComposedEdge;
287 std::map<INTERP_KERNEL::Node *,int> mapAddCoo;
288 for(it3.first();!it3.finished();it3.next(),i++)//iteration over 'other' _sub_edges
290 QuadraticPolygon otherTmp;
291 ElementaryEdge* curE3=it3.current();
292 otherTmp.pushBack(new ElementaryEdge(curE3->getPtr(),curE3->getDirection())); curE3->getPtr()->incrRef();
293 IteratorOnComposedEdge it2(&otherTmp);
294 for(it2.first();!it2.finished();it2.next())//iteration on subedges of 'other->_sub_edge'
296 ElementaryEdge* curE2=it2.current();
297 if(!curE2->isThereStartPoint())
300 it1=curE2->getIterator();
301 for(;!it1.finished();)//iteration over 'this' _sub_edges
303 ElementaryEdge* curE1=it1.current();
306 std::map<INTERP_KERNEL::Node *,int>::const_iterator thisStart(mapThis.find(curE1->getStartNode())),thisEnd(mapThis.find(curE1->getEndNode())),otherStart(mapOther.find(curE2->getStartNode())),otherEnd(mapOther.find(curE2->getEndNode()));
307 int thisStart2(thisStart==mapThis.end()?-1:(*thisStart).second),thisEnd2(thisEnd==mapThis.end()?-1:(*thisEnd).second),otherStart2(otherStart==mapOther.end()?-1:(*otherStart).second+offset1),otherEnd2(otherEnd==mapOther.end()?-1:(*otherEnd).second+offset1);
309 if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2))
311 if(!curE1->getDirection()) c1->reverse();
312 if(!curE2->getDirection()) c2->reverse();
313 UpdateNeighbours(merge,it1,it2,c1,c2);
314 //Substitution of simple edge by sub-edges.
315 delete curE1; // <-- destroying simple edge coming from pol1
316 delete curE2; // <-- destroying simple edge coming from pol2
317 it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next.
318 it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next.
321 it1.assignMySelfToAllElems(c2);//To avoid that others
329 UpdateNeighbours(merge,it1,it2,curE1,curE2);
332 merge.updateMergedNodes(thisStart2,thisEnd2,otherStart2,otherEnd2,mergedNodes);
335 if(otherTmp.presenceOfOn())
336 edgesInOtherColinearWithThis[otherEdgeIds[i]].push_back(cellIdThis);
337 if(otherTmp._sub_edges.size()>1)
339 for(std::list<ElementaryEdge *>::const_iterator it=otherTmp._sub_edges.begin();it!=otherTmp._sub_edges.end();it++)
340 (*it)->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/subDivOther[otherEdgeIds[i]],addCoo,mapAddCoo);
346 for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++)
347 (*it)->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/edgesThis,addCoo,mapAddCoo);
352 * This method builds 'this' from its descending conn stored in crude mode (MEDCoupling).
353 * Descending conn is in FORTRAN relative mode in order to give the
354 * orientation of edge (see buildDescendingConnectivity2() method).
355 * See appendEdgeFromCrudeDataArray() for params description.
357 void QuadraticPolygon::buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords,
358 const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges)
360 std::size_t nbOfSeg=std::distance(descBg,descEnd);
361 for(std::size_t i=0;i<nbOfSeg;i++)
363 appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges);
367 void QuadraticPolygon::appendEdgeFromCrudeDataArray(std::size_t edgePos, const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad,
368 const int *nodalBg, const double *coords,
369 const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges)
373 bool direct=descBg[edgePos]>0;
374 int edgeId=abs(descBg[edgePos])-1; // back to C indexing mode
375 const std::vector<int>& subEdge=intersectEdges[edgeId];
376 std::size_t nbOfSubEdges=subEdge.size()/2;
377 for(std::size_t j=0;j<nbOfSubEdges;j++)
378 appendSubEdgeFromCrudeDataArray(0,j,direct,edgeId,subEdge,mapp);
382 std::size_t nbOfSeg=std::distance(descBg,descEnd);
383 const double *st=coords+2*(nodalBg[edgePos]);
384 INTERP_KERNEL::Node *st0=new INTERP_KERNEL::Node(st[0],st[1]);
385 const double *endd=coords+2*(nodalBg[(edgePos+1)%nbOfSeg]);
386 INTERP_KERNEL::Node *endd0=new INTERP_KERNEL::Node(endd[0],endd[1]);
387 const double *middle=coords+2*(nodalBg[edgePos+nbOfSeg]);
388 INTERP_KERNEL::Node *middle0=new INTERP_KERNEL::Node(middle[0],middle[1]);
390 e1=new EdgeLin(st0,middle0);
391 e2=new EdgeLin(middle0,endd0);
392 SegSegIntersector inters(*e1,*e2);
393 bool colinearity=inters.areColinears();
394 delete e1; delete e2;
396 bool direct=descBg[edgePos]>0;
397 int edgeId=abs(descBg[edgePos])-1;
398 const std::vector<int>& subEdge=intersectEdges[edgeId];
399 std::size_t nbOfSubEdges=subEdge.size()/2;
402 for(std::size_t j=0;j<nbOfSubEdges;j++)
403 appendSubEdgeFromCrudeDataArray(0,j,direct,edgeId,subEdge,mapp);
407 Edge *e=new EdgeArcCircle(st0,middle0,endd0,true);
408 for(std::size_t j=0;j<nbOfSubEdges;j++)
409 appendSubEdgeFromCrudeDataArray(e,j,direct,edgeId,subEdge,mapp);
412 st0->decrRef(); endd0->decrRef(); middle0->decrRef();
416 void QuadraticPolygon::appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector<int>& subEdge, const std::map<int,INTERP_KERNEL::Node *>& mapp)
418 std::size_t nbOfSubEdges=subEdge.size()/2;
420 {//it is not a quadratic subedge
421 Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
422 Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
423 ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end);
427 {//it is a quadratic subedge
428 Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second;
429 Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second;
430 Edge *ee=baseEdge->buildEdgeLyingOnMe(start,end);
431 ElementaryEdge *eee=new ElementaryEdge(ee,true);
437 * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the
438 * orientation of edge.
440 void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges,
441 const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1,
442 const std::vector< std::vector<int> >& colinear1,
443 std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >& alreadyExistingIn2)
445 std::size_t nbOfSeg=std::distance(descBg,descEnd);
446 for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2
448 bool direct=descBg[i]>0;
449 int edgeId=abs(descBg[i])-1;//current edge id of pol2
450 std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >::const_iterator it1=alreadyExistingIn2.find(descBg[i]),it2=alreadyExistingIn2.find(-descBg[i]);
451 if(it1!=alreadyExistingIn2.end() || it2!=alreadyExistingIn2.end())
453 bool sameDir=(it1!=alreadyExistingIn2.end());
454 const std::vector<INTERP_KERNEL::ElementaryEdge *>& edgesAlreadyBuilt=sameDir?(*it1).second:(*it2).second;
457 for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_iterator it3=edgesAlreadyBuilt.begin();it3!=edgesAlreadyBuilt.end();it3++)
459 Edge *ee=(*it3)->getPtr(); ee->incrRef();
460 pushBack(new ElementaryEdge(ee,(*it3)->getDirection()));
465 for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_reverse_iterator it4=edgesAlreadyBuilt.rbegin();it4!=edgesAlreadyBuilt.rend();it4++)
467 Edge *ee=(*it4)->getPtr(); ee->incrRef();
468 pushBack(new ElementaryEdge(ee,!(*it4)->getDirection()));
473 bool directos=colinear1[edgeId].empty();
474 std::vector<std::pair<int,std::pair<bool,int> > > idIns1;
477 {// if the current edge of pol2 has one or more colinear edges part into pol1
478 const std::vector<int>& c=colinear1[edgeId];
479 std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1);
480 for(std::size_t j=0;j<nbOfEdgesIn1;j++)
482 int edgeId1=abs(descBg1[j])-1;
483 if(std::find(c.begin(),c.end(),edgeId1)!=c.end())
485 idIns1.push_back(std::pair<int,std::pair<bool,int> >(edgeId1,std::pair<bool,int>(descBg1[j]>0,offset1)));// it exists an edge into pol1 given by tuple (idIn1,direct1) that is colinear at edge 'edgeId' in pol2
486 //std::pair<edgeId1); direct1=descBg1[j]>0;
488 offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2
490 directos=idIns1.empty();
493 {//no subpart of edge 'edgeId' of pol2 is in pol1 so let's operate the same thing that QuadraticPolygon::buildFromCrudeDataArray method
494 std::size_t oldSz=_sub_edges.size();
495 appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges);
496 std::size_t newSz=_sub_edges.size();
497 std::size_t zeSz=newSz-oldSz;
498 alreadyExistingIn2[descBg[i]].resize(zeSz);
499 std::list<ElementaryEdge *>::const_reverse_iterator it5=_sub_edges.rbegin();
500 for(std::size_t p=0;p<zeSz;p++,it5++)
501 alreadyExistingIn2[descBg[i]][zeSz-p-1]=*it5;
504 {//there is subpart of edge 'edgeId' of pol2 inside pol1
505 const std::vector<int>& subEdge=intersectEdges[edgeId];
506 std::size_t nbOfSubEdges=subEdge.size()/2;
507 for(std::size_t j=0;j<nbOfSubEdges;j++)
509 int idBg=direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1];
510 int idEnd=direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2];
511 bool direction11,found=false;
512 bool direct1;//store if needed the direction in 1
514 std::size_t nbOfSubEdges1;
515 for(std::vector<std::pair<int,std::pair<bool,int> > >::const_iterator it=idIns1.begin();it!=idIns1.end() && !found;it++)
517 int idIn1=(*it).first;//store if needed the cell id in 1
518 direct1=(*it).second.first;
519 offset1=(*it).second.second;
520 const std::vector<int>& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1];
521 nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2;
523 for(std::size_t k=0;k<nbOfSubEdges1 && !found;k++)
524 {//perform a loop on all subedges of pol1 that includes edge 'edgeId' of pol2. For the moment we iterate only on subedges of ['idIn1']... To improve
525 if(subEdge1PossiblyAlreadyIn1[2*k]==idBg && subEdge1PossiblyAlreadyIn1[2*k+1]==idEnd)
526 { direction11=true; found=true; }
527 else if(subEdge1PossiblyAlreadyIn1[2*k]==idEnd && subEdge1PossiblyAlreadyIn1[2*k+1]==idBg)
528 { direction11=false; found=true; }
534 {//the current subedge of edge 'edgeId' of pol2 is not a part of the colinear edge 'idIn1' of pol1 -> build new Edge instance
535 //appendEdgeFromCrudeDataArray(j,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges);
536 Node *start=(*mapp.find(idBg)).second;
537 Node *end=(*mapp.find(idEnd)).second;
538 ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end);
540 alreadyExistingIn2[descBg[i]].push_back(e);
543 {//the current subedge of edge 'edgeId' of pol2 is part of the colinear edge 'idIn1' of pol1 -> reuse Edge instance of pol1
544 ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)];
545 Edge *ee=e->getPtr();
547 ElementaryEdge *e2=new ElementaryEdge(ee,!(direct1^direction11));
549 alreadyExistingIn2[descBg[i]].push_back(e2);
557 * Method expected to be called on pol2. Every params not suffixed by numbered are supposed to refer to pol2 (this).
558 * Method to find edges that are ON.
560 void QuadraticPolygon::updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges,
561 const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1,
562 const std::vector<std::vector<int> >& intersectEdges1, const std::vector< std::vector<int> >& colinear1) const
564 std::size_t nbOfSeg=std::distance(descBg,descEnd);
565 for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2
567 bool direct=descBg[i]>0;
568 int edgeId=abs(descBg[i])-1;//current edge id of pol2
569 const std::vector<int>& c=colinear1[edgeId];
572 const std::vector<int>& subEdge=intersectEdges[edgeId];
573 std::size_t nbOfSubEdges=subEdge.size()/2;
575 std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1);
577 for(std::size_t j=0;j<nbOfEdgesIn1;j++)
579 int edgeId1=abs(descBg1[j])-1;
580 if(std::find(c.begin(),c.end(),edgeId1)!=c.end())
582 for(std::size_t k=0;k<nbOfSubEdges;k++)
584 int idBg=direct?subEdge[2*k]:subEdge[2*nbOfSubEdges-2*k-1];
585 int idEnd=direct?subEdge[2*k+1]:subEdge[2*nbOfSubEdges-2*k-2];
587 bool direct1=descBg1[j]>0;
588 const std::vector<int>& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1];
589 std::size_t nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2;
592 for(std::size_t kk=0;kk<nbOfSubEdges1 && !found;kk++)
594 found=(subEdge1PossiblyAlreadyIn1[2*kk]==idBg && subEdge1PossiblyAlreadyIn1[2*kk+1]==idEnd) || (subEdge1PossiblyAlreadyIn1[2*kk]==idEnd && subEdge1PossiblyAlreadyIn1[2*kk+1]==idBg);
600 ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)];
601 e->getPtr()->declareOn();
605 offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2
610 void QuadraticPolygon::appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, double xBary, double yBary, double fact, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI) const
613 bool presenceOfQuadratic=presenceOfQuadraticEdge();
614 conn.push_back(presenceOfQuadratic?NORM_QPOLYG:NORM_POLYGON);
615 for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++)
618 tmp=(*it)->getStartNode();
619 std::map<INTERP_KERNEL::Node *,int>::const_iterator it1=mapp.find(tmp);
620 conn.push_back((*it1).second);
623 if(presenceOfQuadratic)
626 int off=offset+((int)addCoordsQuadratic.size())/2;
627 for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++,j++,nbOfNodesInPg++)
629 INTERP_KERNEL::Node *node=(*it)->getPtr()->buildRepresentantOfMySelf();
630 node->unApplySimilarity(xBary,yBary,fact);
631 addCoordsQuadratic.push_back((*node)[0]);
632 addCoordsQuadratic.push_back((*node)[1]);
633 conn.push_back(off+j);
637 connI.push_back(connI.back()+nbOfNodesInPg+1);
641 * This method make the hypothesis that \a this and \a other are split at the minimum into edges that are fully IN, OUT or ON.
642 * This method returns newly created polygons in \a conn and \a connI and the corresponding ids ( \a idThis, \a idOther) are stored respectively into \a nbThis and \a nbOther.
643 * @param [in,out] edgesThis, parameter that keep informed the caller about the edges in this not shared by the result of intersection of \a this with \a other
644 * @param [in,out] edgesBoundaryOther, parameter that stores all edges in result of intersection that are not
646 void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, std::set<INTERP_KERNEL::Edge *>& edgesThis, std::set<INTERP_KERNEL::Edge *>& edgesBoundaryOther, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nbThis, std::vector<int>& nbOther)
648 double xBaryBB, yBaryBB;
649 double fact=normalizeExt(&other, xBaryBB, yBaryBB);
650 //Locate \a this relative to \a other (edges of \a this, aka \a pol1 are marked as IN or OUT)
651 other.performLocatingOperationSlow(*this); // without any assumption
652 std::vector<QuadraticPolygon *> res=buildIntersectionPolygons(other,*this);
653 for(std::vector<QuadraticPolygon *>::iterator it=res.begin();it!=res.end();it++)
655 (*it)->appendCrudeData(mapp,xBaryBB,yBaryBB,fact,offset,addCoordsQuadratic,conn,connI);
656 INTERP_KERNEL::IteratorOnComposedEdge it1(*it);
657 for(it1.first();!it1.finished();it1.next())
659 Edge *e=it1.current()->getPtr();
660 if(edgesThis.find(e)!=edgesThis.end())
664 if(edgesBoundaryOther.find(e)!=edgesBoundaryOther.end())
665 edgesBoundaryOther.erase(e);
667 edgesBoundaryOther.insert(e);
670 nbThis.push_back(idThis);
671 nbOther.push_back(idOther);
674 unApplyGlobalSimilarityExt(other,xBaryBB,yBaryBB,fact);
678 * Warning This method is \b NOT const. 'this' and 'other' are modified after call of this method.
679 * 'other' is a QuadraticPolygon of \b non closed edges.
681 double QuadraticPolygon::intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear)
683 double ret = 0., xBaryBB, yBaryBB;
684 double fact = normalize(&other, xBaryBB, yBaryBB);
686 QuadraticPolygon cpyOfThis(*this);
687 QuadraticPolygon cpyOfOther(other);
689 SplitPolygonsEachOther(cpyOfThis, cpyOfOther, nbOfSplits);
690 //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done.
691 performLocatingOperation(cpyOfOther);
693 for(std::list<ElementaryEdge *>::const_iterator it=cpyOfOther._sub_edges.begin();it!=cpyOfOther._sub_edges.end();it++)
695 switch((*it)->getLoc())
699 ret += fabs((*it)->getPtr()->getCurveLength());
705 ret += fabs((*it)->getPtr()->getCurveLength());
717 * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method.
719 double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other, double* barycenter)
721 double ret=0.,bary[2],area,xBaryBB,yBaryBB;
722 barycenter[0] = barycenter[1] = 0.;
723 double fact=normalize(&other,xBaryBB,yBaryBB);
724 std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
725 for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
727 area=fabs((*iter)->getArea());
728 (*iter)->getBarycenter(bary);
731 barycenter[0] += bary[0]*area;
732 barycenter[1] += bary[1]*area;
734 if ( ret > std::numeric_limits<double>::min() )
736 barycenter[0]=barycenter[0]/ret*fact+xBaryBB;
737 barycenter[1]=barycenter[1]/ret*fact+yBaryBB;
740 return ret*fact*fact;
744 * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified.
745 * This is possible because loc attribute in Edge class is mutable.
746 * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them.
748 double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const
751 std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
752 for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
754 ret+=fabs((*iter)->getArea());
761 * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified.
762 * This is possible because loc attribute in Edge class is mutable.
763 * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them.
765 double QuadraticPolygon::intersectWith(const QuadraticPolygon& other, double* barycenter) const
767 double ret=0., bary[2];
768 barycenter[0] = barycenter[1] = 0.;
769 std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
770 for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
772 double area = fabs((*iter)->getArea());
773 (*iter)->getBarycenter(bary);
776 barycenter[0] += bary[0]*area;
777 barycenter[1] += bary[1]*area;
779 if ( ret > std::numeric_limits<double>::min() )
781 barycenter[0] /= ret;
782 barycenter[1] /= ret;
788 * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified.
789 * This is possible because loc attribute in Edge class is mutable.
790 * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them.
792 void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const
794 perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.;
795 QuadraticPolygon cpyOfThis(*this);
796 QuadraticPolygon cpyOfOther(other); int nbOfSplits=0;
797 SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits);
798 performLocatingOperation(cpyOfOther);
799 other.performLocatingOperation(cpyOfThis);
800 cpyOfThis.dispatchPerimeterExcl(perimeterThisPart,perimeterCommonPart);
801 cpyOfOther.dispatchPerimeterExcl(perimeterOtherPart,perimeterCommonPart);
802 perimeterCommonPart/=2.;
806 * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified.
807 * This is possible because loc attribute in Edge class is mutable.
808 * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them.
810 * polThis.size()==this->size() and polOther.size()==other.size().
811 * For each ElementaryEdge of 'this', the corresponding contribution in resulting polygon is in 'polThis'.
812 * For each ElementaryEdge of 'other', the corresponding contribution in resulting polygon is in 'polOther'.
813 * As consequence common part are counted twice (in polThis \b and in polOther).
815 void QuadraticPolygon::intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const
817 polThis.resize(size());
818 polOther.resize(other.size());
819 IteratorOnComposedEdge it1(const_cast<QuadraticPolygon *>(this));
821 for(it1.first();!it1.finished();it1.next(),edgeId++)
823 ElementaryEdge* curE1=it1.current();
824 QuadraticPolygon cpyOfOther(other);
825 QuadraticPolygon tmp;
826 tmp.pushBack(curE1->clone());
828 SplitPolygonsEachOther(tmp,cpyOfOther,tmp2);
829 other.performLocatingOperation(tmp);
830 tmp.dispatchPerimeter(polThis[edgeId]);
833 IteratorOnComposedEdge it2(const_cast<QuadraticPolygon *>(&other));
835 for(it2.first();!it2.finished();it2.next(),edgeId++)
837 ElementaryEdge* curE2=it2.current();
838 QuadraticPolygon cpyOfThis(*this);
839 QuadraticPolygon tmp;
840 tmp.pushBack(curE2->clone());
842 SplitPolygonsEachOther(tmp,cpyOfThis,tmp2);
843 performLocatingOperation(tmp);
844 tmp.dispatchPerimeter(polOther[edgeId]);
850 * numberOfCreatedPointsPerEdge is resized to the number of edges of 'this'.
851 * This method returns in ordered maner the number of newly created points per edge.
852 * This method performs a split process between 'this' and 'other' that gives the result PThis.
853 * Then for each edges of 'this' this method counts how many edges in Pthis have the same id.
855 void QuadraticPolygon::intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const
857 numberOfCreatedPointsPerEdge.resize(size());
858 IteratorOnComposedEdge it1(const_cast<QuadraticPolygon *>(this));
860 for(it1.first();!it1.finished();it1.next(),edgeId++)
862 ElementaryEdge* curE1=it1.current();
863 QuadraticPolygon cpyOfOther(other);
864 QuadraticPolygon tmp;
865 tmp.pushBack(curE1->clone());
867 SplitPolygonsEachOther(tmp,cpyOfOther,tmp2);
868 numberOfCreatedPointsPerEdge[edgeId]=tmp.recursiveSize()-1;
873 * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified.
874 * This is possible because loc attribute in Edge class is mutable.
875 * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them.
877 std::vector<QuadraticPolygon *> QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const
879 QuadraticPolygon cpyOfThis(*this);
880 QuadraticPolygon cpyOfOther(other); int nbOfSplits=0;
881 SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits);
882 //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done.
883 performLocatingOperation(cpyOfOther);
884 return other.buildIntersectionPolygons(cpyOfThis,cpyOfOther);
888 * This method is typically the first step of boolean operations between pol1 and pol2.
889 * This method perform the minimal splitting so that at the end each edges constituting pol1 are fully either IN or OUT or ON.
890 * @param pol1 IN/OUT param that is equal to 'this' when called.
892 void QuadraticPolygon::SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits)
894 IteratorOnComposedEdge it1(&pol1),it2(&pol2);
896 ComposedEdge *c1=new ComposedEdge;
897 ComposedEdge *c2=new ComposedEdge;
898 for(it2.first();!it2.finished();it2.next())
900 ElementaryEdge* curE2=it2.current();
901 if(!curE2->isThereStartPoint())
904 it1=curE2->getIterator();
905 for(;!it1.finished();)
908 ElementaryEdge* curE1=it1.current();
909 merge.clear(); nbOfSplits++;
910 if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2))
912 if(!curE1->getDirection()) c1->reverse();
913 if(!curE2->getDirection()) c2->reverse();
914 UpdateNeighbours(merge,it1,it2,c1,c2);
915 //Substitution of simple edge by sub-edges.
916 delete curE1; // <-- destroying simple edge coming from pol1
917 delete curE2; // <-- destroying simple edge coming from pol2
918 it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next.
919 it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next.
922 it1.assignMySelfToAllElems(c2);//To avoid that others
930 UpdateNeighbours(merge,it1,it2,curE1,curE2);
939 void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol1) const
941 IteratorOnComposedEdge it(&pol1);
942 TypeOfEdgeLocInPolygon loc=FULL_ON_1;
943 for(it.first();!it.finished();it.next())
945 ElementaryEdge *cur=it.current();
946 loc=cur->locateFullyMySelf(*this,loc);//*this=pol2=other
950 void QuadraticPolygon::performLocatingOperationSlow(QuadraticPolygon& pol2) const
952 IteratorOnComposedEdge it(&pol2);
953 for(it.first();!it.finished();it.next())
955 ElementaryEdge *cur=it.current();
956 cur->locateFullyMySelfAbsolute(*this);
961 * Given 2 polygons \a pol1 and \a pol2 (localized) the resulting polygons are returned.
963 * this : pol2 simplified.
964 * @param [in] pol1 pol1 split.
965 * @param [in] pol2 pol2 split.
967 std::vector<QuadraticPolygon *> QuadraticPolygon::buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const
969 std::vector<QuadraticPolygon *> ret;
970 std::list<QuadraticPolygon *> pol2Zip=pol2.zipConsecutiveInSegments();
972 ClosePolygons(pol2Zip,pol1,*this,ret);
974 {//borders of pol2 do not cross pol1,and pol2 borders are outside of pol1. That is to say, either pol2 and pol1
975 //do not overlap or pol1 is fully inside pol2. So in the first case no intersection, in the other case
976 //the intersection is pol1.
977 ElementaryEdge *e1FromPol1=pol1[0];
978 TypeOfEdgeLocInPolygon loc=FULL_ON_1;
979 loc=e1FromPol1->locateFullyMySelf(*this,loc);
981 ret.push_back(new QuadraticPolygon(pol1));
987 * Returns parts of potentially non closed-polygons. Each returned polygons are not mergeable.
988 * this : pol2 split and locallized.
990 std::list<QuadraticPolygon *> QuadraticPolygon::zipConsecutiveInSegments() const
992 std::list<QuadraticPolygon *> ret;
993 IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(this));
994 int nbOfTurns=recursiveSize();
996 if(!it.goToNextInOn(false,i,nbOfTurns))
1002 QuadraticPolygon *tmp1=new QuadraticPolygon;
1003 TypeOfEdgeLocInPolygon loc=it.current()->getLoc();
1004 while(loc!=FULL_OUT_1 && i<nbOfTurns)
1006 ElementaryEdge *tmp3=it.current()->clone();
1007 tmp1->pushBack(tmp3);
1009 loc=it.current()->getLoc();
1016 ret.push_back(tmp1);
1017 it.goToNextInOn(true,i,nbOfTurns);
1023 * @param [in] pol2zip is a list of set of edges (=an opened polygon) coming from split polygon 2.
1024 * @param [in] pol1 is split pol1.
1025 * @param [in] pol2 should be considered as pol2Simplified.
1026 * @param [out] results the resulting \b CLOSED polygons.
1028 void QuadraticPolygon::ClosePolygons(std::list<QuadraticPolygon *>& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2,
1029 std::vector<QuadraticPolygon *>& results)
1031 bool directionKnownInPol1=false;
1032 bool directionInPol1;
1033 for(std::list<QuadraticPolygon *>::iterator iter=pol2Zip.begin();iter!=pol2Zip.end();)
1035 if((*iter)->completed())
1037 results.push_back(*iter);
1038 directionKnownInPol1=false;
1039 iter=pol2Zip.erase(iter);
1042 if(!directionKnownInPol1)
1044 if(!(*iter)->haveIAChanceToBeCompletedBy(pol1,pol2,directionInPol1))
1045 { delete *iter; iter=pol2Zip.erase(iter); continue; }
1047 directionKnownInPol1=true;
1049 std::list<QuadraticPolygon *>::iterator iter2=iter; iter2++;
1050 std::list<QuadraticPolygon *>::iterator iter3=(*iter)->fillAsMuchAsPossibleWith(pol1,iter2,pol2Zip.end(),directionInPol1);
1051 if(iter3!=pol2Zip.end())
1053 (*iter)->pushBack(*iter3);
1055 pol2Zip.erase(iter3);
1061 * 'this' is expected to be set of edges (not closed) of pol2 split.
1063 bool QuadraticPolygon::haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted,const QuadraticPolygon& pol2NotSplitted, bool& direction)
1065 IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1Splitted));
1067 Node *n=getEndNode();
1068 ElementaryEdge *cur=it.current();
1069 for(it.first();!it.finished() && !found;)
1072 found=(cur->getStartNode()==n);
1077 throw Exception("Internal error: polygons incompatible with each others. Should never happen!");
1078 //Ok we found correspondance between this and pol1. Searching for right direction to close polygon.
1079 ElementaryEdge *e=_sub_edges.back();
1080 if(e->getLoc()==FULL_ON_1)
1082 if(e->getPtr()==cur->getPtr())
1087 Node *repr=cur->getPtr()->buildRepresentantOfMySelf();
1088 bool ret=pol2NotSplitted.isInOrOut(repr);
1095 Node *repr=cur->getPtr()->buildRepresentantOfMySelf();
1096 bool ret=pol2NotSplitted.isInOrOut(repr);
1102 direction=cur->locateFullyMySelfAbsolute(pol2NotSplitted)==FULL_IN_1;
1107 * This method fills as much as possible \a this (a sub-part of pol2 split) with edges of \a pol1Splitted.
1109 std::list<QuadraticPolygon *>::iterator QuadraticPolygon::fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted,
1110 std::list<QuadraticPolygon *>::iterator iStart,
1111 std::list<QuadraticPolygon *>::iterator iEnd,
1114 IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1Splitted));
1116 Node *n=getEndNode();
1117 ElementaryEdge *cur;
1118 for(it.first();!it.finished() && !found;)
1121 found=(cur->getStartNode()==n);
1128 int szMax(pol1Splitted.size()+1),ii(0);// here a protection against agressive users of IntersectMeshes of invalid input meshes
1129 std::list<QuadraticPolygon *>::iterator ret;
1133 ElementaryEdge *tmp=cur->clone();
1137 nodeToTest=tmp->getEndNode();
1138 direction?it.nextLoop():it.previousLoop();
1139 ret=CheckInList(nodeToTest,iStart,iEnd);
1144 while(ret==iEnd && ii<szMax);
1145 if(ii==szMax)// here a protection against agressive users of IntersectMeshes of invalid input meshes
1146 throw INTERP_KERNEL::Exception("QuadraticPolygon::fillAsMuchAsPossibleWith : Something is invalid with input polygons !");
1150 std::list<QuadraticPolygon *>::iterator QuadraticPolygon::CheckInList(Node *n, std::list<QuadraticPolygon *>::iterator iStart,
1151 std::list<QuadraticPolygon *>::iterator iEnd)
1153 for(std::list<QuadraticPolygon *>::iterator iter=iStart;iter!=iEnd;iter++)
1154 if((*iter)->isNodeIn(n))
1159 void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::set<Edge *>& notUsedInPol1, const std::set<Edge *>& edgesInPol2OnBoundary, const std::map<INTERP_KERNEL::Node *,int>& mapp, int offset, int idThis,
1160 std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2)
1162 pol1.initLocations();
1163 for(std::set<Edge *>::const_iterator it9=notUsedInPol1.begin();it9!=notUsedInPol1.end();it9++)
1164 { (*it9)->initLocs(); (*it9)->declareOn(); }
1165 for(std::set<Edge *>::const_iterator itA=edgesInPol2OnBoundary.begin();itA!=edgesInPol2OnBoundary.end();itA++)
1166 { (*itA)->initLocs(); (*itA)->declareIn(); }
1168 std::set<Edge *> notUsedInPol1L(notUsedInPol1);
1169 IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1));
1171 std::list<QuadraticPolygon *> pol1Zip;
1172 if(pol1.size()==(int)notUsedInPol1.size() && edgesInPol2OnBoundary.empty())
1174 pol1.appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1);
1177 while(!notUsedInPol1L.empty())
1179 for(int i=0;i<sz && (it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1);i++)
1181 if(it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1)
1182 throw INTERP_KERNEL::Exception("Presence of a target polygon fully included in source polygon ! The partition of this leads to a non simply connex cell (with hole) ! Impossible ! Such resulting cell cannot be stored in MED cell format !");
1183 QuadraticPolygon *tmp1=new QuadraticPolygon;
1186 Edge *ee=it.current()->getPtr();
1187 if(ee->getLoc()==FULL_ON_1)
1189 ee->incrRef(); notUsedInPol1L.erase(ee);
1190 tmp1->pushBack(new ElementaryEdge(ee,it.current()->getDirection()));
1194 while(it.current()->getStartNode()->getLoc()!=IN_1 && !notUsedInPol1L.empty());
1195 pol1Zip.push_back(tmp1);
1198 std::list<QuadraticPolygon *> retPolsUnderContruction;
1199 std::list<Edge *> edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end());
1200 std::map<QuadraticPolygon *, std::list<QuadraticPolygon *> > pol1ZipConsumed;
1201 std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0;
1202 for(std::list<QuadraticPolygon *>::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++)
1203 nbOfTurn+=(*itMNT)->size();
1204 maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn;
1206 while(nbOfTurn<maxNbOfTurn && ((!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty())))
1208 for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();)
1210 if((*it1)->getStartNode()==(*it1)->getEndNode())
1215 Node *curN=(*it1)->getEndNode();
1216 bool smthHappened=false;
1217 for(std::list<Edge *>::iterator it2=edgesInPol2OnBoundaryL.begin();it2!=edgesInPol2OnBoundaryL.end();)
1219 if(curN==(*it2)->getStartNode())
1220 { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,true)); curN=(*it2)->getEndNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); }
1221 else if(curN==(*it2)->getEndNode())
1222 { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,false)); curN=(*it2)->getStartNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); }
1228 for(std::list<QuadraticPolygon *>::iterator it3=pol1Zip.begin();it3!=pol1Zip.end();)
1230 if(curN==(*it3)->getStartNode())
1232 for(std::list<ElementaryEdge *>::const_iterator it4=(*it3)->_sub_edges.begin();it4!=(*it3)->_sub_edges.end();it4++)
1233 { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); (*it1)->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); }
1235 pol1ZipConsumed[*it1].push_back(*it3);
1236 curN=(*it3)->getEndNode();
1237 it3=pol1Zip.erase(it3);
1245 for(std::list<ElementaryEdge *>::const_iterator it5=(*it1)->_sub_edges.begin();it5!=(*it1)->_sub_edges.end();it5++)
1247 Edge *ee=(*it5)->getPtr();
1248 if(edgesInPol2OnBoundary.find(ee)!=edgesInPol2OnBoundary.end())
1249 edgesInPol2OnBoundaryL.push_back(ee);
1251 for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++)
1252 pol1Zip.push_front(*it6);
1253 pol1ZipConsumed.erase(*it1);
1255 it1=retPolsUnderContruction.erase(it1);
1258 if(!pol1Zip.empty())
1260 QuadraticPolygon *tmp=new QuadraticPolygon;
1261 QuadraticPolygon *first=*(pol1Zip.begin());
1262 for(std::list<ElementaryEdge *>::const_iterator it4=first->_sub_edges.begin();it4!=first->_sub_edges.end();it4++)
1263 { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); tmp->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); }
1264 pol1ZipConsumed[tmp].push_back(first);
1265 retPolsUnderContruction.push_back(tmp);
1266 pol1Zip.erase(pol1Zip.begin());
1270 if(nbOfTurn==maxNbOfTurn)
1272 std::ostringstream oss; oss << "Error during reconstruction of residual of cell ! It appears that either source or/and target mesh is/are not conform !";
1273 oss << " Number of turns is = " << nbOfTurn << " !";
1274 throw INTERP_KERNEL::Exception(oss.str().c_str());
1276 for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++)
1278 if((*it1)->getStartNode()==(*it1)->getEndNode())
1280 (*it1)->appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1);
1281 for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++)