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 <Precision.hxx>
20 #include <TColStd_HArray1OfReal.hxx>
21 #include <TColStd_Array1OfReal.hxx>
22 #include <TColStd_Array1OfInteger.hxx>
23 #include <TColStd_SequenceOfReal.hxx>
24 #include <TColStd_ListOfInteger.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26 #include <TColStd_Array1OfListOfInteger.hxx>
28 #include <Bnd_Box.hxx>
30 #include <TColgp_HArray1OfPnt2d.hxx>
31 #include <TColgp_SequenceOfPnt2d.hxx>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColgp_Array1OfPnt2d.hxx>
35 #include <IntAna_QuadQuadGeo.hxx>
37 #include <IntSurf_PntOn2S.hxx>
38 #include <IntSurf_LineOn2S.hxx>
39 #include <IntSurf_PntOn2S.hxx>
40 #include <IntSurf_ListOfPntOn2S.hxx>
41 #include <IntRes2d_Domain.hxx>
42 #include <ProjLib_Plane.hxx>
44 #include <IntPatch_GLine.hxx>
45 #include <IntPatch_RLine.hxx>
46 #include <IntPatch_WLine.hxx>
47 #include <IntPatch_ALine.hxx>
48 #include <IntPatch_ALineToWLine.hxx>
53 #include <BndLib_AddSurface.hxx>
55 #include <Adaptor3d_SurfacePtr.hxx>
56 #include <Adaptor2d_HLine2d.hxx>
58 #include <GeomAbs_SurfaceType.hxx>
59 #include <GeomAbs_CurveType.hxx>
61 #include <Geom_Surface.hxx>
62 #include <Geom_Line.hxx>
63 #include <Geom_Circle.hxx>
64 #include <Geom_Ellipse.hxx>
65 #include <Geom_Parabola.hxx>
66 #include <Geom_Hyperbola.hxx>
67 #include <Geom_TrimmedCurve.hxx>
68 #include <Geom_BSplineCurve.hxx>
69 #include <Geom_RectangularTrimmedSurface.hxx>
70 #include <Geom_OffsetSurface.hxx>
71 #include <Geom_Curve.hxx>
72 #include <Geom_Conic.hxx>
74 #include <Geom2d_TrimmedCurve.hxx>
75 #include <Geom2d_BSplineCurve.hxx>
76 #include <Geom2d_Line.hxx>
77 #include <Geom2d_Curve.hxx>
79 #include <Geom2dInt_GInter.hxx>
80 #include <Geom2dAdaptor.hxx>
81 #include <GeomAdaptor_HSurface.hxx>
82 #include <GeomAdaptor_Surface.hxx>
83 #include <GeomLib_CheckBSplineCurve.hxx>
84 #include <GeomLib_Check2dBSplineCurve.hxx>
86 #include <GeomInt_WLApprox.hxx>
87 #include <GeomProjLib.hxx>
88 #include <GeomAPI_ProjectPointOnSurf.hxx>
89 #include <Geom2dAdaptor_Curve.hxx>
91 #include <TopoDS_Edge.hxx>
92 #include <TopExp_Explorer.hxx>
94 #include <BRep_Tool.hxx>
95 #include <BRepTools.hxx>
96 #include <BRepAdaptor_Surface.hxx>
98 #include <IntTools_Curve.hxx>
99 #include <IntTools_Tools.hxx>
100 #include <IntTools_Tools.hxx>
101 #include <IntTools_TopolTool.hxx>
102 #include <IntTools_PntOnFace.hxx>
103 #include <IntTools_PntOn2Faces.hxx>
104 #include <IntTools_Context.hxx>
105 #include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
107 #include <Approx_CurveOnSurface.hxx>
108 #include <GeomAdaptor.hxx>
109 #include <GeomInt_IntSS.hxx>
110 #include <IntTools_WLineTool.hxx>
111 #include <IntPatch_WLineTool.hxx>
113 //#ifdef OCCT_DEBUG_DUMPWLINE
115 // void DumpWLine(const Handle(IntPatch_WLine)& aWLine);
119 void TolR3d(const TopoDS_Face& ,
124 void Parameters(const Handle(GeomAdaptor_HSurface)&,
125 const Handle(GeomAdaptor_HSurface)&,
133 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
134 const Standard_Real theTolerance,
135 Standard_Real& theumin,
136 Standard_Real& theumax,
137 Standard_Real& thevmin,
138 Standard_Real& thevmax);
141 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
142 const Handle(Geom_Curve)& theCurve,
143 const TopoDS_Face& theFace1,
144 const TopoDS_Face& theFace2,
145 const Standard_Real theOtherParameter,
146 const Standard_Boolean bIncreasePar,
147 Standard_Real& theNewParameter,
148 const Handle(IntTools_Context)& );
151 Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve);
154 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
155 const gp_Sphere& theSph);
157 static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
158 const Handle(GeomAdaptor_HSurface)& theS2,
159 const Standard_Real TolAng,
160 const Standard_Real TolTang,
161 const Standard_Boolean theApprox1,
162 const Standard_Boolean theApprox2,
163 IntTools_SequenceOfCurves& theSeqOfCurve,
164 Standard_Boolean& theTangentFaces);
166 static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
167 const gp_Lin2d& theLin2d,
168 const Standard_Real theTol,
169 Standard_Real& theP1,
170 Standard_Real& theP2);
173 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
174 const Handle(GeomAdaptor_HSurface)& aHS2,
175 Standard_Integer& iDegMin,
176 Standard_Integer& iNbIter,
177 Standard_Integer& iDegMax);
180 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
181 const Handle(GeomAdaptor_HSurface)& aHS2,
182 Standard_Real& aTolTang);
185 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
186 const GeomAbs_SurfaceType aType2);
188 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
192 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
193 const TopoDS_Face& aFace);
196 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
197 const Standard_Real aT,
198 GeomAPI_ProjectPointOnSurf& theProjPS);
201 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
202 const Standard_Real theFirst,
203 const Standard_Real theLast,
204 GeomAPI_ProjectPointOnSurf& theProjPS,
205 const Standard_Real theEps);
208 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
209 const Standard_Real theFirst,
210 const Standard_Real theLast,
211 const TopoDS_Face& theFace,
212 const Handle(IntTools_Context)& theContext);
215 void CorrectPlaneBoundaries(Standard_Real& aUmin,
216 Standard_Real& aUmax,
217 Standard_Real& aVmin,
218 Standard_Real& aVmax);
220 //=======================================================================
223 //=======================================================================
224 IntTools_FaceFace::IntTools_FaceFace()
226 myIsDone=Standard_False;
227 myTangentFaces=Standard_False;
229 myHS1 = new GeomAdaptor_HSurface ();
230 myHS2 = new GeomAdaptor_HSurface ();
233 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
236 //=======================================================================
237 //function : SetContext
239 //=======================================================================
240 void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
244 //=======================================================================
247 //=======================================================================
248 const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
252 //=======================================================================
255 //=======================================================================
256 const TopoDS_Face& IntTools_FaceFace::Face1() const
260 //=======================================================================
263 //=======================================================================
264 const TopoDS_Face& IntTools_FaceFace::Face2() const
268 //=======================================================================
269 //function : TangentFaces
271 //=======================================================================
272 Standard_Boolean IntTools_FaceFace::TangentFaces() const
274 return myTangentFaces;
276 //=======================================================================
279 //=======================================================================
280 const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
284 //=======================================================================
287 //=======================================================================
288 Standard_Boolean IntTools_FaceFace::IsDone() const
292 //=======================================================================
293 //function : TolReached3d
295 //=======================================================================
296 Standard_Real IntTools_FaceFace::TolReached3d() const
298 return myTolReached3d;
300 //=======================================================================
302 //purpose : return lines of intersection
303 //=======================================================================
304 const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
306 StdFail_NotDone_Raise_if
308 "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
311 //=======================================================================
312 //function : TolReached2d
314 //=======================================================================
315 Standard_Real IntTools_FaceFace::TolReached2d() const
317 return myTolReached2d;
319 // =======================================================================
320 // function: SetParameters
322 // =======================================================================
323 void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
324 const Standard_Boolean ToApproxC2dOnS1,
325 const Standard_Boolean ToApproxC2dOnS2,
326 const Standard_Real ApproximationTolerance)
328 myApprox = ToApproxC3d;
329 myApprox1 = ToApproxC2dOnS1;
330 myApprox2 = ToApproxC2dOnS2;
331 myTolApprox = ApproximationTolerance;
333 //=======================================================================
336 //=======================================================================
337 void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
339 myListOfPnts = aListOfPnts;
343 static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
344 const TopoDS_Face& theF2)
346 const Standard_Real Tolang = 1.e-8;
347 const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
348 const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
349 const Standard_Real aTolSum = aTolF1 + aTolF2;
350 Standard_Real aHigh = 0.0;
352 const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
353 const GeomAbs_SurfaceType aType1=aBAS1.GetType();
354 const GeomAbs_SurfaceType aType2=aBAS2.GetType();
358 if(aType1 == GeomAbs_Plane)
362 else if(aType2 == GeomAbs_Plane)
368 return Standard_True;
371 if(aType1 == GeomAbs_Cylinder)
373 aS2=aBAS1.Cylinder();
374 const Standard_Real VMin = aBAS1.FirstVParameter();
375 const Standard_Real VMax = aBAS1.LastVParameter();
377 if( Precision::IsNegativeInfinite(VMin) ||
378 Precision::IsPositiveInfinite(VMax))
379 return Standard_True;
383 else if(aType2 == GeomAbs_Cylinder)
385 aS2=aBAS2.Cylinder();
387 const Standard_Real VMin = aBAS2.FirstVParameter();
388 const Standard_Real VMax = aBAS2.LastVParameter();
390 if( Precision::IsNegativeInfinite(VMin) ||
391 Precision::IsPositiveInfinite(VMax))
392 return Standard_True;
398 return Standard_True;
401 IntAna_QuadQuadGeo inter;
402 inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh);
403 if(inter.TypeInter() == IntAna_Ellipse)
405 const gp_Elips anEl = inter.Ellipse(1);
406 const Standard_Real aMajorR = anEl.MajorRadius();
407 const Standard_Real aMinorR = anEl.MinorRadius();
409 return (aMajorR < 100000.0 * aMinorR);
413 return inter.IsDone();
416 //=======================================================================
418 //purpose : intersect surfaces of the faces
419 //=======================================================================
420 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
421 const TopoDS_Face& aF2)
423 Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False;
425 if (myContext.IsNull()) {
426 myContext=new IntTools_Context;
429 mySeqOfCurve.Clear();
432 myIsDone = Standard_False;
438 const BRepAdaptor_Surface aBAS1(myFace1, Standard_False);
439 const BRepAdaptor_Surface aBAS2(myFace2, Standard_False);
440 GeomAbs_SurfaceType aType1=aBAS1.GetType();
441 GeomAbs_SurfaceType aType2=aBAS2.GetType();
443 const Standard_Boolean bReverse=SortTypes(aType1, aType2);
448 aType1=aBAS2.GetType();
449 aType2=aBAS1.GetType();
451 if (myListOfPnts.Extent())
453 Standard_Real aU1,aV1,aU2,aV2;
454 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
456 aItP2S.Initialize(myListOfPnts);
457 for (; aItP2S.More(); aItP2S.Next())
459 IntSurf_PntOn2S& aP2S=aItP2S.Value();
460 aP2S.Parameters(aU1,aV1,aU2,aV2);
461 aP2S.SetValue(aU2,aV2,aU1,aV1);
465 Standard_Boolean anAproxTmp = myApprox1;
466 myApprox1 = myApprox2;
467 myApprox2 = anAproxTmp;
471 const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
472 const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
474 const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
475 const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
477 Standard_Real TolArc = aTolF1 + aTolF2;
478 Standard_Real TolTang = TolArc;
480 const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
481 aType1 == GeomAbs_Cone ||
482 aType1 == GeomAbs_Torus);
484 const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
485 aType2 == GeomAbs_Cone ||
486 aType2 == GeomAbs_Torus);
488 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
489 Standard_Real umin, umax, vmin, vmax;
491 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
492 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
493 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
495 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
496 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
497 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
499 Standard_Real TolAng = 1.e-8;
501 PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
502 mySeqOfCurve, myTangentFaces);
504 myIsDone = Standard_True;
506 if(!myTangentFaces) {
507 const Standard_Integer NbLinPP = mySeqOfCurve.Length();
509 Standard_Real aTolFMax;
510 myTolReached3d = 1.e-7;
511 aTolFMax=Max(aTolF1, aTolF2);
512 if (aTolFMax>myTolReached3d) {
513 myTolReached3d=aTolFMax;
516 myTolReached2d = myTolReached3d;
519 Handle(Geom2d_Curve) aC2D1, aC2D2;
520 const Standard_Integer aNbLin = mySeqOfCurve.Length();
521 for (Standard_Integer i = 1; i <= aNbLin; ++i) {
522 IntTools_Curve& aIC=mySeqOfCurve(i);
523 aC2D1=aIC.FirstCurve2d();
524 aC2D2=aIC.SecondCurve2d();
525 aIC.SetFirstCurve2d(aC2D2);
526 aIC.SetSecondCurve2d(aC2D1);
532 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
534 if ((aType1==GeomAbs_Plane) && isFace2Quad)
536 Standard_Real umin, umax, vmin, vmax;
538 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
539 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
540 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
542 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
543 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
544 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
546 if( aType2==GeomAbs_Cone ) {
548 hasCone = Standard_True;
551 else if ((aType2==GeomAbs_Plane) && isFace1Quad)
553 Standard_Real umin, umax, vmin, vmax;
555 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
556 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
557 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
559 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
560 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
561 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
563 if( aType1==GeomAbs_Cone ) {
565 hasCone = Standard_True;
570 Standard_Real umin, umax, vmin, vmax;
571 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
572 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
573 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
574 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
575 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
576 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
579 const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
580 const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
582 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
585 Tolerances(myHS1, myHS2, TolTang);
588 const Standard_Real UVMaxStep = 0.001;
589 const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1;
590 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
593 if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
594 (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
595 (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
596 (myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
598 RestrictLine = Standard_True;
601 if((aType1 != GeomAbs_BSplineSurface) &&
602 (aType1 != GeomAbs_BezierSurface) &&
603 (aType1 != GeomAbs_OtherSurface) &&
604 (aType2 != GeomAbs_BSplineSurface) &&
605 (aType2 != GeomAbs_BezierSurface) &&
606 (aType2 != GeomAbs_OtherSurface))
608 RestrictLine = Standard_True;
610 if ((aType1 == GeomAbs_Torus) ||
611 (aType2 == GeomAbs_Torus))
613 myListOfPnts.Clear();
620 TopExp_Explorer aExp;
621 for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
623 const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
624 aExp.Init(aF, TopAbs_EDGE);
625 for(; aExp.More(); aExp.Next())
627 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
629 if(BRep_Tool::Degenerated(aE))
631 RestrictLine = Standard_True;
638 const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2);
639 myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
640 myListOfPnts, RestrictLine, isGeomInt);
642 myIsDone = myIntersector.IsDone();
646 myTangentFaces=myIntersector.TangentFaces();
647 if (myTangentFaces) {
652 myListOfPnts.Clear(); // to use LineConstructor
655 const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
656 for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
657 MakeCurve(i, dom1, dom2, TolArc);
660 ComputeTolReached3d();
663 Handle(Geom2d_Curve) aC2D1, aC2D2;
665 const Standard_Integer aNbLinSeqOfCurve =mySeqOfCurve.Length();
666 for (Standard_Integer i=1; i<=aNbLinSeqOfCurve; ++i)
668 IntTools_Curve& aIC=mySeqOfCurve(i);
669 aC2D1=aIC.FirstCurve2d();
670 aC2D2=aIC.SecondCurve2d();
671 aIC.SetFirstCurve2d(aC2D2);
672 aIC.SetSecondCurve2d(aC2D1);
677 Standard_Boolean bValid2D1, bValid2D2;
678 Standard_Real U1,V1,U2,V2;
679 IntTools_PntOnFace aPntOnF1, aPntOnF2;
680 IntTools_PntOn2Faces aPntOn2Faces;
682 const Standard_Integer aNbPnts = myIntersector.NbPnts();
683 for (Standard_Integer i=1; i <= aNbPnts; ++i)
685 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
686 const gp_Pnt& aPnt=aISPnt.Value();
687 aISPnt.Parameters(U1,V1,U2,V2);
689 // check the validity of the intersection point for the faces
690 bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
695 bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
700 // add the intersection point
701 aPntOnF1.Init(myFace1, aPnt, U1, V1);
702 aPntOnF2.Init(myFace2, aPnt, U2, V2);
706 aPntOn2Faces.SetP1(aPntOnF1);
707 aPntOn2Faces.SetP2(aPntOnF2);
711 aPntOn2Faces.SetP2(aPntOnF1);
712 aPntOn2Faces.SetP1(aPntOnF2);
715 myPnts.Append(aPntOn2Faces);
720 //=======================================================================
721 //function : ComputeTolerance
723 //=======================================================================
724 Standard_Real IntTools_FaceFace::ComputeTolerance()
726 Standard_Integer i, j, aNbLin;
727 Standard_Real aFirst, aLast, aD, aDMax, aT;
728 Handle(Geom_Surface) aS1, aS2;
731 aNbLin = mySeqOfCurve.Length();
733 aS1 = myHS1->ChangeSurface().Surface();
734 aS2 = myHS2->ChangeSurface().Surface();
736 for (i = 1; i <= aNbLin; ++i)
738 const IntTools_Curve& aIC = mySeqOfCurve(i);
739 const Handle(Geom_Curve)& aC3D = aIC.Curve();
745 aFirst = aC3D->FirstParameter();
746 aLast = aC3D->LastParameter();
748 const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
749 const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
751 for (j = 0; j < 2; ++j)
753 const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
754 const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
758 if (IntTools_Tools::ComputeTolerance
759 (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
769 const TopoDS_Face& aF = !j ? myFace1 : myFace2;
770 aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
782 //=======================================================================
783 //function :ComputeTolReached3d
785 //=======================================================================
786 void IntTools_FaceFace::ComputeTolReached3d()
788 Standard_Integer aNbLin;
789 GeomAbs_SurfaceType aType1, aType2;
791 aNbLin=myIntersector.NbLines();
796 aType1=myHS1->Surface().GetType();
797 aType2=myHS2->Surface().GetType();
799 if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder)
803 Handle(IntPatch_Line) aIL1, aIL2;
804 IntPatch_IType aTL1, aTL2;
806 aIL1=myIntersector.Line(1);
807 aIL2=myIntersector.Line(2);
808 aTL1=aIL1->ArcType();
809 aTL2=aIL2->ArcType();
810 if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
811 Standard_Real aD, aDTresh, dTol;
817 aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
818 aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
819 aD=aL1.Distance(aL2);
822 {//In order to avoid creation too thin face
823 myTolReached3d=aD+dTol;
827 }// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
830 Standard_Real aDMax = ComputeTolerance();
831 if (aDMax > myTolReached3d)
833 myTolReached3d = aDMax;
837 //=======================================================================
838 //function : MakeCurve
840 //=======================================================================
841 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
842 const Handle(Adaptor3d_TopolTool)& dom1,
843 const Handle(Adaptor3d_TopolTool)& dom2,
844 const Standard_Real theToler)
846 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
847 Standard_Boolean ok, bPCurvesOk;
848 Standard_Integer i, j, aNbParts;
849 Standard_Real fprm, lprm;
851 Handle(IntPatch_Line) L;
853 Handle(Geom_Curve) newc;
855 const Standard_Real TOLCHECK =0.0000001;
856 const Standard_Real TOLANGCHECK=0.1;
858 rejectSurface = Standard_False;
859 reApprox = Standard_False;
861 bPCurvesOk = Standard_True;
866 bAvoidLineConstructor = Standard_False;
867 L = myIntersector.Line(Index);
870 if(typl==IntPatch_Walking) {
871 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
872 if(aWLine.IsNull()) {
878 //if(!myListOfPnts.IsEmpty()) {
879 // bAvoidLineConstructor = Standard_True;
882 Standard_Integer nbp = aWLine->NbPnts();
883 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
884 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
886 const gp_Pnt& P1 = p1.Value();
887 const gp_Pnt& P2 = p2.Value();
889 if(P1.SquareDistance(P2) < 1.e-14) {
890 bAvoidLineConstructor = Standard_False;
898 if(!bAvoidLineConstructor) {
899 myLConstruct.Perform(L);
901 bDone=myLConstruct.IsDone();
907 if(typl != IntPatch_Restriction)
909 aNbParts=myLConstruct.NbParts();
920 //########################################
921 // Line, Parabola, Hyperbola
922 //########################################
924 case IntPatch_Parabola:
925 case IntPatch_Hyperbola: {
926 if (typl == IntPatch_Lin) {
928 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
931 else if (typl == IntPatch_Parabola) {
933 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
936 else if (typl == IntPatch_Hyperbola) {
938 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
942 if (typl == IntPatch_Lin) {
943 TolR3d (myFace1, myFace2, myTolReached3d);
946 aNbParts=myLConstruct.NbParts();
947 for (i=1; i<=aNbParts; i++) {
948 Standard_Boolean bFNIt, bLPIt;
950 myLConstruct.Part(i, fprm, lprm);
952 bFNIt=Precision::IsNegativeInfinite(fprm);
953 bLPIt=Precision::IsPositiveInfinite(lprm);
955 if (!bFNIt && !bLPIt) {
957 IntTools_Curve aCurve;
959 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
960 aCurve.SetCurve(aCT3D);
961 if (typl == IntPatch_Parabola) {
962 Standard_Real aTolF1, aTolF2, aTolBase;
964 aTolF1 = BRep_Tool::Tolerance(myFace1);
965 aTolF2 = BRep_Tool::Tolerance(myFace2);
966 aTolBase=aTolF1+aTolF2;
967 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
970 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
972 Handle (Geom2d_Curve) C2d;
973 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
974 myHS1->ChangeSurface().Surface(), newc, C2d);
975 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
976 myTolReached2d=Tolpc;
979 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
982 Handle(Geom2d_BSplineCurve) H1;
984 aCurve.SetFirstCurve2d(H1);
988 Handle (Geom2d_Curve) C2d;
989 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
990 myHS2->ChangeSurface().Surface(), newc, C2d);
991 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
992 myTolReached2d=Tolpc;
995 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
998 Handle(Geom2d_BSplineCurve) H1;
1000 aCurve.SetSecondCurve2d(H1);
1002 mySeqOfCurve.Append(aCurve);
1003 } //if (!bFNIt && !bLPIt) {
1005 // on regarde si on garde
1007 Standard_Real aTestPrm, dT=100.;
1010 if (bFNIt && !bLPIt) {
1013 else if (!bFNIt && bLPIt) {
1017 // i.e, if (bFNIt && bLPIt)
1018 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
1021 gp_Pnt ptref(newc->Value(aTestPrm));
1023 GeomAbs_SurfaceType typS1 = myHS1->GetType();
1024 GeomAbs_SurfaceType typS2 = myHS2->GetType();
1025 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
1026 typS1 == GeomAbs_OffsetSurface ||
1027 typS1 == GeomAbs_SurfaceOfRevolution ||
1028 typS2 == GeomAbs_SurfaceOfExtrusion ||
1029 typS2 == GeomAbs_OffsetSurface ||
1030 typS2 == GeomAbs_SurfaceOfRevolution) {
1031 Handle(Geom2d_BSplineCurve) H1;
1032 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1036 Standard_Real u1, v1, u2, v2, Tol;
1038 Tol = Precision::Confusion();
1039 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1040 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1042 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1045 Handle(Geom2d_BSplineCurve) H1;
1046 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1049 }// for (i=1; i<=aNbParts; i++) {
1050 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
1053 //########################################
1054 // Circle and Ellipse
1055 //########################################
1056 case IntPatch_Circle:
1057 case IntPatch_Ellipse: {
1059 if (typl == IntPatch_Circle) {
1060 newc = new Geom_Circle
1061 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
1063 else { //IntPatch_Ellipse
1064 newc = new Geom_Ellipse
1065 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
1069 TolR3d (myFace1, myFace2, myTolReached3d);
1071 aNbParts=myLConstruct.NbParts();
1073 Standard_Real aPeriod, aNul;
1074 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
1079 for (i=1; i<=aNbParts; i++) {
1080 myLConstruct.Part(i, fprm, lprm);
1082 if (fprm < aNul && lprm > aNul) {
1083 // interval that goes through 0. is divided on two intervals;
1084 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1085 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1087 if((aPeriod - fprm) > Tolpc) {
1088 aSeqFprm.Append(fprm);
1089 aSeqLprm.Append(aPeriod);
1092 gp_Pnt P1 = newc->Value(fprm);
1093 gp_Pnt P2 = newc->Value(aPeriod);
1094 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1095 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1097 if(P1.Distance(P2) > aTolDist) {
1098 Standard_Real anewpar = fprm;
1100 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
1101 lprm, Standard_False, anewpar, myContext)) {
1104 aSeqFprm.Append(fprm);
1105 aSeqLprm.Append(aPeriod);
1110 if((lprm - aNul) > Tolpc) {
1111 aSeqFprm.Append(aNul);
1112 aSeqLprm.Append(lprm);
1115 gp_Pnt P1 = newc->Value(aNul);
1116 gp_Pnt P2 = newc->Value(lprm);
1117 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1118 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1120 if(P1.Distance(P2) > aTolDist) {
1121 Standard_Real anewpar = lprm;
1123 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
1124 fprm, Standard_True, anewpar, myContext)) {
1127 aSeqFprm.Append(aNul);
1128 aSeqLprm.Append(lprm);
1134 aSeqFprm.Append(fprm);
1135 aSeqLprm.Append(lprm);
1140 aNbParts=aSeqFprm.Length();
1141 for (i=1; i<=aNbParts; i++) {
1145 Standard_Real aRealEpsilon=RealEpsilon();
1146 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
1147 //==============================================
1149 IntTools_Curve aCurve;
1150 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1151 aCurve.SetCurve(aTC3D);
1152 fprm=aTC3D->FirstParameter();
1153 lprm=aTC3D->LastParameter ();
1155 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1157 Handle (Geom2d_Curve) C2d;
1158 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1159 myHS1->ChangeSurface().Surface(), newc, C2d);
1160 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1161 myTolReached2d=Tolpc;
1164 aCurve.SetFirstCurve2d(C2d);
1167 Handle(Geom2d_BSplineCurve) H1;
1168 aCurve.SetFirstCurve2d(H1);
1173 Handle (Geom2d_Curve) C2d;
1174 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1175 myHS2->ChangeSurface().Surface(),newc,C2d);
1176 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1177 myTolReached2d=Tolpc;
1180 aCurve.SetSecondCurve2d(C2d);
1183 Handle(Geom2d_BSplineCurve) H1;
1184 aCurve.SetSecondCurve2d(H1);
1189 Handle(Geom2d_BSplineCurve) H1;
1190 aCurve.SetFirstCurve2d(H1);
1191 aCurve.SetSecondCurve2d(H1);
1193 mySeqOfCurve.Append(aCurve);
1194 //==============================================
1195 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
1198 // on regarde si on garde
1201 // if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1202 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1203 IntTools_Curve aCurve;
1204 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1205 aCurve.SetCurve(aTC3D);
1206 fprm=aTC3D->FirstParameter();
1207 lprm=aTC3D->LastParameter ();
1210 Handle (Geom2d_Curve) C2d;
1211 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1212 myHS1->ChangeSurface().Surface(),newc,C2d);
1213 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1214 myTolReached2d=Tolpc;
1217 aCurve.SetFirstCurve2d(C2d);
1220 Handle(Geom2d_BSplineCurve) H1;
1221 aCurve.SetFirstCurve2d(H1);
1225 Handle (Geom2d_Curve) C2d;
1226 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1227 myHS2->ChangeSurface().Surface(),newc,C2d);
1228 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1229 myTolReached2d=Tolpc;
1232 aCurve.SetSecondCurve2d(C2d);
1235 Handle(Geom2d_BSplineCurve) H1;
1236 aCurve.SetSecondCurve2d(H1);
1238 mySeqOfCurve.Append(aCurve);
1243 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1245 aTwoPIdiv17=2.*M_PI/17.;
1247 for (j=0; j<=17; j++) {
1248 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1249 Tol = Precision::Confusion();
1251 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1252 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1254 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1257 IntTools_Curve aCurve;
1258 aCurve.SetCurve(newc);
1259 //==============================================
1260 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1263 Handle (Geom2d_Curve) C2d;
1264 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1265 myHS1->ChangeSurface().Surface(), newc, C2d);
1266 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1267 myTolReached2d=Tolpc;
1270 aCurve.SetFirstCurve2d(C2d);
1273 Handle(Geom2d_BSplineCurve) H1;
1274 aCurve.SetFirstCurve2d(H1);
1278 Handle (Geom2d_Curve) C2d;
1279 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1280 myHS2->ChangeSurface().Surface(), newc, C2d);
1281 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1282 myTolReached2d=Tolpc;
1285 aCurve.SetSecondCurve2d(C2d);
1289 Handle(Geom2d_BSplineCurve) H1;
1290 aCurve.SetSecondCurve2d(H1);
1292 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1295 Handle(Geom2d_BSplineCurve) H1;
1297 aCurve.SetFirstCurve2d(H1);
1298 aCurve.SetSecondCurve2d(H1);
1300 //==============================================
1302 mySeqOfCurve.Append(aCurve);
1305 }// end of if (ok) {
1306 }// end of for (Standard_Integer j=0; j<=17; j++)
1307 }// end of else { on regarde si on garde
1308 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1309 }// IntPatch_Circle: IntPatch_Ellipse:
1312 case IntPatch_Analytic: {
1313 IntSurf_Quadric quad1,quad2;
1314 GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
1318 quad1.SetValue(myHS1->Surface().Plane());
1320 case GeomAbs_Cylinder:
1321 quad1.SetValue(myHS1->Surface().Cylinder());
1324 quad1.SetValue(myHS1->Surface().Cone());
1326 case GeomAbs_Sphere:
1327 quad1.SetValue(myHS1->Surface().Sphere());
1330 quad1.SetValue(myHS1->Surface().Torus());
1333 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
1336 typs = myHS2->Surface().GetType();
1340 quad2.SetValue(myHS2->Surface().Plane());
1342 case GeomAbs_Cylinder:
1343 quad2.SetValue(myHS2->Surface().Cylinder());
1346 quad2.SetValue(myHS2->Surface().Cone());
1348 case GeomAbs_Sphere:
1349 quad2.SetValue(myHS2->Surface().Sphere());
1352 quad2.SetValue(myHS2->Surface().Torus());
1355 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
1359 IntPatch_ALineToWLine convert (quad1, quad2);
1362 aNbParts=myLConstruct.NbParts();
1363 for (i=1; i<=aNbParts; i++) {
1364 myLConstruct.Part(i, fprm, lprm);
1365 Handle(IntPatch_WLine) WL =
1366 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1368 Handle(Geom2d_BSplineCurve) H1;
1369 Handle(Geom2d_BSplineCurve) H2;
1372 H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1376 H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1379 mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1383 else { // myApprox=TRUE
1384 GeomInt_WLApprox theapp3d;
1386 Standard_Real tol2d = myTolApprox;
1388 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
1390 aNbParts=myLConstruct.NbParts();
1391 for (i=1; i<=aNbParts; i++) {
1392 myLConstruct.Part(i, fprm, lprm);
1393 Handle(IntPatch_WLine) WL =
1394 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
1396 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
1398 if (!theapp3d.IsDone()) {
1400 Handle(Geom2d_BSplineCurve) H1;
1401 Handle(Geom2d_BSplineCurve) H2;
1404 H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1408 H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1411 mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1415 if(myApprox1 || myApprox2) {
1416 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1417 myTolReached2d = theapp3d.TolReached2d();
1421 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1422 myTolReached3d = theapp3d.TolReached3d();
1425 Standard_Integer aNbMultiCurves, nbpoles;
1426 aNbMultiCurves=theapp3d.NbMultiCurves();
1427 for (j=1; j<=aNbMultiCurves; j++) {
1428 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1429 nbpoles = mbspc.NbPoles();
1431 TColgp_Array1OfPnt tpoles(1, nbpoles);
1432 mbspc.Curve(1, tpoles);
1433 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1435 mbspc.Multiplicities(),
1438 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1439 Check.FixTangent(Standard_True,Standard_True);
1441 IntTools_Curve aCurve;
1442 aCurve.SetCurve(BS);
1445 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1446 mbspc.Curve(2,tpoles2d);
1447 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1449 mbspc.Multiplicities(),
1452 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1453 newCheck.FixTangent(Standard_True,Standard_True);
1455 aCurve.SetFirstCurve2d(BS2);
1458 Handle(Geom2d_BSplineCurve) H1;
1459 aCurve.SetFirstCurve2d(H1);
1463 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1464 Standard_Integer TwoOrThree;
1465 TwoOrThree=myApprox1 ? 3 : 2;
1466 mbspc.Curve(TwoOrThree, tpoles2d);
1467 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1469 mbspc.Multiplicities(),
1472 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1473 newCheck.FixTangent(Standard_True,Standard_True);
1475 aCurve.SetSecondCurve2d(BS2);
1478 Handle(Geom2d_BSplineCurve) H2;
1479 aCurve.SetSecondCurve2d(H2);
1482 mySeqOfCurve.Append(aCurve);
1484 }// for (j=1; j<=aNbMultiCurves; j++) {
1485 }// else from if (!theapp3d.IsDone())
1486 }// for (i=1; i<=aNbParts; i++) {
1487 }// else { // myApprox=TRUE
1488 }// case IntPatch_Analytic:
1491 case IntPatch_Walking:{
1492 Handle(IntPatch_WLine) WL =
1493 Handle(IntPatch_WLine)::DownCast(L);
1500 Standard_Integer ifprm, ilprm;
1504 if(!bAvoidLineConstructor){
1505 aNbParts=myLConstruct.NbParts();
1507 for (i=1; i<=aNbParts; ++i) {
1508 Handle(Geom2d_BSplineCurve) H1, H2;
1509 Handle(Geom_Curve) aBSp;
1511 if(bAvoidLineConstructor) {
1513 ilprm = WL->NbPnts();
1516 myLConstruct.Part(i, fprm, lprm);
1517 ifprm=(Standard_Integer)fprm;
1518 ilprm=(Standard_Integer)lprm;
1522 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1526 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1529 aBSp=GeomInt_IntSS::MakeBSpline(WL, ifprm, ilprm);
1530 IntTools_Curve aIC(aBSp, H1, H2);
1531 mySeqOfCurve.Append(aIC);
1532 }// for (i=1; i<=aNbParts; ++i) {
1533 }// if (!myApprox) {
1536 Standard_Boolean bIsDecomposited;
1537 Standard_Integer nbiter, aNbSeqOfL;
1538 Standard_Real tol2d, aTolApproxImp;
1539 IntPatch_SequenceOfLine aSeqOfL;
1540 GeomInt_WLApprox theapp3d;
1541 Approx_ParametrizationType aParType = Approx_ChordLength;
1543 Standard_Boolean anApprox1 = myApprox1;
1544 Standard_Boolean anApprox2 = myApprox2;
1546 aTolApproxImp=1.e-5;
1547 tol2d = myTolApprox;
1549 GeomAbs_SurfaceType typs1, typs2;
1550 typs1 = myHS1->Surface().GetType();
1551 typs2 = myHS2->Surface().GetType();
1552 Standard_Boolean anWithPC = Standard_True;
1554 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
1556 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
1558 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
1560 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
1564 myTolApprox = aTolApproxImp;//1.e-5;
1565 anApprox1 = Standard_False;
1566 anApprox2 = Standard_False;
1568 tol2d = myTolApprox;
1571 if(myHS1 == myHS2) {
1572 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1573 rejectSurface = Standard_True;
1576 if(reApprox && !rejectSurface)
1577 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1579 Standard_Integer iDegMax, iDegMin, iNbIter;
1581 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1582 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax,
1583 iNbIter, 30, Standard_True, aParType);
1587 Standard_Real aReachedTol = Precision::Confusion();
1588 bIsDecomposited = IntTools_WLineTool::
1589 DecompositionOfWLine(WL,
1595 bAvoidLineConstructor,
1599 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
1600 myTolReached3d = aReachedTol;
1603 aNbSeqOfL=aSeqOfL.Length();
1605 if (bIsDecomposited) {
1611 if (!bAvoidLineConstructor) {
1612 aNbParts=myLConstruct.NbParts();
1617 for(i = 1; i <= nbiter; ++i) {
1618 if(bIsDecomposited) {
1619 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1621 ilprm = WL->NbPnts();
1624 if(bAvoidLineConstructor) {
1626 ilprm = WL->NbPnts();
1629 myLConstruct.Part(i, fprm, lprm);
1630 ifprm = (Standard_Integer)fprm;
1631 ilprm = (Standard_Integer)lprm;
1635 //-- Si une des surfaces est un plan , on approxime en 2d
1636 //-- sur cette surface et on remonte les points 2d en 3d.
1637 if(typs1 == GeomAbs_Plane) {
1638 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1640 else if(typs2 == GeomAbs_Plane) {
1641 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1645 if (myHS1 != myHS2){
1646 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1647 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1649 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1650 Standard_True, aParType);
1652 Standard_Boolean bUseSurfaces;
1653 bUseSurfaces = IntTools_WLineTool::NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1656 rejectSurface = Standard_True;
1658 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1659 Standard_False, aParType);
1664 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1667 if (!theapp3d.IsDone()) {
1668 Handle(Geom2d_BSplineCurve) H1;
1669 Handle(Geom2d_BSplineCurve) H2;
1671 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1674 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1678 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1681 IntTools_Curve aIC(aBSp, H1, H2);
1682 mySeqOfCurve.Append(aIC);
1686 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1687 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1688 myTolReached2d = theapp3d.TolReached2d();
1691 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1692 myTolReached3d = myTolReached2d;
1694 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1695 if (myTolReached3d<1.e-6) {
1696 myTolReached3d = theapp3d.TolReached3d();
1697 myTolReached3d=1.e-6;
1701 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1702 myTolReached3d = theapp3d.TolReached3d();
1705 Standard_Integer aNbMultiCurves, nbpoles;
1706 aNbMultiCurves=theapp3d.NbMultiCurves();
1707 for (j=1; j<=aNbMultiCurves; j++) {
1708 if(typs1 == GeomAbs_Plane) {
1709 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1710 nbpoles = mbspc.NbPoles();
1712 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1713 TColgp_Array1OfPnt tpoles(1,nbpoles);
1715 mbspc.Curve(1,tpoles2d);
1716 const gp_Pln& Pln = myHS1->Surface().Plane();
1718 Standard_Integer ik;
1719 for(ik = 1; ik<= nbpoles; ik++) {
1721 ElSLib::Value(tpoles2d.Value(ik).X(),
1722 tpoles2d.Value(ik).Y(),
1726 Handle(Geom_BSplineCurve) BS =
1727 new Geom_BSplineCurve(tpoles,
1729 mbspc.Multiplicities(),
1731 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1732 Check.FixTangent(Standard_True, Standard_True);
1734 IntTools_Curve aCurve;
1735 aCurve.SetCurve(BS);
1738 Handle(Geom2d_BSplineCurve) BS1 =
1739 new Geom2d_BSplineCurve(tpoles2d,
1741 mbspc.Multiplicities(),
1743 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1744 Check1.FixTangent(Standard_True,Standard_True);
1746 // ############################################
1747 if(!rejectSurface && !reApprox) {
1748 Standard_Boolean isValid = IsCurveValid(BS1);
1750 reApprox = Standard_True;
1754 // ############################################
1755 aCurve.SetFirstCurve2d(BS1);
1758 Handle(Geom2d_BSplineCurve) H1;
1759 aCurve.SetFirstCurve2d(H1);
1763 mbspc.Curve(2, tpoles2d);
1765 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1767 mbspc.Multiplicities(),
1769 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1770 newCheck.FixTangent(Standard_True,Standard_True);
1772 // ###########################################
1773 if(!rejectSurface && !reApprox) {
1774 Standard_Boolean isValid = IsCurveValid(BS2);
1776 reApprox = Standard_True;
1780 // ###########################################
1782 aCurve.SetSecondCurve2d(BS2);
1785 Handle(Geom2d_BSplineCurve) H2;
1787 aCurve.SetSecondCurve2d(H2);
1790 mySeqOfCurve.Append(aCurve);
1792 }//if(typs1 == GeomAbs_Plane) {
1794 else if(typs2 == GeomAbs_Plane)
1796 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1797 nbpoles = mbspc.NbPoles();
1799 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1800 TColgp_Array1OfPnt tpoles(1,nbpoles);
1801 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1802 const gp_Pln& Pln = myHS2->Surface().Plane();
1804 Standard_Integer ik;
1805 for(ik = 1; ik<= nbpoles; ik++) {
1807 ElSLib::Value(tpoles2d.Value(ik).X(),
1808 tpoles2d.Value(ik).Y(),
1813 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1815 mbspc.Multiplicities(),
1817 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1818 Check.FixTangent(Standard_True,Standard_True);
1820 IntTools_Curve aCurve;
1821 aCurve.SetCurve(BS);
1824 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1826 mbspc.Multiplicities(),
1828 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1829 Check1.FixTangent(Standard_True,Standard_True);
1831 // ###########################################
1832 if(!rejectSurface && !reApprox) {
1833 Standard_Boolean isValid = IsCurveValid(BS1);
1835 reApprox = Standard_True;
1839 // ###########################################
1840 bPCurvesOk = CheckPCurve(BS1, myFace2);
1841 aCurve.SetSecondCurve2d(BS1);
1844 Handle(Geom2d_BSplineCurve) H2;
1845 aCurve.SetSecondCurve2d(H2);
1849 mbspc.Curve(1,tpoles2d);
1850 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1852 mbspc.Multiplicities(),
1854 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
1855 Check2.FixTangent(Standard_True,Standard_True);
1857 // ###########################################
1858 if(!rejectSurface && !reApprox) {
1859 Standard_Boolean isValid = IsCurveValid(BS2);
1861 reApprox = Standard_True;
1865 // ###########################################
1866 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1);
1867 aCurve.SetFirstCurve2d(BS2);
1870 Handle(Geom2d_BSplineCurve) H1;
1872 aCurve.SetFirstCurve2d(H1);
1875 //if points of the pcurves are out of the faces bounds
1876 //create 3d and 2d curves without approximation
1878 Handle(Geom2d_BSplineCurve) H1, H2;
1879 bPCurvesOk = Standard_True;
1881 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1884 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1885 bPCurvesOk = CheckPCurve(H1, myFace1);
1889 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1890 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2);
1893 //if pcurves created without approximation are out of the
1894 //faces bounds, use approximated 3d and 2d curves
1896 IntTools_Curve aIC(aBSp, H1, H2);
1897 mySeqOfCurve.Append(aIC);
1899 mySeqOfCurve.Append(aCurve);
1902 mySeqOfCurve.Append(aCurve);
1905 }// else if(typs2 == GeomAbs_Plane)
1907 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
1908 Standard_Boolean bIsValid1, bIsValid2;
1909 Handle(Geom_BSplineCurve) BS;
1910 Handle(Geom2d_BSplineCurve) aH2D;
1911 IntTools_Curve aCurve;
1913 bIsValid1=Standard_True;
1914 bIsValid2=Standard_True;
1916 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1917 nbpoles = mbspc.NbPoles();
1918 TColgp_Array1OfPnt tpoles(1,nbpoles);
1919 mbspc.Curve(1,tpoles);
1920 BS=new Geom_BSplineCurve(tpoles,
1922 mbspc.Multiplicities(),
1924 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1925 Check.FixTangent(Standard_True,Standard_True);
1927 aCurve.SetCurve(BS);
1928 aCurve.SetFirstCurve2d(aH2D);
1929 aCurve.SetSecondCurve2d(aH2D);
1933 Handle(Geom2d_BSplineCurve) BS1;
1934 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1935 mbspc.Curve(2,tpoles2d);
1937 BS1=new Geom2d_BSplineCurve(tpoles2d,
1939 mbspc.Multiplicities(),
1941 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
1942 newCheck.FixTangent(Standard_True,Standard_True);
1945 bIsValid1=CheckPCurve(BS1, myFace1);
1948 aCurve.SetFirstCurve2d(BS1);
1951 Handle(Geom2d_BSplineCurve) BS1;
1952 fprm = BS->FirstParameter();
1953 lprm = BS->LastParameter();
1955 Handle(Geom2d_Curve) C2d;
1956 Standard_Real aTol = myTolApprox;
1957 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1958 myHS1->ChangeSurface().Surface(), BS, C2d);
1959 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1960 aCurve.SetFirstCurve2d(BS1);
1962 } // if(myApprox1) {
1966 Handle(Geom2d_BSplineCurve) BS2;
1967 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1968 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
1969 BS2=new Geom2d_BSplineCurve(tpoles2d,
1971 mbspc.Multiplicities(),
1973 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1974 newCheck.FixTangent(Standard_True,Standard_True);
1977 bIsValid2=CheckPCurve(BS2, myFace2);
1979 aCurve.SetSecondCurve2d(BS2);
1982 Handle(Geom2d_BSplineCurve) BS2;
1983 fprm = BS->FirstParameter();
1984 lprm = BS->LastParameter();
1986 Handle(Geom2d_Curve) C2d;
1987 Standard_Real aTol = myTolApprox;
1988 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1989 myHS2->ChangeSurface().Surface(), BS, C2d);
1990 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1991 aCurve.SetSecondCurve2d(BS2);
1994 if (!bIsValid1 || !bIsValid2) {
1995 myTolApprox=aTolApproxImp;//1.e-5;
1996 tol2d = myTolApprox;
1997 reApprox = Standard_True;
2001 mySeqOfCurve.Append(aCurve);
2007 }// case IntPatch_Walking:{
2010 case IntPatch_Restriction:
2012 Handle(IntPatch_RLine) RL =
2013 Handle(IntPatch_RLine)::DownCast(L);
2014 Handle(Geom_Curve) aC3d;
2015 Handle(Geom2d_Curve) aC2d1, aC2d2;
2016 Standard_Real aTolReached;
2017 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
2018 aC2d1, aC2d2, aTolReached);
2023 Bnd_Box2d aBox1, aBox2;
2025 const Standard_Real aU1f = myHS1->FirstUParameter(),
2026 aV1f = myHS1->FirstVParameter(),
2027 aU1l = myHS1->LastUParameter(),
2028 aV1l = myHS1->LastVParameter();
2029 const Standard_Real aU2f = myHS2->FirstUParameter(),
2030 aV2f = myHS2->FirstVParameter(),
2031 aU2l = myHS2->LastUParameter(),
2032 aV2l = myHS2->LastVParameter();
2034 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
2035 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
2036 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
2037 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
2039 GeomInt_VectorOfReal anArrayOfParameters;
2041 //We consider here that the intersection line is same-parameter-line
2042 anArrayOfParameters.Append(aC3d->FirstParameter());
2043 anArrayOfParameters.Append(aC3d->LastParameter());
2046 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
2048 //Intersect with true boundaries. After that, enlarge bounding-boxes in order to
2049 //correct definition, if point on curve is inscribed in the box.
2050 aBox1.Enlarge(theToler);
2051 aBox2.Enlarge(theToler);
2053 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
2056 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
2058 Standard_Real &aParF = anArrayOfParameters(anInd),
2059 &aParL = anArrayOfParameters(anInd+1);
2061 if((aParL - aParF) <= Precision::PConfusion())
2063 //In order to more precise extending to the boundaries of source curves.
2064 if(anInd < aNbIntersSolutionsm1-1)
2070 const Standard_Real aPar = 0.5*(aParF + aParL);
2073 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
2076 aC2d1->D0(aPar, aPt);
2078 if(aBox1.IsOut(aPt))
2082 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
2087 aC2d2->D0(aPar, aPt);
2089 if(aBox2.IsOut(aPt))
2093 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
2096 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
2098 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
2099 mySeqOfCurve.Append(aIC);
2109 //=======================================================================
2110 //function : Parameters
2112 //=======================================================================
2113 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
2114 const Handle(GeomAdaptor_HSurface)& HS2,
2115 const gp_Pnt& Ptref,
2122 IntSurf_Quadric quad1,quad2;
2123 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2127 quad1.SetValue(HS1->Surface().Plane());
2129 case GeomAbs_Cylinder:
2130 quad1.SetValue(HS1->Surface().Cylinder());
2133 quad1.SetValue(HS1->Surface().Cone());
2135 case GeomAbs_Sphere:
2136 quad1.SetValue(HS1->Surface().Sphere());
2139 quad1.SetValue(HS1->Surface().Torus());
2142 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2145 typs = HS2->Surface().GetType();
2148 quad2.SetValue(HS2->Surface().Plane());
2150 case GeomAbs_Cylinder:
2151 quad2.SetValue(HS2->Surface().Cylinder());
2154 quad2.SetValue(HS2->Surface().Cone());
2156 case GeomAbs_Sphere:
2157 quad2.SetValue(HS2->Surface().Sphere());
2160 quad2.SetValue(HS2->Surface().Torus());
2163 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2166 quad1.Parameters(Ptref,U1,V1);
2167 quad2.Parameters(Ptref,U2,V2);
2170 //=======================================================================
2171 //function : MakeBSpline
2173 //=======================================================================
2174 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
2175 const Standard_Integer ideb,
2176 const Standard_Integer ifin)
2178 Standard_Integer i,nbpnt = ifin-ideb+1;
2179 TColgp_Array1OfPnt poles(1,nbpnt);
2180 TColStd_Array1OfReal knots(1,nbpnt);
2181 TColStd_Array1OfInteger mults(1,nbpnt);
2182 Standard_Integer ipidebm1;
2183 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2184 poles(i) = WL->Point(ipidebm1).Value();
2188 mults(1) = mults(nbpnt) = 2;
2190 new Geom_BSplineCurve(poles,knots,mults,1);
2193 //=======================================================================
2194 //function : PrepareLines3D
2196 //=======================================================================
2197 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
2199 Standard_Integer i, aNbCurves;
2200 GeomAbs_SurfaceType aType1, aType2;
2201 IntTools_SequenceOfCurves aNewCvs;
2203 // 1. Treatment closed curves
2204 aNbCurves=mySeqOfCurve.Length();
2205 for (i=1; i<=aNbCurves; ++i) {
2206 const IntTools_Curve& aIC=mySeqOfCurve(i);
2209 Standard_Integer j, aNbC;
2210 IntTools_SequenceOfCurves aSeqCvs;
2212 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2214 for (j=1; j<=aNbC; ++j) {
2215 const IntTools_Curve& aICNew=aSeqCvs(j);
2216 aNewCvs.Append(aICNew);
2220 aNewCvs.Append(aIC);
2224 aNewCvs.Append(aIC);
2228 // 2. Plane\Cone intersection when we had 4 curves
2229 aType1=myHS1->GetType();
2230 aType2=myHS2->GetType();
2231 aNbCurves=aNewCvs.Length();
2233 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2234 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
2236 GeomAbs_CurveType aCType1;
2238 aCType1=aNewCvs(1).Type();
2239 if (aCType1==GeomAbs_Line) {
2240 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2242 for (i=1; i<=aNbCurves; ++i) {
2243 const IntTools_Curve& aIC=aNewCvs(i);
2247 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2250 aNbCurves=aSeqOut.Length();
2251 for (i=1; i<=aNbCurves; ++i) {
2252 const IntTools_Curve& aIC=aSeqOut(i);
2253 aNewCvs.Append(aIC);
2257 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
2259 // 3. Fill mySeqOfCurve
2260 mySeqOfCurve.Clear();
2261 aNbCurves=aNewCvs.Length();
2262 for (i=1; i<=aNbCurves; ++i) {
2263 const IntTools_Curve& aIC=aNewCvs(i);
2264 mySeqOfCurve.Append(aIC);
2267 //=======================================================================
2268 //function : CorrectSurfaceBoundaries
2270 //=======================================================================
2271 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
2272 const Standard_Real theTolerance,
2273 Standard_Real& theumin,
2274 Standard_Real& theumax,
2275 Standard_Real& thevmin,
2276 Standard_Real& thevmax)
2278 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2279 Standard_Real uinf, usup, vinf, vsup, delta;
2280 GeomAbs_SurfaceType aType;
2281 Handle(Geom_Surface) aSurface;
2283 aSurface = BRep_Tool::Surface(theFace);
2284 aSurface->Bounds(uinf, usup, vinf, vsup);
2285 delta = theTolerance;
2286 enlarge = Standard_False;
2288 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2290 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2291 Handle(Geom_Surface) aBasisSurface =
2292 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2294 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2295 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2300 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2301 Handle(Geom_Surface) aBasisSurface =
2302 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2304 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2305 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2310 isuperiodic = anAdaptorSurface.IsUPeriodic();
2311 isvperiodic = anAdaptorSurface.IsVPeriodic();
2313 aType=anAdaptorSurface.GetType();
2314 if((aType==GeomAbs_BezierSurface) ||
2315 (aType==GeomAbs_BSplineSurface) ||
2316 (aType==GeomAbs_SurfaceOfExtrusion) ||
2317 (aType==GeomAbs_SurfaceOfRevolution) ||
2318 (aType==GeomAbs_Cylinder)) {
2319 enlarge=Standard_True;
2322 if(!isuperiodic && enlarge) {
2324 if(!Precision::IsInfinite(theumin) &&
2325 ((theumin - uinf) > delta))
2331 if(!Precision::IsInfinite(theumax) &&
2332 ((usup - theumax) > delta))
2338 if(!isvperiodic && enlarge) {
2339 if(!Precision::IsInfinite(thevmin) &&
2340 ((thevmin - vinf) > delta)) {
2346 if(!Precision::IsInfinite(thevmax) &&
2347 ((vsup - thevmax) > delta)) {
2356 Standard_Integer aNbP;
2357 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2359 aTolPA=Precision::Angular();
2362 aXP=anAdaptorSurface.UPeriod();
2363 dXfact=theumax-theumin;
2364 if (dXfact-aTolPA>aXP) {
2365 aXmid=0.5*(theumax+theumin);
2366 aNbP=RealToInt(aXmid/aXP);
2371 if (theumin>aTolPA) {
2372 aX1=theumin+aNbP*aXP;
2385 aXP=anAdaptorSurface.VPeriod();
2386 dXfact=thevmax-thevmin;
2387 if (dXfact-aTolPA>aXP) {
2388 aXmid=0.5*(thevmax+thevmin);
2389 aNbP=RealToInt(aXmid/aXP);
2394 if (thevmin>aTolPA) {
2395 aX1=thevmin+aNbP*aXP;
2408 if(isuperiodic || isvperiodic) {
2409 Standard_Boolean correct = Standard_False;
2410 Standard_Boolean correctU = Standard_False;
2411 Standard_Boolean correctV = Standard_False;
2413 TopExp_Explorer anExp;
2415 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2416 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
2417 correct = Standard_True;
2419 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2421 for(Standard_Integer i = 0; i < 2; i++) {
2423 anEdge.Orientation(TopAbs_FORWARD);
2426 anEdge.Orientation(TopAbs_REVERSED);
2428 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2430 if(aCurve.IsNull()) {
2431 correct = Standard_False;
2434 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2436 if(aLine.IsNull()) {
2437 correct = Standard_False;
2440 gp_Dir2d anUDir(1., 0.);
2441 gp_Dir2d aVDir(0., 1.);
2442 Standard_Real anAngularTolerance = Precision::Angular();
2444 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2445 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2447 gp_Pnt2d pp1 = aCurve->Value(f);
2449 gp_Pnt2d pp2 = aCurve->Value(l);
2458 Standard_Real umin, vmin, umax, vmax;
2459 aBox.Get(umin, vmin, umax, vmax);
2461 if(isuperiodic && correctU) {
2466 if(theumax > umax) {
2470 if(isvperiodic && correctV) {
2481 //=======================================================================
2484 //=======================================================================
2485 void TolR3d(const TopoDS_Face& aF1,
2486 const TopoDS_Face& aF2,
2487 Standard_Real& myTolReached3d)
2489 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
2491 aTolTresh=2.999999e-3;
2492 aTolF1 = BRep_Tool::Tolerance(aF1);
2493 aTolF2 = BRep_Tool::Tolerance(aF2);
2494 aTolFMax=Max(aTolF1, aTolF2);
2496 if (aTolFMax>aTolTresh) {
2497 myTolReached3d=aTolFMax;
2501 // ------------------------------------------------------------------------------------------------
2502 // static function: ParameterOutOfBoundary
2503 // purpose: Computes a new parameter for given curve. The corresponding 2d points
2504 // does not lay on any boundary of given faces
2505 // ------------------------------------------------------------------------------------------------
2506 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
2507 const Handle(Geom_Curve)& theCurve,
2508 const TopoDS_Face& theFace1,
2509 const TopoDS_Face& theFace2,
2510 const Standard_Real theOtherParameter,
2511 const Standard_Boolean bIncreasePar,
2512 Standard_Real& theNewParameter,
2513 const Handle(IntTools_Context)& aContext)
2515 Standard_Boolean bIsComputed = Standard_False;
2516 theNewParameter = theParameter;
2518 Standard_Real acurpar = theParameter;
2519 TopAbs_State aState = TopAbs_ON;
2520 Standard_Integer iter = 0;
2521 Standard_Real asumtol = BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
2522 Standard_Real adelta = asumtol * 0.1;
2523 adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
2524 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
2525 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
2527 Standard_Real u1, u2, v1, v2;
2529 GeomAPI_ProjectPointOnSurf aPrj1;
2530 aSurf1->Bounds(u1, u2, v1, v2);
2531 aPrj1.Init(aSurf1, u1, u2, v1, v2);
2533 GeomAPI_ProjectPointOnSurf aPrj2;
2534 aSurf2->Bounds(u1, u2, v1, v2);
2535 aPrj2.Init(aSurf2, u1, u2, v1, v2);
2537 while(aState == TopAbs_ON) {
2542 gp_Pnt aPCurrent = theCurve->Value(acurpar);
2543 aPrj1.Perform(aPCurrent);
2544 Standard_Real U=0., V=0.;
2546 if(aPrj1.IsDone()) {
2547 aPrj1.LowerDistanceParameters(U, V);
2548 aState = aContext->StatePointFace(theFace1, gp_Pnt2d(U, V));
2551 if(aState != TopAbs_ON) {
2552 aPrj2.Perform(aPCurrent);
2554 if(aPrj2.IsDone()) {
2555 aPrj2.LowerDistanceParameters(U, V);
2556 aState = aContext->StatePointFace(theFace2, gp_Pnt2d(U, V));
2567 theNewParameter = acurpar;
2568 bIsComputed = Standard_True;
2571 if(acurpar >= theOtherParameter)
2572 theNewParameter = theOtherParameter;
2575 if(acurpar <= theOtherParameter)
2576 theNewParameter = theOtherParameter;
2582 //=======================================================================
2583 //function : IsCurveValid
2585 //=======================================================================
2586 Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve)
2588 if(thePCurve.IsNull())
2589 return Standard_False;
2591 Standard_Real tolint = 1.e-10;
2592 Geom2dAdaptor_Curve PCA;
2593 IntRes2d_Domain PCD;
2594 Geom2dInt_GInter PCI;
2596 Standard_Real pf = 0., pl = 0.;
2597 gp_Pnt2d pntf, pntl;
2599 if(!thePCurve->IsClosed() && !thePCurve->IsPeriodic()) {
2600 pf = thePCurve->FirstParameter();
2601 pl = thePCurve->LastParameter();
2602 pntf = thePCurve->Value(pf);
2603 pntl = thePCurve->Value(pl);
2604 PCA.Load(thePCurve);
2605 if(!PCA.IsPeriodic()) {
2606 if(PCA.FirstParameter() > pf) pf = PCA.FirstParameter();
2607 if(PCA.LastParameter() < pl) pl = PCA.LastParameter();
2609 PCD.SetValues(pntf,pf,tolint,pntl,pl,tolint);
2610 PCI.Perform(PCA,PCD,tolint,tolint);
2612 if(PCI.NbPoints() > 0) {
2613 return Standard_False;
2617 return Standard_True;
2620 //=======================================================================
2621 //static function : ApproxWithPCurves
2622 //purpose : for bug 20964 only
2623 //=======================================================================
2624 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
2625 const gp_Sphere& theSph)
2627 Standard_Boolean bRes = Standard_True;
2628 Standard_Real R1 = theCyl.Radius(), R2 = theSph.Radius();
2631 Standard_Real aD2, aRc2, aEps;
2637 const gp_Ax3& aAx3Sph=theSph.Position();
2638 const gp_Pnt& aLocSph=aAx3Sph.Location();
2639 const gp_Dir& aDirSph=aAx3Sph.Direction();
2641 const gp_Ax1& aAx1Cyl=theCyl.Axis();
2642 gp_Lin aLinCyl(aAx1Cyl);
2644 aApexSph.SetXYZ(aLocSph.XYZ()+R2*aDirSph.XYZ());
2645 aD2=aLinCyl.SquareDistance(aApexSph);
2646 if (fabs(aD2-aRc2)<aEps) {
2650 aApexSph.SetXYZ(aLocSph.XYZ()-R2*aDirSph.XYZ());
2651 aD2=aLinCyl.SquareDistance(aApexSph);
2652 if (fabs(aD2-aRc2)<aEps) {
2661 gp_Lin anCylAx(theCyl.Axis());
2663 Standard_Real aDist = anCylAx.Distance(theSph.Location());
2664 Standard_Real aDRel = Abs(aDist - R1)/R2;
2666 if(aDRel > .2) return bRes;
2668 Standard_Real par = ElCLib::Parameter(anCylAx, theSph.Location());
2669 gp_Pnt aP = ElCLib::Value(par, anCylAx);
2670 gp_Vec aV(aP, theSph.Location());
2672 Standard_Real dd = aV.Dot(theSph.Position().XDirection());
2674 if(aDist < R1 && dd > 0.) return Standard_False;
2675 if(aDist > R1 && dd < 0.) return Standard_False;
2680 //=======================================================================
2681 //function : PerformPlanes
2683 //=======================================================================
2684 void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
2685 const Handle(GeomAdaptor_HSurface)& theS2,
2686 const Standard_Real TolAng,
2687 const Standard_Real TolTang,
2688 const Standard_Boolean theApprox1,
2689 const Standard_Boolean theApprox2,
2690 IntTools_SequenceOfCurves& theSeqOfCurve,
2691 Standard_Boolean& theTangentFaces)
2694 gp_Pln aPln1 = theS1->Surface().Plane();
2695 gp_Pln aPln2 = theS2->Surface().Plane();
2697 IntAna_QuadQuadGeo aPlnInter(aPln1, aPln2, TolAng, TolTang);
2699 if(!aPlnInter.IsDone()) {
2700 theTangentFaces = Standard_False;
2704 IntAna_ResultType aResType = aPlnInter.TypeInter();
2706 if(aResType == IntAna_Same) {
2707 theTangentFaces = Standard_True;
2711 theTangentFaces = Standard_False;
2713 if(aResType == IntAna_Empty) {
2717 gp_Lin aLin = aPlnInter.Line(1);
2719 ProjLib_Plane aProj;
2722 aProj.Project(aLin);
2723 gp_Lin2d aLin2d1 = aProj.Line();
2726 aProj.Project(aLin);
2727 gp_Lin2d aLin2d2 = aProj.Line();
2729 //classify line2d1 relatively first plane
2730 Standard_Real P11, P12;
2731 Standard_Boolean IsCrossed = ClassifyLin2d(theS1, aLin2d1, TolTang, P11, P12);
2732 if(!IsCrossed) return;
2733 //classify line2d2 relatively second plane
2734 Standard_Real P21, P22;
2735 IsCrossed = ClassifyLin2d(theS2, aLin2d2, TolTang, P21, P22);
2736 if(!IsCrossed) return;
2738 //Analysis of parametric intervals: must have common part
2740 if(P21 >= P12) return;
2741 if(P22 <= P11) return;
2743 Standard_Real pmin, pmax;
2744 pmin = Max(P11, P21);
2745 pmax = Min(P12, P22);
2747 if(pmax - pmin <= TolTang) return;
2749 Handle(Geom_Line) aGLin = new Geom_Line(aLin);
2751 IntTools_Curve aCurve;
2752 Handle(Geom_TrimmedCurve) aGTLin = new Geom_TrimmedCurve(aGLin, pmin, pmax);
2754 aCurve.SetCurve(aGTLin);
2757 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d1);
2758 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2761 Handle(Geom2d_Curve) H1;
2762 aCurve.SetFirstCurve2d(H1);
2765 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d2);
2766 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2769 Handle(Geom2d_Curve) H1;
2770 aCurve.SetFirstCurve2d(H1);
2773 theSeqOfCurve.Append(aCurve);
2777 //=======================================================================
2778 //function : ClassifyLin2d
2780 //=======================================================================
2781 static inline Standard_Boolean INTER(const Standard_Real d1,
2782 const Standard_Real d2,
2783 const Standard_Real tol)
2785 return (d1 > tol && d2 < -tol) ||
2786 (d1 < -tol && d2 > tol) ||
2787 ((d1 <= tol && d1 >= -tol) && (d2 > tol || d2 < -tol)) ||
2788 ((d2 <= tol && d2 >= -tol) && (d1 > tol || d1 < -tol));
2790 static inline Standard_Boolean COINC(const Standard_Real d1,
2791 const Standard_Real d2,
2792 const Standard_Real tol)
2794 return (d1 <= tol && d1 >= -tol) && (d2 <= tol && d2 >= -tol);
2796 Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
2797 const gp_Lin2d& theLin2d,
2798 const Standard_Real theTol,
2799 Standard_Real& theP1,
2800 Standard_Real& theP2)
2803 Standard_Real xmin, xmax, ymin, ymax, d1, d2, A, B, C;
2804 Standard_Real par[2];
2805 Standard_Integer nbi = 0;
2807 xmin = theS->Surface().FirstUParameter();
2808 xmax = theS->Surface().LastUParameter();
2809 ymin = theS->Surface().FirstVParameter();
2810 ymax = theS->Surface().LastVParameter();
2812 theLin2d.Coefficients(A, B, C);
2814 //xmin, ymin <-> xmin, ymax
2815 d1 = A*xmin + B*ymin + C;
2816 d2 = A*xmin + B*ymax + C;
2818 if(INTER(d1, d2, theTol)) {
2819 //Intersection with boundary
2820 Standard_Real y = -(C + A*xmin)/B;
2821 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, y));
2824 else if (COINC(d1, d2, theTol)) {
2825 //Coincidence with boundary
2826 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2827 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2833 if(fabs(par[0]-par[1]) > theTol) {
2834 theP1 = Min(par[0], par[1]);
2835 theP2 = Max(par[0], par[1]);
2836 return Standard_True;
2838 else return Standard_False;
2842 //xmin, ymax <-> xmax, ymax
2844 d2 = A*xmax + B*ymax + C;
2846 if(d1 > theTol || d1 < -theTol) {//to avoid checking of
2847 //coincidence with the same point
2848 if(INTER(d1, d2, theTol)) {
2849 Standard_Real x = -(C + B*ymax)/A;
2850 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymax));
2853 else if (COINC(d1, d2, theTol)) {
2854 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2855 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2862 if(fabs(par[0]-par[1]) > theTol) {
2863 theP1 = Min(par[0], par[1]);
2864 theP2 = Max(par[0], par[1]);
2865 return Standard_True;
2867 else return Standard_False;
2871 //xmax, ymax <-> xmax, ymin
2873 d2 = A*xmax + B*ymin + C;
2875 if(d1 > theTol || d1 < -theTol) {
2876 if(INTER(d1, d2, theTol)) {
2877 Standard_Real y = -(C + A*xmax)/B;
2878 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, y));
2881 else if (COINC(d1, d2, theTol)) {
2882 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2883 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2889 if(fabs(par[0]-par[1]) > theTol) {
2890 theP1 = Min(par[0], par[1]);
2891 theP2 = Max(par[0], par[1]);
2892 return Standard_True;
2894 else return Standard_False;
2897 //xmax, ymin <-> xmin, ymin
2899 d2 = A*xmin + B*ymin + C;
2901 if(d1 > theTol || d1 < -theTol) {
2902 if(INTER(d1, d2, theTol)) {
2903 Standard_Real x = -(C + B*ymin)/A;
2904 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymin));
2907 else if (COINC(d1, d2, theTol)) {
2908 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2909 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2915 if(fabs(par[0]-par[1]) > theTol) {
2916 theP1 = Min(par[0], par[1]);
2917 theP2 = Max(par[0], par[1]);
2918 return Standard_True;
2920 else return Standard_False;
2923 return Standard_False;
2927 //=======================================================================
2928 //function : ApproxParameters
2930 //=======================================================================
2931 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
2932 const Handle(GeomAdaptor_HSurface)& aHS2,
2933 Standard_Integer& iDegMin,
2934 Standard_Integer& iDegMax,
2935 Standard_Integer& iNbIter)
2938 GeomAbs_SurfaceType aTS1, aTS2;
2945 aTS1=aHS1->Surface().GetType();
2946 aTS2=aHS2->Surface().GetType();
2949 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2950 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2951 Standard_Real aRC, aRT, dR, aPC;
2952 gp_Cylinder aCylinder;
2955 aPC=Precision::Confusion();
2957 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2958 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
2960 aRC=aCylinder.Radius();
2961 aRT=aTorus.MinorRadius();
2971 if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
2975 //=======================================================================
2976 //function : Tolerances
2978 //=======================================================================
2979 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
2980 const Handle(GeomAdaptor_HSurface)& aHS2,
2981 Standard_Real& aTolTang)
2983 GeomAbs_SurfaceType aTS1, aTS2;
2985 aTS1=aHS1->Surface().GetType();
2986 aTS2=aHS2->Surface().GetType();
2989 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2990 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2991 Standard_Real aRC, aRT, dR, aPC;
2992 gp_Cylinder aCylinder;
2995 aPC=Precision::Confusion();
2997 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2998 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
3000 aRC=aCylinder.Radius();
3001 aRT=aTorus.MinorRadius();
3008 aTolTang=0.1*aTolTang;
3012 //=======================================================================
3013 //function : SortTypes
3015 //=======================================================================
3016 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
3017 const GeomAbs_SurfaceType aType2)
3019 Standard_Boolean bRet;
3020 Standard_Integer aI1, aI2;
3022 bRet=Standard_False;
3024 aI1=IndexType(aType1);
3025 aI2=IndexType(aType2);
3031 //=======================================================================
3032 //function : IndexType
3034 //=======================================================================
3035 Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
3037 Standard_Integer aIndex;
3041 if (aType==GeomAbs_Plane) {
3044 else if (aType==GeomAbs_Cylinder) {
3047 else if (aType==GeomAbs_Cone) {
3050 else if (aType==GeomAbs_Sphere) {
3053 else if (aType==GeomAbs_Torus) {
3056 else if (aType==GeomAbs_BezierSurface) {
3059 else if (aType==GeomAbs_BSplineSurface) {
3062 else if (aType==GeomAbs_SurfaceOfRevolution) {
3065 else if (aType==GeomAbs_SurfaceOfExtrusion) {
3068 else if (aType==GeomAbs_OffsetSurface) {
3071 else if (aType==GeomAbs_OtherSurface) {
3076 #ifdef OCCT_DEBUG_DUMPWLINE
3077 //=======================================================================
3078 //function : DumpWLine
3080 //=======================================================================
3081 void DumpWLine(const Handle(IntPatch_WLine)& aWLine)
3083 Standard_Integer i, aNbPnts;
3084 Standard_Real aX, aY, aZ, aU1, aV1, aU2, aV2;
3086 printf(" *WLine\n");
3087 aNbPnts=aWLine->NbPnts();
3088 for (i=1; i<=aNbPnts; ++i) {
3089 const IntSurf_PntOn2S aPntOn2S=aWLine->Point(i);
3090 const gp_Pnt& aP3D=aPntOn2S.Value();
3091 aP3D.Coord(aX, aY, aZ);
3092 aPntOn2S.Parameters(aU1, aV1, aU2, aV2);
3094 printf("point p_%d %lf %lf %lf\n", i, aX, aY, aZ);
3095 //printf("point p_%d %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf\n",
3096 // i, aX, aY, aZ, aU1, aV1, aU2, aV2);
3101 //=======================================================================
3102 // Function : FindMaxDistance
3104 //=======================================================================
3105 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
3106 const Standard_Real theFirst,
3107 const Standard_Real theLast,
3108 const TopoDS_Face& theFace,
3109 const Handle(IntTools_Context)& theContext)
3111 Standard_Integer aNbS;
3112 Standard_Real aT1, aT2, aDt, aD, aDMax, anEps;
3115 aDt = (theLast - theFirst) / aNbS;
3117 anEps = 1.e-4 * aDt;
3119 GeomAPI_ProjectPointOnSurf& aProjPS = theContext->ProjPS(theFace);
3125 if (aT2 > theLast) {
3129 aD = FindMaxDistance(theCurve, aT1, aT2, aProjPS, anEps);
3138 //=======================================================================
3139 // Function : FindMaxDistance
3141 //=======================================================================
3142 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
3143 const Standard_Real theFirst,
3144 const Standard_Real theLast,
3145 GeomAPI_ProjectPointOnSurf& theProjPS,
3146 const Standard_Real theEps)
3148 Standard_Real aA, aB, aCf, aX, aX1, aX2, aF1, aF2, aF;
3150 aCf = 0.61803398874989484820458683436564;//(sqrt(5.)-1)/2.;
3154 aX1 = aB - aCf * (aB - aA);
3155 aF1 = MaxDistance(theC, aX1, theProjPS);
3156 aX2 = aA + aCf * (aB - aA);
3157 aF2 = MaxDistance(theC, aX2, theProjPS);
3160 if ((aB - aA) < theEps) {
3168 aX1 = aB - aCf * (aB - aA);
3169 aF1 = MaxDistance(theC, aX1, theProjPS);
3175 aX2 = aA + aCf * (aB - aA);
3176 aF2 = MaxDistance(theC, aX2, theProjPS);
3180 aX = 0.5 * (aA + aB);
3181 aF = MaxDistance(theC, aX, theProjPS);
3194 //=======================================================================
3195 // Function : MaxDistance
3197 //=======================================================================
3198 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
3199 const Standard_Real aT,
3200 GeomAPI_ProjectPointOnSurf& theProjPS)
3206 theProjPS.Perform(aP);
3207 aD = theProjPS.NbPoints() ? theProjPS.LowerDistance() : 0.;
3212 //=======================================================================
3213 //function : CheckPCurve
3214 //purpose : Checks if points of the pcurve are out of the face bounds.
3215 //=======================================================================
3216 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
3217 const TopoDS_Face& aFace)
3219 const Standard_Integer NPoints = 23;
3221 Standard_Real umin,umax,vmin,vmax;
3223 BRepTools::UVBounds(aFace, umin, umax, vmin, vmax);
3224 Standard_Real tolU = Max ((umax-umin)*0.01, Precision::Confusion());
3225 Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
3226 Standard_Real fp = aPC->FirstParameter();
3227 Standard_Real lp = aPC->LastParameter();
3230 // adjust domain for periodic surfaces
3231 TopLoc_Location aLoc;
3232 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
3233 if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
3234 aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
3236 gp_Pnt2d pnt = aPC->Value((fp+lp)/2);
3240 if (aSurf->IsUPeriodic()) {
3241 Standard_Real aPer = aSurf->UPeriod();
3242 Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer);
3243 if (u < umin+aPer*nshift) nshift--;
3244 umin += aPer*nshift;
3245 umax += aPer*nshift;
3247 if (aSurf->IsVPeriodic()) {
3248 Standard_Real aPer = aSurf->VPeriod();
3249 Standard_Integer nshift = (Standard_Integer) ((v-vmin)/aPer);
3250 if (v < vmin+aPer*nshift) nshift--;
3251 vmin += aPer*nshift;
3252 vmax += aPer*nshift;
3255 //--------------------------------------------------------
3256 Standard_Boolean bRet;
3257 Standard_Integer j, aNbIntervals;
3258 Standard_Real aT, dT;
3261 Geom2dAdaptor_Curve aGAC(aPC);
3262 aNbIntervals=aGAC.NbIntervals(GeomAbs_CN);
3264 TColStd_Array1OfReal aTI(1, aNbIntervals+1);
3265 aGAC.Intervals(aTI,GeomAbs_CN);
3267 bRet=Standard_False;
3269 aT=aGAC.FirstParameter();
3270 for (j=1; j<=aNbIntervals; ++j) {
3271 dT=(aTI(j+1)-aTI(j))/NPoints;
3273 for (i=1; i<NPoints; i++) {
3277 if (umin-u > tolU || u-umax > tolU ||
3278 vmin-v > tolV || v-vmax > tolV) {
3285 //=======================================================================
3286 //function : CorrectPlaneBoundaries
3288 //=======================================================================
3289 void CorrectPlaneBoundaries(Standard_Real& aUmin,
3290 Standard_Real& aUmax,
3291 Standard_Real& aVmin,
3292 Standard_Real& aVmax)
3294 if (!(Precision::IsInfinite(aUmin) ||
3295 Precision::IsInfinite(aUmax))) {
3298 dU=0.1*(aUmax-aUmin);
3302 if (!(Precision::IsInfinite(aVmin) ||
3303 Precision::IsInfinite(aVmax))) {
3306 dV=0.1*(aVmax-aVmin);