1 // Created on: 1995-01-27
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
19 #include <GeomInt_IntSS.ixx>
21 #include <GeomInt.hxx>
23 #include <Precision.hxx>
25 #include <gp_Pnt2d.hxx>
28 #include <TColStd_Array1OfReal.hxx>
29 #include <TColStd_Array1OfInteger.hxx>
30 #include <TColStd_Array1OfListOfInteger.hxx>
31 #include <TColStd_SequenceOfReal.hxx>
32 #include <TColStd_ListOfInteger.hxx>
33 #include <TColStd_ListIteratorOfListOfInteger.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColgp_Array1OfPnt2d.hxx>
38 #include <Adaptor3d_TopolTool.hxx>
39 #include <IntPatch_Line.hxx>
40 #include <IntPatch_WLine.hxx>
41 #include <IntPatch_GLine.hxx>
42 #include <IntPatch_RLine.hxx>
43 #include <IntPatch_ALineToWLine.hxx>
44 #include <IntPatch_IType.hxx>
45 #include <NCollection_IncAllocator.hxx>
46 #include <NCollection_List.hxx>
47 #include <NCollection_LocalArray.hxx>
48 #include <NCollection_StdAllocator.hxx>
51 #include <AppParCurves_MultiBSpCurve.hxx>
53 #include <GeomAbs_SurfaceType.hxx>
54 #include <GeomAbs_CurveType.hxx>
56 #include <GeomAdaptor.hxx>
57 #include <Geom_Curve.hxx>
58 #include <Geom_Line.hxx>
59 #include <Geom_Parabola.hxx>
60 #include <Geom_Hyperbola.hxx>
61 #include <Geom_TrimmedCurve.hxx>
62 #include <Geom_Circle.hxx>
63 #include <Geom_Ellipse.hxx>
64 #include <Geom_BSplineCurve.hxx>
66 #include <Geom2dAdaptor.hxx>
67 #include <Adaptor2d_HCurve2d.hxx>
68 #include <Geom2d_Curve.hxx>
69 #include <Geom2d_BSplineCurve.hxx>
70 #include <Geom2d_TrimmedCurve.hxx>
72 #include <GeomLib_CheckBSplineCurve.hxx>
73 #include <GeomLib_Check2dBSplineCurve.hxx>
74 #include <GeomProjLib.hxx>
75 #include <Approx_CurveOnSurface.hxx>
79 #include <GeomInt_WLApprox.hxx>
80 #include <Extrema_ExtPS.hxx>
82 #include <GeomAdaptor_HSurface.hxx>
83 #include <gp_Lin2d.hxx>
84 #include <Geom2d_Line.hxx>
85 #include <IntPatch_RLine.hxx>
86 #include <Geom2dAdaptor.hxx>
87 #include <Adaptor2d_HCurve2d.hxx>
88 #include <Approx_CurveOnSurface.hxx>
89 #include <GeomAdaptor.hxx>
90 #include <GeomProjLib.hxx>
91 #include <TColStd_Array1OfReal.hxx>
92 #include <TColgp_Array1OfPnt2d.hxx>
93 #include <TColStd_Array1OfInteger.hxx>
94 #include <Geom2d_BSplineCurve.hxx>
95 #include <Geom2dAdaptor_Curve.hxx>
96 #include <IntRes2d_IntersectionPoint.hxx>
97 #include <IntRes2d_IntersectionSegment.hxx>
98 #include <Geom2dInt_GInter.hxx>
99 #include <IntPatch_ALine.hxx>
102 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
103 const Handle(GeomAdaptor_HSurface)& HS2,
111 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
112 const Standard_Integer ideb,
113 const Standard_Integer ifin);
116 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
117 const Standard_Integer ideb,
118 const Standard_Integer ifin,
119 const Standard_Boolean onFirst);
122 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
126 Standard_Boolean DecompositionOfWLine (const Handle(IntPatch_WLine)& theWLine,
127 const Handle(GeomAdaptor_HSurface)& theSurface1,
128 const Handle(GeomAdaptor_HSurface)& theSurface2,
129 const Standard_Real aTolSum,
130 const GeomInt_LineConstructor& theLConstructor,
131 IntPatch_SequenceOfLine& theNewLines);
134 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
135 const Standard_Real parmin,
136 const Standard_Real parmax,
137 const Standard_Real thePeriod,
138 Standard_Real& theOffset) ;
140 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
141 const Standard_Real theFirstBoundary,
142 const Standard_Real theSecondBoundary,
143 const Standard_Real theResolution,
144 Standard_Boolean& IsOnFirstBoundary);
147 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
148 const gp_Pnt2d& theLastPoint,
149 const Standard_Real theUmin,
150 const Standard_Real theUmax,
151 const Standard_Real theVmin,
152 const Standard_Real theVmax,
153 gp_Pnt2d& theNewPoint);
157 void AdjustUPeriodic (const Handle(Geom_Surface)& aS,
158 Handle(Geom2d_Curve)& aC2D);
160 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1,
161 IntSurf_Quadric& quad1);
163 class ProjectPointOnSurf
166 ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {}
167 void Init(const Handle(Geom_Surface)& Surface,
168 const Standard_Real Umin,
169 const Standard_Real Usup,
170 const Standard_Real Vmin,
171 const Standard_Real Vsup);
173 void Perform(const gp_Pnt& P);
174 Standard_Boolean IsDone () const { return myIsDone; }
175 void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const;
176 Standard_Real LowerDistance() const;
178 Standard_Boolean myIsDone;
179 Standard_Integer myIndex;
180 Extrema_ExtPS myExtPS;
181 GeomAdaptor_Surface myGeomAdaptor;
184 //=======================================================================
187 //=======================================================================
188 void ProjectPointOnSurf::Init (const Handle(Geom_Surface)& Surface,
189 const Standard_Real Umin,
190 const Standard_Real Usup,
191 const Standard_Real Vmin,
192 const Standard_Real Vsup )
194 const Standard_Real Tolerance = Precision::PConfusion();
196 myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
197 myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
198 myIsDone = Standard_False;
200 //=======================================================================
203 //=======================================================================
204 void ProjectPointOnSurf::Init ()
206 myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0);
208 // evaluate the lower distance and its index;
209 Standard_Real Dist2Min = myExtPS.SquareDistance(1);
211 for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++)
213 const Standard_Real Dist2 = myExtPS.SquareDistance(i);
214 if (Dist2 < Dist2Min) {
221 //=======================================================================
224 //=======================================================================
225 void ProjectPointOnSurf::Perform(const gp_Pnt& P)
230 //=======================================================================
231 //function : LowerDistanceParameters
233 //=======================================================================
234 void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U,
235 Standard_Real& V ) const
237 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters");
238 (myExtPS.Point(myIndex)).Parameter(U,V);
240 //=======================================================================
241 //function : LowerDistance
243 //=======================================================================
244 Standard_Real ProjectPointOnSurf::LowerDistance() const
246 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance");
247 return sqrt(myExtPS.SquareDistance(myIndex));
251 //=======================================================================
252 //function : MakeCurve
254 //=======================================================================
255 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
256 const Handle(Adaptor3d_TopolTool) & dom1,
257 const Handle(Adaptor3d_TopolTool) & dom2,
258 const Standard_Real Tol,
259 const Standard_Boolean Approx,
260 const Standard_Boolean ApproxS1,
261 const Standard_Boolean ApproxS2)
264 Standard_Boolean myApprox1, myApprox2, myApprox;
265 Standard_Real Tolpc, myTolApprox;
267 Handle(Geom2d_BSplineCurve) H1;
268 Handle(Geom_Surface) aS1, aS2;
274 myTolApprox=0.0000001;
276 aS1=myHS1->ChangeSurface().Surface();
277 aS2=myHS2->ChangeSurface().Surface();
279 Handle(IntPatch_Line) L = myIntersector.Line(Index);
282 if(typl==IntPatch_Walking) {
283 Handle(IntPatch_Line) anewL =
284 ComputePurgedWLine(Handle(IntPatch_WLine)::DownCast(L));
293 myLConstruct.Perform(L);
294 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
299 Standard_Integer i, j, aNbParts;
300 Standard_Real fprm, lprm;
301 Handle(Geom_Curve) newc;
304 //########################################
305 // Line, Parabola, Hyperbola
306 //########################################
308 case IntPatch_Parabola:
309 case IntPatch_Hyperbola: {
310 if (typl == IntPatch_Lin) {
311 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
313 else if (typl == IntPatch_Parabola) {
314 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
316 else if (typl == IntPatch_Hyperbola) {
317 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
320 aNbParts=myLConstruct.NbParts();
321 for (i=1; i<=aNbParts; i++) {
322 myLConstruct.Part(i, fprm, lprm);
324 if (!Precision::IsNegativeInfinite(fprm) &&
325 !Precision::IsPositiveInfinite(lprm)) {
326 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
330 Handle (Geom2d_Curve) C2d;
331 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
332 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
333 myTolReached2d=Tolpc;
335 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
342 Handle (Geom2d_Curve) C2d;
343 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
344 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
345 myTolReached2d=Tolpc;
348 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
353 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
356 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
357 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
358 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
359 typS1 == GeomAbs_OffsetSurface ||
360 typS1 == GeomAbs_SurfaceOfRevolution ||
361 typS2 == GeomAbs_SurfaceOfExtrusion ||
362 typS2 == GeomAbs_OffsetSurface ||
363 typS2 == GeomAbs_SurfaceOfRevolution) {
369 Standard_Boolean bFNIt, bLPIt;
370 Standard_Real aTestPrm, dT=100.;
371 Standard_Real u1, v1, u2, v2, TolX;
373 bFNIt=Precision::IsNegativeInfinite(fprm);
374 bLPIt=Precision::IsPositiveInfinite(lprm);
378 if (bFNIt && !bLPIt) {
381 else if (!bFNIt && bLPIt) {
385 gp_Pnt ptref(newc->Value(aTestPrm));
387 TolX = Precision::Confusion();
388 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
389 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
391 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
399 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
400 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
403 //########################################
404 // Circle and Ellipse
405 //########################################
406 case IntPatch_Circle:
407 case IntPatch_Ellipse: {
409 if (typl == IntPatch_Circle) {
410 newc = new Geom_Circle
411 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
414 newc = new Geom_Ellipse
415 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
418 Standard_Real aPeriod, aRealEpsilon;
420 aRealEpsilon=RealEpsilon();
423 aNbParts=myLConstruct.NbParts();
425 for (i=1; i<=aNbParts; i++) {
426 myLConstruct.Part(i, fprm, lprm);
428 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
429 //==============================================
430 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
434 fprm=aTC3D->FirstParameter();
435 lprm=aTC3D->LastParameter ();
438 Handle (Geom2d_Curve) C2d;
439 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
440 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
441 myTolReached2d=Tolpc;
450 Handle (Geom2d_Curve) C2d;
451 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
452 if(Tolpc>myTolReached2d || myTolReached2d==0) {
453 myTolReached2d=Tolpc;
460 //==============================================
461 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
463 else {// on regarde si on garde
466 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
467 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
470 fprm=aTC3D->FirstParameter();
471 lprm=aTC3D->LastParameter ();
474 Handle (Geom2d_Curve) C2d;
475 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
476 if(Tolpc>myTolReached2d || myTolReached2d==0) {
477 myTolReached2d=Tolpc;
486 Handle (Geom2d_Curve) C2d;
487 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
488 if(Tolpc>myTolReached2d || myTolReached2d==0) {
489 myTolReached2d=Tolpc;
500 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
502 aTwoPIdiv17=2.*M_PI/17.;
504 for (j=0; j<=17; j++) {
505 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
506 TolX = Precision::Confusion();
508 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
509 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
511 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
515 //==============================================
517 Handle (Geom2d_Curve) C2d;
518 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
519 if(Tolpc>myTolReached2d || myTolReached2d==0) {
520 myTolReached2d=Tolpc;
529 Handle (Geom2d_Curve) C2d;
530 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
531 if(Tolpc>myTolReached2d || myTolReached2d==0) {
532 myTolReached2d=Tolpc;
541 }// end of for (Standard_Integer j=0; j<=17; j++)
542 }// end of else { on regarde si on garde
543 }// for (i=1; i<=myLConstruct.NbParts(); i++)
544 }// IntPatch_Circle: IntPatch_Ellipse
547 //########################################
549 //########################################
550 case IntPatch_Analytic: {
551 IntSurf_Quadric quad1,quad2;
553 GetQuadric(myHS1, quad1);
554 GetQuadric(myHS2, quad2);
556 IntPatch_ALineToWLine convert (quad1, quad2);
559 Handle(Geom2d_BSplineCurve) aH1, aH2;
561 aNbParts=myLConstruct.NbParts();
562 for (i=1; i<=aNbParts; i++) {
563 myLConstruct.Part(i, fprm, lprm);
564 Handle(IntPatch_WLine) WL =
565 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
568 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
572 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
574 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
580 else { // myApprox=TRUE
581 GeomInt_WLApprox theapp3d;
582 Standard_Real tol2d = myTolApprox;
584 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
586 aNbParts=myLConstruct.NbParts();
587 for (i=1; i<=aNbParts; i++) {
588 myLConstruct.Part(i, fprm, lprm);
589 Handle(IntPatch_WLine) WL =
590 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
592 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
593 if (!theapp3d.IsDone()) {
595 Handle(Geom2d_BSplineCurve) aH1, aH2;
598 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
602 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
604 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
610 if(myApprox1 || myApprox2) {
611 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
612 myTolReached2d = theapp3d.TolReached2d();
616 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
617 myTolReached3d = theapp3d.TolReached3d();
620 Standard_Integer aNbMultiCurves, nbpoles;
621 aNbMultiCurves=theapp3d.NbMultiCurves();
622 for (j=1; j<=aNbMultiCurves; j++) {
623 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
625 nbpoles = mbspc.NbPoles();
626 TColgp_Array1OfPnt tpoles(1, nbpoles);
627 mbspc.Curve(1, tpoles);
628 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
630 mbspc.Multiplicities(),
633 GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
634 Check.FixTangent(Standard_True,Standard_True);
639 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
640 mbspc.Curve(2,tpoles2d);
641 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
643 mbspc.Multiplicities(),
646 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
647 newCheck.FixTangent(Standard_True,Standard_True);
655 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
656 Standard_Integer TwoOrThree;
657 TwoOrThree=myApprox1 ? 3 : 2;
658 mbspc.Curve(TwoOrThree, tpoles2d);
659 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
661 mbspc.Multiplicities(),
664 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
665 newCheck.FixTangent(Standard_True,Standard_True);
673 }// for (j=1; j<=aNbMultiCurves; j++) {
674 }// else from if (!theapp3d.IsDone())
675 }// for (i=1; i<=aNbParts; i++) {
676 }// else { // myApprox=TRUE
677 }// case IntPatch_Analytic:
680 //########################################
682 //########################################
683 case IntPatch_Walking:{
684 Handle(IntPatch_WLine) WL =
685 Handle(IntPatch_WLine)::DownCast(L);
687 Standard_Integer ifprm, ilprm;
690 aNbParts=myLConstruct.NbParts();
691 for (i=1; i<=aNbParts; i++) {
692 myLConstruct.Part(i, fprm, lprm);
693 ifprm=(Standard_Integer)fprm;
694 ilprm=(Standard_Integer)lprm;
696 Handle(Geom2d_BSplineCurve) aH1, aH2;
699 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
702 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
705 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
714 Standard_Boolean bIsDecomposited;
715 Standard_Integer nbiter, aNbSeqOfL;
716 GeomInt_WLApprox theapp3d;
717 IntPatch_SequenceOfLine aSeqOfL;
718 Standard_Real tol2d, aTolSS;
723 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
726 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
730 DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
732 aNbParts=myLConstruct.NbParts();
733 aNbSeqOfL=aSeqOfL.Length();
735 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
737 for(i = 1; i <= nbiter; i++) {
738 if(bIsDecomposited) {
739 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
741 ilprm = WL->NbPnts();
744 myLConstruct.Part(i, fprm, lprm);
745 ifprm = (Standard_Integer)fprm;
746 ilprm = (Standard_Integer)lprm;
749 //-- Si une des surfaces est un plan , on approxime en 2d
750 //-- sur cette surface et on remonte les points 2d en 3d.
751 GeomAbs_SurfaceType typs1, typs2;
752 typs1 = myHS1->Surface().GetType();
753 typs2 = myHS2->Surface().GetType();
755 if(typs1 == GeomAbs_Plane) {
756 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
757 Standard_True, myApprox2,
760 else if(typs2 == GeomAbs_Plane) {
761 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
762 myApprox1,Standard_True,
768 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
769 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
771 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
772 //Standard_Boolean bUseSurfaces;
773 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
774 //if (bUseSurfaces) {
775 //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
780 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
785 if (!theapp3d.IsDone()) {
787 Handle(Geom2d_BSplineCurve) aH1, aH2;
789 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
791 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
794 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
800 }//if (!theapp3d.IsDone())
803 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
804 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
805 myTolReached2d = theapp3d.TolReached2d();
808 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
809 myTolReached3d = myTolReached2d;
811 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
812 myTolReached3d = theapp3d.TolReached3d();
815 Standard_Integer aNbMultiCurves, nbpoles;
817 aNbMultiCurves=theapp3d.NbMultiCurves();
818 for (j=1; j<=aNbMultiCurves; j++) {
819 if(typs1 == GeomAbs_Plane) {
820 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
821 nbpoles = mbspc.NbPoles();
823 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
824 TColgp_Array1OfPnt tpoles(1,nbpoles);
826 mbspc.Curve(1,tpoles2d);
827 const gp_Pln& Pln = myHS1->Surface().Plane();
830 for(ik = 1; ik<= nbpoles; ik++) {
832 ElSLib::Value(tpoles2d.Value(ik).X(),
833 tpoles2d.Value(ik).Y(),
837 Handle(Geom_BSplineCurve) BS =
838 new Geom_BSplineCurve(tpoles,
840 mbspc.Multiplicities(),
842 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
843 Check.FixTangent(Standard_True, Standard_True);
848 Handle(Geom2d_BSplineCurve) BS1 =
849 new Geom2d_BSplineCurve(tpoles2d,
851 mbspc.Multiplicities(),
853 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
854 Check1.FixTangent(Standard_True,Standard_True);
856 AdjustUPeriodic (aS1, BS1);
865 mbspc.Curve(2, tpoles2d);
867 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
869 mbspc.Multiplicities(),
871 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
872 newCheck.FixTangent(Standard_True,Standard_True);
874 AdjustUPeriodic (aS2, BS2);
881 }//if(typs1 == GeomAbs_Plane)
883 else if(typs2 == GeomAbs_Plane) {
884 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
885 nbpoles = mbspc.NbPoles();
887 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
888 TColgp_Array1OfPnt tpoles(1,nbpoles);
889 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
890 const gp_Pln& Pln = myHS2->Surface().Plane();
893 for(ik = 1; ik<= nbpoles; ik++) {
895 ElSLib::Value(tpoles2d.Value(ik).X(),
896 tpoles2d.Value(ik).Y(),
901 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
903 mbspc.Multiplicities(),
905 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
906 Check.FixTangent(Standard_True,Standard_True);
911 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
913 mbspc.Multiplicities(),
915 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
916 Check1.FixTangent(Standard_True,Standard_True);
919 AdjustUPeriodic (aS2, BS1);
928 mbspc.Curve(1,tpoles2d);
929 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
931 mbspc.Multiplicities(),
933 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
934 Check2.FixTangent(Standard_True,Standard_True);
937 AdjustUPeriodic (aS1, BS2);
944 } // else if(typs2 == GeomAbs_Plane)
946 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
947 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
948 nbpoles = mbspc.NbPoles();
949 TColgp_Array1OfPnt tpoles(1,nbpoles);
950 mbspc.Curve(1,tpoles);
951 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
953 mbspc.Multiplicities(),
955 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
956 Check.FixTangent(Standard_True,Standard_True);
959 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
960 BS->EndPoint().XYZ().SquareModulus());
961 Standard_Real eps = Epsilon(aDist);
962 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
964 // Avoid creating B-splines containing two coincident poles only
965 if (mbspc.Degree() == 1 && nbpoles == 2)
968 if (!BS->IsClosed() && !BS->IsPeriodic())
971 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
973 BS->SetPole(BS->NbPoles(), aPm);
979 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
980 mbspc.Curve(2,tpoles2d);
981 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
983 mbspc.Multiplicities(),
985 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
986 newCheck.FixTangent(Standard_True,Standard_True);
988 AdjustUPeriodic (aS1, BS1);
996 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
997 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
998 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1000 mbspc.Multiplicities(),
1002 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
1003 newCheck.FixTangent(Standard_True,Standard_True);
1005 AdjustUPeriodic (aS2, BS2);
1007 slineS2.Append(BS2);
1012 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
1013 }// for (j=1; j<=aNbMultiCurves; j++
1020 case IntPatch_Restriction:
1022 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
1023 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
1024 Standard_Boolean isAnalS1 = Standard_False;
1028 case GeomAbs_Cylinder:
1029 case GeomAbs_Sphere:
1031 case GeomAbs_Torus: isAnalS1 = Standard_True; break;
1035 Standard_Integer isAnalS2 = Standard_False;
1039 case GeomAbs_Cylinder:
1040 case GeomAbs_Sphere:
1042 case GeomAbs_Torus: isAnalS2 = Standard_True; break;
1046 Handle(IntPatch_RLine) RL =
1047 Handle(IntPatch_RLine)::DownCast(L);
1048 Handle(Geom_Curve) aC3d;
1049 Handle(Geom2d_Curve) aC2d1, aC2d2;
1050 Standard_Real aTolReached;
1051 TreatRLine(RL, myHS1, myHS2, aC3d,
1052 aC2d1, aC2d2, aTolReached);
1057 Bnd_Box2d aBox1, aBox2;
1059 const Standard_Real aU1f = myHS1->FirstUParameter(),
1060 aV1f = myHS1->FirstVParameter(),
1061 aU1l = myHS1->LastUParameter(),
1062 aV1l = myHS1->LastVParameter();
1063 const Standard_Real aU2f = myHS2->FirstUParameter(),
1064 aV2f = myHS2->FirstVParameter(),
1065 aU2l = myHS2->LastUParameter(),
1066 aV2l = myHS2->LastVParameter();
1068 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1069 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1070 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1071 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1073 GeomInt_VectorOfReal anArrayOfParameters;
1075 //We consider here that the intersection line is same-parameter-line
1076 anArrayOfParameters.Append(aC3d->FirstParameter());
1077 anArrayOfParameters.Append(aC3d->LastParameter());
1079 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1081 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1084 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1086 const Standard_Real aParF = anArrayOfParameters(anInd),
1087 aParL = anArrayOfParameters(anInd+1);
1089 if((aParL - aParF) <= Precision::PConfusion())
1092 const Standard_Real aPar = 0.5*(aParF + aParL);
1095 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1098 aC2d1->D0(aPar, aPt);
1100 if(aBox1.IsOut(aPt))
1104 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1109 aC2d2->D0(aPar, aPt);
1111 if(aBox2.IsOut(aPt))
1115 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1118 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1120 sline.Append(aCurv3d);
1121 slineS1.Append(aCurv2d1);
1122 slineS2.Append(aCurv2d2);
1129 //=======================================================================
1130 //function : AdjustUPeriodic
1132 //=======================================================================
1133 void AdjustUPeriodic (const Handle(Geom_Surface)& aS, Handle(Geom2d_Curve)& aC2D)
1135 if (aC2D.IsNull() || !aS->IsUPeriodic())
1138 const Standard_Real aEps=Precision::PConfusion();//1.e-9
1139 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
1141 Standard_Real umin,umax,vmin,vmax;
1142 aS->Bounds(umin,umax,vmin,vmax);
1143 const Standard_Real aPeriod = aS->UPeriod();
1145 const Standard_Real aT1=aC2D->FirstParameter();
1146 const Standard_Real aT2=aC2D->LastParameter();
1147 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
1148 const gp_Pnt2d aPx=aC2D->Value(aTx);
1150 Standard_Real aUx=aPx.X();
1151 if (fabs(aUx)<aEpsilon)
1153 if (fabs(aUx-aPeriod)<aEpsilon)
1156 Standard_Real dU=0.;
1157 while(aUx <(umin-aEps)) {
1161 while(aUx>(umax+aEps)) {
1167 gp_Vec2d aV2D(dU, 0.);
1168 aC2D->Translate(aV2D);
1173 //=======================================================================
1174 //function : GetQuadric
1176 //=======================================================================
1177 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
1179 switch (HS1->Surface().GetType())
1181 case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break;
1182 case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
1183 case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break;
1184 case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break;
1185 case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break;
1186 default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
1190 //=======================================================================
1191 //function : Parameters
1193 //=======================================================================
1194 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
1195 const Handle(GeomAdaptor_HSurface)& HS2,
1196 const gp_Pnt& Ptref,
1202 IntSurf_Quadric quad1,quad2;
1204 GetQuadric(HS1, quad1);
1205 GetQuadric(HS2, quad2);
1207 quad1.Parameters(Ptref,U1,V1);
1208 quad2.Parameters(Ptref,U2,V2);
1211 //=======================================================================
1212 //function : MakeBSpline
1214 //=======================================================================
1215 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
1216 const Standard_Integer ideb,
1217 const Standard_Integer ifin)
1219 const Standard_Integer nbpnt = ifin-ideb+1;
1220 TColgp_Array1OfPnt poles(1,nbpnt);
1221 TColStd_Array1OfReal knots(1,nbpnt);
1222 TColStd_Array1OfInteger mults(1,nbpnt);
1223 Standard_Integer i = 1, ipidebm1 = ideb;
1224 for(; i<=nbpnt; ipidebm1++, i++)
1226 poles(i) = WL->Point(ipidebm1).Value();
1230 mults(1) = mults(nbpnt) = 2;
1231 return new Geom_BSplineCurve(poles,knots,mults,1);
1234 //=======================================================================
1235 //function : MakeBSpline2d
1237 //=======================================================================
1238 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1239 const Standard_Integer ideb,
1240 const Standard_Integer ifin,
1241 const Standard_Boolean onFirst)
1243 const Standard_Integer nbpnt = ifin-ideb+1;
1244 TColgp_Array1OfPnt2d poles(1,nbpnt);
1245 TColStd_Array1OfReal knots(1,nbpnt);
1246 TColStd_Array1OfInteger mults(1,nbpnt);
1247 Standard_Integer i = 1, ipidebm1 = ideb;
1248 for(; i <= nbpnt; ipidebm1++, i++)
1252 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1254 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1255 poles(i).SetCoord(U, V);
1259 mults(1) = mults(nbpnt) = 2;
1260 return new Geom2d_BSplineCurve(poles,knots,mults,1);
1263 //=========================================================================
1264 // static function : ComputePurgedWLine
1265 // purpose : Removes equal points (leave one of equal points) from theWLine
1266 // and recompute vertex parameters.
1267 // Returns new WLine or null WLine if the number
1268 // of the points is less than 2.
1269 //=========================================================================
1270 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine)
1272 Handle(IntPatch_WLine) aResult;
1273 Handle(IntPatch_WLine) aLocalWLine;
1274 Handle(IntPatch_WLine) aTmpWLine = theWLine;
1276 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1277 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1278 Standard_Integer i, k, v, nb, nbvtx;
1279 nbvtx = theWLine->NbVertex();
1280 nb = theWLine->NbPnts();
1282 for(i = 1; i <= nb; i++) {
1283 aLineOn2S->Add(theWLine->Point(i));
1286 for(v = 1; v <= nbvtx; v++) {
1287 aLocalWLine->AddVertex(theWLine->Vertex(v));
1290 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
1291 Standard_Integer aStartIndex = i + 1;
1292 Standard_Integer anEndIndex = i + 5;
1293 nb = aLineOn2S->NbPoints();
1294 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
1296 if((aStartIndex >= nb) || (anEndIndex <= 1)) {
1301 while(k <= anEndIndex) {
1304 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
1305 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
1307 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
1308 aTmpWLine = aLocalWLine;
1309 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1311 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
1312 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
1313 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
1315 if(avertexindex >= k) {
1316 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
1318 aLocalWLine->AddVertex(aVertex);
1320 aLineOn2S->RemovePoint(k);
1329 if(aLineOn2S->NbPoints() > 1) {
1330 aResult = aLocalWLine;
1334 //=======================================================================
1335 //function : DecompositionOfWLine
1337 //=======================================================================
1338 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
1339 const Handle(GeomAdaptor_HSurface)& theSurface1,
1340 const Handle(GeomAdaptor_HSurface)& theSurface2,
1341 const Standard_Real aTolSum,
1342 const GeomInt_LineConstructor& theLConstructor,
1343 IntPatch_SequenceOfLine& theNewLines)
1345 typedef NCollection_List<Standard_Integer> ListOfInteger;
1346 //have to use std::vector, not NCollection_Vector in order to use copy constructor of
1347 //ListOfInteger which will be created with specific allocator instance
1348 typedef std::vector<ListOfInteger, NCollection_StdAllocator<
1349 ListOfInteger> > ArrayOfListOfInteger;
1351 Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary;
1352 Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex;
1353 Standard_Real aTol, umin, umax, vmin, vmax;
1355 //an inc allocator, it will contain wasted space (upon list's Clear()) but it should
1356 //still be faster than the standard allocator, and wasted memory should not be
1357 //significant and will be limited by time span of this function;
1358 //this is a separate allocator from the anIncAlloc below what provides better data
1359 //locality in the latter (by avoiding wastes which will only be in anIdxAlloc)
1360 Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator();
1361 ListOfInteger aListOfPointIndex (anIdxAlloc);
1363 //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2;
1364 ProjectPointOnSurf aPrj1, aPrj2;
1365 Handle(Geom_Surface) aSurf1, aSurf2;
1367 aNbParts=theLConstructor.NbParts();
1368 aNbPnts=theWLine->NbPnts();
1370 if((!aNbPnts) || (!aNbParts)){
1371 return Standard_False;
1374 Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
1375 NCollection_StdAllocator<ListOfInteger> anAlloc (anIncAlloc);
1376 const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from
1377 ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc);
1379 NCollection_LocalArray<Standard_Integer> anArrayOfLineTypeArr (aNbPnts + 1);
1380 Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr;
1383 aTol = Precision::Confusion();
1385 aSurf1 = theSurface1->ChangeSurface().Surface();
1386 aSurf1->Bounds(umin, umax, vmin, vmax);
1387 aPrj1.Init(aSurf1, umin, umax, vmin, vmax);
1389 aSurf2 = theSurface2->ChangeSurface().Surface();
1390 aSurf2->Bounds(umin, umax, vmin, vmax);
1391 aPrj2.Init(aSurf2, umin, umax, vmin, vmax);
1394 bIsPrevPointOnBoundary=Standard_False;
1395 for(pit=1; pit<=aNbPnts; pit++) {
1396 const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
1397 bIsCurrentPointOnBoundary=Standard_False;
1399 // whether aPoint is on boundary or not
1401 for(i=0; i<2; i++) {// exploration Surface 1,2
1402 Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
1403 aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
1405 for(j=0; j<2; j++) {// exploration of coordinate U,V
1406 Standard_Boolean isperiodic;
1408 isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1413 Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
1414 Standard_Real aParameter, anoffset, anAdjustPar;
1415 Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary;
1417 aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1418 aPeriod = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1419 alowerboundary = (!j) ? umin : vmin;
1420 aupperboundary = (!j) ? umax : vmax;
1424 aPoint.ParametersOnS1(U, V);
1427 aPoint.ParametersOnS2(U, V);
1430 aParameter = (!j) ? U : V;
1432 anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1434 bIsOnFirstBoundary=Standard_True;
1437 IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
1439 if(bIsPointOnBoundary) {
1440 bIsCurrentPointOnBoundary = Standard_True;
1443 }// for(j=0; j<2; j++)
1445 if(bIsCurrentPointOnBoundary){
1448 }// for(i=0; i<2; i++)
1450 if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
1452 if(!aListOfPointIndex.IsEmpty()) {
1454 anArrayOfLines[nblines] = aListOfPointIndex;
1455 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1456 aListOfPointIndex.Clear();
1458 bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
1460 aListOfPointIndex.Append(pit);
1461 } // for(pit=1; pit<=aNbPnts; pit++)
1463 aNbListOfPointIndex=aListOfPointIndex.Extent();
1464 if(aNbListOfPointIndex) {
1466 anArrayOfLines[nblines].Assign (aListOfPointIndex);
1467 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1468 aListOfPointIndex.Clear();
1472 return Standard_False;
1475 // Correct wlines.begin
1476 Standard_Integer aLineType;
1477 TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
1478 Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator());
1480 for(i = 1; i <= nblines; i++) {
1481 aLineType=anArrayOfLineType[i];
1486 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1487 if(aListOfIndex.Extent() < 2) {
1491 TColStd_ListOfInteger aListOfFLIndex;
1492 Standard_Integer aneighbourindex, aLineTypeNeib;
1494 for(j = 0; j < 2; j++) {// neighbour line choice
1495 aneighbourindex = (!j) ? (i-1) : (i+1);
1496 if((aneighbourindex < 1) || (aneighbourindex > nblines)){
1500 aLineTypeNeib=anArrayOfLineType[aneighbourindex];
1505 const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex];
1506 Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First();
1507 const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
1508 // check if need use derivative.begin .end [absence]
1510 IntSurf_PntOn2S aNewP = aPoint;
1511 Standard_Integer surfit, parit;
1513 for(surfit = 0; surfit < 2; ++surfit) {
1515 Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2;
1517 umin = aGASurface->FirstUParameter();
1518 umax = aGASurface->LastUParameter();
1519 vmin = aGASurface->FirstVParameter();
1520 vmax = aGASurface->LastVParameter();
1521 Standard_Real U=0., V=0.;
1524 aNewP.ParametersOnS1(U, V);
1527 aNewP.ParametersOnS2(U, V);
1530 Standard_Integer nbboundaries = 0;
1531 Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
1532 Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
1534 for(parit = 0; parit < 2; parit++) {
1535 Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1537 Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1538 Standard_Real alowerboundary = (!parit) ? umin : vmin;
1539 Standard_Real aupperboundary = (!parit) ? umax : vmax;
1541 Standard_Real aParameter = (!parit) ? U : V;
1542 Standard_Boolean bIsOnFirstBoundary = Standard_True;
1545 if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1546 bIsUBoundary = (!parit);
1547 bIsFirstBoundary = bIsOnFirstBoundary;
1552 Standard_Real aPeriod = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1553 Standard_Real anoffset = 0.;
1554 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1556 if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1557 bIsUBoundary = (parit == 0);
1558 bIsFirstBoundary = bIsOnFirstBoundary;
1564 Standard_Boolean bComputeLineEnd = Standard_False;
1566 if(nbboundaries == 2) {
1567 bComputeLineEnd = Standard_True;
1569 else if(nbboundaries == 1) {
1570 Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1573 Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
1574 Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
1575 Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1576 Standard_Real aParameter = (bIsUBoundary) ? U : V;
1577 Standard_Real anoffset = 0.;
1578 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1580 Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
1581 Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
1582 anotherPar += anoffset;
1583 Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1584 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
1585 Standard_Real nU1, nV1;
1588 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1590 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1592 Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
1593 Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
1594 bComputeLineEnd = Standard_True;
1595 Standard_Boolean bCheckAngle1 = Standard_False;
1596 Standard_Boolean bCheckAngle2 = Standard_False;
1598 Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
1599 Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
1601 if(((adist1 - adist2) > Precision::PConfusion()) &&
1602 (adist2 < (aPeriod / 4.))) {
1603 bCheckAngle1 = Standard_True;
1604 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
1606 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1607 aNewP.SetValue((surfit == 0), anewU, anewV);
1608 bCheckAngle1 = Standard_False;
1611 else if(adist1 < (aPeriod / 4.)) {
1612 bCheckAngle2 = Standard_True;
1613 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
1615 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1616 bCheckAngle2 = Standard_False;
1620 if(bCheckAngle1 || bCheckAngle2) {
1621 // assume there are at least two points in line (see "if" above)
1622 Standard_Integer anindexother = aneighbourpointindex;
1624 while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
1625 anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
1626 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
1627 Standard_Real nU2, nV2;
1630 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1632 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1633 gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
1635 if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
1639 Standard_Real anAngle = aNewVec.Angle(aVecOld);
1641 if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
1644 Standard_Real U1, U2, V1, V2;
1645 IntSurf_PntOn2S atmppoint = aNewP;
1646 atmppoint.SetValue((surfit == 0), anewU, anewV);
1647 atmppoint.Parameters(U1, V1, U2, V2);
1648 gp_Pnt P1 = theSurface1->Value(U1, V1);
1649 gp_Pnt P2 = theSurface2->Value(U2, V2);
1650 gp_Pnt P0 = aPoint.Value();
1652 if(P0.IsEqual(P1, aTol) &&
1653 P0.IsEqual(P2, aTol) &&
1654 P1.IsEqual(P2, aTol)) {
1655 bComputeLineEnd = Standard_False;
1656 aNewP.SetValue((surfit == 0), anewU, anewV);
1661 bComputeLineEnd = Standard_False;
1666 } // end while(anindexother...)
1671 if(bComputeLineEnd) {
1672 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1673 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
1674 Standard_Real nU1, nV1;
1677 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1679 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1680 gp_Pnt2d ap1(nU1, nV1);
1681 gp_Pnt2d ap2(nU1, nV1);
1682 Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
1684 while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
1685 aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
1686 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
1687 Standard_Real nU2, nV2;
1690 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1692 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1696 if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
1701 Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
1705 Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
1706 //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1707 ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1708 Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
1710 gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
1711 aProjector.Perform(aP3d);
1713 if(aProjector.IsDone()) {
1714 if(aProjector.LowerDistance() < aCriteria) {
1715 Standard_Real foundU = U, foundV = V;
1716 aProjector.LowerDistanceParameters(foundU, foundV);
1719 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
1721 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
1727 aSeqOfPntOn2S->Add(aNewP);
1728 aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
1730 anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
1732 // Correct wlines.end
1734 // Split wlines.begin
1735 for(j = 1; j <= theLConstructor.NbParts(); j++) {
1736 Standard_Real fprm = 0., lprm = 0.;
1737 theLConstructor.Part(j, fprm, lprm);
1738 Standard_Integer ifprm = (Standard_Integer)fprm;
1739 Standard_Integer ilprm = (Standard_Integer)lprm;
1741 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1743 for(i = 1; i <= nblines; i++) {
1744 if(anArrayOfLineType[i] != 0) {
1747 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1749 if(aListOfIndex.Extent() < 2) {
1752 const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
1753 Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
1754 Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
1756 if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
1757 bhasfirstpoint = (i != 1);
1760 if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
1761 bhaslastpoint = (i != nblines);
1763 Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
1764 Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
1766 if(!bIsFirstInside && !bIsLastInside) {
1767 if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
1768 // append whole line, and boundaries if neccesary
1769 if(bhasfirstpoint) {
1770 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1773 ListOfInteger::Iterator anIt(aListOfIndex);
1775 for(; anIt.More(); anIt.Next()) {
1776 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1781 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1785 // check end of split line (end is almost always)
1786 Standard_Integer aneighbour = i + 1;
1787 Standard_Boolean bIsEndOfLine = Standard_True;
1789 if(aneighbour <= nblines) {
1790 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1792 if((anArrayOfLineType[aneighbour] != 0) &&
1793 (aListOfNeighbourIndex.IsEmpty())) {
1794 bIsEndOfLine = Standard_False;
1799 if(aLineOn2S->NbPoints() > 1) {
1800 Handle(IntPatch_WLine) aNewWLine =
1801 new IntPatch_WLine(aLineOn2S, Standard_False);
1802 theNewLines.Append(aNewWLine);
1804 aLineOn2S = new IntSurf_LineOn2S();
1809 // end if(!bIsFirstInside && !bIsLastInside)
1811 if(bIsFirstInside && bIsLastInside) {
1812 // append inside points between ifprm and ilprm
1813 ListOfInteger::Iterator anIt(aListOfIndex);
1815 for(; anIt.More(); anIt.Next()) {
1816 if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
1818 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1824 if(bIsFirstInside) {
1825 // append points from ifprm to last point + boundary point
1826 ListOfInteger::Iterator anIt(aListOfIndex);
1828 for(; anIt.More(); anIt.Next()) {
1829 if(anIt.Value() < ifprm)
1831 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1836 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1839 // check end of split line (end is almost always)
1840 Standard_Integer aneighbour = i + 1;
1841 Standard_Boolean bIsEndOfLine = Standard_True;
1843 if(aneighbour <= nblines) {
1844 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1846 if((anArrayOfLineType[aneighbour] != 0) &&
1847 (aListOfNeighbourIndex.IsEmpty())) {
1848 bIsEndOfLine = Standard_False;
1853 if(aLineOn2S->NbPoints() > 1) {
1854 Handle(IntPatch_WLine) aNewWLine =
1855 new IntPatch_WLine(aLineOn2S, Standard_False);
1856 theNewLines.Append(aNewWLine);
1858 aLineOn2S = new IntSurf_LineOn2S();
1861 // end if(bIsFirstInside)
1864 // append points from first boundary point to ilprm
1865 if(bhasfirstpoint) {
1866 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1869 ListOfInteger::Iterator anIt(aListOfIndex);
1871 for(; anIt.More(); anIt.Next()) {
1872 if(anIt.Value() > ilprm)
1874 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1878 //end if(bIsLastInside)
1882 if(aLineOn2S->NbPoints() > 1) {
1883 Handle(IntPatch_WLine) aNewWLine =
1884 new IntPatch_WLine(aLineOn2S, Standard_False);
1885 theNewLines.Append(aNewWLine);
1891 Standard_Real fprm, lprm;
1892 Standard_Integer ifprm, ilprm, aNbPoints, aIndex;
1894 aNbParts=theLConstructor.NbParts();
1896 for(j = 1; j <= aNbParts; j++) {
1897 theLConstructor.Part(j, fprm, lprm);
1898 ifprm=(Standard_Integer)fprm;
1899 ilprm=(Standard_Integer)lprm;
1901 if ((ilprm-ifprm)==1) {
1902 for(i = 1; i <= nblines; i++) {
1903 aLineType=anArrayOfLineType[i];
1908 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1909 aNbPoints=aListOfIndex.Extent();
1911 aIndex=aListOfIndex.First();
1912 if (aIndex==ifprm || aIndex==ilprm) {
1913 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1914 const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm);
1915 const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm);
1916 aLineOn2S->Add(aP1);
1917 aLineOn2S->Add(aP2);
1918 Handle(IntPatch_WLine) aNewWLine =
1919 new IntPatch_WLine(aLineOn2S, Standard_False);
1920 theNewLines.Append(aNewWLine);
1927 return Standard_True;
1930 //=======================================================================
1931 //function : AdjustPeriodic
1933 //=======================================================================
1934 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
1935 const Standard_Real parmin,
1936 const Standard_Real parmax,
1937 const Standard_Real thePeriod,
1938 Standard_Real& theOffset)
1940 Standard_Real aresult = theParameter;
1942 while(aresult < parmin) {
1943 aresult += thePeriod;
1944 theOffset += thePeriod;
1946 while(aresult > parmax) {
1947 aresult -= thePeriod;
1948 theOffset -= thePeriod;
1953 //=======================================================================
1954 //function : IsPointOnBoundary
1956 //=======================================================================
1957 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
1958 const Standard_Real theFirstBoundary,
1959 const Standard_Real theSecondBoundary,
1960 const Standard_Real theResolution,
1961 Standard_Boolean& IsOnFirstBoundary)
1963 IsOnFirstBoundary = Standard_True;
1964 if(fabs(theParameter - theFirstBoundary) < theResolution)
1965 return Standard_True;
1966 if(fabs(theParameter - theSecondBoundary) < theResolution)
1968 IsOnFirstBoundary = Standard_False;
1969 return Standard_True;
1971 return Standard_False;
1973 //=======================================================================
1974 //function : FindPoint
1976 //=======================================================================
1977 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
1978 const gp_Pnt2d& theLastPoint,
1979 const Standard_Real theUmin,
1980 const Standard_Real theUmax,
1981 const Standard_Real theVmin,
1982 const Standard_Real theVmax,
1983 gp_Pnt2d& theNewPoint)
1985 gp_Vec2d aVec(theFirstPoint, theLastPoint);
1986 Standard_Integer i = 0, j = 0;
1988 for(i = 0; i < 4; i++) {
1989 gp_Vec2d anOtherVec;
1990 gp_Vec2d anOtherVecNormal;
1991 gp_Pnt2d aprojpoint = theLastPoint;
1994 anOtherVec.SetX(0.);
1995 anOtherVec.SetY(1.);
1996 anOtherVecNormal.SetX(1.);
1997 anOtherVecNormal.SetY(0.);
2000 aprojpoint.SetX(theUmin);
2002 aprojpoint.SetX(theUmax);
2005 anOtherVec.SetX(1.);
2006 anOtherVec.SetY(0.);
2007 anOtherVecNormal.SetX(0.);
2008 anOtherVecNormal.SetY(1.);
2011 aprojpoint.SetY(theVmin);
2013 aprojpoint.SetY(theVmax);
2015 gp_Vec2d anormvec = aVec;
2016 anormvec.Normalize();
2017 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
2019 if(fabs(adot1) < Precision::Angular())
2021 Standard_Real adist = 0.;
2024 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
2027 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
2029 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
2031 for(j = 0; j < 2; j++) {
2032 anoffset = (j == 0) ? anoffset : -anoffset;
2033 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
2034 gp_Vec2d acurvec(theLastPoint, acurpoint);
2037 Standard_Real aDotX, anAngleX, aPC;
2039 aDotX=aVec.Dot(acurvec);
2040 anAngleX=aVec.Angle(acurvec);
2041 aPC=Precision::PConfusion();
2043 if(aDotX > 0. && fabs(anAngleX) < aPC) {
2046 if((acurpoint.Y() >= theVmin) &&
2047 (acurpoint.Y() <= theVmax)) {
2048 theNewPoint = acurpoint;
2049 return Standard_True;
2053 if((acurpoint.X() >= theUmin) &&
2054 (acurpoint.X() <= theUmax)) {
2055 theNewPoint = acurpoint;
2056 return Standard_True;
2062 return Standard_False;
2065 //=======================================================================
2066 //function : ParametersOfNearestPointOnSurface
2068 //=======================================================================
2069 static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
2070 Standard_Real& theU,
2071 Standard_Real& theV)
2073 if(!theExtr.IsDone() || !theExtr.NbExt())
2074 return Standard_False;
2076 Standard_Integer anIndex = 1;
2077 Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
2078 for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
2080 Standard_Real aSQD = theExtr.SquareDistance(i);
2081 if (aSQD < aMinSQDist)
2088 theExtr.Point(anIndex).Parameter(theU, theV);
2090 return Standard_True;
2093 //=======================================================================
2094 //function : GetSegmentBoundary
2096 //=======================================================================
2097 static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
2098 const Handle(Geom2d_Curve)& theCurve,
2099 GeomInt_VectorOfReal& theArrayOfParameters)
2101 Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
2103 if(theSegm.HasFirstPoint())
2105 const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
2106 aU1 = anIPF.ParamOnFirst();
2109 if(theSegm.HasLastPoint())
2111 const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
2112 aU2 = anIPL.ParamOnFirst();
2115 theArrayOfParameters.Append(aU1);
2116 theArrayOfParameters.Append(aU2);
2119 //=======================================================================
2120 //function : IntersectCurveAndBoundary
2122 //=======================================================================
2123 static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
2124 const Handle(Geom2d_Curve)* const theArrBounds,
2125 const Standard_Integer theNumberOfCurves,
2126 const Standard_Real theTol,
2127 GeomInt_VectorOfReal& theArrayOfParameters)
2132 Geom2dAdaptor_Curve anAC1(theC2d);
2133 for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
2135 if(theArrBounds[aCurID].IsNull())
2138 Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
2139 Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
2141 if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
2144 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
2146 const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
2147 theArrayOfParameters.Append(aParam);
2150 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
2152 GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
2157 //=======================================================================
2158 //function : TreatRLine
2159 //purpose : Approx of Restriction line
2160 //=======================================================================
2161 void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
2162 const Handle(GeomAdaptor_HSurface)& theHS1,
2163 const Handle(GeomAdaptor_HSurface)& theHS2,
2164 Handle(Geom_Curve)& theC3d,
2165 Handle(Geom2d_Curve)& theC2d1,
2166 Handle(Geom2d_Curve)& theC2d2,
2167 Standard_Real& theTolReached)
2169 Handle(GeomAdaptor_HSurface) aGAHS;
2170 Handle(Adaptor2d_HCurve2d) anAHC2d;
2171 Standard_Real tf, tl;
2173 // It is assumed that 2d curve is 2d line (rectangular surface domain)
2174 if(theRL->IsArcOnS1())
2177 anAHC2d = theRL->ArcOnS1();
2178 theRL->ParamOnS1(tf, tl);
2179 theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2181 else if (theRL->IsArcOnS2())
2184 anAHC2d = theRL->ArcOnS2();
2185 theRL->ParamOnS2(tf, tl);
2186 theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2193 //To provide sameparameter it is necessary to get 3d curve as
2194 //approximation of curve on surface.
2195 Standard_Integer aMaxDeg = 8;
2196 Standard_Integer aMaxSeg = 1000;
2197 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
2198 GeomAbs_C1, aMaxDeg, aMaxSeg,
2199 Standard_True, Standard_False);
2200 if(!anApp.HasResult())
2203 theC3d = anApp.Curve3d();
2204 theTolReached = anApp.MaxError3d();
2205 Standard_Real aTol = Precision::Confusion();
2206 if(theRL->IsArcOnS1())
2208 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
2209 BuildPCurves (tf, tl, aTol,
2210 aS, theC3d, theC2d2);
2212 if(theRL->IsArcOnS2())
2214 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
2215 BuildPCurves (tf, tl, aTol,
2216 aS, theC3d, theC2d1);
2218 theTolReached = Max(theTolReached, aTol);
2221 //=======================================================================
2222 //function : BuildPCurves
2224 //=======================================================================
2225 void GeomInt_IntSS::BuildPCurves (Standard_Real f,
2228 const Handle (Geom_Surface)& S,
2229 const Handle (Geom_Curve)& C,
2230 Handle (Geom2d_Curve)& C2d)
2232 if (!C2d.IsNull()) {
2236 Standard_Real umin,umax,vmin,vmax;
2238 S->Bounds(umin, umax, vmin, vmax);
2239 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
2240 if((l - f) > 2.e-09) {
2241 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
2244 // proj. a circle that goes through the pole on a sphere to the sphere
2245 Tol += Precision::Confusion();
2246 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2250 if((l - f) > Epsilon(Abs(f)))
2252 //The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
2253 //On this small range C2d can be considered as segment
2256 Standard_Real aU=0., aV=0.;
2257 GeomAdaptor_Surface anAS;
2259 Extrema_ExtPS anExtr;
2260 const gp_Pnt aP3d1 = C->Value(f);
2261 const gp_Pnt aP3d2 = C->Value(l);
2263 anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
2264 anExtr.Initialize(anAS, umin, umax, vmin, vmax,
2265 Precision::Confusion(), Precision::Confusion());
2266 anExtr.Perform(aP3d1);
2268 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
2270 const gp_Pnt2d aP2d1(aU, aV);
2272 anExtr.Perform(aP3d2);
2274 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
2276 const gp_Pnt2d aP2d2(aU, aV);
2278 if(aP2d1.Distance(aP2d2) > gp::Resolution())
2280 TColgp_Array1OfPnt2d poles(1,2);
2281 TColStd_Array1OfReal knots(1,2);
2282 TColStd_Array1OfInteger mults(1,2);
2287 mults(1) = mults(2) = 2;
2289 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
2291 //Check same parameter in middle point .begin
2292 const gp_Pnt PMid(C->Value(0.5*(f+l)));
2293 const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
2294 const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
2295 const Standard_Real aDist = PMid.Distance(aPC);
2296 Tol = Max(aDist, Tol);
2297 //Check same parameter in middle point .end
2304 if (S->IsUPeriodic() && !C2d.IsNull()) {
2305 // Recadre dans le domaine UV de la face
2306 Standard_Real aTm, U0, aEps, period, du, U0x;
2307 Standard_Boolean bAdjust;
2309 aEps = Precision::PConfusion();
2310 period = S->UPeriod();
2313 gp_Pnt2d pm = C2d->Value(aTm);
2317 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
2319 gp_Vec2d T1(du, 0.);
2325 //=======================================================================
2326 //function : TrimILineOnSurfBoundaries
2327 //purpose : This function finds intersection points of given curves with
2328 // surface boundaries and fills theArrayOfParameters by parameters
2329 // along the given curves corresponding of these points.
2330 //=======================================================================
2331 void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
2332 const Handle(Geom2d_Curve)& theC2d2,
2333 const Bnd_Box2d& theBound1,
2334 const Bnd_Box2d& theBound2,
2335 GeomInt_VectorOfReal& theArrayOfParameters)
2337 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
2338 // [2]:V=Vfirst, [3]:V=Vlast
2339 const Standard_Integer aNumberOfCurves = 4;
2340 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
2341 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
2343 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
2344 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
2346 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
2347 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
2349 Standard_Real aDelta = aV1l-aV1f;
2350 if(Abs(aDelta) > RealSmall())
2352 if(!Precision::IsInfinite(aU1f))
2354 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
2356 if(!Precision::IsInfinite(aDelta))
2357 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
2360 if(!Precision::IsInfinite(aU1l))
2362 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
2363 if(!Precision::IsInfinite(aDelta))
2364 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
2369 if(Abs(aDelta) > RealSmall())
2371 if(!Precision::IsInfinite(aV1f))
2373 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
2374 if(!Precision::IsInfinite(aDelta))
2375 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
2378 if(!Precision::IsInfinite(aV1l))
2380 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
2381 if(!Precision::IsInfinite(aDelta))
2382 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
2387 if(Abs(aDelta) > RealSmall())
2389 if(!Precision::IsInfinite(aU2f))
2391 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
2392 if(!Precision::IsInfinite(aDelta))
2393 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
2396 if(!Precision::IsInfinite(aU2l))
2398 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
2399 if(!Precision::IsInfinite(aDelta))
2400 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
2405 if(Abs(aDelta) > RealSmall())
2407 if(!Precision::IsInfinite(aV2f))
2409 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
2410 if(!Precision::IsInfinite(aDelta))
2411 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
2414 if(!Precision::IsInfinite(aV2l))
2416 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
2417 if(!Precision::IsInfinite(aDelta))
2418 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
2422 const Standard_Real anIntTol = 10.0*Precision::Confusion();
2424 IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
2425 aNumberOfCurves, anIntTol, theArrayOfParameters);
2427 IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
2428 aNumberOfCurves, anIntTol, theArrayOfParameters);
2430 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());