0023024: Update headers of OCCT files
[occt.git] / src / BOPTools / BOPTools_Tools.cxx
1 // Created on: 2000-11-16
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21
22 #include <BOPTools_Tools.ixx>
23
24 #include <Precision.hxx>
25
26 #include <TopExp_Explorer.hxx>
27 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
28
29 #include <TopoDS.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Iterator.hxx>
34
35 #include <gp_Pnt.hxx>
36 #include <gp_XYZ.hxx>
37 #include <gp_Pnt2d.hxx>
38
39 #include <BRep_Builder.hxx>
40 #include <BRepBuilderAPI_MakeEdge.hxx>
41 #include <BRep_Tool.hxx>
42
43 #include <BRepAdaptor_Curve.hxx>
44 #include <BRepAdaptor_Surface.hxx>
45
46 #include <GeomAdaptor_Curve.hxx>
47 #include <Geom_Curve.hxx>
48 #include <Geom_Surface.hxx>
49 #include <GeomAPI_ProjectPointOnSurf.hxx>
50 #include <GeomAbs_CurveType.hxx>
51
52 #include <BooleanOperations_OnceExplorer.hxx>
53
54 #include <IntTools_ShrunkRange.hxx>
55 #include <IntTools_Tools.hxx>
56 #include <IntTools_Range.hxx>
57
58
59 static  
60   void CopySrc(const TopoDS_Shape& E, 
61                TopTools_IndexedDataMapOfShapeShape& aMapSS, 
62                TopoDS_Shape& anEdge);
63
64 //=======================================================================
65 // function: IsBlockInOnFace
66 // purpose: 
67 //=======================================================================
68   Standard_Boolean BOPTools_Tools::IsBlockInOnFace (const BOPTools_PaveBlock& aPB1,
69                                                     const TopoDS_Face& aF,
70                                                     const Handle(IntTools_Context)& aContext)
71 {
72   Standard_Boolean bFlag;
73   Standard_Real f1, l1, ULD, VLD;
74   gp_Pnt2d aP2D;
75   gp_Pnt aP11, aP12;
76   //
77   // Edge's data 
78   const IntTools_ShrunkRange& aSR1=aPB1.ShrunkRange();
79   const TopoDS_Edge& aE1=aSR1.Edge();
80  
81   const IntTools_Range& aShrR= aSR1.ShrunkRange();
82   aShrR.Range(f1, l1);
83   //
84   Standard_Real dt=0.0075,  k;//dt=0.001,  k;
85   k=dt*(l1-f1);
86   f1=f1+k;
87   l1=l1-k;
88   //
89   // Treatment P11
90   BOPTools_Tools::PointOnEdge(aE1, f1, aP11);
91   //
92   GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
93   aProjector.Perform(aP11);
94   //
95   bFlag=aProjector.IsDone();
96   if (!bFlag) {
97     return bFlag;
98   }
99   
100   aProjector.LowerDistanceParameters(ULD, VLD);
101   aP2D.SetCoord(ULD, VLD);
102   //
103   bFlag=aContext->IsPointInOnFace (aF, aP2D);
104   //
105   if (!bFlag) {
106     return bFlag;
107   }
108   //
109   // Treatment P12
110   BOPTools_Tools::PointOnEdge(aE1, l1, aP12);
111   //
112   aProjector.Perform(aP12);
113   //
114   bFlag=aProjector.IsDone();
115   if (!bFlag) {
116     return bFlag;
117   }
118   
119   aProjector.LowerDistanceParameters(ULD, VLD);
120   aP2D.SetCoord(ULD, VLD);
121   //
122   bFlag=aContext->IsPointInOnFace (aF, aP2D);
123   //
124   if (!bFlag) {
125     return bFlag;
126   }
127   //
128   // Treatment intemediate
129   Standard_Real m1, aTolF, aTolE, aTol, aDist;
130   m1=IntTools_Tools::IntermediatePoint(f1, l1);
131   BOPTools_Tools::PointOnEdge(aE1, m1, aP12);
132   //
133   aProjector.Perform(aP12);
134   //
135   bFlag=aProjector.IsDone();
136   if (!bFlag) {
137     return bFlag;
138   }
139   //
140   aTolE=BRep_Tool::Tolerance(aE1);
141   aTolF=BRep_Tool::Tolerance(aF);
142   aTol=aTolE+aTolF;
143   aDist=aProjector.LowerDistance();
144   if (aDist > aTol){
145    return Standard_False;
146   }
147
148   aProjector.LowerDistanceParameters(ULD, VLD);
149   aP2D.SetCoord(ULD, VLD);
150   //
151   bFlag=aContext->IsPointInOnFace (aF, aP2D);
152   //
153   if (!bFlag) {
154     return bFlag;
155   }
156   return bFlag;
157 }
158
159 //=======================================================================
160 // function: IsBlocksCoinside
161 // purpose: 
162 //=======================================================================
163   Standard_Boolean BOPTools_Tools::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
164                                                     const BOPTools_PaveBlock& aPB2)
165 {
166   //
167   Standard_Real f1, l1, aTol1;
168   const IntTools_ShrunkRange aSR1=aPB1.ShrunkRange();
169   const TopoDS_Edge& aE1=aSR1.Edge();
170   aTol1=BRep_Tool::Tolerance(aE1);
171   aPB1.Parameters(f1, l1);
172   gp_Pnt aP11, aP12;
173   BOPTools_Tools::PointOnEdge(aE1, f1, aP11);
174   BOPTools_Tools::PointOnEdge(aE1, l1, aP12);
175   //
176   Standard_Real f2, l2, aTol2;
177   const IntTools_ShrunkRange aSR2=aPB2.ShrunkRange();
178   const TopoDS_Edge& aE2=aSR2.Edge();
179   aTol2=BRep_Tool::Tolerance(aE2);
180   aPB2.Parameters(f2, l2);
181   gp_Pnt aP21, aP22;
182   BOPTools_Tools::PointOnEdge(aE2, f2, aP21);
183   BOPTools_Tools::PointOnEdge(aE2, l2, aP22);
184   ////
185   Standard_Real aTolSum, d1121, d1122, d1222, d1221;
186
187   aTolSum=1.05*(aTol1+aTol2);
188   
189   d1121=aP11.Distance(aP21);
190   if (d1121<aTolSum) {
191     d1222=aP12.Distance(aP22);
192     if (d1222<aTolSum) {
193       return Standard_True;
194     }
195   }
196   //
197   d1122=aP11.Distance(aP22);
198   if (d1122<aTolSum) {
199     d1221=aP12.Distance(aP21);
200     if (d1221<aTolSum) {
201       return Standard_True;
202     }
203   }
204   return Standard_False;
205 }
206 //
207 //=======================================================================
208 // function: UpdateVertex
209 // purpose: 
210 //=======================================================================
211   void BOPTools_Tools::UpdateVertex (const TopoDS_Vertex& aVF,
212                                      const TopoDS_Vertex& aNewVertex)
213 {
214   Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
215   //
216   gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
217   gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
218   aTolVF=BRep_Tool::Tolerance(aVF);
219   aTolNewVertex=BRep_Tool::Tolerance(aNewVertex);
220
221   aDist=aPVF.Distance(aPNewVertex);
222   aNewTol=aDist+aTolNewVertex;
223
224   if (aNewTol>aTolVF) {
225     BRep_Builder BB;
226     BB.UpdateVertex (aVF, aNewTol+aDTol);
227   }
228 }
229 //
230 //=======================================================================
231 // function: UpdateVertex
232 // purpose: 
233 //=======================================================================
234   void BOPTools_Tools::UpdateVertex (const TopoDS_Edge& aE,
235                                      const Standard_Real  aT,
236                                      const TopoDS_Vertex& aV)
237 {
238   Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
239   gp_Pnt  aPc; 
240
241   gp_Pnt aPv=BRep_Tool::Pnt(aV);
242   aTolV=BRep_Tool::Tolerance(aV);
243
244   Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast);
245   aC3D->D0(aT, aPc);
246   aDist=aPv.Distance(aPc);
247   if (aDist>aTolV) {
248     BRep_Builder BB;
249     BB.UpdateVertex (aV, aDist+aDTol);
250   }
251 }
252 //
253 //=======================================================================
254 // function: UpdateVertex
255 // purpose: 
256 //=======================================================================
257   void BOPTools_Tools::UpdateVertex (const IntTools_Curve& aC,
258                                      const Standard_Real  aT,
259                                      const TopoDS_Vertex& aV)
260 {
261   Standard_Real aTolV, aDist, aDTol=1.e-12;
262   gp_Pnt  aPc; 
263
264   gp_Pnt aPv=BRep_Tool::Pnt(aV);
265   aTolV=BRep_Tool::Tolerance(aV);
266
267   Handle(Geom_Curve) aC3D=aC.Curve();
268   aC3D->D0(aT, aPc);
269   aDist=aPv.Distance(aPc);
270   if (aDist>aTolV) {
271     BRep_Builder BB;
272     BB.UpdateVertex (aV, aDist+aDTol);
273   }
274 }
275 //=======================================================================
276 // function: MakeSectEdge
277 // purpose: 
278 //=======================================================================
279   void BOPTools_Tools::MakeSectEdge(const IntTools_Curve& aIC,
280                                      const TopoDS_Vertex& aV1,
281                                      const Standard_Real  aP1,
282                                      const TopoDS_Vertex& aV2,
283                                      const Standard_Real  aP2,
284                                      TopoDS_Edge& aNewEdge)
285 {
286   Handle(Geom_Curve) aC=aIC.Curve ();
287   
288   BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
289   
290   const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
291   //
292   // Range must be as it was !
293   BRep_Builder aBB;
294   aBB.Range (aE, aP1, aP2);
295   //
296   aNewEdge=aE;
297   
298 }
299
300 //=======================================================================
301 // function: MakeSplitEdge
302 // purpose: 
303 //=======================================================================
304   void BOPTools_Tools::MakeSplitEdge(const TopoDS_Edge&   aE,
305                                      const TopoDS_Vertex& aV1,
306                                      const Standard_Real  aP1,
307                                      const TopoDS_Vertex& aV2,
308                                      const Standard_Real  aP2,
309                                      TopoDS_Edge& aNewEdge)
310 {
311   Standard_Real f, l, aTol;
312   Handle(Geom_Curve) aC=BRep_Tool::Curve (aE, f, l);
313   aTol=BRep_Tool::Tolerance(aE);
314   //
315   // MakeEdge is used for chechking all input data only 
316   BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
317   //ZZ const TopoDS_Edge& E1=TopoDS::Edge(aMakeEdge.Shape());
318   TopoDS_Edge E=aE;
319   E.EmptyCopy();
320
321   BRep_Builder BB;
322   BB.Add  (E, aV1);
323   BB.Add  (E, aV2);
324   BB.Range(E, aP1, aP2);
325   BB.UpdateEdge(E, aTol);
326   aNewEdge=E;
327 }
328
329 //=======================================================================
330 // function: MakeNewVertex
331 // purpose: 
332 //=======================================================================
333   void BOPTools_Tools::MakeNewVertex(const TopoDS_Vertex& aV1,
334                                      const TopoDS_Vertex& aV2,
335                                      TopoDS_Vertex& aNewVertex)
336 {
337   gp_Pnt aPnt1=BRep_Tool::Pnt(aV1);
338   Standard_Real aTol1=BRep_Tool::Tolerance(aV1);
339         
340   gp_Pnt aPnt2=BRep_Tool::Pnt(aV2);
341   Standard_Real aTol2=BRep_Tool::Tolerance(aV2);
342
343   Standard_Real aMaxTol, aDist;
344         
345   aDist=aPnt1.Distance(aPnt2);
346   aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
347   aMaxTol=aMaxTol+0.5*aDist;
348         
349   const gp_XYZ& aXYZ1=aPnt1.XYZ();
350   const gp_XYZ& aXYZ2=aPnt2.XYZ();
351   gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
352         
353   gp_Pnt aNewPnt(aNewXYZ);
354   BRep_Builder aBB;
355   aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
356 }
357  //=======================================================================
358 // function: MakeNewVertex
359 // purpose: 
360 //=======================================================================
361   void BOPTools_Tools::MakeNewVertex(const gp_Pnt& aP,
362                                      const Standard_Real aTol,
363                                      TopoDS_Vertex& aNewVertex)
364 {
365   BRep_Builder aBB;
366   aBB.MakeVertex (aNewVertex, aP, aTol);
367 }
368
369 //=======================================================================
370 // function: MakeNewVertex
371 // purpose: 
372 //=======================================================================
373   void BOPTools_Tools::MakeNewVertex(const TopoDS_Edge& aE1,
374                                      const Standard_Real aParm1,
375                                      const TopoDS_Edge& aE2,
376                                      const Standard_Real aParm2,
377                                      TopoDS_Vertex& aNewVertex)
378 {
379   Standard_Real aTol1, aTol2, aMaxTol, aDist; 
380   gp_Pnt aPnt1, aPnt2;
381
382   PointOnEdge (aE1, aParm1, aPnt1);
383   PointOnEdge (aE2, aParm2, aPnt2);
384
385   aTol1=BRep_Tool::Tolerance(aE1);
386   aTol2=BRep_Tool::Tolerance(aE2);
387   
388   aDist=aPnt1.Distance(aPnt2);
389   aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
390   aMaxTol=aMaxTol+0.5*aDist;
391
392   const gp_XYZ& aXYZ1=aPnt1.XYZ();
393   const gp_XYZ& aXYZ2=aPnt2.XYZ();
394   gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
395         
396   gp_Pnt aNewPnt(aNewXYZ);
397   BRep_Builder aBB;
398   aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
399 }
400 //=======================================================================
401 // function: MakeNewVertex
402 // purpose: 
403 //=======================================================================
404   void BOPTools_Tools::MakeNewVertex(const TopoDS_Edge& aE1,
405                                      const Standard_Real aParm1,
406                                      const TopoDS_Face& aF1,
407                                      TopoDS_Vertex& aNewVertex)
408 {
409   Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12; 
410   gp_Pnt aPnt;
411
412   PointOnEdge (aE1, aParm1, aPnt);
413
414   aTol1=BRep_Tool::Tolerance(aE1);
415   aTol2=BRep_Tool::Tolerance(aF1);
416   //
417   //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
418   aMaxTol=aTol1+aTol2+delta;
419   //
420   BRep_Builder aBB;
421   aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
422 }
423
424 //=======================================================================
425 // function: PointOnEdge
426 // purpose: 
427 //=======================================================================
428   void BOPTools_Tools::PointOnEdge(const TopoDS_Edge& aE,
429                                    const Standard_Real aParm,
430                                    gp_Pnt& aPnt)
431 {
432   Standard_Real f, l;
433   Handle(Geom_Curve) C1=BRep_Tool::Curve(aE, f, l);
434   C1->D0(aParm, aPnt);
435 }
436
437 //=======================================================================
438 //function : CopySource
439 //purpose  : 
440 //=======================================================================
441   void BOPTools_Tools::CopySource(const TopoDS_Shape& aSS, 
442                                   TopoDS_Shape& aSD)
443 {
444   TopTools_IndexedDataMapOfShapeShape aMapSS;
445   CopySrc (aSS, aMapSS, aSD);
446 }
447
448 //=======================================================================
449 //function : MapShapes
450 //purpose  : 
451 //=======================================================================
452   void BOPTools_Tools::MapShapes(const TopoDS_Shape& aS,
453                                  TopTools_IndexedMapOfShape& aM)
454 {
455   aM.Add(aS);
456   TopoDS_Iterator anIt;
457   anIt.Initialize(aS);
458   for (; anIt.More(); anIt.Next()) {
459     const TopoDS_Shape& aSx=anIt.Value();
460     BOPTools_Tools::MapShapes(aSx, aM);
461   }
462 }
463
464 //=======================================================================
465 //function : CorrectRange
466 //purpose  : 
467 //=======================================================================
468   void BOPTools_Tools::CorrectRange(const TopoDS_Edge& aE1,
469                                     const TopoDS_Edge& aE2,
470                                     const IntTools_Range& aSR,
471                                     IntTools_Range& aNewSR)
472 {
473   Standard_Integer i;
474   Standard_Real aRes, aTolE1, aTolE2, aTF, aTL, dT;
475   BRepAdaptor_Curve aBC;
476   GeomAbs_CurveType aCT;
477   gp_Pnt aP;
478   gp_Vec aDer;
479   //
480   aNewSR=aSR;
481   //
482   //modified by NIZNHY-PKV Tue Feb 10 08:47:03 2009f
483   aBC.Initialize(aE1);
484   aCT=aBC.GetType();
485   if (aCT==GeomAbs_Line) {
486     return;
487   }
488   //modified by NIZNHY-PKV Tue Feb 10 08:47:06 2009t
489   //
490   dT=Precision::PConfusion();
491   aTF=aSR.First();
492   aTL=aSR.Last();
493   //
494   //modified by NIZNHY-PKV Tue Feb 10 08:47:39 2009f
495   /*
496   aBC.Initialize(aE1);
497   aCT=aBC.GetType();
498   */
499   //modified by NIZNHY-PKV Tue Feb 10 08:47:43 2009t
500   //
501   aTolE1=BRep_Tool::Tolerance(aE1);
502   aTolE2=BRep_Tool::Tolerance(aE2);
503   //
504   for(i=0; i<2; ++i) {
505     aRes = 2.*(aTolE1 + aTolE2);
506     //
507     if (aCT==GeomAbs_BezierCurve ||
508         aCT==GeomAbs_BSplineCurve||
509         aCT==GeomAbs_OtherCurve) {
510       
511       if(!i){
512         aBC.D1 (aTF, aP, aDer);
513       }
514       else {
515         aBC.D1 (aTL, aP, aDer);
516       }
517       //
518       Standard_Real aMgn = aDer.Magnitude();
519       
520       if(aMgn  > 1.e-12) {
521         aRes = aRes/aMgn ;
522       }
523       else {
524         aRes = aBC.Resolution(aRes);
525       }
526     } // if (aCT==GeomAbs_BezierCurve||...
527     else {
528       aRes = aBC.Resolution(aRes);
529     }
530     //
531     if(!i) {
532       aNewSR.SetFirst (aTF+aRes);
533     }
534     else {
535       aNewSR.SetLast (aTL-aRes);
536     }
537     //
538     if ((aNewSR.Last()-aNewSR.First()) < dT) {
539       aNewSR=aSR;
540     }
541     //aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
542   }
543 }
544                                     
545 //=======================================================================
546 //function : CorrectRange
547 //purpose  : 
548 //=======================================================================
549   void BOPTools_Tools::CorrectRange(const TopoDS_Edge& aE,
550                                     const TopoDS_Face& aF,
551                                     const IntTools_Range& aSR,
552                                     IntTools_Range& aNewSR)
553 {
554   Standard_Integer i;
555   Standard_Real aRes, aTolF, aTF, aTL, dT;
556   BRepAdaptor_Curve aBC;
557   GeomAbs_CurveType aCT;
558   gp_Pnt aP;
559   gp_Vec aDer;
560   //
561   aNewSR=aSR;
562   //
563   dT=Precision::PConfusion();
564   aTF=aSR.First();
565   aTL=aSR.Last();
566   //
567   aBC.Initialize(aE);
568   aCT=aBC.GetType();
569   //
570   aTolF=BRep_Tool::Tolerance(aF);
571   //
572   for(i=0; i<2; ++i) {
573     aRes =aTolF;
574
575     if (aCT==GeomAbs_BezierCurve ||
576         aCT==GeomAbs_BSplineCurve||
577         aCT==GeomAbs_OtherCurve) {
578       
579       if(!i){
580         aBC.D1 (aTF, aP, aDer);
581       }
582       else {
583         aBC.D1 (aTL, aP, aDer);
584       }
585       //
586       Standard_Real aMgn = aDer.Magnitude();
587       
588       if(aMgn  > 1.e-12) {
589         aRes = aRes/aMgn ;
590       }
591       else {
592         aRes = aBC.Resolution(aRes);
593       }
594     } // if (aCT==GeomAbs_BezierCurve||...
595     else {
596       aRes = aBC.Resolution(aRes);
597     }
598     //
599     if(!i) {
600       aNewSR.SetFirst (aTF+aRes);
601     }
602     else {
603       aNewSR.SetLast (aTL-aRes);
604     }
605     //
606     if ((aNewSR.Last()-aNewSR.First()) < dT) {
607       aNewSR=aSR;
608     }
609   }
610 }
611
612 //=======================================================================
613 //function : CopySrc
614 //purpose  : 
615 //=======================================================================
616 void CopySrc(const TopoDS_Shape& E, 
617              TopTools_IndexedDataMapOfShapeShape& aMapSS, 
618              TopoDS_Shape& anEdge)
619 {
620   BRep_Builder BB;
621   TopAbs_ShapeEnum aTT;
622   Standard_Integer aR;
623   aTT=E.ShapeType();
624
625   if (aMapSS.Contains(E)) {
626     anEdge=aMapSS.ChangeFromKey(E);
627     if (aTT==TopAbs_EDGE)
628       return;
629   }
630   else {
631     anEdge=E.EmptyCopied();
632     aMapSS.Add(E, anEdge);
633   }
634   
635   aR=(Standard_Integer)aTT+1;
636
637   if (aR>TopAbs_VERTEX) {
638     return;
639   }
640
641   Standard_Boolean free = anEdge.Free();
642   anEdge.Free(Standard_True);
643  
644  aTT=(TopAbs_ShapeEnum) aR;
645   TopExp_Explorer anExpVertices(E, aTT);
646   for (; anExpVertices.More();  anExpVertices.Next()) {
647     const TopoDS_Shape& V=anExpVertices.Current();
648     TopoDS_Shape aVertex;
649
650     CopySrc (V, aMapSS, aVertex);  
651
652     aVertex.Orientation(V.Orientation());
653     BB.Add(anEdge, aVertex);
654   }
655
656   anEdge.Free(free);
657 }