Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/geom.git] / src / PARTITION / Partition_Inter2d.cxx
1 //  GEOM PARTITION : partition algorithm
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R& D, LEG, PRINCIPIA R& D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : Partition_Inter2d.cxx
25 //  Author : Benedicte MARTIN
26 //  Module : GEOM
27 //  $Header$
28
29 using namespace std;
30 #include "Partition_Inter2d.ixx"
31
32 #include "utilities.h"
33
34 #include <BRepAdaptor_Curve.hxx>
35 #include <BRepAlgo_AsDes.hxx>
36 #include <BRepLib_MakeVertex.hxx>
37 #include <BRep_Builder.hxx>
38 #include <BRep_Tool.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Precision.hxx>
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopOpeBRepDS_Transition.hxx>
44 #include <TopOpeBRep_EdgesIntersector.hxx>
45 #include <TopOpeBRep_Point2d.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopTools_MapIteratorOfMapOfShape.hxx>
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopoDS.hxx>
51 #include <TopoDS_Edge.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <gp_Pnt.hxx>
54
55 #ifdef DEB
56 static Standard_Boolean TestEdges = 0;
57 static Standard_Integer NbF2d = 0;
58 static Standard_Integer NbE2d = 0;
59 #endif
60
61 //=======================================================================
62 //function : getOtherShape
63 //purpose  :
64 //=======================================================================
65
66 static TopoDS_Shape getOtherShape(const TopoDS_Shape&         theS,
67                                   const TopTools_ListOfShape& theSList)
68 {
69   TopTools_ListIteratorOfListOfShape anIt( theSList );
70   for ( ; anIt.More(); anIt.Next() )
71     if (!theS.IsSame( anIt.Value() ))
72       return anIt.Value();
73
74   return TopoDS_Shape();
75 }
76
77 //=======================================================================
78 //function : findVOnE
79 //purpose  : on theE, find a vertex close to theV, such that an edge
80 //           passing through it is an itersection of theF1 and theF2.
81 //           theE intersects theE2 at theV
82 //=======================================================================
83
84 static Standard_Boolean findVOnE(const TopoDS_Vertex &         theV,
85                                  const TopoDS_Edge&            theE,
86                                  const TopoDS_Edge&            theE2,
87                                  const TopoDS_Shape&           theF1,
88                                  const TopoDS_Shape&           theF2,
89                                  const Handle(BRepAlgo_AsDes)& theAsDes,
90                                  TopoDS_Vertex &               theFoundV)
91 {
92   Standard_Real MinDist2 = ::RealLast();
93   gp_Pnt P;
94
95   // check all vertices on theE
96   const TopTools_ListOfShape& aVList = theAsDes->Descendant( theE );
97   TopTools_ListIteratorOfListOfShape anIt( aVList );
98   if (anIt.More())
99     P = BRep_Tool::Pnt( theV );
100   for ( ; anIt.More(); anIt.Next() )
101   {
102     // check by distance
103     TopoDS_Vertex & V = TopoDS::Vertex( anIt.Value() );
104     Standard_Real dist2 = P.SquareDistance( BRep_Tool::Pnt( V ));
105     if (dist2 < MinDist2)
106       MinDist2 = dist2;
107     else
108       continue;
109
110     // V is a candidate if among edges passing through V there is one
111     // which is an intersection of theF1 and theF2
112     TopTools_ListIteratorOfListOfShape anEIt( theAsDes->Ascendant( V ));
113     Standard_Boolean isOk = Standard_False;
114     for (  ; !isOk && anEIt.More(); anEIt.Next() )
115     {
116       const TopoDS_Shape & E2 = anEIt.Value();
117       if ( theE2.IsSame( E2 ))
118         continue;
119       const TopTools_ListOfShape & aFList = theAsDes->Ascendant( E2 );
120       if (aFList.IsEmpty())
121         continue;
122       if ( theF1.IsSame( aFList.First() ))
123         isOk = theF2.IsSame( aFList.Last() );
124       else
125         isOk = theF2.IsSame( aFList.First() ) && theF1.IsSame( aFList.Last() );
126     }
127     if (isOk)
128       theFoundV = V;
129   }
130
131   if (theFoundV.IsNull())
132     return Standard_False;
133
134   // check that MinDist2 is not too large
135   Standard_Real f, l;
136   TopLoc_Location L;
137   Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theE, L, f, l );
138   gp_Pnt P1 = aCurve->Value( f );
139   gp_Pnt P2 = aCurve->Value( 0.3 * f + 0.7 * l );
140   //gp_Pnt P2 = aCurve->Value( 0.5 * ( f + l ));
141   if (MinDist2 > P1.SquareDistance( P2 ))
142     return Standard_False;
143
144 #ifdef DEB
145   MESSAGE("findVOnE: found MinDist = " << sqrt (MinDist2));
146 #endif
147
148   return Standard_True;
149 }
150
151 //=======================================================================
152 //function : AddVonE
153 //purpose  : Put V in AsDes as intersection of E1 and E2.
154 //           Check that vertex equal to V already exists on one
155 //           of edges, in  such  a  case,  V  is  not added but
156 //           existing vertex is updated to  be on E1 and E2 and
157 //           is returned insead of V.
158 //=======================================================================
159
160 TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV,
161                                          const TopoDS_Edge&   E1,
162                                          const TopoDS_Edge&   E2,
163                                          const Handle(BRepAlgo_AsDes)& AsDes,
164                                          const TopoDS_Face&   theF)
165
166 {
167   //-------------------------------------------------------------
168   // test if the points of intersection already exist. If not,
169   // add as descendants of the edges.
170   // nb: theses points are only vertices of intersection.
171   //-------------------------------------------------------------
172   const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
173   const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
174   gp_Pnt                      P1,P2;
175   TopoDS_Vertex               V1,V2;
176   TopTools_ListIteratorOfListOfShape it;
177   BRep_Builder                       B;
178   TopAbs_Orientation                 O1,O2;
179   Standard_Real                      U1,U2;
180   Standard_Real                      Tol,Tol1,Tol2;
181   Standard_Boolean                   OnE1,OnE2;
182
183   TopoDS_Vertex V    = theV;
184
185   U1 = BRep_Tool::Parameter(V,E1);
186   U2 = BRep_Tool::Parameter(V,E2);
187   O1 = V.Orientation();
188   O2 = O1;
189   P1  = BRep_Tool::Pnt(V);
190   Tol = BRep_Tool::Tolerance( V );
191   OnE1 = OnE2 = Standard_False;
192
193   //-----------------------------------------------------------------
194   // Search if the point of intersection is a vertex of E1.
195   //-----------------------------------------------------------------
196   for (it.Initialize(VOnE1); it.More(); it.Next()) {
197     const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() );
198     if (V.IsSame( CV )) {
199       V1   = V;
200       OnE1 = Standard_True;
201       break;
202     }
203     P2 = BRep_Tool::Pnt( CV );
204     Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV ));
205     if (P1.SquareDistance(P2) <= Tol1*Tol1) {
206       V    = CV;
207       V1   = V;
208       OnE1 = Standard_True;
209       break;
210     }
211   }
212   if (OnE1) {
213     //-----------------------------------------------------------------
214     // Search if the vertex found is still on E2.
215     //-----------------------------------------------------------------
216     for (it.Initialize(VOnE2); it.More(); it.Next()) {
217       if (V.IsSame( it.Value() )) {
218         OnE2 = Standard_True;
219         V2   = V;
220         break;
221       }
222     }
223   }
224   if (!OnE2) {
225     for (it.Initialize(VOnE2); it.More(); it.Next()) {
226       //-----------------------------------------------------------------
227       // Search if the point of intersection is a vertex of E2.
228       //-----------------------------------------------------------------
229       const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() );
230       P2 = BRep_Tool::Pnt( CV );
231       Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV ));
232       if (P1.SquareDistance(P2) <= Tol2*Tol2) {
233         V  = CV;
234         V2 = V;
235         OnE2 = Standard_True;
236         break;
237       }
238     }
239   }
240
241
242   if (!OnE1 && !OnE2 && !theF.IsNull())
243   {
244     // if 3 faces intersects each others, 3 new edges on them must pass
245     // through one vertex but real intersection points of each
246     // pair of edges are sometimes more far than a tolerance.
247     // Try to analitically find vertices that E1 and E2 must pass trough
248
249     TopoDS_Shape F1 = getOtherShape( theF, AsDes->Ascendant( E1 ));
250     TopoDS_Shape F2 = getOtherShape( theF, AsDes->Ascendant( E2 ));
251     if (!F1.IsNull() && !F2.IsNull() && !F1.IsSame( F2 ))
252     {
253       OnE1 = findVOnE ( theV, E1, E2, F1, F2, AsDes, V1 );
254       OnE2 = findVOnE ( theV, E2, E1, F1, F2, AsDes, V2 );
255       if (OnE2) V = V2;
256       if (OnE1) V = V1;
257     }
258   }
259
260   if (OnE1 && OnE2) {
261     if (!V1.IsSame(V2)) {
262       // replace V1 with V2 on all edges V1 is on
263       Standard_Real UV1;
264       TopoDS_Edge   EWE1;
265       TopoDS_Vertex VI;
266       const TopTools_ListOfShape& EdgeWithV1 = AsDes->Ascendant(V1);
267
268       for (it.Initialize(EdgeWithV1); it.More(); it.Next()) {
269         EWE1  = TopoDS::Edge(it.Value());
270         VI = V1;
271         VI.Orientation(TopAbs_INTERNAL);
272         UV1 = BRep_Tool::Parameter(VI,EWE1);
273         VI = V2;
274         VI.Orientation(TopAbs_INTERNAL);
275         B.UpdateVertex( VI, UV1, EWE1, GetTolerance( VI, UV1, EWE1, AsDes));
276       }
277       AsDes->Replace(V1,V2);
278       V = V2;
279     }
280   }
281
282   // add existing vertices instead of new ones
283   if (!OnE1) {
284     if (OnE2) {
285       V.Orientation(TopAbs_INTERNAL);
286       B.UpdateVertex (V, U1, E1, GetTolerance( V, U1, E1, AsDes));
287     }
288     V.Orientation(O1);
289     AsDes->Add(E1,V);
290   }
291   if (!OnE2) {
292     if (OnE1) {
293       V.Orientation(TopAbs_INTERNAL);
294       B.UpdateVertex (V, U2, E2, GetTolerance( V, U2, E2, AsDes ));
295     }
296     V.Orientation(O2);
297     AsDes->Add(E2,V);
298   }
299
300   return V;
301 }
302
303 //=======================================================================
304 //function : FindEndVertex
305 //purpose  : Returns a vertex  from  <VertList> having parameter on
306 //           <E>  closest  to  <f>  or  <l>.  <isFirst>  is True if
307 //           found vertex is closer  to <f>. <DU> returns parameter
308 //           difference.
309 //=======================================================================
310
311 TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV,
312                                                const Standard_Real f,
313                                                const Standard_Real l,
314                                                const TopoDS_Edge&  E,
315                                                Standard_Boolean&   isFirst,
316                                                Standard_Real&      minDU)
317 {
318   TopoDS_Vertex endV;
319   Standard_Real U, endU, min;
320   minDU = 1.e10;
321
322   TopTools_ListIteratorOfListOfShape it;
323   it.Initialize(LV);
324   for (; it.More(); it.Next()) {
325     const TopoDS_Vertex& v = TopoDS::Vertex(it.Value());
326     U = BRep_Tool::Parameter(v, E);
327     min = Min( Abs(U-f), Abs(U-l) );
328     if (min < minDU) {
329       endV = v;
330       endU = U;
331       minDU = min;
332     }
333   }
334   if (Abs(endU-f) < Abs(endU-l))
335     isFirst = Standard_True;
336   else
337     isFirst = Standard_False;
338
339   return endV;
340 }
341
342 //=======================================================================
343 //function : treatClosed
344 //purpose  : add second vertex to closed edge. Vertex is one of <LV1>
345 //=======================================================================
346
347 static void treatClosed (const TopoDS_Edge& E1,
348                           const Standard_Real f,
349                           const Standard_Real l,
350                           TopTools_ListOfShape& LV1,
351                           TopTools_ListOfShape& /*LV2*/)
352 {
353   Standard_Boolean isFirst=0;
354   Standard_Real    minDU = 1.e10;
355   TopoDS_Vertex endV;
356   endV = Partition_Inter2d::FindEndVertex(LV1, f,l, E1, isFirst,minDU);
357
358   if (minDU > Precision::PConfusion())
359     return; // not end point
360
361   Standard_Real newU;
362   if (isFirst)
363     newU = f + (l - f);
364   else
365     newU = l - (l - f);
366
367   // update end parameter
368   BRep_Builder B;
369   endV.Orientation(TopAbs_INTERNAL);
370   B.UpdateVertex(endV,newU,E1,BRep_Tool::Tolerance(endV));
371 }
372
373 //=======================================================================
374 //function : EdgesPartition
375 //purpose  :
376 //=======================================================================
377
378 static void EdgesPartition(const TopoDS_Face&            F,
379                            const TopoDS_Edge&            E1,
380                            const TopoDS_Edge&            E2,
381                            const Handle(BRepAlgo_AsDes)& AsDes,
382                            const TopTools_MapOfShape&    NewEdges,
383                            const Standard_Boolean        WithOri)
384 {
385
386   Standard_Real f[3],l[3];
387   Standard_Real MilTol2;
388   Standard_Real Tol = Max (BRep_Tool::Tolerance(E1),
389                            BRep_Tool::Tolerance(E2));
390   MilTol2 = Tol * Tol * 10;
391
392   BRep_Tool::Range(E1, f[1], l[1]);
393   BRep_Tool::Range(E2, f[2], l[2]);
394
395   BRepAdaptor_Curve CE1(E1,F);
396   BRepAdaptor_Curve CE2(E2,F);
397
398   TopoDS_Edge                 EI[3]; EI[1] = E1; EI[2] = E2;
399   TopTools_ListOfShape        LV1; // new vertices at intersections on E1
400   TopTools_ListOfShape        LV2; // ... on E2
401   BRep_Builder                B;
402
403   // if E1 and E2 are results of intersection of F and two connex faces then
404   // no need to intersect edges, they can contact by vertices only
405   // (encounted an exception in TopOpeBRep_EdgesIntersector in such a case)
406   Standard_Boolean intersect = Standard_True;
407   TopTools_IndexedMapOfShape ME;
408   TopExp::MapShapes(F, TopAbs_EDGE, ME);
409   if (!ME.Contains(E1) && ! ME.Contains(E2)) { // if E1 and E2 are new on F
410     TopoDS_Shape F1, F2;
411     const TopTools_ListOfShape& LF1 = AsDes->Ascendant( E1 );
412     F1 = F.IsSame( LF1.First() ) ? LF1.Last() : LF1.First();
413     const TopTools_ListOfShape& LF2 = AsDes->Ascendant( E2 );
414     F2 = F.IsSame( LF2.First() ) ? LF2.Last() : LF2.First();
415     if (!F.IsSame(F2) && !F.IsSame(F1) ) {
416       TopExp_Explorer exp(F2, TopAbs_EDGE);
417       TopExp::MapShapes(F1, TopAbs_EDGE, ME);
418       for (; exp.More(); exp.Next()) {
419         if (ME.Contains( exp.Current())) {
420           intersect = Standard_False;
421           break;
422         }
423       }
424     }
425   }
426
427   if (intersect) {
428     //------------------------------------------------------
429     // compute the points of Intersection in 2D
430     //-----------------------------------------------------
431     // i.e. fill LV1 and LV2
432     TopOpeBRep_EdgesIntersector EInter;
433     EInter.SetFaces(F,F);
434     Standard_Real TolDub = 1.e-7;
435     EInter.ForceTolerances(TolDub,TolDub);
436     Standard_Boolean reducesegments = Standard_False;
437     EInter.Perform (E1,E2,reducesegments);
438
439     Standard_Boolean rejectreducedsegmentpoints = Standard_False;
440     EInter.InitPoint(rejectreducedsegmentpoints);
441     for ( ; EInter.MorePoint(); EInter.NextPoint() )
442     {
443       const TopOpeBRep_Point2d& P2D = EInter.Point();
444       const gp_Pnt&    P    = P2D.Value();
445       TopoDS_Vertex    V    = BRepLib_MakeVertex(P);
446
447       //-------------------------
448       // control the point found.
449       //-------------------------
450       gp_Pnt P1 = CE1.Value(P2D.Parameter(1));
451       gp_Pnt P2 = CE2.Value(P2D.Parameter(2));
452       Standard_Real sqd1 = P1.SquareDistance(P);
453       Standard_Real sqd2 = P2.SquareDistance(P);
454       if (sqd1 > MilTol2 || sqd2 > MilTol2  )
455         continue;
456
457       // add a new vertex to the both edges
458       Standard_Real toler = Max( Tol, sqrt( Max( sqd1, sqd2 )));
459       Standard_Integer i;
460       for (i = 1; i <= 2; i++) {
461         Standard_Real U = P2D.Parameter(i);
462         V.Orientation(TopAbs_INTERNAL);
463         B.UpdateVertex( V,U,EI[i], toler);
464         TopAbs_Orientation OO = TopAbs_REVERSED;
465         if (WithOri) {
466           if (P2D.IsVertex(i))
467             OO = P2D.Vertex(i).Orientation();
468           else if (P2D.Transition(i).Before() == TopAbs_OUT) {
469             OO = TopAbs_FORWARD;
470           }
471           V.Orientation(OO);
472           if (i == 1) LV1.Append(V);
473           else        LV2.Append(V);
474         }
475       }
476     }
477   } // if (intersect)
478
479   //----------------------------------
480   // Test the extremities of the edges.
481   //----------------------------------
482   // add to LV* vertices for vertex-vertex closeness
483   Standard_Real U1,U2;
484   Standard_Real TolConf2, TolConf;
485   TopoDS_Vertex V1[2],V2[2];
486   TopExp::Vertices(E1,V1[0],V1[1]);
487   TopExp::Vertices(E2,V2[0],V2[1]);
488
489   Standard_Integer i,j,k;
490   for (j = 0; j < 2; j++) {
491     if (V1[j].IsNull()) continue;
492     for ( k = 0; k < 2; k++) {
493       if (V2[k].IsNull()) continue;
494       gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
495       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
496       TolConf = BRep_Tool::Tolerance(V1[j]) + BRep_Tool::Tolerance(V2[k]);
497       TolConf = Max (Tol, TolConf);
498       TolConf2 = TolConf * TolConf;
499       if (!intersect)
500         TolConf2 *= 100;
501       Standard_Real SqDist = P1.SquareDistance(P2);
502
503       if (SqDist <= TolConf2) {
504         TopoDS_Vertex V = BRepLib_MakeVertex(P1);
505         V.Orientation(TopAbs_INTERNAL);
506         U1 = (j == 0) ? f[1] : l[1];
507         U2 = (k == 0) ? f[2] : l[2];
508         B.UpdateVertex(V,U1,E1,TolConf);
509         B.UpdateVertex(V,U2,E2,TolConf);
510         LV1.Prepend(V.Oriented(V1[j].Orientation()));
511         LV2.Prepend(V.Oriented(V2[k].Orientation()));
512       }
513     }
514   }
515
516   Standard_Boolean AffichPurge = Standard_False;
517
518   if ( LV1.IsEmpty()) return;
519
520   //----------------------------------
521   // Purge of all the vertices.
522   //----------------------------------
523   // remove one of close vertices
524   TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
525   gp_Pnt P1,P2;
526   Standard_Boolean Purge = Standard_True;
527
528   while (Purge) {
529     i = 1;
530     Purge = Standard_False;
531     for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
532          it1LV1.More();
533          it1LV1.Next(),it1LV2.Next()) {
534       j = 1;
535       it2LV1.Initialize(LV1);
536       while (j < i) {
537         const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value());
538         const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value());
539         Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 );
540         Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 );
541         P1 = BRep_Tool::Pnt( VE1 );
542         P2 = BRep_Tool::Pnt( VE2 );
543         if (P1.IsEqual(P2, Tol1 + Tol2)) {
544           LV1.Remove(it1LV1);
545           LV2.Remove(it1LV2);
546           Purge = Standard_True;
547           break;
548         }
549         j++;
550         it2LV1.Next();
551       }
552       if (Purge) break;
553       i++;
554     }
555   }
556
557   // care of new closed edges, they always intersect with seam at end
558   if (V1[0].IsSame( V1[1] ) && NewEdges.Contains(E1) )
559     treatClosed (E1, f[1], l[1], LV1, LV2);
560   if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) )
561     treatClosed (E2, f[2], l[2], LV2, LV1);
562
563   //----------------
564   // Stocking vertex
565   //----------------
566
567   for ( it1LV1.Initialize( LV1 ); it1LV1.More(); it1LV1.Next())
568     Partition_Inter2d::AddVonE (TopoDS::Vertex( it1LV1.Value()),
569                                 E1, E2, AsDes, F);
570 }
571
572 //=======================================================================
573 //function : CompletPart2d
574 //purpose  : Computes the intersections between the edges stored
575 //           is AsDes as descendants of <F> . Intersections is computed
576 //           between two edges if one of them is bound in NewEdges.
577 //=======================================================================
578
579 void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)&   AsDes,
580                                        const TopoDS_Face&              F,
581                                        const TopTools_MapOfShape&      NewEdges)
582 {
583
584 #ifdef DEB
585   NbF2d++;
586   NbE2d = 0;
587 #endif
588
589   //Do not intersect the edges of a face
590   TopTools_IndexedMapOfShape EdgesOfFace;
591   TopExp::MapShapes( F, TopAbs_EDGE , EdgesOfFace);
592
593   //-------------------------------------------------------------------
594   // compute the intersection2D on the faces touched by the intersection3D
595   //-------------------------------------------------------------------
596   TopTools_ListIteratorOfListOfShape it1LE ;
597   TopTools_ListIteratorOfListOfShape it2LE ;
598
599   //-----------------------------------------------
600   // Intersection edge-edge.
601   //-----------------------------------------------
602   const TopTools_ListOfShape&        LE = AsDes->Descendant(F);
603   TopoDS_Vertex                      V1,V2;
604   Standard_Integer                   j, i = 1;
605
606   TopoDS_Face FF = F;
607   FF.Orientation(TopAbs_FORWARD);
608
609   for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
610     const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
611     j = 1;
612     it2LE.Initialize(LE);
613
614     while (j < i && it2LE.More()) {
615       const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
616       //----------------------------------------------------------
617       // Intersections of the new edges obtained by intersection
618       // between them and with the restrictions edges
619       //----------------------------------------------------------
620       if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
621            (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
622         EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True);
623       }
624       it2LE.Next();
625       j++;
626     }
627     i++;
628   }
629 }
630
631 //=======================================================================
632 //function : GetTolerance
633 //purpose  : Returns  tolerance  theV   must   have  atfer  its
634 //           addition to theE with  theU parameter. theAsDes is
635 //           used to find pcurves of theE
636 //=======================================================================
637
638 Standard_Real Partition_Inter2d::GetTolerance
639                          (const TopoDS_Vertex &         theV,
640                           const Standard_Real           theU,
641                           const TopoDS_Edge &           theE,
642                           const Handle(BRepAlgo_AsDes)& theAsDes)
643 {
644   Standard_Real aTol = BRep_Tool::Tolerance( theV );
645   gp_Pnt aPnt = BRep_Tool::Pnt( theV );
646
647   // check point on 3D curve
648   Standard_Real f,l;
649   Handle(Geom_Curve) C = BRep_Tool::Curve( theE, f, l );
650   if (!C.IsNull())
651     aTol = Max ( aTol, aPnt.Distance( C->Value( theU )));
652
653   // check points on pcurves
654   const TopTools_ListOfShape& aFList = theAsDes->Ascendant( theE );
655   TopTools_ListIteratorOfListOfShape aFIt( aFList );
656   for (  ; aFIt.More(); aFIt.Next() )
657   {
658     const TopoDS_Face& F = TopoDS::Face( aFIt.Value() );
659     Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( theE, F, f, l );
660     if (!pcurve.IsNull())
661     {
662       gp_Pnt2d aPnt2d = pcurve->Value( theU );
663       TopLoc_Location L;
664       Handle(Geom_Surface) S = BRep_Tool::Surface( F, L );
665       gp_Pnt aPntOnS = S->Value( aPnt2d.X(), aPnt2d.Y() );
666       if (!L.IsIdentity())
667         aPntOnS.Transform( L.Transformation() );
668       aTol = Max ( aTol, aPnt.Distance( aPntOnS ));
669     }
670   }
671
672   return aTol;
673 }