0031007: Coding - eliminate warnings issued while compiling with -pedantic flag
[occt.git] / src / BOPTools / BOPTools_AlgoTools_1.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Adaptor3d_CurveOnSurface.hxx>
17 #include <Adaptor3d_HCurve.hxx>
18 #include <Adaptor3d_HCurveOnSurface.hxx>
19 #include <BOPTools_AlgoTools.hxx>
20 #include <BOPTools_Parallel.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_CurveRepresentation.hxx>
23 #include <BRep_GCurve.hxx>
24 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
25 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
26 #include <BRep_PointRepresentation.hxx>
27 #include <BRep_TEdge.hxx>
28 #include <BRep_TFace.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRep_TVertex.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32 #include <BRepAdaptor_Curve.hxx>
33 #include <BRepLib_CheckCurveOnSurface.hxx>
34 #include <BRepTools_WireExplorer.hxx>
35 #include <Extrema_LocateExtPC.hxx>
36 #include <Geom2d_Curve.hxx>
37 #include <Geom2dAdaptor.hxx>
38 #include <Geom2dAdaptor_Curve.hxx>
39 #include <Geom2dAdaptor_HCurve.hxx>
40 #include <Geom2dInt_GInter.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
44 #include <Geom_Surface.hxx>
45 #include <Geom_TrimmedCurve.hxx>
46 #include <GeomAdaptor_Curve.hxx>
47 #include <GeomAdaptor_HCurve.hxx>
48 #include <GeomAdaptor_HSurface.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomProjLib.hxx>
51 #include <GCPnts_AbscissaPoint.hxx>
52 #include <gp_Pnt.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <IntRes2d_Domain.hxx>
55 #include <IntRes2d_IntersectionPoint.hxx>
56 #include <IntRes2d_IntersectionSegment.hxx>
57 #include <IntTools_Context.hxx>
58 #include <IntTools_Curve.hxx>
59 #include <IntTools_Range.hxx>
60 #include <IntTools_Tools.hxx>
61 #include <NCollection_Vector.hxx>
62 #include <ProjLib_ProjectedCurve.hxx>
63 #include <TopExp.hxx>
64 #include <TopExp_Explorer.hxx>
65 #include <TopLoc_Location.hxx>
66 #include <TopoDS.hxx>
67 #include <TopoDS_Edge.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Iterator.hxx>
70 #include <TopoDS_Shape.hxx>
71 #include <TopoDS_Shell.hxx>
72 #include <TopoDS_Solid.hxx>
73 #include <TopoDS_Vertex.hxx>
74 #include <TopoDS_Wire.hxx>
75 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
76 #include <TopTools_IndexedMapOfShape.hxx>
77 #include <TopTools_ListIteratorOfListOfShape.hxx>
78 #include <TopTools_ListOfShape.hxx>
79
80
81 static 
82   void CheckEdge (const TopoDS_Edge& E,
83                   const Standard_Real aMaxTol,
84                   const TopTools_IndexedMapOfShape& aMapToAvoid);
85 static 
86   void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
87                              const TopoDS_Face& S,
88                              const Standard_Real aMaxTol,
89                              const TopTools_IndexedMapOfShape& aMapToAvoid);
90 static 
91   Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
92                             const Adaptor3d_Curve& Other,
93                             const Standard_Real Tol,
94                             const Standard_Boolean SameParameter,
95                             Standard_Real& aNewTolerance);
96
97 static
98   void CorrectVertexTolerance(const TopoDS_Edge& aE,
99                               const TopTools_IndexedMapOfShape& aMapToAvoid);
100
101 static
102   void CorrectWires(const TopoDS_Face& aF,
103                     const TopTools_IndexedMapOfShape& aMapToAvoid);
104
105
106
107 static
108   void UpdateEdges(const TopoDS_Face& aF,
109                    const TopTools_IndexedMapOfShape& aMapToAvoid);
110
111 static
112   void UpdateShape(const TopoDS_Shape& aS,
113                    const Standard_Real aTol,
114                    const TopTools_IndexedMapOfShape& aMapToAvoid);
115
116 //=======================================================================
117 //class    : BOPTools_CPC
118 //purpose  : 
119 //=======================================================================
120 class BOPTools_CPC {
121  public:
122   BOPTools_CPC()
123     : myMaxTol(1.e-7), mypMapToAvoid(0L) {
124   }
125   //
126   ~BOPTools_CPC() {
127   }
128   //
129   void SetEdge(const TopoDS_Edge& aE) {
130     myEdge=aE;
131   }
132   //
133   const TopoDS_Edge& Edge()const {
134     return myEdge;
135   }
136   //
137   void SetMaxTol(const Standard_Real aMaxTol) {
138     myMaxTol=aMaxTol;
139   }
140   //
141   Standard_Real MaxTol()const {
142     return myMaxTol;
143   }
144   //
145   void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
146     mypMapToAvoid = &aMapToAvoid;
147   }
148   //
149   void Perform() {
150     Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
151     CheckEdge(myEdge, myMaxTol, *mypMapToAvoid);
152   }
153   
154  protected:
155   Standard_Real myMaxTol;
156   TopoDS_Edge myEdge;
157   const TopTools_IndexedMapOfShape* mypMapToAvoid;
158 };
159 //
160 //=======================================================================
161 typedef NCollection_Vector<BOPTools_CPC> BOPTools_VectorOfCPC; 
162
163 //=======================================================================
164 //class    : BOPTools_CWT
165 //purpose  : 
166 //=======================================================================
167 class BOPTools_CWT {
168  public:
169   BOPTools_CWT() : mypMapToAvoid(0L) {
170   }
171   //
172   ~BOPTools_CWT() {
173   }
174   //
175   void SetFace(const TopoDS_Face& aF) {
176     myFace=aF;
177   }
178   //
179   void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
180     mypMapToAvoid = &aMapToAvoid;
181   }
182   //
183   void Perform() {
184     Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
185     CorrectWires(myFace, *mypMapToAvoid);
186   }
187   //
188  protected:
189   TopoDS_Face myFace;
190   const TopTools_IndexedMapOfShape* mypMapToAvoid;
191 };
192 //=======================================================================
193 typedef NCollection_Vector<BOPTools_CWT> BOPTools_VectorOfCWT; 
194
195 //=======================================================================
196 //class    : BOPTools_CDT
197 //purpose  : 
198 //=======================================================================
199 class BOPTools_CDT {
200  public:
201   BOPTools_CDT() 
202     : myMaxTol(1.e-7), mypMapToAvoid(0L) {
203   }
204   //
205   ~BOPTools_CDT() {
206   }
207   //
208   void SetEdge(const TopoDS_Edge& aE) {
209     myEdge=aE;
210   }
211   //
212   void SetFace(const TopoDS_Face& aF) {
213     myFace=aF;
214   }
215   //
216   void SetMaxTol(const Standard_Real aMaxTol) {
217     myMaxTol=aMaxTol;
218   }
219   //
220   void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
221     mypMapToAvoid = &aMapToAvoid;
222   }
223   //
224   void Perform() {
225     Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
226     CorrectEdgeTolerance (myEdge, myFace, myMaxTol, *mypMapToAvoid);
227   }
228   //
229  protected:
230   Standard_Real myMaxTol;
231   TopoDS_Edge myEdge;
232   TopoDS_Face myFace;
233   const TopTools_IndexedMapOfShape* mypMapToAvoid;
234 };
235 //=======================================================================
236 typedef NCollection_Vector<BOPTools_CDT> BOPTools_VectorOfCDT; 
237
238 //=======================================================================
239 //class    : BOPTools_CVT
240 //purpose  : 
241 //=======================================================================
242 class BOPTools_CVT {
243  public:
244   BOPTools_CVT() : mypMapToAvoid(0L) {
245   }
246   //
247   ~BOPTools_CVT() {
248   }
249   //
250   void SetEdge(const TopoDS_Edge& aE) {
251     myEdge=aE;
252   }
253   //
254   void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
255     mypMapToAvoid = &aMapToAvoid;
256   }
257   //
258   void Perform() {
259     Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
260     CorrectVertexTolerance(myEdge, *mypMapToAvoid);
261   }
262   //
263  protected:
264   TopoDS_Edge myEdge;
265   const TopTools_IndexedMapOfShape* mypMapToAvoid;
266 };
267 //
268 //=======================================================================
269 typedef NCollection_Vector<BOPTools_CVT> BOPTools_VectorOfCVT; 
270
271 //=======================================================================
272 //class    : BOPTools_CET
273 //purpose  : 
274 //=======================================================================
275 class BOPTools_CET {
276  public:
277   BOPTools_CET() : mypMapToAvoid(0L) {
278   }
279   //
280   ~BOPTools_CET() {
281   }
282   //
283   void SetFace(const TopoDS_Face& aF) {
284     myFace=aF;
285   }
286   //
287   void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
288     mypMapToAvoid = &aMapToAvoid;
289   }
290   //
291   void Perform() {
292     Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
293     UpdateEdges(myFace, *mypMapToAvoid);
294   }
295   //
296  protected:
297   TopoDS_Face myFace;
298   const TopTools_IndexedMapOfShape* mypMapToAvoid;
299 };
300 //=======================================================================
301 typedef NCollection_Vector<BOPTools_CET> BOPTools_VectorOfCET; 
302
303 //=======================================================================
304 // Function : CorrectTolerances
305 // purpose : 
306 //=======================================================================
307 void BOPTools_AlgoTools::CorrectTolerances
308   (const TopoDS_Shape& aShape,
309    const TopTools_IndexedMapOfShape& aMapToAvoid,
310    const Standard_Real aMaxTol,
311    const Standard_Boolean bRunParallel)
312 {
313   BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMapToAvoid, aMaxTol, bRunParallel);
314   BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMapToAvoid, aMaxTol, bRunParallel);
315 }
316 //
317 //=======================================================================
318 // Function : CorrectPointOnCurve
319 // purpose : 
320 //=======================================================================
321 void BOPTools_AlgoTools::CorrectPointOnCurve
322   (const TopoDS_Shape& aS,
323    const TopTools_IndexedMapOfShape& aMapToAvoid,
324    const Standard_Real aMaxTol,
325    const Standard_Boolean bRunParallel)
326 {
327   TopExp_Explorer aExp;
328   BOPTools_VectorOfCPC aVCPC;
329   //
330   aExp.Init(aS, TopAbs_EDGE);
331   for(; aExp.More();  aExp.Next()) {
332     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
333     BOPTools_CPC& aCPC=aVCPC.Appended();
334     aCPC.SetEdge(aE);
335     aCPC.SetMaxTol(aMaxTol);
336     aCPC.SetMapToAvoid(aMapToAvoid);
337   }
338   //
339   //======================================================
340   BOPTools_Parallel::Perform (bRunParallel, aVCPC);
341   //======================================================
342 }
343 //=======================================================================
344 // Function : CorrectCurveOnSurface
345 // purpose : 
346 //=======================================================================
347 void BOPTools_AlgoTools::CorrectCurveOnSurface
348   (const TopoDS_Shape& aS,
349    const TopTools_IndexedMapOfShape& aMapToAvoid,
350    const Standard_Real aMaxTol,
351    const Standard_Boolean bRunParallel)
352 {
353   TopExp_Explorer aExpF, aExpE;
354   BOPTools_VectorOfCWT aVCWT;
355   BOPTools_VectorOfCDT aVCDT;
356   //
357   aExpF.Init(aS, TopAbs_FACE);
358   for (; aExpF.More(); aExpF.Next()) {
359     const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
360     //
361     BOPTools_CWT& aCWT=aVCWT.Appended();
362     aCWT.SetFace(aF);
363     aCWT.SetMapToAvoid(aMapToAvoid);
364     //
365     aExpE.Init(aF, TopAbs_EDGE);
366     for (; aExpE.More(); aExpE.Next()) {
367       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
368       //
369       BOPTools_CDT& aCDT=aVCDT.Appended();
370       aCDT.SetEdge(aE);
371       aCDT.SetFace(aF);
372       aCDT.SetMaxTol(aMaxTol);
373       aCDT.SetMapToAvoid(aMapToAvoid);
374     }
375   }
376   //
377   //======================================================
378   BOPTools_Parallel::Perform (bRunParallel, aVCWT);
379   //======================================================
380   BOPTools_Parallel::Perform (bRunParallel, aVCDT);
381   //======================================================
382 }
383 //=======================================================================
384 // Function : CorrectShapeTolerances
385 // purpose : 
386 //=======================================================================
387 void BOPTools_AlgoTools::CorrectShapeTolerances
388   (const TopoDS_Shape& aShape,
389    const TopTools_IndexedMapOfShape& aMapToAvoid,
390    const Standard_Boolean bRunParallel)
391
392   TopExp_Explorer aExp;
393   BOPTools_VectorOfCVT aVCVT;
394   BOPTools_VectorOfCET aVCET;
395   //
396   aExp.Init(aShape, TopAbs_EDGE);
397   for (; aExp.More(); aExp.Next()) {
398     const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
399     BOPTools_CVT& aCVT=aVCVT.Appended();
400     aCVT.SetEdge(aE);
401     aCVT.SetMapToAvoid(aMapToAvoid);
402   }
403   //
404   //======================================================
405   BOPTools_Parallel::Perform (bRunParallel, aVCVT);
406   //======================================================
407   //
408   aExp.Init(aShape, TopAbs_FACE);
409   for (; aExp.More(); aExp.Next()) {
410     const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
411     BOPTools_CET& aCET=aVCET.Appended();
412     aCET.SetFace(aF);
413     aCET.SetMapToAvoid(aMapToAvoid);
414   }
415   //
416   //======================================================
417   BOPTools_Parallel::Perform (bRunParallel, aVCET);
418   //======================================================
419 }
420 //
421 //=======================================================================
422 // Function : CheckEdge
423 // purpose :  Correct tolerances for Vertices on Edge 
424 //=======================================================================
425 void CheckEdge (const TopoDS_Edge& Ed, 
426                 const Standard_Real aMaxTol,
427                 const TopTools_IndexedMapOfShape& aMapToAvoid)
428 {
429   TopoDS_Edge aE = Ed;
430   aE.Orientation(TopAbs_FORWARD);
431   Standard_Real aTolE = BRep_Tool::Tolerance(aE);
432   //
433   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
434   //
435   const TopLoc_Location& Eloc = aE.Location();
436
437   TopoDS_Iterator aItS(aE);
438   for (; aItS.More(); aItS.Next()) {
439     const TopoDS_Vertex& aV= TopoDS::Vertex(aItS.Value());
440     //
441     Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
442     const gp_Pnt& aPV = TV->Pnt();
443     //
444     Standard_Real aTol=BRep_Tool::Tolerance(aV);
445     aTol=Max(aTol, aTolE);
446     Standard_Real dd=0.1*aTol;
447     aTol*=aTol;
448     //
449     BRep_ListIteratorOfListOfCurveRepresentation aItCR(TE->Curves());
450     while (aItCR.More()) {
451       const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
452       //
453       if (aCR->IsCurve3D()) {
454         const Handle(Geom_Curve)& aC = aCR->Curve3D();
455         if (!aC.IsNull()) {
456           TopLoc_Location L = (Eloc * aCR->Location()).Predivided(aV.Location());
457           BRep_ListIteratorOfListOfPointRepresentation aItPR(TV->Points());
458           while (aItPR.More()) {
459             const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
460             if (aPR->IsPointOnCurve(aC, L)) {
461               gp_Pnt aPC = aC->Value(aPR->Parameter());
462               aPC.Transform(L.Transformation());
463               Standard_Real aD2=aPV.SquareDistance(aPC);
464               if (aD2 > aTol) {
465                 Standard_Real aNewTolerance=sqrt(aD2)+dd;
466                 if (aNewTolerance<aMaxTol)
467                   UpdateShape(aV, aNewTolerance, aMapToAvoid);
468               }
469             }
470             aItPR.Next();
471           }
472           //
473           TopAbs_Orientation aOrV=aV.Orientation();
474           if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
475             Handle(BRep_GCurve) aGC (Handle(BRep_GCurve)::DownCast (aCR));
476             gp_Pnt aPC;
477             if (aOrV==TopAbs_FORWARD) {
478               aPC=aC->Value(aGC->First());
479             }
480             else {
481               aPC=aC->Value(aGC->Last());
482             }
483             aPC.Transform(L.Transformation());
484             //
485             Standard_Real aD2=aPV.SquareDistance(aPC);
486             if (aD2 > aTol) {
487               Standard_Real aNewTolerance=sqrt(aD2)+dd;
488               if (aNewTolerance<aMaxTol) 
489                 UpdateShape(aV, aNewTolerance, aMapToAvoid);
490             }
491           }
492         }
493       }
494       aItCR.Next();
495     }//  while (itcr.More()) {  
496   } // for (; aVExp.More(); aVExp.Next()) {
497 }
498
499 //=======================================================================
500 // Function : MapEdgeLength
501 // purpose  : Compute edge length and cache it in the map
502 //=======================================================================
503 static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
504                                    NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
505 {
506   const Standard_Real* pLen = theMapEdgeLen.Seek(theEdge);
507   if (!pLen)
508   {
509     Standard_Real aLen = 0.;
510     if (!BRep_Tool::Degenerated(theEdge))
511     {
512       BRepAdaptor_Curve aCurve(theEdge);
513       aLen = GCPnts_AbscissaPoint::Length(aCurve);
514     }
515     pLen = theMapEdgeLen.Bound(theEdge, aLen);
516   }
517   return *pLen;
518 }
519
520 //=======================================================================
521 // Function : EdgeData
522 // purpose : Structure to store edge data
523 //=======================================================================
524 namespace {
525   struct EdgeData {
526     const TopoDS_Edge* Edge; // Edge
527     Standard_Real VParameter; // Parameter of the vertex on the edge
528     Standard_Boolean IsClosed; // Closed flag of the edge
529     Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
530     Standard_Real First; // First parameter in the range
531     Standard_Real Last; // Last parameter in the rage
532   };
533 }
534 //=======================================================================
535 // Function : IntersectCurves2d
536 // purpose  : Intersect 2d curves of edges
537 //=======================================================================
538 static
539   Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
540                                   const Handle(Geom_Surface)& theS,
541                                   const EdgeData& theEData1,
542                                   const EdgeData& theEData2,
543                                   NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
544 {
545   Geom2dInt_GInter anInter;
546   // Range of the first edge
547   Standard_Real aT11 = theEData1.First;
548   Standard_Real aT12 = theEData1.Last;
549   // Range of the second edge
550   Standard_Real aT21 = theEData2.First;
551   Standard_Real aT22 = theEData2.Last;
552
553   Standard_Real aMaxDist = 0.;
554   Standard_Real aTol2d = 1.e-10;
555   //
556   IntRes2d_Domain aDom1(theEData1.GAdaptor.Value(aT11), aT11, aTol2d,
557                         theEData1.GAdaptor.Value(aT12), aT12, aTol2d);
558   IntRes2d_Domain aDom2(theEData2.GAdaptor.Value(aT21), aT21, aTol2d,
559                         theEData2.GAdaptor.Value(aT22), aT22, aTol2d);
560   //
561   anInter.Perform(theEData1.GAdaptor, aDom1, theEData2.GAdaptor, aDom2, aTol2d, aTol2d);
562   if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
563     return aMaxDist;
564   }
565   //
566   Standard_Real aT1, aT2, aTint1, aTint2, aHalfR1, aHalfR2, aDist;
567   Standard_Integer i, aNb;
568   gp_Pnt aP, aPV;
569   gp_Pnt2d aP2d;
570   NCollection_List<IntRes2d_IntersectionPoint> aLP;
571   NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
572   //
573   aPV = BRep_Tool::Pnt(theV);
574   aT1 = theEData1.VParameter;
575   aT2 = theEData2.VParameter;
576   //
577   aHalfR1 = (aT12 - aT11) / 2.;
578   aHalfR2 = (aT22 - aT21) / 2.;
579   //
580   aDist = 0.;
581   //
582   aNb = anInter.NbSegments();
583   for (i = 1; i <= aNb; ++i) {
584     const IntRes2d_IntersectionSegment& aSeg = anInter.Segment(i);
585     aLP.Append(aSeg.FirstPoint());
586     aLP.Append(aSeg.LastPoint());
587   }
588   //
589   aNb = anInter.NbPoints();
590   for (i = 1; i <= aNb; ++i) {
591     const IntRes2d_IntersectionPoint& aPnt = anInter.Point(i);
592     aLP.Append(aPnt);
593   }
594   //
595   // evaluate the length of the smallest edge, so that not to return too large distance
596   Standard_Real aLen1 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
597   Standard_Real aLen2 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
598   const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
599   Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
600   aMaxThresDist *= aMaxThresDist;
601   aItLP.Initialize(aLP);
602   for (; aItLP.More(); aItLP.Next()) {
603     const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
604     //
605     aTint1 = aPnt.ParamOnFirst();
606     aTint2 = aPnt.ParamOnSecond();
607     //
608     if ((aTint1 < aT11 || aTint1 > aT12) ||
609         (aTint2 < aT21 || aTint2 > aT22)) {
610       // out of range;
611       continue;
612     }
613     //
614     if ((!theEData1.IsClosed && Abs (aTint1 - aT1) > aHalfR1) ||
615         (!theEData2.IsClosed && Abs (aTint2 - aT2) > aHalfR2)) {
616       // intersection is on the other end of the edge
617       continue;
618     }
619     //
620     aP2d = aPnt.Value();
621     theS->D0(aP2d.X(), aP2d.Y(), aP);
622     aDist = aPV.SquareDistance(aP);
623     if (aDist > aMaxDist && aDist < aMaxThresDist) {
624       aMaxDist = aDist;
625     }
626   }
627   //
628   return aMaxDist;
629 }
630 //=======================================================================
631 // Function : CorrectWires
632 // purpose : 
633 //=======================================================================
634 void CorrectWires(const TopoDS_Face& aFx,
635                   const TopTools_IndexedMapOfShape& aMapToAvoid)
636 {
637   Standard_Integer i, aNbV;
638   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2;
639   gp_Pnt aP, aPV;
640   gp_Pnt2d aP2D;
641   TopoDS_Face aF;
642   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
643   TopTools_ListIteratorOfListOfShape aIt;
644   //
645   aF=aFx;
646   aF.Orientation(TopAbs_FORWARD);
647   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
648
649   TopExp::MapShapesAndUniqueAncestors (aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE, Standard_True);
650
651   NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
652   aNbV=aMVE.Extent();
653   for (i=1; i<=aNbV; ++i) {
654     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
655     aPV=BRep_Tool::Pnt(aV);
656     aTol=BRep_Tool::Tolerance(aV);
657     aTol2=aTol*aTol;
658     //
659     aD2max=-1.;
660     // Save edge's data to avoid its recalculation during intersection of 2d curves
661     NCollection_List<EdgeData> aLEPars;
662     const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
663     aIt.Initialize(aLE);
664     for (; aIt.More(); aIt.Next()) {
665       const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
666       const Handle(Geom2d_Curve)& aC2D=
667         BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
668       Standard_Real aT = BRep_Tool::Parameter (aV, aE);
669       Standard_Boolean isClosed = Standard_False;
670       {
671         TopoDS_Vertex aV1, aV2;
672         TopExp::Vertices (aE, aV1, aV2);
673         isClosed = aV1.IsSame (aV2);
674       }
675       //
676       aC2D->D0(aT, aP2D);
677       aS->D0(aP2D.X(), aP2D.Y(), aP);
678       aD2=aPV.SquareDistance(aP);
679       if (aD2>aD2max) {
680         aD2max=aD2;
681       }
682       EdgeData anEData = {&aE, aT, isClosed, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
683       aLEPars.Append(anEData);
684     }
685     //
686     //check wires on self interference by intersecting 2d curves of the edges
687     NCollection_List<EdgeData>::Iterator aItE1(aLEPars);
688     for (; aItE1.More(); aItE1.Next()) {
689       const EdgeData& aEData1 = aItE1.Value();
690       const TopoDS_Shape& aE1 = *aEData1.Edge;
691
692       NCollection_List<EdgeData>::Iterator aItE2 = aItE1;
693       for (aItE2.Next(); aItE2.More(); aItE2.Next()) {
694         const EdgeData& aEData2 = aItE2.Value();
695         const TopoDS_Shape& aE2 = *aEData2.Edge;
696
697         if (aE1.IsSame(aE2))
698           continue;
699
700         aD2 = IntersectCurves2d(aV, aS, aEData1, aEData2, aMapEdgeLen);
701         if (aD2 > aD2max) {
702           aD2max = aD2;
703         }
704       }
705     }
706     //
707     if (aD2max>aTol2) {
708       aTol = 1.01 * sqrt(aD2max);
709       UpdateShape(aV, aTol, aMapToAvoid);
710     }
711   }// for (i=1; i<=aNbV; ++i) {
712 }
713
714 //=======================================================================
715 // Function : CorrectEdgeTolerance
716 // purpose :  Correct tolerances for Edge 
717 //=======================================================================
718 void CorrectEdgeTolerance (const TopoDS_Edge& myShape, 
719                            const TopoDS_Face& S,
720                            const Standard_Real aMaxTol,
721                            const TopTools_IndexedMapOfShape& aMapToAvoid)
722 {
723   // 
724   // 1. Minimum of conditions to Perform
725   Handle (BRep_CurveRepresentation) myCref;
726   Handle (Adaptor3d_HCurve) myHCurve;
727
728   myCref.Nullify();
729
730   Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
731   BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
732   Standard_Boolean Degenerated, SameParameterx, SameRangex;
733
734   Standard_Integer unique = 0;
735
736   Degenerated    = TEx->Degenerated();
737   SameParameterx = TEx->SameParameter();
738   SameRangex     = TEx->SameRange();
739   
740   if (!SameRangex && SameParameterx) {
741     return;
742   }
743
744   Handle(Geom_Curve) C3d;
745   while (itcrx.More()) {
746     const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
747     if (cr->IsCurve3D()) {
748       unique++;
749       if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
750         myCref = cr;
751       }
752     }
753     itcrx.Next();
754   }
755   
756   if (unique==0) {
757     return;//...No3DCurve
758   }
759   if (unique>1) {
760     return;//...Multiple3DCurve;
761   }
762
763   if (myCref.IsNull() && !Degenerated) {
764     itcrx.Initialize(TEx->Curves());
765     while (itcrx.More()) {
766       const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
767       if (cr->IsCurveOnSurface()) {
768         myCref = cr;
769         break;
770       }
771       itcrx.Next();
772     }
773   }
774   
775   else if (!myCref.IsNull() && Degenerated){
776     return ;//...InvalidDegeneratedFlag;
777   }
778   
779   if (!myCref.IsNull()) {
780     Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
781     Standard_Real First,Last;
782     GCref->Range(First,Last);
783     if (Last<=First) {
784       myCref.Nullify();
785       return ;//InvalidRange;
786     }
787     
788     else {
789       if (myCref->IsCurve3D()) {
790         Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
791           (myCref->Curve3D()->Transformed 
792            (myCref->Location().Transformation()));
793         GeomAdaptor_Curve GAC3d(C3dx, First, Last);
794         myHCurve = new GeomAdaptor_HCurve(GAC3d);
795       }
796       else { // curve on surface
797         Handle(Geom_Surface) Sref = myCref->Surface();
798         Sref = Handle(Geom_Surface)::
799           DownCast(Sref->Transformed(myCref->Location().Transformation()));
800         const  Handle(Geom2d_Curve)& PCref = myCref->PCurve();
801         Handle(GeomAdaptor_HSurface) GAHSref = 
802           new GeomAdaptor_HSurface(Sref);
803         Handle(Geom2dAdaptor_HCurve) GHPCref = 
804           new Geom2dAdaptor_HCurve(PCref, First, Last);
805         Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
806         myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
807       }
808     }
809   }
810
811   //=============================================== 
812   // 2. Tolerances in InContext
813   {
814     if (myCref.IsNull()) 
815       return;
816     Standard_Boolean ok = Standard_True;
817
818     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
819     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
820     Standard_Real aNewTol=Tol;
821
822     Standard_Boolean SameParameter = TE->SameParameter();
823     Standard_Boolean SameRange = TE->SameRange();
824     Standard_Real First = myHCurve->FirstParameter();
825     Standard_Real Last  = myHCurve->LastParameter();
826     Standard_Real Delta =1.e-12;
827
828     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
829     const TopLoc_Location& Floc = S.Location();
830     const TopLoc_Location& TFloc = TF->Location();
831     const Handle(Geom_Surface)& Su = TF->Surface();
832     TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
833     Standard_Boolean pcurvefound = Standard_False;
834
835     BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
836     while (itcr.More()) {
837       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
838       if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
839         pcurvefound = Standard_True;
840         Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
841         Standard_Real f,l;
842         GC->Range(f,l);
843         if (SameRange && (f != First || l != Last)) {
844           return ;//BRepCheck_InvalidSameRangeFlag;
845         }
846  
847         Handle(Geom_Surface) Sb = cr->Surface();
848         Sb = Handle(Geom_Surface)::
849           DownCast (Su->Transformed(L.Transformation()));
850         Handle(Geom2d_Curve) PC = cr->PCurve();
851         Handle(GeomAdaptor_HSurface) GAHS = 
852           new GeomAdaptor_HSurface(Sb);
853         Handle(Geom2dAdaptor_HCurve) GHPC = 
854           new Geom2dAdaptor_HCurve(PC,f,l);
855         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
856         ok = Validate(myHCurve->Curve(), ACS, 
857                       Tol, SameParameter, aNewTol);
858         if (ok) {
859           if (aNewTol<aMaxTol) {
860             UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
861             CorrectVertexTolerance(myShape, aMapToAvoid);
862           }
863         }
864         
865         if (cr->IsCurveOnClosedSurface()) {
866           //checkclosed = Standard_True;
867           GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
868           ACS.Load(GHPC, GAHS); // sans doute inutile
869           ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
870           if (ok) {
871             if (aNewTol<aMaxTol) {
872               UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
873               CorrectVertexTolerance(myShape, aMapToAvoid);
874             } 
875           }
876         }
877       }
878       itcr.Next();
879     }
880     
881     if (!pcurvefound) {
882       Handle(Geom_Plane) P;
883       Handle(Standard_Type) styp = Su->DynamicType();
884       if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
885         P = Handle(Geom_Plane)::
886           DownCast(Handle(Geom_RectangularTrimmedSurface)::
887                    DownCast(Su)->BasisSurface());
888       }
889       else {
890         P = Handle(Geom_Plane)::DownCast(Su);
891       }
892       if (P.IsNull()) { // not a plane
893         return;
894       }
895       
896       else {// on fait la projection a la volee, comme BRep_Tool
897         P = Handle(Geom_Plane)::
898           DownCast(P->Transformed(L.Transformation()));
899         //on projette Cref sur ce plan
900         Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
901         
902         // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
903         GeomAdaptor_Curve& Gac = 
904           Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
905         Handle(Geom_Curve) C3dx = Gac.Curve();
906         Handle(Geom_Curve) ProjOnPlane = 
907           GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last), 
908                                        P, 
909                                        P->Position().Direction(), 
910                                        Standard_True);
911         
912         Handle(GeomAdaptor_HCurve) aHCurve = 
913           new GeomAdaptor_HCurve(ProjOnPlane);
914         
915         ProjLib_ProjectedCurve proj(GAHS,aHCurve);
916         Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
917         Handle(Geom2dAdaptor_HCurve) GHPC = 
918           new Geom2dAdaptor_HCurve(PC, 
919                                    myHCurve->FirstParameter(), 
920                                    myHCurve->LastParameter());
921         
922         Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
923         
924         Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
925                                         Tol,Standard_True, aNewTol); 
926         if (okx) {
927           if (aNewTol<aMaxTol) {
928             UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
929             CorrectVertexTolerance(myShape, aMapToAvoid);
930           }
931         }
932       }
933     }//end of if (!pcurvefound) {
934   } // end of  2. Tolerances in InContext
935 }
936 //=======================================================================
937 //function : CorrectVertexTolerance
938 //purpose  : 
939 //=======================================================================
940 void CorrectVertexTolerance(const TopoDS_Edge& aE,
941                             const TopTools_IndexedMapOfShape& aMapToAvoid)
942 {
943   Standard_Real aTolE, aTolV;
944   TopoDS_Iterator aIt;
945   //
946   aTolE=BRep_Tool::Tolerance(aE);
947   aIt.Initialize(aE);
948   for(; aIt.More(); aIt.Next()) {
949     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
950     aTolV=BRep_Tool::Tolerance(aV);
951     if (aTolV<aTolE) {
952       UpdateShape(aV, aTolE, aMapToAvoid);
953     }
954   }
955 }
956 //=======================================================================
957 //function : Validate
958 //purpose  : 
959 //=======================================================================
960 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
961                           const Adaptor3d_Curve& Other,
962                           const Standard_Real Tol,
963                           const Standard_Boolean SameParameter,
964                           Standard_Real& aNewTolerance)
965 {
966   Standard_Real First, Last, MaxDistance, aD, Tol2;
967
968   First = CRef.FirstParameter();
969   Last  = CRef.LastParameter();
970   MaxDistance = 0.;
971   Tol2 = Tol*Tol;
972   //
973   Standard_Integer NCONTROL=23;
974   Standard_Integer i, aNC1=NCONTROL-1;
975
976   Standard_Boolean aFlag=Standard_False;
977   Standard_Boolean proj = (!SameParameter || 
978                            First != Other.FirstParameter() ||
979                            Last  != Other.LastParameter());
980   //
981   // 1. 
982   if (!proj) {
983     for (i = 0; i < NCONTROL; i++) {
984       Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
985       gp_Pnt pref   = CRef.Value(prm);
986       gp_Pnt pother = Other.Value(prm);
987       
988       aD=pref.SquareDistance(pother);
989
990       if (aD > Tol2) {
991         if (aD>MaxDistance) {
992           MaxDistance=aD;
993         }
994         aFlag=Standard_True;
995       }
996     }
997
998     if (aFlag) {
999       aNewTolerance=sqrt(MaxDistance);
1000     }
1001     return aFlag;
1002   }
1003   
1004   //
1005   // 2.
1006   else {
1007     Extrema_LocateExtPC refd,otherd;
1008     Standard_Real OFirst, OLast;
1009     OFirst = Other.FirstParameter();
1010     OLast  = Other.LastParameter();
1011     
1012     gp_Pnt pd  = CRef.Value(First);
1013     gp_Pnt pdo = Other.Value(OFirst);
1014     
1015     aD = pd.SquareDistance(pdo);
1016     if (aD > Tol2) {
1017       if (aD>MaxDistance) {
1018         MaxDistance=aD;
1019       }
1020       aFlag=Standard_True;
1021     }
1022
1023     pd  = CRef.Value(Last);
1024     pdo = Other.Value(OLast);
1025     aD = pd.SquareDistance(pdo);
1026     if (aD > Tol2 && aD > MaxDistance) {
1027       MaxDistance=aD;
1028       aFlag=Standard_True;
1029     }
1030
1031     refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
1032     otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
1033     
1034     for (i = 2; i< aNC1; i++) {
1035       Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
1036       gp_Pnt pref = CRef.Value(rprm);
1037
1038       Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
1039       gp_Pnt pother = Other.Value(oprm);
1040
1041       refd.Perform(pother,rprm);
1042       if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
1043         if (refd.IsDone()) {
1044           aD=refd.SquareDistance();
1045           if (aD > Tol2 && aD>MaxDistance) {
1046             aFlag=Standard_True;
1047             MaxDistance=aD;
1048           }
1049         }
1050       }
1051
1052       otherd.Perform(pref,oprm);
1053       if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1054         
1055         if (otherd.IsDone()) {
1056           aD=otherd.SquareDistance();
1057           if (aD > Tol2 && aD>MaxDistance) {
1058             aFlag=Standard_True;
1059             MaxDistance=aD;
1060           }
1061         }
1062       }
1063     }
1064   }
1065   
1066   aD=sqrt (MaxDistance);
1067   aNewTolerance=aD;
1068   return aFlag;
1069 }
1070 //=======================================================================
1071 // Function : UpdateEdges
1072 // purpose : 
1073 //=======================================================================
1074 void UpdateEdges(const TopoDS_Face& aF,
1075                  const TopTools_IndexedMapOfShape& aMapToAvoid)
1076 {
1077   Standard_Real aTolF, aTolE, aTolV;
1078   TopoDS_Iterator aItF, aItW, aItE;
1079   //
1080   aTolE=aTolF= BRep_Tool::Tolerance(aF);
1081   aItF.Initialize(aF);
1082   for (; aItF.More(); aItF.Next()) {
1083     const TopoDS_Shape& aS = aItF.Value();
1084     if (aS.ShapeType()==TopAbs_WIRE) {
1085       aItW.Initialize(aS);
1086       for (; aItW.More(); aItW.Next()) {
1087         const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1088         aTolE = BRep_Tool::Tolerance(aE);
1089         if (aTolE < aTolF) {
1090           UpdateShape(aE, aTolF, aMapToAvoid);
1091           aTolE = aTolF;
1092         }
1093       }
1094     }
1095     else {
1096       const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1097       aTolV = BRep_Tool::Tolerance(aV);
1098       if (aTolV < aTolE) {
1099         UpdateShape(aV, aTolF, aMapToAvoid);
1100       }
1101     }
1102   }
1103 }
1104 //=======================================================================
1105 //function : UpdateShape
1106 //purpose  : 
1107 //=======================================================================
1108 void UpdateShape(const TopoDS_Shape& aS,
1109                  const Standard_Real aTol,
1110                  const TopTools_IndexedMapOfShape& aMapToAvoid)
1111 {
1112   if (aMapToAvoid.Contains(aS)) {
1113     return;
1114   }
1115   //
1116   TopAbs_ShapeEnum aType;
1117   BRep_Builder aBB;
1118   //
1119   aType=aS.ShapeType();
1120   if (aType==TopAbs_EDGE) {
1121     const TopoDS_Edge& aE = *((TopoDS_Edge*)&aS);
1122     aBB.UpdateEdge(aE, aTol);
1123   }
1124   else if (aType==TopAbs_VERTEX) {
1125    const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&aS);
1126    aBB.UpdateVertex(aV, aTol); 
1127   }
1128 }
1129 //=======================================================================
1130 // Function : ComputeTolerance
1131 // purpose : 
1132 //=======================================================================
1133 Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1134   (const TopoDS_Face& theFace,
1135    const TopoDS_Edge& theEdge,
1136    Standard_Real& theMaxDist,
1137    Standard_Real& theMaxPar)
1138 {
1139   BRepLib_CheckCurveOnSurface aCS;
1140   //
1141   aCS.Init(theEdge, theFace);
1142   aCS.Perform();
1143   if (!aCS.IsDone()) {
1144     return Standard_False;
1145   }
1146   //
1147   theMaxDist = aCS.MaxDistance();
1148   theMaxPar  = aCS.MaxParameter();
1149     //
1150   return Standard_True;
1151 }