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 <GeomInt_IntSS.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <Approx_CurveOnSurface.hxx>
23 #include <Extrema_ExtPS.hxx>
24 #include <Geom2dAdaptor.hxx>
25 #include <Geom2dAdaptor_Curve.hxx>
26 #include <Geom2dInt_GInter.hxx>
27 #include <Geom2d_BSplineCurve.hxx>
28 #include <Geom2d_Line.hxx>
29 #include <Geom2d_TrimmedCurve.hxx>
30 #include <GeomAdaptor.hxx>
31 #include <GeomAdaptor_Surface.hxx>
32 #include <GeomInt.hxx>
33 #include <GeomInt_LineTool.hxx>
34 #include <GeomInt_WLApprox.hxx>
35 #include <GeomLib_Check2dBSplineCurve.hxx>
36 #include <GeomLib_CheckBSplineCurve.hxx>
37 #include <GeomProjLib.hxx>
38 #include <Geom_BSplineCurve.hxx>
39 #include <Geom_Circle.hxx>
40 #include <Geom_Ellipse.hxx>
41 #include <Geom_Hyperbola.hxx>
42 #include <Geom_Line.hxx>
43 #include <Geom_Parabola.hxx>
44 #include <Geom_TrimmedCurve.hxx>
45 #include <IntPatch_GLine.hxx>
46 #include <IntPatch_RLine.hxx>
47 #include <IntPatch_WLine.hxx>
48 #include <IntRes2d_IntersectionSegment.hxx>
49 #include <IntSurf_Quadric.hxx>
50 #include <Precision.hxx>
51 #include <ApproxInt_KnotTools.hxx>
53 //=======================================================================
54 //function : AdjustUPeriodic
56 //=======================================================================
57 static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
59 if (aC2D.IsNull() || !aS->IsUPeriodic())
62 const Standard_Real aEps=Precision::PConfusion();//1.e-9
63 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
65 Standard_Real umin,umax,vmin,vmax;
66 aS->Bounds(umin,umax,vmin,vmax);
67 const Standard_Real aPeriod = aS->UPeriod();
69 const Standard_Real aT1=aC2D->FirstParameter();
70 const Standard_Real aT2=aC2D->LastParameter();
71 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
72 const gp_Pnt2d aPx=aC2D->Value(aTx);
74 Standard_Real aUx=aPx.X();
75 if (fabs(aUx)<aEpsilon)
77 if (fabs(aUx-aPeriod)<aEpsilon)
81 while(aUx <(umin-aEps)) {
85 while(aUx>(umax+aEps)) {
91 gp_Vec2d aV2D(dU, 0.);
92 aC2D->Translate(aV2D);
96 //=======================================================================
97 //function : GetQuadric
99 //=======================================================================
100 static void GetQuadric(const Handle(GeomAdaptor_Surface)& HS1, IntSurf_Quadric& quad1)
102 switch (HS1->GetType())
104 case GeomAbs_Plane: quad1.SetValue(HS1->Plane()); break;
105 case GeomAbs_Cylinder: quad1.SetValue(HS1->Cylinder()); break;
106 case GeomAbs_Cone: quad1.SetValue(HS1->Cone()); break;
107 case GeomAbs_Sphere: quad1.SetValue(HS1->Sphere()); break;
108 case GeomAbs_Torus: quad1.SetValue(HS1->Torus()); break;
109 default: throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
113 //=======================================================================
114 //function : Parameters
116 //=======================================================================
117 static void Parameters( const Handle(GeomAdaptor_Surface)& HS1,
118 const Handle(GeomAdaptor_Surface)& HS2,
125 IntSurf_Quadric quad1,quad2;
127 GetQuadric(HS1, quad1);
128 GetQuadric(HS2, quad2);
130 quad1.Parameters(Ptref,U1,V1);
131 quad2.Parameters(Ptref,U2,V2);
134 //=======================================================================
135 //function : ParametersOfNearestPointOnSurface
137 //=======================================================================
138 static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS& theExtr,
142 if(!theExtr.IsDone() || !theExtr.NbExt())
143 return Standard_False;
145 Standard_Integer anIndex = 1;
146 Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
147 for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
149 Standard_Real aSQD = theExtr.SquareDistance(i);
150 if (aSQD < aMinSQDist)
157 theExtr.Point(anIndex).Parameter(theU, theV);
159 return Standard_True;
162 //=======================================================================
163 //function : GetSegmentBoundary
165 //=======================================================================
166 static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
167 const Handle(Geom2d_Curve)& theCurve,
168 GeomInt_VectorOfReal& theArrayOfParameters)
170 Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
172 if(theSegm.HasFirstPoint())
174 const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
175 aU1 = anIPF.ParamOnFirst();
178 if(theSegm.HasLastPoint())
180 const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
181 aU2 = anIPL.ParamOnFirst();
184 theArrayOfParameters.Append(aU1);
185 theArrayOfParameters.Append(aU2);
188 //=======================================================================
189 //function : IntersectCurveAndBoundary
191 //=======================================================================
192 static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
193 const Handle(Geom2d_Curve)* const theArrBounds,
194 const Standard_Integer theNumberOfCurves,
195 const Standard_Real theTol,
196 GeomInt_VectorOfReal& theArrayOfParameters)
201 Geom2dAdaptor_Curve anAC1(theC2d);
202 for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
204 if(theArrBounds[aCurID].IsNull())
207 Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
208 Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
210 if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
213 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
215 const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
216 theArrayOfParameters.Append(aParam);
219 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
221 GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
226 //=======================================================================
227 //function : isDegenerated
228 //purpose : Check if theAHC2d corresponds to a degenerated edge.
229 //=======================================================================
230 static Standard_Boolean isDegenerated(const Handle(GeomAdaptor_Surface)& theGAHS,
231 const Handle(Adaptor2d_Curve2d)& theAHC2d,
232 const Standard_Real theFirstPar,
233 const Standard_Real theLastPar)
235 const Standard_Real aSqTol = Precision::Confusion()*Precision::Confusion();
239 theAHC2d->D0(theFirstPar, aP2d);
240 theGAHS->D0(aP2d.X(), aP2d.Y(), aP1);
242 theAHC2d->D0(theLastPar, aP2d);
243 theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
245 if(aP1.SquareDistance(aP2) > aSqTol)
246 return Standard_False;
248 theAHC2d->D0(0.5*(theFirstPar+theLastPar), aP2d);
249 theGAHS->D0(aP2d.X(), aP2d.Y(), aP2);
251 if(aP1.SquareDistance(aP2) > aSqTol)
252 return Standard_False;
254 return Standard_True;
257 //=======================================================================
258 //function : MakeCurve
260 //=======================================================================
261 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
262 const Handle(Adaptor3d_TopolTool) & dom1,
263 const Handle(Adaptor3d_TopolTool) & dom2,
264 const Standard_Real Tol,
265 const Standard_Boolean Approx,
266 const Standard_Boolean ApproxS1,
267 const Standard_Boolean ApproxS2)
270 Standard_Boolean myApprox1, myApprox2, myApprox;
271 Standard_Real Tolpc, myTolApprox;
273 Handle(Geom2d_BSplineCurve) H1;
274 Handle(Geom_Surface) aS1, aS2;
280 myTolApprox=0.0000001;
282 aS1=myHS1->Surface();
283 aS2=myHS2->Surface();
285 Handle(IntPatch_Line) L = myIntersector.Line(Index);
288 if(typl==IntPatch_Walking) {
289 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
290 if(aWLine.IsNull()) {
297 myLConstruct.Perform(L);
298 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
303 Standard_Integer i, j, aNbParts;
304 Standard_Real fprm, lprm;
305 Handle(Geom_Curve) newc;
308 //########################################
309 // Line, Parabola, Hyperbola
310 //########################################
312 case IntPatch_Parabola:
313 case IntPatch_Hyperbola: {
314 if (typl == IntPatch_Lin) {
315 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
317 else if (typl == IntPatch_Parabola) {
318 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
320 else if (typl == IntPatch_Hyperbola) {
321 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
324 aNbParts=myLConstruct.NbParts();
325 for (i=1; i<=aNbParts; i++) {
326 myLConstruct.Part(i, fprm, lprm);
328 if (!Precision::IsNegativeInfinite(fprm) &&
329 !Precision::IsPositiveInfinite(lprm)) {
330 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
334 Handle (Geom2d_Curve) C2d;
335 BuildPCurves(fprm, lprm, Tolpc, myHS1->Surface(), newc, C2d);
336 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
337 myTolReached2d=Tolpc;
339 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
346 Handle (Geom2d_Curve) C2d;
347 BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
348 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
349 myTolReached2d=Tolpc;
352 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
357 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
360 GeomAbs_SurfaceType typS1 = myHS1->GetType();
361 GeomAbs_SurfaceType typS2 = myHS2->GetType();
362 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
363 typS1 == GeomAbs_OffsetSurface ||
364 typS1 == GeomAbs_SurfaceOfRevolution ||
365 typS2 == GeomAbs_SurfaceOfExtrusion ||
366 typS2 == GeomAbs_OffsetSurface ||
367 typS2 == GeomAbs_SurfaceOfRevolution) {
373 Standard_Boolean bFNIt, bLPIt;
374 Standard_Real aTestPrm, dT=100.;
375 Standard_Real u1, v1, u2, v2, TolX;
377 bFNIt=Precision::IsNegativeInfinite(fprm);
378 bLPIt=Precision::IsPositiveInfinite(lprm);
382 if (bFNIt && !bLPIt) {
385 else if (!bFNIt && bLPIt) {
389 gp_Pnt ptref(newc->Value(aTestPrm));
391 TolX = Precision::Confusion();
392 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
393 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
395 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
403 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
404 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
407 //########################################
408 // Circle and Ellipse
409 //########################################
410 case IntPatch_Circle:
411 case IntPatch_Ellipse: {
413 if (typl == IntPatch_Circle) {
414 newc = new Geom_Circle
415 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
418 newc = new Geom_Ellipse
419 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
422 Standard_Real aPeriod, aRealEpsilon;
424 aRealEpsilon=RealEpsilon();
427 aNbParts=myLConstruct.NbParts();
429 for (i=1; i<=aNbParts; i++) {
430 myLConstruct.Part(i, fprm, lprm);
432 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
433 //==============================================
434 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
438 fprm=aTC3D->FirstParameter();
439 lprm=aTC3D->LastParameter ();
442 Handle (Geom2d_Curve) C2d;
443 BuildPCurves(fprm,lprm,Tolpc,myHS1->Surface(),newc,C2d);
444 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
445 myTolReached2d=Tolpc;
454 Handle (Geom2d_Curve) C2d;
455 BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
456 if(Tolpc>myTolReached2d || myTolReached2d==0) {
457 myTolReached2d=Tolpc;
464 //==============================================
465 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
467 else {// on regarde si on garde
470 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
471 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
474 fprm=aTC3D->FirstParameter();
475 lprm=aTC3D->LastParameter ();
478 Handle (Geom2d_Curve) C2d;
479 BuildPCurves(fprm,lprm,Tolpc,myHS1->Surface(),newc,C2d);
480 if(Tolpc>myTolReached2d || myTolReached2d==0) {
481 myTolReached2d=Tolpc;
490 Handle (Geom2d_Curve) C2d;
491 BuildPCurves(fprm,lprm,Tolpc,myHS2->Surface(),newc,C2d);
492 if(Tolpc>myTolReached2d || myTolReached2d==0) {
493 myTolReached2d=Tolpc;
504 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
506 aTwoPIdiv17=2.*M_PI/17.;
508 for (j=0; j<=17; j++) {
509 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
510 TolX = Precision::Confusion();
512 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
513 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
515 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
519 //==============================================
521 Handle (Geom2d_Curve) C2d;
522 BuildPCurves(fprm, lprm, Tolpc, myHS1->Surface(), newc, C2d);
523 if(Tolpc>myTolReached2d || myTolReached2d==0) {
524 myTolReached2d=Tolpc;
533 Handle (Geom2d_Curve) C2d;
534 BuildPCurves(fprm, lprm, Tolpc,myHS2->Surface(), newc, C2d);
535 if(Tolpc>myTolReached2d || myTolReached2d==0) {
536 myTolReached2d=Tolpc;
545 }// end of for (Standard_Integer j=0; j<=17; j++)
546 }// end of else { on regarde si on garde
547 }// for (i=1; i<=myLConstruct.NbParts(); i++)
548 }// IntPatch_Circle: IntPatch_Ellipse
551 //########################################
553 //########################################
554 case IntPatch_Analytic:
555 //This case was processed earlier (in IntPatch_Intersection)
559 //########################################
561 //########################################
562 case IntPatch_Walking:{
563 Handle(IntPatch_WLine) WL =
564 Handle(IntPatch_WLine)::DownCast(L);
566 #ifdef GEOMINT_INTSS_DEBUG
571 Standard_Integer ifprm, ilprm;
574 aNbParts=myLConstruct.NbParts();
575 for (i=1; i<=aNbParts; i++) {
576 myLConstruct.Part(i, fprm, lprm);
577 ifprm=(Standard_Integer)fprm;
578 ilprm=(Standard_Integer)lprm;
580 Handle(Geom2d_BSplineCurve) aH1, aH2;
583 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
586 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
589 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
598 Standard_Boolean bIsDecomposited;
599 Standard_Integer nbiter, aNbSeqOfL;
600 GeomInt_WLApprox theapp3d;
601 IntPatch_SequenceOfLine aSeqOfL;
602 Standard_Real tol2d, aTolSS;
606 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2);
609 GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
611 aNbParts=myLConstruct.NbParts();
612 aNbSeqOfL=aSeqOfL.Length();
614 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
616 for(i = 1; i <= nbiter; i++) {
617 if(bIsDecomposited) {
618 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
620 ilprm = WL->NbPnts();
623 myLConstruct.Part(i, fprm, lprm);
624 ifprm = (Standard_Integer)fprm;
625 ilprm = (Standard_Integer)lprm;
628 Standard_Boolean anApprox = myApprox;
629 Standard_Boolean anApprox1 = myApprox1;
630 Standard_Boolean anApprox2 = myApprox2;
631 GeomAbs_SurfaceType typs1, typs2;
632 typs1 = myHS1->GetType();
633 typs2 = myHS2->GetType();
635 if (typs1 == GeomAbs_Plane) {
636 anApprox = Standard_False;
637 anApprox1 = Standard_True;
639 else if (typs2 == GeomAbs_Plane) {
640 anApprox = Standard_False;
641 anApprox2 = Standard_True;
644 Approx_ParametrizationType aParType = ApproxInt_KnotTools::DefineParType(WL, ifprm, ilprm,
645 anApprox, anApprox1, anApprox2);
647 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2, aParType);
650 //-- Si une des surfaces est un plan , on approxime en 2d
651 //-- sur cette surface et on remonte les points 2d en 3d.
653 if(typs1 == GeomAbs_Plane) {
654 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
655 Standard_True, myApprox2,
658 else if(typs2 == GeomAbs_Plane) {
659 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
660 myApprox1,Standard_True,
666 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
667 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
669 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True, aParType);
673 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
678 if (!theapp3d.IsDone()) {
680 Handle(Geom2d_BSplineCurve) aH1, aH2;
682 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
684 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
687 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
693 }//if (!theapp3d.IsDone())
696 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
697 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
698 myTolReached2d = theapp3d.TolReached2d();
701 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
702 myTolReached3d = myTolReached2d;
704 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
705 myTolReached3d = theapp3d.TolReached3d();
708 Standard_Integer aNbMultiCurves, nbpoles;
710 aNbMultiCurves=theapp3d.NbMultiCurves();
711 for (j=1; j<=aNbMultiCurves; j++) {
712 if(typs1 == GeomAbs_Plane) {
713 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
714 nbpoles = mbspc.NbPoles();
716 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
717 TColgp_Array1OfPnt tpoles(1,nbpoles);
719 mbspc.Curve(1,tpoles2d);
720 const gp_Pln& Pln = myHS1->Plane();
723 for(ik = 1; ik<= nbpoles; ik++) {
725 ElSLib::Value(tpoles2d.Value(ik).X(),
726 tpoles2d.Value(ik).Y(),
730 Handle(Geom_BSplineCurve) BS =
731 new Geom_BSplineCurve(tpoles,
733 mbspc.Multiplicities(),
735 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
736 Check.FixTangent(Standard_True, Standard_True);
741 Handle(Geom2d_BSplineCurve) BS1 =
742 new Geom2d_BSplineCurve(tpoles2d,
744 mbspc.Multiplicities(),
746 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
747 Check1.FixTangent(Standard_True,Standard_True);
749 AdjustUPeriodic (aS1, BS1);
758 mbspc.Curve(2, tpoles2d);
760 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
762 mbspc.Multiplicities(),
764 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
765 newCheck.FixTangent(Standard_True,Standard_True);
767 AdjustUPeriodic (aS2, BS2);
774 }//if(typs1 == GeomAbs_Plane)
776 else if(typs2 == GeomAbs_Plane) {
777 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
778 nbpoles = mbspc.NbPoles();
780 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
781 TColgp_Array1OfPnt tpoles(1,nbpoles);
782 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
783 const gp_Pln& Pln = myHS2->Plane();
786 for(ik = 1; ik<= nbpoles; ik++) {
788 ElSLib::Value(tpoles2d.Value(ik).X(),
789 tpoles2d.Value(ik).Y(),
794 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
796 mbspc.Multiplicities(),
798 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
799 Check.FixTangent(Standard_True,Standard_True);
804 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
806 mbspc.Multiplicities(),
808 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
809 Check1.FixTangent(Standard_True,Standard_True);
812 AdjustUPeriodic (aS2, BS1);
821 mbspc.Curve(1,tpoles2d);
822 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
824 mbspc.Multiplicities(),
826 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
827 Check2.FixTangent(Standard_True,Standard_True);
830 AdjustUPeriodic (aS1, BS2);
837 } // else if(typs2 == GeomAbs_Plane)
839 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
840 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
841 nbpoles = mbspc.NbPoles();
842 TColgp_Array1OfPnt tpoles(1,nbpoles);
843 mbspc.Curve(1,tpoles);
844 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
846 mbspc.Multiplicities(),
848 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
849 Check.FixTangent(Standard_True,Standard_True);
852 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
853 BS->EndPoint().XYZ().SquareModulus());
854 Standard_Real eps = Epsilon(aDist);
855 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
857 // Avoid creating B-splines containing two coincident poles only
858 if (mbspc.Degree() == 1 && nbpoles == 2)
861 if (!BS->IsClosed() && !BS->IsPeriodic())
864 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
866 BS->SetPole(BS->NbPoles(), aPm);
872 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
873 mbspc.Curve(2,tpoles2d);
874 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
876 mbspc.Multiplicities(),
878 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
879 newCheck.FixTangent(Standard_True,Standard_True);
881 AdjustUPeriodic (aS1, BS1);
889 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
890 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
891 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
893 mbspc.Multiplicities(),
895 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
896 newCheck.FixTangent(Standard_True,Standard_True);
898 AdjustUPeriodic (aS2, BS2);
905 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
906 }// for (j=1; j<=aNbMultiCurves; j++
913 case IntPatch_Restriction:
915 Handle(IntPatch_RLine) RL =
916 Handle(IntPatch_RLine)::DownCast(L);
917 Handle(Geom_Curve) aC3d;
918 Handle(Geom2d_Curve) aC2d1, aC2d2;
919 Standard_Real aTolReached;
920 TreatRLine(RL, myHS1, myHS2, aC3d,
921 aC2d1, aC2d2, aTolReached);
926 Bnd_Box2d aBox1, aBox2;
928 const Standard_Real aU1f = myHS1->FirstUParameter(),
929 aV1f = myHS1->FirstVParameter(),
930 aU1l = myHS1->LastUParameter(),
931 aV1l = myHS1->LastVParameter();
932 const Standard_Real aU2f = myHS2->FirstUParameter(),
933 aV2f = myHS2->FirstVParameter(),
934 aU2l = myHS2->LastUParameter(),
935 aV2l = myHS2->LastVParameter();
937 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
938 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
939 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
940 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
942 GeomInt_VectorOfReal anArrayOfParameters;
944 //We consider here that the intersection line is same-parameter-line
945 anArrayOfParameters.Append(aC3d->FirstParameter());
946 anArrayOfParameters.Append(aC3d->LastParameter());
948 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
950 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
953 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
955 const Standard_Real aParF = anArrayOfParameters(anInd),
956 aParL = anArrayOfParameters(anInd+1);
958 if((aParL - aParF) <= Precision::PConfusion())
961 const Standard_Real aPar = 0.5*(aParF + aParL);
964 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
967 aC2d1->D0(aPar, aPt);
973 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
978 aC2d2->D0(aPar, aPt);
984 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
987 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
989 sline.Append(aCurv3d);
990 slineS1.Append(aCurv2d1);
991 slineS2.Append(aCurv2d2);
998 //=======================================================================
999 //function : TreatRLine
1000 //purpose : Approx of Restriction line
1001 //=======================================================================
1002 void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
1003 const Handle(GeomAdaptor_Surface)& theHS1,
1004 const Handle(GeomAdaptor_Surface)& theHS2,
1005 Handle(Geom_Curve)& theC3d,
1006 Handle(Geom2d_Curve)& theC2d1,
1007 Handle(Geom2d_Curve)& theC2d2,
1008 Standard_Real& theTolReached)
1010 Handle(GeomAdaptor_Surface) aGAHS;
1011 Handle(Adaptor2d_Curve2d) anAHC2d;
1012 Standard_Real tf, tl;
1014 // It is assumed that 2d curve is 2d line (rectangular surface domain)
1015 if(theRL->IsArcOnS1())
1018 anAHC2d = theRL->ArcOnS1();
1019 theRL->ParamOnS1(tf, tl);
1020 theC2d1 = Geom2dAdaptor::MakeCurve (*anAHC2d);
1021 tf = Max(tf, theC2d1->FirstParameter());
1022 tl = Min(tl, theC2d1->LastParameter());
1023 theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl);
1025 else if (theRL->IsArcOnS2())
1028 anAHC2d = theRL->ArcOnS2();
1029 theRL->ParamOnS2(tf, tl);
1030 theC2d2 = Geom2dAdaptor::MakeCurve (*anAHC2d);
1031 tf = Max(tf, theC2d2->FirstParameter());
1032 tl = Min(tl, theC2d2->LastParameter());
1033 theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl);
1040 //Restriction line can correspond to a degenerated edge.
1041 //In this case we return null-curve.
1042 if(isDegenerated(aGAHS, anAHC2d, tf, tl))
1046 //To provide sameparameter it is necessary to get 3d curve as
1047 //approximation of curve on surface.
1048 Standard_Integer aMaxDeg = 8;
1049 Standard_Integer aMaxSeg = 1000;
1050 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion());
1051 anApp.Perform(aMaxSeg, aMaxDeg, GeomAbs_C1, Standard_True, Standard_False);
1052 if(!anApp.HasResult())
1055 theC3d = anApp.Curve3d();
1056 theTolReached = anApp.MaxError3d();
1057 Standard_Real aTol = Precision::Confusion();
1058 if(theRL->IsArcOnS1())
1060 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface (*theHS2);
1061 BuildPCurves (tf, tl, aTol,
1062 aS, theC3d, theC2d2);
1064 if(theRL->IsArcOnS2())
1066 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface (*theHS1);
1067 BuildPCurves (tf, tl, aTol,
1068 aS, theC3d, theC2d1);
1070 theTolReached = Max(theTolReached, aTol);
1073 //=======================================================================
1074 //function : BuildPCurves
1076 //=======================================================================
1077 void GeomInt_IntSS::BuildPCurves (Standard_Real f,
1080 const Handle (Geom_Surface)& S,
1081 const Handle (Geom_Curve)& C,
1082 Handle (Geom2d_Curve)& C2d)
1084 if (!C2d.IsNull()) {
1088 Standard_Real umin,umax,vmin,vmax;
1090 S->Bounds(umin, umax, vmin, vmax);
1091 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
1092 if((l - f) > 2.e-09) {
1093 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
1095 // proj. a circle that goes through the pole on a sphere to the sphere
1096 Tol += Precision::Confusion();
1097 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
1099 const Handle(Standard_Type)& aType = C2d->DynamicType();
1100 if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve))
1102 //Check first, last knots to avoid problems with trimming
1103 //First, last knots can differ from f, l because of numerical error
1104 //of projection and approximation
1105 //The same checking as in Geom2d_TrimmedCurve
1106 if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
1107 (l - C2d->LastParameter() > Precision::PConfusion()))
1109 Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1110 TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
1111 aBspl->Knots(aKnots);
1112 BSplCLib::Reparametrize(f, l, aKnots);
1113 aBspl->SetKnots(aKnots);
1118 if((l - f) > Epsilon(Abs(f)))
1120 //The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
1121 //On this small range C2d can be considered as segment
1124 Standard_Real aU=0., aV=0.;
1125 GeomAdaptor_Surface anAS;
1127 Extrema_ExtPS anExtr;
1128 const gp_Pnt aP3d1 = C->Value(f);
1129 const gp_Pnt aP3d2 = C->Value(l);
1131 anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
1132 anExtr.Initialize(anAS, umin, umax, vmin, vmax,
1133 Precision::Confusion(), Precision::Confusion());
1134 anExtr.Perform(aP3d1);
1136 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1138 const gp_Pnt2d aP2d1(aU, aV);
1140 anExtr.Perform(aP3d2);
1142 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1144 const gp_Pnt2d aP2d2(aU, aV);
1146 if(aP2d1.Distance(aP2d2) > gp::Resolution())
1148 TColgp_Array1OfPnt2d poles(1,2);
1149 TColStd_Array1OfReal knots(1,2);
1150 TColStd_Array1OfInteger mults(1,2);
1155 mults(1) = mults(2) = 2;
1157 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
1159 //Check same parameter in middle point .begin
1160 const gp_Pnt PMid(C->Value(0.5*(f+l)));
1161 const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
1162 const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
1163 const Standard_Real aDist = PMid.Distance(aPC);
1164 Tol = Max(aDist, Tol);
1165 //Check same parameter in middle point .end
1172 if (S->IsUPeriodic() && !C2d.IsNull()) {
1173 // Recadre dans le domaine UV de la face
1174 Standard_Real aTm, U0, aEps, period, du, U0x;
1175 Standard_Boolean bAdjust;
1177 aEps = Precision::PConfusion();
1178 period = S->UPeriod();
1181 gp_Pnt2d pm = C2d->Value(aTm);
1185 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
1187 gp_Vec2d T1(du, 0.);
1193 //=======================================================================
1194 //function : TrimILineOnSurfBoundaries
1195 //purpose : This function finds intersection points of given curves with
1196 // surface boundaries and fills theArrayOfParameters by parameters
1197 // along the given curves corresponding of these points.
1198 //=======================================================================
1199 void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
1200 const Handle(Geom2d_Curve)& theC2d2,
1201 const Bnd_Box2d& theBound1,
1202 const Bnd_Box2d& theBound2,
1203 GeomInt_VectorOfReal& theArrayOfParameters)
1205 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
1206 // [2]:V=Vfirst, [3]:V=Vlast
1207 const Standard_Integer aNumberOfCurves = 4;
1208 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
1209 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
1211 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
1212 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
1214 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
1215 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
1217 Standard_Real aDelta = aV1l-aV1f;
1218 if(Abs(aDelta) > RealSmall())
1220 if(!Precision::IsInfinite(aU1f))
1222 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
1224 if(!Precision::IsInfinite(aDelta))
1225 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
1228 if(!Precision::IsInfinite(aU1l))
1230 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
1231 if(!Precision::IsInfinite(aDelta))
1232 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
1237 if(Abs(aDelta) > RealSmall())
1239 if(!Precision::IsInfinite(aV1f))
1241 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
1242 if(!Precision::IsInfinite(aDelta))
1243 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
1246 if(!Precision::IsInfinite(aV1l))
1248 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
1249 if(!Precision::IsInfinite(aDelta))
1250 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
1255 if(Abs(aDelta) > RealSmall())
1257 if(!Precision::IsInfinite(aU2f))
1259 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
1260 if(!Precision::IsInfinite(aDelta))
1261 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
1264 if(!Precision::IsInfinite(aU2l))
1266 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
1267 if(!Precision::IsInfinite(aDelta))
1268 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
1273 if(Abs(aDelta) > RealSmall())
1275 if(!Precision::IsInfinite(aV2f))
1277 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
1278 if(!Precision::IsInfinite(aDelta))
1279 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
1282 if(!Precision::IsInfinite(aV2l))
1284 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
1285 if(!Precision::IsInfinite(aDelta))
1286 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
1290 const Standard_Real anIntTol = 10.0*Precision::Confusion();
1292 IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
1293 aNumberOfCurves, anIntTol, theArrayOfParameters);
1295 IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
1296 aNumberOfCurves, anIntTol, theArrayOfParameters);
1298 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());
1301 //=======================================================================
1302 //function : MakeBSpline
1304 //=======================================================================
1305 Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline (const Handle(IntPatch_WLine)& WL,
1306 const Standard_Integer ideb,
1307 const Standard_Integer ifin)
1309 const Standard_Integer nbpnt = ifin-ideb+1;
1310 TColgp_Array1OfPnt poles(1,nbpnt);
1311 TColStd_Array1OfReal knots(1,nbpnt);
1312 TColStd_Array1OfInteger mults(1,nbpnt);
1313 Standard_Integer i = 1, ipidebm1 = ideb;
1314 for(; i<=nbpnt; ipidebm1++, i++)
1316 poles(i) = WL->Point(ipidebm1).Value();
1320 mults(1) = mults(nbpnt) = 2;
1321 return new Geom_BSplineCurve(poles,knots,mults,1);
1324 //=======================================================================
1325 //function : MakeBSpline2d
1327 //=======================================================================
1328 Handle(Geom2d_BSplineCurve) GeomInt_IntSS::
1329 MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1330 const Standard_Integer ideb,
1331 const Standard_Integer ifin,
1332 const Standard_Boolean onFirst)
1334 const Standard_Integer nbpnt = ifin-ideb+1;
1335 TColgp_Array1OfPnt2d poles(1,nbpnt);
1336 TColStd_Array1OfReal knots(1,nbpnt);
1337 TColStd_Array1OfInteger mults(1,nbpnt);
1338 Standard_Integer i = 1, ipidebm1 = ideb;
1339 for(; i <= nbpnt; ipidebm1++, i++)
1343 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1345 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1346 poles(i).SetCoord(U, V);
1351 mults(1) = mults(nbpnt) = 2;
1352 return new Geom2d_BSplineCurve(poles,knots,mults,1);