1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Bnd_Box.hxx>
17 #include <Bnd_OBB.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Surface.hxx>
20 #include <BRepBndLib.hxx>
21 #include <BRepClass3d_SolidClassifier.hxx>
22 #include <Extrema_LocateExtPC.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2d_TrimmedCurve.hxx>
25 #include <Geom2dHatch_Hatcher.hxx>
26 #include <Geom2dHatch_Intersector.hxx>
27 #include <Geom_BoundedCurve.hxx>
28 #include <Geom_Curve.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <GeomAPI_ProjectPointOnCurve.hxx>
31 #include <GeomAPI_ProjectPointOnSurf.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <IntTools_Context.hxx>
35 #include <IntTools_Curve.hxx>
36 #include <IntTools_FClass2d.hxx>
37 #include <IntTools_SurfaceRangeLocalizeData.hxx>
38 #include <IntTools_Tools.hxx>
39 #include <Precision.hxx>
40 #include <Standard_Type.hxx>
41 #include <TopAbs_State.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Face.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopoDS_Solid.hxx>
48 #include <TopoDS_Vertex.hxx>
50 IMPLEMENT_STANDARD_RTTIEXT(IntTools_Context,Standard_Transient)
53 //=======================================================================
56 //=======================================================================
57 IntTools_Context::IntTools_Context()
59 myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
60 myFClass2dMap(100, myAllocator),
61 myProjPSMap(100, myAllocator),
62 myProjPCMap(100, myAllocator),
63 mySClassMap(100, myAllocator),
64 myProjPTMap(100, myAllocator),
65 myHatcherMap(100, myAllocator),
66 myProjSDataMap(100, myAllocator),
67 myBndBoxDataMap(100, myAllocator),
68 mySurfAdaptorMap(100, myAllocator),
69 myOBBMap(100, myAllocator),
71 myPOnSTolerance(1.e-12)
74 //=======================================================================
77 //=======================================================================
78 IntTools_Context::IntTools_Context
79 (const Handle(NCollection_BaseAllocator)& theAllocator)
81 myAllocator(theAllocator),
82 myFClass2dMap(100, myAllocator),
83 myProjPSMap(100, myAllocator),
84 myProjPCMap(100, myAllocator),
85 mySClassMap(100, myAllocator),
86 myProjPTMap(100, myAllocator),
87 myHatcherMap(100, myAllocator),
88 myProjSDataMap(100, myAllocator),
89 myBndBoxDataMap(100, myAllocator),
90 mySurfAdaptorMap(100, myAllocator),
91 myOBBMap(100, myAllocator),
93 myPOnSTolerance(1.e-12)
96 //=======================================================================
99 //=======================================================================
100 IntTools_Context::~IntTools_Context()
102 Standard_Address anAdr;
103 DataMapOfShapeAddress::Iterator aIt;
104 DataMapOfTransientAddress::Iterator aIt1;
106 IntTools_FClass2d* pFClass2d;
108 aIt.Initialize(myFClass2dMap);
109 for (; aIt.More(); aIt.Next()) {
111 pFClass2d=(IntTools_FClass2d*)anAdr;
112 (*pFClass2d).~IntTools_FClass2d();
113 myAllocator->Free(anAdr);
115 myFClass2dMap.Clear();
117 clearCachedPOnSProjectors();
119 GeomAPI_ProjectPointOnCurve* pProjPC;
120 aIt.Initialize(myProjPCMap);
121 for (; aIt.More(); aIt.Next()) {
123 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
124 (*pProjPC).~GeomAPI_ProjectPointOnCurve();
125 myAllocator->Free(anAdr);
130 BRepClass3d_SolidClassifier* pSC;
131 aIt.Initialize(mySClassMap);
132 for (; aIt.More(); aIt.Next()) {
134 pSC=(BRepClass3d_SolidClassifier*)anAdr;
135 (*pSC).~BRepClass3d_SolidClassifier();
136 myAllocator->Free(anAdr);
140 GeomAPI_ProjectPointOnCurve* pProjPT;
141 aIt1.Initialize(myProjPTMap);
142 for (; aIt1.More(); aIt1.Next()) {
144 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
145 (*pProjPT).~GeomAPI_ProjectPointOnCurve();
146 myAllocator->Free(anAdr);
150 Geom2dHatch_Hatcher* pHatcher;
151 aIt.Initialize(myHatcherMap);
152 for (; aIt.More(); aIt.Next()) {
154 pHatcher=(Geom2dHatch_Hatcher*)anAdr;
155 (*pHatcher).~Geom2dHatch_Hatcher();
156 myAllocator->Free(anAdr);
158 myHatcherMap.Clear();
160 IntTools_SurfaceRangeLocalizeData* pSData = NULL;
161 aIt.Initialize(myProjSDataMap);
162 for (; aIt.More(); aIt.Next()) {
164 pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
165 (*pSData).~IntTools_SurfaceRangeLocalizeData();
166 myAllocator->Free(anAdr);
168 myProjSDataMap.Clear();
171 aIt.Initialize(myBndBoxDataMap);
172 for (; aIt.More(); aIt.Next()) {
174 pBox=(Bnd_Box*)anAdr;
176 myAllocator->Free(anAdr);
178 myBndBoxDataMap.Clear();
180 BRepAdaptor_Surface* pSurfAdaptor;
181 aIt.Initialize(mySurfAdaptorMap);
182 for (; aIt.More(); aIt.Next()) {
184 pSurfAdaptor=(BRepAdaptor_Surface*)anAdr;
185 (*pSurfAdaptor).~BRepAdaptor_Surface();
186 myAllocator->Free(anAdr);
188 mySurfAdaptorMap.Clear();
191 aIt.Initialize(myOBBMap);
192 for (; aIt.More(); aIt.Next()) {
194 pOBB=(Bnd_OBB*)anAdr;
196 myAllocator->Free(anAdr);
200 //=======================================================================
203 //=======================================================================
204 Bnd_Box& IntTools_Context::BndBox(const TopoDS_Shape& aS)
206 Standard_Address anAdr;
209 if (!myBndBoxDataMap.IsBound(aS)) {
211 pBox=(Bnd_Box*)myAllocator->Allocate(sizeof(Bnd_Box));
212 new (pBox) Bnd_Box();
215 BRepBndLib::Add(aS, aBox);
217 anAdr=(Standard_Address)pBox;
218 myBndBoxDataMap.Bind(aS, anAdr);
221 anAdr=myBndBoxDataMap.Find(aS);
222 pBox=(Bnd_Box*)anAdr;
226 //=======================================================================
227 //function : IsInfiniteFace
229 //=======================================================================
230 Standard_Boolean IntTools_Context::IsInfiniteFace
231 (const TopoDS_Face& aFace)
233 Standard_Boolean bRet;
239 if (!BRep_Tool::NaturalRestriction(aFace)) {
243 Bnd_Box& aBox=BndBox(aFace);
245 aBox.Get(aX[0], aX[1], aX[2], aX[3], aX[4], aX[5]);
247 for (i=0; (i<6) && (!bRet); ++i) {
248 bRet=Precision::IsInfinite(aX[i]);
253 //=======================================================================
254 //function : FClass2d
256 //=======================================================================
257 IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
259 Standard_Address anAdr;
260 IntTools_FClass2d* pFClass2d;
262 if (!myFClass2dMap.IsBound(aF)) {
267 aFF.Orientation(TopAbs_FORWARD);
268 aTolF=BRep_Tool::Tolerance(aFF);
270 pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d));
271 new (pFClass2d) IntTools_FClass2d(aFF, aTolF);
273 anAdr=(Standard_Address)pFClass2d;
274 myFClass2dMap.Bind(aFF, anAdr);
277 anAdr=myFClass2dMap.Find(aF);
278 pFClass2d=(IntTools_FClass2d*)anAdr;
282 //=======================================================================
285 //=======================================================================
286 GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
288 Standard_Address anAdr;
289 GeomAPI_ProjectPointOnSurf* pProjPS;
291 if (!myProjPSMap.IsBound(aF)) {
292 Standard_Real Umin, Usup, Vmin, Vsup;
293 UVBounds(aF, Umin, Usup, Vmin, Vsup);
294 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
296 pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf));
297 new (pProjPS) GeomAPI_ProjectPointOnSurf();
298 pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, myPOnSTolerance);
299 pProjPS->SetExtremaFlag(Extrema_ExtFlag_MIN);
301 anAdr=(Standard_Address)pProjPS;
302 myProjPSMap.Bind(aF, anAdr);
306 anAdr=myProjPSMap.Find(aF);
307 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
311 //=======================================================================
314 //=======================================================================
315 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPC(const TopoDS_Edge& aE)
317 Standard_Address anAdr;
318 GeomAPI_ProjectPointOnCurve* pProjPC;
320 if (!myProjPCMap.IsBound(aE)) {
323 Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l);
325 pProjPC=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
326 new (pProjPC) GeomAPI_ProjectPointOnCurve();
327 pProjPC->Init(aC3D, f, l);
329 anAdr=(Standard_Address)pProjPC;
330 myProjPCMap.Bind(aE, anAdr);
334 anAdr=myProjPCMap.Find(aE);
335 pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
340 //=======================================================================
343 //=======================================================================
344 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPT
345 (const Handle(Geom_Curve)& aC3D)
348 Standard_Address anAdr;
349 GeomAPI_ProjectPointOnCurve* pProjPT;
351 if (!myProjPTMap.IsBound(aC3D)) {
353 f=aC3D->FirstParameter();
354 l=aC3D->LastParameter();
356 pProjPT=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
357 new (pProjPT) GeomAPI_ProjectPointOnCurve();
358 pProjPT->Init(aC3D, f, l);
360 anAdr=(Standard_Address)pProjPT;
361 myProjPTMap.Bind(aC3D, anAdr);
365 anAdr=myProjPTMap.Find(aC3D);
366 pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
370 //=======================================================================
371 //function : SolidClassifier
373 //=======================================================================
374 BRepClass3d_SolidClassifier& IntTools_Context::SolidClassifier
375 (const TopoDS_Solid& aSolid)
377 Standard_Address anAdr;
378 BRepClass3d_SolidClassifier* pSC;
380 if (!mySClassMap.IsBound(aSolid)) {
382 pSC=(BRepClass3d_SolidClassifier*)myAllocator->Allocate(sizeof(BRepClass3d_SolidClassifier));
383 new (pSC) BRepClass3d_SolidClassifier(aSolid);
385 anAdr=(Standard_Address)pSC;
386 mySClassMap.Bind(aSolid, anAdr);
390 anAdr=mySClassMap.Find(aSolid);
391 pSC =(BRepClass3d_SolidClassifier*)anAdr;
396 //=======================================================================
397 //function : SurfaceAdaptor
399 //=======================================================================
400 BRepAdaptor_Surface& IntTools_Context::SurfaceAdaptor
401 (const TopoDS_Face& theFace)
403 Standard_Address anAdr;
404 BRepAdaptor_Surface* pBAS;
406 if (!mySurfAdaptorMap.IsBound(theFace)) {
408 pBAS=(BRepAdaptor_Surface*)myAllocator->Allocate(sizeof(BRepAdaptor_Surface));
409 new (pBAS) BRepAdaptor_Surface(theFace, Standard_True);
411 anAdr=(Standard_Address)pBAS;
412 mySurfAdaptorMap.Bind(theFace, anAdr);
416 anAdr=mySurfAdaptorMap.Find(theFace);
417 pBAS =(BRepAdaptor_Surface*)anAdr;
422 //=======================================================================
425 //=======================================================================
426 Geom2dHatch_Hatcher& IntTools_Context::Hatcher(const TopoDS_Face& aF)
428 Standard_Address anAdr;
429 Geom2dHatch_Hatcher* pHatcher;
431 if (!myHatcherMap.IsBound(aF)) {
432 Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
433 Standard_Real aU1, aU2, aEpsT;
434 TopAbs_Orientation aOrE;
435 Handle(Geom_Surface) aS;
436 Handle(Geom2d_Curve) aC2D;
437 Handle(Geom2d_TrimmedCurve) aCT2D;
439 TopExp_Explorer aExp;
444 aTolTangfIntr=1.e-10;
445 aEpsT=Precision::PConfusion();
447 Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr);
448 pHatcher=(Geom2dHatch_Hatcher*)
449 myAllocator->Allocate(sizeof(Geom2dHatch_Hatcher));
450 new (pHatcher) Geom2dHatch_Hatcher(aIntr,
451 aTolHatch2D, aTolHatch3D,
452 Standard_True, Standard_False);
455 aFF.Orientation(TopAbs_FORWARD);
456 aS=BRep_Tool::Surface(aFF);
458 aExp.Init (aFF, TopAbs_EDGE);
459 for (; aExp.More() ; aExp.Next()) {
460 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
461 aOrE=aE.Orientation();
463 aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
464 if (aC2D.IsNull() ) {
467 if (fabs(aU1-aU2) < aEpsT) {
471 aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
472 Geom2dAdaptor_Curve aGAC (aCT2D);
473 pHatcher->AddElement(aGAC, aOrE);
474 }// for (; aExp.More() ; aExp.Next()) {
476 anAdr=(Standard_Address)pHatcher;
477 myHatcherMap.Bind(aFF, anAdr);
478 }//if (!myHatcherMap.IsBound(aF)) {
481 anAdr=myHatcherMap.Find(aF);
482 pHatcher=(Geom2dHatch_Hatcher*)anAdr;
488 //=======================================================================
491 //=======================================================================
492 Bnd_OBB& IntTools_Context::OBB(const TopoDS_Shape& aS,
493 const Standard_Real theGap)
495 Standard_Address anAdr;
498 if (!myOBBMap.IsBound(aS))
500 pBox = (Bnd_OBB*)myAllocator->Allocate(sizeof(Bnd_OBB));
501 new (pBox) Bnd_OBB();
503 Bnd_OBB &aBox = *pBox;
504 BRepBndLib::AddOBB(aS, aBox);
505 aBox.Enlarge(theGap);
507 anAdr = (Standard_Address)pBox;
508 myOBBMap.Bind(aS, anAdr);
512 anAdr = myOBBMap.Find(aS);
513 pBox = (Bnd_OBB*)anAdr;
518 //=======================================================================
519 //function : SurfaceData
521 //=======================================================================
522 IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData
523 (const TopoDS_Face& aF)
525 Standard_Address anAdr;
526 IntTools_SurfaceRangeLocalizeData* pSData;
528 if (!myProjSDataMap.IsBound(aF)) {
529 pSData=(IntTools_SurfaceRangeLocalizeData*)
530 myAllocator->Allocate(sizeof(IntTools_SurfaceRangeLocalizeData));
531 new (pSData) IntTools_SurfaceRangeLocalizeData
534 10. * Precision::PConfusion(),
535 10. * Precision::PConfusion());
537 anAdr=(Standard_Address)pSData;
538 myProjSDataMap.Bind(aF, anAdr);
542 anAdr=myProjSDataMap.Find(aF);
543 pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr;
549 //=======================================================================
550 //function : ComputePE
552 //=======================================================================
553 Standard_Integer IntTools_Context::ComputePE
555 const Standard_Real aTolP1,
556 const TopoDS_Edge& aE2,
558 Standard_Real& aDist)
560 if (!BRep_Tool::IsGeometric(aE2)) {
563 Standard_Real aTolE2, aTolSum;
564 Standard_Integer aNbProj;
566 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
567 aProjector.Perform(aP1);
569 aNbProj=aProjector.NbPoints();
572 // point falls on the curve
573 aDist = aProjector.LowerDistance();
575 aTolE2 = BRep_Tool::Tolerance(aE2);
576 aTolSum = aTolP1 + aTolE2 + Precision::Confusion();
578 aT = aProjector.LowerDistanceParameter();
579 if (aDist > aTolSum) {
585 // point falls out of the curve, check distance to vertices
586 TopoDS_Edge aEFwd = TopoDS::Edge(aE2.Oriented(TopAbs_FORWARD));
587 TopoDS_Iterator itV(aEFwd);
589 for (; itV.More(); itV.Next())
591 const TopoDS_Vertex& aV = TopoDS::Vertex(itV.Value());
592 if (aV.Orientation() == TopAbs_FORWARD || aV.Orientation() == TopAbs_REVERSED)
594 gp_Pnt aPV = BRep_Tool::Pnt(aV);
595 aTolSum = aTolP1 + BRep_Tool::Tolerance(aV) + Precision::Confusion();
596 Standard_Real aDist1 = aP1.SquareDistance(aPV);
597 if (aDist1 < aDist && aDist1 < Square(aTolSum))
600 aT = BRep_Tool::Parameter(aV, aEFwd);
604 if (Precision::IsInfinite(aDist)) {
610 //=======================================================================
611 //function : ComputeVE
613 //=======================================================================
614 Standard_Integer IntTools_Context::ComputeVE
615 (const TopoDS_Vertex& theV,
616 const TopoDS_Edge& theE,
618 Standard_Real& theTol,
619 const Standard_Real theFuzz)
621 if (BRep_Tool::Degenerated(theE)) {
624 if (!BRep_Tool::IsGeometric(theE)) {
627 Standard_Real aDist, aTolV, aTolE, aTolSum;
628 Standard_Integer aNbProj;
631 aP=BRep_Tool::Pnt(theV);
633 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(theE);
634 aProjector.Perform(aP);
636 aNbProj=aProjector.NbPoints();
641 aDist=aProjector.LowerDistance();
643 aTolV=BRep_Tool::Tolerance(theV);
644 aTolE=BRep_Tool::Tolerance(theE);
645 aTolSum = aTolV + aTolE + Max(theFuzz, Precision::Confusion());
647 theTol = aDist + aTolE;
648 theT = aProjector.LowerDistanceParameter();
649 if (aDist > aTolSum) {
654 //=======================================================================
655 //function : ComputeVF
657 //=======================================================================
658 Standard_Integer IntTools_Context::ComputeVF
659 (const TopoDS_Vertex& theVertex,
660 const TopoDS_Face& theFace,
663 Standard_Real& theTol,
664 const Standard_Real theFuzz)
666 Standard_Real aTolV, aTolF, aTolSum, aDist;
669 aP = BRep_Tool::Pnt(theVertex);
671 // 1. Check if the point is projectable on the surface
672 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(theFace);
673 aProjector.Perform(aP);
675 if (!aProjector.IsDone()) { // the point is not projectable on the surface
679 // 2. Check the distance between the projection point and
680 // the original point
681 aDist = aProjector.LowerDistance();
683 aTolV = BRep_Tool::Tolerance(theVertex);
684 aTolF = BRep_Tool::Tolerance(theFace);
686 aTolSum = aTolV + aTolF + Max(theFuzz, Precision::Confusion());
687 theTol = aDist + aTolF;
688 aProjector.LowerDistanceParameters(theU, theV);
690 if (aDist > aTolSum) {
691 // the distance is too large
695 gp_Pnt2d aP2d(theU, theV);
696 Standard_Boolean pri = IsPointInFace (theFace, aP2d);
697 if (!pri) {// the point lays on the surface but out of the face
702 //=======================================================================
703 //function : StatePointFace
705 //=======================================================================
706 TopAbs_State IntTools_Context::StatePointFace
707 (const TopoDS_Face& aF,
708 const gp_Pnt2d& aP2d)
711 IntTools_FClass2d& aClass2d=FClass2d(aF);
712 aState=aClass2d.Perform(aP2d);
715 //=======================================================================
716 //function : IsPointInFace
718 //=======================================================================
719 Standard_Boolean IntTools_Context::IsPointInFace
720 (const TopoDS_Face& aF,
721 const gp_Pnt2d& aP2d)
723 TopAbs_State aState=StatePointFace(aF, aP2d);
724 if (aState==TopAbs_OUT || aState==TopAbs_ON) {
725 return Standard_False;
727 return Standard_True;
729 //=======================================================================
730 //function : IsPointInFace
732 //=======================================================================
733 Standard_Boolean IntTools_Context::IsPointInFace
735 const TopoDS_Face& aF,
736 const Standard_Real aTol)
738 Standard_Boolean bIn;
741 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
742 aProjector.Perform(aP);
744 bIn = aProjector.IsDone();
746 aDist = aProjector.LowerDistance();
750 aProjector.LowerDistanceParameters(U, V);
752 bIn = IsPointInFace(aF, aP2D);
758 //=======================================================================
759 //function : IsPointInOnFace
761 //=======================================================================
762 Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
763 const gp_Pnt2d& aP2d)
765 TopAbs_State aState=StatePointFace(aF, aP2d);
766 if (aState==TopAbs_OUT) {
767 return Standard_False;
769 return Standard_True;
771 //=======================================================================
772 //function : IsValidPointForFace
774 //=======================================================================
775 Standard_Boolean IntTools_Context::IsValidPointForFace
777 const TopoDS_Face& aF,
778 const Standard_Real aTol)
780 Standard_Boolean bFlag;
781 Standard_Real Umin, U, V;
783 GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
784 aProjector.Perform(aP);
786 bFlag=aProjector.IsDone();
789 Umin=aProjector.LowerDistance();
790 //if (Umin > 1.e-3) { // it was
795 aProjector.LowerDistanceParameters(U, V);
797 bFlag=IsPointInOnFace (aF, aP2D);
801 //=======================================================================
802 //function : IsValidPointForFaces
804 //=======================================================================
805 Standard_Boolean IntTools_Context::IsValidPointForFaces
807 const TopoDS_Face& aF1,
808 const TopoDS_Face& aF2,
809 const Standard_Real aTol)
811 Standard_Boolean bFlag1, bFlag2;
813 bFlag1=IsValidPointForFace(aP, aF1, aTol);
817 bFlag2=IsValidPointForFace(aP, aF2, aTol);
820 //=======================================================================
821 //function : IsValidBlockForFace
823 //=======================================================================
824 Standard_Boolean IntTools_Context::IsValidBlockForFace
825 (const Standard_Real aT1,
826 const Standard_Real aT2,
827 const IntTools_Curve& aC,
828 const TopoDS_Face& aF,
829 const Standard_Real aTol)
831 Standard_Boolean bFlag;
832 Standard_Real aTInterm;
835 aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
837 Handle(Geom_Curve) aC3D=aC.Curve();
839 aC3D->D0(aTInterm, aPInterm);
841 bFlag=IsValidPointForFace (aPInterm, aF, aTol);
844 //=======================================================================
845 //function : IsValidBlockForFaces
847 //=======================================================================
848 Standard_Boolean IntTools_Context::IsValidBlockForFaces(const Standard_Real theT1,
849 const Standard_Real theT2,
850 const IntTools_Curve& theC,
851 const TopoDS_Face& theF1,
852 const TopoDS_Face& theF2,
853 const Standard_Real theTol)
855 const Standard_Integer aNbElem = 2;
856 const Handle(Geom2d_Curve) &aPC1 = theC.FirstCurve2d();
857 const Handle(Geom2d_Curve) &aPC2 = theC.SecondCurve2d();
858 const Handle(Geom_Curve) &aC3D = theC.Curve();
860 const Handle(Geom2d_Curve)* anArrPC[aNbElem] = { &aPC1, &aPC2 };
861 const TopoDS_Face* anArrF[aNbElem] = { &theF1, &theF2 };
863 const Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(theT1, theT2);
864 const gp_Pnt aP(aC3D->Value(aMidPar));
866 Standard_Boolean bFlag = Standard_True;
869 for (Standard_Integer i = 0; (i < 2) && bFlag; ++i)
871 const Handle(Geom2d_Curve) &aPC = *anArrPC[i];
872 const TopoDS_Face &aF = *anArrF[i];
876 aPC->D0(aMidPar, aPnt2D);
877 bFlag = IsPointInOnFace(aF, aPnt2D);
881 bFlag = IsValidPointForFace(aP, aF, theTol);
887 //=======================================================================
888 //function : IsVertexOnLine
890 //=======================================================================
891 Standard_Boolean IntTools_Context::IsVertexOnLine
892 (const TopoDS_Vertex& aV,
893 const IntTools_Curve& aC,
894 const Standard_Real aTolC,
897 Standard_Boolean bRet;
900 aTolV=BRep_Tool::Tolerance(aV);
901 bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
905 //=======================================================================
906 //function : IsVertexOnLine
908 //=======================================================================
909 Standard_Boolean IntTools_Context::IsVertexOnLine
910 (const TopoDS_Vertex& aV,
911 const Standard_Real aTolV,
912 const IntTools_Curve& aC,
913 const Standard_Real aTolC,
916 Standard_Real aFirst, aLast, aDist, aTolSum;
917 Standard_Integer aNbProj;
920 aPv=BRep_Tool::Pnt(aV);
922 Handle(Geom_Curve) aC3D=aC.Curve();
927 GeomAdaptor_Curve aGAC(aC3D);
928 GeomAbs_CurveType aType=aGAC.GetType();
929 if (aType==GeomAbs_BSplineCurve ||
930 aType==GeomAbs_BezierCurve) {
937 aTolSum=2.*aTolSum;//xft
942 aFirst=aC3D->FirstParameter();
943 aLast =aC3D->LastParameter();
945 // Checking extermities first
946 // It is necessary to chose the closest bound to the point
947 Standard_Boolean bFirstValid = Standard_False;
948 Standard_Real aFirstDist = Precision::Infinite();
950 if (!Precision::IsInfinite(aFirst)) {
951 gp_Pnt aPCFirst=aC3D->Value(aFirst);
952 aFirstDist = aPv.Distance(aPCFirst);
953 if (aFirstDist < aTolSum) {
954 bFirstValid = Standard_True;
957 if (aFirstDist > aTolV) {
958 Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
961 Extrema_POnCurv aPOncurve = anExt.Point();
962 aT = aPOncurve.Parameter();
964 if((aT > (aLast + aFirst) * 0.5) ||
965 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
966 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
971 // Local search may fail. Try to use more precise algo.
972 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
973 Standard_Real aMinDist = RealLast();
974 Standard_Integer aMinIdx = -1;
975 if (anExt2.IsDone()) {
976 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
978 if ( anExt2.IsMin(anIdx) &&
979 anExt2.SquareDistance(anIdx) < aMinDist )
981 aMinDist = anExt2.SquareDistance(anIdx);
988 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
989 aT = aPOncurve.Parameter();
991 if((aT > (aLast + aFirst) * 0.5) ||
992 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
993 (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
1002 if (!Precision::IsInfinite(aLast)) {
1003 gp_Pnt aPCLast=aC3D->Value(aLast);
1004 aDist=aPv.Distance(aPCLast);
1005 if (bFirstValid && (aFirstDist < aDist)) {
1006 return Standard_True;
1009 if (aDist < aTolSum) {
1013 Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
1015 if(anExt.IsDone()) {
1016 Extrema_POnCurv aPOncurve = anExt.Point();
1017 aT = aPOncurve.Parameter();
1019 if((aT < (aLast + aFirst) * 0.5) ||
1020 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
1021 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
1026 // Local search may fail. Try to use more precise algo.
1027 Extrema_ExtPC anExt2(aPv, aGAC, 1.e-10);
1028 Standard_Real aMinDist = RealLast();
1029 Standard_Integer aMinIdx = -1;
1030 if (anExt2.IsDone()) {
1031 for (Standard_Integer anIdx = 1; anIdx <= anExt2.NbExt(); anIdx++)
1033 if ( anExt2.IsMin(anIdx) &&
1034 anExt2.SquareDistance(anIdx) < aMinDist )
1036 aMinDist = anExt2.SquareDistance(anIdx);
1043 const Extrema_POnCurv& aPOncurve = anExt2.Point(aMinIdx);
1044 aT = aPOncurve.Parameter();
1046 if((aT < (aLast + aFirst) * 0.5) ||
1047 (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
1048 (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
1054 return Standard_True;
1057 else if (bFirstValid) {
1058 return Standard_True;
1061 GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
1062 aProjector.Perform(aPv);
1064 aNbProj=aProjector.NbPoints();
1066 Handle(Geom_BoundedCurve) aBC=
1067 Handle(Geom_BoundedCurve)::DownCast(aC3D);
1068 if (!aBC.IsNull()) {
1069 gp_Pnt aPStart=aBC->StartPoint();
1070 gp_Pnt aPEnd =aBC->EndPoint();
1072 aDist=aPv.Distance(aPStart);
1073 if (aDist < aTolSum) {
1075 return Standard_True;
1078 aDist=aPv.Distance(aPEnd);
1079 if (aDist < aTolSum) {
1081 return Standard_True;
1085 return Standard_False;
1088 aDist=aProjector.LowerDistance();
1090 if (aDist > aTolSum) {
1091 return Standard_False;
1094 aT=aProjector.LowerDistanceParameter();
1096 return Standard_True;
1098 //=======================================================================
1099 //function : ProjectPointOnEdge
1101 //=======================================================================
1102 Standard_Boolean IntTools_Context::ProjectPointOnEdge
1104 const TopoDS_Edge& anEdge,
1107 Standard_Integer aNbPoints;
1109 GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
1110 aProjector.Perform(aP);
1112 aNbPoints=aProjector.NbPoints();
1114 aT=aProjector.LowerDistanceParameter();
1115 return Standard_True;
1117 return Standard_False;
1120 //=======================================================================
1121 //function : SetPOnSProjectionTolerance
1123 //=======================================================================
1124 void IntTools_Context::SetPOnSProjectionTolerance(const Standard_Real theValue)
1126 myPOnSTolerance = theValue;
1127 clearCachedPOnSProjectors();
1130 //=======================================================================
1131 //function : clearCachedPOnSProjectors
1133 //=======================================================================
1134 void IntTools_Context::clearCachedPOnSProjectors()
1136 GeomAPI_ProjectPointOnSurf* pProjPS;
1137 DataMapOfShapeAddress::Iterator aIt(myProjPSMap);
1138 for (; aIt.More(); aIt.Next()) {
1139 Standard_Address anAdr=aIt.Value();
1140 pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
1141 (*pProjPS).~GeomAPI_ProjectPointOnSurf();
1142 myAllocator->Free(anAdr);
1144 myProjPSMap.Clear();
1147 //=======================================================================
1148 //function : UVBounds
1150 //=======================================================================
1151 void IntTools_Context::UVBounds(const TopoDS_Face& theFace,
1152 Standard_Real& UMin,
1153 Standard_Real& UMax,
1154 Standard_Real& VMin,
1155 Standard_Real& VMax)
1157 const BRepAdaptor_Surface& aBAS = SurfaceAdaptor(theFace);
1158 UMin = aBAS.FirstUParameter();
1159 UMax = aBAS.LastUParameter ();
1160 VMin = aBAS.FirstVParameter();
1161 VMax = aBAS.LastVParameter ();