1 // Created on: 2000-11-23
2 // Created by: Michael KLOKOV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <IntTools_FaceFace.hxx>
18 #include <BRepAdaptor_Surface.hxx>
19 #include <BRepTools.hxx>
20 #include <BRep_Tool.hxx>
23 #include <Geom2dAdaptor_Curve.hxx>
24 #include <Geom2dInt_GInter.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom2d_TrimmedCurve.hxx>
27 #include <GeomAPI_ProjectPointOnSurf.hxx>
28 #include <GeomAdaptor_HSurface.hxx>
29 #include <GeomInt_IntSS.hxx>
30 #include <GeomInt_WLApprox.hxx>
31 #include <GeomLib_Check2dBSplineCurve.hxx>
32 #include <GeomLib_CheckBSplineCurve.hxx>
33 #include <Geom_BSplineCurve.hxx>
34 #include <Geom_Circle.hxx>
35 #include <Geom_Ellipse.hxx>
36 #include <Geom_Hyperbola.hxx>
37 #include <Geom_Line.hxx>
38 #include <Geom_OffsetSurface.hxx>
39 #include <Geom_Parabola.hxx>
40 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <Geom_TrimmedCurve.hxx>
42 #include <IntAna_QuadQuadGeo.hxx>
43 #include <IntPatch_GLine.hxx>
44 #include <IntPatch_RLine.hxx>
45 #include <IntPatch_WLine.hxx>
46 #include <IntRes2d_Domain.hxx>
47 #include <IntSurf_Quadric.hxx>
48 #include <IntTools_Context.hxx>
49 #include <IntTools_Tools.hxx>
50 #include <IntTools_TopolTool.hxx>
51 #include <IntTools_WLineTool.hxx>
52 #include <ProjLib_Plane.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <gp_Elips.hxx>
59 void Parameters(const Handle(GeomAdaptor_HSurface)&,
60 const Handle(GeomAdaptor_HSurface)&,
68 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
69 const Standard_Real theTolerance,
70 Standard_Real& theumin,
71 Standard_Real& theumax,
72 Standard_Real& thevmin,
73 Standard_Real& thevmax);
76 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
77 const Handle(Geom_Curve)& theCurve,
78 const TopoDS_Face& theFace1,
79 const TopoDS_Face& theFace2,
80 const Standard_Real theOtherParameter,
81 const Standard_Boolean bIncreasePar,
82 const Standard_Real theTol,
83 Standard_Real& theNewParameter,
84 const Handle(IntTools_Context)& );
87 Standard_Boolean IsCurveValid(const Handle(Geom2d_Curve)& thePCurve);
90 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
91 const gp_Sphere& theSph);
93 static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
94 const Handle(GeomAdaptor_HSurface)& theS2,
95 const Standard_Real TolF1,
96 const Standard_Real TolF2,
97 const Standard_Real TolAng,
98 const Standard_Real TolTang,
99 const Standard_Boolean theApprox1,
100 const Standard_Boolean theApprox2,
101 IntTools_SequenceOfCurves& theSeqOfCurve,
102 Standard_Boolean& theTangentFaces);
104 static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
105 const gp_Lin2d& theLin2d,
106 const Standard_Real theTol,
107 Standard_Real& theP1,
108 Standard_Real& theP2);
111 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
112 const Handle(GeomAdaptor_HSurface)& aHS2,
113 Standard_Integer& iDegMin,
114 Standard_Integer& iNbIter,
115 Standard_Integer& iDegMax);
118 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
119 const Handle(GeomAdaptor_HSurface)& aHS2,
120 Standard_Real& aTolTang);
123 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
124 const GeomAbs_SurfaceType aType2);
126 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
130 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
131 const TopoDS_Face& aFace,
132 const Handle(IntTools_Context)& theCtx);
135 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
136 const Standard_Real aT,
137 GeomAPI_ProjectPointOnSurf& theProjPS);
140 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
141 const Standard_Real theFirst,
142 const Standard_Real theLast,
143 GeomAPI_ProjectPointOnSurf& theProjPS,
144 const Standard_Real theEps);
147 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
148 const Standard_Real theFirst,
149 const Standard_Real theLast,
150 const TopoDS_Face& theFace,
151 const Handle(IntTools_Context)& theContext);
154 void CorrectPlaneBoundaries(Standard_Real& aUmin,
155 Standard_Real& aUmax,
156 Standard_Real& aVmin,
157 Standard_Real& aVmax);
159 //=======================================================================
162 //=======================================================================
163 IntTools_FaceFace::IntTools_FaceFace()
165 myIsDone=Standard_False;
166 myTangentFaces=Standard_False;
168 myHS1 = new GeomAdaptor_HSurface ();
169 myHS2 = new GeomAdaptor_HSurface ();
173 myFuzzyValue = Precision::Confusion();
174 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
176 //=======================================================================
177 //function : SetContext
179 //=======================================================================
180 void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
184 //=======================================================================
187 //=======================================================================
188 const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
192 //=======================================================================
195 //=======================================================================
196 const TopoDS_Face& IntTools_FaceFace::Face1() const
200 //=======================================================================
203 //=======================================================================
204 const TopoDS_Face& IntTools_FaceFace::Face2() const
208 //=======================================================================
209 //function : TangentFaces
211 //=======================================================================
212 Standard_Boolean IntTools_FaceFace::TangentFaces() const
214 return myTangentFaces;
216 //=======================================================================
219 //=======================================================================
220 const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
224 //=======================================================================
227 //=======================================================================
228 Standard_Boolean IntTools_FaceFace::IsDone() const
232 //=======================================================================
234 //purpose : return lines of intersection
235 //=======================================================================
236 const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
238 StdFail_NotDone_Raise_if
240 "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
243 // =======================================================================
244 // function: SetParameters
246 // =======================================================================
247 void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
248 const Standard_Boolean ToApproxC2dOnS1,
249 const Standard_Boolean ToApproxC2dOnS2,
250 const Standard_Real ApproximationTolerance)
252 myApprox = ToApproxC3d;
253 myApprox1 = ToApproxC2dOnS1;
254 myApprox2 = ToApproxC2dOnS2;
255 myTolApprox = ApproximationTolerance;
257 //=======================================================================
258 //function : SetFuzzyValue
260 //=======================================================================
261 void IntTools_FaceFace::SetFuzzyValue(const Standard_Real theFuzz)
263 myFuzzyValue = Max(theFuzz, Precision::Confusion());
265 //=======================================================================
266 //function : FuzzyValue
268 //=======================================================================
269 Standard_Real IntTools_FaceFace::FuzzyValue() const
274 //=======================================================================
277 //=======================================================================
278 void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
280 myListOfPnts = aListOfPnts;
284 static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
285 const BRepAdaptor_Surface& theBAS2,
286 const Standard_Real theTol)
288 const Standard_Real Tolang = 1.e-8;
289 Standard_Real aHigh = 0.0;
291 const GeomAbs_SurfaceType aType1=theBAS1.GetType();
292 const GeomAbs_SurfaceType aType2=theBAS2.GetType();
296 if(aType1 == GeomAbs_Plane)
300 else if(aType2 == GeomAbs_Plane)
306 return Standard_True;
309 if(aType1 == GeomAbs_Cylinder)
311 aS2=theBAS1.Cylinder();
312 const Standard_Real VMin = theBAS1.FirstVParameter();
313 const Standard_Real VMax = theBAS1.LastVParameter();
315 if( Precision::IsNegativeInfinite(VMin) ||
316 Precision::IsPositiveInfinite(VMax))
317 return Standard_True;
321 else if(aType2 == GeomAbs_Cylinder)
323 aS2=theBAS2.Cylinder();
325 const Standard_Real VMin = theBAS2.FirstVParameter();
326 const Standard_Real VMax = theBAS2.LastVParameter();
328 if( Precision::IsNegativeInfinite(VMin) ||
329 Precision::IsPositiveInfinite(VMax))
330 return Standard_True;
336 return Standard_True;
339 IntAna_QuadQuadGeo inter;
340 inter.Perform(aS1,aS2,Tolang,theTol, aHigh);
341 if(inter.TypeInter() == IntAna_Ellipse)
343 const gp_Elips anEl = inter.Ellipse(1);
344 const Standard_Real aMajorR = anEl.MajorRadius();
345 const Standard_Real aMinorR = anEl.MinorRadius();
347 return (aMajorR < 100000.0 * aMinorR);
351 return inter.IsDone();
354 //=======================================================================
356 //purpose : intersect surfaces of the faces
357 //=======================================================================
358 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
359 const TopoDS_Face& aF2)
361 if (myContext.IsNull()) {
362 myContext=new IntTools_Context;
365 mySeqOfCurve.Clear();
366 myIsDone = Standard_False;
372 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(myFace1);
373 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(myFace2);
374 GeomAbs_SurfaceType aType1=aBAS1.GetType();
375 GeomAbs_SurfaceType aType2=aBAS2.GetType();
377 const Standard_Boolean bReverse=SortTypes(aType1, aType2);
382 aType1=aBAS2.GetType();
383 aType2=aBAS1.GetType();
385 if (myListOfPnts.Extent())
387 Standard_Real aU1,aV1,aU2,aV2;
388 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
390 aItP2S.Initialize(myListOfPnts);
391 for (; aItP2S.More(); aItP2S.Next())
393 IntSurf_PntOn2S& aP2S=aItP2S.Value();
394 aP2S.Parameters(aU1,aV1,aU2,aV2);
395 aP2S.SetValue(aU2,aV2,aU1,aV1);
399 Standard_Boolean anAproxTmp = myApprox1;
400 myApprox1 = myApprox2;
401 myApprox2 = anAproxTmp;
405 const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
406 const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
408 Standard_Real aFuzz = myFuzzyValue / 2.;
409 myTolF1 = BRep_Tool::Tolerance(myFace1) + aFuzz;
410 myTolF2 = BRep_Tool::Tolerance(myFace2) + aFuzz;
411 myTol = myTolF1 + myTolF2;
413 Standard_Real TolArc = myTol;
414 Standard_Real TolTang = TolArc;
416 const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
417 aType1 == GeomAbs_Cone ||
418 aType1 == GeomAbs_Torus);
420 const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
421 aType2 == GeomAbs_Cone ||
422 aType2 == GeomAbs_Torus);
424 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
425 Standard_Real umin, umax, vmin, vmax;
427 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
428 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
429 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
431 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
432 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
433 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
435 Standard_Real TolAng = 1.e-8;
437 PerformPlanes(myHS1, myHS2,
438 myTolF1, myTolF2, TolAng, TolTang,
439 myApprox1, myApprox2,
440 mySeqOfCurve, myTangentFaces);
442 myIsDone = Standard_True;
444 if (!myTangentFaces) {
445 const Standard_Integer NbLinPP = mySeqOfCurve.Length();
446 if (NbLinPP && bReverse) {
447 Handle(Geom2d_Curve) aC2D1, aC2D2;
448 const Standard_Integer aNbLin = mySeqOfCurve.Length();
449 for (Standard_Integer i = 1; i <= aNbLin; ++i) {
450 IntTools_Curve& aIC = mySeqOfCurve(i);
451 aC2D1 = aIC.FirstCurve2d();
452 aC2D2 = aIC.SecondCurve2d();
453 aIC.SetFirstCurve2d(aC2D2);
454 aIC.SetSecondCurve2d(aC2D1);
459 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
461 if ((aType1==GeomAbs_Plane) && isFace2Quad)
463 Standard_Real umin, umax, vmin, vmax;
465 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
466 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
467 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
469 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
470 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
471 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
473 else if ((aType2==GeomAbs_Plane) && isFace1Quad)
475 Standard_Real umin, umax, vmin, vmax;
477 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
478 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
479 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
481 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
482 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
483 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
487 Standard_Real umin, umax, vmin, vmax;
488 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
489 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
490 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
491 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
492 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
493 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
496 const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
497 const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
499 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
502 Tolerances(myHS1, myHS2, TolTang);
505 const Standard_Real UVMaxStep = 0.001;
506 const Standard_Real Deflection = 0.1;
507 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
510 if((aType1 != GeomAbs_BSplineSurface) &&
511 (aType1 != GeomAbs_BezierSurface) &&
512 (aType1 != GeomAbs_OtherSurface) &&
513 (aType2 != GeomAbs_BSplineSurface) &&
514 (aType2 != GeomAbs_BezierSurface) &&
515 (aType2 != GeomAbs_OtherSurface))
517 if ((aType1 == GeomAbs_Torus) ||
518 (aType2 == GeomAbs_Torus))
520 myListOfPnts.Clear();
524 #ifdef INTTOOLS_FACEFACE_DEBUG
525 if(!myListOfPnts.IsEmpty()) {
527 const IntSurf_PntOn2S& aPt = myListOfPnts.First();
528 Standard_Real u1, v1, u2, v2;
529 aPt.Parameters(u1, v1, u2, v2);
531 Sprintf(aBuff,"bopcurves <face1 face2> -2d");
532 IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);
533 for(;IterLOP1.More(); IterLOP1.Next())
535 const IntSurf_PntOn2S& aPt = IterLOP1.Value();
536 Standard_Real u1, v1, u2, v2;
537 aPt.Parameters(u1, v1, u2, v2);
539 Sprintf(aBuff, "%s -p %+10.20f %+10.20f %+10.20f %+10.20f", aBuff, u1, v1, u2, v2);
542 cout << aBuff << endl;
546 const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol);
548 myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
550 myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
551 myListOfPnts, isGeomInt);
553 myIsDone = myIntersector.IsDone();
557 myTangentFaces=myIntersector.TangentFaces();
558 if (myTangentFaces) {
562 const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
563 for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
564 MakeCurve(i, dom1, dom2, TolArc);
567 ComputeTolReached3d();
570 Handle(Geom2d_Curve) aC2D1, aC2D2;
572 const Standard_Integer aNbLinSeqOfCurve =mySeqOfCurve.Length();
573 for (Standard_Integer i=1; i<=aNbLinSeqOfCurve; ++i)
575 IntTools_Curve& aIC=mySeqOfCurve(i);
576 aC2D1=aIC.FirstCurve2d();
577 aC2D2=aIC.SecondCurve2d();
578 aIC.SetFirstCurve2d(aC2D2);
579 aIC.SetSecondCurve2d(aC2D1);
584 Standard_Boolean bValid2D1, bValid2D2;
585 Standard_Real U1,V1,U2,V2;
586 IntTools_PntOnFace aPntOnF1, aPntOnF2;
587 IntTools_PntOn2Faces aPntOn2Faces;
589 const Standard_Integer aNbPnts = myIntersector.NbPnts();
590 for (Standard_Integer i=1; i <= aNbPnts; ++i)
592 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
593 const gp_Pnt& aPnt=aISPnt.Value();
594 aISPnt.Parameters(U1,V1,U2,V2);
596 // check the validity of the intersection point for the faces
597 bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
602 bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
607 // add the intersection point
608 aPntOnF1.Init(myFace1, aPnt, U1, V1);
609 aPntOnF2.Init(myFace2, aPnt, U2, V2);
613 aPntOn2Faces.SetP1(aPntOnF1);
614 aPntOn2Faces.SetP2(aPntOnF2);
618 aPntOn2Faces.SetP2(aPntOnF1);
619 aPntOn2Faces.SetP1(aPntOnF2);
622 myPnts.Append(aPntOn2Faces);
627 //=======================================================================
628 //function :ComputeTolReached3d
630 //=======================================================================
631 void IntTools_FaceFace::ComputeTolReached3d()
633 Standard_Integer i, j, aNbLin = mySeqOfCurve.Length();
638 // Minimal tangential tolerance for the curve
639 Standard_Real aTolFMax = Max(myTolF1, myTolF2);
641 const Handle(Geom_Surface)& aS1 = myHS1->ChangeSurface().Surface();
642 const Handle(Geom_Surface)& aS2 = myHS2->ChangeSurface().Surface();
644 for (i = 1; i <= aNbLin; ++i)
646 IntTools_Curve& aIC = mySeqOfCurve(i);
647 const Handle(Geom_Curve)& aC3D = aIC.Curve();
653 Standard_Real aTolC = aIC.Tolerance();
654 Standard_Real aFirst = aC3D->FirstParameter();
655 Standard_Real aLast = aC3D->LastParameter();
657 // Compute the tolerance for the curve
658 const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
659 const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
661 for (j = 0; j < 2; ++j)
663 const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
666 // Look for the maximal deviation between 3D and 2D curves
667 Standard_Real aD, aT;
668 const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
669 if (IntTools_Tools::ComputeTolerance
670 (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
680 // Look for the maximal deviation between 3D curve and surface
681 const TopoDS_Face& aF = !j ? myFace1 : myFace2;
682 Standard_Real aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
689 // Set the valid tolerance for the curve
690 aIC.SetTolerance(aTolC);
692 // Set the tangential tolerance for the curve.
693 // Note, that, currently, computation of the tangential tolerance is
694 // implemented for the Plane/Plane case only.
695 // Thus, set the tangential tolerance equal to maximal tolerance of faces.
696 if (aIC.TangentialTolerance() < aTolFMax) {
697 aIC.SetTangentialTolerance(aTolFMax);
702 //=======================================================================
703 //function : MakeCurve
705 //=======================================================================
706 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
707 const Handle(Adaptor3d_TopolTool)& dom1,
708 const Handle(Adaptor3d_TopolTool)& dom2,
709 const Standard_Real theToler)
711 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
712 Standard_Boolean ok, bPCurvesOk;
713 Standard_Integer i, j, aNbParts;
714 Standard_Real fprm, lprm;
716 Handle(IntPatch_Line) L;
718 Handle(Geom_Curve) newc;
720 const Standard_Real TOLCHECK = 1.e-7;
721 const Standard_Real TOLANGCHECK = 1.e-6;
723 rejectSurface = Standard_False;
724 reApprox = Standard_False;
726 bPCurvesOk = Standard_True;
731 bAvoidLineConstructor = Standard_False;
732 L = myIntersector.Line(Index);
735 if(typl==IntPatch_Walking) {
736 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
737 if(aWLine.IsNull()) {
742 Standard_Integer nbp = aWLine->NbPnts();
743 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
744 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
746 const gp_Pnt& P1 = p1.Value();
747 const gp_Pnt& P2 = p2.Value();
749 if(P1.SquareDistance(P2) < 1.e-14) {
750 bAvoidLineConstructor = Standard_False;
756 if(typl == IntPatch_Restriction)
757 bAvoidLineConstructor = Standard_True;
761 if(!bAvoidLineConstructor) {
762 myLConstruct.Perform(L);
764 bDone=myLConstruct.IsDone();
770 if(typl != IntPatch_Restriction)
772 aNbParts=myLConstruct.NbParts();
783 //########################################
784 // Line, Parabola, Hyperbola
785 //########################################
787 case IntPatch_Parabola:
788 case IntPatch_Hyperbola: {
789 if (typl == IntPatch_Lin) {
791 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
794 else if (typl == IntPatch_Parabola) {
796 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
799 else if (typl == IntPatch_Hyperbola) {
801 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
804 aNbParts=myLConstruct.NbParts();
805 for (i=1; i<=aNbParts; i++) {
806 Standard_Boolean bFNIt, bLPIt;
808 myLConstruct.Part(i, fprm, lprm);
810 bFNIt=Precision::IsNegativeInfinite(fprm);
811 bLPIt=Precision::IsPositiveInfinite(lprm);
813 if (!bFNIt && !bLPIt) {
815 IntTools_Curve aCurve;
817 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
818 aCurve.SetCurve(aCT3D);
819 if (typl == IntPatch_Parabola) {
820 Standard_Real aTolC = IntTools_Tools::CurveTolerance(aCT3D, myTol);
821 aCurve.SetTolerance(aTolC);
824 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
826 Handle (Geom2d_Curve) C2d;
827 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
828 myHS1->ChangeSurface().Surface(), newc, C2d);
829 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
833 Handle (Geom2d_Curve) C2d;
834 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
835 myHS2->ChangeSurface().Surface(), newc, C2d);
836 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
839 mySeqOfCurve.Append(aCurve);
840 } //if (!bFNIt && !bLPIt) {
842 // on regarde si on garde
844 Standard_Real aTestPrm, dT=100.;
847 if (bFNIt && !bLPIt) {
850 else if (!bFNIt && bLPIt) {
854 // i.e, if (bFNIt && bLPIt)
855 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
858 gp_Pnt ptref(newc->Value(aTestPrm));
860 GeomAbs_SurfaceType typS1 = myHS1->GetType();
861 GeomAbs_SurfaceType typS2 = myHS2->GetType();
862 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
863 typS1 == GeomAbs_OffsetSurface ||
864 typS1 == GeomAbs_SurfaceOfRevolution ||
865 typS2 == GeomAbs_SurfaceOfExtrusion ||
866 typS2 == GeomAbs_OffsetSurface ||
867 typS2 == GeomAbs_SurfaceOfRevolution) {
868 Handle(Geom2d_BSplineCurve) H1;
869 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
873 Standard_Real u1, v1, u2, v2, Tol;
875 Tol = Precision::Confusion();
876 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
877 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
879 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
882 Handle(Geom2d_BSplineCurve) H1;
883 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
886 }// for (i=1; i<=aNbParts; i++) {
887 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
890 //########################################
891 // Circle and Ellipse
892 //########################################
893 case IntPatch_Circle:
894 case IntPatch_Ellipse: {
896 if (typl == IntPatch_Circle) {
897 newc = new Geom_Circle
898 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
900 else { //IntPatch_Ellipse
901 newc = new Geom_Ellipse
902 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
905 aNbParts=myLConstruct.NbParts();
907 Standard_Real aPeriod, aNul;
908 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
913 for (i=1; i<=aNbParts; i++) {
914 myLConstruct.Part(i, fprm, lprm);
916 if (fprm < aNul && lprm > aNul) {
917 // interval that goes through 0. is divided on two intervals;
918 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
919 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
921 if((aPeriod - fprm) > Tolpc) {
922 aSeqFprm.Append(fprm);
923 aSeqLprm.Append(aPeriod);
926 gp_Pnt P1 = newc->Value(fprm);
927 gp_Pnt P2 = newc->Value(aPeriod);
929 if(P1.Distance(P2) > myTol) {
930 Standard_Real anewpar = fprm;
932 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
933 lprm, Standard_False, myTol, anewpar, myContext)) {
936 aSeqFprm.Append(fprm);
937 aSeqLprm.Append(aPeriod);
942 if((lprm - aNul) > Tolpc) {
943 aSeqFprm.Append(aNul);
944 aSeqLprm.Append(lprm);
947 gp_Pnt P1 = newc->Value(aNul);
948 gp_Pnt P2 = newc->Value(lprm);
950 if(P1.Distance(P2) > myTol) {
951 Standard_Real anewpar = lprm;
953 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
954 fprm, Standard_True, myTol, anewpar, myContext)) {
957 aSeqFprm.Append(aNul);
958 aSeqLprm.Append(lprm);
964 aSeqFprm.Append(fprm);
965 aSeqLprm.Append(lprm);
969 aNbParts=aSeqFprm.Length();
970 for (i=1; i<=aNbParts; i++) {
974 Standard_Real aRealEpsilon=RealEpsilon();
975 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
976 //==============================================
978 IntTools_Curve aCurve;
979 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
980 aCurve.SetCurve(aTC3D);
981 fprm=aTC3D->FirstParameter();
982 lprm=aTC3D->LastParameter ();
984 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
986 Handle (Geom2d_Curve) C2d;
987 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
988 myHS1->ChangeSurface().Surface(), newc, C2d);
989 aCurve.SetFirstCurve2d(C2d);
993 Handle (Geom2d_Curve) C2d;
994 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
995 myHS2->ChangeSurface().Surface(),newc,C2d);
996 aCurve.SetSecondCurve2d(C2d);
1000 mySeqOfCurve.Append(aCurve);
1001 //==============================================
1002 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
1005 // on regarde si on garde
1008 // if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1009 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1010 IntTools_Curve aCurve;
1011 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1012 aCurve.SetCurve(aTC3D);
1013 fprm=aTC3D->FirstParameter();
1014 lprm=aTC3D->LastParameter ();
1017 Handle (Geom2d_Curve) C2d;
1018 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1019 myHS1->ChangeSurface().Surface(),newc,C2d);
1020 aCurve.SetFirstCurve2d(C2d);
1024 Handle (Geom2d_Curve) C2d;
1025 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1026 myHS2->ChangeSurface().Surface(),newc,C2d);
1027 aCurve.SetSecondCurve2d(C2d);
1030 mySeqOfCurve.Append(aCurve);
1035 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1037 aTwoPIdiv17=2.*M_PI/17.;
1039 for (j=0; j<=17; j++) {
1040 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1041 Tol = Precision::Confusion();
1043 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1044 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1046 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1049 IntTools_Curve aCurve;
1050 aCurve.SetCurve(newc);
1051 //==============================================
1052 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1055 Handle (Geom2d_Curve) C2d;
1056 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1057 myHS1->ChangeSurface().Surface(), newc, C2d);
1058 aCurve.SetFirstCurve2d(C2d);
1062 Handle (Geom2d_Curve) C2d;
1063 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1064 myHS2->ChangeSurface().Surface(), newc, C2d);
1065 aCurve.SetSecondCurve2d(C2d);
1067 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1068 //==============================================
1070 mySeqOfCurve.Append(aCurve);
1073 }// end of if (ok) {
1074 }// end of for (Standard_Integer j=0; j<=17; j++)
1075 }// end of else { on regarde si on garde
1076 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1077 }// IntPatch_Circle: IntPatch_Ellipse:
1080 case IntPatch_Analytic:
1081 //This case was processed earlier (in IntPatch_Intersection)
1084 case IntPatch_Walking:{
1085 Handle(IntPatch_WLine) WL =
1086 Handle(IntPatch_WLine)::DownCast(L);
1088 #ifdef INTTOOLS_FACEFACE_DEBUG
1093 Standard_Integer ifprm, ilprm;
1097 if(!bAvoidLineConstructor){
1098 aNbParts=myLConstruct.NbParts();
1100 for (i=1; i<=aNbParts; ++i) {
1101 Handle(Geom2d_BSplineCurve) H1, H2;
1102 Handle(Geom_Curve) aBSp;
1104 if(bAvoidLineConstructor) {
1106 ilprm = WL->NbPnts();
1109 myLConstruct.Part(i, fprm, lprm);
1110 ifprm=(Standard_Integer)fprm;
1111 ilprm=(Standard_Integer)lprm;
1115 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1119 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1122 aBSp=GeomInt_IntSS::MakeBSpline(WL, ifprm, ilprm);
1123 IntTools_Curve aIC(aBSp, H1, H2);
1124 mySeqOfCurve.Append(aIC);
1125 }// for (i=1; i<=aNbParts; ++i) {
1126 }// if (!myApprox) {
1129 Standard_Boolean bIsDecomposited;
1130 Standard_Integer nbiter, aNbSeqOfL;
1131 Standard_Real tol2d, aTolApproxImp;
1132 IntPatch_SequenceOfLine aSeqOfL;
1133 GeomInt_WLApprox theapp3d;
1134 Approx_ParametrizationType aParType = Approx_ChordLength;
1136 Standard_Boolean anApprox1 = myApprox1;
1137 Standard_Boolean anApprox2 = myApprox2;
1139 aTolApproxImp=1.e-5;
1140 tol2d = myTolApprox;
1142 GeomAbs_SurfaceType typs1, typs2;
1143 typs1 = myHS1->Surface().GetType();
1144 typs2 = myHS2->Surface().GetType();
1145 Standard_Boolean anWithPC = Standard_True;
1147 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
1149 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
1151 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
1153 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
1157 myTolApprox = aTolApproxImp;//1.e-5;
1158 anApprox1 = Standard_False;
1159 anApprox2 = Standard_False;
1161 tol2d = myTolApprox;
1164 if(myHS1 == myHS2) {
1165 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1166 rejectSurface = Standard_True;
1169 if(reApprox && !rejectSurface)
1170 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1172 Standard_Integer iDegMax, iDegMin, iNbIter;
1174 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1175 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax,
1176 iNbIter, 30, Standard_True, aParType);
1180 Standard_Real aReachedTol = Precision::Confusion();
1181 bIsDecomposited = IntTools_WLineTool::
1182 DecompositionOfWLine(WL,
1188 bAvoidLineConstructor,
1194 aNbSeqOfL=aSeqOfL.Length();
1196 Standard_Real aTolC = 0.;
1197 if (bIsDecomposited) {
1199 aTolC = aReachedTol;
1204 if (!bAvoidLineConstructor) {
1205 aNbParts=myLConstruct.NbParts();
1210 for(i = 1; i <= nbiter; ++i) {
1211 if(bIsDecomposited) {
1212 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1214 ilprm = WL->NbPnts();
1217 if(bAvoidLineConstructor) {
1219 ilprm = WL->NbPnts();
1222 myLConstruct.Part(i, fprm, lprm);
1223 ifprm = (Standard_Integer)fprm;
1224 ilprm = (Standard_Integer)lprm;
1228 //-- Si une des surfaces est un plan , on approxime en 2d
1229 //-- sur cette surface et on remonte les points 2d en 3d.
1230 if(typs1 == GeomAbs_Plane) {
1231 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1233 else if(typs2 == GeomAbs_Plane) {
1234 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1238 if (myHS1 != myHS2){
1239 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1240 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1242 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1243 Standard_True, aParType);
1245 Standard_Boolean bUseSurfaces;
1246 bUseSurfaces = IntTools_WLineTool::NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1249 rejectSurface = Standard_True;
1251 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1252 Standard_False, aParType);
1257 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1260 if (!theapp3d.IsDone()) {
1261 Handle(Geom2d_BSplineCurve) H1;
1262 Handle(Geom2d_BSplineCurve) H2;
1264 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1267 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1271 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1274 IntTools_Curve aIC(aBSp, H1, H2);
1275 mySeqOfCurve.Append(aIC);
1278 if (typs1 == GeomAbs_Plane || typs2 == GeomAbs_Plane) {
1280 if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1281 if (aTolC < 1.e-6) {
1287 Standard_Integer aNbMultiCurves, nbpoles;
1288 aNbMultiCurves=theapp3d.NbMultiCurves();
1289 for (j=1; j<=aNbMultiCurves; j++) {
1290 if(typs1 == GeomAbs_Plane) {
1291 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1292 nbpoles = mbspc.NbPoles();
1294 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1295 TColgp_Array1OfPnt tpoles(1,nbpoles);
1297 mbspc.Curve(1,tpoles2d);
1298 const gp_Pln& Pln = myHS1->Surface().Plane();
1300 Standard_Integer ik;
1301 for(ik = 1; ik<= nbpoles; ik++) {
1303 ElSLib::Value(tpoles2d.Value(ik).X(),
1304 tpoles2d.Value(ik).Y(),
1308 Handle(Geom_BSplineCurve) BS =
1309 new Geom_BSplineCurve(tpoles,
1311 mbspc.Multiplicities(),
1313 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1314 Check.FixTangent(Standard_True, Standard_True);
1316 IntTools_Curve aCurve;
1317 aCurve.SetCurve(BS);
1320 Handle(Geom2d_BSplineCurve) BS1 =
1321 new Geom2d_BSplineCurve(tpoles2d,
1323 mbspc.Multiplicities(),
1325 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1326 Check1.FixTangent(Standard_True,Standard_True);
1328 // ############################################
1329 if(!rejectSurface && !reApprox) {
1330 Standard_Boolean isValid = IsCurveValid(BS1);
1332 reApprox = Standard_True;
1336 // ############################################
1337 aCurve.SetFirstCurve2d(BS1);
1341 mbspc.Curve(2, tpoles2d);
1343 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1345 mbspc.Multiplicities(),
1347 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1348 newCheck.FixTangent(Standard_True,Standard_True);
1350 // ###########################################
1351 if(!rejectSurface && !reApprox) {
1352 Standard_Boolean isValid = IsCurveValid(BS2);
1354 reApprox = Standard_True;
1358 // ###########################################
1360 aCurve.SetSecondCurve2d(BS2);
1363 aCurve.SetTolerance(aTolC);
1365 mySeqOfCurve.Append(aCurve);
1367 }//if(typs1 == GeomAbs_Plane) {
1369 else if(typs2 == GeomAbs_Plane)
1371 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1372 nbpoles = mbspc.NbPoles();
1374 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1375 TColgp_Array1OfPnt tpoles(1,nbpoles);
1376 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1377 const gp_Pln& Pln = myHS2->Surface().Plane();
1379 Standard_Integer ik;
1380 for(ik = 1; ik<= nbpoles; ik++) {
1382 ElSLib::Value(tpoles2d.Value(ik).X(),
1383 tpoles2d.Value(ik).Y(),
1388 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1390 mbspc.Multiplicities(),
1392 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1393 Check.FixTangent(Standard_True,Standard_True);
1395 IntTools_Curve aCurve;
1396 aCurve.SetCurve(BS);
1397 aCurve.SetTolerance(aTolC);
1400 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1402 mbspc.Multiplicities(),
1404 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1405 Check1.FixTangent(Standard_True,Standard_True);
1407 // ###########################################
1408 if(!rejectSurface && !reApprox) {
1409 Standard_Boolean isValid = IsCurveValid(BS1);
1411 reApprox = Standard_True;
1415 // ###########################################
1416 bPCurvesOk = CheckPCurve(BS1, myFace2, myContext);
1417 aCurve.SetSecondCurve2d(BS1);
1421 mbspc.Curve(1,tpoles2d);
1422 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1424 mbspc.Multiplicities(),
1426 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
1427 Check2.FixTangent(Standard_True,Standard_True);
1429 // ###########################################
1430 if(!rejectSurface && !reApprox) {
1431 Standard_Boolean isValid = IsCurveValid(BS2);
1433 reApprox = Standard_True;
1437 // ###########################################
1438 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1, myContext);
1439 aCurve.SetFirstCurve2d(BS2);
1442 //if points of the pcurves are out of the faces bounds
1443 //create 3d and 2d curves without approximation
1445 Handle(Geom2d_BSplineCurve) H1, H2;
1446 bPCurvesOk = Standard_True;
1448 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1451 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1452 bPCurvesOk = CheckPCurve(H1, myFace1, myContext);
1456 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1457 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2, myContext);
1460 //if pcurves created without approximation are out of the
1461 //faces bounds, use approximated 3d and 2d curves
1463 IntTools_Curve aIC(aBSp, H1, H2, aTolC);
1464 mySeqOfCurve.Append(aIC);
1466 mySeqOfCurve.Append(aCurve);
1469 mySeqOfCurve.Append(aCurve);
1472 }// else if(typs2 == GeomAbs_Plane)
1474 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
1475 Standard_Boolean bIsValid1, bIsValid2;
1476 Handle(Geom_BSplineCurve) BS;
1477 IntTools_Curve aCurve;
1479 bIsValid1=Standard_True;
1480 bIsValid2=Standard_True;
1482 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1483 nbpoles = mbspc.NbPoles();
1484 TColgp_Array1OfPnt tpoles(1,nbpoles);
1485 mbspc.Curve(1,tpoles);
1486 BS=new Geom_BSplineCurve(tpoles,
1488 mbspc.Multiplicities(),
1490 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1491 Check.FixTangent(Standard_True,Standard_True);
1493 aCurve.SetCurve(BS);
1494 aCurve.SetTolerance(aTolC);
1498 Handle(Geom2d_BSplineCurve) BS1;
1499 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1500 mbspc.Curve(2,tpoles2d);
1502 BS1=new Geom2d_BSplineCurve(tpoles2d,
1504 mbspc.Multiplicities(),
1506 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
1507 newCheck.FixTangent(Standard_True,Standard_True);
1510 bIsValid1=CheckPCurve(BS1, myFace1, myContext);
1513 aCurve.SetFirstCurve2d(BS1);
1516 Handle(Geom2d_BSplineCurve) BS1;
1517 fprm = BS->FirstParameter();
1518 lprm = BS->LastParameter();
1520 Handle(Geom2d_Curve) C2d;
1521 Standard_Real aTol = myTolApprox;
1522 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1523 myHS1->ChangeSurface().Surface(), BS, C2d);
1524 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1525 aCurve.SetFirstCurve2d(BS1);
1527 } // if(myApprox1) {
1531 Handle(Geom2d_BSplineCurve) BS2;
1532 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1533 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
1534 BS2=new Geom2d_BSplineCurve(tpoles2d,
1536 mbspc.Multiplicities(),
1538 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1539 newCheck.FixTangent(Standard_True,Standard_True);
1542 bIsValid2=CheckPCurve(BS2, myFace2, myContext);
1544 aCurve.SetSecondCurve2d(BS2);
1547 Handle(Geom2d_BSplineCurve) BS2;
1548 fprm = BS->FirstParameter();
1549 lprm = BS->LastParameter();
1551 Handle(Geom2d_Curve) C2d;
1552 Standard_Real aTol = myTolApprox;
1553 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1554 myHS2->ChangeSurface().Surface(), BS, C2d);
1555 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1556 aCurve.SetSecondCurve2d(BS2);
1559 if (!bIsValid1 || !bIsValid2) {
1560 myTolApprox=aTolApproxImp;//1.e-5;
1561 tol2d = myTolApprox;
1562 reApprox = Standard_True;
1566 mySeqOfCurve.Append(aCurve);
1572 }// case IntPatch_Walking:{
1575 case IntPatch_Restriction:
1577 Handle(IntPatch_RLine) RL =
1578 Handle(IntPatch_RLine)::DownCast(L);
1580 #ifdef INTTOOLS_FACEFACE_DEBUG
1584 Handle(Geom_Curve) aC3d;
1585 Handle(Geom2d_Curve) aC2d1, aC2d2;
1586 Standard_Real aTolReached;
1587 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
1588 aC2d1, aC2d2, aTolReached);
1593 Bnd_Box2d aBox1, aBox2;
1595 const Standard_Real aU1f = myHS1->FirstUParameter(),
1596 aV1f = myHS1->FirstVParameter(),
1597 aU1l = myHS1->LastUParameter(),
1598 aV1l = myHS1->LastVParameter();
1599 const Standard_Real aU2f = myHS2->FirstUParameter(),
1600 aV2f = myHS2->FirstVParameter(),
1601 aU2l = myHS2->LastUParameter(),
1602 aV2l = myHS2->LastVParameter();
1604 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1605 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1606 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1607 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1609 GeomInt_VectorOfReal anArrayOfParameters;
1611 //We consider here that the intersection line is same-parameter-line
1612 anArrayOfParameters.Append(aC3d->FirstParameter());
1613 anArrayOfParameters.Append(aC3d->LastParameter());
1616 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1618 //Intersect with true boundaries. After that, enlarge bounding-boxes in order to
1619 //correct definition, if point on curve is inscribed in the box.
1620 aBox1.Enlarge(theToler);
1621 aBox2.Enlarge(theToler);
1623 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1626 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1628 Standard_Real &aParF = anArrayOfParameters(anInd),
1629 &aParL = anArrayOfParameters(anInd+1);
1631 if((aParL - aParF) <= Precision::PConfusion())
1633 //In order to more precise extending to the boundaries of source curves.
1634 if(anInd < aNbIntersSolutionsm1-1)
1640 const Standard_Real aPar = 0.5*(aParF + aParL);
1643 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1646 aC2d1->D0(aPar, aPt);
1648 if(aBox1.IsOut(aPt))
1652 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1657 aC2d2->D0(aPar, aPt);
1659 if(aBox2.IsOut(aPt))
1663 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1666 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1668 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
1669 mySeqOfCurve.Append(aIC);
1679 //=======================================================================
1680 //function : Parameters
1682 //=======================================================================
1683 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
1684 const Handle(GeomAdaptor_HSurface)& HS2,
1685 const gp_Pnt& Ptref,
1692 IntSurf_Quadric quad1,quad2;
1693 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
1697 quad1.SetValue(HS1->Surface().Plane());
1699 case GeomAbs_Cylinder:
1700 quad1.SetValue(HS1->Surface().Cylinder());
1703 quad1.SetValue(HS1->Surface().Cone());
1705 case GeomAbs_Sphere:
1706 quad1.SetValue(HS1->Surface().Sphere());
1709 quad1.SetValue(HS1->Surface().Torus());
1712 throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
1715 typs = HS2->Surface().GetType();
1718 quad2.SetValue(HS2->Surface().Plane());
1720 case GeomAbs_Cylinder:
1721 quad2.SetValue(HS2->Surface().Cylinder());
1724 quad2.SetValue(HS2->Surface().Cone());
1726 case GeomAbs_Sphere:
1727 quad2.SetValue(HS2->Surface().Sphere());
1730 quad2.SetValue(HS2->Surface().Torus());
1733 throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
1736 quad1.Parameters(Ptref,U1,V1);
1737 quad2.Parameters(Ptref,U2,V2);
1740 //=======================================================================
1741 //function : MakeBSpline
1743 //=======================================================================
1744 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
1745 const Standard_Integer ideb,
1746 const Standard_Integer ifin)
1748 Standard_Integer i,nbpnt = ifin-ideb+1;
1749 TColgp_Array1OfPnt poles(1,nbpnt);
1750 TColStd_Array1OfReal knots(1,nbpnt);
1751 TColStd_Array1OfInteger mults(1,nbpnt);
1752 Standard_Integer ipidebm1;
1753 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
1754 poles(i) = WL->Point(ipidebm1).Value();
1758 mults(1) = mults(nbpnt) = 2;
1760 new Geom_BSplineCurve(poles,knots,mults,1);
1763 //=======================================================================
1764 //function : PrepareLines3D
1766 //=======================================================================
1767 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
1769 Standard_Integer i, aNbCurves;
1770 GeomAbs_SurfaceType aType1, aType2;
1771 IntTools_SequenceOfCurves aNewCvs;
1773 // 1. Treatment closed curves
1774 aNbCurves=mySeqOfCurve.Length();
1775 for (i=1; i<=aNbCurves; ++i) {
1776 const IntTools_Curve& aIC=mySeqOfCurve(i);
1779 Standard_Integer j, aNbC;
1780 IntTools_SequenceOfCurves aSeqCvs;
1782 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
1784 for (j=1; j<=aNbC; ++j) {
1785 const IntTools_Curve& aICNew=aSeqCvs(j);
1786 aNewCvs.Append(aICNew);
1790 aNewCvs.Append(aIC);
1794 aNewCvs.Append(aIC);
1798 // 2. Plane\Cone intersection when we had 4 curves
1799 aType1=myHS1->GetType();
1800 aType2=myHS2->GetType();
1801 aNbCurves=aNewCvs.Length();
1803 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
1804 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
1806 GeomAbs_CurveType aCType1;
1808 aCType1=aNewCvs(1).Type();
1809 if (aCType1==GeomAbs_Line) {
1810 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
1812 for (i=1; i<=aNbCurves; ++i) {
1813 const IntTools_Curve& aIC=aNewCvs(i);
1817 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
1820 aNbCurves=aSeqOut.Length();
1821 for (i=1; i<=aNbCurves; ++i) {
1822 const IntTools_Curve& aIC=aSeqOut(i);
1823 aNewCvs.Append(aIC);
1827 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
1829 // 3. Fill mySeqOfCurve
1830 mySeqOfCurve.Clear();
1831 aNbCurves=aNewCvs.Length();
1832 for (i=1; i<=aNbCurves; ++i) {
1833 const IntTools_Curve& aIC=aNewCvs(i);
1834 mySeqOfCurve.Append(aIC);
1837 //=======================================================================
1838 //function : CorrectSurfaceBoundaries
1840 //=======================================================================
1841 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
1842 const Standard_Real theTolerance,
1843 Standard_Real& theumin,
1844 Standard_Real& theumax,
1845 Standard_Real& thevmin,
1846 Standard_Real& thevmax)
1848 Standard_Boolean enlarge, isuperiodic, isvperiodic;
1849 Standard_Real uinf, usup, vinf, vsup, delta;
1850 GeomAbs_SurfaceType aType;
1851 Handle(Geom_Surface) aSurface;
1853 aSurface = BRep_Tool::Surface(theFace);
1854 aSurface->Bounds(uinf, usup, vinf, vsup);
1855 delta = theTolerance;
1856 enlarge = Standard_False;
1858 GeomAdaptor_Surface anAdaptorSurface(aSurface);
1860 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1861 Handle(Geom_Surface) aBasisSurface =
1862 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
1864 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
1865 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1870 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1871 Handle(Geom_Surface) aBasisSurface =
1872 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
1874 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
1875 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1880 isuperiodic = anAdaptorSurface.IsUPeriodic();
1881 isvperiodic = anAdaptorSurface.IsVPeriodic();
1883 aType=anAdaptorSurface.GetType();
1884 if((aType==GeomAbs_BezierSurface) ||
1885 (aType==GeomAbs_BSplineSurface) ||
1886 (aType==GeomAbs_SurfaceOfExtrusion) ||
1887 (aType==GeomAbs_SurfaceOfRevolution) ||
1888 (aType==GeomAbs_Cylinder)) {
1889 enlarge=Standard_True;
1892 if(!isuperiodic && enlarge) {
1894 if(!Precision::IsInfinite(theumin) &&
1895 ((theumin - uinf) > delta))
1901 if(!Precision::IsInfinite(theumax) &&
1902 ((usup - theumax) > delta))
1908 if(!isvperiodic && enlarge) {
1909 if(!Precision::IsInfinite(thevmin) &&
1910 ((thevmin - vinf) > delta)) {
1916 if(!Precision::IsInfinite(thevmax) &&
1917 ((vsup - thevmax) > delta)) {
1925 if(isuperiodic || isvperiodic) {
1926 Standard_Boolean correct = Standard_False;
1927 Standard_Boolean correctU = Standard_False;
1928 Standard_Boolean correctV = Standard_False;
1930 TopExp_Explorer anExp;
1932 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1933 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
1934 correct = Standard_True;
1936 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1938 for(Standard_Integer i = 0; i < 2; i++) {
1940 anEdge.Orientation(TopAbs_FORWARD);
1943 anEdge.Orientation(TopAbs_REVERSED);
1945 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
1947 if(aCurve.IsNull()) {
1948 correct = Standard_False;
1951 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
1953 if(aLine.IsNull()) {
1954 correct = Standard_False;
1957 gp_Dir2d anUDir(1., 0.);
1958 gp_Dir2d aVDir(0., 1.);
1959 Standard_Real anAngularTolerance = Precision::Angular();
1961 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
1962 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
1964 gp_Pnt2d pp1 = aCurve->Value(f);
1966 gp_Pnt2d pp2 = aCurve->Value(l);
1975 Standard_Real umin, vmin, umax, vmax;
1976 aBox.Get(umin, vmin, umax, vmax);
1978 if(isuperiodic && correctU) {
1981 if(theumax > umax) {
1985 if(isvperiodic && correctV) {
1995 // ------------------------------------------------------------------------------------------------
1996 // static function: ParameterOutOfBoundary
1997 // purpose: Computes a new parameter for given curve. The corresponding 2d points
1998 // does not lay on any boundary of given faces
1999 // ------------------------------------------------------------------------------------------------
2000 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
2001 const Handle(Geom_Curve)& theCurve,
2002 const TopoDS_Face& theFace1,
2003 const TopoDS_Face& theFace2,
2004 const Standard_Real theOtherParameter,
2005 const Standard_Boolean bIncreasePar,
2006 const Standard_Real theTol,
2007 Standard_Real& theNewParameter,
2008 const Handle(IntTools_Context)& aContext)
2010 Standard_Boolean bIsComputed = Standard_False;
2011 theNewParameter = theParameter;
2013 Standard_Real acurpar = theParameter;
2014 TopAbs_State aState = TopAbs_ON;
2015 Standard_Integer iter = 0;
2016 Standard_Real asumtol = theTol;
2017 Standard_Real adelta = asumtol * 0.1;
2018 adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
2019 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
2020 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
2022 Standard_Real u1, u2, v1, v2;
2024 GeomAPI_ProjectPointOnSurf aPrj1;
2025 aSurf1->Bounds(u1, u2, v1, v2);
2026 aPrj1.Init(aSurf1, u1, u2, v1, v2);
2028 GeomAPI_ProjectPointOnSurf aPrj2;
2029 aSurf2->Bounds(u1, u2, v1, v2);
2030 aPrj2.Init(aSurf2, u1, u2, v1, v2);
2032 while(aState == TopAbs_ON) {
2037 gp_Pnt aPCurrent = theCurve->Value(acurpar);
2038 aPrj1.Perform(aPCurrent);
2039 Standard_Real U=0., V=0.;
2041 if(aPrj1.IsDone()) {
2042 aPrj1.LowerDistanceParameters(U, V);
2043 aState = aContext->StatePointFace(theFace1, gp_Pnt2d(U, V));
2046 if(aState != TopAbs_ON) {
2047 aPrj2.Perform(aPCurrent);
2049 if(aPrj2.IsDone()) {
2050 aPrj2.LowerDistanceParameters(U, V);
2051 aState = aContext->StatePointFace(theFace2, gp_Pnt2d(U, V));
2062 theNewParameter = acurpar;
2063 bIsComputed = Standard_True;
2066 if(acurpar >= theOtherParameter)
2067 theNewParameter = theOtherParameter;
2070 if(acurpar <= theOtherParameter)
2071 theNewParameter = theOtherParameter;
2077 //=======================================================================
2078 //function : IsCurveValid
2080 //=======================================================================
2081 Standard_Boolean IsCurveValid (const Handle(Geom2d_Curve)& thePCurve)
2083 if(thePCurve.IsNull())
2084 return Standard_False;
2086 Standard_Real tolint = 1.e-10;
2087 Geom2dAdaptor_Curve PCA;
2088 IntRes2d_Domain PCD;
2089 Geom2dInt_GInter PCI;
2091 Standard_Real pf = 0., pl = 0.;
2092 gp_Pnt2d pntf, pntl;
2094 if(!thePCurve->IsClosed() && !thePCurve->IsPeriodic()) {
2095 pf = thePCurve->FirstParameter();
2096 pl = thePCurve->LastParameter();
2097 pntf = thePCurve->Value(pf);
2098 pntl = thePCurve->Value(pl);
2099 PCA.Load(thePCurve);
2100 if(!PCA.IsPeriodic()) {
2101 if(PCA.FirstParameter() > pf) pf = PCA.FirstParameter();
2102 if(PCA.LastParameter() < pl) pl = PCA.LastParameter();
2104 PCD.SetValues(pntf,pf,tolint,pntl,pl,tolint);
2105 PCI.Perform(PCA,PCD,tolint,tolint);
2107 if(PCI.NbPoints() > 0) {
2108 return Standard_False;
2112 return Standard_True;
2115 //=======================================================================
2116 //static function : ApproxWithPCurves
2117 //purpose : for bug 20964 only
2118 //=======================================================================
2119 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
2120 const gp_Sphere& theSph)
2122 Standard_Boolean bRes = Standard_True;
2123 Standard_Real R1 = theCyl.Radius(), R2 = theSph.Radius();
2126 Standard_Real aD2, aRc2, aEps;
2132 const gp_Ax3& aAx3Sph=theSph.Position();
2133 const gp_Pnt& aLocSph=aAx3Sph.Location();
2134 const gp_Dir& aDirSph=aAx3Sph.Direction();
2136 const gp_Ax1& aAx1Cyl=theCyl.Axis();
2137 gp_Lin aLinCyl(aAx1Cyl);
2139 aApexSph.SetXYZ(aLocSph.XYZ()+R2*aDirSph.XYZ());
2140 aD2=aLinCyl.SquareDistance(aApexSph);
2141 if (fabs(aD2-aRc2)<aEps) {
2145 aApexSph.SetXYZ(aLocSph.XYZ()-R2*aDirSph.XYZ());
2146 aD2=aLinCyl.SquareDistance(aApexSph);
2147 if (fabs(aD2-aRc2)<aEps) {
2156 gp_Lin anCylAx(theCyl.Axis());
2158 Standard_Real aDist = anCylAx.Distance(theSph.Location());
2159 Standard_Real aDRel = Abs(aDist - R1)/R2;
2161 if(aDRel > .2) return bRes;
2163 Standard_Real par = ElCLib::Parameter(anCylAx, theSph.Location());
2164 gp_Pnt aP = ElCLib::Value(par, anCylAx);
2165 gp_Vec aV(aP, theSph.Location());
2167 Standard_Real dd = aV.Dot(theSph.Position().XDirection());
2169 if(aDist < R1 && dd > 0.) return Standard_False;
2170 if(aDist > R1 && dd < 0.) return Standard_False;
2175 //=======================================================================
2176 //function : PerformPlanes
2178 //=======================================================================
2179 void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
2180 const Handle(GeomAdaptor_HSurface)& theS2,
2181 const Standard_Real TolF1,
2182 const Standard_Real TolF2,
2183 const Standard_Real TolAng,
2184 const Standard_Real TolTang,
2185 const Standard_Boolean theApprox1,
2186 const Standard_Boolean theApprox2,
2187 IntTools_SequenceOfCurves& theSeqOfCurve,
2188 Standard_Boolean& theTangentFaces)
2191 gp_Pln aPln1 = theS1->Surface().Plane();
2192 gp_Pln aPln2 = theS2->Surface().Plane();
2194 IntAna_QuadQuadGeo aPlnInter(aPln1, aPln2, TolAng, TolTang);
2196 if(!aPlnInter.IsDone()) {
2197 theTangentFaces = Standard_False;
2201 IntAna_ResultType aResType = aPlnInter.TypeInter();
2203 if(aResType == IntAna_Same) {
2204 theTangentFaces = Standard_True;
2208 theTangentFaces = Standard_False;
2210 if(aResType == IntAna_Empty) {
2214 gp_Lin aLin = aPlnInter.Line(1);
2216 ProjLib_Plane aProj;
2219 aProj.Project(aLin);
2220 gp_Lin2d aLin2d1 = aProj.Line();
2223 aProj.Project(aLin);
2224 gp_Lin2d aLin2d2 = aProj.Line();
2226 //classify line2d1 relatively first plane
2227 Standard_Real P11, P12;
2228 Standard_Boolean IsCrossed = ClassifyLin2d(theS1, aLin2d1, TolTang, P11, P12);
2229 if(!IsCrossed) return;
2230 //classify line2d2 relatively second plane
2231 Standard_Real P21, P22;
2232 IsCrossed = ClassifyLin2d(theS2, aLin2d2, TolTang, P21, P22);
2233 if(!IsCrossed) return;
2235 //Analysis of parametric intervals: must have common part
2237 if(P21 >= P12) return;
2238 if(P22 <= P11) return;
2240 Standard_Real pmin, pmax;
2241 pmin = Max(P11, P21);
2242 pmax = Min(P12, P22);
2244 if(pmax - pmin <= TolTang) return;
2246 Handle(Geom_Line) aGLin = new Geom_Line(aLin);
2248 IntTools_Curve aCurve;
2249 Handle(Geom_TrimmedCurve) aGTLin = new Geom_TrimmedCurve(aGLin, pmin, pmax);
2251 aCurve.SetCurve(aGTLin);
2254 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d1);
2255 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2258 Handle(Geom2d_Curve) H1;
2259 aCurve.SetFirstCurve2d(H1);
2262 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d2);
2263 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2266 Handle(Geom2d_Curve) H1;
2267 aCurve.SetFirstCurve2d(H1);
2270 // Valid tolerance for the intersection curve between planar faces
2271 // is the maximal tolerance between tolerances of faces
2272 Standard_Real aTolC = Max(TolF1, TolF2);
2273 aCurve.SetTolerance(aTolC);
2275 // Computation of the tangential tolerance
2276 Standard_Real anAngle, aDt;
2279 aD1 = aPln1.Position().Direction();
2280 aD2 = aPln2.Position().Direction();
2281 anAngle = aD1.Angle(aD2);
2283 aDt = IntTools_Tools::ComputeIntRange(TolF1, TolF2, anAngle);
2284 Standard_Real aTangTol = sqrt(aDt*aDt + TolF1*TolF1);
2286 aCurve.SetTangentialTolerance(aTangTol);
2288 theSeqOfCurve.Append(aCurve);
2291 //=======================================================================
2292 //function : ClassifyLin2d
2294 //=======================================================================
2295 static inline Standard_Boolean INTER(const Standard_Real d1,
2296 const Standard_Real d2,
2297 const Standard_Real tol)
2299 return (d1 > tol && d2 < -tol) ||
2300 (d1 < -tol && d2 > tol) ||
2301 ((d1 <= tol && d1 >= -tol) && (d2 > tol || d2 < -tol)) ||
2302 ((d2 <= tol && d2 >= -tol) && (d1 > tol || d1 < -tol));
2304 static inline Standard_Boolean COINC(const Standard_Real d1,
2305 const Standard_Real d2,
2306 const Standard_Real tol)
2308 return (d1 <= tol && d1 >= -tol) && (d2 <= tol && d2 >= -tol);
2310 Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
2311 const gp_Lin2d& theLin2d,
2312 const Standard_Real theTol,
2313 Standard_Real& theP1,
2314 Standard_Real& theP2)
2317 Standard_Real xmin, xmax, ymin, ymax, d1, d2, A, B, C;
2318 Standard_Real par[2];
2319 Standard_Integer nbi = 0;
2321 xmin = theS->Surface().FirstUParameter();
2322 xmax = theS->Surface().LastUParameter();
2323 ymin = theS->Surface().FirstVParameter();
2324 ymax = theS->Surface().LastVParameter();
2326 theLin2d.Coefficients(A, B, C);
2328 //xmin, ymin <-> xmin, ymax
2329 d1 = A*xmin + B*ymin + C;
2330 d2 = A*xmin + B*ymax + C;
2332 if(INTER(d1, d2, theTol)) {
2333 //Intersection with boundary
2334 Standard_Real y = -(C + A*xmin)/B;
2335 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, y));
2338 else if (COINC(d1, d2, theTol)) {
2339 //Coincidence with boundary
2340 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2341 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2347 if(fabs(par[0]-par[1]) > theTol) {
2348 theP1 = Min(par[0], par[1]);
2349 theP2 = Max(par[0], par[1]);
2350 return Standard_True;
2352 else return Standard_False;
2356 //xmin, ymax <-> xmax, ymax
2358 d2 = A*xmax + B*ymax + C;
2360 if(d1 > theTol || d1 < -theTol) {//to avoid checking of
2361 //coincidence with the same point
2362 if(INTER(d1, d2, theTol)) {
2363 Standard_Real x = -(C + B*ymax)/A;
2364 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymax));
2367 else if (COINC(d1, d2, theTol)) {
2368 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2369 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2376 if(fabs(par[0]-par[1]) > theTol) {
2377 theP1 = Min(par[0], par[1]);
2378 theP2 = Max(par[0], par[1]);
2379 return Standard_True;
2381 else return Standard_False;
2385 //xmax, ymax <-> xmax, ymin
2387 d2 = A*xmax + B*ymin + C;
2389 if(d1 > theTol || d1 < -theTol) {
2390 if(INTER(d1, d2, theTol)) {
2391 Standard_Real y = -(C + A*xmax)/B;
2392 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, y));
2395 else if (COINC(d1, d2, theTol)) {
2396 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2397 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2403 if(fabs(par[0]-par[1]) > theTol) {
2404 theP1 = Min(par[0], par[1]);
2405 theP2 = Max(par[0], par[1]);
2406 return Standard_True;
2408 else return Standard_False;
2411 //xmax, ymin <-> xmin, ymin
2413 d2 = A*xmin + B*ymin + C;
2415 if(d1 > theTol || d1 < -theTol) {
2416 if(INTER(d1, d2, theTol)) {
2417 Standard_Real x = -(C + B*ymin)/A;
2418 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymin));
2421 else if (COINC(d1, d2, theTol)) {
2422 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2423 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2429 if(fabs(par[0]-par[1]) > theTol) {
2430 theP1 = Min(par[0], par[1]);
2431 theP2 = Max(par[0], par[1]);
2432 return Standard_True;
2434 else return Standard_False;
2437 return Standard_False;
2441 //=======================================================================
2442 //function : ApproxParameters
2444 //=======================================================================
2445 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
2446 const Handle(GeomAdaptor_HSurface)& aHS2,
2447 Standard_Integer& iDegMin,
2448 Standard_Integer& iDegMax,
2449 Standard_Integer& iNbIter)
2452 GeomAbs_SurfaceType aTS1, aTS2;
2459 aTS1=aHS1->Surface().GetType();
2460 aTS2=aHS2->Surface().GetType();
2463 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2464 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2465 Standard_Real aRC, aRT, dR, aPC;
2466 gp_Cylinder aCylinder;
2469 aPC=Precision::Confusion();
2471 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2472 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
2474 aRC=aCylinder.Radius();
2475 aRT=aTorus.MinorRadius();
2485 if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
2489 //=======================================================================
2490 //function : Tolerances
2492 //=======================================================================
2493 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
2494 const Handle(GeomAdaptor_HSurface)& aHS2,
2495 Standard_Real& aTolTang)
2497 GeomAbs_SurfaceType aTS1, aTS2;
2499 aTS1=aHS1->Surface().GetType();
2500 aTS2=aHS2->Surface().GetType();
2503 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2504 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2505 Standard_Real aRC, aRT, dR, aPC;
2506 gp_Cylinder aCylinder;
2509 aPC=Precision::Confusion();
2511 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2512 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
2514 aRC=aCylinder.Radius();
2515 aRT=aTorus.MinorRadius();
2522 aTolTang=0.1*aTolTang;
2526 //=======================================================================
2527 //function : SortTypes
2529 //=======================================================================
2530 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
2531 const GeomAbs_SurfaceType aType2)
2533 Standard_Boolean bRet;
2534 Standard_Integer aI1, aI2;
2536 bRet=Standard_False;
2538 aI1=IndexType(aType1);
2539 aI2=IndexType(aType2);
2545 //=======================================================================
2546 //function : IndexType
2548 //=======================================================================
2549 Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
2551 Standard_Integer aIndex;
2555 if (aType==GeomAbs_Plane) {
2558 else if (aType==GeomAbs_Cylinder) {
2561 else if (aType==GeomAbs_Cone) {
2564 else if (aType==GeomAbs_Sphere) {
2567 else if (aType==GeomAbs_Torus) {
2570 else if (aType==GeomAbs_BezierSurface) {
2573 else if (aType==GeomAbs_BSplineSurface) {
2576 else if (aType==GeomAbs_SurfaceOfRevolution) {
2579 else if (aType==GeomAbs_SurfaceOfExtrusion) {
2582 else if (aType==GeomAbs_OffsetSurface) {
2585 else if (aType==GeomAbs_OtherSurface) {
2591 //=======================================================================
2592 // Function : FindMaxDistance
2594 //=======================================================================
2595 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
2596 const Standard_Real theFirst,
2597 const Standard_Real theLast,
2598 const TopoDS_Face& theFace,
2599 const Handle(IntTools_Context)& theContext)
2601 Standard_Integer aNbS;
2602 Standard_Real aT1, aT2, aDt, aD, aDMax, anEps;
2605 aDt = (theLast - theFirst) / aNbS;
2607 anEps = 1.e-4 * aDt;
2609 GeomAPI_ProjectPointOnSurf& aProjPS = theContext->ProjPS(theFace);
2615 if (aT2 > theLast) {
2619 aD = FindMaxDistance(theCurve, aT1, aT2, aProjPS, anEps);
2628 //=======================================================================
2629 // Function : FindMaxDistance
2631 //=======================================================================
2632 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
2633 const Standard_Real theFirst,
2634 const Standard_Real theLast,
2635 GeomAPI_ProjectPointOnSurf& theProjPS,
2636 const Standard_Real theEps)
2638 Standard_Real aA, aB, aCf, aX, aX1, aX2, aF1, aF2, aF;
2640 aCf = 0.61803398874989484820458683436564;//(sqrt(5.)-1)/2.;
2644 aX1=aB - aCf*(aB-aA);
2645 aF1 = MaxDistance(theC, aX1, theProjPS);
2646 aX2 = aA + aCf * (aB - aA);
2647 aF2 = MaxDistance(theC, aX2, theProjPS);
2649 while (Abs(aX1-aX2) > theEps)
2655 aX1 = aB-aCf*(aB-aA);
2656 aF1 = MaxDistance(theC, aX1, theProjPS);
2663 aF2 = MaxDistance(theC, aX2, theProjPS);
2667 aX = 0.5 * (aA + aB);
2668 aF = MaxDistance(theC, aX, theProjPS);
2681 //=======================================================================
2682 // Function : MaxDistance
2684 //=======================================================================
2685 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
2686 const Standard_Real aT,
2687 GeomAPI_ProjectPointOnSurf& theProjPS)
2693 theProjPS.Perform(aP);
2694 aD = theProjPS.NbPoints() ? theProjPS.LowerDistance() : 0.;
2699 //=======================================================================
2700 //function : CheckPCurve
2701 //purpose : Checks if points of the pcurve are out of the face bounds.
2702 //=======================================================================
2703 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
2704 const TopoDS_Face& aFace,
2705 const Handle(IntTools_Context)& theCtx)
2707 const Standard_Integer NPoints = 23;
2709 Standard_Real umin,umax,vmin,vmax;
2711 theCtx->UVBounds(aFace, umin, umax, vmin, vmax);
2712 Standard_Real tolU = Max ((umax-umin)*0.01, Precision::Confusion());
2713 Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
2714 Standard_Real fp = aPC->FirstParameter();
2715 Standard_Real lp = aPC->LastParameter();
2718 // adjust domain for periodic surfaces
2719 TopLoc_Location aLoc;
2720 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
2721 if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2722 aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
2724 gp_Pnt2d pnt = aPC->Value((fp+lp)/2);
2728 if (aSurf->IsUPeriodic()) {
2729 Standard_Real aPer = aSurf->UPeriod();
2730 Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer);
2731 if (u < umin+aPer*nshift) nshift--;
2732 umin += aPer*nshift;
2733 umax += aPer*nshift;
2735 if (aSurf->IsVPeriodic()) {
2736 Standard_Real aPer = aSurf->VPeriod();
2737 Standard_Integer nshift = (Standard_Integer) ((v-vmin)/aPer);
2738 if (v < vmin+aPer*nshift) nshift--;
2739 vmin += aPer*nshift;
2740 vmax += aPer*nshift;
2743 //--------------------------------------------------------
2744 Standard_Boolean bRet;
2745 Standard_Integer j, aNbIntervals;
2746 Standard_Real aT, dT;
2749 Geom2dAdaptor_Curve aGAC(aPC);
2750 aNbIntervals=aGAC.NbIntervals(GeomAbs_CN);
2752 TColStd_Array1OfReal aTI(1, aNbIntervals+1);
2753 aGAC.Intervals(aTI,GeomAbs_CN);
2755 bRet=Standard_False;
2757 aT=aGAC.FirstParameter();
2758 for (j=1; j<=aNbIntervals; ++j) {
2759 dT=(aTI(j+1)-aTI(j))/NPoints;
2761 for (i=1; i<NPoints; i++) {
2765 if (umin-u > tolU || u-umax > tolU ||
2766 vmin-v > tolV || v-vmax > tolV) {
2773 //=======================================================================
2774 //function : CorrectPlaneBoundaries
2776 //=======================================================================
2777 void CorrectPlaneBoundaries(Standard_Real& aUmin,
2778 Standard_Real& aUmax,
2779 Standard_Real& aVmin,
2780 Standard_Real& aVmax)
2782 if (!(Precision::IsInfinite(aUmin) ||
2783 Precision::IsInfinite(aUmax))) {
2786 dU=0.1*(aUmax-aUmin);
2790 if (!(Precision::IsInfinite(aVmin) ||
2791 Precision::IsInfinite(aVmax))) {
2794 dV=0.1*(aVmax-aVmin);