b311480e |
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 | |
7fd59977 |
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, |
4f189102 |
62 | const Handle(IntTools_Context)& ) |
7fd59977 |
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, |
4f189102 |
110 | const Handle(IntTools_Context)& aContext) |
7fd59977 |
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); |
4f189102 |
128 | aContext->ProjectPointOnEdge(aPx, anE1, aT1); |
7fd59977 |
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 | } |