0022593: Fixed data races in Poly
[occt.git] / src / IntTools / IntTools_Context.cxx
CommitLineData
7fd59977 1// File: IntTools_Context.cxx
2// Created: Wed Apr 3 16:57:54 2002
3// Author: Peter KURNEV
4// <pkv@irinox>
5
6
7#include <IntTools_Context.ixx>
8
9#include <Precision.hxx>
10
11#include <Geom_Curve.hxx>
12#include <Geom_BoundedCurve.hxx>
13#include <GeomAPI_ProjectPointOnCurve.hxx>
14#include <GeomAPI_ProjectPointOnSurf.hxx>
15#include <GeomAdaptor_Curve.hxx>
16
17#include <TopAbs_State.hxx>
18#include <TopoDS.hxx>
19#include <TopExp_Explorer.hxx>
20
21#include <BRep_Tool.hxx>
22#include <BRepAdaptor_Surface.hxx>
23
24#include <IntTools_Tools.hxx>
25#include <IntTools_FClass2d.hxx>
26//
27#include <Extrema_LocateExtPC.hxx>
28
29#include <Geom2d_Curve.hxx>
30
31//=======================================================================
32//function :
33//purpose :
34//=======================================================================
35 IntTools_Context::IntTools_Context()
36{
37}
38//=======================================================================
39//function : ~
40//purpose :
41//=======================================================================
42 IntTools_Context::~IntTools_Context()
43{
44 Standard_Address anAdr;
45 Standard_Integer i, aNb;
46 //
47 IntTools_FClass2d* pFClass2d;
48 aNb=myFClass2dMap.Extent();
49 for (i=1; i<=aNb; ++i) {
50 anAdr=myFClass2dMap(i);
51 pFClass2d=(IntTools_FClass2d*)anAdr;
52 delete pFClass2d;
53 }
54 myFClass2dMap.Clear();
55 //
56 GeomAPI_ProjectPointOnSurf* pProjPS;
57 aNb=myProjPSMap.Extent();
58 for (i=1; i<=aNb; ++i) {
59 anAdr=myProjPSMap(i);
60 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
61 delete pProjPS;
62 }
63 myProjPSMap.Clear();
64 //
65 GeomAPI_ProjectPointOnCurve* pProjPC;
66 aNb=myProjPCMap.Extent();
67 for (i=1; i<=aNb; ++i) {
68 anAdr=myProjPCMap(i);
69 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
70 delete pProjPC;
71 }
72 myProjPCMap.Clear();
73 //
74 GeomAPI_ProjectPointOnCurve* pProjPT;
75 aNb=myProjPTMap.Extent();
76 for (i=1; i<=aNb; ++i) {
77 anAdr=myProjPTMap(i);
78 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
79 delete pProjPT;
80 }
81 myProjPTMap.Clear();
82 //
83 BRepClass3d_SolidClassifier* pSC;
84 aNb=mySClassMap.Extent();
85 for (i=1; i<=aNb; ++i) {
86 anAdr=mySClassMap(i);
87 pSC=(BRepClass3d_SolidClassifier*)anAdr;
88 delete pSC;
89 }
90 mySClassMap.Clear();
91 //
92 IntTools_SurfaceRangeLocalizeData* pSData = NULL;
93 aNb = myProjSDataMap.Extent();
94 for (i=1; i<=aNb; ++i) {
95 anAdr=myProjSDataMap(i);
96 pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
97 if(pSData)
98 delete pSData;
99 pSData = NULL;
100 }
101 myProjSDataMap.Clear();
102}
103//=======================================================================
104//function : FClass2d
105//purpose :
106//=======================================================================
107 IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
108{
109 Standard_Address anAdr;
110 IntTools_FClass2d* pFClass2d;
111
112 if (!myFClass2dMap.Contains(aF)) {
113 Standard_Real aTolF;
114 TopoDS_Face aFF=aF;
115 aFF.Orientation(TopAbs_FORWARD);
116 aTolF=BRep_Tool::Tolerance(aFF);
117 //
118 pFClass2d=new IntTools_FClass2d(aFF, aTolF);
119 //
120 anAdr=(Standard_Address)pFClass2d;
121 myFClass2dMap.Add(aFF, anAdr);
122 }
123
124 else {
125 anAdr=myFClass2dMap.FindFromKey(aF);
126 pFClass2d=(IntTools_FClass2d*)anAdr;
127 }
128
129 return *pFClass2d;
130}
131//=======================================================================
132//function : ProjPS
133//purpose :
134//=======================================================================
135 GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
136{
137 Standard_Address anAdr;
138 GeomAPI_ProjectPointOnSurf* pProjPS;
139
140 if (!myProjPSMap.Contains(aF)) {
141 Standard_Real Umin, Usup, Vmin, Vsup, anEpsT=1.e-12 ;
142 BRepAdaptor_Surface aBAS;
143 //
144 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
145 aBAS.Initialize (aF, Standard_True);
146 //
147 Umin=aBAS.FirstUParameter();
148 Usup=aBAS.LastUParameter ();
149 Vmin=aBAS.FirstVParameter();
150 Vsup=aBAS.LastVParameter ();
151 //
152 pProjPS=new GeomAPI_ProjectPointOnSurf;
153 pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT);
154 //
155 anAdr=(Standard_Address)pProjPS;
156 myProjPSMap.Add(aF, anAdr);
157 }
158
159 else {
160 anAdr=myProjPSMap.FindFromKey(aF);
161 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
162 }
163 return *pProjPS;
164}
165//=======================================================================
166//function : ProjPC
167//purpose :
168//=======================================================================
169 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPC(const TopoDS_Edge& aE)
170{
171 Standard_Address anAdr;
172 GeomAPI_ProjectPointOnCurve* pProjPC;
173
174 if (!myProjPCMap.Contains(aE)) {
175 Standard_Real f, l;
176 //
177 Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l);
178 //
179 pProjPC=new GeomAPI_ProjectPointOnCurve;
180 pProjPC->Init(aC3D, f, l);
181 //
182 anAdr=(Standard_Address)pProjPC;
183 myProjPCMap.Add(aE, anAdr);
184 }
185
186 else {
187 anAdr=myProjPCMap.FindFromKey(aE);
188 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
189 }
190 return *pProjPC;
191}
192//=======================================================================
193//function : ProjPT
194//purpose :
195//=======================================================================
196 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPT(const Handle(Geom_Curve)& aC3D)
197
198{
199 Standard_Address anAdr;
200 GeomAPI_ProjectPointOnCurve* pProjPT;
201
202 if (!myProjPTMap.Contains(aC3D)) {
203 Standard_Real f, l;
204 f=aC3D->FirstParameter();
205 l=aC3D->LastParameter();
206 //
207 pProjPT=new GeomAPI_ProjectPointOnCurve;
208 pProjPT->Init(aC3D, f, l);
209 //
210 anAdr=(Standard_Address)pProjPT;
211 myProjPTMap.Add(aC3D, anAdr);
212 }
213
214 else {
215 anAdr=myProjPTMap.FindFromKey(aC3D);
216 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
217 }
218 return *pProjPT;
219}
220//=======================================================================
221//function : SurfaceData
222//purpose :
223//=======================================================================
224 IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData(const TopoDS_Face& aF)
225{
226 Standard_Address anAdr;
227 IntTools_SurfaceRangeLocalizeData* pSData;
228
229 if (!myProjSDataMap.Contains(aF)) {
230 //
231 pSData=new IntTools_SurfaceRangeLocalizeData(3,
232 3,
233 10. * Precision::PConfusion(),
234 10. * Precision::PConfusion());
235 //
236 anAdr=(Standard_Address)pSData;
237 myProjSDataMap.Add(aF, anAdr);
238 }
239
240 else {
241 anAdr=myProjSDataMap.FindFromKey(aF);
242 pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr;
243 }
244 return *pSData;
245
246}
247//=======================================================================
248//function : SolidClassifier
249//purpose :
250//=======================================================================
251 BRepClass3d_SolidClassifier& IntTools_Context::SolidClassifier(const TopoDS_Solid& aSolid)
252{
253 Standard_Address anAdr;
254 BRepClass3d_SolidClassifier* pSC;
255
256 if (!mySClassMap.Contains(aSolid)) {
257 //
258 pSC=new BRepClass3d_SolidClassifier(aSolid);
259 //
260 anAdr=(Standard_Address)pSC;
261 mySClassMap.Add(aSolid, anAdr);
262 }
263
264 else {
265 anAdr=mySClassMap.FindFromKey(aSolid);
266 pSC =(BRepClass3d_SolidClassifier*)anAdr;
267 }
268 return *pSC;
269}
270
271
272//modified by NIZNHY-PKV Tue Feb 2 08:33:16 2010f
273//=======================================================================
274//function : ComputeVE
275//purpose :
276//=======================================================================
277 Standard_Integer IntTools_Context::ComputeVE(const TopoDS_Vertex& aV1,
278 const TopoDS_Edge& aE2,
279 Standard_Real& aT)
280{
281 Standard_Boolean bToUpdate;
282 Standard_Integer iFlag;
283 Standard_Real aDist;
284 //
285 iFlag= IntTools_Context::ComputeVE(aV1, aE2, aT, bToUpdate, aDist);
286 //
287 return iFlag;
288}
289//=======================================================================
290//function : ComputeVE
291//purpose :
292//=======================================================================
293 Standard_Integer IntTools_Context::ComputeVE(const TopoDS_Vertex& aV1,
294 const TopoDS_Edge& aE2,
295 Standard_Real& aT,
296 Standard_Boolean& bToUpdateVertex,
297 Standard_Real& aDist)
298{
299 bToUpdateVertex=Standard_False;
300 aDist=0.;
301 //
302 if (BRep_Tool::Degenerated(aE2)) {
303 return -1;
304 }
305 if (!BRep_Tool::IsGeometric(aE2)) {
306 return -2;
307 }
308 //
309 Standard_Real aTolV1, aTolE2, aTolSum, aTolVx;
310 Standard_Integer aNbProj;
311 gp_Pnt aP;
312 //
313 aP=BRep_Tool::Pnt(aV1);
314 //
315 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
316 aProjector.Perform(aP);
317 aNbProj=aProjector.NbPoints();
318 if (!aNbProj) {
319 return -3;
320 }
321 //
322 aDist=aProjector.LowerDistance();
323 aTolV1=BRep_Tool::Tolerance(aV1);
324 aTolE2=BRep_Tool::Tolerance(aE2);
325 aTolSum=aTolV1+aTolE2;
326 //
327 aT=aProjector.LowerDistanceParameter();
328 if (aDist > aTolSum) {
329 return -4;
330 }
331 //
332 aTolVx=aDist+aTolE2;
333 if (aTolVx>aTolV1) {
334 bToUpdateVertex=!bToUpdateVertex;
335 aDist=aTolVx;
336 }
337 //
338 return 0;
339}
340//modified by NIZNHY-PKV Tue Feb 2 08:33:21 2010t
341//=======================================================================
342//function : ComputeVS
343//purpose :
344//=======================================================================
345 Standard_Integer IntTools_Context::ComputeVS(const TopoDS_Vertex& aV1,
346 const TopoDS_Face& aF2,
347 Standard_Real& U,
348 Standard_Real& V)
349{
350 Standard_Real aTolV1, aTolF2, aTolSum, aDist;
351 gp_Pnt aP;
352
353 aP=BRep_Tool::Pnt(aV1);
354 //
355 // 1. Check if the point is projectable on the surface
356 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2);
357 aProjector.Perform(aP);
358 //
359 if (!aProjector.IsDone()) {
360 // the point is not projectable on the surface
361 return -1;
362 }
363 //
364 // 2. Check the distance between the projection point and
365 // the original point
366 aDist=aProjector.LowerDistance();
367
368 aTolV1=BRep_Tool::Tolerance(aV1);
369 aTolF2=BRep_Tool::Tolerance(aF2);
370 aTolSum=aTolV1+aTolF2;
371 if (aDist > aTolSum) {
372 // the distance is too large
373 return -2;
374 }
375 aProjector.LowerDistanceParameters(U, V);
376 //
377 gp_Pnt2d aP2d(U, V);
378 Standard_Boolean pri=IsPointInFace (aF2, aP2d);
379 if (!pri) {
380 // the point lays on the surface but out of the face
381 return -3;
382 }
383 return 0;
384}
385//=======================================================================
386//function : StatePointFace
387//purpose :
388//=======================================================================
389 TopAbs_State IntTools_Context::StatePointFace(const TopoDS_Face& aF,
390 const gp_Pnt2d& aP2d)
391{
392 TopAbs_State aState;
393 IntTools_FClass2d& aClass2d=FClass2d(aF);
394 aState=aClass2d.Perform(aP2d);
395 return aState;
396}
397//=======================================================================
398//function : IsPointInFace
399//purpose :
400//=======================================================================
401 Standard_Boolean IntTools_Context::IsPointInFace(const TopoDS_Face& aF,
402 const gp_Pnt2d& aP2d)
403{
404 TopAbs_State aState=StatePointFace(aF, aP2d);
405 if (aState==TopAbs_OUT || aState==TopAbs_ON) {
406 return Standard_False;
407 }
408 return Standard_True;
409}
410//=======================================================================
411//function : IsPointInOnFace
412//purpose :
413//=======================================================================
414 Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
415 const gp_Pnt2d& aP2d)
416{
417 TopAbs_State aState=StatePointFace(aF, aP2d);
418 if (aState==TopAbs_OUT) {
419 return Standard_False;
420 }
421 return Standard_True;
422}
423//=======================================================================
424//function : IsValidPointForFace
425//purpose :
426//=======================================================================
427 Standard_Boolean IntTools_Context::IsValidPointForFace(const gp_Pnt& aP,
428 const TopoDS_Face& aF,
429 const Standard_Real aTol)
430{
431 Standard_Boolean bFlag;
432 Standard_Real Umin, myEpsT, U, V;
433 myEpsT=1.e-12;
434
435 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
436 aProjector.Perform(aP);
437
438 bFlag=aProjector.IsDone();
439 if (bFlag) {
440
441 Umin=aProjector.LowerDistance();
442 //if (Umin > 1.e-3) { // it was
443 if (Umin > aTol) {
444 return !bFlag;
445 }
446 //
447 aProjector.LowerDistanceParameters(U, V);
448 gp_Pnt2d aP2D(U, V);
449 bFlag=IsPointInOnFace (aF, aP2D);
450 }
451 return bFlag;
452}
453//=======================================================================
454//function : IsValidPointForFaces
455//purpose :
456//=======================================================================
457 Standard_Boolean IntTools_Context::IsValidPointForFaces (const gp_Pnt& aP,
458 const TopoDS_Face& aF1,
459 const TopoDS_Face& aF2,
460 const Standard_Real aTol)
461{
462 Standard_Boolean bFlag1, bFlag2;
463
464 bFlag1=IsValidPointForFace(aP, aF1, aTol);
465 if (!bFlag1) {
466 return bFlag1;
467 }
468 bFlag2=IsValidPointForFace(aP, aF2, aTol);
469 return bFlag2;
470}
471//=======================================================================
472//function : IsValidBlockForFace
473//purpose :
474//=======================================================================
475 Standard_Boolean IntTools_Context::IsValidBlockForFace (const Standard_Real aT1,
476 const Standard_Real aT2,
477 const IntTools_Curve& aC,
478 const TopoDS_Face& aF,
479 const Standard_Real aTol)
480{
481 Standard_Boolean bFlag;
482 Standard_Real aTInterm, aFirst, aLast;
483 gp_Pnt aPInterm;
484
485 aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
486
487 Handle(Geom_Curve) aC3D=aC.Curve();
488 aFirst=aC3D->FirstParameter();
489 aLast =aC3D->LastParameter();
490 // point 3D
491 aC3D->D0(aTInterm, aPInterm);
492 //
493 bFlag=IsValidPointForFace (aPInterm, aF, aTol);
494 return bFlag;
495}
496//=======================================================================
497//function : IsValidBlockForFaces
498//purpose :
499//=======================================================================
500 Standard_Boolean IntTools_Context::IsValidBlockForFaces (const Standard_Real aT1,
501 const Standard_Real aT2,
502 const IntTools_Curve& aC,
503 const TopoDS_Face& aF1,
504 const TopoDS_Face& aF2,
505 const Standard_Real aTol)
506{
507 Standard_Boolean bFlag1, bFlag2;
508 //
509 Handle(Geom2d_Curve) aPC1 = aC.FirstCurve2d();
510 Handle(Geom2d_Curve) aPC2 = aC.SecondCurve2d();
511 if( !aPC1.IsNull() && !aPC2.IsNull() ) {
512 Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(aT1, aT2);
513 gp_Pnt2d aPnt2D;
514
515
516 aPC1->D0(aMidPar, aPnt2D);
517 bFlag1 = IsPointInOnFace(aF1, aPnt2D);
518
519 if( !bFlag1 )
520 return bFlag1;
521
522 aPC2->D0(aMidPar, aPnt2D);
523 bFlag2 = IsPointInOnFace(aF2, aPnt2D);
524 return bFlag2;
525 }
526 //
527
528 bFlag1=IsValidBlockForFace (aT1, aT2, aC, aF1, aTol);
529 if (!bFlag1) {
530 return bFlag1;
531 }
532 bFlag2=IsValidBlockForFace (aT1, aT2, aC, aF2, aTol);
533 return bFlag2;
534}
535//=======================================================================
536//function : IsVertexOnLine
537//purpose :
538//=======================================================================
539 Standard_Boolean IntTools_Context::IsVertexOnLine (const TopoDS_Vertex& aV,
540 const IntTools_Curve& aC,
541 const Standard_Real aTolC,
542 Standard_Real& aT)
543{
544 Standard_Boolean bRet;
545 Standard_Real aTolV;
546 //
547 aTolV=BRep_Tool::Tolerance(aV);
548 bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
549 //
550 return bRet;
551}
552//=======================================================================
553//function : IsVertexOnLine
554//purpose :
555//=======================================================================
556 Standard_Boolean IntTools_Context::IsVertexOnLine (const TopoDS_Vertex& aV,
557 const Standard_Real aTolV,
558 const IntTools_Curve& aC,
559 const Standard_Real aTolC,
560 Standard_Real& aT)
561{
562 Standard_Real aFirst, aLast, aDist, aTolSum;
563 Standard_Integer aNbProj;
564 gp_Pnt aPv;
565
566 aPv=BRep_Tool::Pnt(aV);
567
568 Handle(Geom_Curve) aC3D=aC.Curve();
569
570
571 aTolSum=aTolV+aTolC;
572 //
573 GeomAdaptor_Curve aGAC(aC3D);
574 GeomAbs_CurveType aType=aGAC.GetType();
575 if (aType==GeomAbs_BSplineCurve ||
576 aType==GeomAbs_BezierCurve) {
577 aTolSum=2.*aTolSum;
578 if (aTolSum<1.e-5) {
579 aTolSum=1.e-5;
580 }
581 }
582 else {
583 aTolSum=2.*aTolSum;//xft
584 if(aTolSum < 1.e-6)
585 aTolSum = 1.e-6;
586 }
587 //
588 aFirst=aC3D->FirstParameter();
589 aLast =aC3D->LastParameter();
590 //
591 //Checking extermities first
592 if (!Precision::IsInfinite(aFirst)) {
593 gp_Pnt aPCFirst=aC3D->Value(aFirst);
594 aDist=aPv.Distance(aPCFirst);
595 if (aDist < aTolSum) {
596 aT=aFirst;
597 //
598 if(aDist > aTolV) {
599 Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
600
601 if(anExt.IsDone()) {
602 Extrema_POnCurv aPOncurve = anExt.Point();
603 aT = aPOncurve.Parameter();
604
605 if((aT > (aLast + aFirst) * 0.5) ||
606 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
607 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
608 aT = aFirst;
609 }
610 }
611 //
612 return Standard_True;
613 }
614 }
615 //
616 if (!Precision::IsInfinite(aLast)) {
617 gp_Pnt aPCLast=aC3D->Value(aLast);
618 aDist=aPv.Distance(aPCLast);
619 if (aDist < aTolSum) {
620 aT=aLast;
621 //
622 if(aDist > aTolV) {
623 Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
624
625 if(anExt.IsDone()) {
626 Extrema_POnCurv aPOncurve = anExt.Point();
627 aT = aPOncurve.Parameter();
628
629 if((aT < (aLast + aFirst) * 0.5) ||
630 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
631 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
632 aT = aLast;
633 }
634 }
635 //
636 return Standard_True;
637 }
638 }
639 //
640 GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
641 aProjector.Perform(aPv);
642
643 aNbProj=aProjector.NbPoints();
644 if (!aNbProj) {
645 Handle(Geom_BoundedCurve) aBC=
646 Handle(Geom_BoundedCurve)::DownCast(aC3D);
647 if (!aBC.IsNull()) {
648 gp_Pnt aPStart=aBC->StartPoint();
649 gp_Pnt aPEnd =aBC->EndPoint();
650
651 aDist=aPv.Distance(aPStart);
652 if (aDist < aTolSum) {
653 aT=aFirst;
654 return Standard_True;
655 }
656
657 aDist=aPv.Distance(aPEnd);
658 if (aDist < aTolSum) {
659 aT=aLast;
660 return Standard_True;
661 }
662 }
663
664 return Standard_False;
665 }
666
667 aDist=aProjector.LowerDistance();
668
669 if (aDist > aTolSum) {
670 return Standard_False;
671 }
672
673 aT=aProjector.LowerDistanceParameter();
674
675 return Standard_True;
676}
677//=======================================================================
678//function : ProjectPointOnEdge
679//purpose :
680//=======================================================================
681 Standard_Boolean IntTools_Context::ProjectPointOnEdge(const gp_Pnt& aP,
682 const TopoDS_Edge& anEdge,
683 Standard_Real& aT)
684{
685 Standard_Integer aNbPoints;
686
687 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
688 aProjector.Perform(aP);
689
690 aNbPoints=aProjector.NbPoints();
691 if (aNbPoints) {
692 aT=aProjector.LowerDistanceParameter();
693 return Standard_True;
694 }
695 return Standard_False;
696}
697