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