1 // Created on: 2000-11-16
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <IntTools_Tools.ixx>
18 #include <Precision.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopLoc_Location.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <BRepAdaptor_Surface.hxx>
38 #include <gp_Pnt2d.hxx>
44 #include <Geom_Curve.hxx>
45 #include <GeomAdaptor_Surface.hxx>
46 #include <Geom_Surface.hxx>
47 #include <GeomAPI_ProjectPointOnSurf.hxx>
48 #include <GeomAPI_ProjectPointOnCurve.hxx>
49 #include <GeomAdaptor_Curve.hxx>
50 #include <GeomAbs_CurveType.hxx>
51 #include <Geom_Line.hxx>
52 #include <Geom2d_Curve.hxx>
53 #include <Geom_BoundedCurve.hxx>
54 #include <Geom_Geometry.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <Geom2d_TrimmedCurve.hxx>
58 #include <IntTools_FClass2d.hxx>
59 #include <IntTools_Curve.hxx>
60 #include <IntTools_SequenceOfCurves.hxx>
63 void ParabolaTolerance(const Handle(Geom_Curve)& ,
70 //=======================================================================
71 //function : HasInternalEdge
73 //=======================================================================
74 Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW)
76 Standard_Boolean bFlag=Standard_True;
78 TopExp_Explorer anExp(aW, TopAbs_EDGE);
79 for (; anExp.More(); anExp.Next()) {
80 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
81 TopAbs_Orientation anOr=aE.Orientation();
82 if (anOr==TopAbs_INTERNAL) {
89 //=======================================================================
92 //=======================================================================
93 Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D)
95 Standard_Boolean bRet;
96 Standard_Real aF, aL, aDist, aPC;
99 Handle (Geom_BoundedCurve) aGBC=
100 Handle (Geom_BoundedCurve)::DownCast(aC3D);
102 return Standard_False;
105 aF=aC3D->FirstParameter();
106 aL=aC3D-> LastParameter();
113 aPC=Precision::Confusion();
115 aDist=aP1.SquareDistance(aP2);
120 //=======================================================================
121 //function : RejectLines
123 //=======================================================================
124 void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn,
125 IntTools_SequenceOfCurves& aSOut)
127 Standard_Integer i, j, aNb;
128 Standard_Boolean bFlag;
129 Handle (Geom_Curve) aC3D;
136 for (i=1; i<=aNb; i++) {
137 const IntTools_Curve& IC=aSIn(i);
140 Handle (Geom_TrimmedCurve) aGTC=
141 Handle (Geom_TrimmedCurve)::DownCast(aC3D);
143 if (!aGTC.IsNull()) {
144 aC3D=aGTC->BasisCurve();
145 IntTools_Curve* pIC=(IntTools_Curve*) &IC;
149 Handle (Geom_Line) aGLine=
150 Handle (Geom_Line)::DownCast(aC3D);
152 if (aGLine.IsNull()) {
154 for (j=1; j<=aNb; j++) {
155 aSOut.Append(aSIn(j));
160 gp_Lin aLin=aGLine->Lin();
161 aD2=aLin.Direction();
168 bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2);
176 //=======================================================================
177 //function : IsDirsCoinside
179 //=======================================================================
180 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2)
182 Standard_Boolean bFlag;
183 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
184 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
185 Standard_Real dLim=0.0002, d;
187 bFlag= (d<dLim || fabs (2.-d)<dLim);
191 //=======================================================================
192 //function : IsDirsCoinside
194 //=======================================================================
195 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1,
197 const Standard_Real dLim)
199 Standard_Boolean bFlag;
202 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
203 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
205 bFlag= (d<dLim || fabs (2.-d)<dLim);
208 //=======================================================================
209 //function : SplitCurve
211 //=======================================================================
212 Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC,
213 IntTools_SequenceOfCurves& aCvs)
215 Handle (Geom_Curve) aC3D =IC.Curve();
219 Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d();
220 Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d();
221 Standard_Boolean bIsClosed;
223 bIsClosed=IntTools_Tools::IsClosed(aC3D);
228 Standard_Real aF, aL, aMid;
231 aF=aC3D->FirstParameter();
232 aL=aC3D->LastParameter();
234 GeomAdaptor_Curve aGAC(aC3D);
235 GeomAbs_CurveType aCT=aGAC.GetType();
236 if (aCT==GeomAbs_BSplineCurve ||
237 aCT==GeomAbs_BezierCurve) {
239 aMid=IntTools_Tools::IntermediatePoint(aF, aL);
242 Handle(Geom_Curve) aC3DNewF, aC3DNewL;
243 aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid);
244 aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL);
247 Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L;
249 if(!aC2D1.IsNull()) {
250 aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid);
251 aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL);
254 if(!aC2D2.IsNull()) {
255 aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid);
256 aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL);
260 IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F);
261 IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L);
270 //=======================================================================
271 //function : IntermediatePoint
273 //=======================================================================
274 Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst,
275 const Standard_Real aLast)
277 //define parameter division number as 10*e^(-M_PI) = 0.43213918
278 const Standard_Real PAR_T = 0.43213918;
280 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
284 //=======================================================================
285 //function : IsVertex
287 //=======================================================================
288 Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP,
289 const Standard_Real aTolPV,
290 const TopoDS_Vertex& aV)
292 Standard_Boolean bRet;
293 Standard_Real aTolV, aD, dTol;
296 aTolV=BRep_Tool::Tolerance(aV);
298 dTol=Precision::Confusion();
299 aTolV=aTolV+aTolPV+dTol;
301 aPv=BRep_Tool::Pnt(aV);
303 aD=aPv.SquareDistance(aP);
310 //=======================================================================
311 //function : IsVertex
313 //=======================================================================
314 Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt)
316 Standard_Boolean anIsVertex;
317 Standard_Real aParam;
319 const TopoDS_Edge& aE1=aCmnPrt.Edge1();
320 const IntTools_Range& aR1=aCmnPrt.Range1();
321 aParam=0.5*(aR1.First()+aR1.Last());
322 anIsVertex=IntTools_Tools::IsVertex (aE1, aParam);
325 return Standard_True;
328 const TopoDS_Edge& aE2=aCmnPrt.Edge2();
329 const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2();
330 const IntTools_Range& aR2=aRs2(1);
331 aParam=0.5*(aR2.First()+aR2.Last());
332 anIsVertex=IntTools_Tools::IsVertex (aE2, aParam);
334 return Standard_True;
336 return Standard_False;
339 //=======================================================================
340 //function : IsVertex
342 //=======================================================================
343 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
344 const TopoDS_Vertex& aV,
345 const Standard_Real t)
347 Standard_Real aTolV, aTolV2, d2;
350 BRepAdaptor_Curve aBAC(aE);
353 aTolV=BRep_Tool::Tolerance(aV);
355 aPv=BRep_Tool::Pnt(aV);
356 d2=aPv.SquareDistance (aPt);
358 return Standard_True;
360 return Standard_False;
362 //=======================================================================
363 //function : IsVertex
365 //=======================================================================
366 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
367 const Standard_Real t)
369 Standard_Real aTolV, aTolV2, d2;
373 BRepAdaptor_Curve aBAC(aE);
376 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
377 for (; anExp.More(); anExp.Next()) {
378 aV=TopoDS::Vertex (anExp.Current());
379 aTolV=BRep_Tool::Tolerance(aV);
382 aPv=BRep_Tool::Pnt(aV);
383 d2=aPv.SquareDistance (aPt);
385 return Standard_True;
388 return Standard_False;
392 //=======================================================================
393 //function : ComputeVV
395 //=======================================================================
396 Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1,
397 const TopoDS_Vertex& aV2)
399 Standard_Real aTolV1, aTolV2, aTolSum, d;
402 aTolV1=BRep_Tool::Tolerance(aV1);
403 aTolV2=BRep_Tool::Tolerance(aV2);
404 aTolSum=aTolV1+aTolV2;
406 aP1=BRep_Tool::Pnt(aV1);
407 aP2=BRep_Tool::Pnt(aV2);
408 aTolSum=aTolSum*aTolSum;
409 d=aP1.SquareDistance(aP2);
416 //=======================================================================
417 //function : MakeFaceFromWireAndFace
419 //=======================================================================
420 void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW,
421 const TopoDS_Face& aF,
426 aFF.Orientation(TopAbs_FORWARD);
427 aFNew=TopoDS::Face (aFF.EmptyCopied());
432 //=======================================================================
433 //function : ClassifyPointByFace
435 //=======================================================================
436 TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
437 const gp_Pnt2d& aP2d)
439 Standard_Real aFaceTolerance;
442 aFaceTolerance=BRep_Tool::Tolerance(aF);
443 IntTools_FClass2d aClass2d(aF, aFaceTolerance);
444 aState=aClass2d.Perform(aP2d);
449 //=======================================================================
450 //function : IsMiddlePointsEqual
452 //=======================================================================
453 Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1,
454 const TopoDS_Edge& aE2)
457 Standard_Boolean bRet;
458 Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2;
461 aTol1=BRep_Tool::Tolerance(aE1);
462 Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1);
466 aTol2=BRep_Tool::Tolerance(aE2);
467 Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2);
472 aSumTol=aSumTol*aSumTol;
473 aD2=aP1.SquareDistance(aP2);
478 //=======================================================================
479 //function : CurveTolerance
481 //=======================================================================
482 Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D,
483 const Standard_Real aTolBase)
485 Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax;
487 aTolReached=aTolBase;
493 Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D);
494 if (aCT3D.IsNull()) {
501 aTf=aCT3D->FirstParameter();
502 aTl=aCT3D->LastParameter();
504 GeomAdaptor_Curve aGAC(aCT3D);
505 GeomAbs_CurveType aCType=aGAC.GetType();
507 if (aCType==GeomAbs_Parabola) {
508 Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve();
509 ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax);
516 #include <Geom_Parabola.hxx>
517 #include <gp_Parab.hxx>
518 #include <BndLib_Add3dCurve.hxx>
519 //=======================================================================
520 //function : ParabolaTolerance
522 //=======================================================================
523 void ParabolaTolerance(const Handle(Geom_Curve)& aC3D,
524 const Standard_Real aTf,
525 const Standard_Real aTl,
526 const Standard_Real aTol,
527 Standard_Real& aTolMin,
528 Standard_Real& aTolMax)
534 Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D);
539 Standard_Integer aNbPoints;
540 Standard_Real aFocal, aX1, aX2, aTol1, aTol2;
542 gp_Parab aParab=aGP->Parab();
543 gp_Ax1 aXAxis=aParab.XAxis();
544 Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis);
555 GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis);
556 aNbPoints=aProj1.NbPoints();
558 aX1=aProj1.LowerDistanceParameter();
561 aTol1=aTol*sqrt(0.5*aX1/aFocal);
571 GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis);
572 aNbPoints=aProj2.NbPoints();
574 aX2=aProj2.LowerDistanceParameter();
578 aTol2=aTol*sqrt(0.5*aX2/aFocal);
584 aTolMax=(aTol1>aTol2) ? aTol1 : aTol2;
585 aTolMin=(aTol1<aTol2) ? aTol1 : aTol2;
587 /////////////////////////////////////////////////////////////////////////
588 //=======================================================================
589 //function : CheckCurve
591 //=======================================================================
592 Standard_Boolean IntTools_Tools::CheckCurve(const Handle (Geom_Curve)& aC3D,
593 const Standard_Real aTolR3D,
596 Standard_Boolean bRet;
597 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dX, dY, dZ;
598 Standard_Real dS, aTol;
599 GeomAdaptor_Curve aGAC;
602 BndLib_Add3dCurve::Add(aGAC, aTolR3D, aBox);
604 aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
610 bRet=(dX>aTol || dY>aTol || dZ>aTol);
614 //=======================================================================
615 //function : IsOnPave
617 //=======================================================================
618 Standard_Boolean IntTools_Tools::IsOnPave(const Standard_Real aT1,
619 const IntTools_Range& aRange,
620 const Standard_Real aTolerance)
622 Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
624 firstisonpave1 = (Abs(aRange.First() - aT1) < aTolerance);
625 firstisonpave2 = (Abs(aRange.Last() - aT1) < aTolerance);
626 bIsOnPave=(firstisonpave1 || firstisonpave2);
629 //=======================================================================
630 // function: VertexParameters
632 //=======================================================================
633 void IntTools_Tools::VertexParameters(const IntTools_CommonPrt& aCPart,
637 const IntTools_Range& aR1=aCPart.Range1();
638 aT1=0.5*(aR1.First()+aR1.Last());
640 if((aCPart.VertexParameter1() >= aR1.First()) &&
641 (aCPart.VertexParameter1() <= aR1.Last())) {
642 aT1 = aCPart.VertexParameter1();
645 const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
646 const IntTools_Range& aR2=aRanges2(1);
647 aT2=0.5*(aR2.First()+aR2.Last());
649 if((aCPart.VertexParameter2() >= aR2.First()) &&
650 (aCPart.VertexParameter2() <= aR2.Last())) {
651 aT2 = aCPart.VertexParameter2();
654 //=======================================================================
655 // function: VertexParameter
657 //=======================================================================
658 void IntTools_Tools::VertexParameter(const IntTools_CommonPrt& aCPart,
661 const IntTools_Range& aR=aCPart.Range1();
662 aT=0.5*(aR.First()+aR.Last());
663 if((aCPart.VertexParameter1() >= aR.First()) &&
664 (aCPart.VertexParameter1() <= aR.Last())) {
665 aT = aCPart.VertexParameter1();
668 //=======================================================================
669 // function: IsOnPave1
671 //=======================================================================
672 Standard_Boolean IntTools_Tools::IsOnPave1(const Standard_Real aTR,
673 const IntTools_Range& aCPRange,
674 const Standard_Real aTolerance)
676 Standard_Boolean bIsOnPave;
677 Standard_Real aT1, aT2, dT1, dT2;
679 aT1=aCPRange.First();
681 bIsOnPave=(aTR>=aT1 && aTR<=aT1);
688 bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);
691 //=======================================================================
692 // function: IsInRange
694 //=======================================================================
695 Standard_Boolean IntTools_Tools::IsInRange(const IntTools_Range& aRRef,
696 const IntTools_Range& aR,
697 const Standard_Real aTolerance)
699 Standard_Boolean bIsIn;
700 Standard_Real aT1, aT2, aTRef1, aTRef2;
703 aRRef.Range(aTRef1, aTRef2);
708 bIsIn = (aT1>=aTRef1 && aT1<=aTRef2) ||
709 (aT2>=aTRef1 && aT2<=aTRef2);
713 //=======================================================================
716 //=======================================================================
717 Standard_Integer IntTools_Tools::SegPln(const gp_Lin& theLin,
718 const Standard_Real theTLin1,
719 const Standard_Real theTLin2,
720 const Standard_Real theTolLin,
721 const gp_Pln& thePln,
722 const Standard_Real theTolPln,
724 Standard_Real& theTP,
725 Standard_Real& theTolP,
726 Standard_Real& theTPmin,
727 Standard_Real& theTPmax)
729 Standard_Integer iRet;
730 Standard_Real aTol, aA, aB, aC, aD, aE, aH, aTP, aDist1, aDist2;
734 aTol=theTolLin+theTolPln;
736 const gp_Ax3& aPosPln=thePln.Position();
737 const gp_Dir& aDirPln=aPosPln.Direction();
738 const gp_Pnt& aLocPln=aPosPln.Location();
740 const gp_Dir& aDirLin=theLin.Direction();
741 const gp_Pnt& aLocLin=theLin.Location();
743 aP1.SetXYZ(aLocLin.XYZ()+theTLin1*aDirLin.XYZ());
744 aDist1=aDirPln.X()*(aP1.X()-aLocPln.X())+
745 aDirPln.Y()*(aP1.Y()-aLocPln.Y())+
746 aDirPln.Z()*(aP1.Z()-aLocPln.Z());
748 aP2.SetXYZ(aLocLin.XYZ()+theTLin2*aDirLin.XYZ());
749 aDist2=aDirPln.X()*(aP2.X()-aLocPln.X())+
750 aDirPln.Y()*(aP2.Y()-aLocPln.Y())+
751 aDirPln.Z()*(aP2.Z()-aLocPln.Z());
753 if (aDist1<aTol && aDist2<aTol){
754 iRet=1; // common block
758 if (aDist1*aDist2 > 0.) {
759 iRet=2; // segment lays on one side to the Plane
763 thePln.Coefficients(aA, aB, aC, aD);
764 aE=aA*aLocLin.X()+aB*aLocLin.Y()+aC*aLocLin.Z()+aD;
765 aH=aA*aDirLin.X()+aB*aDirLin.Y()+aC*aDirLin.Z();
767 if (aTP < theTLin1-aTol || aTP > theTLin2+aTol) {
768 iRet=3; // no intersections due to range of the Line
773 theP.SetXYZ(aLocLin.XYZ()+aTP*aDirLin.XYZ());
775 theTPmin=theTP-theTolPln;
776 theTPmax=theTP+theTolPln;
777 iRet=0; // intersection point
781 //=======================================================================
782 //function : AdjustPeriodic
784 //=======================================================================
785 Standard_Boolean IntTools_Tools::AdjustPeriodic(const Standard_Real thePar,
786 const Standard_Real theParMin,
787 const Standard_Real theParMax,
788 const Standard_Real thePeriod,
789 Standard_Real &theNewPar,
790 Standard_Real &theOffset,
791 const Standard_Real theEps)
793 Standard_Boolean bMin, bMax;
797 bMin = theParMin - thePar > theEps;
798 bMax = thePar - theParMax > theEps;
801 Standard_Real dp, aNbPer;
803 dp = (bMin) ? (theParMax - thePar) : (theParMin - thePar);
804 modf(dp / thePeriod, &aNbPer);
806 theOffset = aNbPer * thePeriod;
807 theNewPar += theOffset;
810 return (theOffset > 0.);