0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPTools / BOPTools_Tools3D_2.cxx
1 // Created on: 2004-06-10
2 // Created by: Peter KURNEV
3 // Copyright (c) 2004-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 #include <BOPTools_Tools3D.ixx>
22
23 #include <math.h>
24 #include <gp_Dir.hxx>
25 #include <gp_Cylinder.hxx>
26 #include <gp_Lin.hxx>
27 #include <gp_Ax1.hxx>
28 #include <gp_Cone.hxx>
29
30 #include <TopAbs_Orientation.hxx>
31 #include <Geom_Surface.hxx>
32 #include <GeomAbs_SurfaceType.hxx>
33 #include <BRep_Tool.hxx>
34 #include <GeomAdaptor_Surface.hxx>
35 #include <IntTools_Tools.hxx>
36 #include <BOPTools_Tools2D.hxx>
37 #include <Geom_Curve.hxx>
38 #include <gp_Vec.hxx>
39
40 static
41   Standard_Boolean AnalyticState(const TopoDS_Face& aF1,
42                                  const TopoDS_Face& aFx,
43                                  const gp_Pnt& aP,
44                                  const gp_Dir& aDNSx,
45                                  const Standard_Real aTolR,
46                                  TopAbs_State& aSt);
47
48 static
49   gp_Pnt ProjectedPoint (const gp_Pnt&,
50                          const gp_Ax1&);
51
52 //=======================================================================
53 //function : TreatedAsAnalytic
54 //purpose  : 
55 //=======================================================================
56   Standard_Boolean BOPTools_Tools3D::TreatedAsAnalytic(const TopoDS_Face& aFx, 
57                                                        const TopoDS_Edge& aSpE1,
58                                                        const TopoDS_Face& aF1,
59                                                        const Standard_Real aTolTangent,
60                                                        const Standard_Real aTolR,
61                                                        TopAbs_State& aSt,
62                                                        const Handle(IntTools_Context)& )
63
64   Standard_Boolean bFlag, bIsAnalytic, bIsDirsCoinside;
65   Standard_Real aT1, aTb, aTe;
66   gp_Dir aDNSx, aDNS1;
67   gp_Pnt aP1;
68   //
69   bFlag=Standard_False;
70   //
71   bIsAnalytic=BOPTools_Tools3D::HasAnalyticSurfaceType(aFx);
72   if (!bIsAnalytic) {
73     return bFlag;
74   }
75   bIsAnalytic=BOPTools_Tools3D::HasAnalyticSurfaceType(aF1);
76   if (!bIsAnalytic) {
77     return bFlag;
78   }
79   //
80   Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpE1, aTb, aTe);
81   aT1=BOPTools_Tools2D::IntermediatePoint (aTb, aTe);
82   aC3D->D0(aT1, aP1);
83   //
84   BOPTools_Tools3D::GetNormalToFaceOnEdge(aSpE1, aF1, aT1, aDNS1);
85   BOPTools_Tools3D::GetNormalToFaceOnEdge(aSpE1, aFx, aT1, aDNSx);
86   //
87   bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNSx, aDNS1, aTolTangent);
88   if (!bIsDirsCoinside) {
89     return bFlag;
90   }
91   //
92   bFlag=AnalyticState(aF1, aFx, aP1, aDNSx, aTolR, aSt);
93   //
94   return bFlag;
95 }
96
97 //=======================================================================
98 //function : TreatedAsAnalytic
99 //purpose  : 
100 //=======================================================================
101   Standard_Boolean BOPTools_Tools3D::TreatedAsAnalytic(const Standard_Real aTx,
102                                                        const gp_Pnt& aPx,
103                                                        const TopoDS_Edge& anEx,
104                                                        const TopoDS_Face& aFx, 
105                                                        const TopoDS_Edge& anE1,
106                                                        const TopoDS_Face& aF1,
107                                                        const Standard_Real aTolTangent,
108                                                        const Standard_Real aTolR,
109                                                        TopAbs_State& aSt,
110                                                        const Handle(IntTools_Context)& aContext)
111
112   Standard_Boolean bFlag, bIsAnalytic, bIsDirsCoinside;
113   Standard_Real  aT1;
114   gp_Dir aDNSx, aDNS1;
115   //
116   bFlag=Standard_False;
117   //
118   bIsAnalytic=BOPTools_Tools3D::HasAnalyticSurfaceType(aFx);
119   if (!bIsAnalytic) {
120     return bFlag;
121   }
122   bIsAnalytic=BOPTools_Tools3D::HasAnalyticSurfaceType(aF1);
123   if (!bIsAnalytic) {
124     return bFlag;
125   }
126   //
127   BOPTools_Tools3D::GetNormalToFaceOnEdge(anEx, aFx, aTx, aDNSx);
128   aContext->ProjectPointOnEdge(aPx, anE1, aT1);
129   BOPTools_Tools3D::GetNormalToFaceOnEdge(anE1, aF1, aT1, aDNS1);
130   //
131   bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNSx, aDNS1, aTolTangent);
132   if (!bIsDirsCoinside) {
133     return bFlag;
134   }
135   //
136   bFlag=AnalyticState(aF1, aFx, aPx, aDNSx, aTolR, aSt);
137   //
138   return bFlag;
139 }
140
141 //=======================================================================
142 //function : AnalyticState
143 //purpose  : 
144 //=======================================================================
145 Standard_Boolean AnalyticState(const TopoDS_Face& aF1,
146                                const TopoDS_Face& aFx,
147                                const gp_Pnt& aP,
148                                const gp_Dir& aDNSx,
149                                const Standard_Real aTolR,
150                                TopAbs_State& aSt)
151 {
152   Standard_Boolean bFlag;
153   Standard_Real aScPr;
154   Handle(Geom_Surface) aSF1, aSFx;
155   GeomAbs_SurfaceType aTypeF1, aTypeFx;
156   TopAbs_Orientation anOrFx;
157   gp_Dir aDNFx;
158   gp_Pnt aPOnAxis;
159   //
160   bFlag=Standard_False;
161   aSt=TopAbs_OUT;
162   //
163   aSF1=BRep_Tool::Surface(aF1);
164   GeomAdaptor_Surface aGASF1(aSF1);
165   aTypeF1=aGASF1.GetType();
166   //
167   aSFx=BRep_Tool::Surface(aFx);
168   GeomAdaptor_Surface aGASFx(aSFx);
169   aTypeFx=aGASFx.GetType();
170   //
171   aDNFx=aDNSx;
172   anOrFx=aFx.Orientation();
173   if (anOrFx==TopAbs_REVERSED){
174     aDNFx.Reverse();
175   }
176   // 
177   // Plane/Cylinder
178   if (aTypeF1==GeomAbs_Plane && aTypeFx==GeomAbs_Cylinder) {
179     gp_Cylinder aCYx;
180     //
181     aCYx=aGASFx.Cylinder();
182     aPOnAxis=ProjectedPoint(aP, aCYx.Axis());
183     gp_Vec aVTC(aP, aPOnAxis);
184     gp_Dir aDTC(aVTC);
185     //
186     aScPr=aDNFx*aDTC;
187     if (aScPr>0.) {
188       aSt=TopAbs_IN;
189     }
190     bFlag=!bFlag;
191     //
192   } 
193   //
194   // Cylinder/Plane
195   else if (aTypeF1==GeomAbs_Cylinder &&  aTypeFx==GeomAbs_Plane) {
196     gp_Cylinder aCY1;
197     //
198     aCY1=aGASF1.Cylinder();
199     aPOnAxis=ProjectedPoint(aP, aCY1.Axis());
200     gp_Vec aVTC(aP, aPOnAxis);
201     gp_Dir aDTC(aVTC);
202     //
203     aScPr=aDNFx*aDTC;
204     if (aScPr<0.) {
205       aSt=TopAbs_IN;
206     }
207     bFlag=!bFlag;
208   } //
209   //
210   // Plane/Cone
211   else if ( aTypeF1==GeomAbs_Plane && aTypeFx==GeomAbs_Cone) {
212     gp_Cone aCNx;
213     //
214     aCNx=aGASFx.Cone();
215     aPOnAxis=ProjectedPoint(aP, aCNx.Axis());
216     gp_Vec aVTC(aP, aPOnAxis);
217     gp_Dir aDTC(aVTC);
218     //
219     aScPr=aDNFx*aDTC;
220     if (aScPr>0.) {
221       aSt=TopAbs_IN;
222     }
223     bFlag=!bFlag;
224   }
225   // Cone/Plane
226   else if (aTypeF1==GeomAbs_Cone && aTypeFx==GeomAbs_Plane) {
227     gp_Cone aCN1;
228     //
229     aCN1=aGASF1.Cone();
230     aPOnAxis=ProjectedPoint(aP, aCN1.Axis());
231     gp_Vec aVTC(aP, aPOnAxis);
232     gp_Dir aDTC(aVTC);
233     //
234     aScPr=aDNFx*aDTC;
235     if (aScPr<0.) {
236       aSt=TopAbs_IN;
237     }
238     bFlag=!bFlag;
239   } //
240   // 
241   // Cylinder(Cone)/Cylinder(Cone)
242   else if ((aTypeF1==GeomAbs_Cylinder || aTypeF1==GeomAbs_Cone) && 
243            (aTypeFx==GeomAbs_Cylinder || aTypeFx==GeomAbs_Cone)) {
244     //
245     Standard_Real aPr, aR1, aRx, aSemiAngle, aDist; 
246     gp_Pnt aPOnAxis1, aPOnAxisx;
247     gp_Cylinder aCY1, aCYx;
248     gp_Cone aCN1, aCNx;
249     gp_Ax1 anAx1, anAxx;
250     //
251     // surface 1
252     if (aTypeF1==GeomAbs_Cylinder) {
253       aCY1=aGASF1.Cylinder();
254       anAx1=aCY1.Axis();
255       aR1=aCY1.Radius();
256       aPOnAxis1=ProjectedPoint(aP, anAx1);
257     }
258     else {
259       aCN1=aGASF1.Cone();
260       anAx1=aCN1.Axis();
261       aSemiAngle=aCN1.SemiAngle();
262       gp_Lin aLin(anAx1);
263       aDist=aLin.Distance(aP);
264       aR1=aDist/cos(aSemiAngle);
265       aPOnAxis1=ProjectedPoint(aP, anAx1);
266     }
267     // surface x
268     if (aTypeFx==GeomAbs_Cylinder) {
269       aCYx=aGASFx.Cylinder();
270       anAxx=aCYx.Axis();
271       aRx=aCYx.Radius();
272       aPOnAxisx=ProjectedPoint(aP, anAxx);
273     }
274     else {
275       aCNx=aGASFx.Cone();
276       anAxx=aCNx.Axis();
277       aSemiAngle=aCNx.SemiAngle();
278       gp_Lin aLin(anAxx);
279       aDist=aLin.Distance(aP);
280       aRx=aDist/cos(aSemiAngle);
281       aPOnAxisx=ProjectedPoint(aP, anAxx);
282     }
283     //
284     if (fabs(aRx-aR1) < aTolR) {
285       return bFlag;
286     }
287     //
288     gp_Vec aVTC1(aP, aPOnAxis1);
289     gp_Vec aVTCx(aP, aPOnAxisx);
290     gp_Dir aDTC1(aVTC1);
291     gp_Dir aDTCx(aVTCx);
292     //
293     aPr=aDTC1*aDTCx;
294     if (aPr < 0.) {
295       // opposite case
296       aScPr=aDNFx*aDTCx;
297       if (aScPr>0.) {
298         aSt=TopAbs_IN;
299       }
300       
301     }
302     else {
303       // one inside other
304       aScPr=aDNFx*aDTC1;
305       if (aRx<aR1) {
306         if (aScPr>0.) {
307           aSt=TopAbs_IN;
308         }
309       }
310       else {
311         if (aScPr<0.) {
312           aSt=TopAbs_IN;
313         }
314       }
315     }
316     bFlag=!bFlag;
317     //
318   }
319   //
320   return bFlag;
321 }
322
323 //=======================================================================
324 //function : HasAnalyticSurfaceType
325 //purpose  : 
326 //=======================================================================
327   Standard_Boolean BOPTools_Tools3D::HasAnalyticSurfaceType(const TopoDS_Face& aF)
328 {
329   Standard_Boolean bFlag=Standard_False;
330   GeomAbs_SurfaceType aType;
331   //
332   Handle(Geom_Surface) aS;
333   //
334   aS=BRep_Tool::Surface(aF);
335   GeomAdaptor_Surface aGAS(aS);
336   aType=aGAS.GetType();
337
338   //
339   bFlag= (aType==GeomAbs_Plane || 
340           aType==GeomAbs_Cylinder || 
341           aType==GeomAbs_Cone ||
342           aType==GeomAbs_Sphere);
343   //
344   return bFlag;
345 }
346
347 //=======================================================================
348 //function :ProjectedPoint
349 //purpose  : 
350 //=======================================================================
351   gp_Pnt ProjectedPoint (const gp_Pnt& aP,
352                          const gp_Ax1& anAx1)
353 {
354   Standard_Real aDist;
355   //
356   gp_Vec aVDirection(anAx1.Direction());
357   gp_Pnt anOrigin=anAx1.Location();
358   gp_Vec aV(anOrigin, aP);
359   aDist = aVDirection.Dot(aV);
360   //
361   gp_Pnt aPx= anOrigin.Translated(aDist*aVDirection);
362   return aPx;
363 }