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 <GeomAPI_ProjectPointOnSurf.hxx>
92 #include <TColStd_Array1OfReal.hxx>
93 #include <TColgp_Array1OfPnt2d.hxx>
94 #include <TColStd_Array1OfInteger.hxx>
95 #include <Geom2d_BSplineCurve.hxx>
96 #include <Geom2dAPI_InterCurveCurve.hxx>
97 #include <IntRes2d_IntersectionPoint.hxx>
100 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
101 const Handle(GeomAdaptor_HSurface)& HS2,
109 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
110 const Standard_Integer ideb,
111 const Standard_Integer ifin);
114 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
115 const Standard_Integer ideb,
116 const Standard_Integer ifin,
117 const Standard_Boolean onFirst);
120 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
124 Standard_Boolean DecompositionOfWLine (const Handle(IntPatch_WLine)& theWLine,
125 const Handle(GeomAdaptor_HSurface)& theSurface1,
126 const Handle(GeomAdaptor_HSurface)& theSurface2,
127 const Standard_Real aTolSum,
128 const GeomInt_LineConstructor& theLConstructor,
129 IntPatch_SequenceOfLine& theNewLines);
132 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
133 const Standard_Real parmin,
134 const Standard_Real parmax,
135 const Standard_Real thePeriod,
136 Standard_Real& theOffset) ;
138 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
139 const Standard_Real theFirstBoundary,
140 const Standard_Real theSecondBoundary,
141 const Standard_Real theResolution,
142 Standard_Boolean& IsOnFirstBoundary);
145 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
146 const gp_Pnt2d& theLastPoint,
147 const Standard_Real theUmin,
148 const Standard_Real theUmax,
149 const Standard_Real theVmin,
150 const Standard_Real theVmax,
151 gp_Pnt2d& theNewPoint);
155 void AdjustUPeriodic (const Handle(Geom_Surface)& aS,
156 Handle(Geom2d_Curve)& aC2D);
158 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1,
159 IntSurf_Quadric& quad1);
161 class ProjectPointOnSurf
164 ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {}
165 void Init(const Handle(Geom_Surface)& Surface,
166 const Standard_Real Umin,
167 const Standard_Real Usup,
168 const Standard_Real Vmin,
169 const Standard_Real Vsup);
171 void Perform(const gp_Pnt& P);
172 Standard_Boolean IsDone () const { return myIsDone; }
173 void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const;
174 Standard_Real LowerDistance() const;
176 Standard_Boolean myIsDone;
177 Standard_Integer myIndex;
178 Extrema_ExtPS myExtPS;
179 GeomAdaptor_Surface myGeomAdaptor;
182 //=======================================================================
185 //=======================================================================
186 void ProjectPointOnSurf::Init (const Handle(Geom_Surface)& Surface,
187 const Standard_Real Umin,
188 const Standard_Real Usup,
189 const Standard_Real Vmin,
190 const Standard_Real Vsup )
192 const Standard_Real Tolerance = Precision::PConfusion();
194 myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
195 myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
196 myIsDone = Standard_False;
198 //=======================================================================
201 //=======================================================================
202 void ProjectPointOnSurf::Init ()
204 myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0);
206 // evaluate the lower distance and its index;
207 Standard_Real Dist2Min = myExtPS.SquareDistance(1);
209 for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++)
211 const Standard_Real Dist2 = myExtPS.SquareDistance(i);
212 if (Dist2 < Dist2Min) {
219 //=======================================================================
222 //=======================================================================
223 void ProjectPointOnSurf::Perform(const gp_Pnt& P)
228 //=======================================================================
229 //function : LowerDistanceParameters
231 //=======================================================================
232 void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U,
233 Standard_Real& V ) const
235 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters");
236 (myExtPS.Point(myIndex)).Parameter(U,V);
238 //=======================================================================
239 //function : LowerDistance
241 //=======================================================================
242 Standard_Real ProjectPointOnSurf::LowerDistance() const
244 StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance");
245 return sqrt(myExtPS.SquareDistance(myIndex));
249 //=======================================================================
250 //function : MakeCurve
252 //=======================================================================
253 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
254 const Handle(Adaptor3d_TopolTool) & dom1,
255 const Handle(Adaptor3d_TopolTool) & dom2,
256 const Standard_Real Tol,
257 const Standard_Boolean Approx,
258 const Standard_Boolean ApproxS1,
259 const Standard_Boolean ApproxS2)
262 Standard_Boolean myApprox1, myApprox2, myApprox;
263 Standard_Real Tolpc, myTolApprox;
265 Handle(Geom2d_BSplineCurve) H1;
266 Handle(Geom_Surface) aS1, aS2;
272 myTolApprox=0.0000001;
274 aS1=myHS1->ChangeSurface().Surface();
275 aS2=myHS2->ChangeSurface().Surface();
277 Handle(IntPatch_Line) L = myIntersector.Line(Index);
280 if(typl==IntPatch_Walking) {
281 Handle(IntPatch_Line) anewL =
282 ComputePurgedWLine(Handle(IntPatch_WLine)::DownCast(L));
291 myLConstruct.Perform(L);
292 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
297 Standard_Integer i, j, aNbParts;
298 Standard_Real fprm, lprm;
299 Handle(Geom_Curve) newc;
302 //########################################
303 // Line, Parabola, Hyperbola
304 //########################################
306 case IntPatch_Parabola:
307 case IntPatch_Hyperbola: {
308 if (typl == IntPatch_Lin) {
309 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
311 else if (typl == IntPatch_Parabola) {
312 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
314 else if (typl == IntPatch_Hyperbola) {
315 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
318 aNbParts=myLConstruct.NbParts();
319 for (i=1; i<=aNbParts; i++) {
320 myLConstruct.Part(i, fprm, lprm);
322 if (!Precision::IsNegativeInfinite(fprm) &&
323 !Precision::IsPositiveInfinite(lprm)) {
324 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
328 Handle (Geom2d_Curve) C2d;
329 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
330 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
331 myTolReached2d=Tolpc;
333 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
340 Handle (Geom2d_Curve) C2d;
341 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
342 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
343 myTolReached2d=Tolpc;
346 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
351 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
354 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
355 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
356 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
357 typS1 == GeomAbs_OffsetSurface ||
358 typS1 == GeomAbs_SurfaceOfRevolution ||
359 typS2 == GeomAbs_SurfaceOfExtrusion ||
360 typS2 == GeomAbs_OffsetSurface ||
361 typS2 == GeomAbs_SurfaceOfRevolution) {
367 Standard_Boolean bFNIt, bLPIt;
368 Standard_Real aTestPrm, dT=100.;
369 Standard_Real u1, v1, u2, v2, TolX;
371 bFNIt=Precision::IsNegativeInfinite(fprm);
372 bLPIt=Precision::IsPositiveInfinite(lprm);
376 if (bFNIt && !bLPIt) {
379 else if (!bFNIt && bLPIt) {
383 gp_Pnt ptref(newc->Value(aTestPrm));
385 TolX = Precision::Confusion();
386 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
387 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
389 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
397 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
398 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
401 //########################################
402 // Circle and Ellipse
403 //########################################
404 case IntPatch_Circle:
405 case IntPatch_Ellipse: {
407 if (typl == IntPatch_Circle) {
408 newc = new Geom_Circle
409 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
412 newc = new Geom_Ellipse
413 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
416 Standard_Real aPeriod, aRealEpsilon;
418 aRealEpsilon=RealEpsilon();
421 aNbParts=myLConstruct.NbParts();
423 for (i=1; i<=aNbParts; i++) {
424 myLConstruct.Part(i, fprm, lprm);
426 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
427 //==============================================
428 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
432 fprm=aTC3D->FirstParameter();
433 lprm=aTC3D->LastParameter ();
436 Handle (Geom2d_Curve) C2d;
437 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
438 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
439 myTolReached2d=Tolpc;
448 Handle (Geom2d_Curve) C2d;
449 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
450 if(Tolpc>myTolReached2d || myTolReached2d==0) {
451 myTolReached2d=Tolpc;
458 //==============================================
459 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
461 else {// on regarde si on garde
464 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
465 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
468 fprm=aTC3D->FirstParameter();
469 lprm=aTC3D->LastParameter ();
472 Handle (Geom2d_Curve) C2d;
473 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
474 if(Tolpc>myTolReached2d || myTolReached2d==0) {
475 myTolReached2d=Tolpc;
484 Handle (Geom2d_Curve) C2d;
485 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
486 if(Tolpc>myTolReached2d || myTolReached2d==0) {
487 myTolReached2d=Tolpc;
498 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
500 aTwoPIdiv17=2.*M_PI/17.;
502 for (j=0; j<=17; j++) {
503 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
504 TolX = Precision::Confusion();
506 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
507 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
509 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
513 //==============================================
515 Handle (Geom2d_Curve) C2d;
516 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
517 if(Tolpc>myTolReached2d || myTolReached2d==0) {
518 myTolReached2d=Tolpc;
527 Handle (Geom2d_Curve) C2d;
528 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
529 if(Tolpc>myTolReached2d || myTolReached2d==0) {
530 myTolReached2d=Tolpc;
539 }// end of for (Standard_Integer j=0; j<=17; j++)
540 }// end of else { on regarde si on garde
541 }// for (i=1; i<=myLConstruct.NbParts(); i++)
542 }// IntPatch_Circle: IntPatch_Ellipse
545 //########################################
547 //########################################
548 case IntPatch_Analytic: {
549 IntSurf_Quadric quad1,quad2;
551 GetQuadric(myHS1, quad1);
552 GetQuadric(myHS2, quad2);
554 IntPatch_ALineToWLine convert (quad1, quad2);
557 Handle(Geom2d_BSplineCurve) aH1, aH2;
559 aNbParts=myLConstruct.NbParts();
560 for (i=1; i<=aNbParts; i++) {
561 myLConstruct.Part(i, fprm, lprm);
562 Handle(IntPatch_WLine) WL =
563 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
566 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
570 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
572 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
578 else { // myApprox=TRUE
579 GeomInt_WLApprox theapp3d;
580 Standard_Real tol2d = myTolApprox;
582 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
584 aNbParts=myLConstruct.NbParts();
585 for (i=1; i<=aNbParts; i++) {
586 myLConstruct.Part(i, fprm, lprm);
587 Handle(IntPatch_WLine) WL =
588 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
590 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
591 if (!theapp3d.IsDone()) {
593 Handle(Geom2d_BSplineCurve) aH1, aH2;
596 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
600 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
602 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
608 if(myApprox1 || myApprox2) {
609 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
610 myTolReached2d = theapp3d.TolReached2d();
614 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
615 myTolReached3d = theapp3d.TolReached3d();
618 Standard_Integer aNbMultiCurves, nbpoles;
619 aNbMultiCurves=theapp3d.NbMultiCurves();
620 for (j=1; j<=aNbMultiCurves; j++) {
621 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
623 nbpoles = mbspc.NbPoles();
624 TColgp_Array1OfPnt tpoles(1, nbpoles);
625 mbspc.Curve(1, tpoles);
626 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
628 mbspc.Multiplicities(),
631 GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
632 Check.FixTangent(Standard_True,Standard_True);
637 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
638 mbspc.Curve(2,tpoles2d);
639 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
641 mbspc.Multiplicities(),
644 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
645 newCheck.FixTangent(Standard_True,Standard_True);
653 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
654 Standard_Integer TwoOrThree;
655 TwoOrThree=myApprox1 ? 3 : 2;
656 mbspc.Curve(TwoOrThree, tpoles2d);
657 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
659 mbspc.Multiplicities(),
662 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
663 newCheck.FixTangent(Standard_True,Standard_True);
671 }// for (j=1; j<=aNbMultiCurves; j++) {
672 }// else from if (!theapp3d.IsDone())
673 }// for (i=1; i<=aNbParts; i++) {
674 }// else { // myApprox=TRUE
675 }// case IntPatch_Analytic:
678 //########################################
680 //########################################
681 case IntPatch_Walking:{
682 Handle(IntPatch_WLine) WL =
683 Handle(IntPatch_WLine)::DownCast(L);
685 Standard_Integer ifprm, ilprm;
688 aNbParts=myLConstruct.NbParts();
689 for (i=1; i<=aNbParts; i++) {
690 myLConstruct.Part(i, fprm, lprm);
691 ifprm=(Standard_Integer)fprm;
692 ilprm=(Standard_Integer)lprm;
694 Handle(Geom2d_BSplineCurve) aH1, aH2;
697 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
700 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
703 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
712 Standard_Boolean bIsDecomposited;
713 Standard_Integer nbiter, aNbSeqOfL;
714 GeomInt_WLApprox theapp3d;
715 IntPatch_SequenceOfLine aSeqOfL;
716 Standard_Real tol2d, aTolSS;
721 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
724 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
728 DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
730 aNbParts=myLConstruct.NbParts();
731 aNbSeqOfL=aSeqOfL.Length();
733 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
735 for(i = 1; i <= nbiter; i++) {
736 if(bIsDecomposited) {
737 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
739 ilprm = WL->NbPnts();
742 myLConstruct.Part(i, fprm, lprm);
743 ifprm = (Standard_Integer)fprm;
744 ilprm = (Standard_Integer)lprm;
747 //-- Si une des surfaces est un plan , on approxime en 2d
748 //-- sur cette surface et on remonte les points 2d en 3d.
749 GeomAbs_SurfaceType typs1, typs2;
750 typs1 = myHS1->Surface().GetType();
751 typs2 = myHS2->Surface().GetType();
753 if(typs1 == GeomAbs_Plane) {
754 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
755 Standard_True, myApprox2,
758 else if(typs2 == GeomAbs_Plane) {
759 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
760 myApprox1,Standard_True,
766 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
767 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
769 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
770 //Standard_Boolean bUseSurfaces;
771 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
772 //if (bUseSurfaces) {
773 //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
778 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
783 if (!theapp3d.IsDone()) {
785 Handle(Geom2d_BSplineCurve) aH1, aH2;
787 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
789 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
792 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
798 }//if (!theapp3d.IsDone())
801 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
802 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
803 myTolReached2d = theapp3d.TolReached2d();
806 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
807 myTolReached3d = myTolReached2d;
809 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
810 myTolReached3d = theapp3d.TolReached3d();
813 Standard_Integer aNbMultiCurves, nbpoles;
815 aNbMultiCurves=theapp3d.NbMultiCurves();
816 for (j=1; j<=aNbMultiCurves; j++) {
817 if(typs1 == GeomAbs_Plane) {
818 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
819 nbpoles = mbspc.NbPoles();
821 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
822 TColgp_Array1OfPnt tpoles(1,nbpoles);
824 mbspc.Curve(1,tpoles2d);
825 const gp_Pln& Pln = myHS1->Surface().Plane();
828 for(ik = 1; ik<= nbpoles; ik++) {
830 ElSLib::Value(tpoles2d.Value(ik).X(),
831 tpoles2d.Value(ik).Y(),
835 Handle(Geom_BSplineCurve) BS =
836 new Geom_BSplineCurve(tpoles,
838 mbspc.Multiplicities(),
840 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
841 Check.FixTangent(Standard_True, Standard_True);
846 Handle(Geom2d_BSplineCurve) BS1 =
847 new Geom2d_BSplineCurve(tpoles2d,
849 mbspc.Multiplicities(),
851 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
852 Check1.FixTangent(Standard_True,Standard_True);
854 AdjustUPeriodic (aS1, BS1);
863 mbspc.Curve(2, tpoles2d);
865 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
867 mbspc.Multiplicities(),
869 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
870 newCheck.FixTangent(Standard_True,Standard_True);
872 AdjustUPeriodic (aS2, BS2);
879 }//if(typs1 == GeomAbs_Plane)
881 else if(typs2 == GeomAbs_Plane) {
882 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
883 nbpoles = mbspc.NbPoles();
885 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
886 TColgp_Array1OfPnt tpoles(1,nbpoles);
887 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
888 const gp_Pln& Pln = myHS2->Surface().Plane();
891 for(ik = 1; ik<= nbpoles; ik++) {
893 ElSLib::Value(tpoles2d.Value(ik).X(),
894 tpoles2d.Value(ik).Y(),
899 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
901 mbspc.Multiplicities(),
903 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
904 Check.FixTangent(Standard_True,Standard_True);
909 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
911 mbspc.Multiplicities(),
913 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
914 Check1.FixTangent(Standard_True,Standard_True);
917 AdjustUPeriodic (aS2, BS1);
926 mbspc.Curve(1,tpoles2d);
927 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
929 mbspc.Multiplicities(),
931 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
932 Check2.FixTangent(Standard_True,Standard_True);
935 AdjustUPeriodic (aS1, BS2);
942 } // else if(typs2 == GeomAbs_Plane)
944 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
945 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
946 nbpoles = mbspc.NbPoles();
947 TColgp_Array1OfPnt tpoles(1,nbpoles);
948 mbspc.Curve(1,tpoles);
949 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
951 mbspc.Multiplicities(),
953 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
954 Check.FixTangent(Standard_True,Standard_True);
957 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
958 BS->EndPoint().XYZ().SquareModulus());
959 Standard_Real eps = Epsilon(aDist);
960 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
961 !BS->IsClosed() && !BS->IsPeriodic())
964 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
966 BS->SetPole(BS->NbPoles(), aPm);
971 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
972 mbspc.Curve(2,tpoles2d);
973 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
975 mbspc.Multiplicities(),
977 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
978 newCheck.FixTangent(Standard_True,Standard_True);
980 AdjustUPeriodic (aS1, BS1);
988 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
989 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
990 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
992 mbspc.Multiplicities(),
994 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
995 newCheck.FixTangent(Standard_True,Standard_True);
997 AdjustUPeriodic (aS2, BS2);
1004 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
1005 }// for (j=1; j<=aNbMultiCurves; j++
1012 case IntPatch_Restriction:
1014 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
1015 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
1016 Standard_Boolean isAnalS1 = Standard_False;
1020 case GeomAbs_Cylinder:
1021 case GeomAbs_Sphere:
1023 case GeomAbs_Torus: isAnalS1 = Standard_True; break;
1027 Standard_Integer isAnalS2 = Standard_False;
1031 case GeomAbs_Cylinder:
1032 case GeomAbs_Sphere:
1034 case GeomAbs_Torus: isAnalS2 = Standard_True; break;
1038 Handle(IntPatch_RLine) RL =
1039 Handle(IntPatch_RLine)::DownCast(L);
1040 Handle(Geom_Curve) aC3d;
1041 Handle(Geom2d_Curve) aC2d1, aC2d2;
1042 Standard_Real aTolReached;
1043 TreatRLine(RL, myHS1, myHS2, aC3d,
1044 aC2d1, aC2d2, aTolReached);
1049 Bnd_Box2d aBox1, aBox2;
1051 const Standard_Real aU1f = myHS1->FirstUParameter(),
1052 aV1f = myHS1->FirstVParameter(),
1053 aU1l = myHS1->LastUParameter(),
1054 aV1l = myHS1->LastVParameter();
1055 const Standard_Real aU2f = myHS2->FirstUParameter(),
1056 aV2f = myHS2->FirstVParameter(),
1057 aU2l = myHS2->LastUParameter(),
1058 aV2l = myHS2->LastVParameter();
1060 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1061 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1062 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1063 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1065 GeomInt_VectorOfReal anArrayOfParameters;
1067 //We consider here that the intersection line is same-parameter-line
1068 anArrayOfParameters.Append(aC3d->FirstParameter());
1069 anArrayOfParameters.Append(aC3d->LastParameter());
1071 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1073 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1076 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1078 const Standard_Real aParF = anArrayOfParameters(anInd),
1079 aParL = anArrayOfParameters(anInd+1);
1081 if((aParL - aParF) <= Precision::PConfusion())
1084 const Standard_Real aPar = 0.5*(aParF + aParL);
1087 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1090 aC2d1->D0(aPar, aPt);
1092 if(aBox1.IsOut(aPt))
1096 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1101 aC2d2->D0(aPar, aPt);
1103 if(aBox2.IsOut(aPt))
1107 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1110 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1112 sline.Append(aCurv3d);
1113 slineS1.Append(aCurv2d1);
1114 slineS2.Append(aCurv2d2);
1121 //=======================================================================
1122 //function : AdjustUPeriodic
1124 //=======================================================================
1125 void AdjustUPeriodic (const Handle(Geom_Surface)& aS, Handle(Geom2d_Curve)& aC2D)
1127 if (aC2D.IsNull() || !aS->IsUPeriodic())
1130 const Standard_Real aEps=Precision::PConfusion();//1.e-9
1131 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
1133 Standard_Real umin,umax,vmin,vmax;
1134 aS->Bounds(umin,umax,vmin,vmax);
1135 const Standard_Real aPeriod = aS->UPeriod();
1137 const Standard_Real aT1=aC2D->FirstParameter();
1138 const Standard_Real aT2=aC2D->LastParameter();
1139 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
1140 const gp_Pnt2d aPx=aC2D->Value(aTx);
1142 Standard_Real aUx=aPx.X();
1143 if (fabs(aUx)<aEpsilon)
1145 if (fabs(aUx-aPeriod)<aEpsilon)
1148 Standard_Real dU=0.;
1149 while(aUx <(umin-aEps)) {
1153 while(aUx>(umax+aEps)) {
1159 gp_Vec2d aV2D(dU, 0.);
1160 aC2D->Translate(aV2D);
1165 //=======================================================================
1166 //function : GetQuadric
1168 //=======================================================================
1169 void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
1171 switch (HS1->Surface().GetType())
1173 case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break;
1174 case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
1175 case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break;
1176 case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break;
1177 case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break;
1178 default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
1182 //=======================================================================
1183 //function : Parameters
1185 //=======================================================================
1186 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
1187 const Handle(GeomAdaptor_HSurface)& HS2,
1188 const gp_Pnt& Ptref,
1194 IntSurf_Quadric quad1,quad2;
1196 GetQuadric(HS1, quad1);
1197 GetQuadric(HS2, quad2);
1199 quad1.Parameters(Ptref,U1,V1);
1200 quad2.Parameters(Ptref,U2,V2);
1203 //=======================================================================
1204 //function : MakeBSpline
1206 //=======================================================================
1207 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
1208 const Standard_Integer ideb,
1209 const Standard_Integer ifin)
1211 const Standard_Integer nbpnt = ifin-ideb+1;
1212 TColgp_Array1OfPnt poles(1,nbpnt);
1213 TColStd_Array1OfReal knots(1,nbpnt);
1214 TColStd_Array1OfInteger mults(1,nbpnt);
1215 Standard_Integer i = 1, ipidebm1 = ideb;
1216 for(; i<=nbpnt; ipidebm1++, i++)
1218 poles(i) = WL->Point(ipidebm1).Value();
1222 mults(1) = mults(nbpnt) = 2;
1223 return new Geom_BSplineCurve(poles,knots,mults,1);
1226 //=======================================================================
1227 //function : MakeBSpline2d
1229 //=======================================================================
1230 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1231 const Standard_Integer ideb,
1232 const Standard_Integer ifin,
1233 const Standard_Boolean onFirst)
1235 const Standard_Integer nbpnt = ifin-ideb+1;
1236 TColgp_Array1OfPnt2d poles(1,nbpnt);
1237 TColStd_Array1OfReal knots(1,nbpnt);
1238 TColStd_Array1OfInteger mults(1,nbpnt);
1239 Standard_Integer i = 1, ipidebm1 = ideb;
1240 for(; i <= nbpnt; ipidebm1++, i++)
1244 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1246 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1247 poles(i).SetCoord(U, V);
1251 mults(1) = mults(nbpnt) = 2;
1252 return new Geom2d_BSplineCurve(poles,knots,mults,1);
1255 //=========================================================================
1256 // static function : ComputePurgedWLine
1257 // purpose : Removes equal points (leave one of equal points) from theWLine
1258 // and recompute vertex parameters.
1259 // Returns new WLine or null WLine if the number
1260 // of the points is less than 2.
1261 //=========================================================================
1262 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine)
1264 Handle(IntPatch_WLine) aResult;
1265 Handle(IntPatch_WLine) aLocalWLine;
1266 Handle(IntPatch_WLine) aTmpWLine = theWLine;
1268 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1269 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1270 Standard_Integer i, k, v, nb, nbvtx;
1271 nbvtx = theWLine->NbVertex();
1272 nb = theWLine->NbPnts();
1274 for(i = 1; i <= nb; i++) {
1275 aLineOn2S->Add(theWLine->Point(i));
1278 for(v = 1; v <= nbvtx; v++) {
1279 aLocalWLine->AddVertex(theWLine->Vertex(v));
1282 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
1283 Standard_Integer aStartIndex = i + 1;
1284 Standard_Integer anEndIndex = i + 5;
1285 nb = aLineOn2S->NbPoints();
1286 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
1288 if((aStartIndex >= nb) || (anEndIndex <= 1)) {
1293 while(k <= anEndIndex) {
1296 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
1297 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
1299 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
1300 aTmpWLine = aLocalWLine;
1301 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1303 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
1304 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
1305 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
1307 if(avertexindex >= k) {
1308 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
1310 aLocalWLine->AddVertex(aVertex);
1312 aLineOn2S->RemovePoint(k);
1321 if(aLineOn2S->NbPoints() > 1) {
1322 aResult = aLocalWLine;
1326 //=======================================================================
1327 //function : DecompositionOfWLine
1329 //=======================================================================
1330 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
1331 const Handle(GeomAdaptor_HSurface)& theSurface1,
1332 const Handle(GeomAdaptor_HSurface)& theSurface2,
1333 const Standard_Real aTolSum,
1334 const GeomInt_LineConstructor& theLConstructor,
1335 IntPatch_SequenceOfLine& theNewLines)
1337 typedef NCollection_List<Standard_Integer> ListOfInteger;
1338 //have to use std::vector, not NCollection_Vector in order to use copy constructor of
1339 //ListOfInteger which will be created with specific allocator instance
1340 typedef std::vector<ListOfInteger, NCollection_StdAllocator<
1341 ListOfInteger> > ArrayOfListOfInteger;
1343 Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary;
1344 Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex;
1345 Standard_Real aTol, umin, umax, vmin, vmax;
1347 //an inc allocator, it will contain wasted space (upon list's Clear()) but it should
1348 //still be faster than the standard allocator, and wasted memory should not be
1349 //significant and will be limited by time span of this function;
1350 //this is a separate allocator from the anIncAlloc below what provides better data
1351 //locality in the latter (by avoiding wastes which will only be in anIdxAlloc)
1352 Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator();
1353 ListOfInteger aListOfPointIndex (anIdxAlloc);
1355 //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2;
1356 ProjectPointOnSurf aPrj1, aPrj2;
1357 Handle(Geom_Surface) aSurf1, aSurf2;
1359 aNbParts=theLConstructor.NbParts();
1360 aNbPnts=theWLine->NbPnts();
1362 if((!aNbPnts) || (!aNbParts)){
1363 return Standard_False;
1366 Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
1367 NCollection_StdAllocator<ListOfInteger> anAlloc (anIncAlloc);
1368 const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from
1369 ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc);
1371 NCollection_LocalArray<Standard_Integer> anArrayOfLineTypeArr (aNbPnts + 1);
1372 Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr;
1375 aTol = Precision::Confusion();
1377 aSurf1 = theSurface1->ChangeSurface().Surface();
1378 aSurf1->Bounds(umin, umax, vmin, vmax);
1379 aPrj1.Init(aSurf1, umin, umax, vmin, vmax);
1381 aSurf2 = theSurface2->ChangeSurface().Surface();
1382 aSurf2->Bounds(umin, umax, vmin, vmax);
1383 aPrj2.Init(aSurf2, umin, umax, vmin, vmax);
1386 bIsPrevPointOnBoundary=Standard_False;
1387 for(pit=1; pit<=aNbPnts; pit++) {
1388 const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
1389 bIsCurrentPointOnBoundary=Standard_False;
1391 // whether aPoint is on boundary or not
1393 for(i=0; i<2; i++) {// exploration Surface 1,2
1394 Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
1395 aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
1397 for(j=0; j<2; j++) {// exploration of coordinate U,V
1398 Standard_Boolean isperiodic;
1400 isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1405 Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
1406 Standard_Real aParameter, anoffset, anAdjustPar;
1407 Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary;
1409 aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1410 aPeriod = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1411 alowerboundary = (!j) ? umin : vmin;
1412 aupperboundary = (!j) ? umax : vmax;
1416 aPoint.ParametersOnS1(U, V);
1419 aPoint.ParametersOnS2(U, V);
1422 aParameter = (!j) ? U : V;
1424 anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1426 bIsOnFirstBoundary=Standard_True;
1429 IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
1431 if(bIsPointOnBoundary) {
1432 bIsCurrentPointOnBoundary = Standard_True;
1435 }// for(j=0; j<2; j++)
1437 if(bIsCurrentPointOnBoundary){
1440 }// for(i=0; i<2; i++)
1442 if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
1444 if(!aListOfPointIndex.IsEmpty()) {
1446 anArrayOfLines[nblines] = aListOfPointIndex;
1447 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1448 aListOfPointIndex.Clear();
1450 bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
1452 aListOfPointIndex.Append(pit);
1453 } // for(pit=1; pit<=aNbPnts; pit++)
1455 aNbListOfPointIndex=aListOfPointIndex.Extent();
1456 if(aNbListOfPointIndex) {
1458 anArrayOfLines[nblines].Assign (aListOfPointIndex);
1459 anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
1460 aListOfPointIndex.Clear();
1464 return Standard_False;
1467 // Correct wlines.begin
1468 Standard_Integer aLineType;
1469 TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
1470 Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator());
1472 for(i = 1; i <= nblines; i++) {
1473 aLineType=anArrayOfLineType[i];
1478 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1479 if(aListOfIndex.Extent() < 2) {
1483 TColStd_ListOfInteger aListOfFLIndex;
1484 Standard_Integer aneighbourindex, aLineTypeNeib;
1486 for(j = 0; j < 2; j++) {// neighbour line choice
1487 aneighbourindex = (!j) ? (i-1) : (i+1);
1488 if((aneighbourindex < 1) || (aneighbourindex > nblines)){
1492 aLineTypeNeib=anArrayOfLineType[aneighbourindex];
1497 const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex];
1498 Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First();
1499 const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
1500 // check if need use derivative.begin .end [absence]
1502 IntSurf_PntOn2S aNewP = aPoint;
1503 Standard_Integer surfit, parit;
1505 for(surfit = 0; surfit < 2; ++surfit) {
1507 Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2;
1509 umin = aGASurface->FirstUParameter();
1510 umax = aGASurface->LastUParameter();
1511 vmin = aGASurface->FirstVParameter();
1512 vmax = aGASurface->LastVParameter();
1513 Standard_Real U=0., V=0.;
1516 aNewP.ParametersOnS1(U, V);
1519 aNewP.ParametersOnS2(U, V);
1522 Standard_Integer nbboundaries = 0;
1523 Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
1524 Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
1526 for(parit = 0; parit < 2; parit++) {
1527 Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1529 Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
1530 Standard_Real alowerboundary = (!parit) ? umin : vmin;
1531 Standard_Real aupperboundary = (!parit) ? umax : vmax;
1533 Standard_Real aParameter = (!parit) ? U : V;
1534 Standard_Boolean bIsOnFirstBoundary = Standard_True;
1537 if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1538 bIsUBoundary = (!parit);
1539 bIsFirstBoundary = bIsOnFirstBoundary;
1544 Standard_Real aPeriod = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1545 Standard_Real anoffset = 0.;
1546 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1548 if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
1549 bIsUBoundary = (parit == 0);
1550 bIsFirstBoundary = bIsOnFirstBoundary;
1556 Standard_Boolean bComputeLineEnd = Standard_False;
1558 if(nbboundaries == 2) {
1559 bComputeLineEnd = Standard_True;
1561 else if(nbboundaries == 1) {
1562 Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
1565 Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
1566 Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
1567 Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
1568 Standard_Real aParameter = (bIsUBoundary) ? U : V;
1569 Standard_Real anoffset = 0.;
1570 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
1572 Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
1573 Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
1574 anotherPar += anoffset;
1575 Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1576 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
1577 Standard_Real nU1, nV1;
1580 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1582 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1584 Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
1585 Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
1586 bComputeLineEnd = Standard_True;
1587 Standard_Boolean bCheckAngle1 = Standard_False;
1588 Standard_Boolean bCheckAngle2 = Standard_False;
1590 Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
1591 Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
1593 if(((adist1 - adist2) > Precision::PConfusion()) &&
1594 (adist2 < (aPeriod / 4.))) {
1595 bCheckAngle1 = Standard_True;
1596 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
1598 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1599 aNewP.SetValue((surfit == 0), anewU, anewV);
1600 bCheckAngle1 = Standard_False;
1603 else if(adist1 < (aPeriod / 4.)) {
1604 bCheckAngle2 = Standard_True;
1605 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
1607 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
1608 bCheckAngle2 = Standard_False;
1612 if(bCheckAngle1 || bCheckAngle2) {
1613 // assume there are at least two points in line (see "if" above)
1614 Standard_Integer anindexother = aneighbourpointindex;
1616 while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
1617 anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
1618 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
1619 Standard_Real nU2, nV2;
1622 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1624 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1625 gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
1627 if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
1631 Standard_Real anAngle = aNewVec.Angle(aVecOld);
1633 if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
1636 Standard_Real U1, U2, V1, V2;
1637 IntSurf_PntOn2S atmppoint = aNewP;
1638 atmppoint.SetValue((surfit == 0), anewU, anewV);
1639 atmppoint.Parameters(U1, V1, U2, V2);
1640 gp_Pnt P1 = theSurface1->Value(U1, V1);
1641 gp_Pnt P2 = theSurface2->Value(U2, V2);
1642 gp_Pnt P0 = aPoint.Value();
1644 if(P0.IsEqual(P1, aTol) &&
1645 P0.IsEqual(P2, aTol) &&
1646 P1.IsEqual(P2, aTol)) {
1647 bComputeLineEnd = Standard_False;
1648 aNewP.SetValue((surfit == 0), anewU, anewV);
1653 bComputeLineEnd = Standard_False;
1658 } // end while(anindexother...)
1663 if(bComputeLineEnd) {
1664 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
1665 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
1666 Standard_Real nU1, nV1;
1669 aNeighbourPoint.ParametersOnS1(nU1, nV1);
1671 aNeighbourPoint.ParametersOnS2(nU1, nV1);
1672 gp_Pnt2d ap1(nU1, nV1);
1673 gp_Pnt2d ap2(nU1, nV1);
1674 Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
1676 while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
1677 aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
1678 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
1679 Standard_Real nU2, nV2;
1682 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
1684 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
1688 if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
1693 Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
1697 Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
1698 //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1699 ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
1700 Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
1702 gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
1703 aProjector.Perform(aP3d);
1705 if(aProjector.IsDone()) {
1706 if(aProjector.LowerDistance() < aCriteria) {
1707 Standard_Real foundU = U, foundV = V;
1708 aProjector.LowerDistanceParameters(foundU, foundV);
1711 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
1713 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
1719 aSeqOfPntOn2S->Add(aNewP);
1720 aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
1722 anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
1724 // Correct wlines.end
1726 // Split wlines.begin
1727 for(j = 1; j <= theLConstructor.NbParts(); j++) {
1728 Standard_Real fprm = 0., lprm = 0.;
1729 theLConstructor.Part(j, fprm, lprm);
1730 Standard_Integer ifprm = (Standard_Integer)fprm;
1731 Standard_Integer ilprm = (Standard_Integer)lprm;
1733 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1735 for(i = 1; i <= nblines; i++) {
1736 if(anArrayOfLineType[i] != 0) {
1739 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1741 if(aListOfIndex.Extent() < 2) {
1744 const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
1745 Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
1746 Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
1748 if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
1749 bhasfirstpoint = (i != 1);
1752 if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
1753 bhaslastpoint = (i != nblines);
1755 Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
1756 Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
1758 if(!bIsFirstInside && !bIsLastInside) {
1759 if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
1760 // append whole line, and boundaries if neccesary
1761 if(bhasfirstpoint) {
1762 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1765 ListOfInteger::Iterator anIt(aListOfIndex);
1767 for(; anIt.More(); anIt.Next()) {
1768 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1773 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1777 // check end of split line (end is almost always)
1778 Standard_Integer aneighbour = i + 1;
1779 Standard_Boolean bIsEndOfLine = Standard_True;
1781 if(aneighbour <= nblines) {
1782 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1784 if((anArrayOfLineType[aneighbour] != 0) &&
1785 (aListOfNeighbourIndex.IsEmpty())) {
1786 bIsEndOfLine = Standard_False;
1791 if(aLineOn2S->NbPoints() > 1) {
1792 Handle(IntPatch_WLine) aNewWLine =
1793 new IntPatch_WLine(aLineOn2S, Standard_False);
1794 theNewLines.Append(aNewWLine);
1796 aLineOn2S = new IntSurf_LineOn2S();
1801 // end if(!bIsFirstInside && !bIsLastInside)
1803 if(bIsFirstInside && bIsLastInside) {
1804 // append inside points between ifprm and ilprm
1805 ListOfInteger::Iterator anIt(aListOfIndex);
1807 for(; anIt.More(); anIt.Next()) {
1808 if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
1810 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1816 if(bIsFirstInside) {
1817 // append points from ifprm to last point + boundary point
1818 ListOfInteger::Iterator anIt(aListOfIndex);
1820 for(; anIt.More(); anIt.Next()) {
1821 if(anIt.Value() < ifprm)
1823 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1828 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
1831 // check end of split line (end is almost always)
1832 Standard_Integer aneighbour = i + 1;
1833 Standard_Boolean bIsEndOfLine = Standard_True;
1835 if(aneighbour <= nblines) {
1836 const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
1838 if((anArrayOfLineType[aneighbour] != 0) &&
1839 (aListOfNeighbourIndex.IsEmpty())) {
1840 bIsEndOfLine = Standard_False;
1845 if(aLineOn2S->NbPoints() > 1) {
1846 Handle(IntPatch_WLine) aNewWLine =
1847 new IntPatch_WLine(aLineOn2S, Standard_False);
1848 theNewLines.Append(aNewWLine);
1850 aLineOn2S = new IntSurf_LineOn2S();
1853 // end if(bIsFirstInside)
1856 // append points from first boundary point to ilprm
1857 if(bhasfirstpoint) {
1858 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
1861 ListOfInteger::Iterator anIt(aListOfIndex);
1863 for(; anIt.More(); anIt.Next()) {
1864 if(anIt.Value() > ilprm)
1866 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
1870 //end if(bIsLastInside)
1874 if(aLineOn2S->NbPoints() > 1) {
1875 Handle(IntPatch_WLine) aNewWLine =
1876 new IntPatch_WLine(aLineOn2S, Standard_False);
1877 theNewLines.Append(aNewWLine);
1883 Standard_Real fprm, lprm;
1884 Standard_Integer ifprm, ilprm, aNbPoints, aIndex;
1886 aNbParts=theLConstructor.NbParts();
1888 for(j = 1; j <= aNbParts; j++) {
1889 theLConstructor.Part(j, fprm, lprm);
1890 ifprm=(Standard_Integer)fprm;
1891 ilprm=(Standard_Integer)lprm;
1893 if ((ilprm-ifprm)==1) {
1894 for(i = 1; i <= nblines; i++) {
1895 aLineType=anArrayOfLineType[i];
1900 const ListOfInteger& aListOfIndex = anArrayOfLines[i];
1901 aNbPoints=aListOfIndex.Extent();
1903 aIndex=aListOfIndex.First();
1904 if (aIndex==ifprm || aIndex==ilprm) {
1905 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1906 const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm);
1907 const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm);
1908 aLineOn2S->Add(aP1);
1909 aLineOn2S->Add(aP2);
1910 Handle(IntPatch_WLine) aNewWLine =
1911 new IntPatch_WLine(aLineOn2S, Standard_False);
1912 theNewLines.Append(aNewWLine);
1919 return Standard_True;
1922 //=======================================================================
1923 //function : AdjustPeriodic
1925 //=======================================================================
1926 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
1927 const Standard_Real parmin,
1928 const Standard_Real parmax,
1929 const Standard_Real thePeriod,
1930 Standard_Real& theOffset)
1932 Standard_Real aresult = theParameter;
1934 while(aresult < parmin) {
1935 aresult += thePeriod;
1936 theOffset += thePeriod;
1938 while(aresult > parmax) {
1939 aresult -= thePeriod;
1940 theOffset -= thePeriod;
1945 //=======================================================================
1946 //function : IsPointOnBoundary
1948 //=======================================================================
1949 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
1950 const Standard_Real theFirstBoundary,
1951 const Standard_Real theSecondBoundary,
1952 const Standard_Real theResolution,
1953 Standard_Boolean& IsOnFirstBoundary)
1955 IsOnFirstBoundary = Standard_True;
1956 if(fabs(theParameter - theFirstBoundary) < theResolution)
1957 return Standard_True;
1958 if(fabs(theParameter - theSecondBoundary) < theResolution)
1960 IsOnFirstBoundary = Standard_False;
1961 return Standard_True;
1963 return Standard_False;
1965 //=======================================================================
1966 //function : FindPoint
1968 //=======================================================================
1969 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
1970 const gp_Pnt2d& theLastPoint,
1971 const Standard_Real theUmin,
1972 const Standard_Real theUmax,
1973 const Standard_Real theVmin,
1974 const Standard_Real theVmax,
1975 gp_Pnt2d& theNewPoint)
1977 gp_Vec2d aVec(theFirstPoint, theLastPoint);
1978 Standard_Integer i = 0, j = 0;
1980 for(i = 0; i < 4; i++) {
1981 gp_Vec2d anOtherVec;
1982 gp_Vec2d anOtherVecNormal;
1983 gp_Pnt2d aprojpoint = theLastPoint;
1986 anOtherVec.SetX(0.);
1987 anOtherVec.SetY(1.);
1988 anOtherVecNormal.SetX(1.);
1989 anOtherVecNormal.SetY(0.);
1992 aprojpoint.SetX(theUmin);
1994 aprojpoint.SetX(theUmax);
1997 anOtherVec.SetX(1.);
1998 anOtherVec.SetY(0.);
1999 anOtherVecNormal.SetX(0.);
2000 anOtherVecNormal.SetY(1.);
2003 aprojpoint.SetY(theVmin);
2005 aprojpoint.SetY(theVmax);
2007 gp_Vec2d anormvec = aVec;
2008 anormvec.Normalize();
2009 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
2011 if(fabs(adot1) < Precision::Angular())
2013 Standard_Real adist = 0.;
2016 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
2019 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
2021 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
2023 for(j = 0; j < 2; j++) {
2024 anoffset = (j == 0) ? anoffset : -anoffset;
2025 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
2026 gp_Vec2d acurvec(theLastPoint, acurpoint);
2029 Standard_Real aDotX, anAngleX, aPC;
2031 aDotX=aVec.Dot(acurvec);
2032 anAngleX=aVec.Angle(acurvec);
2033 aPC=Precision::PConfusion();
2035 if(aDotX > 0. && fabs(anAngleX) < aPC) {
2038 if((acurpoint.Y() >= theVmin) &&
2039 (acurpoint.Y() <= theVmax)) {
2040 theNewPoint = acurpoint;
2041 return Standard_True;
2045 if((acurpoint.X() >= theUmin) &&
2046 (acurpoint.X() <= theUmax)) {
2047 theNewPoint = acurpoint;
2048 return Standard_True;
2054 return Standard_False;
2057 //=======================================================================
2058 //function : TreatRLine
2059 //purpose : Approx of Restriction line
2060 //=======================================================================
2061 void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
2062 const Handle(GeomAdaptor_HSurface)& theHS1,
2063 const Handle(GeomAdaptor_HSurface)& theHS2,
2064 Handle(Geom_Curve)& theC3d,
2065 Handle(Geom2d_Curve)& theC2d1,
2066 Handle(Geom2d_Curve)& theC2d2,
2067 Standard_Real& theTolReached)
2069 Handle(GeomAdaptor_HSurface) aGAHS;
2070 Handle(Adaptor2d_HCurve2d) anAHC2d;
2071 Standard_Real tf, tl;
2073 // It is assumed that 2d curve is 2d line (rectangular surface domain)
2074 if(theRL->IsArcOnS1())
2077 anAHC2d = theRL->ArcOnS1();
2078 theRL->ParamOnS1(tf, tl);
2079 theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2081 else if (theRL->IsArcOnS2())
2084 anAHC2d = theRL->ArcOnS2();
2085 theRL->ParamOnS2(tf, tl);
2086 theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
2093 //To provide sameparameter it is necessary to get 3d curve as
2094 //approximation of curve on surface.
2095 Standard_Integer aMaxDeg = 8;
2096 Standard_Integer aMaxSeg = 1000;
2097 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
2098 GeomAbs_C1, aMaxDeg, aMaxSeg,
2099 Standard_True, Standard_False);
2100 if(!anApp.HasResult())
2103 theC3d = anApp.Curve3d();
2104 theTolReached = anApp.MaxError3d();
2105 Standard_Real aTol = Precision::Confusion();
2106 if(theRL->IsArcOnS1())
2108 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
2109 BuildPCurves (tf, tl, aTol,
2110 aS, theC3d, theC2d2);
2112 if(theRL->IsArcOnS2())
2114 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
2115 BuildPCurves (tf, tl, aTol,
2116 aS, theC3d, theC2d1);
2118 theTolReached = Max(theTolReached, aTol);
2121 //=======================================================================
2122 //function : BuildPCurves
2124 //=======================================================================
2125 void GeomInt_IntSS::BuildPCurves (Standard_Real f,
2128 const Handle (Geom_Surface)& S,
2129 const Handle (Geom_Curve)& C,
2130 Handle (Geom2d_Curve)& C2d)
2132 if (!C2d.IsNull()) {
2136 Standard_Real umin,umax,vmin,vmax;
2138 S->Bounds(umin, umax, vmin, vmax);
2139 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
2140 if((l - f) > 2.e-09) {
2141 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
2144 // proj. a circle that goes through the pole on a sphere to the sphere
2145 Tol += Precision::Confusion();
2146 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2150 if((l - f) > Epsilon(Abs(f))) {
2151 GeomAPI_ProjectPointOnSurf aProjector1, aProjector2;
2152 gp_Pnt P1 = C->Value(f);
2153 gp_Pnt P2 = C->Value(l);
2154 aProjector1.Init(P1, S);
2155 aProjector2.Init(P2, S);
2157 if(aProjector1.IsDone() && aProjector2.IsDone()) {
2158 Standard_Real U=0., V=0.;
2159 aProjector1.LowerDistanceParameters(U, V);
2162 aProjector2.LowerDistanceParameters(U, V);
2165 if(p1.Distance(p2) > gp::Resolution()) {
2166 TColgp_Array1OfPnt2d poles(1,2);
2167 TColStd_Array1OfReal knots(1,2);
2168 TColStd_Array1OfInteger mults(1,2);
2173 mults(1) = mults(2) = 2;
2175 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
2177 // compute reached tolerance.begin
2178 gp_Pnt PMid = C->Value((f + l) * 0.5);
2179 aProjector1.Perform(PMid);
2181 if(aProjector1.IsDone()) {
2182 aProjector1.LowerDistanceParameters(U, V);
2183 gp_Pnt2d pmidproj(U, V);
2184 gp_Pnt2d pmidcurve2d = C2d->Value((f + l) * 0.5);
2185 Standard_Real adist = pmidcurve2d.Distance(pmidproj);
2186 Tol = (adist > Tol) ? adist : Tol;
2188 // compute reached tolerance.end
2194 if (S->IsUPeriodic() && !C2d.IsNull()) {
2195 // Recadre dans le domaine UV de la face
2196 Standard_Real aTm, U0, aEps, period, du, U0x;
2197 Standard_Boolean bAdjust;
2199 aEps = Precision::PConfusion();
2200 period = S->UPeriod();
2203 gp_Pnt2d pm = C2d->Value(aTm);
2207 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
2209 gp_Vec2d T1(du, 0.);
2215 //=======================================================================
2216 //function : TrimILineOnSurfBoundaries
2217 //purpose : This function finds intersection points of given curves with
2218 // surface boundaries and fills theArrayOfParameters by parameters
2219 // along the given curves corresponding of these points.
2220 //=======================================================================
2221 void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
2222 const Handle(Geom2d_Curve)& theC2d2,
2223 const Bnd_Box2d& theBound1,
2224 const Bnd_Box2d& theBound2,
2225 GeomInt_VectorOfReal& theArrayOfParameters)
2227 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
2228 // [2]:V=Vfirst, [3]:V=Vlast
2229 const Standard_Integer aNumberOfCurves = 4;
2230 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
2231 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
2233 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
2234 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
2236 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
2237 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
2239 Standard_Real aDelta = aV1l-aV1f;
2240 if(Abs(aDelta) > RealSmall())
2242 if(!Precision::IsInfinite(aU1f))
2244 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
2246 if(!Precision::IsInfinite(aDelta))
2247 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
2250 if(!Precision::IsInfinite(aU1l))
2252 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
2253 if(!Precision::IsInfinite(aDelta))
2254 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
2259 if(Abs(aDelta) > RealSmall())
2261 if(!Precision::IsInfinite(aV1f))
2263 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
2264 if(!Precision::IsInfinite(aDelta))
2265 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
2268 if(!Precision::IsInfinite(aV1l))
2270 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
2271 if(!Precision::IsInfinite(aDelta))
2272 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
2277 if(Abs(aDelta) > RealSmall())
2279 if(!Precision::IsInfinite(aU2f))
2281 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
2282 if(!Precision::IsInfinite(aDelta))
2283 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
2286 if(!Precision::IsInfinite(aU2l))
2288 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
2289 if(!Precision::IsInfinite(aDelta))
2290 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
2295 if(Abs(aDelta) > RealSmall())
2297 if(!Precision::IsInfinite(aV2f))
2299 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
2300 if(!Precision::IsInfinite(aDelta))
2301 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
2304 if(!Precision::IsInfinite(aV2l))
2306 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
2307 if(!Precision::IsInfinite(aDelta))
2308 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
2312 Geom2dAPI_InterCurveCurve anIntCC2d;
2314 if(!theC2d1.IsNull())
2316 for(Standard_Integer aCurID = 0; aCurID < aNumberOfCurves; aCurID++)
2318 if(aCurS1Bounds[aCurID].IsNull())
2321 anIntCC2d.Init(theC2d1, aCurS1Bounds[aCurID]);
2323 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
2325 const Standard_Real aParam = anIntCC2d.Intersector().Point(aPntID).ParamOnFirst();
2326 theArrayOfParameters.Append(aParam);
2329 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
2331 Handle(Geom2d_Curve) aCS, aCSTemp;
2332 anIntCC2d.Segment(aSegmID, aCS, aCSTemp);
2333 theArrayOfParameters.Append(aCS->FirstParameter());
2334 theArrayOfParameters.Append(aCS->LastParameter());
2339 if(!theC2d2.IsNull())
2341 for(Standard_Integer aCurID = 0; aCurID < aNumberOfCurves; aCurID++)
2343 if(aCurS2Bounds[aCurID].IsNull())
2346 anIntCC2d.Init(theC2d2, aCurS2Bounds[aCurID]);
2348 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
2350 const Standard_Real aParam = anIntCC2d.Intersector().Point(aPntID).ParamOnFirst();
2351 theArrayOfParameters.Append(aParam);
2354 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
2356 Handle(Geom2d_Curve) aCS, aCSTemp;
2357 anIntCC2d.Segment(aSegmID, aCS, aCSTemp);
2358 theArrayOfParameters.Append(aCS->FirstParameter());
2359 theArrayOfParameters.Append(aCS->LastParameter());
2364 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());