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 TolR3d(const Standard_Real aTolF1,
60 const Standard_Real aTolF2,
61 Standard_Real& myTolReached3d);
64 void Parameters(const Handle(GeomAdaptor_HSurface)&,
65 const Handle(GeomAdaptor_HSurface)&,
73 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
74 const Standard_Real theTolerance,
75 Standard_Real& theumin,
76 Standard_Real& theumax,
77 Standard_Real& thevmin,
78 Standard_Real& thevmax);
81 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
82 const Handle(Geom_Curve)& theCurve,
83 const TopoDS_Face& theFace1,
84 const TopoDS_Face& theFace2,
85 const Standard_Real theOtherParameter,
86 const Standard_Boolean bIncreasePar,
87 const Standard_Real theTol,
88 Standard_Real& theNewParameter,
89 const Handle(IntTools_Context)& );
92 Standard_Boolean IsCurveValid(const Handle(Geom2d_Curve)& thePCurve);
95 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
96 const gp_Sphere& theSph);
98 static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
99 const Handle(GeomAdaptor_HSurface)& theS2,
100 const Standard_Real TolF1,
101 const Standard_Real TolF2,
102 const Standard_Real TolAng,
103 const Standard_Real TolTang,
104 const Standard_Boolean theApprox1,
105 const Standard_Boolean theApprox2,
106 IntTools_SequenceOfCurves& theSeqOfCurve,
107 Standard_Boolean& theTangentFaces,
108 Standard_Real& TolReached3d);
110 static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
111 const gp_Lin2d& theLin2d,
112 const Standard_Real theTol,
113 Standard_Real& theP1,
114 Standard_Real& theP2);
117 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
118 const Handle(GeomAdaptor_HSurface)& aHS2,
119 Standard_Integer& iDegMin,
120 Standard_Integer& iNbIter,
121 Standard_Integer& iDegMax);
124 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
125 const Handle(GeomAdaptor_HSurface)& aHS2,
126 Standard_Real& aTolTang);
129 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
130 const GeomAbs_SurfaceType aType2);
132 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
136 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
137 const TopoDS_Face& aFace,
138 const Handle(IntTools_Context)& theCtx);
141 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
142 const Standard_Real aT,
143 GeomAPI_ProjectPointOnSurf& theProjPS);
146 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
147 const Standard_Real theFirst,
148 const Standard_Real theLast,
149 GeomAPI_ProjectPointOnSurf& theProjPS,
150 const Standard_Real theEps);
153 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
154 const Standard_Real theFirst,
155 const Standard_Real theLast,
156 const TopoDS_Face& theFace,
157 const Handle(IntTools_Context)& theContext);
160 void CorrectPlaneBoundaries(Standard_Real& aUmin,
161 Standard_Real& aUmax,
162 Standard_Real& aVmin,
163 Standard_Real& aVmax);
165 //=======================================================================
168 //=======================================================================
169 IntTools_FaceFace::IntTools_FaceFace()
171 myIsDone=Standard_False;
172 myTangentFaces=Standard_False;
174 myHS1 = new GeomAdaptor_HSurface ();
175 myHS2 = new GeomAdaptor_HSurface ();
182 myFuzzyValue = Precision::Confusion();
183 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
185 //=======================================================================
186 //function : SetContext
188 //=======================================================================
189 void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
193 //=======================================================================
196 //=======================================================================
197 const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
201 //=======================================================================
204 //=======================================================================
205 const TopoDS_Face& IntTools_FaceFace::Face1() const
209 //=======================================================================
212 //=======================================================================
213 const TopoDS_Face& IntTools_FaceFace::Face2() const
217 //=======================================================================
218 //function : TangentFaces
220 //=======================================================================
221 Standard_Boolean IntTools_FaceFace::TangentFaces() const
223 return myTangentFaces;
225 //=======================================================================
228 //=======================================================================
229 const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
233 //=======================================================================
236 //=======================================================================
237 Standard_Boolean IntTools_FaceFace::IsDone() const
241 //=======================================================================
242 //function : TolReached3d
244 //=======================================================================
245 Standard_Real IntTools_FaceFace::TolReached3d() const
247 return myTolReached3d;
249 //=======================================================================
252 //=======================================================================
253 Standard_Real IntTools_FaceFace::TolReal() const
257 //=======================================================================
259 //purpose : return lines of intersection
260 //=======================================================================
261 const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
263 StdFail_NotDone_Raise_if
265 "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
268 //=======================================================================
269 //function : TolReached2d
271 //=======================================================================
272 Standard_Real IntTools_FaceFace::TolReached2d() const
274 return myTolReached2d;
276 // =======================================================================
277 // function: SetParameters
279 // =======================================================================
280 void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
281 const Standard_Boolean ToApproxC2dOnS1,
282 const Standard_Boolean ToApproxC2dOnS2,
283 const Standard_Real ApproximationTolerance)
285 myApprox = ToApproxC3d;
286 myApprox1 = ToApproxC2dOnS1;
287 myApprox2 = ToApproxC2dOnS2;
288 myTolApprox = ApproximationTolerance;
290 //=======================================================================
291 //function : SetFuzzyValue
293 //=======================================================================
294 void IntTools_FaceFace::SetFuzzyValue(const Standard_Real theFuzz)
296 myFuzzyValue = Max(theFuzz, Precision::Confusion());
298 //=======================================================================
299 //function : FuzzyValue
301 //=======================================================================
302 Standard_Real IntTools_FaceFace::FuzzyValue() const
307 //=======================================================================
310 //=======================================================================
311 void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
313 myListOfPnts = aListOfPnts;
317 static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
318 const BRepAdaptor_Surface& theBAS2,
319 const Standard_Real theTol)
321 const Standard_Real Tolang = 1.e-8;
322 Standard_Real aHigh = 0.0;
324 const GeomAbs_SurfaceType aType1=theBAS1.GetType();
325 const GeomAbs_SurfaceType aType2=theBAS2.GetType();
329 if(aType1 == GeomAbs_Plane)
333 else if(aType2 == GeomAbs_Plane)
339 return Standard_True;
342 if(aType1 == GeomAbs_Cylinder)
344 aS2=theBAS1.Cylinder();
345 const Standard_Real VMin = theBAS1.FirstVParameter();
346 const Standard_Real VMax = theBAS1.LastVParameter();
348 if( Precision::IsNegativeInfinite(VMin) ||
349 Precision::IsPositiveInfinite(VMax))
350 return Standard_True;
354 else if(aType2 == GeomAbs_Cylinder)
356 aS2=theBAS2.Cylinder();
358 const Standard_Real VMin = theBAS2.FirstVParameter();
359 const Standard_Real VMax = theBAS2.LastVParameter();
361 if( Precision::IsNegativeInfinite(VMin) ||
362 Precision::IsPositiveInfinite(VMax))
363 return Standard_True;
369 return Standard_True;
372 IntAna_QuadQuadGeo inter;
373 inter.Perform(aS1,aS2,Tolang,theTol, aHigh);
374 if(inter.TypeInter() == IntAna_Ellipse)
376 const gp_Elips anEl = inter.Ellipse(1);
377 const Standard_Real aMajorR = anEl.MajorRadius();
378 const Standard_Real aMinorR = anEl.MinorRadius();
380 return (aMajorR < 100000.0 * aMinorR);
384 return inter.IsDone();
387 //=======================================================================
389 //purpose : intersect surfaces of the faces
390 //=======================================================================
391 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
392 const TopoDS_Face& aF2)
394 Standard_Boolean RestrictLine = Standard_False;
396 if (myContext.IsNull()) {
397 myContext=new IntTools_Context;
400 mySeqOfCurve.Clear();
404 myIsDone = Standard_False;
410 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(myFace1);
411 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(myFace2);
412 GeomAbs_SurfaceType aType1=aBAS1.GetType();
413 GeomAbs_SurfaceType aType2=aBAS2.GetType();
415 const Standard_Boolean bReverse=SortTypes(aType1, aType2);
420 aType1=aBAS2.GetType();
421 aType2=aBAS1.GetType();
423 if (myListOfPnts.Extent())
425 Standard_Real aU1,aV1,aU2,aV2;
426 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
428 aItP2S.Initialize(myListOfPnts);
429 for (; aItP2S.More(); aItP2S.Next())
431 IntSurf_PntOn2S& aP2S=aItP2S.Value();
432 aP2S.Parameters(aU1,aV1,aU2,aV2);
433 aP2S.SetValue(aU2,aV2,aU1,aV1);
437 Standard_Boolean anAproxTmp = myApprox1;
438 myApprox1 = myApprox2;
439 myApprox2 = anAproxTmp;
443 const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
444 const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
446 Standard_Real aFuzz = myFuzzyValue / 2.;
447 myTolF1 = BRep_Tool::Tolerance(myFace1) + aFuzz;
448 myTolF2 = BRep_Tool::Tolerance(myFace2) + aFuzz;
449 myTol = myTolF1 + myTolF2;
451 Standard_Real TolArc = myTol;
452 Standard_Real TolTang = TolArc;
454 const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
455 aType1 == GeomAbs_Cone ||
456 aType1 == GeomAbs_Torus);
458 const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
459 aType2 == GeomAbs_Cone ||
460 aType2 == GeomAbs_Torus);
462 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
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 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
471 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
473 Standard_Real TolAng = 1.e-8;
475 PerformPlanes(myHS1, myHS2,
476 myTolF1, myTolF2, TolAng, TolTang,
477 myApprox1, myApprox2,
478 mySeqOfCurve, myTangentFaces, myTolReached3d);
480 myIsDone = Standard_True;
482 if(!myTangentFaces) {
483 const Standard_Integer NbLinPP = mySeqOfCurve.Length();
485 Standard_Real aTolFMax;
486 aTolFMax=Max(myTolF1, myTolF2);
487 myTolReal = Precision::Confusion();
488 if (aTolFMax > myTolReal) {
489 myTolReal = aTolFMax;
491 if (aTolFMax > myTolReached3d) {
492 myTolReached3d = aTolFMax;
495 myTolReached2d = myTolReal;
498 Handle(Geom2d_Curve) aC2D1, aC2D2;
499 const Standard_Integer aNbLin = mySeqOfCurve.Length();
500 for (Standard_Integer i = 1; i <= aNbLin; ++i) {
501 IntTools_Curve& aIC=mySeqOfCurve(i);
502 aC2D1=aIC.FirstCurve2d();
503 aC2D2=aIC.SecondCurve2d();
504 aIC.SetFirstCurve2d(aC2D2);
505 aIC.SetSecondCurve2d(aC2D1);
511 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
513 if ((aType1==GeomAbs_Plane) && isFace2Quad)
515 Standard_Real umin, umax, vmin, vmax;
517 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
518 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
519 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
521 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
522 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
523 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
525 else if ((aType2==GeomAbs_Plane) && isFace1Quad)
527 Standard_Real umin, umax, vmin, vmax;
529 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
530 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
531 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
533 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
534 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
535 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
539 Standard_Real umin, umax, vmin, vmax;
540 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
541 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
542 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
543 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
544 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
545 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
548 const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
549 const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
551 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
554 Tolerances(myHS1, myHS2, TolTang);
557 const Standard_Real UVMaxStep = 0.001;
558 const Standard_Real Deflection = 0.1;
559 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
562 if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
563 (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
564 (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
565 (myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
567 RestrictLine = Standard_True;
570 if((aType1 != GeomAbs_BSplineSurface) &&
571 (aType1 != GeomAbs_BezierSurface) &&
572 (aType1 != GeomAbs_OtherSurface) &&
573 (aType2 != GeomAbs_BSplineSurface) &&
574 (aType2 != GeomAbs_BezierSurface) &&
575 (aType2 != GeomAbs_OtherSurface))
577 RestrictLine = Standard_True;
579 if ((aType1 == GeomAbs_Torus) ||
580 (aType2 == GeomAbs_Torus))
582 myListOfPnts.Clear();
589 TopExp_Explorer aExp;
590 for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
592 const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
593 aExp.Init(aF, TopAbs_EDGE);
594 for(; aExp.More(); aExp.Next())
596 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
598 if(BRep_Tool::Degenerated(aE))
600 RestrictLine = Standard_True;
607 #ifdef INTTOOLS_FACEFACE_DEBUG
608 if(!myListOfPnts.IsEmpty()) {
610 const IntSurf_PntOn2S& aPt = myListOfPnts.First();
611 Standard_Real u1, v1, u2, v2;
612 aPt.Parameters(u1, v1, u2, v2);
614 Sprintf(aBuff,"bopcurves <face1 face2> -2d");
615 IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);
616 for(;IterLOP1.More(); IterLOP1.Next())
618 const IntSurf_PntOn2S& aPt = IterLOP1.Value();
619 Standard_Real u1, v1, u2, v2;
620 aPt.Parameters(u1, v1, u2, v2);
622 Sprintf(aBuff, "%s -p %+10.20f %+10.20f %+10.20f %+10.20f", aBuff, u1, v1, u2, v2);
625 cout << aBuff << endl;
629 const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol);
630 myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
631 myListOfPnts, RestrictLine, isGeomInt);
633 myIsDone = myIntersector.IsDone();
637 myTangentFaces=myIntersector.TangentFaces();
638 if (myTangentFaces) {
643 myListOfPnts.Clear(); // to use LineConstructor
646 const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
647 for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
648 MakeCurve(i, dom1, dom2, TolArc);
651 ComputeTolReached3d();
654 Handle(Geom2d_Curve) aC2D1, aC2D2;
656 const Standard_Integer aNbLinSeqOfCurve =mySeqOfCurve.Length();
657 for (Standard_Integer i=1; i<=aNbLinSeqOfCurve; ++i)
659 IntTools_Curve& aIC=mySeqOfCurve(i);
660 aC2D1=aIC.FirstCurve2d();
661 aC2D2=aIC.SecondCurve2d();
662 aIC.SetFirstCurve2d(aC2D2);
663 aIC.SetSecondCurve2d(aC2D1);
668 Standard_Boolean bValid2D1, bValid2D2;
669 Standard_Real U1,V1,U2,V2;
670 IntTools_PntOnFace aPntOnF1, aPntOnF2;
671 IntTools_PntOn2Faces aPntOn2Faces;
673 const Standard_Integer aNbPnts = myIntersector.NbPnts();
674 for (Standard_Integer i=1; i <= aNbPnts; ++i)
676 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
677 const gp_Pnt& aPnt=aISPnt.Value();
678 aISPnt.Parameters(U1,V1,U2,V2);
680 // check the validity of the intersection point for the faces
681 bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
686 bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
691 // add the intersection point
692 aPntOnF1.Init(myFace1, aPnt, U1, V1);
693 aPntOnF2.Init(myFace2, aPnt, U2, V2);
697 aPntOn2Faces.SetP1(aPntOnF1);
698 aPntOn2Faces.SetP2(aPntOnF2);
702 aPntOn2Faces.SetP2(aPntOnF1);
703 aPntOn2Faces.SetP1(aPntOnF2);
706 myPnts.Append(aPntOn2Faces);
711 //=======================================================================
712 //function : ComputeTolerance
714 //=======================================================================
715 Standard_Real IntTools_FaceFace::ComputeTolerance()
717 Standard_Integer i, j, aNbLin;
718 Standard_Real aFirst, aLast, aD, aDMax, aT;
719 Handle(Geom_Surface) aS1, aS2;
722 aNbLin = mySeqOfCurve.Length();
724 aS1 = myHS1->ChangeSurface().Surface();
725 aS2 = myHS2->ChangeSurface().Surface();
727 for (i = 1; i <= aNbLin; ++i)
729 const IntTools_Curve& aIC = mySeqOfCurve(i);
730 const Handle(Geom_Curve)& aC3D = aIC.Curve();
736 aFirst = aC3D->FirstParameter();
737 aLast = aC3D->LastParameter();
739 const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
740 const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
742 for (j = 0; j < 2; ++j)
744 const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
745 const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
749 if (IntTools_Tools::ComputeTolerance
750 (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
760 const TopoDS_Face& aF = !j ? myFace1 : myFace2;
761 aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
773 //=======================================================================
774 //function :ComputeTolReached3d
776 //=======================================================================
777 void IntTools_FaceFace::ComputeTolReached3d()
779 Standard_Integer aNbLin;
780 GeomAbs_SurfaceType aType1, aType2;
782 aNbLin=myIntersector.NbLines();
787 aType1=myHS1->Surface().GetType();
788 aType2=myHS2->Surface().GetType();
790 if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder)
794 Handle(IntPatch_Line) aIL1, aIL2;
795 IntPatch_IType aTL1, aTL2;
797 aIL1=myIntersector.Line(1);
798 aIL2=myIntersector.Line(2);
799 aTL1=aIL1->ArcType();
800 aTL2=aIL2->ArcType();
801 if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
802 Standard_Real aD, aDTresh, dTol;
808 aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
809 aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
810 aD=aL1.Distance(aL2);
813 {//In order to avoid creation too thin face
814 myTolReached3d=aD+dTol;
818 }// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
821 Standard_Real aDMax = ComputeTolerance();
822 if (aDMax > myTolReached3d)
824 myTolReached3d = aDMax;
826 myTolReal = myTolReached3d;
829 //=======================================================================
830 //function : MakeCurve
832 //=======================================================================
833 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
834 const Handle(Adaptor3d_TopolTool)& dom1,
835 const Handle(Adaptor3d_TopolTool)& dom2,
836 const Standard_Real theToler)
838 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
839 Standard_Boolean ok, bPCurvesOk;
840 Standard_Integer i, j, aNbParts;
841 Standard_Real fprm, lprm;
843 Handle(IntPatch_Line) L;
845 Handle(Geom_Curve) newc;
847 const Standard_Real TOLCHECK =0.0000001;
848 const Standard_Real TOLANGCHECK=0.1;
850 rejectSurface = Standard_False;
851 reApprox = Standard_False;
853 bPCurvesOk = Standard_True;
858 bAvoidLineConstructor = Standard_False;
859 L = myIntersector.Line(Index);
862 if(typl==IntPatch_Walking) {
863 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
864 if(aWLine.IsNull()) {
869 Standard_Integer nbp = aWLine->NbPnts();
870 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
871 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
873 const gp_Pnt& P1 = p1.Value();
874 const gp_Pnt& P2 = p2.Value();
876 if(P1.SquareDistance(P2) < 1.e-14) {
877 bAvoidLineConstructor = Standard_False;
883 if(typl == IntPatch_Restriction)
884 bAvoidLineConstructor = Standard_True;
888 if(!bAvoidLineConstructor) {
889 myLConstruct.Perform(L);
891 bDone=myLConstruct.IsDone();
897 if(typl != IntPatch_Restriction)
899 aNbParts=myLConstruct.NbParts();
910 //########################################
911 // Line, Parabola, Hyperbola
912 //########################################
914 case IntPatch_Parabola:
915 case IntPatch_Hyperbola: {
916 if (typl == IntPatch_Lin) {
918 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
921 else if (typl == IntPatch_Parabola) {
923 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
926 else if (typl == IntPatch_Hyperbola) {
928 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
932 if (typl == IntPatch_Lin) {
933 TolR3d (myTolF1, myTolF2, myTolReached3d);
936 aNbParts=myLConstruct.NbParts();
937 for (i=1; i<=aNbParts; i++) {
938 Standard_Boolean bFNIt, bLPIt;
940 myLConstruct.Part(i, fprm, lprm);
942 bFNIt=Precision::IsNegativeInfinite(fprm);
943 bLPIt=Precision::IsPositiveInfinite(lprm);
945 if (!bFNIt && !bLPIt) {
947 IntTools_Curve aCurve;
949 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
950 aCurve.SetCurve(aCT3D);
951 if (typl == IntPatch_Parabola) {
952 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, myTol);
955 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
957 Handle (Geom2d_Curve) C2d;
958 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
959 myHS1->ChangeSurface().Surface(), newc, C2d);
960 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
961 myTolReached2d=Tolpc;
964 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
967 Handle(Geom2d_BSplineCurve) H1;
969 aCurve.SetFirstCurve2d(H1);
973 Handle (Geom2d_Curve) C2d;
974 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
975 myHS2->ChangeSurface().Surface(), newc, C2d);
976 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
977 myTolReached2d=Tolpc;
980 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
983 Handle(Geom2d_BSplineCurve) H1;
985 aCurve.SetSecondCurve2d(H1);
987 mySeqOfCurve.Append(aCurve);
988 } //if (!bFNIt && !bLPIt) {
990 // on regarde si on garde
992 Standard_Real aTestPrm, dT=100.;
995 if (bFNIt && !bLPIt) {
998 else if (!bFNIt && bLPIt) {
1002 // i.e, if (bFNIt && bLPIt)
1003 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
1006 gp_Pnt ptref(newc->Value(aTestPrm));
1008 GeomAbs_SurfaceType typS1 = myHS1->GetType();
1009 GeomAbs_SurfaceType typS2 = myHS2->GetType();
1010 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
1011 typS1 == GeomAbs_OffsetSurface ||
1012 typS1 == GeomAbs_SurfaceOfRevolution ||
1013 typS2 == GeomAbs_SurfaceOfExtrusion ||
1014 typS2 == GeomAbs_OffsetSurface ||
1015 typS2 == GeomAbs_SurfaceOfRevolution) {
1016 Handle(Geom2d_BSplineCurve) H1;
1017 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1021 Standard_Real u1, v1, u2, v2, Tol;
1023 Tol = Precision::Confusion();
1024 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1025 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1027 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1030 Handle(Geom2d_BSplineCurve) H1;
1031 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1034 }// for (i=1; i<=aNbParts; i++) {
1035 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
1038 //########################################
1039 // Circle and Ellipse
1040 //########################################
1041 case IntPatch_Circle:
1042 case IntPatch_Ellipse: {
1044 if (typl == IntPatch_Circle) {
1045 newc = new Geom_Circle
1046 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
1048 else { //IntPatch_Ellipse
1049 newc = new Geom_Ellipse
1050 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
1054 TolR3d (myTolF1, myTolF2, myTolReached3d);
1056 aNbParts=myLConstruct.NbParts();
1058 Standard_Real aPeriod, aNul;
1059 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
1064 for (i=1; i<=aNbParts; i++) {
1065 myLConstruct.Part(i, fprm, lprm);
1067 if (fprm < aNul && lprm > aNul) {
1068 // interval that goes through 0. is divided on two intervals;
1069 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1070 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1072 if((aPeriod - fprm) > Tolpc) {
1073 aSeqFprm.Append(fprm);
1074 aSeqLprm.Append(aPeriod);
1077 gp_Pnt P1 = newc->Value(fprm);
1078 gp_Pnt P2 = newc->Value(aPeriod);
1079 Standard_Real aTolDist = myTol;
1080 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1082 if(P1.Distance(P2) > aTolDist) {
1083 Standard_Real anewpar = fprm;
1085 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
1086 lprm, Standard_False, myTol, anewpar, myContext)) {
1089 aSeqFprm.Append(fprm);
1090 aSeqLprm.Append(aPeriod);
1095 if((lprm - aNul) > Tolpc) {
1096 aSeqFprm.Append(aNul);
1097 aSeqLprm.Append(lprm);
1100 gp_Pnt P1 = newc->Value(aNul);
1101 gp_Pnt P2 = newc->Value(lprm);
1102 Standard_Real aTolDist = myTol;
1103 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1105 if(P1.Distance(P2) > aTolDist) {
1106 Standard_Real anewpar = lprm;
1108 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
1109 fprm, Standard_True, myTol, anewpar, myContext)) {
1112 aSeqFprm.Append(aNul);
1113 aSeqLprm.Append(lprm);
1119 aSeqFprm.Append(fprm);
1120 aSeqLprm.Append(lprm);
1125 aNbParts=aSeqFprm.Length();
1126 for (i=1; i<=aNbParts; i++) {
1130 Standard_Real aRealEpsilon=RealEpsilon();
1131 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
1132 //==============================================
1134 IntTools_Curve aCurve;
1135 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1136 aCurve.SetCurve(aTC3D);
1137 fprm=aTC3D->FirstParameter();
1138 lprm=aTC3D->LastParameter ();
1140 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1142 Handle (Geom2d_Curve) C2d;
1143 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1144 myHS1->ChangeSurface().Surface(), newc, C2d);
1145 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1146 myTolReached2d=Tolpc;
1149 aCurve.SetFirstCurve2d(C2d);
1152 Handle(Geom2d_BSplineCurve) H1;
1153 aCurve.SetFirstCurve2d(H1);
1158 Handle (Geom2d_Curve) C2d;
1159 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1160 myHS2->ChangeSurface().Surface(),newc,C2d);
1161 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1162 myTolReached2d=Tolpc;
1165 aCurve.SetSecondCurve2d(C2d);
1168 Handle(Geom2d_BSplineCurve) H1;
1169 aCurve.SetSecondCurve2d(H1);
1174 Handle(Geom2d_BSplineCurve) H1;
1175 aCurve.SetFirstCurve2d(H1);
1176 aCurve.SetSecondCurve2d(H1);
1178 mySeqOfCurve.Append(aCurve);
1179 //==============================================
1180 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
1183 // on regarde si on garde
1186 // if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1187 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1188 IntTools_Curve aCurve;
1189 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1190 aCurve.SetCurve(aTC3D);
1191 fprm=aTC3D->FirstParameter();
1192 lprm=aTC3D->LastParameter ();
1195 Handle (Geom2d_Curve) C2d;
1196 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1197 myHS1->ChangeSurface().Surface(),newc,C2d);
1198 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1199 myTolReached2d=Tolpc;
1202 aCurve.SetFirstCurve2d(C2d);
1205 Handle(Geom2d_BSplineCurve) H1;
1206 aCurve.SetFirstCurve2d(H1);
1210 Handle (Geom2d_Curve) C2d;
1211 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1212 myHS2->ChangeSurface().Surface(),newc,C2d);
1213 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1214 myTolReached2d=Tolpc;
1217 aCurve.SetSecondCurve2d(C2d);
1220 Handle(Geom2d_BSplineCurve) H1;
1221 aCurve.SetSecondCurve2d(H1);
1223 mySeqOfCurve.Append(aCurve);
1228 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1230 aTwoPIdiv17=2.*M_PI/17.;
1232 for (j=0; j<=17; j++) {
1233 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1234 Tol = Precision::Confusion();
1236 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1237 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1239 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1242 IntTools_Curve aCurve;
1243 aCurve.SetCurve(newc);
1244 //==============================================
1245 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1248 Handle (Geom2d_Curve) C2d;
1249 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1250 myHS1->ChangeSurface().Surface(), newc, C2d);
1251 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1252 myTolReached2d=Tolpc;
1255 aCurve.SetFirstCurve2d(C2d);
1258 Handle(Geom2d_BSplineCurve) H1;
1259 aCurve.SetFirstCurve2d(H1);
1263 Handle (Geom2d_Curve) C2d;
1264 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1265 myHS2->ChangeSurface().Surface(), newc, C2d);
1266 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1267 myTolReached2d=Tolpc;
1270 aCurve.SetSecondCurve2d(C2d);
1274 Handle(Geom2d_BSplineCurve) H1;
1275 aCurve.SetSecondCurve2d(H1);
1277 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1280 Handle(Geom2d_BSplineCurve) H1;
1282 aCurve.SetFirstCurve2d(H1);
1283 aCurve.SetSecondCurve2d(H1);
1285 //==============================================
1287 mySeqOfCurve.Append(aCurve);
1290 }// end of if (ok) {
1291 }// end of for (Standard_Integer j=0; j<=17; j++)
1292 }// end of else { on regarde si on garde
1293 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1294 }// IntPatch_Circle: IntPatch_Ellipse:
1297 case IntPatch_Analytic:
1298 //This case was processed earlier (in IntPatch_Intersection)
1301 case IntPatch_Walking:{
1302 Handle(IntPatch_WLine) WL =
1303 Handle(IntPatch_WLine)::DownCast(L);
1305 #ifdef INTTOOLS_FACEFACE_DEBUG
1310 Standard_Integer ifprm, ilprm;
1314 if(!bAvoidLineConstructor){
1315 aNbParts=myLConstruct.NbParts();
1317 for (i=1; i<=aNbParts; ++i) {
1318 Handle(Geom2d_BSplineCurve) H1, H2;
1319 Handle(Geom_Curve) aBSp;
1321 if(bAvoidLineConstructor) {
1323 ilprm = WL->NbPnts();
1326 myLConstruct.Part(i, fprm, lprm);
1327 ifprm=(Standard_Integer)fprm;
1328 ilprm=(Standard_Integer)lprm;
1332 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1336 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1339 aBSp=GeomInt_IntSS::MakeBSpline(WL, ifprm, ilprm);
1340 IntTools_Curve aIC(aBSp, H1, H2);
1341 mySeqOfCurve.Append(aIC);
1342 }// for (i=1; i<=aNbParts; ++i) {
1343 }// if (!myApprox) {
1346 Standard_Boolean bIsDecomposited;
1347 Standard_Integer nbiter, aNbSeqOfL;
1348 Standard_Real tol2d, aTolApproxImp;
1349 IntPatch_SequenceOfLine aSeqOfL;
1350 GeomInt_WLApprox theapp3d;
1351 Approx_ParametrizationType aParType = Approx_ChordLength;
1353 Standard_Boolean anApprox1 = myApprox1;
1354 Standard_Boolean anApprox2 = myApprox2;
1356 aTolApproxImp=1.e-5;
1357 tol2d = myTolApprox;
1359 GeomAbs_SurfaceType typs1, typs2;
1360 typs1 = myHS1->Surface().GetType();
1361 typs2 = myHS2->Surface().GetType();
1362 Standard_Boolean anWithPC = Standard_True;
1364 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
1366 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
1368 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
1370 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
1374 myTolApprox = aTolApproxImp;//1.e-5;
1375 anApprox1 = Standard_False;
1376 anApprox2 = Standard_False;
1378 tol2d = myTolApprox;
1381 if(myHS1 == myHS2) {
1382 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1383 rejectSurface = Standard_True;
1386 if(reApprox && !rejectSurface)
1387 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1389 Standard_Integer iDegMax, iDegMin, iNbIter;
1391 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1392 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax,
1393 iNbIter, 30, Standard_True, aParType);
1397 Standard_Real aReachedTol = Precision::Confusion();
1398 bIsDecomposited = IntTools_WLineTool::
1399 DecompositionOfWLine(WL,
1405 bAvoidLineConstructor,
1410 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
1411 myTolReached3d = aReachedTol;
1414 aNbSeqOfL=aSeqOfL.Length();
1416 if (bIsDecomposited) {
1422 if (!bAvoidLineConstructor) {
1423 aNbParts=myLConstruct.NbParts();
1428 for(i = 1; i <= nbiter; ++i) {
1429 if(bIsDecomposited) {
1430 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1432 ilprm = WL->NbPnts();
1435 if(bAvoidLineConstructor) {
1437 ilprm = WL->NbPnts();
1440 myLConstruct.Part(i, fprm, lprm);
1441 ifprm = (Standard_Integer)fprm;
1442 ilprm = (Standard_Integer)lprm;
1446 //-- Si une des surfaces est un plan , on approxime en 2d
1447 //-- sur cette surface et on remonte les points 2d en 3d.
1448 if(typs1 == GeomAbs_Plane) {
1449 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1451 else if(typs2 == GeomAbs_Plane) {
1452 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1456 if (myHS1 != myHS2){
1457 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1458 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1460 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1461 Standard_True, aParType);
1463 Standard_Boolean bUseSurfaces;
1464 bUseSurfaces = IntTools_WLineTool::NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1467 rejectSurface = Standard_True;
1469 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1470 Standard_False, aParType);
1475 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1478 if (!theapp3d.IsDone()) {
1479 Handle(Geom2d_BSplineCurve) H1;
1480 Handle(Geom2d_BSplineCurve) H2;
1482 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1485 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1489 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1492 IntTools_Curve aIC(aBSp, H1, H2);
1493 mySeqOfCurve.Append(aIC);
1497 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1498 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1499 myTolReached2d = theapp3d.TolReached2d();
1502 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1503 myTolReached3d = myTolReached2d;
1505 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1506 if (myTolReached3d<1.e-6) {
1507 myTolReached3d = theapp3d.TolReached3d();
1508 myTolReached3d=1.e-6;
1512 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1513 myTolReached3d = theapp3d.TolReached3d();
1516 Standard_Integer aNbMultiCurves, nbpoles;
1517 aNbMultiCurves=theapp3d.NbMultiCurves();
1518 for (j=1; j<=aNbMultiCurves; j++) {
1519 if(typs1 == GeomAbs_Plane) {
1520 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1521 nbpoles = mbspc.NbPoles();
1523 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1524 TColgp_Array1OfPnt tpoles(1,nbpoles);
1526 mbspc.Curve(1,tpoles2d);
1527 const gp_Pln& Pln = myHS1->Surface().Plane();
1529 Standard_Integer ik;
1530 for(ik = 1; ik<= nbpoles; ik++) {
1532 ElSLib::Value(tpoles2d.Value(ik).X(),
1533 tpoles2d.Value(ik).Y(),
1537 Handle(Geom_BSplineCurve) BS =
1538 new Geom_BSplineCurve(tpoles,
1540 mbspc.Multiplicities(),
1542 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1543 Check.FixTangent(Standard_True, Standard_True);
1545 IntTools_Curve aCurve;
1546 aCurve.SetCurve(BS);
1549 Handle(Geom2d_BSplineCurve) BS1 =
1550 new Geom2d_BSplineCurve(tpoles2d,
1552 mbspc.Multiplicities(),
1554 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1555 Check1.FixTangent(Standard_True,Standard_True);
1557 // ############################################
1558 if(!rejectSurface && !reApprox) {
1559 Standard_Boolean isValid = IsCurveValid(BS1);
1561 reApprox = Standard_True;
1565 // ############################################
1566 aCurve.SetFirstCurve2d(BS1);
1569 Handle(Geom2d_BSplineCurve) H1;
1570 aCurve.SetFirstCurve2d(H1);
1574 mbspc.Curve(2, tpoles2d);
1576 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1578 mbspc.Multiplicities(),
1580 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1581 newCheck.FixTangent(Standard_True,Standard_True);
1583 // ###########################################
1584 if(!rejectSurface && !reApprox) {
1585 Standard_Boolean isValid = IsCurveValid(BS2);
1587 reApprox = Standard_True;
1591 // ###########################################
1593 aCurve.SetSecondCurve2d(BS2);
1596 Handle(Geom2d_BSplineCurve) H2;
1598 aCurve.SetSecondCurve2d(H2);
1601 mySeqOfCurve.Append(aCurve);
1603 }//if(typs1 == GeomAbs_Plane) {
1605 else if(typs2 == GeomAbs_Plane)
1607 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1608 nbpoles = mbspc.NbPoles();
1610 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1611 TColgp_Array1OfPnt tpoles(1,nbpoles);
1612 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1613 const gp_Pln& Pln = myHS2->Surface().Plane();
1615 Standard_Integer ik;
1616 for(ik = 1; ik<= nbpoles; ik++) {
1618 ElSLib::Value(tpoles2d.Value(ik).X(),
1619 tpoles2d.Value(ik).Y(),
1624 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1626 mbspc.Multiplicities(),
1628 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1629 Check.FixTangent(Standard_True,Standard_True);
1631 IntTools_Curve aCurve;
1632 aCurve.SetCurve(BS);
1635 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1637 mbspc.Multiplicities(),
1639 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1640 Check1.FixTangent(Standard_True,Standard_True);
1642 // ###########################################
1643 if(!rejectSurface && !reApprox) {
1644 Standard_Boolean isValid = IsCurveValid(BS1);
1646 reApprox = Standard_True;
1650 // ###########################################
1651 bPCurvesOk = CheckPCurve(BS1, myFace2, myContext);
1652 aCurve.SetSecondCurve2d(BS1);
1655 Handle(Geom2d_BSplineCurve) H2;
1656 aCurve.SetSecondCurve2d(H2);
1660 mbspc.Curve(1,tpoles2d);
1661 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1663 mbspc.Multiplicities(),
1665 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
1666 Check2.FixTangent(Standard_True,Standard_True);
1668 // ###########################################
1669 if(!rejectSurface && !reApprox) {
1670 Standard_Boolean isValid = IsCurveValid(BS2);
1672 reApprox = Standard_True;
1676 // ###########################################
1677 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1, myContext);
1678 aCurve.SetFirstCurve2d(BS2);
1681 Handle(Geom2d_BSplineCurve) H1;
1683 aCurve.SetFirstCurve2d(H1);
1686 //if points of the pcurves are out of the faces bounds
1687 //create 3d and 2d curves without approximation
1689 Handle(Geom2d_BSplineCurve) H1, H2;
1690 bPCurvesOk = Standard_True;
1692 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
1695 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1696 bPCurvesOk = CheckPCurve(H1, myFace1, myContext);
1700 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1701 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2, myContext);
1704 //if pcurves created without approximation are out of the
1705 //faces bounds, use approximated 3d and 2d curves
1707 IntTools_Curve aIC(aBSp, H1, H2);
1708 mySeqOfCurve.Append(aIC);
1710 mySeqOfCurve.Append(aCurve);
1713 mySeqOfCurve.Append(aCurve);
1716 }// else if(typs2 == GeomAbs_Plane)
1718 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
1719 Standard_Boolean bIsValid1, bIsValid2;
1720 Handle(Geom_BSplineCurve) BS;
1721 Handle(Geom2d_BSplineCurve) aH2D;
1722 IntTools_Curve aCurve;
1724 bIsValid1=Standard_True;
1725 bIsValid2=Standard_True;
1727 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1728 nbpoles = mbspc.NbPoles();
1729 TColgp_Array1OfPnt tpoles(1,nbpoles);
1730 mbspc.Curve(1,tpoles);
1731 BS=new Geom_BSplineCurve(tpoles,
1733 mbspc.Multiplicities(),
1735 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1736 Check.FixTangent(Standard_True,Standard_True);
1738 aCurve.SetCurve(BS);
1739 aCurve.SetFirstCurve2d(aH2D);
1740 aCurve.SetSecondCurve2d(aH2D);
1744 Handle(Geom2d_BSplineCurve) BS1;
1745 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1746 mbspc.Curve(2,tpoles2d);
1748 BS1=new Geom2d_BSplineCurve(tpoles2d,
1750 mbspc.Multiplicities(),
1752 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
1753 newCheck.FixTangent(Standard_True,Standard_True);
1756 bIsValid1=CheckPCurve(BS1, myFace1, myContext);
1759 aCurve.SetFirstCurve2d(BS1);
1762 Handle(Geom2d_BSplineCurve) BS1;
1763 fprm = BS->FirstParameter();
1764 lprm = BS->LastParameter();
1766 Handle(Geom2d_Curve) C2d;
1767 Standard_Real aTol = myTolApprox;
1768 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1769 myHS1->ChangeSurface().Surface(), BS, C2d);
1770 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1771 aCurve.SetFirstCurve2d(BS1);
1773 } // if(myApprox1) {
1777 Handle(Geom2d_BSplineCurve) BS2;
1778 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1779 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
1780 BS2=new Geom2d_BSplineCurve(tpoles2d,
1782 mbspc.Multiplicities(),
1784 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1785 newCheck.FixTangent(Standard_True,Standard_True);
1788 bIsValid2=CheckPCurve(BS2, myFace2, myContext);
1790 aCurve.SetSecondCurve2d(BS2);
1793 Handle(Geom2d_BSplineCurve) BS2;
1794 fprm = BS->FirstParameter();
1795 lprm = BS->LastParameter();
1797 Handle(Geom2d_Curve) C2d;
1798 Standard_Real aTol = myTolApprox;
1799 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
1800 myHS2->ChangeSurface().Surface(), BS, C2d);
1801 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1802 aCurve.SetSecondCurve2d(BS2);
1805 if (!bIsValid1 || !bIsValid2) {
1806 myTolApprox=aTolApproxImp;//1.e-5;
1807 tol2d = myTolApprox;
1808 reApprox = Standard_True;
1812 mySeqOfCurve.Append(aCurve);
1818 }// case IntPatch_Walking:{
1821 case IntPatch_Restriction:
1823 Handle(IntPatch_RLine) RL =
1824 Handle(IntPatch_RLine)::DownCast(L);
1826 #ifdef INTTOOLS_FACEFACE_DEBUG
1830 Handle(Geom_Curve) aC3d;
1831 Handle(Geom2d_Curve) aC2d1, aC2d2;
1832 Standard_Real aTolReached;
1833 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
1834 aC2d1, aC2d2, aTolReached);
1839 Bnd_Box2d aBox1, aBox2;
1841 const Standard_Real aU1f = myHS1->FirstUParameter(),
1842 aV1f = myHS1->FirstVParameter(),
1843 aU1l = myHS1->LastUParameter(),
1844 aV1l = myHS1->LastVParameter();
1845 const Standard_Real aU2f = myHS2->FirstUParameter(),
1846 aV2f = myHS2->FirstVParameter(),
1847 aU2l = myHS2->LastUParameter(),
1848 aV2l = myHS2->LastVParameter();
1850 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1851 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1852 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1853 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1855 GeomInt_VectorOfReal anArrayOfParameters;
1857 //We consider here that the intersection line is same-parameter-line
1858 anArrayOfParameters.Append(aC3d->FirstParameter());
1859 anArrayOfParameters.Append(aC3d->LastParameter());
1862 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1864 //Intersect with true boundaries. After that, enlarge bounding-boxes in order to
1865 //correct definition, if point on curve is inscribed in the box.
1866 aBox1.Enlarge(theToler);
1867 aBox2.Enlarge(theToler);
1869 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1872 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1874 Standard_Real &aParF = anArrayOfParameters(anInd),
1875 &aParL = anArrayOfParameters(anInd+1);
1877 if((aParL - aParF) <= Precision::PConfusion())
1879 //In order to more precise extending to the boundaries of source curves.
1880 if(anInd < aNbIntersSolutionsm1-1)
1886 const Standard_Real aPar = 0.5*(aParF + aParL);
1889 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1892 aC2d1->D0(aPar, aPt);
1894 if(aBox1.IsOut(aPt))
1898 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1903 aC2d2->D0(aPar, aPt);
1905 if(aBox2.IsOut(aPt))
1909 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1912 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1914 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
1915 mySeqOfCurve.Append(aIC);
1925 //=======================================================================
1926 //function : Parameters
1928 //=======================================================================
1929 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
1930 const Handle(GeomAdaptor_HSurface)& HS2,
1931 const gp_Pnt& Ptref,
1938 IntSurf_Quadric quad1,quad2;
1939 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
1943 quad1.SetValue(HS1->Surface().Plane());
1945 case GeomAbs_Cylinder:
1946 quad1.SetValue(HS1->Surface().Cylinder());
1949 quad1.SetValue(HS1->Surface().Cone());
1951 case GeomAbs_Sphere:
1952 quad1.SetValue(HS1->Surface().Sphere());
1955 quad1.SetValue(HS1->Surface().Torus());
1958 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
1961 typs = HS2->Surface().GetType();
1964 quad2.SetValue(HS2->Surface().Plane());
1966 case GeomAbs_Cylinder:
1967 quad2.SetValue(HS2->Surface().Cylinder());
1970 quad2.SetValue(HS2->Surface().Cone());
1972 case GeomAbs_Sphere:
1973 quad2.SetValue(HS2->Surface().Sphere());
1976 quad2.SetValue(HS2->Surface().Torus());
1979 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
1982 quad1.Parameters(Ptref,U1,V1);
1983 quad2.Parameters(Ptref,U2,V2);
1986 //=======================================================================
1987 //function : MakeBSpline
1989 //=======================================================================
1990 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
1991 const Standard_Integer ideb,
1992 const Standard_Integer ifin)
1994 Standard_Integer i,nbpnt = ifin-ideb+1;
1995 TColgp_Array1OfPnt poles(1,nbpnt);
1996 TColStd_Array1OfReal knots(1,nbpnt);
1997 TColStd_Array1OfInteger mults(1,nbpnt);
1998 Standard_Integer ipidebm1;
1999 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2000 poles(i) = WL->Point(ipidebm1).Value();
2004 mults(1) = mults(nbpnt) = 2;
2006 new Geom_BSplineCurve(poles,knots,mults,1);
2009 //=======================================================================
2010 //function : PrepareLines3D
2012 //=======================================================================
2013 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
2015 Standard_Integer i, aNbCurves;
2016 GeomAbs_SurfaceType aType1, aType2;
2017 IntTools_SequenceOfCurves aNewCvs;
2019 // 1. Treatment closed curves
2020 aNbCurves=mySeqOfCurve.Length();
2021 for (i=1; i<=aNbCurves; ++i) {
2022 const IntTools_Curve& aIC=mySeqOfCurve(i);
2025 Standard_Integer j, aNbC;
2026 IntTools_SequenceOfCurves aSeqCvs;
2028 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2030 for (j=1; j<=aNbC; ++j) {
2031 const IntTools_Curve& aICNew=aSeqCvs(j);
2032 aNewCvs.Append(aICNew);
2036 aNewCvs.Append(aIC);
2040 aNewCvs.Append(aIC);
2044 // 2. Plane\Cone intersection when we had 4 curves
2045 aType1=myHS1->GetType();
2046 aType2=myHS2->GetType();
2047 aNbCurves=aNewCvs.Length();
2049 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2050 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
2052 GeomAbs_CurveType aCType1;
2054 aCType1=aNewCvs(1).Type();
2055 if (aCType1==GeomAbs_Line) {
2056 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2058 for (i=1; i<=aNbCurves; ++i) {
2059 const IntTools_Curve& aIC=aNewCvs(i);
2063 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2066 aNbCurves=aSeqOut.Length();
2067 for (i=1; i<=aNbCurves; ++i) {
2068 const IntTools_Curve& aIC=aSeqOut(i);
2069 aNewCvs.Append(aIC);
2073 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
2075 // 3. Fill mySeqOfCurve
2076 mySeqOfCurve.Clear();
2077 aNbCurves=aNewCvs.Length();
2078 for (i=1; i<=aNbCurves; ++i) {
2079 const IntTools_Curve& aIC=aNewCvs(i);
2080 mySeqOfCurve.Append(aIC);
2083 //=======================================================================
2084 //function : CorrectSurfaceBoundaries
2086 //=======================================================================
2087 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
2088 const Standard_Real theTolerance,
2089 Standard_Real& theumin,
2090 Standard_Real& theumax,
2091 Standard_Real& thevmin,
2092 Standard_Real& thevmax)
2094 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2095 Standard_Real uinf, usup, vinf, vsup, delta;
2096 GeomAbs_SurfaceType aType;
2097 Handle(Geom_Surface) aSurface;
2099 aSurface = BRep_Tool::Surface(theFace);
2100 aSurface->Bounds(uinf, usup, vinf, vsup);
2101 delta = theTolerance;
2102 enlarge = Standard_False;
2104 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2106 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2107 Handle(Geom_Surface) aBasisSurface =
2108 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2110 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2111 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2116 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2117 Handle(Geom_Surface) aBasisSurface =
2118 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2120 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2121 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2126 isuperiodic = anAdaptorSurface.IsUPeriodic();
2127 isvperiodic = anAdaptorSurface.IsVPeriodic();
2129 aType=anAdaptorSurface.GetType();
2130 if((aType==GeomAbs_BezierSurface) ||
2131 (aType==GeomAbs_BSplineSurface) ||
2132 (aType==GeomAbs_SurfaceOfExtrusion) ||
2133 (aType==GeomAbs_SurfaceOfRevolution) ||
2134 (aType==GeomAbs_Cylinder)) {
2135 enlarge=Standard_True;
2138 if(!isuperiodic && enlarge) {
2140 if(!Precision::IsInfinite(theumin) &&
2141 ((theumin - uinf) > delta))
2147 if(!Precision::IsInfinite(theumax) &&
2148 ((usup - theumax) > delta))
2154 if(!isvperiodic && enlarge) {
2155 if(!Precision::IsInfinite(thevmin) &&
2156 ((thevmin - vinf) > delta)) {
2162 if(!Precision::IsInfinite(thevmax) &&
2163 ((vsup - thevmax) > delta)) {
2171 if(isuperiodic || isvperiodic) {
2172 Standard_Boolean correct = Standard_False;
2173 Standard_Boolean correctU = Standard_False;
2174 Standard_Boolean correctV = Standard_False;
2176 TopExp_Explorer anExp;
2178 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2179 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
2180 correct = Standard_True;
2182 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2184 for(Standard_Integer i = 0; i < 2; i++) {
2186 anEdge.Orientation(TopAbs_FORWARD);
2189 anEdge.Orientation(TopAbs_REVERSED);
2191 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2193 if(aCurve.IsNull()) {
2194 correct = Standard_False;
2197 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2199 if(aLine.IsNull()) {
2200 correct = Standard_False;
2203 gp_Dir2d anUDir(1., 0.);
2204 gp_Dir2d aVDir(0., 1.);
2205 Standard_Real anAngularTolerance = Precision::Angular();
2207 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2208 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2210 gp_Pnt2d pp1 = aCurve->Value(f);
2212 gp_Pnt2d pp2 = aCurve->Value(l);
2221 Standard_Real umin, vmin, umax, vmax;
2222 aBox.Get(umin, vmin, umax, vmax);
2224 if(isuperiodic && correctU) {
2227 if(theumax > umax) {
2231 if(isvperiodic && correctV) {
2241 //=======================================================================
2244 //=======================================================================
2245 void TolR3d(const Standard_Real aTolF1,
2246 const Standard_Real aTolF2,
2247 Standard_Real& myTolReached3d)
2249 Standard_Real aTolFMax, aTolTresh;
2251 aTolTresh=2.999999e-3;
2252 aTolFMax=Max(aTolF1, aTolF2);
2254 if (aTolFMax>aTolTresh) {
2255 myTolReached3d=aTolFMax;
2259 // ------------------------------------------------------------------------------------------------
2260 // static function: ParameterOutOfBoundary
2261 // purpose: Computes a new parameter for given curve. The corresponding 2d points
2262 // does not lay on any boundary of given faces
2263 // ------------------------------------------------------------------------------------------------
2264 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
2265 const Handle(Geom_Curve)& theCurve,
2266 const TopoDS_Face& theFace1,
2267 const TopoDS_Face& theFace2,
2268 const Standard_Real theOtherParameter,
2269 const Standard_Boolean bIncreasePar,
2270 const Standard_Real theTol,
2271 Standard_Real& theNewParameter,
2272 const Handle(IntTools_Context)& aContext)
2274 Standard_Boolean bIsComputed = Standard_False;
2275 theNewParameter = theParameter;
2277 Standard_Real acurpar = theParameter;
2278 TopAbs_State aState = TopAbs_ON;
2279 Standard_Integer iter = 0;
2280 Standard_Real asumtol = theTol;
2281 Standard_Real adelta = asumtol * 0.1;
2282 adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
2283 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
2284 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
2286 Standard_Real u1, u2, v1, v2;
2288 GeomAPI_ProjectPointOnSurf aPrj1;
2289 aSurf1->Bounds(u1, u2, v1, v2);
2290 aPrj1.Init(aSurf1, u1, u2, v1, v2);
2292 GeomAPI_ProjectPointOnSurf aPrj2;
2293 aSurf2->Bounds(u1, u2, v1, v2);
2294 aPrj2.Init(aSurf2, u1, u2, v1, v2);
2296 while(aState == TopAbs_ON) {
2301 gp_Pnt aPCurrent = theCurve->Value(acurpar);
2302 aPrj1.Perform(aPCurrent);
2303 Standard_Real U=0., V=0.;
2305 if(aPrj1.IsDone()) {
2306 aPrj1.LowerDistanceParameters(U, V);
2307 aState = aContext->StatePointFace(theFace1, gp_Pnt2d(U, V));
2310 if(aState != TopAbs_ON) {
2311 aPrj2.Perform(aPCurrent);
2313 if(aPrj2.IsDone()) {
2314 aPrj2.LowerDistanceParameters(U, V);
2315 aState = aContext->StatePointFace(theFace2, gp_Pnt2d(U, V));
2326 theNewParameter = acurpar;
2327 bIsComputed = Standard_True;
2330 if(acurpar >= theOtherParameter)
2331 theNewParameter = theOtherParameter;
2334 if(acurpar <= theOtherParameter)
2335 theNewParameter = theOtherParameter;
2341 //=======================================================================
2342 //function : IsCurveValid
2344 //=======================================================================
2345 Standard_Boolean IsCurveValid (const Handle(Geom2d_Curve)& thePCurve)
2347 if(thePCurve.IsNull())
2348 return Standard_False;
2350 Standard_Real tolint = 1.e-10;
2351 Geom2dAdaptor_Curve PCA;
2352 IntRes2d_Domain PCD;
2353 Geom2dInt_GInter PCI;
2355 Standard_Real pf = 0., pl = 0.;
2356 gp_Pnt2d pntf, pntl;
2358 if(!thePCurve->IsClosed() && !thePCurve->IsPeriodic()) {
2359 pf = thePCurve->FirstParameter();
2360 pl = thePCurve->LastParameter();
2361 pntf = thePCurve->Value(pf);
2362 pntl = thePCurve->Value(pl);
2363 PCA.Load(thePCurve);
2364 if(!PCA.IsPeriodic()) {
2365 if(PCA.FirstParameter() > pf) pf = PCA.FirstParameter();
2366 if(PCA.LastParameter() < pl) pl = PCA.LastParameter();
2368 PCD.SetValues(pntf,pf,tolint,pntl,pl,tolint);
2369 PCI.Perform(PCA,PCD,tolint,tolint);
2371 if(PCI.NbPoints() > 0) {
2372 return Standard_False;
2376 return Standard_True;
2379 //=======================================================================
2380 //static function : ApproxWithPCurves
2381 //purpose : for bug 20964 only
2382 //=======================================================================
2383 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
2384 const gp_Sphere& theSph)
2386 Standard_Boolean bRes = Standard_True;
2387 Standard_Real R1 = theCyl.Radius(), R2 = theSph.Radius();
2390 Standard_Real aD2, aRc2, aEps;
2396 const gp_Ax3& aAx3Sph=theSph.Position();
2397 const gp_Pnt& aLocSph=aAx3Sph.Location();
2398 const gp_Dir& aDirSph=aAx3Sph.Direction();
2400 const gp_Ax1& aAx1Cyl=theCyl.Axis();
2401 gp_Lin aLinCyl(aAx1Cyl);
2403 aApexSph.SetXYZ(aLocSph.XYZ()+R2*aDirSph.XYZ());
2404 aD2=aLinCyl.SquareDistance(aApexSph);
2405 if (fabs(aD2-aRc2)<aEps) {
2409 aApexSph.SetXYZ(aLocSph.XYZ()-R2*aDirSph.XYZ());
2410 aD2=aLinCyl.SquareDistance(aApexSph);
2411 if (fabs(aD2-aRc2)<aEps) {
2420 gp_Lin anCylAx(theCyl.Axis());
2422 Standard_Real aDist = anCylAx.Distance(theSph.Location());
2423 Standard_Real aDRel = Abs(aDist - R1)/R2;
2425 if(aDRel > .2) return bRes;
2427 Standard_Real par = ElCLib::Parameter(anCylAx, theSph.Location());
2428 gp_Pnt aP = ElCLib::Value(par, anCylAx);
2429 gp_Vec aV(aP, theSph.Location());
2431 Standard_Real dd = aV.Dot(theSph.Position().XDirection());
2433 if(aDist < R1 && dd > 0.) return Standard_False;
2434 if(aDist > R1 && dd < 0.) return Standard_False;
2439 //=======================================================================
2440 //function : PerformPlanes
2442 //=======================================================================
2443 void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
2444 const Handle(GeomAdaptor_HSurface)& theS2,
2445 const Standard_Real TolF1,
2446 const Standard_Real TolF2,
2447 const Standard_Real TolAng,
2448 const Standard_Real TolTang,
2449 const Standard_Boolean theApprox1,
2450 const Standard_Boolean theApprox2,
2451 IntTools_SequenceOfCurves& theSeqOfCurve,
2452 Standard_Boolean& theTangentFaces,
2453 Standard_Real& TolReached3d)
2456 gp_Pln aPln1 = theS1->Surface().Plane();
2457 gp_Pln aPln2 = theS2->Surface().Plane();
2459 IntAna_QuadQuadGeo aPlnInter(aPln1, aPln2, TolAng, TolTang);
2461 if(!aPlnInter.IsDone()) {
2462 theTangentFaces = Standard_False;
2466 IntAna_ResultType aResType = aPlnInter.TypeInter();
2468 if(aResType == IntAna_Same) {
2469 theTangentFaces = Standard_True;
2473 theTangentFaces = Standard_False;
2475 if(aResType == IntAna_Empty) {
2479 gp_Lin aLin = aPlnInter.Line(1);
2481 ProjLib_Plane aProj;
2484 aProj.Project(aLin);
2485 gp_Lin2d aLin2d1 = aProj.Line();
2488 aProj.Project(aLin);
2489 gp_Lin2d aLin2d2 = aProj.Line();
2491 //classify line2d1 relatively first plane
2492 Standard_Real P11, P12;
2493 Standard_Boolean IsCrossed = ClassifyLin2d(theS1, aLin2d1, TolTang, P11, P12);
2494 if(!IsCrossed) return;
2495 //classify line2d2 relatively second plane
2496 Standard_Real P21, P22;
2497 IsCrossed = ClassifyLin2d(theS2, aLin2d2, TolTang, P21, P22);
2498 if(!IsCrossed) return;
2500 //Analysis of parametric intervals: must have common part
2502 if(P21 >= P12) return;
2503 if(P22 <= P11) return;
2505 Standard_Real pmin, pmax;
2506 pmin = Max(P11, P21);
2507 pmax = Min(P12, P22);
2509 if(pmax - pmin <= TolTang) return;
2511 Handle(Geom_Line) aGLin = new Geom_Line(aLin);
2513 IntTools_Curve aCurve;
2514 Handle(Geom_TrimmedCurve) aGTLin = new Geom_TrimmedCurve(aGLin, pmin, pmax);
2516 aCurve.SetCurve(aGTLin);
2519 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d1);
2520 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2523 Handle(Geom2d_Curve) H1;
2524 aCurve.SetFirstCurve2d(H1);
2527 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d2);
2528 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2531 Handle(Geom2d_Curve) H1;
2532 aCurve.SetFirstCurve2d(H1);
2535 theSeqOfCurve.Append(aCurve);
2537 // computation of the tolerance reached
2538 Standard_Real anAngle, aDt;
2541 aD1 = aPln1.Position().Direction();
2542 aD2 = aPln2.Position().Direction();
2543 anAngle = aD1.Angle(aD2);
2545 aDt = IntTools_Tools::ComputeIntRange(TolF1, TolF2, anAngle);
2546 TolReached3d = sqrt(aDt*aDt + TolF1*TolF1);
2549 //=======================================================================
2550 //function : ClassifyLin2d
2552 //=======================================================================
2553 static inline Standard_Boolean INTER(const Standard_Real d1,
2554 const Standard_Real d2,
2555 const Standard_Real tol)
2557 return (d1 > tol && d2 < -tol) ||
2558 (d1 < -tol && d2 > tol) ||
2559 ((d1 <= tol && d1 >= -tol) && (d2 > tol || d2 < -tol)) ||
2560 ((d2 <= tol && d2 >= -tol) && (d1 > tol || d1 < -tol));
2562 static inline Standard_Boolean COINC(const Standard_Real d1,
2563 const Standard_Real d2,
2564 const Standard_Real tol)
2566 return (d1 <= tol && d1 >= -tol) && (d2 <= tol && d2 >= -tol);
2568 Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
2569 const gp_Lin2d& theLin2d,
2570 const Standard_Real theTol,
2571 Standard_Real& theP1,
2572 Standard_Real& theP2)
2575 Standard_Real xmin, xmax, ymin, ymax, d1, d2, A, B, C;
2576 Standard_Real par[2];
2577 Standard_Integer nbi = 0;
2579 xmin = theS->Surface().FirstUParameter();
2580 xmax = theS->Surface().LastUParameter();
2581 ymin = theS->Surface().FirstVParameter();
2582 ymax = theS->Surface().LastVParameter();
2584 theLin2d.Coefficients(A, B, C);
2586 //xmin, ymin <-> xmin, ymax
2587 d1 = A*xmin + B*ymin + C;
2588 d2 = A*xmin + B*ymax + C;
2590 if(INTER(d1, d2, theTol)) {
2591 //Intersection with boundary
2592 Standard_Real y = -(C + A*xmin)/B;
2593 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, y));
2596 else if (COINC(d1, d2, theTol)) {
2597 //Coincidence with boundary
2598 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2599 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2605 if(fabs(par[0]-par[1]) > theTol) {
2606 theP1 = Min(par[0], par[1]);
2607 theP2 = Max(par[0], par[1]);
2608 return Standard_True;
2610 else return Standard_False;
2614 //xmin, ymax <-> xmax, ymax
2616 d2 = A*xmax + B*ymax + C;
2618 if(d1 > theTol || d1 < -theTol) {//to avoid checking of
2619 //coincidence with the same point
2620 if(INTER(d1, d2, theTol)) {
2621 Standard_Real x = -(C + B*ymax)/A;
2622 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymax));
2625 else if (COINC(d1, d2, theTol)) {
2626 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2627 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2634 if(fabs(par[0]-par[1]) > theTol) {
2635 theP1 = Min(par[0], par[1]);
2636 theP2 = Max(par[0], par[1]);
2637 return Standard_True;
2639 else return Standard_False;
2643 //xmax, ymax <-> xmax, ymin
2645 d2 = A*xmax + B*ymin + C;
2647 if(d1 > theTol || d1 < -theTol) {
2648 if(INTER(d1, d2, theTol)) {
2649 Standard_Real y = -(C + A*xmax)/B;
2650 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, y));
2653 else if (COINC(d1, d2, theTol)) {
2654 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2655 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2661 if(fabs(par[0]-par[1]) > theTol) {
2662 theP1 = Min(par[0], par[1]);
2663 theP2 = Max(par[0], par[1]);
2664 return Standard_True;
2666 else return Standard_False;
2669 //xmax, ymin <-> xmin, ymin
2671 d2 = A*xmin + B*ymin + C;
2673 if(d1 > theTol || d1 < -theTol) {
2674 if(INTER(d1, d2, theTol)) {
2675 Standard_Real x = -(C + B*ymin)/A;
2676 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymin));
2679 else if (COINC(d1, d2, theTol)) {
2680 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2681 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2687 if(fabs(par[0]-par[1]) > theTol) {
2688 theP1 = Min(par[0], par[1]);
2689 theP2 = Max(par[0], par[1]);
2690 return Standard_True;
2692 else return Standard_False;
2695 return Standard_False;
2699 //=======================================================================
2700 //function : ApproxParameters
2702 //=======================================================================
2703 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
2704 const Handle(GeomAdaptor_HSurface)& aHS2,
2705 Standard_Integer& iDegMin,
2706 Standard_Integer& iDegMax,
2707 Standard_Integer& iNbIter)
2710 GeomAbs_SurfaceType aTS1, aTS2;
2717 aTS1=aHS1->Surface().GetType();
2718 aTS2=aHS2->Surface().GetType();
2721 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2722 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2723 Standard_Real aRC, aRT, dR, aPC;
2724 gp_Cylinder aCylinder;
2727 aPC=Precision::Confusion();
2729 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2730 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
2732 aRC=aCylinder.Radius();
2733 aRT=aTorus.MinorRadius();
2743 if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
2747 //=======================================================================
2748 //function : Tolerances
2750 //=======================================================================
2751 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
2752 const Handle(GeomAdaptor_HSurface)& aHS2,
2753 Standard_Real& aTolTang)
2755 GeomAbs_SurfaceType aTS1, aTS2;
2757 aTS1=aHS1->Surface().GetType();
2758 aTS2=aHS2->Surface().GetType();
2761 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2762 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2763 Standard_Real aRC, aRT, dR, aPC;
2764 gp_Cylinder aCylinder;
2767 aPC=Precision::Confusion();
2769 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
2770 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
2772 aRC=aCylinder.Radius();
2773 aRT=aTorus.MinorRadius();
2780 aTolTang=0.1*aTolTang;
2784 //=======================================================================
2785 //function : SortTypes
2787 //=======================================================================
2788 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
2789 const GeomAbs_SurfaceType aType2)
2791 Standard_Boolean bRet;
2792 Standard_Integer aI1, aI2;
2794 bRet=Standard_False;
2796 aI1=IndexType(aType1);
2797 aI2=IndexType(aType2);
2803 //=======================================================================
2804 //function : IndexType
2806 //=======================================================================
2807 Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
2809 Standard_Integer aIndex;
2813 if (aType==GeomAbs_Plane) {
2816 else if (aType==GeomAbs_Cylinder) {
2819 else if (aType==GeomAbs_Cone) {
2822 else if (aType==GeomAbs_Sphere) {
2825 else if (aType==GeomAbs_Torus) {
2828 else if (aType==GeomAbs_BezierSurface) {
2831 else if (aType==GeomAbs_BSplineSurface) {
2834 else if (aType==GeomAbs_SurfaceOfRevolution) {
2837 else if (aType==GeomAbs_SurfaceOfExtrusion) {
2840 else if (aType==GeomAbs_OffsetSurface) {
2843 else if (aType==GeomAbs_OtherSurface) {
2849 //=======================================================================
2850 // Function : FindMaxDistance
2852 //=======================================================================
2853 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
2854 const Standard_Real theFirst,
2855 const Standard_Real theLast,
2856 const TopoDS_Face& theFace,
2857 const Handle(IntTools_Context)& theContext)
2859 Standard_Integer aNbS;
2860 Standard_Real aT1, aT2, aDt, aD, aDMax, anEps;
2863 aDt = (theLast - theFirst) / aNbS;
2865 anEps = 1.e-4 * aDt;
2867 GeomAPI_ProjectPointOnSurf& aProjPS = theContext->ProjPS(theFace);
2873 if (aT2 > theLast) {
2877 aD = FindMaxDistance(theCurve, aT1, aT2, aProjPS, anEps);
2886 //=======================================================================
2887 // Function : FindMaxDistance
2889 //=======================================================================
2890 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
2891 const Standard_Real theFirst,
2892 const Standard_Real theLast,
2893 GeomAPI_ProjectPointOnSurf& theProjPS,
2894 const Standard_Real theEps)
2896 Standard_Real aA, aB, aCf, aX, aX1, aX2, aF1, aF2, aF;
2898 aCf = 0.61803398874989484820458683436564;//(sqrt(5.)-1)/2.;
2902 aX1 = aB - aCf * (aB - aA);
2903 aF1 = MaxDistance(theC, aX1, theProjPS);
2904 aX2 = aA + aCf * (aB - aA);
2905 aF2 = MaxDistance(theC, aX2, theProjPS);
2908 if ((aB - aA) < theEps) {
2916 aX1 = aB - aCf * (aB - aA);
2917 aF1 = MaxDistance(theC, aX1, theProjPS);
2923 aX2 = aA + aCf * (aB - aA);
2924 aF2 = MaxDistance(theC, aX2, theProjPS);
2928 aX = 0.5 * (aA + aB);
2929 aF = MaxDistance(theC, aX, theProjPS);
2942 //=======================================================================
2943 // Function : MaxDistance
2945 //=======================================================================
2946 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
2947 const Standard_Real aT,
2948 GeomAPI_ProjectPointOnSurf& theProjPS)
2954 theProjPS.Perform(aP);
2955 aD = theProjPS.NbPoints() ? theProjPS.LowerDistance() : 0.;
2960 //=======================================================================
2961 //function : CheckPCurve
2962 //purpose : Checks if points of the pcurve are out of the face bounds.
2963 //=======================================================================
2964 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
2965 const TopoDS_Face& aFace,
2966 const Handle(IntTools_Context)& theCtx)
2968 const Standard_Integer NPoints = 23;
2970 Standard_Real umin,umax,vmin,vmax;
2972 theCtx->UVBounds(aFace, umin, umax, vmin, vmax);
2973 Standard_Real tolU = Max ((umax-umin)*0.01, Precision::Confusion());
2974 Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
2975 Standard_Real fp = aPC->FirstParameter();
2976 Standard_Real lp = aPC->LastParameter();
2979 // adjust domain for periodic surfaces
2980 TopLoc_Location aLoc;
2981 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
2982 if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2983 aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
2985 gp_Pnt2d pnt = aPC->Value((fp+lp)/2);
2989 if (aSurf->IsUPeriodic()) {
2990 Standard_Real aPer = aSurf->UPeriod();
2991 Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer);
2992 if (u < umin+aPer*nshift) nshift--;
2993 umin += aPer*nshift;
2994 umax += aPer*nshift;
2996 if (aSurf->IsVPeriodic()) {
2997 Standard_Real aPer = aSurf->VPeriod();
2998 Standard_Integer nshift = (Standard_Integer) ((v-vmin)/aPer);
2999 if (v < vmin+aPer*nshift) nshift--;
3000 vmin += aPer*nshift;
3001 vmax += aPer*nshift;
3004 //--------------------------------------------------------
3005 Standard_Boolean bRet;
3006 Standard_Integer j, aNbIntervals;
3007 Standard_Real aT, dT;
3010 Geom2dAdaptor_Curve aGAC(aPC);
3011 aNbIntervals=aGAC.NbIntervals(GeomAbs_CN);
3013 TColStd_Array1OfReal aTI(1, aNbIntervals+1);
3014 aGAC.Intervals(aTI,GeomAbs_CN);
3016 bRet=Standard_False;
3018 aT=aGAC.FirstParameter();
3019 for (j=1; j<=aNbIntervals; ++j) {
3020 dT=(aTI(j+1)-aTI(j))/NPoints;
3022 for (i=1; i<NPoints; i++) {
3026 if (umin-u > tolU || u-umax > tolU ||
3027 vmin-v > tolV || v-vmax > tolV) {
3034 //=======================================================================
3035 //function : CorrectPlaneBoundaries
3037 //=======================================================================
3038 void CorrectPlaneBoundaries(Standard_Real& aUmin,
3039 Standard_Real& aUmax,
3040 Standard_Real& aVmin,
3041 Standard_Real& aVmax)
3043 if (!(Precision::IsInfinite(aUmin) ||
3044 Precision::IsInfinite(aUmax))) {
3047 dU=0.1*(aUmax-aUmin);
3051 if (!(Precision::IsInfinite(aVmin) ||
3052 Precision::IsInfinite(aVmax))) {
3055 dV=0.1*(aVmax-aVmin);