1 // Created on: 2000-11-23
2 // Created by: Michael KLOKOV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
22 #include <IntTools_FaceFace.ixx>
24 #include <Precision.hxx>
26 #include <TColStd_HArray1OfReal.hxx>
27 #include <TColStd_Array1OfReal.hxx>
28 #include <TColStd_Array1OfInteger.hxx>
29 #include <TColStd_SequenceOfReal.hxx>
30 #include <TColStd_ListOfInteger.hxx>
31 #include <TColStd_ListIteratorOfListOfInteger.hxx>
32 #include <TColStd_Array1OfListOfInteger.hxx>
34 #include <gp_Lin2d.hxx>
35 #include <gp_Ax22d.hxx>
36 #include <gp_Circ2d.hxx>
37 #include <gp_Torus.hxx>
38 #include <gp_Cylinder.hxx>
40 #include <Bnd_Box.hxx>
42 #include <TColgp_HArray1OfPnt2d.hxx>
43 #include <TColgp_SequenceOfPnt2d.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColgp_Array1OfPnt2d.hxx>
47 #include <IntAna_QuadQuadGeo.hxx>
49 #include <IntSurf_PntOn2S.hxx>
50 #include <IntSurf_LineOn2S.hxx>
51 #include <IntSurf_PntOn2S.hxx>
52 #include <IntSurf_ListOfPntOn2S.hxx>
53 #include <IntRes2d_Domain.hxx>
54 #include <ProjLib_Plane.hxx>
56 #include <IntPatch_GLine.hxx>
57 #include <IntPatch_RLine.hxx>
58 #include <IntPatch_WLine.hxx>
59 #include <IntPatch_ALine.hxx>
60 #include <IntPatch_ALineToWLine.hxx>
65 #include <Extrema_ExtCC.hxx>
66 #include <Extrema_POnCurv.hxx>
67 #include <BndLib_AddSurface.hxx>
69 #include <Adaptor3d_SurfacePtr.hxx>
70 #include <Adaptor2d_HLine2d.hxx>
72 #include <GeomAbs_SurfaceType.hxx>
73 #include <GeomAbs_CurveType.hxx>
75 #include <Geom_Surface.hxx>
76 #include <Geom_Line.hxx>
77 #include <Geom_Circle.hxx>
78 #include <Geom_Ellipse.hxx>
79 #include <Geom_Parabola.hxx>
80 #include <Geom_Hyperbola.hxx>
81 #include <Geom_TrimmedCurve.hxx>
82 #include <Geom_BSplineCurve.hxx>
83 #include <Geom_RectangularTrimmedSurface.hxx>
84 #include <Geom_OffsetSurface.hxx>
85 #include <Geom_Curve.hxx>
86 #include <Geom_Conic.hxx>
88 #include <Geom2d_TrimmedCurve.hxx>
89 #include <Geom2d_BSplineCurve.hxx>
90 #include <Geom2d_Line.hxx>
91 #include <Geom2d_Curve.hxx>
92 #include <Geom2d_Circle.hxx>
94 #include <Geom2dAPI_InterCurveCurve.hxx>
95 #include <Geom2dInt_GInter.hxx>
96 #include <GeomAdaptor_Curve.hxx>
97 #include <GeomAdaptor_HSurface.hxx>
98 #include <GeomAdaptor_Surface.hxx>
99 #include <GeomLib_CheckBSplineCurve.hxx>
100 #include <GeomLib_Check2dBSplineCurve.hxx>
102 #include <GeomInt_WLApprox.hxx>
103 #include <GeomProjLib.hxx>
104 #include <GeomAPI_ProjectPointOnSurf.hxx>
105 #include <Geom2dAdaptor_Curve.hxx>
106 #include <TopoDS.hxx>
107 #include <TopoDS_Edge.hxx>
108 #include <TopExp_Explorer.hxx>
110 #include <BRep_Tool.hxx>
111 #include <BRepTools.hxx>
112 #include <BRepAdaptor_Surface.hxx>
114 #include <BOPTColStd_Dump.hxx>
116 #include <IntTools_Curve.hxx>
117 #include <IntTools_Tools.hxx>
118 #include <IntTools_Tools.hxx>
119 #include <IntTools_TopolTool.hxx>
120 #include <IntTools_PntOnFace.hxx>
121 #include <IntTools_PntOn2Faces.hxx>
122 #include <IntTools_Context.hxx>
123 #include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
126 void RefineVector(gp_Vec2d& aV2D);
129 void DumpWLine(const Handle(IntPatch_WLine)& aWLine);
132 void TolR3d(const TopoDS_Face& ,
136 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)&,
137 const Standard_Integer,
138 const Standard_Integer);
141 void Parameters(const Handle(GeomAdaptor_HSurface)&,
142 const Handle(GeomAdaptor_HSurface)&,
150 void BuildPCurves (Standard_Real f,Standard_Real l,Standard_Real& Tol,
151 const Handle (Geom_Surface)& S,
152 const Handle (Geom_Curve)& C,
153 Handle (Geom2d_Curve)& C2d);
156 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
157 const Standard_Real theTolerance,
158 Standard_Real& theumin,
159 Standard_Real& theumax,
160 Standard_Real& thevmin,
161 Standard_Real& thevmax);
163 Standard_Boolean NotUseSurfacesForApprox
164 (const TopoDS_Face& aF1,
165 const TopoDS_Face& aF2,
166 const Handle(IntPatch_WLine)& WL,
167 const Standard_Integer ifprm,
168 const Standard_Integer ilprm);
171 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
174 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
175 const Standard_Real parmin,
176 const Standard_Real parmax,
177 const Standard_Real thePeriod,
178 Standard_Real& theOffset);
181 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
182 const Standard_Integer ideb,
183 const Standard_Integer ifin,
184 const Standard_Boolean onFirst);
187 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
188 const Handle(GeomAdaptor_HSurface)& theSurface1,
189 const Handle(GeomAdaptor_HSurface)& theSurface2,
190 const TopoDS_Face& theFace1,
191 const TopoDS_Face& theFace2,
192 const IntTools_LineConstructor& theLConstructor,
193 const Standard_Boolean theAvoidLConstructor,
194 IntPatch_SequenceOfLine& theNewLines,
195 Standard_Real& theReachedTol3d,
196 const Handle(IntTools_Context)& );
199 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
200 const Handle(Geom_Curve)& theCurve,
201 const TopoDS_Face& theFace1,
202 const TopoDS_Face& theFace2,
203 const Standard_Real theOtherParameter,
204 const Standard_Boolean bIncreasePar,
205 Standard_Real& theNewParameter,
206 const Handle(IntTools_Context)& );
209 Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve);
212 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
213 const Standard_Real theFirstBoundary,
214 const Standard_Real theSecondBoundary,
215 const Standard_Real theResolution,
216 Standard_Boolean& IsOnFirstBoundary);
218 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
219 const gp_Pnt2d& theLastPoint,
220 const Standard_Real theUmin,
221 const Standard_Real theUmax,
222 const Standard_Real theVmin,
223 const Standard_Real theVmax,
224 gp_Pnt2d& theNewPoint);
228 Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
229 const Handle(GeomAdaptor_HSurface)& theSurface2,
230 const TopoDS_Face& theFace1,
231 const TopoDS_Face& theFace2,
232 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
233 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
234 Handle(TColStd_HArray1OfReal)& theResultRadius,
235 const Handle(IntTools_Context)& );
238 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
239 const gp_Pnt2d& theLastPoint,
240 const Standard_Real theUmin,
241 const Standard_Real theUmax,
242 const Standard_Real theVmin,
243 const Standard_Real theVmax,
244 const gp_Pnt2d& theTanZoneCenter,
245 const Standard_Real theZoneRadius,
246 Handle(GeomAdaptor_HSurface) theGASurface,
247 gp_Pnt2d& theNewPoint);
250 Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
251 const gp_Pnt2d& theTanZoneCenter,
252 const Standard_Real theZoneRadius,
253 Handle(GeomAdaptor_HSurface) theGASurface);
256 gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
257 const gp_Pnt2d& theOriginalPoint,
258 Handle(GeomAdaptor_HSurface) theGASurface);
260 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
261 const gp_Sphere& theSph);
263 static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
264 const Handle(GeomAdaptor_HSurface)& theS2,
265 const Standard_Real TolAng,
266 const Standard_Real TolTang,
267 const Standard_Boolean theApprox1,
268 const Standard_Boolean theApprox2,
269 IntTools_SequenceOfCurves& theSeqOfCurve,
270 Standard_Boolean& theTangentFaces);
272 static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
273 const gp_Lin2d& theLin2d,
274 const Standard_Real theTol,
275 Standard_Real& theP1,
276 Standard_Real& theP2);
279 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
280 const Handle(GeomAdaptor_HSurface)& aHS2,
281 Standard_Integer& iDegMin,
282 Standard_Integer& iNbIter,
283 Standard_Integer& iDegMax);
286 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
287 const Handle(GeomAdaptor_HSurface)& aHS2,
288 Standard_Real& aTolArc,
289 Standard_Real& aTolTang,
290 Standard_Real& aUVMaxStep,
291 Standard_Real& aDeflection);
294 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
295 const GeomAbs_SurfaceType aType2);
297 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
301 Standard_Real MaxSquareDistance (const Standard_Real aT,
302 const Handle(Geom_Curve)& aC3D,
303 const Handle(Geom2d_Curve)& aC2D1,
304 const Handle(Geom2d_Curve)& aC2D2,
305 const Handle(GeomAdaptor_HSurface) myHS1,
306 const Handle(GeomAdaptor_HSurface) myHS2,
307 const TopoDS_Face& aF1,
308 const TopoDS_Face& aF2,
309 const Handle(IntTools_Context)& aCtx);
312 Standard_Real FindMaxSquareDistance (const Standard_Real aA,
313 const Standard_Real aB,
314 const Standard_Real aEps,
315 const Handle(Geom_Curve)& aC3D,
316 const Handle(Geom2d_Curve)& aC2D1,
317 const Handle(Geom2d_Curve)& aC2D2,
318 const Handle(GeomAdaptor_HSurface)& myHS1,
319 const Handle(GeomAdaptor_HSurface)& myHS2,
320 const TopoDS_Face& aF1,
321 const TopoDS_Face& aF2,
322 const Handle(IntTools_Context)& aCtx);
324 //=======================================================================
327 //=======================================================================
328 IntTools_FaceFace::IntTools_FaceFace()
330 myTangentFaces=Standard_False;
332 myHS1 = new GeomAdaptor_HSurface ();
333 myHS2 = new GeomAdaptor_HSurface ();
336 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
339 //=======================================================================
340 //function : SetContext
342 //=======================================================================
343 void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
347 //=======================================================================
350 //=======================================================================
351 const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
355 //=======================================================================
358 //=======================================================================
359 const TopoDS_Face& IntTools_FaceFace::Face1() const
363 //=======================================================================
366 //=======================================================================
367 const TopoDS_Face& IntTools_FaceFace::Face2() const
371 //=======================================================================
372 //function : TangentFaces
374 //=======================================================================
375 Standard_Boolean IntTools_FaceFace::TangentFaces() const
377 return myTangentFaces;
379 //=======================================================================
382 //=======================================================================
383 const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
387 //=======================================================================
390 //=======================================================================
391 Standard_Boolean IntTools_FaceFace::IsDone() const
395 //=======================================================================
396 //function : TolReached3d
398 //=======================================================================
399 Standard_Real IntTools_FaceFace::TolReached3d() const
401 return myTolReached3d;
403 //=======================================================================
405 //purpose : return lines of intersection
406 //=======================================================================
407 const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
409 StdFail_NotDone_Raise_if
411 "IntTools_FaceFace::Lines() => !myIntersector.IsDone()");
414 //=======================================================================
415 //function : TolReached2d
417 //=======================================================================
418 Standard_Real IntTools_FaceFace::TolReached2d() const
420 return myTolReached2d;
422 // =======================================================================
423 // function: SetParameters
425 // =======================================================================
426 void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
427 const Standard_Boolean ToApproxC2dOnS1,
428 const Standard_Boolean ToApproxC2dOnS2,
429 const Standard_Real ApproximationTolerance)
431 myApprox = ToApproxC3d;
432 myApprox1 = ToApproxC2dOnS1;
433 myApprox2 = ToApproxC2dOnS2;
434 myTolApprox = ApproximationTolerance;
436 //=======================================================================
439 //=======================================================================
440 void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
442 myListOfPnts = aListOfPnts;
444 //=======================================================================
446 //purpose : intersect surfaces of the faces
447 //=======================================================================
448 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
449 const TopoDS_Face& aF2)
451 Standard_Boolean hasCone, RestrictLine, bTwoPlanes, bReverse;
452 Standard_Integer aNbLin, aNbPnts, i, NbLinPP;
453 Standard_Real TolArc, TolTang, Deflection, UVMaxStep;
454 Standard_Real umin, umax, vmin, vmax;
455 Standard_Real aTolF1, aTolF2;
456 GeomAbs_SurfaceType aType1, aType2;
457 Handle(Geom_Surface) S1, S2;
458 Handle(IntTools_TopolTool) dom1, dom2;
459 BRepAdaptor_Surface aBAS1, aBAS2;
461 if (myContext.IsNull()) {
462 myContext=new IntTools_Context;
465 mySeqOfCurve.Clear();
468 myIsDone = Standard_False;
470 hasCone = Standard_False;
471 bTwoPlanes = Standard_False;
476 aBAS1.Initialize(myFace1, Standard_False);
477 aBAS2.Initialize(myFace2, Standard_False);
478 aType1=aBAS1.GetType();
479 aType2=aBAS2.GetType();
481 bReverse=SortTypes(aType1, aType2);
485 aType1=aBAS2.GetType();
486 aType2=aBAS1.GetType();
488 if (myListOfPnts.Extent()) {
489 Standard_Real aU1,aV1,aU2,aV2;
490 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
492 aItP2S.Initialize(myListOfPnts);
493 for (; aItP2S.More(); aItP2S.Next()){
494 IntSurf_PntOn2S& aP2S=aItP2S.Value();
495 aP2S.Parameters(aU1,aV1,aU2,aV2);
496 aP2S.SetValue(aU2,aV2,aU1,aV1);
501 S1=BRep_Tool::Surface(myFace1);
502 S2=BRep_Tool::Surface(myFace2);
504 aTolF1=BRep_Tool::Tolerance(myFace1);
505 aTolF2=BRep_Tool::Tolerance(myFace2);
507 TolArc= aTolF1 + aTolF2;
511 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
512 bTwoPlanes = Standard_True;
514 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
515 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
517 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
518 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
519 Standard_Real TolAng = 1.e-8;
520 PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
521 mySeqOfCurve, myTangentFaces);
523 myIsDone = Standard_True;
525 if(!myTangentFaces) {
527 NbLinPP = mySeqOfCurve.Length();
529 Standard_Real aTolFMax;
531 myTolReached3d = 1.e-7;
533 aTolFMax=Max(aTolF1, aTolF2);
535 if (aTolFMax>myTolReached3d) {
536 myTolReached3d=aTolFMax;
538 myTolReached2d = myTolReached3d;
541 Handle(Geom2d_Curve) aC2D1, aC2D2;
543 aNbLin=mySeqOfCurve.Length();
544 for (i=1; i<=aNbLin; ++i) {
545 IntTools_Curve& aIC=mySeqOfCurve(i);
546 aC2D1=aIC.FirstCurve2d();
547 aC2D2=aIC.SecondCurve2d();
549 aIC.SetFirstCurve2d(aC2D2);
550 aIC.SetSecondCurve2d(aC2D1);
556 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
558 if (aType1==GeomAbs_Plane &&
559 (aType2==GeomAbs_Cylinder ||
560 aType2==GeomAbs_Cone ||
561 aType2==GeomAbs_Torus)) {
562 Standard_Real dU, dV;
564 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
571 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
573 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
574 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
575 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
577 if( aType2==GeomAbs_Cone ) {
579 hasCone = Standard_True;
583 else if ((aType1==GeomAbs_Cylinder||
584 aType1==GeomAbs_Cone ||
585 aType1==GeomAbs_Torus) &&
586 aType2==GeomAbs_Plane) {
587 Standard_Real dU, dV;
589 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
590 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
591 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
593 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
600 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
602 if( aType1==GeomAbs_Cone ) {
604 hasCone = Standard_True;
610 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
612 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
614 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
616 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
618 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
620 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
623 dom1 = new IntTools_TopolTool(myHS1);
624 dom2 = new IntTools_TopolTool(myHS2);
626 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
628 Deflection = (hasCone) ? 0.085 : 0.1;
631 Tolerances(myHS1, myHS2, TolArc, TolTang, UVMaxStep, Deflection);
633 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
635 RestrictLine = Standard_False;
637 if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
638 (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
639 (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
640 (myHS2->IsVClosed() && !myHS2->IsVPeriodic())) {
641 RestrictLine = Standard_True;
644 if(((aType1 != GeomAbs_BSplineSurface) &&
645 (aType1 != GeomAbs_BezierSurface) &&
646 (aType1 != GeomAbs_OtherSurface)) &&
647 ((aType2 != GeomAbs_BSplineSurface) &&
648 (aType2 != GeomAbs_BezierSurface) &&
649 (aType2 != GeomAbs_OtherSurface))) {
650 RestrictLine = Standard_True;
652 if ((aType1 == GeomAbs_Torus) ||
653 (aType2 == GeomAbs_Torus) ) {
654 myListOfPnts.Clear();
659 TopExp_Explorer aExp;
661 for(i = 0; (!RestrictLine) && (i < 2); i++) {
662 const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
663 aExp.Init(aF, TopAbs_EDGE);
664 for(; aExp.More(); aExp.Next()) {
665 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
667 if(BRep_Tool::Degenerated(aE)) {
668 RestrictLine = Standard_True;
675 myIntersector.Perform(myHS1, dom1, myHS2, dom2,
677 myListOfPnts, RestrictLine);
679 myIsDone = myIntersector.IsDone();
681 myTangentFaces=myIntersector.TangentFaces();
682 if (myTangentFaces) {
687 myListOfPnts.Clear(); // to use LineConstructor
690 aNbLin = myIntersector.NbLines();
691 for (i=1; i<=aNbLin; ++i) {
692 MakeCurve(i, dom1, dom2);
695 ComputeTolReached3d();
698 Handle(Geom2d_Curve) aC2D1, aC2D2;
700 aNbLin=mySeqOfCurve.Length();
701 for (i=1; i<=aNbLin; ++i) {
702 IntTools_Curve& aIC=mySeqOfCurve(i);
703 aC2D1=aIC.FirstCurve2d();
704 aC2D2=aIC.SecondCurve2d();
706 aIC.SetFirstCurve2d(aC2D2);
707 aIC.SetSecondCurve2d(aC2D1);
712 Standard_Real U1,V1,U2,V2;
713 IntTools_PntOnFace aPntOnF1, aPntOnF2;
714 IntTools_PntOn2Faces aPntOn2Faces;
716 aNbPnts=myIntersector.NbPnts();
717 for (i=1; i<=aNbPnts; ++i) {
718 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
719 const gp_Pnt& aPnt=aISPnt.Value();
720 aISPnt.Parameters(U1,V1,U2,V2);
721 aPntOnF1.Init(myFace1, aPnt, U1, V1);
722 aPntOnF2.Init(myFace2, aPnt, U2, V2);
725 aPntOn2Faces.SetP1(aPntOnF1);
726 aPntOn2Faces.SetP2(aPntOnF2);
729 aPntOn2Faces.SetP2(aPntOnF1);
730 aPntOn2Faces.SetP1(aPntOnF2);
732 myPnts.Append(aPntOn2Faces);
737 //=======================================================================
738 //function :ComputeTolReached3d
740 //=======================================================================
741 void IntTools_FaceFace::ComputeTolReached3d()
743 Standard_Integer aNbLin;
744 GeomAbs_SurfaceType aType1, aType2;
746 aNbLin=myIntersector.NbLines();
751 aType1=myHS1->Surface().GetType();
752 aType2=myHS2->Surface().GetType();
754 if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
756 Handle(IntPatch_Line) aIL1, aIL2;
757 IntPatch_IType aTL1, aTL2;
759 aIL1=myIntersector.Line(1);
760 aIL2=myIntersector.Line(2);
761 aTL1=aIL1->ArcType();
762 aTL2=aIL2->ArcType();
763 if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
764 Standard_Real aD, aDTresh, dTol;
770 aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
771 aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
772 aD=aL1.Distance(aL2);
775 myTolReached3d=aD+dTol;
781 if (aNbLin) {// Check the distances
782 Standard_Integer i, aNbP, j ;
783 Standard_Real aT1, aT2, dT, aD2, aD2Max, aEps, aT11, aT12;
787 aNbLin=mySeqOfCurve.Length();
789 for (i=1; i<=aNbLin; ++i) {
790 const IntTools_Curve& aIC=mySeqOfCurve(i);
791 const Handle(Geom_Curve)& aC3D=aIC.Curve();
792 const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
793 const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
798 const Handle(Geom_BSplineCurve)& aBC=
799 Handle(Geom_BSplineCurve)::DownCast(aC3D);
804 aT1=aBC->FirstParameter();
805 aT2=aBC->LastParameter();
809 for (j=1; j<aNbP; ++j) {
812 aD2=FindMaxSquareDistance(aT11, aT12, aEps, aC3D, aC2D1, aC2D2,
813 myHS1, myHS2, myFace1, myFace2, myContext);
818 }//for (i=1; i<=aNbLin; ++i) {
820 myTolReached3d=sqrt(aD2Max);
822 }// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
825 else if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
826 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
830 aTolF1 = BRep_Tool::Tolerance(myFace1);
831 aTolF2 = BRep_Tool::Tolerance(myFace2);
832 aTolFMax=Max(aTolF1, aTolF2);
834 if (aTolFMax>aTolTresh) {
835 myTolReached3d=aTolFMax;
837 }//if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
840 else if((aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane) ||
841 (aType2 == GeomAbs_Cylinder && aType1 == GeomAbs_Plane)) {
843 const Handle(IntPatch_Line)& aIL1 = myIntersector.Line(1);
844 if(aIL1->ArcType() == IntPatch_Circle) {
845 gp_Circ aCir = Handle(IntPatch_GLine)::DownCast(aIL1)->Circle();
846 gp_XYZ aCirDir = aCir.Axis().Direction().XYZ();
849 if(aType1 == GeomAbs_Plane) {
850 aPln = myHS1->Surface().Plane();
853 aPln = myHS2->Surface().Plane();
855 aPlDir = aPln.Axis().Direction().XYZ();
856 Standard_Real cs = aCirDir*aPlDir;
857 if(cs < 0.) aPlDir.Reverse();
858 Standard_Real eps = 1.e-14;
859 if(!aPlDir.IsEqual(aCirDir, eps)) {
860 Standard_Integer aNbP = 11;
861 Standard_Real dt = 2.*M_PI / (aNbP - 1), t;
862 for(t = 0.; t < 2.*M_PI; t += dt) {
863 Standard_Real d = aPln.Distance(ElCLib::Value(t, aCir));
864 if(myTolReached3d < d) myTolReached3d = d;
866 myTolReached3d *= 1.1;
868 } //aIL1->ArcType() == IntPatch_Circle
870 } // aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane)
871 //End IFV Bug OCC20297
873 else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
874 (aType2==GeomAbs_Plane && aType1==GeomAbs_Torus)) {
875 aNbLin=mySeqOfCurve.Length();
880 Standard_Integer i, aNbP;
881 Standard_Real aT, aT1, aT2, dT, aUT, aVT, aUP, aVP;
882 Standard_Real aDP, aDT, aDmax;
887 const IntTools_Curve& aIC=mySeqOfCurve(1);
888 const Handle(Geom_Curve)& aC3D=aIC.Curve();
889 const Handle(Geom_BSplineCurve)& aBS=
890 Handle(Geom_BSplineCurve)::DownCast(aC3D);
895 aT1=aBS->FirstParameter();
896 aT2=aBS->LastParameter();
898 aPln =(aType1==GeomAbs_Plane) ? myHS1->Plane() : myHS2->Plane();
899 aTorus=(aType1==GeomAbs_Plane) ? myHS2->Torus() : myHS1->Torus();
903 dT=(aT2-aT1)/(aNbP-1);
904 for (i=0; i<aNbP; ++i) {
912 ElSLib::Parameters(aPln, aP, aUP, aVP);
913 aPP=ElSLib::Value(aUP, aVP, aPln);
914 aDP=aP.SquareDistance(aPP);
919 ElSLib::Parameters(aTorus, aP, aUT, aVT);
920 aPT=ElSLib::Value(aUT, aVT, aTorus);
921 aDT=aP.SquareDistance(aPT);
927 if (aDmax > myTolReached3d*myTolReached3d) {
928 myTolReached3d=sqrt(aDmax);
929 myTolReached3d=1.1*myTolReached3d;
931 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
933 else if ((aType1==GeomAbs_SurfaceOfRevolution && aType2==GeomAbs_Cylinder) ||
934 (aType2==GeomAbs_SurfaceOfRevolution && aType1==GeomAbs_Cylinder)) {
935 Standard_Integer i, j, aNbP;
936 Standard_Real aT, aT1, aT2, dT, aD2max, aD2;
938 aNbLin=mySeqOfCurve.Length();
942 for (i=1; i<=aNbLin; ++i) {
943 const IntTools_Curve& aIC=mySeqOfCurve(i);
944 const Handle(Geom_Curve)& aC3D=aIC.Curve();
945 const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
946 const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
951 const Handle(Geom_BSplineCurve)& aBC=
952 Handle(Geom_BSplineCurve)::DownCast(aC3D);
957 aT1=aBC->FirstParameter();
958 aT2=aBC->LastParameter();
960 dT=(aT2-aT1)/(aNbP-1);
961 for (j=0; j<aNbP; ++j) {
967 aD2=MaxSquareDistance(aT, aC3D, aC2D1, aC2D2,
968 myHS1, myHS2, myFace1, myFace2, myContext);
972 }//for (j=0; j<aNbP; ++j) {
974 }//for (i=1; i<=aNbLin; ++i) {
976 aD2=myTolReached3d*myTolReached3d;
978 myTolReached3d=sqrt(aD2max);
980 }//if((aType1==GeomAbs_SurfaceOfRevolution ...
981 //modified by NIZNHY-PKV Thu Aug 30 13:31:10 2012f
982 else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ||
983 (aType2==GeomAbs_Plane && aType1==GeomAbs_Sphere)) {
984 Standard_Integer i, j, aNbP;
985 Standard_Real aT, aT1, aT2, dT, aD2max, aD2, aEps, aT11, aT12;
987 aNbLin=mySeqOfCurve.Length();
991 for (i=1; i<=aNbLin; ++i) {
992 const IntTools_Curve& aIC=mySeqOfCurve(i);
993 const Handle(Geom_Curve)& aC3D=aIC.Curve();
994 const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
995 const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
997 const Handle(Geom2d_BSplineCurve)& aBC2D1=
998 Handle(Geom2d_BSplineCurve)::DownCast(aC2D1);
999 const Handle(Geom2d_BSplineCurve)& aBC2D2=
1000 Handle(Geom2d_BSplineCurve)::DownCast(aC2D2);
1002 if (aBC2D1.IsNull() && aBC2D2.IsNull()) {
1006 if (!aBC2D1.IsNull()) {
1007 aT1=aBC2D1->FirstParameter();
1008 aT2=aBC2D1->LastParameter();
1011 aT1=aBC2D2->FirstParameter();
1012 aT2=aBC2D2->LastParameter();
1015 aEps=0.01*(aT2-aT1);
1016 dT=(aT2-aT1)/(aNbP-1);
1017 for (j=0; j<aNbP; ++j) {
1025 aD2=FindMaxSquareDistance(aT11, aT12, aEps, aC3D, aC2D1, aC2D2,
1026 myHS1, myHS2, myFace1, myFace2, myContext);
1030 }//for (j=0; j<aNbP; ++j) {
1032 }//for (i=1; i<=aNbLin; ++i) {
1034 aD2=myTolReached3d*myTolReached3d;
1036 myTolReached3d=sqrt(aD2max);
1038 }//else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ...
1039 //modified by NIZNHY-PKV Thu Aug 30 13:31:12 2012t
1041 //=======================================================================
1042 //function : MakeCurve
1044 //=======================================================================
1045 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
1046 const Handle(Adaptor3d_TopolTool)& dom1,
1047 const Handle(Adaptor3d_TopolTool)& dom2)
1049 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
1050 Standard_Boolean ok;
1051 Standard_Integer i, j, aNbParts;
1052 Standard_Real fprm, lprm;
1053 Standard_Real Tolpc;
1054 Handle(IntPatch_Line) L;
1055 IntPatch_IType typl;
1056 Handle(Geom_Curve) newc;
1058 const Standard_Real TOLCHECK =0.0000001;
1059 const Standard_Real TOLANGCHECK=0.1;
1061 rejectSurface = Standard_False;
1062 reApprox = Standard_False;
1066 Tolpc = myTolApprox;
1067 bAvoidLineConstructor = Standard_False;
1068 L = myIntersector.Line(Index);
1069 typl = L->ArcType();
1071 if(typl==IntPatch_Walking) {
1072 Handle(IntPatch_Line) anewL;
1074 const Handle(IntPatch_WLine)& aWLine=
1075 Handle(IntPatch_WLine)::DownCast(L);
1077 //DumpWLine(aWLine);
1079 anewL = ComputePurgedWLine(aWLine);
1080 if(anewL.IsNull()) {
1086 { const Handle(IntPatch_WLine)& aWLineX=
1087 Handle(IntPatch_WLine)::DownCast(L);
1093 if(!myListOfPnts.IsEmpty()) {
1094 bAvoidLineConstructor = Standard_True;
1097 Standard_Integer nbp = aWLine->NbPnts();
1098 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
1099 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
1101 const gp_Pnt& P1 = p1.Value();
1102 const gp_Pnt& P2 = p2.Value();
1104 if(P1.SquareDistance(P2) < 1.e-14) {
1105 bAvoidLineConstructor = Standard_False;
1111 if(!bAvoidLineConstructor) {
1112 myLConstruct.Perform(L);
1114 bDone=myLConstruct.IsDone();
1115 aNbParts=myLConstruct.NbParts();
1116 if (!bDone|| !aNbParts) {
1125 //########################################
1126 // Line, Parabola, Hyperbola
1127 //########################################
1129 case IntPatch_Parabola:
1130 case IntPatch_Hyperbola: {
1131 if (typl == IntPatch_Lin) {
1133 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
1136 else if (typl == IntPatch_Parabola) {
1138 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
1141 else if (typl == IntPatch_Hyperbola) {
1143 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
1147 if (typl == IntPatch_Lin) {
1148 TolR3d (myFace1, myFace2, myTolReached3d);
1151 aNbParts=myLConstruct.NbParts();
1152 for (i=1; i<=aNbParts; i++) {
1153 myLConstruct.Part(i, fprm, lprm);
1155 if (!Precision::IsNegativeInfinite(fprm) &&
1156 !Precision::IsPositiveInfinite(lprm)) {
1158 IntTools_Curve aCurve;
1160 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
1161 aCurve.SetCurve(aCT3D);
1162 if (typl == IntPatch_Parabola) {
1163 Standard_Real aTolF1, aTolF2, aTolBase;
1165 aTolF1 = BRep_Tool::Tolerance(myFace1);
1166 aTolF2 = BRep_Tool::Tolerance(myFace2);
1167 aTolBase=aTolF1+aTolF2;
1168 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
1171 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
1173 Handle (Geom2d_Curve) C2d;
1174 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
1175 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1176 myTolReached2d=Tolpc;
1179 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1182 Handle(Geom2d_BSplineCurve) H1;
1184 aCurve.SetFirstCurve2d(H1);
1188 Handle (Geom2d_Curve) C2d;
1189 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
1190 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1191 myTolReached2d=Tolpc;
1194 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1197 Handle(Geom2d_BSplineCurve) H1;
1199 aCurve.SetSecondCurve2d(H1);
1201 mySeqOfCurve.Append(aCurve);
1202 } // end of if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
1205 // on regarde si on garde
1207 Standard_Boolean bFNIt, bLPIt;
1208 Standard_Real aTestPrm, dT=100.;
1210 bFNIt=Precision::IsNegativeInfinite(fprm);
1211 bLPIt=Precision::IsPositiveInfinite(lprm);
1215 if (bFNIt && !bLPIt) {
1218 else if (!bFNIt && bLPIt) {
1222 gp_Pnt ptref(newc->Value(aTestPrm));
1225 Standard_Real u1, v1, u2, v2, Tol;
1227 Tol = Precision::Confusion();
1228 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1229 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1231 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1234 Handle(Geom2d_BSplineCurve) H1;
1235 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1238 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
1239 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
1242 //########################################
1243 // Circle and Ellipse
1244 //########################################
1245 case IntPatch_Circle:
1246 case IntPatch_Ellipse: {
1248 if (typl == IntPatch_Circle) {
1249 newc = new Geom_Circle
1250 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
1252 else { //IntPatch_Ellipse
1253 newc = new Geom_Ellipse
1254 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
1258 TolR3d (myFace1, myFace2, myTolReached3d);
1260 aNbParts=myLConstruct.NbParts();
1262 Standard_Real aPeriod, aNul;
1263 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
1268 for (i=1; i<=aNbParts; i++) {
1269 myLConstruct.Part(i, fprm, lprm);
1271 if (fprm < aNul && lprm > aNul) {
1272 // interval that goes through 0. is divided on two intervals;
1273 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1274 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1276 if((aPeriod - fprm) > Tolpc) {
1277 aSeqFprm.Append(fprm);
1278 aSeqLprm.Append(aPeriod);
1281 gp_Pnt P1 = newc->Value(fprm);
1282 gp_Pnt P2 = newc->Value(aPeriod);
1283 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1284 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1286 if(P1.Distance(P2) > aTolDist) {
1287 Standard_Real anewpar = fprm;
1289 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2, lprm, Standard_False, anewpar, myContext)) {
1292 aSeqFprm.Append(fprm);
1293 aSeqLprm.Append(aPeriod);
1298 if((lprm - aNul) > Tolpc) {
1299 aSeqFprm.Append(aNul);
1300 aSeqLprm.Append(lprm);
1303 gp_Pnt P1 = newc->Value(aNul);
1304 gp_Pnt P2 = newc->Value(lprm);
1305 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1306 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1308 if(P1.Distance(P2) > aTolDist) {
1309 Standard_Real anewpar = lprm;
1311 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2, fprm, Standard_True, anewpar, myContext)) {
1314 aSeqFprm.Append(aNul);
1315 aSeqLprm.Append(lprm);
1321 aSeqFprm.Append(fprm);
1322 aSeqLprm.Append(lprm);
1327 aNbParts=aSeqFprm.Length();
1328 for (i=1; i<=aNbParts; i++) {
1332 Standard_Real aRealEpsilon=RealEpsilon();
1333 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
1334 //==============================================
1336 IntTools_Curve aCurve;
1337 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1338 aCurve.SetCurve(aTC3D);
1339 fprm=aTC3D->FirstParameter();
1340 lprm=aTC3D->LastParameter ();
1342 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1344 Handle (Geom2d_Curve) C2d;
1345 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
1346 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1347 myTolReached2d=Tolpc;
1350 aCurve.SetFirstCurve2d(C2d);
1353 Handle(Geom2d_BSplineCurve) H1;
1354 aCurve.SetFirstCurve2d(H1);
1359 Handle (Geom2d_Curve) C2d;
1360 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
1361 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1362 myTolReached2d=Tolpc;
1365 aCurve.SetSecondCurve2d(C2d);
1368 Handle(Geom2d_BSplineCurve) H1;
1369 aCurve.SetSecondCurve2d(H1);
1374 Handle(Geom2d_BSplineCurve) H1;
1375 aCurve.SetFirstCurve2d(H1);
1376 aCurve.SetSecondCurve2d(H1);
1378 mySeqOfCurve.Append(aCurve);
1379 //==============================================
1380 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
1383 // on regarde si on garde
1386 // if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1387 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1388 IntTools_Curve aCurve;
1389 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1390 aCurve.SetCurve(aTC3D);
1391 fprm=aTC3D->FirstParameter();
1392 lprm=aTC3D->LastParameter ();
1395 Handle (Geom2d_Curve) C2d;
1396 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
1397 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1398 myTolReached2d=Tolpc;
1401 aCurve.SetFirstCurve2d(C2d);
1404 Handle(Geom2d_BSplineCurve) H1;
1405 aCurve.SetFirstCurve2d(H1);
1409 Handle (Geom2d_Curve) C2d;
1410 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
1411 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1412 myTolReached2d=Tolpc;
1415 aCurve.SetSecondCurve2d(C2d);
1418 Handle(Geom2d_BSplineCurve) H1;
1419 aCurve.SetSecondCurve2d(H1);
1421 mySeqOfCurve.Append(aCurve);
1426 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1428 aTwoPIdiv17=2.*M_PI/17.;
1430 for (j=0; j<=17; j++) {
1431 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1432 Tol = Precision::Confusion();
1434 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1435 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1437 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1440 IntTools_Curve aCurve;
1441 aCurve.SetCurve(newc);
1442 //==============================================
1443 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1446 Handle (Geom2d_Curve) C2d;
1447 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
1448 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1449 myTolReached2d=Tolpc;
1452 aCurve.SetFirstCurve2d(C2d);
1455 Handle(Geom2d_BSplineCurve) H1;
1456 aCurve.SetFirstCurve2d(H1);
1460 Handle (Geom2d_Curve) C2d;
1461 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
1462 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1463 myTolReached2d=Tolpc;
1466 aCurve.SetSecondCurve2d(C2d);
1470 Handle(Geom2d_BSplineCurve) H1;
1471 aCurve.SetSecondCurve2d(H1);
1473 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1476 Handle(Geom2d_BSplineCurve) H1;
1478 aCurve.SetFirstCurve2d(H1);
1479 aCurve.SetSecondCurve2d(H1);
1481 //==============================================
1483 mySeqOfCurve.Append(aCurve);
1486 }// end of if (ok) {
1487 }// end of for (Standard_Integer j=0; j<=17; j++)
1488 }// end of else { on regarde si on garde
1489 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1490 }// IntPatch_Circle: IntPatch_Ellipse:
1493 case IntPatch_Analytic: {
1494 IntSurf_Quadric quad1,quad2;
1495 GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
1499 quad1.SetValue(myHS1->Surface().Plane());
1501 case GeomAbs_Cylinder:
1502 quad1.SetValue(myHS1->Surface().Cylinder());
1505 quad1.SetValue(myHS1->Surface().Cone());
1507 case GeomAbs_Sphere:
1508 quad1.SetValue(myHS1->Surface().Sphere());
1511 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
1514 typs = myHS2->Surface().GetType();
1518 quad2.SetValue(myHS2->Surface().Plane());
1520 case GeomAbs_Cylinder:
1521 quad2.SetValue(myHS2->Surface().Cylinder());
1524 quad2.SetValue(myHS2->Surface().Cone());
1526 case GeomAbs_Sphere:
1527 quad2.SetValue(myHS2->Surface().Sphere());
1530 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
1534 IntPatch_ALineToWLine convert (quad1, quad2);
1537 aNbParts=myLConstruct.NbParts();
1538 for (i=1; i<=aNbParts; i++) {
1539 myLConstruct.Part(i, fprm, lprm);
1540 Handle(IntPatch_WLine) WL =
1541 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1543 Handle(Geom2d_BSplineCurve) H1;
1544 Handle(Geom2d_BSplineCurve) H2;
1547 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1551 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1554 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1558 else { // myApprox=TRUE
1559 GeomInt_WLApprox theapp3d;
1561 Standard_Real tol2d = myTolApprox;
1563 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
1565 aNbParts=myLConstruct.NbParts();
1566 for (i=1; i<=aNbParts; i++) {
1567 myLConstruct.Part(i, fprm, lprm);
1568 Handle(IntPatch_WLine) WL =
1569 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
1571 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
1573 if (!theapp3d.IsDone()) {
1575 Handle(Geom2d_BSplineCurve) H1;
1576 Handle(Geom2d_BSplineCurve) H2;
1579 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1583 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1586 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1590 if(myApprox1 || myApprox2) {
1591 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1592 myTolReached2d = theapp3d.TolReached2d();
1596 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1597 myTolReached3d = theapp3d.TolReached3d();
1600 Standard_Integer aNbMultiCurves, nbpoles;
1601 aNbMultiCurves=theapp3d.NbMultiCurves();
1602 for (j=1; j<=aNbMultiCurves; j++) {
1603 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1604 nbpoles = mbspc.NbPoles();
1606 TColgp_Array1OfPnt tpoles(1, nbpoles);
1607 mbspc.Curve(1, tpoles);
1608 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1610 mbspc.Multiplicities(),
1613 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1614 Check.FixTangent(Standard_True,Standard_True);
1616 IntTools_Curve aCurve;
1617 aCurve.SetCurve(BS);
1620 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1621 mbspc.Curve(2,tpoles2d);
1622 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1624 mbspc.Multiplicities(),
1627 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1628 newCheck.FixTangent(Standard_True,Standard_True);
1630 aCurve.SetFirstCurve2d(BS2);
1633 Handle(Geom2d_BSplineCurve) H1;
1634 aCurve.SetFirstCurve2d(H1);
1638 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1639 Standard_Integer TwoOrThree;
1640 TwoOrThree=myApprox1 ? 3 : 2;
1641 mbspc.Curve(TwoOrThree, tpoles2d);
1642 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1644 mbspc.Multiplicities(),
1647 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1648 newCheck.FixTangent(Standard_True,Standard_True);
1650 aCurve.SetSecondCurve2d(BS2);
1653 Handle(Geom2d_BSplineCurve) H2;
1654 aCurve.SetSecondCurve2d(H2);
1657 mySeqOfCurve.Append(aCurve);
1659 }// for (j=1; j<=aNbMultiCurves; j++) {
1660 }// else from if (!theapp3d.IsDone())
1661 }// for (i=1; i<=aNbParts; i++) {
1662 }// else { // myApprox=TRUE
1663 }// case IntPatch_Analytic:
1666 case IntPatch_Walking:{
1667 Handle(IntPatch_WLine) WL =
1668 Handle(IntPatch_WLine)::DownCast(L);
1670 Standard_Integer ifprm, ilprm;
1674 if(!bAvoidLineConstructor){
1675 aNbParts=myLConstruct.NbParts();
1677 for (i=1; i<=aNbParts; ++i) {
1678 Handle(Geom2d_BSplineCurve) H1, H2;
1679 Handle(Geom_Curve) aBSp;
1681 if(bAvoidLineConstructor) {
1683 ilprm = WL->NbPnts();
1686 myLConstruct.Part(i, fprm, lprm);
1687 ifprm=(Standard_Integer)fprm;
1688 ilprm=(Standard_Integer)lprm;
1692 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1696 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1699 aBSp=MakeBSpline(WL, ifprm, ilprm);
1700 IntTools_Curve aIC(aBSp, H1, H2);
1701 mySeqOfCurve.Append(aIC);
1702 }// for (i=1; i<=aNbParts; ++i) {
1703 }// if (!myApprox) {
1706 Standard_Boolean bIsDecomposited;
1707 Standard_Integer nbiter, aNbSeqOfL;
1708 Standard_Real tol2d;
1709 IntPatch_SequenceOfLine aSeqOfL;
1710 GeomInt_WLApprox theapp3d;
1711 Approx_ParametrizationType aParType = Approx_ChordLength;
1713 Standard_Boolean anApprox1 = myApprox1;
1714 Standard_Boolean anApprox2 = myApprox2;
1716 tol2d = myTolApprox;
1718 GeomAbs_SurfaceType typs1, typs2;
1719 typs1 = myHS1->Surface().GetType();
1720 typs2 = myHS2->Surface().GetType();
1721 Standard_Boolean anWithPC = Standard_True;
1723 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
1725 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
1727 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
1729 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
1732 //aParType = Approx_Centripetal;
1733 myTolApprox = 1.e-5;
1734 anApprox1 = Standard_False;
1735 anApprox2 = Standard_False;
1737 tol2d = myTolApprox;
1740 if(myHS1 == myHS2) {
1742 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1743 rejectSurface = Standard_True;
1746 if(reApprox && !rejectSurface)
1747 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1749 Standard_Integer iDegMax, iDegMin, iNbIter;
1751 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1752 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType);
1757 Standard_Real aReachedTol = Precision::Confusion();
1758 bIsDecomposited=DecompositionOfWLine(WL,
1764 bAvoidLineConstructor,
1768 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) )
1769 myTolReached3d = aReachedTol;
1772 aNbSeqOfL=aSeqOfL.Length();
1774 if (bIsDecomposited) {
1780 if (!bAvoidLineConstructor) {
1781 aNbParts=myLConstruct.NbParts();
1786 // nbiter=(bIsDecomposited) ? aSeqOfL.Length() :
1787 // ((bAvoidLineConstructor) ? 1 :aNbParts);
1789 for(i = 1; i <= nbiter; ++i) {
1790 if(bIsDecomposited) {
1791 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1793 ilprm = WL->NbPnts();
1796 if(bAvoidLineConstructor) {
1798 ilprm = WL->NbPnts();
1801 myLConstruct.Part(i, fprm, lprm);
1802 ifprm = (Standard_Integer)fprm;
1803 ilprm = (Standard_Integer)lprm;
1807 //-- Si une des surfaces est un plan , on approxime en 2d
1808 //-- sur cette surface et on remonte les points 2d en 3d.
1809 if(typs1 == GeomAbs_Plane) {
1810 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1812 else if(typs2 == GeomAbs_Plane) {
1813 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1817 if (myHS1 != myHS2){
1818 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1819 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1821 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType);
1823 Standard_Boolean bUseSurfaces;
1824 bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1827 rejectSurface = Standard_True;
1829 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1834 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1837 if (!theapp3d.IsDone()) {
1839 Handle(Geom2d_BSplineCurve) H1;
1841 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
1842 Handle(Geom2d_BSplineCurve) H2;
1845 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1849 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1852 IntTools_Curve aIC(aBSp, H1, H2);
1853 mySeqOfCurve.Append(aIC);
1857 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1858 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1859 myTolReached2d = theapp3d.TolReached2d();
1862 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1863 myTolReached3d = myTolReached2d;
1865 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1866 if (myTolReached3d<1.e-6) {
1867 myTolReached3d = theapp3d.TolReached3d();
1868 myTolReached3d=1.e-6;
1873 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1874 myTolReached3d = theapp3d.TolReached3d();
1877 Standard_Integer aNbMultiCurves, nbpoles;
1878 aNbMultiCurves=theapp3d.NbMultiCurves();
1879 for (j=1; j<=aNbMultiCurves; j++) {
1880 if(typs1 == GeomAbs_Plane) {
1881 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1882 nbpoles = mbspc.NbPoles();
1884 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1885 TColgp_Array1OfPnt tpoles(1,nbpoles);
1887 mbspc.Curve(1,tpoles2d);
1888 const gp_Pln& Pln = myHS1->Surface().Plane();
1890 Standard_Integer ik;
1891 for(ik = 1; ik<= nbpoles; ik++) {
1893 ElSLib::Value(tpoles2d.Value(ik).X(),
1894 tpoles2d.Value(ik).Y(),
1898 Handle(Geom_BSplineCurve) BS =
1899 new Geom_BSplineCurve(tpoles,
1901 mbspc.Multiplicities(),
1903 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1904 Check.FixTangent(Standard_True, Standard_True);
1906 IntTools_Curve aCurve;
1907 aCurve.SetCurve(BS);
1910 Handle(Geom2d_BSplineCurve) BS1 =
1911 new Geom2d_BSplineCurve(tpoles2d,
1913 mbspc.Multiplicities(),
1915 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1916 Check1.FixTangent(Standard_True,Standard_True);
1918 // ############################################
1919 if(!rejectSurface && !reApprox) {
1920 Standard_Boolean isValid = IsCurveValid(BS1);
1922 reApprox = Standard_True;
1926 // ############################################
1927 aCurve.SetFirstCurve2d(BS1);
1930 Handle(Geom2d_BSplineCurve) H1;
1931 aCurve.SetFirstCurve2d(H1);
1935 mbspc.Curve(2, tpoles2d);
1937 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1939 mbspc.Multiplicities(),
1941 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1942 newCheck.FixTangent(Standard_True,Standard_True);
1944 // ###########################################
1945 if(!rejectSurface && !reApprox) {
1946 Standard_Boolean isValid = IsCurveValid(BS2);
1948 reApprox = Standard_True;
1952 // ###########################################
1954 aCurve.SetSecondCurve2d(BS2);
1957 Handle(Geom2d_BSplineCurve) H2;
1959 aCurve.SetSecondCurve2d(H2);
1962 mySeqOfCurve.Append(aCurve);
1965 else if(typs2 == GeomAbs_Plane) {
1966 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1967 nbpoles = mbspc.NbPoles();
1969 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1970 TColgp_Array1OfPnt tpoles(1,nbpoles);
1971 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1972 const gp_Pln& Pln = myHS2->Surface().Plane();
1974 Standard_Integer ik;
1975 for(ik = 1; ik<= nbpoles; ik++) {
1977 ElSLib::Value(tpoles2d.Value(ik).X(),
1978 tpoles2d.Value(ik).Y(),
1983 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1985 mbspc.Multiplicities(),
1987 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1988 Check.FixTangent(Standard_True,Standard_True);
1990 IntTools_Curve aCurve;
1991 aCurve.SetCurve(BS);
1994 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1996 mbspc.Multiplicities(),
1998 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1999 Check1.FixTangent(Standard_True,Standard_True);
2001 // ###########################################
2002 if(!rejectSurface && !reApprox) {
2003 Standard_Boolean isValid = IsCurveValid(BS1);
2005 reApprox = Standard_True;
2009 // ###########################################
2010 aCurve.SetSecondCurve2d(BS1);
2013 Handle(Geom2d_BSplineCurve) H2;
2014 aCurve.SetSecondCurve2d(H2);
2018 mbspc.Curve(1,tpoles2d);
2019 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2021 mbspc.Multiplicities(),
2023 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
2024 Check2.FixTangent(Standard_True,Standard_True);
2026 // ###########################################
2027 if(!rejectSurface && !reApprox) {
2028 Standard_Boolean isValid = IsCurveValid(BS2);
2030 reApprox = Standard_True;
2034 // ###########################################
2035 aCurve.SetFirstCurve2d(BS2);
2038 Handle(Geom2d_BSplineCurve) H1;
2040 aCurve.SetFirstCurve2d(H1);
2043 mySeqOfCurve.Append(aCurve);
2046 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2047 nbpoles = mbspc.NbPoles();
2048 TColgp_Array1OfPnt tpoles(1,nbpoles);
2049 mbspc.Curve(1,tpoles);
2050 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
2052 mbspc.Multiplicities(),
2054 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2055 Check.FixTangent(Standard_True,Standard_True);
2057 IntTools_Curve aCurve;
2058 aCurve.SetCurve(BS);
2062 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2063 mbspc.Curve(2,tpoles2d);
2064 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
2066 mbspc.Multiplicities(),
2068 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
2069 newCheck.FixTangent(Standard_True,Standard_True);
2071 aCurve.SetFirstCurve2d(BS1);
2074 Handle(Geom2d_BSplineCurve) BS1;
2075 fprm = BS->FirstParameter();
2076 lprm = BS->LastParameter();
2078 Handle(Geom2d_Curve) C2d;
2079 Standard_Real aTol = myTolApprox;
2080 BuildPCurves(fprm, lprm, aTol, myHS1->ChangeSurface().Surface(), BS, C2d);
2081 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2082 aCurve.SetFirstCurve2d(BS1);
2087 Handle(Geom2d_BSplineCurve) H1;
2089 aCurve.SetFirstCurve2d(H1);
2093 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2094 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
2095 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2097 mbspc.Multiplicities(),
2099 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
2100 newCheck.FixTangent(Standard_True,Standard_True);
2102 aCurve.SetSecondCurve2d(BS2);
2105 Handle(Geom2d_BSplineCurve) BS2;
2106 fprm = BS->FirstParameter();
2107 lprm = BS->LastParameter();
2109 Handle(Geom2d_Curve) C2d;
2110 Standard_Real aTol = myTolApprox;
2111 BuildPCurves(fprm, lprm, aTol, myHS2->ChangeSurface().Surface(), BS, C2d);
2112 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2113 aCurve.SetSecondCurve2d(BS2);
2118 Handle(Geom2d_BSplineCurve) H2;
2120 aCurve.SetSecondCurve2d(H2);
2123 mySeqOfCurve.Append(aCurve);
2129 }// case IntPatch_Walking:{
2132 case IntPatch_Restriction:
2138 //=======================================================================
2139 //function : BuildPCurves
2141 //=======================================================================
2142 void BuildPCurves (Standard_Real f,
2145 const Handle (Geom_Surface)& S,
2146 const Handle (Geom_Curve)& C,
2147 Handle (Geom2d_Curve)& C2d)
2150 Standard_Real umin,umax,vmin,vmax;
2155 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
2156 if((l - f) > 2.e-09) {
2157 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2160 // proj. a circle that goes through the pole on a sphere to the sphere
2162 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2166 if((l - f) > Epsilon(Abs(f))) {
2167 GeomAPI_ProjectPointOnSurf aProjector1, aProjector2;
2168 gp_Pnt P1 = C->Value(f);
2169 gp_Pnt P2 = C->Value(l);
2170 aProjector1.Init(P1, S);
2171 aProjector2.Init(P2, S);
2173 if(aProjector1.IsDone() && aProjector2.IsDone()) {
2174 Standard_Real U=0., V=0.;
2175 aProjector1.LowerDistanceParameters(U, V);
2178 aProjector2.LowerDistanceParameters(U, V);
2181 if(p1.Distance(p2) > gp::Resolution()) {
2182 TColgp_Array1OfPnt2d poles(1,2);
2183 TColStd_Array1OfReal knots(1,2);
2184 TColStd_Array1OfInteger mults(1,2);
2189 mults(1) = mults(2) = 2;
2191 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
2193 // compute reached tolerance.begin
2194 gp_Pnt PMid = C->Value((f + l) * 0.5);
2195 aProjector1.Perform(PMid);
2197 if(aProjector1.IsDone()) {
2198 aProjector1.LowerDistanceParameters(U, V);
2199 gp_Pnt2d pmidproj(U, V);
2200 gp_Pnt2d pmidcurve2d = C2d->Value((f + l) * 0.5);
2201 Standard_Real adist = pmidcurve2d.Distance(pmidproj);
2202 Tol = (adist > Tol) ? adist : Tol;
2204 // compute reached tolerance.end
2210 S->Bounds(umin, umax, vmin, vmax);
2212 if (S->IsUPeriodic() && !C2d.IsNull()) {
2213 // Recadre dans le domaine UV de la face
2214 Standard_Real period, U0, du, aEps;
2217 aEps=Precision::PConfusion();
2218 period = S->UPeriod();
2219 gp_Pnt2d Pf = C2d->Value(f);
2222 gp_Pnt2d Pl = C2d->Value(l);
2224 U0 = Min(Pl.X(), U0);
2225 // while(U0-umin<aEps) {
2226 while(U0-umin<-aEps) {
2231 while(U0-umax>aEps) {
2242 BOPTColStd_Dump::PrintMessage("BuildPCurves()=> Echec ProjLib\n");
2246 //=======================================================================
2247 //function : Parameters
2249 //=======================================================================
2250 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
2251 const Handle(GeomAdaptor_HSurface)& HS2,
2252 const gp_Pnt& Ptref,
2259 IntSurf_Quadric quad1,quad2;
2260 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2264 quad1.SetValue(HS1->Surface().Plane());
2266 case GeomAbs_Cylinder:
2267 quad1.SetValue(HS1->Surface().Cylinder());
2270 quad1.SetValue(HS1->Surface().Cone());
2272 case GeomAbs_Sphere:
2273 quad1.SetValue(HS1->Surface().Sphere());
2276 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2279 typs = HS2->Surface().GetType();
2282 quad2.SetValue(HS2->Surface().Plane());
2284 case GeomAbs_Cylinder:
2285 quad2.SetValue(HS2->Surface().Cylinder());
2288 quad2.SetValue(HS2->Surface().Cone());
2290 case GeomAbs_Sphere:
2291 quad2.SetValue(HS2->Surface().Sphere());
2294 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2297 quad1.Parameters(Ptref,U1,V1);
2298 quad2.Parameters(Ptref,U2,V2);
2301 //=======================================================================
2302 //function : MakeBSpline
2304 //=======================================================================
2305 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
2306 const Standard_Integer ideb,
2307 const Standard_Integer ifin)
2309 Standard_Integer i,nbpnt = ifin-ideb+1;
2310 TColgp_Array1OfPnt poles(1,nbpnt);
2311 TColStd_Array1OfReal knots(1,nbpnt);
2312 TColStd_Array1OfInteger mults(1,nbpnt);
2313 Standard_Integer ipidebm1;
2314 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2315 poles(i) = WL->Point(ipidebm1).Value();
2319 mults(1) = mults(nbpnt) = 2;
2321 new Geom_BSplineCurve(poles,knots,mults,1);
2325 //=======================================================================
2326 //function : MakeBSpline2d
2328 //=======================================================================
2329 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
2330 const Standard_Integer ideb,
2331 const Standard_Integer ifin,
2332 const Standard_Boolean onFirst)
2334 Standard_Integer i, nbpnt = ifin-ideb+1;
2335 TColgp_Array1OfPnt2d poles(1,nbpnt);
2336 TColStd_Array1OfReal knots(1,nbpnt);
2337 TColStd_Array1OfInteger mults(1,nbpnt);
2338 Standard_Integer ipidebm1;
2340 for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) {
2343 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
2345 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
2346 poles(i).SetCoord(U, V);
2350 mults(1) = mults(nbpnt) = 2;
2352 return new Geom2d_BSplineCurve(poles,knots,mults,1);
2354 //=======================================================================
2355 //function : PrepareLines3D
2357 //=======================================================================
2358 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
2360 Standard_Integer i, aNbCurves;
2361 GeomAbs_SurfaceType aType1, aType2;
2362 IntTools_SequenceOfCurves aNewCvs;
2364 // 1. Treatment closed curves
2365 aNbCurves=mySeqOfCurve.Length();
2366 for (i=1; i<=aNbCurves; ++i) {
2367 const IntTools_Curve& aIC=mySeqOfCurve(i);
2370 Standard_Integer j, aNbC;
2371 IntTools_SequenceOfCurves aSeqCvs;
2373 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2375 for (j=1; j<=aNbC; ++j) {
2376 const IntTools_Curve& aICNew=aSeqCvs(j);
2377 aNewCvs.Append(aICNew);
2381 aNewCvs.Append(aIC);
2385 aNewCvs.Append(aIC);
2389 // 2. Plane\Cone intersection when we had 4 curves
2390 aType1=myHS1->GetType();
2391 aType2=myHS2->GetType();
2392 aNbCurves=aNewCvs.Length();
2394 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2395 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
2397 GeomAbs_CurveType aCType1;
2399 aCType1=aNewCvs(1).Type();
2400 if (aCType1==GeomAbs_Line) {
2401 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2403 for (i=1; i<=aNbCurves; ++i) {
2404 const IntTools_Curve& aIC=aNewCvs(i);
2408 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2411 aNbCurves=aSeqOut.Length();
2412 for (i=1; i<=aNbCurves; ++i) {
2413 const IntTools_Curve& aIC=aSeqOut(i);
2414 aNewCvs.Append(aIC);
2418 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
2420 // 3. Fill mySeqOfCurve
2421 mySeqOfCurve.Clear();
2422 aNbCurves=aNewCvs.Length();
2423 for (i=1; i<=aNbCurves; ++i) {
2424 const IntTools_Curve& aIC=aNewCvs(i);
2425 mySeqOfCurve.Append(aIC);
2428 //=======================================================================
2429 //function : CorrectSurfaceBoundaries
2431 //=======================================================================
2432 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
2433 const Standard_Real theTolerance,
2434 Standard_Real& theumin,
2435 Standard_Real& theumax,
2436 Standard_Real& thevmin,
2437 Standard_Real& thevmax)
2439 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2440 Standard_Real uinf, usup, vinf, vsup, delta;
2441 GeomAbs_SurfaceType aType;
2442 Handle(Geom_Surface) aSurface;
2444 aSurface = BRep_Tool::Surface(theFace);
2445 aSurface->Bounds(uinf, usup, vinf, vsup);
2446 delta = theTolerance;
2447 enlarge = Standard_False;
2449 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2451 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2452 Handle(Geom_Surface) aBasisSurface =
2453 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2455 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2456 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2461 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2462 Handle(Geom_Surface) aBasisSurface =
2463 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2465 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2466 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2471 isuperiodic = anAdaptorSurface.IsUPeriodic();
2472 isvperiodic = anAdaptorSurface.IsVPeriodic();
2474 aType=anAdaptorSurface.GetType();
2475 if((aType==GeomAbs_BezierSurface) ||
2476 (aType==GeomAbs_BSplineSurface) ||
2477 (aType==GeomAbs_SurfaceOfExtrusion) ||
2478 (aType==GeomAbs_SurfaceOfRevolution)) {
2479 enlarge=Standard_True;
2482 if(!isuperiodic && enlarge) {
2484 if((theumin - uinf) > delta )
2490 if((usup - theumax) > delta )
2496 if(!isvperiodic && enlarge) {
2497 if((thevmin - vinf) > delta ) {
2503 if((vsup - thevmax) > delta ) {
2512 Standard_Integer aNbP;
2513 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2515 aTolPA=Precision::Angular();
2518 aXP=anAdaptorSurface.UPeriod();
2519 dXfact=theumax-theumin;
2520 if (dXfact-aTolPA>aXP) {
2521 aXmid=0.5*(theumax+theumin);
2522 aNbP=RealToInt(aXmid/aXP);
2527 if (theumin>aTolPA) {
2528 aX1=theumin+aNbP*aXP;
2541 aXP=anAdaptorSurface.VPeriod();
2542 dXfact=thevmax-thevmin;
2543 if (dXfact-aTolPA>aXP) {
2544 aXmid=0.5*(thevmax+thevmin);
2545 aNbP=RealToInt(aXmid/aXP);
2550 if (thevmin>aTolPA) {
2551 aX1=thevmin+aNbP*aXP;
2564 if(isuperiodic || isvperiodic) {
2565 Standard_Boolean correct = Standard_False;
2566 Standard_Boolean correctU = Standard_False;
2567 Standard_Boolean correctV = Standard_False;
2569 TopExp_Explorer anExp;
2571 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2572 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
2573 correct = Standard_True;
2575 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2577 for(Standard_Integer i = 0; i < 2; i++) {
2579 anEdge.Orientation(TopAbs_FORWARD);
2582 anEdge.Orientation(TopAbs_REVERSED);
2584 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2586 if(aCurve.IsNull()) {
2587 correct = Standard_False;
2590 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2592 if(aLine.IsNull()) {
2593 correct = Standard_False;
2596 gp_Dir2d anUDir(1., 0.);
2597 gp_Dir2d aVDir(0., 1.);
2598 Standard_Real anAngularTolerance = Precision::Angular();
2600 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2601 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2603 gp_Pnt2d pp1 = aCurve->Value(f);
2605 gp_Pnt2d pp2 = aCurve->Value(l);
2614 Standard_Real umin, vmin, umax, vmax;
2615 aBox.Get(umin, vmin, umax, vmax);
2617 if(isuperiodic && correctU) {
2622 if(theumax > umax) {
2626 if(isvperiodic && correctV) {
2638 // The block is dedicated to determine whether WLine [ifprm, ilprm]
2639 // crosses the degenerated zone on each given surface or not.
2640 // If Yes -> We will not use info about surfaces during approximation
2641 // because inside degenerated zone of the surface the approx. algo.
2642 // uses wrong values of normal, etc., and resulting curve will have
2643 // oscillations that we would not like to have.
2644 // PKV Tue Feb 12 2002
2648 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2649 const Handle(Geom_Surface)& aS,
2650 const Standard_Integer iDir);
2652 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2653 const TopoDS_Face& aF1,
2654 const TopoDS_Face& aF2);
2655 //=======================================================================
2656 //function : NotUseSurfacesForApprox
2658 //=======================================================================
2659 Standard_Boolean NotUseSurfacesForApprox(const TopoDS_Face& aF1,
2660 const TopoDS_Face& aF2,
2661 const Handle(IntPatch_WLine)& WL,
2662 const Standard_Integer ifprm,
2663 const Standard_Integer ilprm)
2665 Standard_Boolean bPInDZ;
2667 Handle(IntSurf_LineOn2S) aLineOn2S=WL->Curve();
2669 const IntSurf_PntOn2S& aP2Sfprm=aLineOn2S->Value(ifprm);
2670 bPInDZ=IsPointInDegeneratedZone(aP2Sfprm, aF1, aF2);
2675 const IntSurf_PntOn2S& aP2Slprm=aLineOn2S->Value(ilprm);
2676 bPInDZ=IsPointInDegeneratedZone(aP2Slprm, aF1, aF2);
2680 //=======================================================================
2681 //function : IsPointInDegeneratedZone
2683 //=======================================================================
2684 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2685 const TopoDS_Face& aF1,
2686 const TopoDS_Face& aF2)
2689 Standard_Boolean bFlag=Standard_True;
2690 Standard_Real US11, US12, VS11, VS12, US21, US22, VS21, VS22;
2691 Standard_Real U1, V1, U2, V2, aDelta, aD;
2694 Handle(Geom_Surface)aS1 = BRep_Tool::Surface(aF1);
2695 aS1->Bounds(US11, US12, VS11, VS12);
2696 GeomAdaptor_Surface aGAS1(aS1);
2698 Handle(Geom_Surface)aS2 = BRep_Tool::Surface(aF2);
2699 aS1->Bounds(US21, US22, VS21, VS22);
2700 GeomAdaptor_Surface aGAS2(aS2);
2702 //const gp_Pnt& aP=aP2S.Value();
2703 aP2S.Parameters(U1, V1, U2, V2);
2707 aD=aGAS1.UResolution(aDelta);
2708 aP2d.SetCoord(U1, V1);
2709 if (fabs(U1-US11) < aD) {
2710 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2715 if (fabs(U1-US12) < aD) {
2716 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2721 aD=aGAS1.VResolution(aDelta);
2722 if (fabs(V1-VS11) < aDelta) {
2723 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2728 if (fabs(V1-VS12) < aDelta) {
2729 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2735 aD=aGAS2.UResolution(aDelta);
2736 aP2d.SetCoord(U2, V2);
2737 if (fabs(U2-US21) < aDelta) {
2738 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2743 if (fabs(U2-US22) < aDelta) {
2744 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2749 aD=aGAS2.VResolution(aDelta);
2750 if (fabs(V2-VS21) < aDelta) {
2751 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2756 if (fabs(V2-VS22) < aDelta) {
2757 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2765 //=======================================================================
2766 //function : IsDegeneratedZone
2768 //=======================================================================
2769 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2770 const Handle(Geom_Surface)& aS,
2771 const Standard_Integer iDir)
2773 Standard_Boolean bFlag=Standard_True;
2774 Standard_Real US1, US2, VS1, VS2, dY, dX, d1, d2, dD;
2775 Standard_Real aXm, aYm, aXb, aYb, aXe, aYe;
2776 aS->Bounds(US1, US2, VS1, VS2);
2778 gp_Pnt aPm, aPb, aPe;
2783 aS->D0(aXm, aYm, aPm);
2800 aS->D0(aXb, aYb, aPb);
2801 aS->D0(aXe, aYe, aPe);
2803 d1=aPm.Distance(aPb);
2804 d2=aPm.Distance(aPe);
2805 if (d1 < dD && d2 < dD) {
2822 aS->D0(aXb, aYb, aPb);
2823 aS->D0(aXe, aYe, aPe);
2825 d1=aPm.Distance(aPb);
2826 d2=aPm.Distance(aPe);
2827 if (d1 < dD && d2 < dD) {
2835 //=========================================================================
2836 // static function : ComputePurgedWLine
2837 // purpose : Removes equal points (leave one of equal points) from theWLine
2838 // and recompute vertex parameters.
2839 // Returns new WLine or null WLine if the number
2840 // of the points is less than 2.
2841 //=========================================================================
2842 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
2844 Standard_Integer i, k, v, nb, nbvtx;
2845 Handle(IntPatch_WLine) aResult;
2846 nbvtx = theWLine->NbVertex();
2847 nb = theWLine->NbPnts();
2849 const IntSurf_PntOn2S& p1 = theWLine->Point(1);
2850 const IntSurf_PntOn2S& p2 = theWLine->Point(2);
2851 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2856 Handle(IntPatch_WLine) aLocalWLine;
2857 Handle(IntPatch_WLine) aTmpWLine = theWLine;
2858 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
2859 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2860 for(i = 1; i <= nb; i++) {
2861 aLineOn2S->Add(theWLine->Point(i));
2864 for(v = 1; v <= nbvtx; v++) {
2865 aLocalWLine->AddVertex(theWLine->Vertex(v));
2868 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
2869 Standard_Integer aStartIndex = i + 1;
2870 Standard_Integer anEndIndex = i + 5;
2871 nb = aLineOn2S->NbPoints();
2872 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
2874 if((aStartIndex > nb) || (anEndIndex <= 1)) {
2879 while(k <= anEndIndex) {
2882 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
2883 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
2885 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2886 aTmpWLine = aLocalWLine;
2887 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2889 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
2890 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
2891 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
2893 if(avertexindex >= k) {
2894 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
2896 aLocalWLine->AddVertex(aVertex);
2898 aLineOn2S->RemovePoint(k);
2907 if(aLineOn2S->NbPoints() > 1) {
2908 aResult = aLocalWLine;
2913 //=======================================================================
2916 //=======================================================================
2917 void TolR3d(const TopoDS_Face& aF1,
2918 const TopoDS_Face& aF2,
2919 Standard_Real& myTolReached3d)
2921 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
2923 aTolTresh=2.999999e-3;
2924 aTolF1 = BRep_Tool::Tolerance(aF1);
2925 aTolF2 = BRep_Tool::Tolerance(aF2);
2926 aTolFMax=Max(aTolF1, aTolF2);
2928 if (aTolFMax>aTolTresh) {
2929 myTolReached3d=aTolFMax;
2932 //=======================================================================
2933 //function : AdjustPeriodic
2935 //=======================================================================
2936 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
2937 const Standard_Real parmin,
2938 const Standard_Real parmax,
2939 const Standard_Real thePeriod,
2940 Standard_Real& theOffset)
2942 Standard_Real aresult;
2945 aresult = theParameter;
2946 while(aresult < parmin) {
2947 aresult += thePeriod;
2948 theOffset += thePeriod;
2951 while(aresult > parmax) {
2952 aresult -= thePeriod;
2953 theOffset -= thePeriod;
2957 //=======================================================================
2958 //function : IsPointOnBoundary
2960 //=======================================================================
2961 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
2962 const Standard_Real theFirstBoundary,
2963 const Standard_Real theSecondBoundary,
2964 const Standard_Real theResolution,
2965 Standard_Boolean& IsOnFirstBoundary)
2967 Standard_Boolean bRet;
2969 Standard_Real adist;
2971 bRet=Standard_False;
2972 for(i = 0; i < 2; ++i) {
2973 IsOnFirstBoundary = (i == 0);
2974 if (IsOnFirstBoundary) {
2975 adist = fabs(theParameter - theFirstBoundary);
2978 adist = fabs(theParameter - theSecondBoundary);
2980 if(adist < theResolution) {
2986 // ------------------------------------------------------------------------------------------------
2987 // static function: FindPoint
2989 // ------------------------------------------------------------------------------------------------
2990 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
2991 const gp_Pnt2d& theLastPoint,
2992 const Standard_Real theUmin,
2993 const Standard_Real theUmax,
2994 const Standard_Real theVmin,
2995 const Standard_Real theVmax,
2996 gp_Pnt2d& theNewPoint) {
2998 gp_Vec2d aVec(theFirstPoint, theLastPoint);
2999 Standard_Integer i = 0, j = 0;
3001 for(i = 0; i < 4; i++) {
3002 gp_Vec2d anOtherVec;
3003 gp_Vec2d anOtherVecNormal;
3004 gp_Pnt2d aprojpoint = theLastPoint;
3007 anOtherVec.SetX(0.);
3008 anOtherVec.SetY(1.);
3009 anOtherVecNormal.SetX(1.);
3010 anOtherVecNormal.SetY(0.);
3013 aprojpoint.SetX(theUmin);
3015 aprojpoint.SetX(theUmax);
3018 anOtherVec.SetX(1.);
3019 anOtherVec.SetY(0.);
3020 anOtherVecNormal.SetX(0.);
3021 anOtherVecNormal.SetY(1.);
3024 aprojpoint.SetY(theVmin);
3026 aprojpoint.SetY(theVmax);
3028 gp_Vec2d anormvec = aVec;
3029 anormvec.Normalize();
3030 RefineVector(anormvec);
3031 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
3033 if(fabs(adot1) < Precision::Angular())
3035 Standard_Real adist = 0.;
3036 Standard_Boolean bIsOut = Standard_False;
3039 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
3040 bIsOut = (i < 2) ? (theLastPoint.X() < theUmin) : (theLastPoint.X() > theUmax);
3043 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
3044 bIsOut = (i < 2) ? (theLastPoint.Y() < theVmin) : (theLastPoint.Y() > theVmax);
3046 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
3048 for(j = 0; j < 2; j++) {
3049 anoffset = (j == 0) ? anoffset : -anoffset;
3050 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
3051 gp_Vec2d acurvec(theLastPoint, acurpoint);
3055 Standard_Real aDotX, anAngleX;
3057 aDotX = aVec.Dot(acurvec);
3058 anAngleX = aVec.Angle(acurvec);
3060 if(aDotX > 0. && fabs(anAngleX) < Precision::PConfusion()) {
3062 if((acurpoint.Y() >= theVmin) &&
3063 (acurpoint.Y() <= theVmax)) {
3064 theNewPoint = acurpoint;
3065 return Standard_True;
3069 if((acurpoint.X() >= theUmin) &&
3070 (acurpoint.X() <= theUmax)) {
3071 theNewPoint = acurpoint;
3072 return Standard_True;
3078 return Standard_False;
3082 // ------------------------------------------------------------------------------------------------
3083 // static function: FindPoint
3084 // purpose: Find point on the boundary of radial tangent zone
3085 // ------------------------------------------------------------------------------------------------
3086 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
3087 const gp_Pnt2d& theLastPoint,
3088 const Standard_Real theUmin,
3089 const Standard_Real theUmax,
3090 const Standard_Real theVmin,
3091 const Standard_Real theVmax,
3092 const gp_Pnt2d& theTanZoneCenter,
3093 const Standard_Real theZoneRadius,
3094 Handle(GeomAdaptor_HSurface) theGASurface,
3095 gp_Pnt2d& theNewPoint) {
3096 theNewPoint = theLastPoint;
3098 if ( !IsInsideTanZone( theLastPoint, theTanZoneCenter, theZoneRadius, theGASurface) )
3099 return Standard_False;
3101 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3102 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3104 Standard_Real aRadius = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3105 gp_Ax22d anAxis( theTanZoneCenter, gp_Dir2d(1, 0), gp_Dir2d(0, 1) );
3106 gp_Circ2d aCircle( anAxis, aRadius );
3109 gp_Vec2d aDir( theLastPoint.XY() - theFirstPoint.XY() );
3110 Standard_Real aLength = aDir.Magnitude();
3111 if ( aLength <= gp::Resolution() )
3112 return Standard_False;
3113 gp_Lin2d aLine( theFirstPoint, aDir );
3116 Handle(Geom2d_Line) aCLine = new Geom2d_Line( aLine );
3117 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve( aCLine, 0, aLength );
3118 Handle(Geom2d_Circle) aC2 = new Geom2d_Circle( aCircle );
3120 Standard_Real aTol = aRadius * 0.001;
3121 aTol = ( aTol < Precision::PConfusion() ) ? Precision::PConfusion() : aTol;
3123 Geom2dAPI_InterCurveCurve anIntersector;
3124 anIntersector.Init( aC1, aC2, aTol );
3126 if ( anIntersector.NbPoints() == 0 )
3127 return Standard_False;
3129 Standard_Boolean aFound = Standard_False;
3130 Standard_Real aMinDist = aLength * aLength;
3131 Standard_Integer i = 0;
3132 for ( i = 1; i <= anIntersector.NbPoints(); i++ ) {
3133 gp_Pnt2d aPInt = anIntersector.Point( i );
3134 if ( aPInt.SquareDistance( theFirstPoint ) < aMinDist ) {
3135 if ( ( aPInt.X() >= theUmin ) && ( aPInt.X() <= theUmax ) &&
3136 ( aPInt.Y() >= theVmin ) && ( aPInt.Y() <= theVmax ) ) {
3137 theNewPoint = aPInt;
3138 aFound = Standard_True;
3146 // ------------------------------------------------------------------------------------------------
3147 // static function: IsInsideTanZone
3148 // purpose: Check if point is inside a radial tangent zone
3149 // ------------------------------------------------------------------------------------------------
3150 Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
3151 const gp_Pnt2d& theTanZoneCenter,
3152 const Standard_Real theZoneRadius,
3153 Handle(GeomAdaptor_HSurface) theGASurface) {
3155 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3156 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3157 Standard_Real aRadiusSQR = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3158 aRadiusSQR *= aRadiusSQR;
3159 if ( thePoint.SquareDistance( theTanZoneCenter ) <= aRadiusSQR )
3160 return Standard_True;
3161 return Standard_False;
3164 // ------------------------------------------------------------------------------------------------
3165 // static function: CheckTangentZonesExist
3166 // purpose: Check if tangent zone exists
3167 // ------------------------------------------------------------------------------------------------
3168 Standard_Boolean CheckTangentZonesExist( const Handle(GeomAdaptor_HSurface)& theSurface1,
3169 const Handle(GeomAdaptor_HSurface)& theSurface2 )
3171 if ( ( theSurface1->GetType() != GeomAbs_Torus ) ||
3172 ( theSurface2->GetType() != GeomAbs_Torus ) )
3173 return Standard_False;
3175 gp_Torus aTor1 = theSurface1->Torus();
3176 gp_Torus aTor2 = theSurface2->Torus();
3178 if ( aTor1.Location().Distance( aTor2.Location() ) > Precision::Confusion() )
3179 return Standard_False;
3181 if ( ( fabs( aTor1.MajorRadius() - aTor2.MajorRadius() ) > Precision::Confusion() ) ||
3182 ( fabs( aTor1.MinorRadius() - aTor2.MinorRadius() ) > Precision::Confusion() ) )
3183 return Standard_False;
3185 if ( ( aTor1.MajorRadius() < aTor1.MinorRadius() ) ||
3186 ( aTor2.MajorRadius() < aTor2.MinorRadius() ) )
3187 return Standard_False;
3188 return Standard_True;
3191 // ------------------------------------------------------------------------------------------------
3192 // static function: ComputeTangentZones
3194 // ------------------------------------------------------------------------------------------------
3195 Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
3196 const Handle(GeomAdaptor_HSurface)& theSurface2,
3197 const TopoDS_Face& theFace1,
3198 const TopoDS_Face& theFace2,
3199 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
3200 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
3201 Handle(TColStd_HArray1OfReal)& theResultRadius,
3202 const Handle(IntTools_Context)& aContext)
3204 Standard_Integer aResult = 0;
3205 if ( !CheckTangentZonesExist( theSurface1, theSurface2 ) )
3209 TColgp_SequenceOfPnt2d aSeqResultS1, aSeqResultS2;
3210 TColStd_SequenceOfReal aSeqResultRad;
3212 gp_Torus aTor1 = theSurface1->Torus();
3213 gp_Torus aTor2 = theSurface2->Torus();
3215 gp_Ax2 anax1( aTor1.Location(), aTor1.Axis().Direction() );
3216 gp_Ax2 anax2( aTor2.Location(), aTor2.Axis().Direction() );
3217 Standard_Integer j = 0;
3219 for ( j = 0; j < 2; j++ ) {
3220 Standard_Real aCoef = ( j == 0 ) ? -1 : 1;
3221 Standard_Real aRadius1 = fabs(aTor1.MajorRadius() + aCoef * aTor1.MinorRadius());
3222 Standard_Real aRadius2 = fabs(aTor2.MajorRadius() + aCoef * aTor2.MinorRadius());
3224 gp_Circ aCircle1( anax1, aRadius1 );
3225 gp_Circ aCircle2( anax2, aRadius2 );
3227 // roughly compute radius of tangent zone for perpendicular case
3228 Standard_Real aCriteria = Precision::Confusion() * 0.5;
3230 Standard_Real aT1 = aCriteria;
3231 Standard_Real aT2 = aCriteria;
3233 // internal tangency
3234 Standard_Real aR = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3235 //aT1 = aCriteria * aCriteria + aR * aR - ( aR - aCriteria ) * ( aR - aCriteria );
3236 aT1 = 2. * aR * aCriteria;
3240 // external tangency
3241 Standard_Real aRb = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3242 Standard_Real aRm = ( aRadius1 < aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3243 Standard_Real aDelta = aRb - aCriteria;
3245 aDelta -= aRm * aRm;
3246 aDelta /= 2. * (aRb - aRm);
3247 aDelta -= 0.5 * (aRb - aRm);
3249 aT1 = 2. * aRm * (aRm - aDelta);
3252 aCriteria = ( aT1 > aT2) ? aT1 : aT2;
3253 if ( aCriteria > 0 )
3254 aCriteria = sqrt( aCriteria );
3256 if ( aCriteria > 0.5 * aTor1.MinorRadius() ) {
3257 // too big zone -> drop to minimum
3258 aCriteria = Precision::Confusion();
3261 GeomAdaptor_Curve aC1( new Geom_Circle(aCircle1) );
3262 GeomAdaptor_Curve aC2( new Geom_Circle(aCircle2) );
3263 Extrema_ExtCC anExtrema(aC1, aC2, 0, 2. * M_PI, 0, 2. * M_PI,
3264 Precision::PConfusion(), Precision::PConfusion());
3266 if ( anExtrema.IsDone() ) {
3268 Standard_Integer i = 0;
3269 for ( i = 1; i <= anExtrema.NbExt(); i++ ) {
3270 if ( anExtrema.SquareDistance(i) > aCriteria * aCriteria )
3273 Extrema_POnCurv P1, P2;
3274 anExtrema.Points( i, P1, P2 );
3276 Standard_Boolean bFoundResult = Standard_True;
3279 Standard_Integer surfit = 0;
3280 for ( surfit = 0; surfit < 2; surfit++ ) {
3281 GeomAPI_ProjectPointOnSurf& aProjector =
3282 (surfit == 0) ? aContext->ProjPS(theFace1) : aContext->ProjPS(theFace2);
3284 gp_Pnt aP3d = (surfit == 0) ? P1.Value() : P2.Value();
3285 aProjector.Perform(aP3d);
3287 if(!aProjector.IsDone())
3288 bFoundResult = Standard_False;
3290 if(aProjector.LowerDistance() > aCriteria) {
3291 bFoundResult = Standard_False;
3294 Standard_Real foundU = 0, foundV = 0;
3295 aProjector.LowerDistanceParameters(foundU, foundV);
3297 pr1 = gp_Pnt2d( foundU, foundV );
3299 pr2 = gp_Pnt2d( foundU, foundV );
3303 if ( bFoundResult ) {
3304 aSeqResultS1.Append( pr1 );
3305 aSeqResultS2.Append( pr2 );
3306 aSeqResultRad.Append( aCriteria );
3308 // torus is u and v periodic
3309 const Standard_Real twoPI = M_PI + M_PI;
3310 Standard_Real arr1tmp[2] = {pr1.X(), pr1.Y()};
3311 Standard_Real arr2tmp[2] = {pr2.X(), pr2.Y()};
3313 // iteration on period bounds
3314 for ( Standard_Integer k1 = 0; k1 < 2; k1++ ) {
3315 Standard_Real aBound = ( k1 == 0 ) ? 0 : twoPI;
3316 Standard_Real aShift = ( k1 == 0 ) ? twoPI : -twoPI;
3318 // iteration on surfaces
3319 for ( Standard_Integer k2 = 0; k2 < 2; k2++ ) {
3320 Standard_Real* arr1 = ( k2 == 0 ) ? arr1tmp : arr2tmp;
3321 Standard_Real* arr2 = ( k2 != 0 ) ? arr1tmp : arr2tmp;
3322 TColgp_SequenceOfPnt2d& aSeqS1 = ( k2 == 0 ) ? aSeqResultS1 : aSeqResultS2;
3323 TColgp_SequenceOfPnt2d& aSeqS2 = ( k2 != 0 ) ? aSeqResultS1 : aSeqResultS2;
3325 if (fabs(arr1[0] - aBound) < Precision::PConfusion()) {
3326 aSeqS1.Append( gp_Pnt2d( arr1[0] + aShift, arr1[1] ) );
3327 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3328 aSeqResultRad.Append( aCriteria );
3330 if (fabs(arr1[1] - aBound) < Precision::PConfusion()) {
3331 aSeqS1.Append( gp_Pnt2d( arr1[0], arr1[1] + aShift) );
3332 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3333 aSeqResultRad.Append( aCriteria );
3341 aResult = aSeqResultRad.Length();
3343 if ( aResult > 0 ) {
3344 theResultOnS1 = new TColgp_HArray1OfPnt2d( 1, aResult );
3345 theResultOnS2 = new TColgp_HArray1OfPnt2d( 1, aResult );
3346 theResultRadius = new TColStd_HArray1OfReal( 1, aResult );
3348 for ( Standard_Integer i = 1 ; i <= aResult; i++ ) {
3349 theResultOnS1->SetValue( i, aSeqResultS1.Value(i) );
3350 theResultOnS2->SetValue( i, aSeqResultS2.Value(i) );
3351 theResultRadius->SetValue( i, aSeqResultRad.Value(i) );
3357 // ------------------------------------------------------------------------------------------------
3358 // static function: AdjustByNeighbour
3360 // ------------------------------------------------------------------------------------------------
3361 gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
3362 const gp_Pnt2d& theOriginalPoint,
3363 Handle(GeomAdaptor_HSurface) theGASurface) {
3365 gp_Pnt2d ap1 = theaNeighbourPoint;
3366 gp_Pnt2d ap2 = theOriginalPoint;
3368 if ( theGASurface->IsUPeriodic() ) {
3369 Standard_Real aPeriod = theGASurface->UPeriod();
3370 gp_Pnt2d aPTest = ap2;
3371 Standard_Real aSqDistMin = 1.e+100;
3373 for ( Standard_Integer pIt = -1; pIt <= 1; pIt++) {
3374 aPTest.SetX( theOriginalPoint.X() + aPeriod * pIt );
3375 Standard_Real dd = ap1.SquareDistance( aPTest );
3377 if ( dd < aSqDistMin ) {