0026254: Inject GeomAbs_OffsetCurve into GeomAbs_CurveType enumeration
[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_OffsetCurve ||
305         aCT==GeomAbs_OtherCurve) {
306       
307       if(!i){
308         aBC.D1 (aTF, aP, aDer);
309       }
310       else {
311         aBC.D1 (aTL, aP, aDer);
312       }
313       //
314       Standard_Real aMgn = aDer.Magnitude();
315       
316       if(aMgn  > 1.e-12) {
317         aRes = aRes/aMgn ;
318       }
319       else {
320         aRes = aBC.Resolution(aRes);
321       }
322     } // if (aCT==GeomAbs_BezierCurve||...
323     else {
324       aRes = aBC.Resolution(aRes);
325     }
326     //
327     if(!i) {
328       aNewSR.SetFirst (aTF+aRes);
329     }
330     else {
331       aNewSR.SetLast (aTL-aRes);
332     }
333     //
334     if ((aNewSR.Last()-aNewSR.First()) < dT) {
335       aNewSR=aSR;
336     }
337     //aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
338   }
339 }
340                                     
341 //=======================================================================
342 //function : CorrectRange
343 //purpose  : 
344 //=======================================================================
345 void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
346                                       const TopoDS_Face& aF,
347                                       const IntTools_Range& aSR,
348                                       IntTools_Range& aNewSR)
349 {
350   Standard_Integer i;
351   Standard_Real aRes, aTolF, aTF, aTL, dT;
352   BRepAdaptor_Curve aBC;
353   GeomAbs_CurveType aCT;
354   gp_Pnt aP;
355   gp_Vec aDer;
356   //
357   aNewSR=aSR;
358   //
359   dT=Precision::PConfusion();
360   aTF=aSR.First();
361   aTL=aSR.Last();
362   //
363   aBC.Initialize(aE);
364   aCT=aBC.GetType();
365   //
366   aTolF=BRep_Tool::Tolerance(aF);
367   //
368   for(i=0; i<2; ++i) {
369     aRes =aTolF;
370
371     if (aCT==GeomAbs_BezierCurve ||
372         aCT==GeomAbs_BSplineCurve||
373         aCT==GeomAbs_OffsetCurve ||
374         aCT==GeomAbs_OtherCurve) {
375       
376       if(!i){
377         aBC.D1 (aTF, aP, aDer);
378       }
379       else {
380         aBC.D1 (aTL, aP, aDer);
381       }
382       //
383       Standard_Real aMgn = aDer.Magnitude();
384       
385       if(aMgn  > 1.e-12) {
386         aRes = aRes/aMgn ;
387       }
388       else {
389         aRes = aBC.Resolution(aRes);
390       }
391     } // if (aCT==GeomAbs_BezierCurve||...
392     else {
393       aRes = aBC.Resolution(aRes);
394     }
395     //
396     if(!i) {
397       aNewSR.SetFirst (aTF+aRes);
398     }
399     else {
400       aNewSR.SetLast (aTL-aRes);
401     }
402     //
403     if ((aNewSR.Last()-aNewSR.First()) < dT) {
404       aNewSR=aSR;
405     }
406   }
407 }
408 //=======================================================================
409 //function : Dimension
410 //purpose  : 
411 //=======================================================================
412 Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
413 {
414   Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
415   TopAbs_ShapeEnum aTS;
416   BOPCol_ListOfShape aLS;
417   BOPCol_ListIteratorOfListOfShape aIt;
418   //
419   aTS=theS.ShapeType();
420   if (aTS!=TopAbs_COMPOUND) {
421     switch (aTS) {
422       case TopAbs_EDGE:
423       case TopAbs_WIRE:
424         iRet=1;
425         break;
426       case TopAbs_FACE:
427       case TopAbs_SHELL:
428         iRet=2;
429         break;
430       case TopAbs_SOLID:
431       case TopAbs_COMPSOLID:
432         iRet=3;
433         break;
434       default:
435         iRet=0;
436     }
437     return iRet;
438   }
439   //
440   iRet=-1;
441   TreatCompound(theS, aLS);
442   if(aLS.IsEmpty()) {
443     iRet = -2; //empty compound
444     return iRet;
445   }
446   aIt.Initialize(aLS);
447   for (i=0; aIt.More(); aIt.Next()) {
448     const TopoDS_Shape& aSx=aIt.Value(); 
449     iRx=Dimension(aSx);
450     if (!i) {
451       iRx0=iRx;
452       i=1;
453       continue;
454     }
455     if (iRx!=iRx0) {
456       return iRet;// -1
457     }
458   }
459   return iRx;
460 }
461
462 //=======================================================================
463 //function : TreatCompound
464 //purpose  : 
465 //=======================================================================
466 void TreatCompound(const TopoDS_Shape& theC1, 
467                    BOPCol_ListOfShape& theLSX)
468 {
469   Standard_Integer aNbC1;
470   TopAbs_ShapeEnum aType;
471   BOPCol_ListOfShape aLC, aLC1;
472   BOPCol_ListIteratorOfListOfShape aIt, aIt1;
473   TopoDS_Iterator aItC;
474   //
475   aLC.Append (theC1);
476   for(;;) {
477     aLC1.Clear();
478     aIt.Initialize(aLC);
479     for (; aIt.More(); aIt.Next()) {
480       const TopoDS_Shape& aC=aIt.Value(); //C is compound
481       //
482       aItC.Initialize(aC);
483       for (; aItC.More(); aItC.Next()) {
484         const TopoDS_Shape& aS=aItC.Value();
485         aType=aS.ShapeType();
486         if (aType==TopAbs_COMPOUND) {
487           aLC1.Append(aS);
488         }
489         else {
490           theLSX.Append(aS);
491         }
492       }
493     }
494     //
495     aNbC1=aLC1.Extent();
496     if (!aNbC1) {
497       break;
498     }
499     //
500     aLC.Clear();
501     aIt.Initialize(aLC1);
502     for (; aIt.More(); aIt.Next()) {
503       const TopoDS_Shape& aSC=aIt.Value();
504       aLC.Append(aSC);
505     }
506   }// while(1)
507 }