0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BOPTools / BOPTools_AlgoTools_2.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 <BOPTools_AlgoTools.hxx>
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepBuilderAPI_MakeEdge.hxx>
21 #include <Geom_Curve.hxx>
22 #include <GeomAbs_CurveType.hxx>
23 #include <gp_Pnt.hxx>
24 #include <IntTools_Context.hxx>
25 #include <IntTools_Curve.hxx>
26 #include <IntTools_Range.hxx>
27 #include <Precision.hxx>
28 #include <TopoDS.hxx>
29 #include <TopoDS_Edge.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Shell.hxx>
34 #include <TopoDS_Solid.hxx>
35 #include <TopoDS_Vertex.hxx>
36
37 static
38   void TreatCompound(const TopoDS_Shape& theC1, 
39                      BOPCol_ListOfShape& theLSX);
40
41 //=======================================================================
42 // function: UpdateVertex
43 // purpose: 
44 //=======================================================================
45 void BOPTools_AlgoTools::UpdateVertex
46   (const TopoDS_Vertex& aVF,
47    const TopoDS_Vertex& aNewVertex)
48 {
49   Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
50   //
51   gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
52   gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
53   aTolVF=BRep_Tool::Tolerance(aVF);
54   aTolNewVertex=BRep_Tool::Tolerance(aNewVertex);
55
56   aDist=aPVF.Distance(aPNewVertex);
57   aNewTol=aDist+aTolNewVertex;
58
59   if (aNewTol>aTolVF) {
60     BRep_Builder BB;
61     BB.UpdateVertex (aVF, aNewTol+aDTol);
62   }
63 }
64
65 //=======================================================================
66 // function: UpdateVertex
67 // purpose: 
68 //=======================================================================
69 void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
70                                        const Standard_Real  aT,
71                                        const TopoDS_Vertex& aV)
72 {
73   Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
74   gp_Pnt  aPc; 
75
76   gp_Pnt aPv=BRep_Tool::Pnt(aV);
77   aTolV=BRep_Tool::Tolerance(aV);
78
79   GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
80   aCA.D0(aT, aPc);
81   aDist=aPv.Distance(aPc);
82   if (aDist>aTolV) {
83     BRep_Builder BB;
84     BB.UpdateVertex (aV, aDist+aDTol);
85   }
86 }
87 //
88 //=======================================================================
89 // function: UpdateVertex
90 // purpose: 
91 //=======================================================================
92 void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
93                                        const Standard_Real  aT,
94                                        const TopoDS_Vertex& aV)
95 {
96   Standard_Real aTolV, aDist, aDTol=1.e-12;
97   gp_Pnt  aPc; 
98
99   gp_Pnt aPv=BRep_Tool::Pnt(aV);
100   aTolV=BRep_Tool::Tolerance(aV);
101
102   GeomAdaptor_Curve aCA( aC.Curve() );
103   aCA.D0(aT, aPc);
104   aDist=aPv.Distance(aPc);
105   if (aDist>aTolV) {
106     BRep_Builder BB;
107     BB.UpdateVertex (aV, aDist+aDTol);
108   }
109 }
110 //=======================================================================
111 // function: MakeSectEdge
112 // purpose: 
113 //=======================================================================
114 void BOPTools_AlgoTools::MakeSectEdge(const IntTools_Curve& aIC,
115                                       const TopoDS_Vertex& aV1,
116                                       const Standard_Real  aP1,
117                                       const TopoDS_Vertex& aV2,
118                                       const Standard_Real  aP2,
119                                       TopoDS_Edge& aNewEdge)
120 {
121   Handle(Geom_Curve) aC=aIC.Curve ();
122   
123   BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
124   
125   const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
126   //
127   // Range must be as it was !
128   BRep_Builder aBB;
129   aBB.Range (aE, aP1, aP2);
130   //
131   aNewEdge=aE;
132   
133 }
134
135 //=======================================================================
136 // function: MakeSplitEdge
137 // purpose: 
138 //=======================================================================
139 void BOPTools_AlgoTools::MakeSplitEdge(const TopoDS_Edge&   aE,
140                                        const TopoDS_Vertex& aV1,
141                                        const Standard_Real  aP1,
142                                        const TopoDS_Vertex& aV2,
143                                        const Standard_Real  aP2,
144                                        TopoDS_Edge& aNewEdge)
145 {
146   Standard_Real aTol;//f, l, 
147   aTol=BRep_Tool::Tolerance(aE);
148   //
149   TopoDS_Edge E=aE;
150   E.EmptyCopy();
151   //
152   BRep_Builder BB;
153   BB.Add  (E, aV1);
154   BB.Add  (E, aV2);
155   BB.Range(E, aP1, aP2);
156   BB.UpdateEdge(E, aTol);
157   aNewEdge=E;
158 }
159
160 //=======================================================================
161 // function: MakeNewVertex
162 // purpose: 
163 //=======================================================================
164 void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Vertex& aV1,
165                                        const TopoDS_Vertex& aV2,
166                                        TopoDS_Vertex& aNewVertex)
167 {
168   gp_Pnt aPnt1=BRep_Tool::Pnt(aV1);
169   Standard_Real aTol1=BRep_Tool::Tolerance(aV1);
170         
171   gp_Pnt aPnt2=BRep_Tool::Pnt(aV2);
172   Standard_Real aTol2=BRep_Tool::Tolerance(aV2);
173
174   Standard_Real aMaxTol, aDist;
175         
176   aDist=aPnt1.Distance(aPnt2);
177   aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
178   aMaxTol=aMaxTol+0.5*aDist;
179         
180   const gp_XYZ& aXYZ1=aPnt1.XYZ();
181   const gp_XYZ& aXYZ2=aPnt2.XYZ();
182   gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
183         
184   gp_Pnt aNewPnt(aNewXYZ);
185   BRep_Builder aBB;
186   aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
187 }
188  //=======================================================================
189 // function: MakeNewVertex
190 // purpose: 
191 //=======================================================================
192 void BOPTools_AlgoTools::MakeNewVertex(const gp_Pnt& aP,
193                                        const Standard_Real aTol,
194                                        TopoDS_Vertex& aNewVertex)
195 {
196   BRep_Builder aBB;
197   aBB.MakeVertex (aNewVertex, aP, aTol);
198 }
199
200 //=======================================================================
201 // function: MakeNewVertex
202 // purpose: 
203 //=======================================================================
204 void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
205                                        const Standard_Real aParm1,
206                                        const TopoDS_Edge& aE2,
207                                        const Standard_Real aParm2,
208                                        TopoDS_Vertex& aNewVertex)
209 {
210   Standard_Real aTol1, aTol2, aMaxTol, aDist; 
211   gp_Pnt aPnt1, aPnt2;
212
213   PointOnEdge (aE1, aParm1, aPnt1);
214   PointOnEdge (aE2, aParm2, aPnt2);
215
216   aTol1=BRep_Tool::Tolerance(aE1);
217   aTol2=BRep_Tool::Tolerance(aE2);
218   
219   aDist=aPnt1.Distance(aPnt2);
220   aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
221   aMaxTol=aMaxTol+0.5*aDist;
222
223   const gp_XYZ& aXYZ1=aPnt1.XYZ();
224   const gp_XYZ& aXYZ2=aPnt2.XYZ();
225   gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
226         
227   gp_Pnt aNewPnt(aNewXYZ);
228   BRep_Builder aBB;
229   aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
230 }
231 //=======================================================================
232 // function: MakeNewVertex
233 // purpose: 
234 //=======================================================================
235 void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
236                                        const Standard_Real aParm1,
237                                        const TopoDS_Face& aF1,
238                                        TopoDS_Vertex& aNewVertex)
239 {
240   Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12; 
241   gp_Pnt aPnt;
242
243   PointOnEdge (aE1, aParm1, aPnt);
244
245   aTol1=BRep_Tool::Tolerance(aE1);
246   aTol2=BRep_Tool::Tolerance(aF1);
247   //
248   //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
249   aMaxTol=aTol1+aTol2+delta;
250   //
251   BRep_Builder aBB;
252   aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
253 }
254
255 //=======================================================================
256 // function: PointOnEdge
257 // purpose: 
258 //=======================================================================
259 void BOPTools_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
260                                      const Standard_Real aParm,
261                                      gp_Pnt& aPnt)
262 {
263   Standard_Real f, l;
264   Handle(Geom_Curve) C1=BRep_Tool::Curve(aE, f, l);
265   C1->D0(aParm, aPnt);
266 }
267
268 //=======================================================================
269 //function : CorrectRange
270 //purpose  : 
271 //=======================================================================
272 void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE1,
273                                       const TopoDS_Edge& aE2,
274                                       const IntTools_Range& aSR,
275                                       IntTools_Range& aNewSR)
276 {
277   Standard_Integer i;
278   Standard_Real aRes, aTolE1, aTolE2, aTF, aTL, dT;
279   BRepAdaptor_Curve aBC;
280   GeomAbs_CurveType aCT;
281   gp_Pnt aP;
282   gp_Vec aDer;
283   //
284   aNewSR=aSR;
285   //
286   aBC.Initialize(aE1);
287   aCT=aBC.GetType();
288   if (aCT==GeomAbs_Line) {
289     return;
290   }
291   //
292   dT=Precision::PConfusion();
293   aTF=aSR.First();
294   aTL=aSR.Last();
295   //
296   aTolE1=BRep_Tool::Tolerance(aE1);
297   aTolE2=BRep_Tool::Tolerance(aE2);
298   //
299   for(i=0; i<2; ++i) {
300     aRes = 2.*(aTolE1 + aTolE2);
301     //
302     if (aCT==GeomAbs_BezierCurve ||
303         aCT==GeomAbs_BSplineCurve||
304         aCT==GeomAbs_OtherCurve) {
305       
306       if(!i){
307         aBC.D1 (aTF, aP, aDer);
308       }
309       else {
310         aBC.D1 (aTL, aP, aDer);
311       }
312       //
313       Standard_Real aMgn = aDer.Magnitude();
314       
315       if(aMgn  > 1.e-12) {
316         aRes = aRes/aMgn ;
317       }
318       else {
319         aRes = aBC.Resolution(aRes);
320       }
321     } // if (aCT==GeomAbs_BezierCurve||...
322     else {
323       aRes = aBC.Resolution(aRes);
324     }
325     //
326     if(!i) {
327       aNewSR.SetFirst (aTF+aRes);
328     }
329     else {
330       aNewSR.SetLast (aTL-aRes);
331     }
332     //
333     if ((aNewSR.Last()-aNewSR.First()) < dT) {
334       aNewSR=aSR;
335     }
336     //aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
337   }
338 }
339                                     
340 //=======================================================================
341 //function : CorrectRange
342 //purpose  : 
343 //=======================================================================
344 void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
345                                       const TopoDS_Face& aF,
346                                       const IntTools_Range& aSR,
347                                       IntTools_Range& aNewSR)
348 {
349   Standard_Integer i;
350   Standard_Real aRes, aTolF, aTF, aTL, dT;
351   BRepAdaptor_Curve aBC;
352   GeomAbs_CurveType aCT;
353   gp_Pnt aP;
354   gp_Vec aDer;
355   //
356   aNewSR=aSR;
357   //
358   dT=Precision::PConfusion();
359   aTF=aSR.First();
360   aTL=aSR.Last();
361   //
362   aBC.Initialize(aE);
363   aCT=aBC.GetType();
364   //
365   aTolF=BRep_Tool::Tolerance(aF);
366   //
367   for(i=0; i<2; ++i) {
368     aRes =aTolF;
369
370     if (aCT==GeomAbs_BezierCurve ||
371         aCT==GeomAbs_BSplineCurve||
372         aCT==GeomAbs_OtherCurve) {
373       
374       if(!i){
375         aBC.D1 (aTF, aP, aDer);
376       }
377       else {
378         aBC.D1 (aTL, aP, aDer);
379       }
380       //
381       Standard_Real aMgn = aDer.Magnitude();
382       
383       if(aMgn  > 1.e-12) {
384         aRes = aRes/aMgn ;
385       }
386       else {
387         aRes = aBC.Resolution(aRes);
388       }
389     } // if (aCT==GeomAbs_BezierCurve||...
390     else {
391       aRes = aBC.Resolution(aRes);
392     }
393     //
394     if(!i) {
395       aNewSR.SetFirst (aTF+aRes);
396     }
397     else {
398       aNewSR.SetLast (aTL-aRes);
399     }
400     //
401     if ((aNewSR.Last()-aNewSR.First()) < dT) {
402       aNewSR=aSR;
403     }
404   }
405 }
406 //=======================================================================
407 //function : Dimension
408 //purpose  : 
409 //=======================================================================
410 Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
411 {
412   Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
413   TopAbs_ShapeEnum aTS;
414   BOPCol_ListOfShape aLS;
415   BOPCol_ListIteratorOfListOfShape aIt;
416   //
417   aTS=theS.ShapeType();
418   if (aTS!=TopAbs_COMPOUND) {
419     switch (aTS) {
420       case TopAbs_EDGE:
421       case TopAbs_WIRE:
422         iRet=1;
423         break;
424       case TopAbs_FACE:
425       case TopAbs_SHELL:
426         iRet=2;
427         break;
428       case TopAbs_SOLID:
429       case TopAbs_COMPSOLID:
430         iRet=3;
431         break;
432       default:
433         iRet=0;
434     }
435     return iRet;
436   }
437   //
438   iRet=-1;
439   TreatCompound(theS, aLS);
440   if(aLS.IsEmpty()) {
441     iRet = -2; //empty compound
442     return iRet;
443   }
444   aIt.Initialize(aLS);
445   for (i=0; aIt.More(); aIt.Next()) {
446     const TopoDS_Shape& aSx=aIt.Value(); 
447     iRx=Dimension(aSx);
448     if (!i) {
449       iRx0=iRx;
450       i=1;
451       continue;
452     }
453     if (iRx!=iRx0) {
454       return iRet;// -1
455     }
456   }
457   return iRx;
458 }
459
460 //=======================================================================
461 //function : TreatCompound
462 //purpose  : 
463 //=======================================================================
464 void TreatCompound(const TopoDS_Shape& theC1, 
465                    BOPCol_ListOfShape& theLSX)
466 {
467   Standard_Integer aNbC1;
468   TopAbs_ShapeEnum aType;
469   BOPCol_ListOfShape aLC, aLC1;
470   BOPCol_ListIteratorOfListOfShape aIt, aIt1;
471   TopoDS_Iterator aItC;
472   //
473   aLC.Append (theC1);
474   for(;;) {
475     aLC1.Clear();
476     aIt.Initialize(aLC);
477     for (; aIt.More(); aIt.Next()) {
478       const TopoDS_Shape& aC=aIt.Value(); //C is compound
479       //
480       aItC.Initialize(aC);
481       for (; aItC.More(); aItC.Next()) {
482         const TopoDS_Shape& aS=aItC.Value();
483         aType=aS.ShapeType();
484         if (aType==TopAbs_COMPOUND) {
485           aLC1.Append(aS);
486         }
487         else {
488           theLSX.Append(aS);
489         }
490       }
491     }
492     //
493     aNbC1=aLC1.Extent();
494     if (!aNbC1) {
495       break;
496     }
497     //
498     aLC.Clear();
499     aIt.Initialize(aLC1);
500     for (; aIt.More(); aIt.Next()) {
501       const TopoDS_Shape& aSC=aIt.Value();
502       aLC.Append(aSC);
503     }
504   }// while(1)
505 }