b311480e |
1 | // Created by: Peter KURNEV |
4e57c75e |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
b311480e |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | |
4e57c75e |
20 | #include <BOPInt_Context.ixx> |
7fd59977 |
21 | |
22 | #include <Precision.hxx> |
23 | |
24 | #include <Geom_Curve.hxx> |
25 | #include <Geom_BoundedCurve.hxx> |
26 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
27 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
28 | #include <GeomAdaptor_Curve.hxx> |
29 | |
4e57c75e |
30 | #include <Geom2dHatch_Intersector.hxx> |
31 | #include <Geom2d_TrimmedCurve.hxx> |
32 | |
7fd59977 |
33 | #include <TopAbs_State.hxx> |
34 | #include <TopoDS.hxx> |
35 | #include <TopExp_Explorer.hxx> |
36 | |
37 | #include <BRep_Tool.hxx> |
38 | #include <BRepAdaptor_Surface.hxx> |
39 | |
40 | #include <IntTools_Tools.hxx> |
41 | #include <IntTools_FClass2d.hxx> |
4e57c75e |
42 | // |
7fd59977 |
43 | #include <Extrema_LocateExtPC.hxx> |
44 | |
45 | #include <Geom2d_Curve.hxx> |
4e57c75e |
46 | #include <NCollection_IncAllocator.hxx> |
47 | #include <IntTools_SurfaceRangeLocalizeData.hxx> |
48 | |
7fd59977 |
49 | |
50 | //======================================================================= |
51 | //function : |
52 | //purpose : |
53 | //======================================================================= |
4e57c75e |
54 | BOPInt_Context::BOPInt_Context() |
55 | : |
56 | myAllocator(new NCollection_IncAllocator()), |
57 | myFClass2dMap(100, myAllocator), |
58 | myProjPSMap(100, myAllocator), |
59 | myProjPCMap(100, myAllocator), |
60 | mySClassMap(100, myAllocator), |
61 | myProjPTMap(100, myAllocator), |
62 | myHatcherMap(100, myAllocator), |
63 | myProjSDataMap(100, myAllocator), |
64 | myCreateFlag(0) |
65 | { |
66 | } |
67 | //======================================================================= |
68 | //function : |
69 | //purpose : |
70 | //======================================================================= |
71 | BOPInt_Context::BOPInt_Context(const Handle(NCollection_BaseAllocator)& theAllocator) |
72 | : |
73 | myAllocator(theAllocator), |
74 | myFClass2dMap(100, myAllocator), |
75 | myProjPSMap(100, myAllocator), |
76 | myProjPCMap(100, myAllocator), |
77 | mySClassMap(100, myAllocator), |
78 | myProjPTMap(100, myAllocator), |
79 | myHatcherMap(100, myAllocator), |
80 | myProjSDataMap(100, myAllocator), |
81 | myCreateFlag(1) |
7fd59977 |
82 | { |
83 | } |
84 | //======================================================================= |
85 | //function : ~ |
86 | //purpose : |
87 | //======================================================================= |
4e57c75e |
88 | BOPInt_Context::~BOPInt_Context() |
7fd59977 |
89 | { |
90 | Standard_Address anAdr; |
4e57c75e |
91 | BOPCol_DataMapIteratorOfDataMapOfShapeAddress aIt; |
92 | BOPCol_DataMapIteratorOfDataMapOfTransientAddress aIt1; |
3f524765 |
93 | // |
7fd59977 |
94 | IntTools_FClass2d* pFClass2d; |
4e57c75e |
95 | // |
96 | aIt.Initialize(myFClass2dMap); |
97 | for (; aIt.More(); aIt.Next()) { |
98 | anAdr=aIt.Value(); |
7fd59977 |
99 | pFClass2d=(IntTools_FClass2d*)anAdr; |
4e57c75e |
100 | (*pFClass2d).~IntTools_FClass2d(); |
101 | myAllocator->Free(anAdr); |
7fd59977 |
102 | } |
103 | myFClass2dMap.Clear(); |
104 | // |
105 | GeomAPI_ProjectPointOnSurf* pProjPS; |
4e57c75e |
106 | aIt.Initialize(myProjPSMap); |
107 | for (; aIt.More(); aIt.Next()) { |
108 | anAdr=aIt.Value(); |
7fd59977 |
109 | pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr; |
4e57c75e |
110 | (*pProjPS).~GeomAPI_ProjectPointOnSurf(); |
111 | myAllocator->Free(anAdr); |
7fd59977 |
112 | } |
113 | myProjPSMap.Clear(); |
114 | // |
115 | GeomAPI_ProjectPointOnCurve* pProjPC; |
4e57c75e |
116 | aIt.Initialize(myProjPCMap); |
117 | for (; aIt.More(); aIt.Next()) { |
118 | anAdr=aIt.Value(); |
7fd59977 |
119 | pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr; |
4e57c75e |
120 | (*pProjPC).~GeomAPI_ProjectPointOnCurve(); |
121 | myAllocator->Free(anAdr); |
7fd59977 |
122 | } |
123 | myProjPCMap.Clear(); |
124 | // |
4e57c75e |
125 | // |
126 | BRepClass3d_SolidClassifier* pSC; |
127 | aIt.Initialize(mySClassMap); |
128 | for (; aIt.More(); aIt.Next()) { |
129 | anAdr=aIt.Value(); |
130 | pSC=(BRepClass3d_SolidClassifier*)anAdr; |
131 | (*pSC).~BRepClass3d_SolidClassifier(); |
132 | myAllocator->Free(anAdr); |
133 | } |
134 | mySClassMap.Clear(); |
135 | // |
7fd59977 |
136 | GeomAPI_ProjectPointOnCurve* pProjPT; |
4e57c75e |
137 | aIt1.Initialize(myProjPTMap); |
138 | for (; aIt1.More(); aIt1.Next()) { |
139 | anAdr=aIt1.Value(); |
7fd59977 |
140 | pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr; |
4e57c75e |
141 | (*pProjPT).~GeomAPI_ProjectPointOnCurve(); |
142 | myAllocator->Free(anAdr); |
7fd59977 |
143 | } |
144 | myProjPTMap.Clear(); |
145 | // |
4e57c75e |
146 | Geom2dHatch_Hatcher* pHatcher; |
147 | aIt.Initialize(myHatcherMap); |
148 | for (; aIt.More(); aIt.Next()) { |
149 | anAdr=aIt.Value(); |
150 | pHatcher=(Geom2dHatch_Hatcher*)anAdr; |
151 | (*pHatcher).~Geom2dHatch_Hatcher(); |
152 | myAllocator->Free(anAdr); |
7fd59977 |
153 | } |
4e57c75e |
154 | myHatcherMap.Clear(); |
7fd59977 |
155 | // |
156 | IntTools_SurfaceRangeLocalizeData* pSData = NULL; |
4e57c75e |
157 | aIt.Initialize(myProjSDataMap); |
158 | for (; aIt.More(); aIt.Next()) { |
159 | anAdr=aIt.Value(); |
7fd59977 |
160 | pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr; |
4e57c75e |
161 | (*pSData).~IntTools_SurfaceRangeLocalizeData(); |
162 | myAllocator->Free(anAdr); |
7fd59977 |
163 | } |
164 | myProjSDataMap.Clear(); |
165 | } |
166 | //======================================================================= |
167 | //function : FClass2d |
168 | //purpose : |
169 | //======================================================================= |
4e57c75e |
170 | IntTools_FClass2d& BOPInt_Context::FClass2d(const TopoDS_Face& aF) |
7fd59977 |
171 | { |
172 | Standard_Address anAdr; |
173 | IntTools_FClass2d* pFClass2d; |
cf8e963a |
174 | // |
4e57c75e |
175 | if (!myFClass2dMap.IsBound(aF)) { |
7fd59977 |
176 | Standard_Real aTolF; |
4e57c75e |
177 | TopoDS_Face aFF; |
178 | // |
179 | aFF=aF; |
7fd59977 |
180 | aFF.Orientation(TopAbs_FORWARD); |
181 | aTolF=BRep_Tool::Tolerance(aFF); |
182 | // |
4e57c75e |
183 | pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d)); |
184 | new (pFClass2d) IntTools_FClass2d(aFF, aTolF); |
7fd59977 |
185 | // |
186 | anAdr=(Standard_Address)pFClass2d; |
4e57c75e |
187 | myFClass2dMap.Bind(aFF, anAdr); |
7fd59977 |
188 | } |
7fd59977 |
189 | else { |
4e57c75e |
190 | anAdr=myFClass2dMap.Find(aF); |
191 | pFClass2d=(IntTools_FClass2d*)anAdr; |
7fd59977 |
192 | } |
7fd59977 |
193 | return *pFClass2d; |
194 | } |
195 | //======================================================================= |
196 | //function : ProjPS |
197 | //purpose : |
198 | //======================================================================= |
4e57c75e |
199 | GeomAPI_ProjectPointOnSurf& BOPInt_Context::ProjPS(const TopoDS_Face& aF) |
7fd59977 |
200 | { |
201 | Standard_Address anAdr; |
202 | GeomAPI_ProjectPointOnSurf* pProjPS; |
4e57c75e |
203 | |
204 | if (!myProjPSMap.IsBound(aF)) { |
205 | Standard_Real Umin, Usup, Vmin, Vsup, anEpsT=1.e-12 ; |
7fd59977 |
206 | BRepAdaptor_Surface aBAS; |
207 | // |
208 | const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF); |
209 | aBAS.Initialize (aF, Standard_True); |
210 | // |
211 | Umin=aBAS.FirstUParameter(); |
212 | Usup=aBAS.LastUParameter (); |
213 | Vmin=aBAS.FirstVParameter(); |
214 | Vsup=aBAS.LastVParameter (); |
215 | // |
4e57c75e |
216 | pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf)); |
217 | new (pProjPS) GeomAPI_ProjectPointOnSurf(); |
d633fd70 |
218 | pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT, Extrema_ExtAlgo_Tree); |
219 | Extrema_ExtPS& anExtAlgo = const_cast<Extrema_ExtPS&>(pProjPS->Extrema()); |
220 | anExtAlgo.SetFlag(Extrema_ExtFlag_MIN); |
7fd59977 |
221 | // |
222 | anAdr=(Standard_Address)pProjPS; |
4e57c75e |
223 | myProjPSMap.Bind(aF, anAdr); |
7fd59977 |
224 | } |
225 | |
226 | else { |
4e57c75e |
227 | anAdr=myProjPSMap.Find(aF); |
228 | pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr; |
7fd59977 |
229 | } |
230 | return *pProjPS; |
231 | } |
232 | //======================================================================= |
233 | //function : ProjPC |
234 | //purpose : |
235 | //======================================================================= |
4e57c75e |
236 | GeomAPI_ProjectPointOnCurve& BOPInt_Context::ProjPC(const TopoDS_Edge& aE) |
7fd59977 |
237 | { |
238 | Standard_Address anAdr; |
239 | GeomAPI_ProjectPointOnCurve* pProjPC; |
4e57c75e |
240 | |
241 | if (!myProjPCMap.IsBound(aE)) { |
7fd59977 |
242 | Standard_Real f, l; |
243 | // |
244 | Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l); |
245 | // |
4e57c75e |
246 | pProjPC=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve)); |
247 | new (pProjPC) GeomAPI_ProjectPointOnCurve(); |
7fd59977 |
248 | pProjPC->Init(aC3D, f, l); |
249 | // |
250 | anAdr=(Standard_Address)pProjPC; |
4e57c75e |
251 | myProjPCMap.Bind(aE, anAdr); |
7fd59977 |
252 | } |
4e57c75e |
253 | |
7fd59977 |
254 | else { |
4e57c75e |
255 | anAdr=myProjPCMap.Find(aE); |
256 | pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr; |
7fd59977 |
257 | } |
258 | return *pProjPC; |
259 | } |
4e57c75e |
260 | |
7fd59977 |
261 | //======================================================================= |
262 | //function : ProjPT |
263 | //purpose : |
264 | //======================================================================= |
4e57c75e |
265 | GeomAPI_ProjectPointOnCurve& BOPInt_Context::ProjPT(const Handle(Geom_Curve)& aC3D) |
266 | |
7fd59977 |
267 | { |
268 | Standard_Address anAdr; |
269 | GeomAPI_ProjectPointOnCurve* pProjPT; |
4e57c75e |
270 | |
271 | if (!myProjPTMap.IsBound(aC3D)) { |
7fd59977 |
272 | Standard_Real f, l; |
273 | f=aC3D->FirstParameter(); |
274 | l=aC3D->LastParameter(); |
275 | // |
4e57c75e |
276 | pProjPT=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve)); |
277 | new (pProjPT) GeomAPI_ProjectPointOnCurve(); |
7fd59977 |
278 | pProjPT->Init(aC3D, f, l); |
279 | // |
280 | anAdr=(Standard_Address)pProjPT; |
4e57c75e |
281 | myProjPTMap.Bind(aC3D, anAdr); |
7fd59977 |
282 | } |
283 | |
284 | else { |
4e57c75e |
285 | anAdr=myProjPTMap.Find(aC3D); |
286 | pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr; |
7fd59977 |
287 | } |
288 | return *pProjPT; |
289 | } |
290 | //======================================================================= |
4e57c75e |
291 | //function : SolidClassifier |
7fd59977 |
292 | //purpose : |
293 | //======================================================================= |
4e57c75e |
294 | BRepClass3d_SolidClassifier& BOPInt_Context::SolidClassifier(const TopoDS_Solid& aSolid) |
7fd59977 |
295 | { |
296 | Standard_Address anAdr; |
4e57c75e |
297 | BRepClass3d_SolidClassifier* pSC; |
298 | |
299 | if (!mySClassMap.IsBound(aSolid)) { |
7fd59977 |
300 | // |
4e57c75e |
301 | pSC=(BRepClass3d_SolidClassifier*)myAllocator->Allocate(sizeof(BRepClass3d_SolidClassifier)); |
302 | new (pSC) BRepClass3d_SolidClassifier(aSolid); |
7fd59977 |
303 | // |
4e57c75e |
304 | anAdr=(Standard_Address)pSC; |
305 | mySClassMap.Bind(aSolid, anAdr); |
7fd59977 |
306 | } |
307 | |
308 | else { |
4e57c75e |
309 | anAdr=mySClassMap.Find(aSolid); |
310 | pSC =(BRepClass3d_SolidClassifier*)anAdr; |
7fd59977 |
311 | } |
4e57c75e |
312 | return *pSC; |
7fd59977 |
313 | } |
4e57c75e |
314 | |
7fd59977 |
315 | //======================================================================= |
4e57c75e |
316 | //function : Hatcher |
7fd59977 |
317 | //purpose : |
318 | //======================================================================= |
4e57c75e |
319 | Geom2dHatch_Hatcher& BOPInt_Context::Hatcher(const TopoDS_Face& aF) |
7fd59977 |
320 | { |
321 | Standard_Address anAdr; |
4e57c75e |
322 | Geom2dHatch_Hatcher* pHatcher; |
cf8e963a |
323 | // |
4e57c75e |
324 | if (!myHatcherMap.IsBound(aF)) { |
325 | Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D; |
326 | Standard_Real aU1, aU2, aEpsT; |
327 | TopAbs_Orientation aOrE; |
328 | Handle(Geom_Surface) aS; |
329 | Handle(Geom2d_Curve) aC2D; |
330 | Handle(Geom2d_TrimmedCurve) aCT2D; |
331 | TopoDS_Face aFF; |
332 | TopExp_Explorer aExp; |
7fd59977 |
333 | // |
4e57c75e |
334 | aTolHatch2D=1.e-8; |
335 | aTolHatch3D=1.e-8; |
336 | aTolArcIntr=1.e-10; |
337 | aTolTangfIntr=1.e-10; |
338 | aEpsT=Precision::PConfusion(); |
7fd59977 |
339 | // |
4e57c75e |
340 | Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr); |
341 | pHatcher=new Geom2dHatch_Hatcher(aIntr, |
342 | aTolHatch2D, aTolHatch3D, |
343 | Standard_True, Standard_False); |
344 | |
345 | // |
346 | aFF=aF; |
347 | aFF.Orientation(TopAbs_FORWARD); |
348 | aS=BRep_Tool::Surface(aFF); |
349 | |
350 | aExp.Init (aFF, TopAbs_EDGE); |
351 | for (; aExp.More() ; aExp.Next()) { |
352 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current()); |
353 | aOrE=aE.Orientation(); |
354 | // |
355 | aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2); |
356 | if (aC2D.IsNull() ) { |
357 | continue; |
358 | } |
359 | if (fabs(aU1-aU2) < aEpsT) { |
360 | continue; |
361 | } |
362 | // |
363 | aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2); |
364 | pHatcher->AddElement(aCT2D, aOrE); |
365 | }// for (; aExp.More() ; aExp.Next()) { |
366 | // |
367 | anAdr=(Standard_Address)pHatcher; |
368 | myHatcherMap.Bind(aFF, anAdr); |
369 | }//if (!myHatcherMap.IsBound(aF)) { |
370 | // |
371 | else { |
372 | anAdr=myHatcherMap.Find(aF); |
373 | pHatcher=(Geom2dHatch_Hatcher*)anAdr; |
7fd59977 |
374 | } |
4e57c75e |
375 | |
376 | return *pHatcher; |
377 | } |
378 | |
379 | //======================================================================= |
380 | //function : SurfaceData |
381 | //purpose : |
382 | //======================================================================= |
383 | IntTools_SurfaceRangeLocalizeData& BOPInt_Context::SurfaceData(const TopoDS_Face& aF) |
384 | { |
385 | Standard_Address anAdr; |
386 | IntTools_SurfaceRangeLocalizeData* pSData; |
387 | // |
388 | if (!myProjSDataMap.IsBound(aF)) { |
389 | pSData=new IntTools_SurfaceRangeLocalizeData(3, |
390 | 3, |
391 | 10. * Precision::PConfusion(), |
392 | 10. * Precision::PConfusion()); |
393 | // |
394 | anAdr=(Standard_Address)pSData; |
395 | myProjSDataMap.Bind(aF, anAdr); |
396 | } |
397 | |
7fd59977 |
398 | else { |
4e57c75e |
399 | anAdr=myProjSDataMap.Find(aF); |
400 | pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr; |
7fd59977 |
401 | } |
4e57c75e |
402 | return *pSData; |
403 | |
7fd59977 |
404 | } |
4e57c75e |
405 | |
7fd59977 |
406 | //======================================================================= |
4e57c75e |
407 | //function : ComputePE |
7fd59977 |
408 | //purpose : |
409 | //======================================================================= |
4e57c75e |
410 | Standard_Integer BOPInt_Context::ComputePE(const gp_Pnt& aP1, |
411 | const Standard_Real aTolP1, |
412 | const TopoDS_Edge& aE2, |
413 | Standard_Real& aT) |
7fd59977 |
414 | { |
4e57c75e |
415 | if (!BRep_Tool::IsGeometric(aE2)) { |
416 | return -2; |
417 | } |
418 | Standard_Real aDist, aTolE2, aTolSum; |
419 | Standard_Integer aNbProj; |
7fd59977 |
420 | // |
4e57c75e |
421 | GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2); |
422 | aProjector.Perform(aP1); |
423 | |
424 | aNbProj=aProjector.NbPoints(); |
425 | if (!aNbProj) { |
426 | return -3; |
427 | } |
7fd59977 |
428 | // |
4e57c75e |
429 | aDist=aProjector.LowerDistance(); |
430 | // |
431 | aTolE2=BRep_Tool::Tolerance(aE2); |
432 | aTolSum=aTolP1+aTolE2; |
433 | // |
434 | aT=aProjector.LowerDistanceParameter(); |
435 | if (aDist > aTolSum) { |
436 | return -4; |
437 | } |
438 | return 0; |
7fd59977 |
439 | } |
440 | //======================================================================= |
441 | //function : ComputeVE |
442 | //purpose : |
443 | //======================================================================= |
4e57c75e |
444 | Standard_Integer BOPInt_Context::ComputeVE(const TopoDS_Vertex& aV1, |
445 | const TopoDS_Edge& aE2, |
446 | Standard_Real& aT) |
7fd59977 |
447 | { |
7fd59977 |
448 | if (BRep_Tool::Degenerated(aE2)) { |
449 | return -1; |
450 | } |
4e57c75e |
451 | if (!BRep_Tool::IsGeometric(aE2)) { |
452 | return -2; |
453 | } |
454 | Standard_Real aDist, aTolV1, aTolE2, aTolSum; |
7fd59977 |
455 | Standard_Integer aNbProj; |
456 | gp_Pnt aP; |
457 | // |
458 | aP=BRep_Tool::Pnt(aV1); |
459 | // |
460 | GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2); |
461 | aProjector.Perform(aP); |
4e57c75e |
462 | |
7fd59977 |
463 | aNbProj=aProjector.NbPoints(); |
464 | if (!aNbProj) { |
465 | return -3; |
466 | } |
467 | // |
468 | aDist=aProjector.LowerDistance(); |
4e57c75e |
469 | // |
7fd59977 |
470 | aTolV1=BRep_Tool::Tolerance(aV1); |
471 | aTolE2=BRep_Tool::Tolerance(aE2); |
472 | aTolSum=aTolV1+aTolE2; |
473 | // |
474 | aT=aProjector.LowerDistanceParameter(); |
475 | if (aDist > aTolSum) { |
476 | return -4; |
477 | } |
7fd59977 |
478 | return 0; |
479 | } |
7fd59977 |
480 | //======================================================================= |
481 | //function : ComputeVS |
482 | //purpose : |
483 | //======================================================================= |
4e57c75e |
484 | Standard_Integer BOPInt_Context::ComputeVF(const TopoDS_Vertex& aV1, |
485 | const TopoDS_Face& aF2, |
486 | Standard_Real& U, |
487 | Standard_Real& V) |
7fd59977 |
488 | { |
489 | Standard_Real aTolV1, aTolF2, aTolSum, aDist; |
490 | gp_Pnt aP; |
491 | |
492 | aP=BRep_Tool::Pnt(aV1); |
493 | // |
494 | // 1. Check if the point is projectable on the surface |
495 | GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2); |
496 | aProjector.Perform(aP); |
497 | // |
4e57c75e |
498 | if (!aProjector.IsDone()) { // the point is not projectable on the surface |
7fd59977 |
499 | return -1; |
500 | } |
501 | // |
502 | // 2. Check the distance between the projection point and |
503 | // the original point |
504 | aDist=aProjector.LowerDistance(); |
505 | |
506 | aTolV1=BRep_Tool::Tolerance(aV1); |
507 | aTolF2=BRep_Tool::Tolerance(aF2); |
508 | aTolSum=aTolV1+aTolF2; |
509 | if (aDist > aTolSum) { |
510 | // the distance is too large |
511 | return -2; |
512 | } |
513 | aProjector.LowerDistanceParameters(U, V); |
514 | // |
515 | gp_Pnt2d aP2d(U, V); |
516 | Standard_Boolean pri=IsPointInFace (aF2, aP2d); |
4e57c75e |
517 | if (!pri) {// the point lays on the surface but out of the face |
7fd59977 |
518 | return -3; |
519 | } |
520 | return 0; |
521 | } |
522 | //======================================================================= |
523 | //function : StatePointFace |
524 | //purpose : |
525 | //======================================================================= |
4e57c75e |
526 | TopAbs_State BOPInt_Context::StatePointFace(const TopoDS_Face& aF, |
527 | const gp_Pnt2d& aP2d) |
7fd59977 |
528 | { |
529 | TopAbs_State aState; |
530 | IntTools_FClass2d& aClass2d=FClass2d(aF); |
531 | aState=aClass2d.Perform(aP2d); |
532 | return aState; |
533 | } |
534 | //======================================================================= |
535 | //function : IsPointInFace |
536 | //purpose : |
537 | //======================================================================= |
4e57c75e |
538 | Standard_Boolean BOPInt_Context::IsPointInFace(const TopoDS_Face& aF, |
539 | const gp_Pnt2d& aP2d) |
7fd59977 |
540 | { |
541 | TopAbs_State aState=StatePointFace(aF, aP2d); |
542 | if (aState==TopAbs_OUT || aState==TopAbs_ON) { |
543 | return Standard_False; |
544 | } |
545 | return Standard_True; |
546 | } |
547 | //======================================================================= |
548 | //function : IsPointInOnFace |
549 | //purpose : |
550 | //======================================================================= |
4e57c75e |
551 | Standard_Boolean BOPInt_Context::IsPointInOnFace(const TopoDS_Face& aF, |
552 | const gp_Pnt2d& aP2d) |
7fd59977 |
553 | { |
554 | TopAbs_State aState=StatePointFace(aF, aP2d); |
555 | if (aState==TopAbs_OUT) { |
556 | return Standard_False; |
557 | } |
558 | return Standard_True; |
559 | } |
560 | //======================================================================= |
561 | //function : IsValidPointForFace |
562 | //purpose : |
563 | //======================================================================= |
4e57c75e |
564 | Standard_Boolean BOPInt_Context::IsValidPointForFace(const gp_Pnt& aP, |
565 | const TopoDS_Face& aF, |
566 | const Standard_Real aTol) |
7fd59977 |
567 | { |
568 | Standard_Boolean bFlag; |
569 | Standard_Real Umin, myEpsT, U, V; |
570 | myEpsT=1.e-12; |
571 | |
572 | GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF); |
573 | aProjector.Perform(aP); |
574 | |
575 | bFlag=aProjector.IsDone(); |
576 | if (bFlag) { |
577 | |
578 | Umin=aProjector.LowerDistance(); |
579 | //if (Umin > 1.e-3) { // it was |
580 | if (Umin > aTol) { |
581 | return !bFlag; |
582 | } |
583 | // |
584 | aProjector.LowerDistanceParameters(U, V); |
585 | gp_Pnt2d aP2D(U, V); |
586 | bFlag=IsPointInOnFace (aF, aP2D); |
587 | } |
588 | return bFlag; |
589 | } |
590 | //======================================================================= |
591 | //function : IsValidPointForFaces |
592 | //purpose : |
593 | //======================================================================= |
4e57c75e |
594 | Standard_Boolean BOPInt_Context::IsValidPointForFaces (const gp_Pnt& aP, |
595 | const TopoDS_Face& aF1, |
596 | const TopoDS_Face& aF2, |
597 | const Standard_Real aTol) |
7fd59977 |
598 | { |
599 | Standard_Boolean bFlag1, bFlag2; |
600 | |
601 | bFlag1=IsValidPointForFace(aP, aF1, aTol); |
602 | if (!bFlag1) { |
603 | return bFlag1; |
604 | } |
605 | bFlag2=IsValidPointForFace(aP, aF2, aTol); |
606 | return bFlag2; |
607 | } |
608 | //======================================================================= |
609 | //function : IsValidBlockForFace |
610 | //purpose : |
611 | //======================================================================= |
4e57c75e |
612 | Standard_Boolean BOPInt_Context::IsValidBlockForFace (const Standard_Real aT1, |
613 | const Standard_Real aT2, |
614 | const IntTools_Curve& aC, |
615 | const TopoDS_Face& aF, |
616 | const Standard_Real aTol) |
7fd59977 |
617 | { |
618 | Standard_Boolean bFlag; |
619 | Standard_Real aTInterm, aFirst, aLast; |
620 | gp_Pnt aPInterm; |
621 | |
622 | aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2); |
623 | |
624 | Handle(Geom_Curve) aC3D=aC.Curve(); |
625 | aFirst=aC3D->FirstParameter(); |
626 | aLast =aC3D->LastParameter(); |
627 | // point 3D |
628 | aC3D->D0(aTInterm, aPInterm); |
629 | // |
630 | bFlag=IsValidPointForFace (aPInterm, aF, aTol); |
631 | return bFlag; |
632 | } |
633 | //======================================================================= |
634 | //function : IsValidBlockForFaces |
635 | //purpose : |
636 | //======================================================================= |
4e57c75e |
637 | Standard_Boolean BOPInt_Context::IsValidBlockForFaces (const Standard_Real aT1, |
638 | const Standard_Real aT2, |
639 | const IntTools_Curve& aC, |
640 | const TopoDS_Face& aF1, |
641 | const TopoDS_Face& aF2, |
642 | const Standard_Real aTol) |
7fd59977 |
643 | { |
644 | Standard_Boolean bFlag1, bFlag2; |
645 | // |
646 | Handle(Geom2d_Curve) aPC1 = aC.FirstCurve2d(); |
647 | Handle(Geom2d_Curve) aPC2 = aC.SecondCurve2d(); |
648 | if( !aPC1.IsNull() && !aPC2.IsNull() ) { |
649 | Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(aT1, aT2); |
650 | gp_Pnt2d aPnt2D; |
651 | |
652 | |
653 | aPC1->D0(aMidPar, aPnt2D); |
654 | bFlag1 = IsPointInOnFace(aF1, aPnt2D); |
655 | |
656 | if( !bFlag1 ) |
657 | return bFlag1; |
658 | |
659 | aPC2->D0(aMidPar, aPnt2D); |
660 | bFlag2 = IsPointInOnFace(aF2, aPnt2D); |
661 | return bFlag2; |
662 | } |
663 | // |
664 | |
665 | bFlag1=IsValidBlockForFace (aT1, aT2, aC, aF1, aTol); |
666 | if (!bFlag1) { |
667 | return bFlag1; |
668 | } |
669 | bFlag2=IsValidBlockForFace (aT1, aT2, aC, aF2, aTol); |
670 | return bFlag2; |
671 | } |
672 | //======================================================================= |
673 | //function : IsVertexOnLine |
674 | //purpose : |
675 | //======================================================================= |
4e57c75e |
676 | Standard_Boolean BOPInt_Context::IsVertexOnLine (const TopoDS_Vertex& aV, |
677 | const IntTools_Curve& aC, |
678 | const Standard_Real aTolC, |
679 | Standard_Real& aT) |
7fd59977 |
680 | { |
681 | Standard_Boolean bRet; |
682 | Standard_Real aTolV; |
683 | // |
684 | aTolV=BRep_Tool::Tolerance(aV); |
4e57c75e |
685 | bRet=BOPInt_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT); |
7fd59977 |
686 | // |
687 | return bRet; |
688 | } |
689 | //======================================================================= |
690 | //function : IsVertexOnLine |
691 | //purpose : |
692 | //======================================================================= |
4e57c75e |
693 | Standard_Boolean BOPInt_Context::IsVertexOnLine (const TopoDS_Vertex& aV, |
694 | const Standard_Real aTolV, |
695 | const IntTools_Curve& aC, |
696 | const Standard_Real aTolC, |
697 | Standard_Real& aT) |
7fd59977 |
698 | { |
699 | Standard_Real aFirst, aLast, aDist, aTolSum; |
700 | Standard_Integer aNbProj; |
701 | gp_Pnt aPv; |
702 | |
703 | aPv=BRep_Tool::Pnt(aV); |
704 | |
705 | Handle(Geom_Curve) aC3D=aC.Curve(); |
706 | |
707 | |
708 | aTolSum=aTolV+aTolC; |
709 | // |
710 | GeomAdaptor_Curve aGAC(aC3D); |
711 | GeomAbs_CurveType aType=aGAC.GetType(); |
712 | if (aType==GeomAbs_BSplineCurve || |
713 | aType==GeomAbs_BezierCurve) { |
714 | aTolSum=2.*aTolSum; |
715 | if (aTolSum<1.e-5) { |
716 | aTolSum=1.e-5; |
717 | } |
718 | } |
719 | else { |
720 | aTolSum=2.*aTolSum;//xft |
721 | if(aTolSum < 1.e-6) |
722 | aTolSum = 1.e-6; |
723 | } |
724 | // |
725 | aFirst=aC3D->FirstParameter(); |
726 | aLast =aC3D->LastParameter(); |
727 | // |
728 | //Checking extermities first |
729 | if (!Precision::IsInfinite(aFirst)) { |
730 | gp_Pnt aPCFirst=aC3D->Value(aFirst); |
731 | aDist=aPv.Distance(aPCFirst); |
732 | if (aDist < aTolSum) { |
733 | aT=aFirst; |
734 | // |
735 | if(aDist > aTolV) { |
4e57c75e |
736 | Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10); |
737 | |
738 | if(anExt.IsDone()) { |
739 | Extrema_POnCurv aPOncurve = anExt.Point(); |
740 | aT = aPOncurve.Parameter(); |
741 | |
742 | if((aT > (aLast + aFirst) * 0.5) || |
743 | (aPv.Distance(aPOncurve.Value()) > aTolSum) || |
744 | (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion())) |
745 | aT = aFirst; |
746 | } |
7fd59977 |
747 | } |
748 | // |
749 | return Standard_True; |
750 | } |
751 | } |
752 | // |
4e57c75e |
753 | //if (!Precision::IsInfinite(aFirst)) { |
7fd59977 |
754 | if (!Precision::IsInfinite(aLast)) { |
755 | gp_Pnt aPCLast=aC3D->Value(aLast); |
756 | aDist=aPv.Distance(aPCLast); |
757 | if (aDist < aTolSum) { |
758 | aT=aLast; |
759 | // |
760 | if(aDist > aTolV) { |
4e57c75e |
761 | Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10); |
762 | |
763 | if(anExt.IsDone()) { |
764 | Extrema_POnCurv aPOncurve = anExt.Point(); |
765 | aT = aPOncurve.Parameter(); |
766 | |
767 | if((aT < (aLast + aFirst) * 0.5) || |
768 | (aPv.Distance(aPOncurve.Value()) > aTolSum) || |
769 | (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion())) |
770 | aT = aLast; |
771 | } |
7fd59977 |
772 | } |
773 | // |
774 | return Standard_True; |
775 | } |
776 | } |
777 | // |
778 | GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D); |
779 | aProjector.Perform(aPv); |
780 | |
781 | aNbProj=aProjector.NbPoints(); |
782 | if (!aNbProj) { |
783 | Handle(Geom_BoundedCurve) aBC= |
784 | Handle(Geom_BoundedCurve)::DownCast(aC3D); |
785 | if (!aBC.IsNull()) { |
786 | gp_Pnt aPStart=aBC->StartPoint(); |
787 | gp_Pnt aPEnd =aBC->EndPoint(); |
788 | |
789 | aDist=aPv.Distance(aPStart); |
790 | if (aDist < aTolSum) { |
4e57c75e |
791 | aT=aFirst; |
792 | return Standard_True; |
7fd59977 |
793 | } |
794 | |
795 | aDist=aPv.Distance(aPEnd); |
796 | if (aDist < aTolSum) { |
4e57c75e |
797 | aT=aLast; |
798 | return Standard_True; |
7fd59977 |
799 | } |
800 | } |
801 | |
802 | return Standard_False; |
803 | } |
804 | |
805 | aDist=aProjector.LowerDistance(); |
806 | |
807 | if (aDist > aTolSum) { |
808 | return Standard_False; |
809 | } |
810 | |
811 | aT=aProjector.LowerDistanceParameter(); |
812 | |
813 | return Standard_True; |
814 | } |
815 | //======================================================================= |
816 | //function : ProjectPointOnEdge |
817 | //purpose : |
818 | //======================================================================= |
4e57c75e |
819 | Standard_Boolean BOPInt_Context::ProjectPointOnEdge(const gp_Pnt& aP, |
820 | const TopoDS_Edge& anEdge, |
821 | Standard_Real& aT) |
7fd59977 |
822 | { |
823 | Standard_Integer aNbPoints; |
824 | |
825 | GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge); |
826 | aProjector.Perform(aP); |
827 | |
828 | aNbPoints=aProjector.NbPoints(); |
829 | if (aNbPoints) { |
830 | aT=aProjector.LowerDistanceParameter(); |
831 | return Standard_True; |
832 | } |
833 | return Standard_False; |
834 | } |
835 | |