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.
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_TopolTool.hxx>
20 #include <AppParCurves_MultiBSpCurve.hxx>
21 #include <Approx_CurveOnSurface.hxx>
22 #include <Bnd_Box2d.hxx>
24 #include <Extrema_ExtPS.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom2d_TrimmedCurve.hxx>
29 #include <Geom2dAdaptor.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dInt_GInter.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Ellipse.hxx>
36 #include <Geom_Hyperbola.hxx>
37 #include <Geom_Line.hxx>
38 #include <Geom_Parabola.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <GeomAbs_CurveType.hxx>
42 #include <GeomAbs_SurfaceType.hxx>
43 #include <GeomAdaptor.hxx>
44 #include <GeomAdaptor_HSurface.hxx>
45 #include <GeomInt.hxx>
46 #include <GeomInt_IntSS.hxx>
47 #include <GeomInt_WLApprox.hxx>
48 #include <GeomLib_Check2dBSplineCurve.hxx>
49 #include <GeomLib_CheckBSplineCurve.hxx>
50 #include <GeomProjLib.hxx>
51 #include <gp_Lin2d.hxx>
54 #include <gp_Pnt2d.hxx>
55 #include <IntPatch_ALine.hxx>
56 #include <IntPatch_ALineToWLine.hxx>
57 #include <IntPatch_GLine.hxx>
58 #include <IntPatch_IType.hxx>
59 #include <IntPatch_Line.hxx>
60 #include <IntPatch_RLine.hxx>
61 #include <IntPatch_WLine.hxx>
62 #include <IntRes2d_IntersectionPoint.hxx>
63 #include <IntRes2d_IntersectionSegment.hxx>
64 #include <NCollection_IncAllocator.hxx>
65 #include <NCollection_List.hxx>
66 #include <NCollection_LocalArray.hxx>
67 #include <NCollection_StdAllocator.hxx>
68 #include <Precision.hxx>
69 #include <Standard_OutOfRange.hxx>
70 #include <StdFail_NotDone.hxx>
71 #include <TColgp_Array1OfPnt.hxx>
72 #include <TColgp_Array1OfPnt2d.hxx>
73 #include <TColStd_Array1OfInteger.hxx>
74 #include <TColStd_Array1OfListOfInteger.hxx>
75 #include <TColStd_Array1OfReal.hxx>
76 #include <TColStd_ListIteratorOfListOfInteger.hxx>
77 #include <TColStd_ListOfInteger.hxx>
78 #include <TColStd_SequenceOfReal.hxx>
83 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
84 const Handle(GeomAdaptor_HSurface)& HS2,
92 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
93 const Standard_Integer ideb,
94 const Standard_Integer ifin);
97 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
98 const Standard_Integer ideb,
99 const Standard_Integer ifin,
100 const Standard_Boolean onFirst);
103 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
107 Standard_Boolean DecompositionOfWLine (const Handle(IntPatch_WLine)& theWLine,
108 const Handle(GeomAdaptor_HSurface)& theSurface1,
109 const Handle(GeomAdaptor_HSurface)& theSurface2,
110 const Standard_Real aTolSum,
111 const GeomInt_LineConstructor& theLConstructor,
112 IntPatch_SequenceOfLine& theNewLines);
115 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
116 const Standard_Real parmin,
117 const Standard_Real parmax,
118 const Standard_Real thePeriod,
119 Standard_Real& theOffset) ;
121 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
122 const Standard_Real theFirstBoundary,
123 const Standard_Real theSecondBoundary,
124 const Standard_Real theResolution,
125 Standard_Boolean& IsOnFirstBoundary);
128 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
129 const gp_Pnt2d& theLastPoint,
130 const Standard_Real theUmin,
131 const Standard_Real theUmax,
132 const Standard_Real theVmin,
133 const Standard_Real theVmax,
134 gp_Pnt2d& theNewPoint);
138 void AdjustUPeriodic (const Handle(Geom_Surface)& aS,
139 Handle(Geom2d_Curve)& aC2D);
141 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1,
142 IntSurf_Quadric& quad1);
144 class ProjectPointOnSurf
147 ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {}
148 void Init(const Handle(Geom_Surface)& Surface,
149 const Standard_Real Umin,
150 const Standard_Real Usup,
151 const Standard_Real Vmin,
152 const Standard_Real Vsup);
154 void Perform(const gp_Pnt& P);
155 Standard_Boolean IsDone () const { return myIsDone; }
156 void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const;
157 Standard_Real LowerDistance() const;
159 Standard_Boolean myIsDone;
160 Standard_Integer myIndex;
161 Extrema_ExtPS myExtPS;
162 GeomAdaptor_Surface myGeomAdaptor;
165 //=======================================================================
168 //=======================================================================
169 void ProjectPointOnSurf::Init (const Handle(Geom_Surface)& Surface,
170 const Standard_Real Umin,
171 const Standard_Real Usup,
172 const Standard_Real Vmin,
173 const Standard_Real Vsup )
175 const Standard_Real Tolerance = Precision::PConfusion();
177 myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
178 myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
179 myIsDone = Standard_False;
181 //=======================================================================
184 //=======================================================================
185 void ProjectPointOnSurf::Init ()
187 myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0);
189 // evaluate the lower distance and its index;
190 Standard_Real Dist2Min = myExtPS.SquareDistance(1);
192 for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++)
194 const Standard_Real Dist2 = myExtPS.SquareDistance(i);
195 if (Dist2 < Dist2Min) {
202 //=======================================================================
205 //=======================================================================
206 void ProjectPointOnSurf::Perform(const gp_Pnt& P)
211 //=======================================================================
212 //function : LowerDistanceParameters
214 //=======================================================================
215 void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U,
216 Standard_Real& V ) const
218 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters");
219 (myExtPS.Point(myIndex)).Parameter(U,V);
221 //=======================================================================
222 //function : LowerDistance
224 //=======================================================================
225 Standard_Real ProjectPointOnSurf::LowerDistance() const
227 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance");
228 return sqrt(myExtPS.SquareDistance(myIndex));
232 //=======================================================================
233 //function : MakeCurve
235 //=======================================================================
236 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
237 const Handle(Adaptor3d_TopolTool) & dom1,
238 const Handle(Adaptor3d_TopolTool) & dom2,
239 const Standard_Real Tol,
240 const Standard_Boolean Approx,
241 const Standard_Boolean ApproxS1,
242 const Standard_Boolean ApproxS2)
245 Standard_Boolean myApprox1, myApprox2, myApprox;
246 Standard_Real Tolpc, myTolApprox;
248 Handle(Geom2d_BSplineCurve) H1;
249 Handle(Geom_Surface) aS1, aS2;
255 myTolApprox=0.0000001;
257 aS1=myHS1->ChangeSurface().Surface();
258 aS2=myHS2->ChangeSurface().Surface();
260 Handle(IntPatch_Line) L = myIntersector.Line(Index);
263 if(typl==IntPatch_Walking) {
264 Handle(IntPatch_Line) anewL =
265 ComputePurgedWLine(Handle(IntPatch_WLine)::DownCast(L));
274 myLConstruct.Perform(L);
275 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
280 Standard_Integer i, j, aNbParts;
281 Standard_Real fprm, lprm;
282 Handle(Geom_Curve) newc;
285 //########################################
286 // Line, Parabola, Hyperbola
287 //########################################
289 case IntPatch_Parabola:
290 case IntPatch_Hyperbola: {
291 if (typl == IntPatch_Lin) {
292 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
294 else if (typl == IntPatch_Parabola) {
295 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
297 else if (typl == IntPatch_Hyperbola) {
298 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
301 aNbParts=myLConstruct.NbParts();
302 for (i=1; i<=aNbParts; i++) {
303 myLConstruct.Part(i, fprm, lprm);
305 if (!Precision::IsNegativeInfinite(fprm) &&
306 !Precision::IsPositiveInfinite(lprm)) {
307 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
311 Handle (Geom2d_Curve) C2d;
312 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
313 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
314 myTolReached2d=Tolpc;
316 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
323 Handle (Geom2d_Curve) C2d;
324 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
325 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
326 myTolReached2d=Tolpc;
329 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
334 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
337 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
338 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
339 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
340 typS1 == GeomAbs_OffsetSurface ||
341 typS1 == GeomAbs_SurfaceOfRevolution ||
342 typS2 == GeomAbs_SurfaceOfExtrusion ||
343 typS2 == GeomAbs_OffsetSurface ||
344 typS2 == GeomAbs_SurfaceOfRevolution) {
350 Standard_Boolean bFNIt, bLPIt;
351 Standard_Real aTestPrm, dT=100.;
352 Standard_Real u1, v1, u2, v2, TolX;
354 bFNIt=Precision::IsNegativeInfinite(fprm);
355 bLPIt=Precision::IsPositiveInfinite(lprm);
359 if (bFNIt && !bLPIt) {
362 else if (!bFNIt && bLPIt) {
366 gp_Pnt ptref(newc->Value(aTestPrm));
368 TolX = Precision::Confusion();
369 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
370 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
372 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
380 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
381 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
384 //########################################
385 // Circle and Ellipse
386 //########################################
387 case IntPatch_Circle:
388 case IntPatch_Ellipse: {
390 if (typl == IntPatch_Circle) {
391 newc = new Geom_Circle
392 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
395 newc = new Geom_Ellipse
396 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
399 Standard_Real aPeriod, aRealEpsilon;
401 aRealEpsilon=RealEpsilon();
404 aNbParts=myLConstruct.NbParts();
406 for (i=1; i<=aNbParts; i++) {
407 myLConstruct.Part(i, fprm, lprm);
409 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
410 //==============================================
411 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
415 fprm=aTC3D->FirstParameter();
416 lprm=aTC3D->LastParameter ();
419 Handle (Geom2d_Curve) C2d;
420 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
421 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
422 myTolReached2d=Tolpc;
431 Handle (Geom2d_Curve) C2d;
432 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
433 if(Tolpc>myTolReached2d || myTolReached2d==0) {
434 myTolReached2d=Tolpc;
441 //==============================================
442 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
444 else {// on regarde si on garde
447 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
448 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
451 fprm=aTC3D->FirstParameter();
452 lprm=aTC3D->LastParameter ();
455 Handle (Geom2d_Curve) C2d;
456 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
457 if(Tolpc>myTolReached2d || myTolReached2d==0) {
458 myTolReached2d=Tolpc;
467 Handle (Geom2d_Curve) C2d;
468 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
469 if(Tolpc>myTolReached2d || myTolReached2d==0) {
470 myTolReached2d=Tolpc;
481 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
483 aTwoPIdiv17=2.*M_PI/17.;
485 for (j=0; j<=17; j++) {
486 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
487 TolX = Precision::Confusion();
489 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
490 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
492 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
496 //==============================================
498 Handle (Geom2d_Curve) C2d;
499 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
500 if(Tolpc>myTolReached2d || myTolReached2d==0) {
501 myTolReached2d=Tolpc;
510 Handle (Geom2d_Curve) C2d;
511 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
512 if(Tolpc>myTolReached2d || myTolReached2d==0) {
513 myTolReached2d=Tolpc;
522 }// end of for (Standard_Integer j=0; j<=17; j++)
523 }// end of else { on regarde si on garde
524 }// for (i=1; i<=myLConstruct.NbParts(); i++)
525 }// IntPatch_Circle: IntPatch_Ellipse
528 //########################################
530 //########################################
531 case IntPatch_Analytic: {
532 IntSurf_Quadric quad1,quad2;
534 GetQuadric(myHS1, quad1);
535 GetQuadric(myHS2, quad2);
537 IntPatch_ALineToWLine convert (quad1, quad2);
540 Handle(Geom2d_BSplineCurve) aH1, aH2;
542 aNbParts=myLConstruct.NbParts();
543 for (i=1; i<=aNbParts; i++) {
544 myLConstruct.Part(i, fprm, lprm);
545 Handle(IntPatch_WLine) WL =
546 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
549 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
553 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
555 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
561 else { // myApprox=TRUE
562 GeomInt_WLApprox theapp3d;
563 Standard_Real tol2d = myTolApprox;
565 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
567 aNbParts=myLConstruct.NbParts();
568 for (i=1; i<=aNbParts; i++) {
569 myLConstruct.Part(i, fprm, lprm);
570 Handle(IntPatch_WLine) WL =
571 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
573 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
574 if (!theapp3d.IsDone()) {
576 Handle(Geom2d_BSplineCurve) aH1, aH2;
579 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
583 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
585 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
591 if(myApprox1 || myApprox2) {
592 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
593 myTolReached2d = theapp3d.TolReached2d();
597 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
598 myTolReached3d = theapp3d.TolReached3d();
601 Standard_Integer aNbMultiCurves, nbpoles;
602 aNbMultiCurves=theapp3d.NbMultiCurves();
603 for (j=1; j<=aNbMultiCurves; j++) {
604 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
606 nbpoles = mbspc.NbPoles();
607 TColgp_Array1OfPnt tpoles(1, nbpoles);
608 mbspc.Curve(1, tpoles);
609 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
611 mbspc.Multiplicities(),
614 GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
615 Check.FixTangent(Standard_True,Standard_True);
620 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
621 mbspc.Curve(2,tpoles2d);
622 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
624 mbspc.Multiplicities(),
627 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
628 newCheck.FixTangent(Standard_True,Standard_True);
636 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
637 Standard_Integer TwoOrThree;
638 TwoOrThree=myApprox1 ? 3 : 2;
639 mbspc.Curve(TwoOrThree, tpoles2d);
640 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
642 mbspc.Multiplicities(),
645 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
646 newCheck.FixTangent(Standard_True,Standard_True);
654 }// for (j=1; j<=aNbMultiCurves; j++) {
655 }// else from if (!theapp3d.IsDone())
656 }// for (i=1; i<=aNbParts; i++) {
657 }// else { // myApprox=TRUE
658 }// case IntPatch_Analytic:
661 //########################################
663 //########################################
664 case IntPatch_Walking:{
665 Handle(IntPatch_WLine) WL =
666 Handle(IntPatch_WLine)::DownCast(L);
668 Standard_Integer ifprm, ilprm;
671 aNbParts=myLConstruct.NbParts();
672 for (i=1; i<=aNbParts; i++) {
673 myLConstruct.Part(i, fprm, lprm);
674 ifprm=(Standard_Integer)fprm;
675 ilprm=(Standard_Integer)lprm;
677 Handle(Geom2d_BSplineCurve) aH1, aH2;
680 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
683 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
686 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
695 Standard_Boolean bIsDecomposited;
696 Standard_Integer nbiter, aNbSeqOfL;
697 GeomInt_WLApprox theapp3d;
698 IntPatch_SequenceOfLine aSeqOfL;
699 Standard_Real tol2d, aTolSS;
704 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
707 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
711 DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
713 aNbParts=myLConstruct.NbParts();
714 aNbSeqOfL=aSeqOfL.Length();
716 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
718 for(i = 1; i <= nbiter; i++) {
719 if(bIsDecomposited) {
720 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
722 ilprm = WL->NbPnts();
725 myLConstruct.Part(i, fprm, lprm);
726 ifprm = (Standard_Integer)fprm;
727 ilprm = (Standard_Integer)lprm;
730 //-- Si une des surfaces est un plan , on approxime en 2d
731 //-- sur cette surface et on remonte les points 2d en 3d.
732 GeomAbs_SurfaceType typs1, typs2;
733 typs1 = myHS1->Surface().GetType();
734 typs2 = myHS2->Surface().GetType();
736 if(typs1 == GeomAbs_Plane) {
737 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
738 Standard_True, myApprox2,
741 else if(typs2 == GeomAbs_Plane) {
742 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
743 myApprox1,Standard_True,
749 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
750 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
752 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
753 //Standard_Boolean bUseSurfaces;
754 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
755 //if (bUseSurfaces) {
756 //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
761 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
766 if (!theapp3d.IsDone()) {
768 Handle(Geom2d_BSplineCurve) aH1, aH2;
770 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
772 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
775 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
781 }//if (!theapp3d.IsDone())
784 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
785 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
786 myTolReached2d = theapp3d.TolReached2d();
789 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
790 myTolReached3d = myTolReached2d;
792 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
793 myTolReached3d = theapp3d.TolReached3d();
796 Standard_Integer aNbMultiCurves, nbpoles;
798 aNbMultiCurves=theapp3d.NbMultiCurves();
799 for (j=1; j<=aNbMultiCurves; j++) {
800 if(typs1 == GeomAbs_Plane) {
801 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
802 nbpoles = mbspc.NbPoles();
804 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
805 TColgp_Array1OfPnt tpoles(1,nbpoles);
807 mbspc.Curve(1,tpoles2d);
808 const gp_Pln& Pln = myHS1->Surface().Plane();
811 for(ik = 1; ik<= nbpoles; ik++) {
813 ElSLib::Value(tpoles2d.Value(ik).X(),
814 tpoles2d.Value(ik).Y(),
818 Handle(Geom_BSplineCurve) BS =
819 new Geom_BSplineCurve(tpoles,
821 mbspc.Multiplicities(),
823 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
824 Check.FixTangent(Standard_True, Standard_True);
829 Handle(Geom2d_BSplineCurve) BS1 =
830 new Geom2d_BSplineCurve(tpoles2d,
832 mbspc.Multiplicities(),
834 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
835 Check1.FixTangent(Standard_True,Standard_True);
837 AdjustUPeriodic (aS1, BS1);
846 mbspc.Curve(2, tpoles2d);
848 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
850 mbspc.Multiplicities(),
852 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
853 newCheck.FixTangent(Standard_True,Standard_True);
855 AdjustUPeriodic (aS2, BS2);
862 }//if(typs1 == GeomAbs_Plane)
864 else if(typs2 == GeomAbs_Plane) {
865 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
866 nbpoles = mbspc.NbPoles();
868 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
869 TColgp_Array1OfPnt tpoles(1,nbpoles);
870 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
871 const gp_Pln& Pln = myHS2->Surface().Plane();
874 for(ik = 1; ik<= nbpoles; ik++) {
876 ElSLib::Value(tpoles2d.Value(ik).X(),
877 tpoles2d.Value(ik).Y(),
882 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
884 mbspc.Multiplicities(),
886 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
887 Check.FixTangent(Standard_True,Standard_True);
892 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
894 mbspc.Multiplicities(),
896 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
897 Check1.FixTangent(Standard_True,Standard_True);
900 AdjustUPeriodic (aS2, BS1);
909 mbspc.Curve(1,tpoles2d);
910 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
912 mbspc.Multiplicities(),
914 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
915 Check2.FixTangent(Standard_True,Standard_True);
918 AdjustUPeriodic (aS1, BS2);
925 } // else if(typs2 == GeomAbs_Plane)
927 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
928 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
929 nbpoles = mbspc.NbPoles();
930 TColgp_Array1OfPnt tpoles(1,nbpoles);
931 mbspc.Curve(1,tpoles);
932 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
934 mbspc.Multiplicities(),
936 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
937 Check.FixTangent(Standard_True,Standard_True);
940 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
941 BS->EndPoint().XYZ().SquareModulus());
942 Standard_Real eps = Epsilon(aDist);
943 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
945 // Avoid creating B-splines containing two coincident poles only
946 if (mbspc.Degree() == 1 && nbpoles == 2)
949 if (!BS->IsClosed() && !BS->IsPeriodic())
952 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
954 BS->SetPole(BS->NbPoles(), aPm);
960 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
961 mbspc.Curve(2,tpoles2d);
962 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
964 mbspc.Multiplicities(),
966 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
967 newCheck.FixTangent(Standard_True,Standard_True);
969 AdjustUPeriodic (aS1, BS1);
977 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
978 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
979 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
981 mbspc.Multiplicities(),
983 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
984 newCheck.FixTangent(Standard_True,Standard_True);
986 AdjustUPeriodic (aS2, BS2);
993 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
994 }// for (j=1; j<=aNbMultiCurves; j++
1001 case IntPatch_Restriction:
1003 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
1004 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
1005 Standard_Boolean isAnalS1 = Standard_False;
1009 case GeomAbs_Cylinder:
1010 case GeomAbs_Sphere:
1012 case GeomAbs_Torus: isAnalS1 = Standard_True; break;
1016 Standard_Integer isAnalS2 = Standard_False;
1020 case GeomAbs_Cylinder:
1021 case GeomAbs_Sphere:
1023 case GeomAbs_Torus: isAnalS2 = Standard_True; break;
1027 Handle(IntPatch_RLine) RL =
1028 Handle(IntPatch_RLine)::DownCast(L);
1029 Handle(Geom_Curve) aC3d;
1030 Handle(Geom2d_Curve) aC2d1, aC2d2;
1031 Standard_Real aTolReached;
1032 TreatRLine(RL, myHS1, myHS2, aC3d,
1033 aC2d1, aC2d2, aTolReached);
1038 Bnd_Box2d aBox1, aBox2;
1040 const Standard_Real aU1f = myHS1->FirstUParameter(),
1041 aV1f = myHS1->FirstVParameter(),
1042 aU1l = myHS1->LastUParameter(),
1043 aV1l = myHS1->LastVParameter();
1044 const Standard_Real aU2f = myHS2->FirstUParameter(),
1045 aV2f = myHS2->FirstVParameter(),
1046 aU2l = myHS2->LastUParameter(),
1047 aV2l = myHS2->LastVParameter();
1049 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1050 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1051 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1052 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1054 GeomInt_VectorOfReal anArrayOfParameters;
1056 //We consider here that the intersection line is same-parameter-line
1057 anArrayOfParameters.Append(aC3d->FirstParameter());
1058 anArrayOfParameters.Append(aC3d->LastParameter());
1060 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1062 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1065 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1067 const Standard_Real aParF = anArrayOfParameters(anInd),
1068 aParL = anArrayOfParameters(anInd+1);
1070 if((aParL - aParF) <= Precision::PConfusion())
1073 const Standard_Real aPar = 0.5*(aParF + aParL);
1076 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1079 aC2d1->D0(aPar, aPt);
1081 if(aBox1.IsOut(aPt))
1085 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1090 aC2d2->D0(aPar, aPt);
1092 if(aBox2.IsOut(aPt))
1096 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1099 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1101 sline.Append(aCurv3d);
1102 slineS1.Append(aCurv2d1);
1103 slineS2.Append(aCurv2d2);
1110 //=======================================================================
1111 //function : AdjustUPeriodic
1113 //=======================================================================
1114 void AdjustUPeriodic (const Handle(Geom_Surface)& aS, Handle(Geom2d_Curve)& aC2D)
1116 if (aC2D.IsNull() || !aS->IsUPeriodic())
1119 const Standard_Real aEps=Precision::PConfusion();//1.e-9
1120 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
1122 Standard_Real umin,umax,vmin,vmax;
1123 aS->Bounds(umin,umax,vmin,vmax);
1124 const Standard_Real aPeriod = aS->UPeriod();
1126 const Standard_Real aT1=aC2D->FirstParameter();
1127 const Standard_Real aT2=aC2D->LastParameter();
1128 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
1129 const gp_Pnt2d aPx=aC2D->Value(aTx);
1131 Standard_Real aUx=aPx.X();
1132 if (fabs(aUx)<aEpsilon)
1134 if (fabs(aUx-aPeriod)<aEpsilon)
1137 Standard_Real dU=0.;
1138 while(aUx <(umin-aEps)) {
1142 while(aUx>(umax+aEps)) {
1148 gp_Vec2d aV2D(dU, 0.);
1149 aC2D->Translate(aV2D);
1154 //=======================================================================
1155 //function : GetQuadric
1157 //=======================================================================
1158 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
1160 switch (HS1->Surface().GetType())
1162 case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break;
1163 case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
1164 case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break;
1165 case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break;
1166 case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break;
1167 default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
1171 //=======================================================================
1172 //function : Parameters
1174 //=======================================================================
1175 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
1176 const Handle(GeomAdaptor_HSurface)& HS2,
1177 const gp_Pnt& Ptref,
1183 IntSurf_Quadric quad1,quad2;
1185 GetQuadric(HS1, quad1);
1186 GetQuadric(HS2, quad2);
1188 quad1.Parameters(Ptref,U1,V1);
1189 quad2.Parameters(Ptref,U2,V2);
1192 //=======================================================================
1193 //function : MakeBSpline
1195 //=======================================================================
1196 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
1197 const Standard_Integer ideb,
1198 const Standard_Integer ifin)
1200 const Standard_Integer nbpnt = ifin-ideb+1;
1201 TColgp_Array1OfPnt poles(1,nbpnt);
1202 TColStd_Array1OfReal knots(1,nbpnt);
1203 TColStd_Array1OfInteger mults(1,nbpnt);
1204 Standard_Integer i = 1, ipidebm1 = ideb;
1205 for(; i<=nbpnt; ipidebm1++, i++)
1207 poles(i) = WL->Point(ipidebm1).Value();
1211 mults(1) = mults(nbpnt) = 2;
1212 return new Geom_BSplineCurve(poles,knots,mults,1);
1215 //=======================================================================
1216 //function : MakeBSpline2d
1218 //=======================================================================
1219 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1220 const Standard_Integer ideb,
1221 const Standard_Integer ifin,
1222 const Standard_Boolean onFirst)
1224 const Standard_Integer nbpnt = ifin-ideb+1;
1225 TColgp_Array1OfPnt2d poles(1,nbpnt);
1226 TColStd_Array1OfReal knots(1,nbpnt);
1227 TColStd_Array1OfInteger mults(1,nbpnt);
1228 Standard_Integer i = 1, ipidebm1 = ideb;
1229 for(; i <= nbpnt; ipidebm1++, i++)
1233 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1235 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1236 poles(i).SetCoord(U, V);
1240 mults(1) = mults(nbpnt) = 2;
1241 return new Geom2d_BSplineCurve(poles,knots,mults,1);
1244 //=========================================================================
1245 // static function : ComputePurgedWLine
1246 // purpose : Removes equal points (leave one of equal points) from theWLine
1247 // and recompute vertex parameters.
1248 // Returns new WLine or null WLine if the number
1249 // of the points is less than 2.
1250 //=========================================================================
1251 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine)
1253 Handle(IntPatch_WLine) aResult;
1254 Handle(IntPatch_WLine) aLocalWLine;
1255 Handle(IntPatch_WLine) aTmpWLine = theWLine;
1257 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1258 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1259 Standard_Integer i, k, v, nb, nbvtx;
1260 nbvtx = theWLine->NbVertex();
1261 nb = theWLine->NbPnts();
1263 for(i = 1; i <= nb; i++) {
1264 aLineOn2S->Add(theWLine->Point(i));
1267 for(v = 1; v <= nbvtx; v++) {
1268 aLocalWLine->AddVertex(theWLine->Vertex(v));
1271 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
1272 Standard_Integer aStartIndex = i + 1;
1273 Standard_Integer anEndIndex = i + 5;
1274 nb = aLineOn2S->NbPoints();
1275 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
1277 if((aStartIndex >= nb) || (anEndIndex <= 1)) {
1282 while(k <= anEndIndex) {
1285 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
1286 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
1288 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
1289 aTmpWLine = aLocalWLine;
1290 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1292 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
1293 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
1294 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
1296 if(avertexindex >= k) {
1297 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
1299 aLocalWLine->AddVertex(aVertex);
1301 aLineOn2S->RemovePoint(k);
1310 if(aLineOn2S->NbPoints() > 1) {
1311 aResult = aLocalWLine;
1315 //=======================================================================
1316 //function : DecompositionOfWLine
1318 //=======================================================================
1319 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
1320 const Handle(GeomAdaptor_HSurface)& theSurface1,
1321 const Handle(GeomAdaptor_HSurface)& theSurface2,
1322 const Standard_Real aTolSum,
1323 const GeomInt_LineConstructor& theLConstructor,
1324 IntPatch_SequenceOfLine& theNewLines)
1326 typedef NCollection_List<Standard_Integer> ListOfInteger;
1327 //have to use std::vector, not NCollection_Vector in order to use copy constructor of
1328 //ListOfInteger which will be created with specific allocator instance
1329 typedef std::vector<ListOfInteger, NCollection_StdAllocator<
1330 ListOfInteger> > ArrayOfListOfInteger;
1332 Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary;
1333 Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex;
1334 Standard_Real aTol, umin, umax, vmin, vmax;
1336 //an inc allocator, it will contain wasted space (upon list's Clear()) but it should
1337 //still be faster than the standard allocator, and wasted memory should not be
1338 //significant and will be limited by time span of this function;
1339 //this is a separate allocator from the anIncAlloc below what provides better data
1340 //locality in the latter (by avoiding wastes which will only be in anIdxAlloc)
1341 Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator();
1342 ListOfInteger aListOfPointIndex (anIdxAlloc);
1344 //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2;
1345 ProjectPointOnSurf aPrj1, aPrj2;
1346 Handle(Geom_Surface) aSurf1, aSurf2;
1348 aNbParts=theLConstructor.NbParts();
1349 aNbPnts=theWLine->NbPnts();
1351 if((!aNbPnts) || (!aNbParts)){
1352 return Standard_False;
1355 Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
1356 NCollection_StdAllocator<ListOfInteger> anAlloc (anIncAlloc);
1357 const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from
1358 ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc);
1360 NCollection_LocalArray<Standard_Integer> anArrayOfLineTypeArr (aNbPnts + 1);
1361 Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr;
1364 aTol = Precision::Confusion();
1366 aSurf1 = theSurface1->ChangeSurface().Surface();
1367 aSurf1->Bounds(umin, umax, vmin, vmax);
1368 aPrj1.Init(aSurf1, umin, umax, vmin, vmax);
1370 aSurf2 = theSurface2->ChangeSurface().Surface();
1371 aSurf2->Bounds(umin, umax, vmin, vmax);
1372 aPrj2.Init(aSurf2, umin, umax, vmin, vmax);
1375 bIsPrevPointOnBoundary=Standard_False;
1376 for(pit=1; pit<=aNbPnts; pit++) {
1377 const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
1378 bIsCurrentPointOnBoundary=Standard_False;
1380 // whether aPoint is on boundary or not
1382 for(i=0; i<2; i++) {// exploration Surface 1,2
1383 Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
1384 aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
1386 for(j=0; j<2; j++) {// exploration of coordinate U,V
1387 Standard_Boolean isperiodic;
1389 isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1394 Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
1395 Standard_Real aParameter, anoffset, anAdjustPar;
1396 Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary;
1398 aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1399 aPeriod = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1400 alowerboundary = (!j) ? umin : vmin;
1401 aupperboundary = (!j) ? umax : vmax;
1405 aPoint.ParametersOnS1(U, V);
1408 aPoint.ParametersOnS2(U, V);
1411 aParameter = (!j) ? U : V;
1413 anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1415 bIsOnFirstBoundary=Standard_True;
1418 IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
1420 if(bIsPointOnBoundary) {
1421 bIsCurrentPointOnBoundary = Standard_True;
1424 }// for(j=0; j<2; j++)
1426 if(bIsCurrentPointOnBoundary){
1429 }// for(i=0; i<2; i++)
1431 if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
1433 if(!aListOfPointIndex.IsEmpty()) {
1435 anArrayOfLines[nblines] = aListOfPointIndex;
1436 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1437 aListOfPointIndex.Clear();
1439 bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
1441 aListOfPointIndex.Append(pit);
1442 } // for(pit=1; pit<=aNbPnts; pit++)
1444 aNbListOfPointIndex=aListOfPointIndex.Extent();
1445 if(aNbListOfPointIndex) {
1447 anArrayOfLines[nblines].Assign (aListOfPointIndex);
1448 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1449 aListOfPointIndex.Clear();
1453 return Standard_False;
1456 // Correct wlines.begin
1457 Standard_Integer aLineType;
1458 TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
1459 Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator());
1461 for(i = 1; i <= nblines; i++) {
1462 aLineType=anArrayOfLineType[i];
1467 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1468 if(aListOfIndex.Extent() < 2) {
1472 TColStd_ListOfInteger aListOfFLIndex;
1473 Standard_Integer aneighbourindex, aLineTypeNeib;
1475 for(j = 0; j < 2; j++) {// neighbour line choice
1476 aneighbourindex = (!j) ? (i-1) : (i+1);
1477 if((aneighbourindex < 1) || (aneighbourindex > nblines)){
1481 aLineTypeNeib=anArrayOfLineType[aneighbourindex];
1486 const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex];
1487 Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First();
1488 const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
1489 // check if need use derivative.begin .end [absence]
1491 IntSurf_PntOn2S aNewP = aPoint;
1492 Standard_Integer surfit, parit;
1494 for(surfit = 0; surfit < 2; ++surfit) {
1496 Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2;
1498 umin = aGASurface->FirstUParameter();
1499 umax = aGASurface->LastUParameter();
1500 vmin = aGASurface->FirstVParameter();
1501 vmax = aGASurface->LastVParameter();
1502 Standard_Real U=0., V=0.;
1505 aNewP.ParametersOnS1(U, V);
1508 aNewP.ParametersOnS2(U, V);
1511 Standard_Integer nbboundaries = 0;
1512 Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
1513 Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
1515 for(parit = 0; parit < 2; parit++) {
1516 Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1518 Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1519 Standard_Real alowerboundary = (!parit) ? umin : vmin;
1520 Standard_Real aupperboundary = (!parit) ? umax : vmax;
1522 Standard_Real aParameter = (!parit) ? U : V;
1523 Standard_Boolean bIsOnFirstBoundary = Standard_True;
1526 if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1527 bIsUBoundary = (!parit);
1528 bIsFirstBoundary = bIsOnFirstBoundary;
1533 Standard_Real aPeriod = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1534 Standard_Real anoffset = 0.;
1535 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1537 if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1538 bIsUBoundary = (parit == 0);
1539 bIsFirstBoundary = bIsOnFirstBoundary;
1545 Standard_Boolean bComputeLineEnd = Standard_False;
1547 if(nbboundaries == 2) {
1548 bComputeLineEnd = Standard_True;
1550 else if(nbboundaries == 1) {
1551 Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1554 Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
1555 Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
1556 Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1557 Standard_Real aParameter = (bIsUBoundary) ? U : V;
1558 Standard_Real anoffset = 0.;
1559 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1561 Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
1562 Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
1563 anotherPar += anoffset;
1564 Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1565 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
1566 Standard_Real nU1, nV1;
1569 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1571 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1573 Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
1574 Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
1575 bComputeLineEnd = Standard_True;
1576 Standard_Boolean bCheckAngle1 = Standard_False;
1577 Standard_Boolean bCheckAngle2 = Standard_False;
1579 Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
1580 Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
1582 if(((adist1 - adist2) > Precision::PConfusion()) &&
1583 (adist2 < (aPeriod / 4.))) {
1584 bCheckAngle1 = Standard_True;
1585 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
1587 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1588 aNewP.SetValue((surfit == 0), anewU, anewV);
1589 bCheckAngle1 = Standard_False;
1592 else if(adist1 < (aPeriod / 4.)) {
1593 bCheckAngle2 = Standard_True;
1594 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
1596 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1597 bCheckAngle2 = Standard_False;
1601 if(bCheckAngle1 || bCheckAngle2) {
1602 // assume there are at least two points in line (see "if" above)
1603 Standard_Integer anindexother = aneighbourpointindex;
1605 while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
1606 anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
1607 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
1608 Standard_Real nU2, nV2;
1611 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1613 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1614 gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
1616 if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
1620 Standard_Real anAngle = aNewVec.Angle(aVecOld);
1622 if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
1625 Standard_Real U1, U2, V1, V2;
1626 IntSurf_PntOn2S atmppoint = aNewP;
1627 atmppoint.SetValue((surfit == 0), anewU, anewV);
1628 atmppoint.Parameters(U1, V1, U2, V2);
1629 gp_Pnt P1 = theSurface1->Value(U1, V1);
1630 gp_Pnt P2 = theSurface2->Value(U2, V2);
1631 gp_Pnt P0 = aPoint.Value();
1633 if(P0.IsEqual(P1, aTol) &&
1634 P0.IsEqual(P2, aTol) &&
1635 P1.IsEqual(P2, aTol)) {
1636 bComputeLineEnd = Standard_False;
1637 aNewP.SetValue((surfit == 0), anewU, anewV);
1642 bComputeLineEnd = Standard_False;
1647 } // end while(anindexother...)
1652 if(bComputeLineEnd) {
1653 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1654 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
1655 Standard_Real nU1, nV1;
1658 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1660 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1661 gp_Pnt2d ap1(nU1, nV1);
1662 gp_Pnt2d ap2(nU1, nV1);
1663 Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
1665 while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
1666 aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
1667 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
1668 Standard_Real nU2, nV2;
1671 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1673 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1677 if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
1682 Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
1686 Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
1687 //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1688 ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1689 Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
1691 gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
1692 aProjector.Perform(aP3d);
1694 if(aProjector.IsDone()) {
1695 if(aProjector.LowerDistance() < aCriteria) {
1696 Standard_Real foundU = U, foundV = V;
1697 aProjector.LowerDistanceParameters(foundU, foundV);
1700 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
1702 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
1708 aSeqOfPntOn2S->Add(aNewP);
1709 aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
1711 anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
1713 // Correct wlines.end
1715 // Split wlines.begin
1716 for(j = 1; j <= theLConstructor.NbParts(); j++) {
1717 Standard_Real fprm = 0., lprm = 0.;
1718 theLConstructor.Part(j, fprm, lprm);
1719 Standard_Integer ifprm = (Standard_Integer)fprm;
1720 Standard_Integer ilprm = (Standard_Integer)lprm;
1722 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1724 for(i = 1; i <= nblines; i++) {
1725 if(anArrayOfLineType[i] != 0) {
1728 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1730 if(aListOfIndex.Extent() < 2) {
1733 const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
1734 Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
1735 Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
1737 if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
1738 bhasfirstpoint = (i != 1);
1741 if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
1742 bhaslastpoint = (i != nblines);
1744 Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
1745 Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
1747 if(!bIsFirstInside && !bIsLastInside) {
1748 if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
1749 // append whole line, and boundaries if neccesary
1750 if(bhasfirstpoint) {
1751 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1754 ListOfInteger::Iterator anIt(aListOfIndex);
1756 for(; anIt.More(); anIt.Next()) {
1757 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1762 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1766 // check end of split line (end is almost always)
1767 Standard_Integer aneighbour = i + 1;
1768 Standard_Boolean bIsEndOfLine = Standard_True;
1770 if(aneighbour <= nblines) {
1771 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1773 if((anArrayOfLineType[aneighbour] != 0) &&
1774 (aListOfNeighbourIndex.IsEmpty())) {
1775 bIsEndOfLine = Standard_False;
1780 if(aLineOn2S->NbPoints() > 1) {
1781 Handle(IntPatch_WLine) aNewWLine =
1782 new IntPatch_WLine(aLineOn2S, Standard_False);
1783 theNewLines.Append(aNewWLine);
1785 aLineOn2S = new IntSurf_LineOn2S();
1790 // end if(!bIsFirstInside && !bIsLastInside)
1792 if(bIsFirstInside && bIsLastInside) {
1793 // append inside points between ifprm and ilprm
1794 ListOfInteger::Iterator anIt(aListOfIndex);
1796 for(; anIt.More(); anIt.Next()) {
1797 if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
1799 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1805 if(bIsFirstInside) {
1806 // append points from ifprm to last point + boundary point
1807 ListOfInteger::Iterator anIt(aListOfIndex);
1809 for(; anIt.More(); anIt.Next()) {
1810 if(anIt.Value() < ifprm)
1812 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1817 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1820 // check end of split line (end is almost always)
1821 Standard_Integer aneighbour = i + 1;
1822 Standard_Boolean bIsEndOfLine = Standard_True;
1824 if(aneighbour <= nblines) {
1825 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1827 if((anArrayOfLineType[aneighbour] != 0) &&
1828 (aListOfNeighbourIndex.IsEmpty())) {
1829 bIsEndOfLine = Standard_False;
1834 if(aLineOn2S->NbPoints() > 1) {
1835 Handle(IntPatch_WLine) aNewWLine =
1836 new IntPatch_WLine(aLineOn2S, Standard_False);
1837 theNewLines.Append(aNewWLine);
1839 aLineOn2S = new IntSurf_LineOn2S();
1842 // end if(bIsFirstInside)
1845 // append points from first boundary point to ilprm
1846 if(bhasfirstpoint) {
1847 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1850 ListOfInteger::Iterator anIt(aListOfIndex);
1852 for(; anIt.More(); anIt.Next()) {
1853 if(anIt.Value() > ilprm)
1855 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1859 //end if(bIsLastInside)
1863 if(aLineOn2S->NbPoints() > 1) {
1864 Handle(IntPatch_WLine) aNewWLine =
1865 new IntPatch_WLine(aLineOn2S, Standard_False);
1866 theNewLines.Append(aNewWLine);
1872 Standard_Real fprm, lprm;
1873 Standard_Integer ifprm, ilprm, aNbPoints, aIndex;
1875 aNbParts=theLConstructor.NbParts();
1877 for(j = 1; j <= aNbParts; j++) {
1878 theLConstructor.Part(j, fprm, lprm);
1879 ifprm=(Standard_Integer)fprm;
1880 ilprm=(Standard_Integer)lprm;
1882 if ((ilprm-ifprm)==1) {
1883 for(i = 1; i <= nblines; i++) {
1884 aLineType=anArrayOfLineType[i];
1889 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1890 aNbPoints=aListOfIndex.Extent();
1892 aIndex=aListOfIndex.First();
1893 if (aIndex==ifprm || aIndex==ilprm) {
1894 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1895 const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm);
1896 const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm);
1897 aLineOn2S->Add(aP1);
1898 aLineOn2S->Add(aP2);
1899 Handle(IntPatch_WLine) aNewWLine =
1900 new IntPatch_WLine(aLineOn2S, Standard_False);
1901 theNewLines.Append(aNewWLine);
1908 return Standard_True;
1911 //=======================================================================
1912 //function : AdjustPeriodic
1914 //=======================================================================
1915 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
1916 const Standard_Real parmin,
1917 const Standard_Real parmax,
1918 const Standard_Real thePeriod,
1919 Standard_Real& theOffset)
1921 Standard_Real aresult = theParameter;
1923 while(aresult < parmin) {
1924 aresult += thePeriod;
1925 theOffset += thePeriod;
1927 while(aresult > parmax) {
1928 aresult -= thePeriod;
1929 theOffset -= thePeriod;
1934 //=======================================================================
1935 //function : IsPointOnBoundary
1937 //=======================================================================
1938 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
1939 const Standard_Real theFirstBoundary,
1940 const Standard_Real theSecondBoundary,
1941 const Standard_Real theResolution,
1942 Standard_Boolean& IsOnFirstBoundary)
1944 IsOnFirstBoundary = Standard_True;
1945 if(fabs(theParameter - theFirstBoundary) < theResolution)
1946 return Standard_True;
1947 if(fabs(theParameter - theSecondBoundary) < theResolution)
1949 IsOnFirstBoundary = Standard_False;
1950 return Standard_True;
1952 return Standard_False;
1954 //=======================================================================
1955 //function : FindPoint
1957 //=======================================================================
1958 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
1959 const gp_Pnt2d& theLastPoint,
1960 const Standard_Real theUmin,
1961 const Standard_Real theUmax,
1962 const Standard_Real theVmin,
1963 const Standard_Real theVmax,
1964 gp_Pnt2d& theNewPoint)
1966 gp_Vec2d aVec(theFirstPoint, theLastPoint);
1967 Standard_Integer i = 0, j = 0;
1969 for(i = 0; i < 4; i++) {
1970 gp_Vec2d anOtherVec;
1971 gp_Vec2d anOtherVecNormal;
1972 gp_Pnt2d aprojpoint = theLastPoint;
1975 anOtherVec.SetX(0.);
1976 anOtherVec.SetY(1.);
1977 anOtherVecNormal.SetX(1.);
1978 anOtherVecNormal.SetY(0.);
1981 aprojpoint.SetX(theUmin);
1983 aprojpoint.SetX(theUmax);
1986 anOtherVec.SetX(1.);
1987 anOtherVec.SetY(0.);
1988 anOtherVecNormal.SetX(0.);
1989 anOtherVecNormal.SetY(1.);
1992 aprojpoint.SetY(theVmin);
1994 aprojpoint.SetY(theVmax);
1996 gp_Vec2d anormvec = aVec;
1997 anormvec.Normalize();
1998 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
2000 if(fabs(adot1) < Precision::Angular())
2002 Standard_Real adist = 0.;
2005 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
2008 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
2010 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
2012 for(j = 0; j < 2; j++) {
2013 anoffset = (j == 0) ? anoffset : -anoffset;
2014 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
2015 gp_Vec2d acurvec(theLastPoint, acurpoint);
2018 Standard_Real aDotX, anAngleX, aPC;
2020 aDotX=aVec.Dot(acurvec);
2021 anAngleX=aVec.Angle(acurvec);
2022 aPC=Precision::PConfusion();
2024 if(aDotX > 0. && fabs(anAngleX) < aPC) {
2027 if((acurpoint.Y() >= theVmin) &&
2028 (acurpoint.Y() <= theVmax)) {
2029 theNewPoint = acurpoint;
2030 return Standard_True;
2034 if((acurpoint.X() >= theUmin) &&
2035 (acurpoint.X() <= theUmax)) {
2036 theNewPoint = acurpoint;
2037 return Standard_True;
2043 return Standard_False;
2046 //=======================================================================
2047 //function : ParametersOfNearestPointOnSurface
2049 //=======================================================================
2050 static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
2051 Standard_Real& theU,
2052 Standard_Real& theV)
2054 if(!theExtr.IsDone() || !theExtr.NbExt())
2055 return Standard_False;
2057 Standard_Integer anIndex = 1;
2058 Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
2059 for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
2061 Standard_Real aSQD = theExtr.SquareDistance(i);
2062 if (aSQD < aMinSQDist)
2069 theExtr.Point(anIndex).Parameter(theU, theV);
2071 return Standard_True;
2074 //=======================================================================
2075 //function : GetSegmentBoundary
2077 //=======================================================================
2078 static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
2079 const Handle(Geom2d_Curve)& theCurve,
2080 GeomInt_VectorOfReal& theArrayOfParameters)
2082 Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
2084 if(theSegm.HasFirstPoint())
2086 const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
2087 aU1 = anIPF.ParamOnFirst();
2090 if(theSegm.HasLastPoint())
2092 const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
2093 aU2 = anIPL.ParamOnFirst();
2096 theArrayOfParameters.Append(aU1);
2097 theArrayOfParameters.Append(aU2);
2100 //=======================================================================
2101 //function : IntersectCurveAndBoundary
2103 //=======================================================================
2104 static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
2105 const Handle(Geom2d_Curve)* const theArrBounds,
2106 const Standard_Integer theNumberOfCurves,
2107 const Standard_Real theTol,
2108 GeomInt_VectorOfReal& theArrayOfParameters)
2113 Geom2dAdaptor_Curve anAC1(theC2d);
2114 for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
2116 if(theArrBounds[aCurID].IsNull())
2119 Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
2120 Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
2122 if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
2125 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
2127 const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
2128 theArrayOfParameters.Append(aParam);
2131 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
2133 GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
2138 //=======================================================================
2139 //function : TreatRLine
2140 //purpose : Approx of Restriction line
2141 //=======================================================================
2142 void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
2143 const Handle(GeomAdaptor_HSurface)& theHS1,
2144 const Handle(GeomAdaptor_HSurface)& theHS2,
2145 Handle(Geom_Curve)& theC3d,
2146 Handle(Geom2d_Curve)& theC2d1,
2147 Handle(Geom2d_Curve)& theC2d2,
2148 Standard_Real& theTolReached)
2150 Handle(GeomAdaptor_HSurface) aGAHS;
2151 Handle(Adaptor2d_HCurve2d) anAHC2d;
2152 Standard_Real tf, tl;
2154 // It is assumed that 2d curve is 2d line (rectangular surface domain)
2155 if(theRL->IsArcOnS1())
2158 anAHC2d = theRL->ArcOnS1();
2159 theRL->ParamOnS1(tf, tl);
2160 theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2162 else if (theRL->IsArcOnS2())
2165 anAHC2d = theRL->ArcOnS2();
2166 theRL->ParamOnS2(tf, tl);
2167 theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2174 //To provide sameparameter it is necessary to get 3d curve as
2175 //approximation of curve on surface.
2176 Standard_Integer aMaxDeg = 8;
2177 Standard_Integer aMaxSeg = 1000;
2178 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
2179 GeomAbs_C1, aMaxDeg, aMaxSeg,
2180 Standard_True, Standard_False);
2181 if(!anApp.HasResult())
2184 theC3d = anApp.Curve3d();
2185 theTolReached = anApp.MaxError3d();
2186 Standard_Real aTol = Precision::Confusion();
2187 if(theRL->IsArcOnS1())
2189 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
2190 BuildPCurves (tf, tl, aTol,
2191 aS, theC3d, theC2d2);
2193 if(theRL->IsArcOnS2())
2195 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
2196 BuildPCurves (tf, tl, aTol,
2197 aS, theC3d, theC2d1);
2199 theTolReached = Max(theTolReached, aTol);
2202 //=======================================================================
2203 //function : BuildPCurves
2205 //=======================================================================
2206 void GeomInt_IntSS::BuildPCurves (Standard_Real f,
2209 const Handle (Geom_Surface)& S,
2210 const Handle (Geom_Curve)& C,
2211 Handle (Geom2d_Curve)& C2d)
2213 if (!C2d.IsNull()) {
2217 Standard_Real umin,umax,vmin,vmax;
2219 S->Bounds(umin, umax, vmin, vmax);
2220 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
2221 if((l - f) > 2.e-09) {
2222 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
2225 // proj. a circle that goes through the pole on a sphere to the sphere
2226 Tol += Precision::Confusion();
2227 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2231 if((l - f) > Epsilon(Abs(f)))
2233 //The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
2234 //On this small range C2d can be considered as segment
2237 Standard_Real aU=0., aV=0.;
2238 GeomAdaptor_Surface anAS;
2240 Extrema_ExtPS anExtr;
2241 const gp_Pnt aP3d1 = C->Value(f);
2242 const gp_Pnt aP3d2 = C->Value(l);
2244 anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
2245 anExtr.Initialize(anAS, umin, umax, vmin, vmax,
2246 Precision::Confusion(), Precision::Confusion());
2247 anExtr.Perform(aP3d1);
2249 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
2251 const gp_Pnt2d aP2d1(aU, aV);
2253 anExtr.Perform(aP3d2);
2255 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
2257 const gp_Pnt2d aP2d2(aU, aV);
2259 if(aP2d1.Distance(aP2d2) > gp::Resolution())
2261 TColgp_Array1OfPnt2d poles(1,2);
2262 TColStd_Array1OfReal knots(1,2);
2263 TColStd_Array1OfInteger mults(1,2);
2268 mults(1) = mults(2) = 2;
2270 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
2272 //Check same parameter in middle point .begin
2273 const gp_Pnt PMid(C->Value(0.5*(f+l)));
2274 const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
2275 const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
2276 const Standard_Real aDist = PMid.Distance(aPC);
2277 Tol = Max(aDist, Tol);
2278 //Check same parameter in middle point .end
2285 if (S->IsUPeriodic() && !C2d.IsNull()) {
2286 // Recadre dans le domaine UV de la face
2287 Standard_Real aTm, U0, aEps, period, du, U0x;
2288 Standard_Boolean bAdjust;
2290 aEps = Precision::PConfusion();
2291 period = S->UPeriod();
2294 gp_Pnt2d pm = C2d->Value(aTm);
2298 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
2300 gp_Vec2d T1(du, 0.);
2306 //=======================================================================
2307 //function : TrimILineOnSurfBoundaries
2308 //purpose : This function finds intersection points of given curves with
2309 // surface boundaries and fills theArrayOfParameters by parameters
2310 // along the given curves corresponding of these points.
2311 //=======================================================================
2312 void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
2313 const Handle(Geom2d_Curve)& theC2d2,
2314 const Bnd_Box2d& theBound1,
2315 const Bnd_Box2d& theBound2,
2316 GeomInt_VectorOfReal& theArrayOfParameters)
2318 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
2319 // [2]:V=Vfirst, [3]:V=Vlast
2320 const Standard_Integer aNumberOfCurves = 4;
2321 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
2322 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
2324 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
2325 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
2327 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
2328 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
2330 Standard_Real aDelta = aV1l-aV1f;
2331 if(Abs(aDelta) > RealSmall())
2333 if(!Precision::IsInfinite(aU1f))
2335 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
2337 if(!Precision::IsInfinite(aDelta))
2338 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
2341 if(!Precision::IsInfinite(aU1l))
2343 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
2344 if(!Precision::IsInfinite(aDelta))
2345 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
2350 if(Abs(aDelta) > RealSmall())
2352 if(!Precision::IsInfinite(aV1f))
2354 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
2355 if(!Precision::IsInfinite(aDelta))
2356 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
2359 if(!Precision::IsInfinite(aV1l))
2361 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
2362 if(!Precision::IsInfinite(aDelta))
2363 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
2368 if(Abs(aDelta) > RealSmall())
2370 if(!Precision::IsInfinite(aU2f))
2372 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
2373 if(!Precision::IsInfinite(aDelta))
2374 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
2377 if(!Precision::IsInfinite(aU2l))
2379 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
2380 if(!Precision::IsInfinite(aDelta))
2381 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
2386 if(Abs(aDelta) > RealSmall())
2388 if(!Precision::IsInfinite(aV2f))
2390 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
2391 if(!Precision::IsInfinite(aDelta))
2392 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
2395 if(!Precision::IsInfinite(aV2l))
2397 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
2398 if(!Precision::IsInfinite(aDelta))
2399 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
2403 const Standard_Real anIntTol = 10.0*Precision::Confusion();
2405 IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
2406 aNumberOfCurves, anIntTol, theArrayOfParameters);
2408 IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
2409 aNumberOfCurves, anIntTol, theArrayOfParameters);
2411 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());