0022678: Bad result of the Cut operation.
[occt.git] / src / IntTools / IntTools_FaceFace.cxx
CommitLineData
7fd59977 1// File: IntTools_FaceFace.cxx
2// Created: Thu Nov 23 14:52:53 2000
3// Author: Michael KLOKOV
4// Copyright: OPEN CASCADE 2000
5
6
7#include <IntTools_FaceFace.ixx>
8
9#include <Precision.hxx>
10
11#include <TColStd_HArray1OfReal.hxx>
12#include <TColStd_Array1OfReal.hxx>
13#include <TColStd_Array1OfInteger.hxx>
14#include <TColStd_SequenceOfReal.hxx>
15#include <TColStd_ListOfInteger.hxx>
16#include <TColStd_ListIteratorOfListOfInteger.hxx>
17#include <TColStd_Array1OfListOfInteger.hxx>
18
19#include <gp_Lin2d.hxx>
20#include <gp_Ax22d.hxx>
21#include <gp_Circ2d.hxx>
22#include <gp_Torus.hxx>
23#include <gp_Cylinder.hxx>
24
25#include <Bnd_Box.hxx>
26
27#include <TColgp_HArray1OfPnt2d.hxx>
28#include <TColgp_SequenceOfPnt2d.hxx>
29#include <TColgp_Array1OfPnt.hxx>
30#include <TColgp_Array1OfPnt2d.hxx>
31
32#include <IntAna_QuadQuadGeo.hxx>
33
34#include <IntSurf_PntOn2S.hxx>
35#include <IntSurf_LineOn2S.hxx>
36#include <IntSurf_PntOn2S.hxx>
37#include <IntSurf_ListOfPntOn2S.hxx>
38#include <IntRes2d_Domain.hxx>
39#include <ProjLib_Plane.hxx>
40
41#include <IntPatch_GLine.hxx>
42#include <IntPatch_RLine.hxx>
43#include <IntPatch_WLine.hxx>
44#include <IntPatch_ALine.hxx>
45#include <IntPatch_ALineToWLine.hxx>
46
47#include <ElSLib.hxx>
48#include <ElCLib.hxx>
49
50#include <Extrema_ExtCC.hxx>
51#include <Extrema_POnCurv.hxx>
52#include <BndLib_AddSurface.hxx>
53
54#include <Adaptor3d_SurfacePtr.hxx>
55#include <Adaptor2d_HLine2d.hxx>
56
57#include <GeomAbs_SurfaceType.hxx>
58#include <GeomAbs_CurveType.hxx>
59
60#include <Geom_Surface.hxx>
61#include <Geom_Line.hxx>
62#include <Geom_Circle.hxx>
63#include <Geom_Ellipse.hxx>
64#include <Geom_Parabola.hxx>
65#include <Geom_Hyperbola.hxx>
66#include <Geom_TrimmedCurve.hxx>
67#include <Geom_BSplineCurve.hxx>
68#include <Geom_RectangularTrimmedSurface.hxx>
69#include <Geom_OffsetSurface.hxx>
70#include <Geom_Curve.hxx>
71#include <Geom_Conic.hxx>
72
73#include <Geom2d_TrimmedCurve.hxx>
74#include <Geom2d_BSplineCurve.hxx>
75#include <Geom2d_Line.hxx>
76#include <Geom2d_Curve.hxx>
77#include <Geom2d_Circle.hxx>
78
79#include <Geom2dAPI_InterCurveCurve.hxx>
80#include <Geom2dInt_GInter.hxx>
81#include <GeomAdaptor_Curve.hxx>
82#include <GeomAdaptor_HSurface.hxx>
83#include <GeomAdaptor_Surface.hxx>
84#include <GeomLib_CheckBSplineCurve.hxx>
85#include <GeomLib_Check2dBSplineCurve.hxx>
86
87#include <GeomInt_WLApprox.hxx>
88#include <GeomProjLib.hxx>
89#include <GeomAPI_ProjectPointOnSurf.hxx>
90#include <Geom2dAdaptor_Curve.hxx>
91//
92#include <TopoDS.hxx>
93#include <TopoDS_Edge.hxx>
94#include <TopExp_Explorer.hxx>
95
96#include <BRep_Tool.hxx>
97#include <BRepTools.hxx>
98#include <BRepAdaptor_Surface.hxx>
99
100#include <BOPTColStd_Dump.hxx>
101
102#include <IntTools_Curve.hxx>
103#include <IntTools_Tools.hxx>
104#include <IntTools_Tools.hxx>
105#include <IntTools_TopolTool.hxx>
106#include <IntTools_PntOnFace.hxx>
107#include <IntTools_PntOn2Faces.hxx>
108#include <IntTools_Context.hxx>
0fc4f2e2
P
109#include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
110
7fd59977 111//
112static
113 void TolR3d(const TopoDS_Face& ,
114 const TopoDS_Face& ,
115 Standard_Real& );
116static
117 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)&,
118 const Standard_Integer,
119 const Standard_Integer);
120
121static
122 void Parameters(const Handle(GeomAdaptor_HSurface)&,
123 const Handle(GeomAdaptor_HSurface)&,
124 const gp_Pnt&,
125 Standard_Real&,
126 Standard_Real&,
127 Standard_Real&,
128 Standard_Real&);
129
130static
131 void BuildPCurves (Standard_Real f,Standard_Real l,Standard_Real& Tol,
132 const Handle (Geom_Surface)& S,
133 const Handle (Geom_Curve)& C,
134 Handle (Geom2d_Curve)& C2d);
135
136static
137 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
138 const Standard_Real theTolerance,
139 Standard_Real& theumin,
140 Standard_Real& theumax,
141 Standard_Real& thevmin,
142 Standard_Real& thevmax);
143static
144 Standard_Boolean NotUseSurfacesForApprox
145 (const TopoDS_Face& aF1,
146 const TopoDS_Face& aF2,
147 const Handle(IntPatch_WLine)& WL,
148 const Standard_Integer ifprm,
149 const Standard_Integer ilprm);
150
151static
152 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
153
154static
155 Standard_Real AdjustPeriodic(const Standard_Real theParameter,
156 const Standard_Real parmin,
157 const Standard_Real parmax,
158 const Standard_Real thePeriod,
159 Standard_Real& theOffset);
160
161static
162 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
163 const Standard_Integer ideb,
164 const Standard_Integer ifin,
165 const Standard_Boolean onFirst);
166
167static
168 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
169 const Handle(GeomAdaptor_HSurface)& theSurface1,
170 const Handle(GeomAdaptor_HSurface)& theSurface2,
171 const TopoDS_Face& theFace1,
172 const TopoDS_Face& theFace2,
173 const IntTools_LineConstructor& theLConstructor,
174 const Standard_Boolean theAvoidLConstructor,
175 IntPatch_SequenceOfLine& theNewLines,
176 Standard_Real& theReachedTol3d);
177
178static
179 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
180 const Handle(Geom_Curve)& theCurve,
181 const TopoDS_Face& theFace1,
182 const TopoDS_Face& theFace2,
183 const Standard_Real theOtherParameter,
184 const Standard_Boolean bIncreasePar,
185 Standard_Real& theNewParameter);
186
187static
188 Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve);
189
190static
191 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
192 const Standard_Real theFirstBoundary,
193 const Standard_Real theSecondBoundary,
194 const Standard_Real theResolution,
195 Standard_Boolean& IsOnFirstBoundary);
196static
197 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
198 const gp_Pnt2d& theLastPoint,
199 const Standard_Real theUmin,
200 const Standard_Real theUmax,
201 const Standard_Real theVmin,
202 const Standard_Real theVmax,
203 gp_Pnt2d& theNewPoint);
204
205
206static
207 Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
208 const Handle(GeomAdaptor_HSurface)& theSurface2,
209 const TopoDS_Face& theFace1,
210 const TopoDS_Face& theFace2,
211 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
212 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
213 Handle(TColStd_HArray1OfReal)& theResultRadius);
214
215static
216 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
217 const gp_Pnt2d& theLastPoint,
218 const Standard_Real theUmin,
219 const Standard_Real theUmax,
220 const Standard_Real theVmin,
221 const Standard_Real theVmax,
222 const gp_Pnt2d& theTanZoneCenter,
223 const Standard_Real theZoneRadius,
224 Handle(GeomAdaptor_HSurface) theGASurface,
225 gp_Pnt2d& theNewPoint);
226
227static
228 Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
229 const gp_Pnt2d& theTanZoneCenter,
230 const Standard_Real theZoneRadius,
231 Handle(GeomAdaptor_HSurface) theGASurface);
232
233static
234gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
235 const gp_Pnt2d& theOriginalPoint,
236 Handle(GeomAdaptor_HSurface) theGASurface);
237static
238Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
239 const gp_Sphere& theSph);
240
241static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
242 const Handle(GeomAdaptor_HSurface)& theS2,
243 const Standard_Real TolAng,
244 const Standard_Real TolTang,
245 const Standard_Boolean theApprox1,
246 const Standard_Boolean theApprox2,
247 IntTools_SequenceOfCurves& theSeqOfCurve,
248 Standard_Boolean& theTangentFaces);
249
250static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
251 const gp_Lin2d& theLin2d,
252 const Standard_Real theTol,
253 Standard_Real& theP1,
254 Standard_Real& theP2);
0fc4f2e2 255//
7fd59977 256static
257 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
258 const Handle(GeomAdaptor_HSurface)& aHS2,
259 Standard_Integer& iDegMin,
0fc4f2e2 260 Standard_Integer& iDegMax);
7fd59977 261
0fc4f2e2
P
262static
263 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
264 const Handle(GeomAdaptor_HSurface)& aHS2,
265 Standard_Real& aTolArc,
266 Standard_Real& aTolTang,
267 Standard_Real& aUVMaxStep,
268 Standard_Real& aDeflection);
269
270//modified by NIZNHY-PKV Tue Feb 15 10:16:05 2011f
271static
272 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
273 const GeomAbs_SurfaceType aType2);
274static
275 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
276//modified by NIZNHY-PKV Tue Feb 15 10:16:09 2011t
7fd59977 277//
278//=======================================================================
279//function :
280//purpose :
281//=======================================================================
282 IntTools_FaceFace::IntTools_FaceFace()
283{
284 myTangentFaces=Standard_False;
285 //
286 myHS1 = new GeomAdaptor_HSurface ();
287 myHS2 = new GeomAdaptor_HSurface ();
288 myTolReached2d=0.;
289 myTolReached3d=0.;
290 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
291}
292//=======================================================================
293//function : Face1
294//purpose :
295//=======================================================================
296 const TopoDS_Face& IntTools_FaceFace::Face1() const
297{
298 return myFace1;
299}
300
301//=======================================================================
302//function : Face2
303//purpose :
304//=======================================================================
305 const TopoDS_Face& IntTools_FaceFace::Face2() const
306{
307 return myFace2;
308}
309
310//=======================================================================
311//function : TangentFaces
312//purpose :
313//=======================================================================
314 Standard_Boolean IntTools_FaceFace::TangentFaces() const
315{
316 return myTangentFaces;
317}
318//=======================================================================
319//function : Points
320//purpose :
321//=======================================================================
322 const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
323{
324 return myPnts;
325}
326//=======================================================================
327//function : IsDone
328//purpose :
329//=======================================================================
330 Standard_Boolean IntTools_FaceFace::IsDone() const
331{
332 return myIsDone;
333}
334//=======================================================================
335//function : TolReached3d
336//purpose :
337//=======================================================================
338 Standard_Real IntTools_FaceFace::TolReached3d() const
339{
340 return myTolReached3d;
341}
342//=======================================================================
343//function : Lines
344//purpose : return lines of intersection
345//=======================================================================
346 const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
347{
348 StdFail_NotDone_Raise_if(!myIsDone,
349 "IntTools_FaceFace::Lines() => !myIntersector.IsDone()");
350 return mySeqOfCurve;
351}
352
353//=======================================================================
354//function : TolReached2d
355//purpose :
356//=======================================================================
357 Standard_Real IntTools_FaceFace::TolReached2d() const
358{
359 return myTolReached2d;
360}
361// =======================================================================
362// function: SetParameters
363//
364// =======================================================================
365 void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
366 const Standard_Boolean ToApproxC2dOnS1,
367 const Standard_Boolean ToApproxC2dOnS2,
368 const Standard_Real ApproximationTolerance)
369{
370 myApprox = ToApproxC3d;
371 myApprox1 = ToApproxC2dOnS1;
372 myApprox2 = ToApproxC2dOnS2;
373 myTolApprox = ApproximationTolerance;
374}
375//=======================================================================
376//function : SetList
377//purpose :
378//=======================================================================
379
380void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
381{
382 myListOfPnts = aListOfPnts;
383}
0fc4f2e2 384
7fd59977 385//=======================================================================
386//function : Perform
387//purpose : intersect surfaces of the faces
388//=======================================================================
0fc4f2e2
P
389 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
390 const TopoDS_Face& aF2)
7fd59977 391{
0fc4f2e2
P
392 Standard_Boolean hasCone, RestrictLine, bTwoPlanes, bReverse;
393 Standard_Integer aNbLin, aNbPnts, i, NbLinPP;
7fd59977 394 Standard_Real TolArc, TolTang, Deflection, UVMaxStep;
395 Standard_Real umin, umax, vmin, vmax;
396 Standard_Real aTolF1, aTolF2;
397 GeomAbs_SurfaceType aType1, aType2;
398 Handle(Geom_Surface) S1, S2;
399 Handle(IntTools_TopolTool) dom1, dom2;
0fc4f2e2 400 BRepAdaptor_Surface aBAS1, aBAS2;
7fd59977 401 //
7fd59977 402 mySeqOfCurve.Clear();
7fd59977 403 myTolReached2d=0.;
404 myTolReached3d=0.;
7fd59977 405 myIsDone = Standard_False;
0fc4f2e2
P
406 myNbrestr=0;//?
407 hasCone = Standard_False;
408 bTwoPlanes = Standard_False;
409 //
410 myFace1=aF1;
411 myFace2=aF2;
412 //
413 aBAS1.Initialize(myFace1, Standard_False);
414 aBAS2.Initialize(myFace2, Standard_False);
415 aType1=aBAS1.GetType();
416 aType2=aBAS2.GetType();
417 //
418 //modified by NIZNHY-PKV Tue Feb 15 10:34:39 2011f
419 bReverse=SortTypes(aType1, aType2);
420 if (bReverse) {
421 myFace1=aF2;
422 myFace2=aF1;
423 aType1=aBAS2.GetType();
424 aType2=aBAS1.GetType();
425 //
426 if (myListOfPnts.Extent()) {
427 Standard_Real aU1,aV1,aU2,aV2;
428 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
429 //
430 aItP2S.Initialize(myListOfPnts);
431 for (; aItP2S.More(); aItP2S.Next()){
432 IntSurf_PntOn2S& aP2S=aItP2S.Value();
433 aP2S.Parameters(aU1,aV1,aU2,aV2);
434 aP2S.SetValue(aU2,aV2,aU1,aV1);
435 }
436 }
437 }
438 //modified by NIZNHY-PKV Tue Feb 15 10:34:45 2011t
439 //
440 S1=BRep_Tool::Surface(myFace1);
441 S2=BRep_Tool::Surface(myFace2);
7fd59977 442 //
0fc4f2e2
P
443 aTolF1=BRep_Tool::Tolerance(myFace1);
444 aTolF2=BRep_Tool::Tolerance(myFace2);
7fd59977 445 //
446 TolArc= aTolF1 + aTolF2;
447 TolTang = TolArc;
448 //
0fc4f2e2 449 NbLinPP = 0;
7fd59977 450 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
451 bTwoPlanes = Standard_True;
452
0fc4f2e2 453 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
7fd59977 454 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
455 //
0fc4f2e2 456 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
7fd59977 457 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
458 Standard_Real TolAng = 1.e-8;
0fc4f2e2 459 PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
7fd59977 460 mySeqOfCurve, myTangentFaces);
461
462 myIsDone = Standard_True;
463
0fc4f2e2
P
464 if(myTangentFaces) {
465 return;
466 }
467 //
7fd59977 468 NbLinPP = mySeqOfCurve.Length();
0fc4f2e2
P
469 if(NbLinPP == 0) {
470 return;
471 }
7fd59977 472
473 Standard_Real aTolFMax;
474 //
475 myTolReached3d = 1.e-7;
476 //
477 aTolFMax=Max(aTolF1, aTolF2);
478 //
479 if (aTolFMax>myTolReached3d) {
480 myTolReached3d=aTolFMax;
481 }
482 myTolReached2d = myTolReached3d;
0fc4f2e2
P
483 //modified by NIZNHY-PKV Tue Feb 15 10:33:42 2011f
484 if (bReverse) {
485 Handle(Geom2d_Curve) aC2D1, aC2D2;
486 //
487 aNbLin=mySeqOfCurve.Length();
488 for (i=1; i<=aNbLin; ++i) {
489 IntTools_Curve& aIC=mySeqOfCurve(i);
490 aC2D1=aIC.FirstCurve2d();
491 aC2D2=aIC.SecondCurve2d();
492 //
493 aIC.SetFirstCurve2d(aC2D2);
494 aIC.SetSecondCurve2d(aC2D1);
495 }
496 }
497 //modified by NIZNHY-PKV Tue Feb 15 10:33:46 2011t
7fd59977 498 return;
0fc4f2e2 499 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
7fd59977 500 //
501 if (aType1==GeomAbs_Plane &&
502 (aType2==GeomAbs_Cylinder ||
503 aType2==GeomAbs_Cone ||
504 aType2==GeomAbs_Torus)) {
505 Standard_Real dU, dV;
506 // F1
0fc4f2e2 507 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
7fd59977 508 dU=0.1*(umax-umin);
509 dV=0.1*(vmax-vmin);
510 umin=umin-dU;
511 umax=umax+dU;
512 vmin=vmin-dV;
513 vmax=vmax+dV;
514 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
515 // F2
0fc4f2e2
P
516 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
517 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 518 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
519 //
520 if( aType2==GeomAbs_Cone ) {
521 TolArc = 0.0001;
7fd59977 522 hasCone = Standard_True;
523 }
524 }
525 //
526 else if ((aType1==GeomAbs_Cylinder||
527 aType1==GeomAbs_Cone ||
528 aType1==GeomAbs_Torus) &&
529 aType2==GeomAbs_Plane) {
530 Standard_Real dU, dV;
531 //F1
0fc4f2e2
P
532 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
533 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 534 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
535 // F2
0fc4f2e2 536 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
7fd59977 537 dU=0.1*(umax-umin);
538 dV=0.1*(vmax-vmin);
539 umin=umin-dU;
540 umax=umax+dU;
541 vmin=vmin-dV;
542 vmax=vmax+dV;
543 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
544 //
545 if( aType1==GeomAbs_Cone ) {
546 TolArc = 0.0001;
7fd59977 547 hasCone = Standard_True;
548 }
549 }
550
551 //
552 else {
0fc4f2e2 553 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
7fd59977 554 //
0fc4f2e2 555 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 556 //
557 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
558 //
0fc4f2e2 559 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
7fd59977 560 //
0fc4f2e2 561 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 562 //
563 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
564 }
565 //
566 dom1 = new IntTools_TopolTool(myHS1);
567 dom2 = new IntTools_TopolTool(myHS2);
568 //
569 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
570 //
571 Deflection = (hasCone) ? 0.085 : 0.1;
572 UVMaxStep = 0.001;
573 //
0fc4f2e2
P
574 Tolerances(myHS1, myHS2, TolArc, TolTang, UVMaxStep, Deflection);
575 //
576 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
7fd59977 577 //
578 RestrictLine = Standard_False;
579 //
580 if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
581 (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
582 (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
583 (myHS2->IsVClosed() && !myHS2->IsVPeriodic())) {
584 RestrictLine = Standard_True;
585 }
586 //
587 if(((aType1 != GeomAbs_BSplineSurface) &&
588 (aType1 != GeomAbs_BezierSurface) &&
589 (aType1 != GeomAbs_OtherSurface)) &&
590 ((aType2 != GeomAbs_BSplineSurface) &&
591 (aType2 != GeomAbs_BezierSurface) &&
592 (aType2 != GeomAbs_OtherSurface))) {
593 RestrictLine = Standard_True;
594 //
595 if ((aType1 == GeomAbs_Torus) ||
596 (aType2 == GeomAbs_Torus) ) {
597 myListOfPnts.Clear();
598 }
599 }
600 //
601 if(!RestrictLine) {
602 TopExp_Explorer aExp;
603 //
604 for(i = 0; (!RestrictLine) && (i < 2); i++) {
605 const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
606 aExp.Init(aF, TopAbs_EDGE);
607 for(; aExp.More(); aExp.Next()) {
608 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
609 //
610 if(BRep_Tool::Degenerated(aE)) {
611 RestrictLine = Standard_True;
612 break;
613 }
614 }
615 }
616 }
617 //
618 myIntersector.Perform(myHS1, dom1, myHS2, dom2,
619 TolArc, TolTang,
620 myListOfPnts, RestrictLine);
621 //
622 myIsDone = myIntersector.IsDone();
623 if (myIsDone) {
624 myTangentFaces=myIntersector.TangentFaces();
625 if (myTangentFaces) {
626 return;
627 }
628 //
629 if(RestrictLine) {
630 myListOfPnts.Clear(); // to use LineConstructor
631 }
632 //
633 aNbLin = myIntersector.NbLines();
634 for (i=1; i<=aNbLin; ++i) {
635 MakeCurve(i, dom1, dom2);
636 }
637 //
638 ComputeTolReached3d();
639 //
0fc4f2e2
P
640 //modified by NIZNHY-PKV Tue Feb 15 14:13:25 2011f
641 if (bReverse) {
642 Handle(Geom2d_Curve) aC2D1, aC2D2;
643 //
644 aNbLin=mySeqOfCurve.Length();
645 for (i=1; i<=aNbLin; ++i) {
646 IntTools_Curve& aIC=mySeqOfCurve(i);
647 aC2D1=aIC.FirstCurve2d();
648 aC2D2=aIC.SecondCurve2d();
649 //
650 aIC.SetFirstCurve2d(aC2D2);
651 aIC.SetSecondCurve2d(aC2D1);
652 }
653 }
654 //modified by NIZNHY-PKV Tue Feb 15 14:13:29 2011t
655 //
656 // Points
7fd59977 657 Standard_Real U1,V1,U2,V2;
658 IntTools_PntOnFace aPntOnF1, aPntOnF2;
0fc4f2e2 659 IntTools_PntOn2Faces aPntOn2Faces;
7fd59977 660 //
661 aNbPnts=myIntersector.NbPnts();
662 for (i=1; i<=aNbPnts; ++i) {
663 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
664 const gp_Pnt& aPnt=aISPnt.Value();
665 aISPnt.Parameters(U1,V1,U2,V2);
0fc4f2e2
P
666 aPntOnF1.Init(myFace1, aPnt, U1, V1);
667 aPntOnF2.Init(myFace2, aPnt, U2, V2);
668 //modified by NIZNHY-PKV Tue Feb 15 10:34:10 2011f
669 if (!bReverse) {
670 aPntOn2Faces.SetP1(aPntOnF1);
671 aPntOn2Faces.SetP2(aPntOnF2);
672 }
673 else {
674 aPntOn2Faces.SetP2(aPntOnF1);
675 aPntOn2Faces.SetP1(aPntOnF2);
676 }
677 //aPntOn2Faces.SetP1(aPntOnF1);
678 //aPntOn2Faces.SetP2(aPntOnF2);
679 //modified by NIZNHY-PKV Tue Feb 15 10:34:14 2011t
7fd59977 680 myPnts.Append(aPntOn2Faces);
681 }
682 //
683 }
684}
685//=======================================================================
686//function :ComputeTolReached3d
687//purpose :
688//=======================================================================
689 void IntTools_FaceFace::ComputeTolReached3d()
690{
691 Standard_Integer aNbLin;
692 GeomAbs_SurfaceType aType1, aType2;
693 //
694 aNbLin=myIntersector.NbLines();
695 //
696 aType1=myHS1->Surface().GetType();
697 aType2=myHS2->Surface().GetType();
698 //
699 if (aNbLin==2 &&
700 aType1==GeomAbs_Cylinder &&
701 aType2==GeomAbs_Cylinder) {
702 Handle(IntPatch_Line) aIL1, aIL2;
703 IntPatch_IType aTL1, aTL2;
704 //
705 aIL1=myIntersector.Line(1);
706 aIL2=myIntersector.Line(2);
707 aTL1=aIL1->ArcType();
708 aTL2=aIL2->ArcType();
709 if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
710 Standard_Real aD, aDTresh, dTol;
711 gp_Lin aL1, aL2;
712 //
713 dTol=1.e-8;
714 aDTresh=1.5e-6;
715 //
716 aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
717 aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
718 aD=aL1.Distance(aL2);
719 aD=0.5*aD;
720 if (aD<aDTresh) {
721 myTolReached3d=aD+dTol;
722 }
723 }
724 }
0fc4f2e2 725 //904/G3 f
7fd59977 726 if (aType1==GeomAbs_Plane &&
727 aType2==GeomAbs_Plane) {
728 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
729 //
730 aTolTresh=1.e-7;
731 //
732 aTolF1 = BRep_Tool::Tolerance(myFace1);
733 aTolF2 = BRep_Tool::Tolerance(myFace2);
734 aTolFMax=Max(aTolF1, aTolF2);
735 //
736 if (aTolFMax>aTolTresh) {
737 myTolReached3d=aTolFMax;
738 }
739 }
0fc4f2e2 740 //t
7fd59977 741
742 //IFV Bug OCC20297
743 if((aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane) ||
744 (aType2 == GeomAbs_Cylinder && aType1 == GeomAbs_Plane)) {
745 if(aNbLin == 1) {
746 const Handle(IntPatch_Line)& aIL1 = myIntersector.Line(1);
747 if(aIL1->ArcType() == IntPatch_Circle) {
748 gp_Circ aCir = Handle(IntPatch_GLine)::DownCast(aIL1)->Circle();
749 gp_XYZ aCirDir = aCir.Axis().Direction().XYZ();
750 gp_XYZ aPlDir;
751 gp_Pln aPln;
752 if(aType1 == GeomAbs_Plane) {
753 aPln = myHS1->Surface().Plane();
754 }
755 else {
756 aPln = myHS2->Surface().Plane();
757 }
758 aPlDir = aPln.Axis().Direction().XYZ();
759 Standard_Real cs = aCirDir*aPlDir;
760 if(cs < 0.) aPlDir.Reverse();
761 Standard_Real eps = 1.e-14;
762 if(!aPlDir.IsEqual(aCirDir, eps)) {
763 Standard_Integer aNbP = 11;
764 Standard_Real dt = 2.*PI / (aNbP - 1), t;
765 for(t = 0.; t < 2.*PI; t += dt) {
766 Standard_Real d = aPln.Distance(ElCLib::Value(t, aCir));
767 if(myTolReached3d < d) myTolReached3d = d;
768 }
769 myTolReached3d *= 1.1;
770 }
771 } //aIL1->ArcType() == IntPatch_Circle
772 } //aNbLin == 1
773 } // aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane) ...
774 //End IFV Bug OCC20297
0fc4f2e2
P
775 //
776 //modified by NIZNHY-PKV Mon Feb 14 12:02:46 2011f
777 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
778 (aType2==GeomAbs_Plane && aType1==GeomAbs_Torus)) {
779 aNbLin=mySeqOfCurve.Length();
780 if (aNbLin!=1) {
781 return;
782 }
783 //
784 Standard_Integer i, aNbP;
785 Standard_Real aT, aT1, aT2, dT, aUT, aVT, aUP, aVP;
786 Standard_Real aDP, aDT, aDmax;
787 gp_Pln aPln;
788 gp_Torus aTorus;
789 gp_Pnt aP, aPP, aPT;
790 //
791 const IntTools_Curve& aIC=mySeqOfCurve(1);
792 const Handle(Geom_Curve)& aC3D=aIC.Curve();
793 const Handle(Geom_BSplineCurve)& aBS=Handle(Geom_BSplineCurve)::DownCast(aC3D);
794 if (aBS.IsNull()) {
795 return;
796 }
797 //
798 aT1=aBS->FirstParameter();
799 aT2=aBS->LastParameter();
800 //
801 aPln =(aType1==GeomAbs_Plane) ? myHS1->Plane() : myHS2->Plane();
802 aTorus=(aType1==GeomAbs_Plane) ? myHS2->Torus() : myHS1->Torus();
803 //
804 aDmax=-1.;
805 aNbP=11;
806 dT=(aT2-aT1)/(aNbP-1);
807 for (i=0; i<aNbP; ++i) {
808 aT=aT1+i*dT;
809 if (i==aNbP-1) {
810 aT=aT2;
811 }
812 //
813 aC3D->D0(aT, aP);
814 //
815 ElSLib::Parameters(aPln, aP, aUP, aVP);
816 aPP=ElSLib::Value(aUP, aVP, aPln);
817 aDP=aP.SquareDistance(aPP);
818 if (aDP>aDmax) {
819 aDmax=aDP;
820 }
821 //
822 ElSLib::Parameters(aTorus, aP, aUT, aVT);
823 aPT=ElSLib::Value(aUT, aVT, aTorus);
824 aDT=aP.SquareDistance(aPT);
825 if (aDT>aDmax) {
826 aDmax=aDT;
827 }
828 }
829 //
830 if (aDmax > myTolReached3d*myTolReached3d) {
831 myTolReached3d=sqrt(aDmax);
832 myTolReached3d=1.1*myTolReached3d;
833 }
834 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
835 //modified by NIZNHY-PKV Mon Feb 14 12:02:49 2011t
7fd59977 836}
837//=======================================================================
838//function : MakeCurve
839//purpose :
840//=======================================================================
841 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
842 const Handle(Adaptor3d_TopolTool)& dom1,
843 const Handle(Adaptor3d_TopolTool)& dom2)
844{
845 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
846 Standard_Boolean ok;
847 Standard_Integer i, j, aNbParts;
848 Standard_Real fprm, lprm;
849 Standard_Real Tolpc;
850 Handle(IntPatch_Line) L;
851 IntPatch_IType typl;
852 Handle(Geom_Curve) newc;
853 //
854 const Standard_Real TOLCHECK =0.0000001;
855 const Standard_Real TOLANGCHECK=0.1;
856 //
857 rejectSurface = Standard_False;
858 reApprox = Standard_False;
859
860 reapprox:;
861
862 Tolpc = myTolApprox;
863 bAvoidLineConstructor = Standard_False;
864 L = myIntersector.Line(Index);
865 typl = L->ArcType();
866 //
867 if(typl==IntPatch_Walking) {
868 Handle(IntPatch_Line) anewL;
869 //
870 const Handle(IntPatch_WLine)& aWLine=
871 Handle(IntPatch_WLine)::DownCast(L);
872 //
873 anewL = ComputePurgedWLine(aWLine);
874 if(anewL.IsNull()) {
875 return;
876 }
877 L = anewL;
878 //
879 if(!myListOfPnts.IsEmpty()) {
880 bAvoidLineConstructor = Standard_True;
881 }
882
883 Standard_Integer nbp = aWLine->NbPnts();
884 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
885 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
886
887 const gp_Pnt& P1 = p1.Value();
888 const gp_Pnt& P2 = p2.Value();
889
890 if(P1.SquareDistance(P2) < 1.e-14) {
891 bAvoidLineConstructor = Standard_False;
892 }
893
894 }
895 //
896 // Line Constructor
897 if(!bAvoidLineConstructor) {
898 myLConstruct.Perform(L);
899 //
900 bDone=myLConstruct.IsDone();
901 aNbParts=myLConstruct.NbParts();
902 if (!bDone|| !aNbParts) {
903 return;
904 }
905 }
906 // Do the Curve
907
908
909 typl=L->ArcType();
910 switch (typl) {
911 //########################################
912 // Line, Parabola, Hyperbola
913 //########################################
914 case IntPatch_Lin:
915 case IntPatch_Parabola:
916 case IntPatch_Hyperbola: {
917 if (typl == IntPatch_Lin) {
918 newc =
919 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
920 }
921
922 else if (typl == IntPatch_Parabola) {
923 newc =
924 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
925 }
926
927 else if (typl == IntPatch_Hyperbola) {
928 newc =
929 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
930 }
931 //
932 // myTolReached3d
933 if (typl == IntPatch_Lin) {
934 TolR3d (myFace1, myFace2, myTolReached3d);
935 }
936 //
937 aNbParts=myLConstruct.NbParts();
938 for (i=1; i<=aNbParts; i++) {
939 myLConstruct.Part(i, fprm, lprm);
940
941 if (!Precision::IsNegativeInfinite(fprm) &&
942 !Precision::IsPositiveInfinite(lprm)) {
943 //
944 IntTools_Curve aCurve;
945 //
946 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
947 aCurve.SetCurve(aCT3D);
948 if (typl == IntPatch_Parabola) {
949 Standard_Real aTolF1, aTolF2, aTolBase;
950
951 aTolF1 = BRep_Tool::Tolerance(myFace1);
952 aTolF2 = BRep_Tool::Tolerance(myFace2);
953 aTolBase=aTolF1+aTolF2;
954 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
955 }
956 //
957 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
958 if(myApprox1) {
959 Handle (Geom2d_Curve) C2d;
960 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
961 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
962 myTolReached2d=Tolpc;
963 }
964 //
965 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
966 }
967 else {
968 Handle(Geom2d_BSplineCurve) H1;
969 //
970 aCurve.SetFirstCurve2d(H1);
971 }
972
973 if(myApprox2) {
974 Handle (Geom2d_Curve) C2d;
975 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
976 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
977 myTolReached2d=Tolpc;
978 }
979 //
980 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
981 }
982 else {
983 Handle(Geom2d_BSplineCurve) H1;
984 //
985 aCurve.SetSecondCurve2d(H1);
986 }
987 mySeqOfCurve.Append(aCurve);
988 } // end of if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
989
990 else {
0fc4f2e2 991 // on regarde si on garde
7fd59977 992 //
993 Standard_Boolean bFNIt, bLPIt;
994 Standard_Real aTestPrm, dT=100.;
995
996 bFNIt=Precision::IsNegativeInfinite(fprm);
997 bLPIt=Precision::IsPositiveInfinite(lprm);
998
999 aTestPrm=0.;
1000
1001 if (bFNIt && !bLPIt) {
1002 aTestPrm=lprm-dT;
1003 }
1004 else if (!bFNIt && bLPIt) {
1005 aTestPrm=fprm+dT;
1006 }
1007
1008 gp_Pnt ptref(newc->Value(aTestPrm));
1009 //
1010
1011 Standard_Real u1, v1, u2, v2, Tol;
1012
1013 Tol = Precision::Confusion();
1014 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1015 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1016 if(ok) {
1017 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1018 }
1019 if (ok) {
1020 Handle(Geom2d_BSplineCurve) H1;
1021 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1022 }
1023 }
1024 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
1025 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
1026 break;
1027
1028 //########################################
1029 // Circle and Ellipse
1030 //########################################
1031 case IntPatch_Circle:
1032 case IntPatch_Ellipse: {
1033
1034 if (typl == IntPatch_Circle) {
1035 newc = new Geom_Circle
1036 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
1037 }
1038 else { //IntPatch_Ellipse
1039 newc = new Geom_Ellipse
1040 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
1041 }
1042 //
1043 // myTolReached3d
1044 TolR3d (myFace1, myFace2, myTolReached3d);
1045 //
1046 aNbParts=myLConstruct.NbParts();
1047 //
1048 Standard_Real aPeriod, aNul;
1049 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
1050
1051 aNul=0.;
1052 aPeriod=PI+PI;
1053
1054 for (i=1; i<=aNbParts; i++) {
1055 myLConstruct.Part(i, fprm, lprm);
1056
1057 if (fprm < aNul && lprm > aNul) {
1058 // interval that goes through 0. is divided on two intervals;
1059 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1060 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1061 //
1062 if((aPeriod - fprm) > Tolpc) {
1063 aSeqFprm.Append(fprm);
1064 aSeqLprm.Append(aPeriod);
1065 }
1066 else {
1067 gp_Pnt P1 = newc->Value(fprm);
1068 gp_Pnt P2 = newc->Value(aPeriod);
1069 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1070 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1071
1072 if(P1.Distance(P2) > aTolDist) {
1073 Standard_Real anewpar = fprm;
1074
1075 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2, lprm, Standard_False, anewpar)) {
1076 fprm = anewpar;
1077 }
1078 aSeqFprm.Append(fprm);
1079 aSeqLprm.Append(aPeriod);
1080 }
1081 }
1082
1083 //
1084 if((lprm - aNul) > Tolpc) {
1085 aSeqFprm.Append(aNul);
1086 aSeqLprm.Append(lprm);
1087 }
1088 else {
1089 gp_Pnt P1 = newc->Value(aNul);
1090 gp_Pnt P2 = newc->Value(lprm);
1091 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1092 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1093
1094 if(P1.Distance(P2) > aTolDist) {
1095 Standard_Real anewpar = lprm;
1096
1097 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2, fprm, Standard_True, anewpar)) {
1098 lprm = anewpar;
1099 }
1100 aSeqFprm.Append(aNul);
1101 aSeqLprm.Append(lprm);
1102 }
1103 }
1104 }
1105 else {
1106 // usual interval
1107 aSeqFprm.Append(fprm);
1108 aSeqLprm.Append(lprm);
1109 }
1110 }
1111
1112 //
1113 aNbParts=aSeqFprm.Length();
1114 for (i=1; i<=aNbParts; i++) {
1115 fprm=aSeqFprm(i);
1116 lprm=aSeqLprm(i);
1117 //
1118 Standard_Real aRealEpsilon=RealEpsilon();
1119 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*PI) > aRealEpsilon) {
1120 //==============================================
1121 ////
1122 IntTools_Curve aCurve;
1123 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1124 aCurve.SetCurve(aTC3D);
1125 fprm=aTC3D->FirstParameter();
1126 lprm=aTC3D->LastParameter ();
1127 ////
1128 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1129 if(myApprox1) {
1130 Handle (Geom2d_Curve) C2d;
1131 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
1132 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1133 myTolReached2d=Tolpc;
1134 }
1135 //
1136 aCurve.SetFirstCurve2d(C2d);
1137 }
1138 else { ////
1139 Handle(Geom2d_BSplineCurve) H1;
1140 aCurve.SetFirstCurve2d(H1);
1141 }
1142
1143
1144 if(myApprox2) {
1145 Handle (Geom2d_Curve) C2d;
1146 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
1147 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1148 myTolReached2d=Tolpc;
1149 }
1150 //
1151 aCurve.SetSecondCurve2d(C2d);
1152 }
1153 else {
1154 Handle(Geom2d_BSplineCurve) H1;
1155 aCurve.SetSecondCurve2d(H1);
1156 }
1157 }
1158
1159 else {
1160 Handle(Geom2d_BSplineCurve) H1;
1161 aCurve.SetFirstCurve2d(H1);
1162 aCurve.SetSecondCurve2d(H1);
1163 }
1164 mySeqOfCurve.Append(aCurve);
1165 //==============================================
1166 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*PI) > RealEpsilon())
1167
1168 else {
1169 // on regarde si on garde
1170 //
1171 if (aNbParts==1) {
1172// if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*PI) < RealEpsilon()) {
1173 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*PI) <= aRealEpsilon) {
1174 IntTools_Curve aCurve;
1175 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1176 aCurve.SetCurve(aTC3D);
1177 fprm=aTC3D->FirstParameter();
1178 lprm=aTC3D->LastParameter ();
1179
1180 if(myApprox1) {
1181 Handle (Geom2d_Curve) C2d;
1182 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
1183 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1184 myTolReached2d=Tolpc;
1185 }
1186 //
1187 aCurve.SetFirstCurve2d(C2d);
1188 }
1189 else { ////
1190 Handle(Geom2d_BSplineCurve) H1;
1191 aCurve.SetFirstCurve2d(H1);
1192 }
1193
1194 if(myApprox2) {
1195 Handle (Geom2d_Curve) C2d;
1196 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
1197 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1198 myTolReached2d=Tolpc;
1199 }
1200 //
1201 aCurve.SetSecondCurve2d(C2d);
1202 }
1203 else {
1204 Handle(Geom2d_BSplineCurve) H1;
1205 aCurve.SetSecondCurve2d(H1);
1206 }
1207 mySeqOfCurve.Append(aCurve);
1208 break;
1209 }
1210 }
1211 //
1212 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1213
1214 aTwoPIdiv17=2.*PI/17.;
1215
1216 for (j=0; j<=17; j++) {
1217 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1218 Tol = Precision::Confusion();
1219
1220 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1221 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1222 if(ok) {
1223 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1224 }
1225 if (ok) {
1226 IntTools_Curve aCurve;
1227 aCurve.SetCurve(newc);
1228 //==============================================
1229 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1230
1231 if(myApprox1) {
1232 Handle (Geom2d_Curve) C2d;
1233 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
1234 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1235 myTolReached2d=Tolpc;
1236 }
1237 //
1238 aCurve.SetFirstCurve2d(C2d);
1239 }
1240 else {
1241 Handle(Geom2d_BSplineCurve) H1;
1242 aCurve.SetFirstCurve2d(H1);
1243 }
1244
1245 if(myApprox2) {
1246 Handle (Geom2d_Curve) C2d;
1247 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
1248 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1249 myTolReached2d=Tolpc;
1250 }
1251 //
1252 aCurve.SetSecondCurve2d(C2d);
1253 }
1254
1255 else {
1256 Handle(Geom2d_BSplineCurve) H1;
1257 aCurve.SetSecondCurve2d(H1);
1258 }
1259 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1260
1261 else {
1262 Handle(Geom2d_BSplineCurve) H1;
1263 //
1264 aCurve.SetFirstCurve2d(H1);
1265 aCurve.SetSecondCurve2d(H1);
1266 }
1267 //==============================================
1268 //
1269 mySeqOfCurve.Append(aCurve);
1270 break;
1271
1272 }// end of if (ok) {
1273 }// end of for (Standard_Integer j=0; j<=17; j++)
0fc4f2e2 1274 }// end of else { on regarde si on garde
7fd59977 1275 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1276 }// IntPatch_Circle: IntPatch_Ellipse:
1277 break;
1278
1279 case IntPatch_Analytic: {
1280 IntSurf_Quadric quad1,quad2;
1281 GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
1282
1283 switch (typs) {
1284 case GeomAbs_Plane:
1285 quad1.SetValue(myHS1->Surface().Plane());
1286 break;
1287 case GeomAbs_Cylinder:
1288 quad1.SetValue(myHS1->Surface().Cylinder());
1289 break;
1290 case GeomAbs_Cone:
1291 quad1.SetValue(myHS1->Surface().Cone());
1292 break;
1293 case GeomAbs_Sphere:
1294 quad1.SetValue(myHS1->Surface().Sphere());
1295 break;
1296 default:
1297 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
1298 }
1299
1300 typs = myHS2->Surface().GetType();
1301
1302 switch (typs) {
1303 case GeomAbs_Plane:
1304 quad2.SetValue(myHS2->Surface().Plane());
1305 break;
1306 case GeomAbs_Cylinder:
1307 quad2.SetValue(myHS2->Surface().Cylinder());
1308 break;
1309 case GeomAbs_Cone:
1310 quad2.SetValue(myHS2->Surface().Cone());
1311 break;
1312 case GeomAbs_Sphere:
1313 quad2.SetValue(myHS2->Surface().Sphere());
1314 break;
1315 default:
1316 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
1317 }
1318 //
1319 //=========
1320 IntPatch_ALineToWLine convert (quad1, quad2);
1321
1322 if (!myApprox) {
1323 aNbParts=myLConstruct.NbParts();
1324 for (i=1; i<=aNbParts; i++) {
1325 myLConstruct.Part(i, fprm, lprm);
1326 Handle(IntPatch_WLine) WL =
1327 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1328 //
1329 Handle(Geom2d_BSplineCurve) H1;
1330 Handle(Geom2d_BSplineCurve) H2;
1331
1332 if(myApprox1) {
1333 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1334 }
1335
1336 if(myApprox2) {
1337 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1338 }
1339 //
1340 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1341 }
1342 } // if (!myApprox)
1343
1344 else { // myApprox=TRUE
1345 GeomInt_WLApprox theapp3d;
1346 //
1347 Standard_Real tol2d = myTolApprox;
1348 //
1349 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
1350
1351 aNbParts=myLConstruct.NbParts();
1352 for (i=1; i<=aNbParts; i++) {
1353 myLConstruct.Part(i, fprm, lprm);
1354 Handle(IntPatch_WLine) WL =
1355 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
1356
1357 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
1358
1359 if (!theapp3d.IsDone()) {
1360 //
1361 Handle(Geom2d_BSplineCurve) H1;
1362 Handle(Geom2d_BSplineCurve) H2;
1363
1364 if(myApprox1) {
1365 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1366 }
1367
1368 if(myApprox2) {
1369 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1370 }
1371 //
1372 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1373 }
1374
1375 else {
1376 if(myApprox1 || myApprox2) {
1377 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1378 myTolReached2d = theapp3d.TolReached2d();
1379 }
1380 }
1381
1382 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1383 myTolReached3d = theapp3d.TolReached3d();
1384 }
1385
1386 Standard_Integer aNbMultiCurves, nbpoles;
1387 aNbMultiCurves=theapp3d.NbMultiCurves();
1388 for (j=1; j<=aNbMultiCurves; j++) {
1389 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1390 nbpoles = mbspc.NbPoles();
1391
1392 TColgp_Array1OfPnt tpoles(1, nbpoles);
1393 mbspc.Curve(1, tpoles);
1394 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1395 mbspc.Knots(),
1396 mbspc.Multiplicities(),
1397 mbspc.Degree());
1398
1399 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1400 Check.FixTangent(Standard_True,Standard_True);
1401 //
1402 IntTools_Curve aCurve;
1403 aCurve.SetCurve(BS);
1404
1405 if(myApprox1) {
1406 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1407 mbspc.Curve(2,tpoles2d);
1408 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1409 mbspc.Knots(),
1410 mbspc.Multiplicities(),
1411 mbspc.Degree());
1412
1413 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1414 newCheck.FixTangent(Standard_True,Standard_True);
1415 //
1416 aCurve.SetFirstCurve2d(BS2);
1417 }
1418 else {
1419 Handle(Geom2d_BSplineCurve) H1;
1420 aCurve.SetFirstCurve2d(H1);
1421 }
1422
1423 if(myApprox2) {
1424 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1425 Standard_Integer TwoOrThree;
1426 TwoOrThree=myApprox1 ? 3 : 2;
1427 mbspc.Curve(TwoOrThree, tpoles2d);
1428 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1429 mbspc.Knots(),
1430 mbspc.Multiplicities(),
1431 mbspc.Degree());
1432
1433 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1434 newCheck.FixTangent(Standard_True,Standard_True);
1435 //
1436 aCurve.SetSecondCurve2d(BS2);
1437 }
1438 else {
1439 Handle(Geom2d_BSplineCurve) H2;
1440 aCurve.SetSecondCurve2d(H2);
1441 }
1442 //
1443 mySeqOfCurve.Append(aCurve);
1444
1445 }// for (j=1; j<=aNbMultiCurves; j++) {
1446 }// else from if (!theapp3d.IsDone())
1447 }// for (i=1; i<=aNbParts; i++) {
1448 }// else { // myApprox=TRUE
1449 }// case IntPatch_Analytic:
1450 break;
1451
1452 case IntPatch_Walking:{
1453 Handle(IntPatch_WLine) WL =
1454 Handle(IntPatch_WLine)::DownCast(L);
1455 //
1456 Standard_Integer ifprm, ilprm;
1457 //
1458 if (!myApprox) {
1459 aNbParts = 1;
1460 if(!bAvoidLineConstructor){
1461 aNbParts=myLConstruct.NbParts();
1462 }
1463 for (i=1; i<=aNbParts; ++i) {
1464 Handle(Geom2d_BSplineCurve) H1, H2;
1465 Handle(Geom_Curve) aBSp;
1466 //
1467 if(bAvoidLineConstructor) {
1468 ifprm = 1;
1469 ilprm = WL->NbPnts();
1470 }
1471 else {
1472 myLConstruct.Part(i, fprm, lprm);
1473 ifprm=(Standard_Integer)fprm;
1474 ilprm=(Standard_Integer)lprm;
1475 }
1476 //
1477 if(myApprox1) {
1478 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1479 }
1480 //
1481 if(myApprox2) {
1482 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1483 }
1484 //
1485 aBSp=MakeBSpline(WL, ifprm, ilprm);
1486 IntTools_Curve aIC(aBSp, H1, H2);
1487 mySeqOfCurve.Append(aIC);
1488 }// for (i=1; i<=aNbParts; ++i) {
1489 }// if (!myApprox) {
1490 //
1491 else { // X
1492 Standard_Boolean bIsDecomposited;
1493 Standard_Integer nbiter, aNbSeqOfL;
1494 Standard_Real tol2d;
1495 IntPatch_SequenceOfLine aSeqOfL;
1496 GeomInt_WLApprox theapp3d;
1497 Approx_ParametrizationType aParType = Approx_ChordLength;
1498 //
1499 Standard_Boolean anApprox1 = myApprox1;
1500 Standard_Boolean anApprox2 = myApprox2;
1501
1502 tol2d = myTolApprox;
1503
1504 GeomAbs_SurfaceType typs1, typs2;
1505 typs1 = myHS1->Surface().GetType();
1506 typs2 = myHS2->Surface().GetType();
1507 Standard_Boolean anWithPC = Standard_True;
1508
1509 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
1510 anWithPC =
1511 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
1512 }
1513 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
1514 anWithPC =
1515 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
1516 }
1517 if(!anWithPC) {
1518 //aParType = Approx_Centripetal;
1519 myTolApprox = 1.e-5;
1520 anApprox1 = Standard_False;
1521 anApprox2 = Standard_False;
1522 //
1523 tol2d = myTolApprox;
1524 }
1525
1526 if(myHS1 == myHS2) {
1527 //
1528 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1529 rejectSurface = Standard_True;
1530 }
1531 else {
1532 if(reApprox && !rejectSurface)
1533 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1534 else {
0fc4f2e2 1535 Standard_Integer iDegMax, iDegMin;
7fd59977 1536 //
0fc4f2e2
P
1537 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax);
1538 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, 0, Standard_True, aParType);
7fd59977 1539 }
1540 }
1541 //
1542 Standard_Real aReachedTol = Precision::Confusion();
1543 bIsDecomposited=DecompositionOfWLine(WL,
1544 myHS1,
1545 myHS2,
1546 myFace1,
1547 myFace2,
1548 myLConstruct,
1549 bAvoidLineConstructor,
1550 aSeqOfL,
1551 aReachedTol);
1552 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) )
1553 myTolReached3d = aReachedTol;
1554
1555 //
1556 aNbSeqOfL=aSeqOfL.Length();
1557 //
1558 if (bIsDecomposited) {
1559 nbiter=aNbSeqOfL;
1560 }
1561 else {
1562 nbiter=1;
1563 aNbParts=1;
1564 if (!bAvoidLineConstructor) {
1565 aNbParts=myLConstruct.NbParts();
1566 nbiter=aNbParts;
1567 }
1568 }
1569 //
1570 // nbiter=(bIsDecomposited) ? aSeqOfL.Length() :
1571 // ((bAvoidLineConstructor) ? 1 :aNbParts);
1572 //
1573 for(i = 1; i <= nbiter; ++i) {
1574 if(bIsDecomposited) {
1575 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1576 ifprm = 1;
1577 ilprm = WL->NbPnts();
1578 }
1579 else {
1580 if(bAvoidLineConstructor) {
1581 ifprm = 1;
1582 ilprm = WL->NbPnts();
1583 }
1584 else {
1585 myLConstruct.Part(i, fprm, lprm);
1586 ifprm = (Standard_Integer)fprm;
1587 ilprm = (Standard_Integer)lprm;
1588 }
1589 }
0fc4f2e2
P
1590 //-- lbr :
1591 //-- Si une des surfaces est un plan , on approxime en 2d
1592 //-- sur cette surface et on remonte les points 2d en 3d.
7fd59977 1593 if(typs1 == GeomAbs_Plane) {
1594 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1595 }
1596 else if(typs2 == GeomAbs_Plane) {
1597 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1598 }
1599 else {
1600 //
1601 if (myHS1 != myHS2){
1602 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1603 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1604
1605 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType);
1606
1607 Standard_Boolean bUseSurfaces;
1608 bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1609 if (bUseSurfaces) {
1610 // ######
1611 rejectSurface = Standard_True;
1612 // ######
1613 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1614 }
1615 }
1616 }
1617 //
1618 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1619 }
1620
1621 if (!theapp3d.IsDone()) {
1622 //
1623 Handle(Geom2d_BSplineCurve) H1;
1624 //
1625 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
1626 Handle(Geom2d_BSplineCurve) H2;
1627
1628 if(myApprox1) {
1629 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1630 }
1631
1632 if(myApprox2) {
1633 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1634 }
1635 //
1636 IntTools_Curve aIC(aBSp, H1, H2);
1637 mySeqOfCurve.Append(aIC);
1638 }
1639
1640 else {
1641 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1642 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1643 myTolReached2d = theapp3d.TolReached2d();
1644 }
1645 }
1646 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1647 myTolReached3d = myTolReached2d;
1648 //
1649 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1650 if (myTolReached3d<1.e-6) {
1651 myTolReached3d = theapp3d.TolReached3d();
1652 myTolReached3d=1.e-6;
1653 }
1654 }
1655 //
1656 }
1657 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1658 myTolReached3d = theapp3d.TolReached3d();
1659 }
1660
1661 Standard_Integer aNbMultiCurves, nbpoles;
1662 aNbMultiCurves=theapp3d.NbMultiCurves();
1663 for (j=1; j<=aNbMultiCurves; j++) {
1664 if(typs1 == GeomAbs_Plane) {
1665 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1666 nbpoles = mbspc.NbPoles();
1667
1668 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1669 TColgp_Array1OfPnt tpoles(1,nbpoles);
1670
1671 mbspc.Curve(1,tpoles2d);
1672 const gp_Pln& Pln = myHS1->Surface().Plane();
1673 //
1674 Standard_Integer ik;
1675 for(ik = 1; ik<= nbpoles; ik++) {
1676 tpoles.SetValue(ik,
1677 ElSLib::Value(tpoles2d.Value(ik).X(),
1678 tpoles2d.Value(ik).Y(),
1679 Pln));
1680 }
1681 //
1682 Handle(Geom_BSplineCurve) BS =
1683 new Geom_BSplineCurve(tpoles,
1684 mbspc.Knots(),
1685 mbspc.Multiplicities(),
1686 mbspc.Degree());
1687 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1688 Check.FixTangent(Standard_True, Standard_True);
1689 //
1690 IntTools_Curve aCurve;
1691 aCurve.SetCurve(BS);
1692
1693 if(myApprox1) {
1694 Handle(Geom2d_BSplineCurve) BS1 =
1695 new Geom2d_BSplineCurve(tpoles2d,
1696 mbspc.Knots(),
1697 mbspc.Multiplicities(),
1698 mbspc.Degree());
1699 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1700 Check1.FixTangent(Standard_True,Standard_True);
1701 //
1702 // ############################################
1703 if(!rejectSurface && !reApprox) {
1704 Standard_Boolean isValid = IsCurveValid(BS1);
1705 if(!isValid) {
1706 reApprox = Standard_True;
1707 goto reapprox;
1708 }
1709 }
1710 // ############################################
1711 aCurve.SetFirstCurve2d(BS1);
1712 }
1713 else {
1714 Handle(Geom2d_BSplineCurve) H1;
1715 aCurve.SetFirstCurve2d(H1);
1716 }
1717
1718 if(myApprox2) {
1719 mbspc.Curve(2, tpoles2d);
1720
1721 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1722 mbspc.Knots(),
1723 mbspc.Multiplicities(),
1724 mbspc.Degree());
1725 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1726 newCheck.FixTangent(Standard_True,Standard_True);
1727
1728 // ###########################################
1729 if(!rejectSurface && !reApprox) {
1730 Standard_Boolean isValid = IsCurveValid(BS2);
1731 if(!isValid) {
1732 reApprox = Standard_True;
1733 goto reapprox;
1734 }
1735 }
1736 // ###########################################
1737 //
1738 aCurve.SetSecondCurve2d(BS2);
1739 }
1740 else {
1741 Handle(Geom2d_BSplineCurve) H2;
1742 //
1743 aCurve.SetSecondCurve2d(H2);
1744 }
1745 //
1746 mySeqOfCurve.Append(aCurve);
1747 }
1748
1749 else if(typs2 == GeomAbs_Plane) {
1750 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1751 nbpoles = mbspc.NbPoles();
1752
1753 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1754 TColgp_Array1OfPnt tpoles(1,nbpoles);
1755 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1756 const gp_Pln& Pln = myHS2->Surface().Plane();
1757 //
1758 Standard_Integer ik;
1759 for(ik = 1; ik<= nbpoles; ik++) {
1760 tpoles.SetValue(ik,
1761 ElSLib::Value(tpoles2d.Value(ik).X(),
1762 tpoles2d.Value(ik).Y(),
1763 Pln));
1764
1765 }
1766 //
1767 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1768 mbspc.Knots(),
1769 mbspc.Multiplicities(),
1770 mbspc.Degree());
1771 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1772 Check.FixTangent(Standard_True,Standard_True);
1773 //
1774 IntTools_Curve aCurve;
1775 aCurve.SetCurve(BS);
1776
1777 if(myApprox2) {
1778 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1779 mbspc.Knots(),
1780 mbspc.Multiplicities(),
1781 mbspc.Degree());
1782 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1783 Check1.FixTangent(Standard_True,Standard_True);
1784 //
1785 // ###########################################
1786 if(!rejectSurface && !reApprox) {
1787 Standard_Boolean isValid = IsCurveValid(BS1);
1788 if(!isValid) {
1789 reApprox = Standard_True;
1790 goto reapprox;
1791 }
1792 }
1793 // ###########################################
1794 aCurve.SetSecondCurve2d(BS1);
1795 }
1796 else {
1797 Handle(Geom2d_BSplineCurve) H2;
1798 aCurve.SetSecondCurve2d(H2);
1799 }
1800
1801 if(myApprox1) {
1802 mbspc.Curve(1,tpoles2d);
1803 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1804 mbspc.Knots(),
1805 mbspc.Multiplicities(),
1806 mbspc.Degree());
1807 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
1808 Check2.FixTangent(Standard_True,Standard_True);
1809 //
1810 // ###########################################
1811 if(!rejectSurface && !reApprox) {
1812 Standard_Boolean isValid = IsCurveValid(BS2);
1813 if(!isValid) {
1814 reApprox = Standard_True;
1815 goto reapprox;
1816 }
1817 }
1818 // ###########################################
1819 aCurve.SetFirstCurve2d(BS2);
1820 }
1821 else {
1822 Handle(Geom2d_BSplineCurve) H1;
1823 //
1824 aCurve.SetFirstCurve2d(H1);
1825 }
1826 //
1827 mySeqOfCurve.Append(aCurve);
1828 }
1829 else {
1830 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1831 nbpoles = mbspc.NbPoles();
1832 TColgp_Array1OfPnt tpoles(1,nbpoles);
1833 mbspc.Curve(1,tpoles);
1834 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1835 mbspc.Knots(),
1836 mbspc.Multiplicities(),
1837 mbspc.Degree());
1838 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1839 Check.FixTangent(Standard_True,Standard_True);
1840 //
1841 IntTools_Curve aCurve;
1842 aCurve.SetCurve(BS);
1843
1844 if(myApprox1) {
1845 if(anApprox1) {
1846 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1847 mbspc.Curve(2,tpoles2d);
1848 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1849 mbspc.Knots(),
1850 mbspc.Multiplicities(),
1851 mbspc.Degree());
1852 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
1853 newCheck.FixTangent(Standard_True,Standard_True);
1854 //
1855 aCurve.SetFirstCurve2d(BS1);
1856 }
1857 else {
1858 Handle(Geom2d_BSplineCurve) BS1;
1859 fprm = BS->FirstParameter();
1860 lprm = BS->LastParameter();
1861
1862 Handle(Geom2d_Curve) C2d;
1863 Standard_Real aTol = myTolApprox;
1864 BuildPCurves(fprm, lprm, aTol, myHS1->ChangeSurface().Surface(), BS, C2d);
1865 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1866 aCurve.SetFirstCurve2d(BS1);
1867 }
1868
1869 }
1870 else {
1871 Handle(Geom2d_BSplineCurve) H1;
1872 //
1873 aCurve.SetFirstCurve2d(H1);
1874 }
1875 if(myApprox2) {
1876 if(anApprox2) {
1877 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1878 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
1879 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1880 mbspc.Knots(),
1881 mbspc.Multiplicities(),
1882 mbspc.Degree());
1883 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1884 newCheck.FixTangent(Standard_True,Standard_True);
1885 //
1886 aCurve.SetSecondCurve2d(BS2);
1887 }
1888 else {
1889 Handle(Geom2d_BSplineCurve) BS2;
1890 fprm = BS->FirstParameter();
1891 lprm = BS->LastParameter();
1892
1893 Handle(Geom2d_Curve) C2d;
1894 Standard_Real aTol = myTolApprox;
1895 BuildPCurves(fprm, lprm, aTol, myHS2->ChangeSurface().Surface(), BS, C2d);
1896 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1897 aCurve.SetSecondCurve2d(BS2);
1898 }
1899
1900 }
1901 else {
1902 Handle(Geom2d_BSplineCurve) H2;
1903 //
1904 aCurve.SetSecondCurve2d(H2);
1905 }
1906 //
1907 mySeqOfCurve.Append(aCurve);
1908 }
1909 }
1910 }
1911 }
1912 }// else { // X
1913 }// case IntPatch_Walking:{
1914 break;
1915
1916 case IntPatch_Restriction:
1917 break;
1918
1919 }
1920}
1921
1922//=======================================================================
1923//function : BuildPCurves
1924//purpose :
1925//=======================================================================
1926 void BuildPCurves (Standard_Real f,
1927 Standard_Real l,
1928 Standard_Real& Tol,
1929 const Handle (Geom_Surface)& S,
1930 const Handle (Geom_Curve)& C,
1931 Handle (Geom2d_Curve)& C2d)
1932{
1933
1934 Standard_Real umin,umax,vmin,vmax;
1935 //
1936
1937 if (C2d.IsNull()) {
1938
1939 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
1940 if((l - f) > 2.e-09) {
1941 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
1942 //
1943 if (C2d.IsNull()) {
1944 // proj. a circle that goes through the pole on a sphere to the sphere
1945 Tol=Tol+1.e-7;
1946 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
1947 }
1948 }
1949 else {
1950 if((l - f) > Epsilon(Abs(f))) {
1951 GeomAPI_ProjectPointOnSurf aProjector1, aProjector2;
1952 gp_Pnt P1 = C->Value(f);
1953 gp_Pnt P2 = C->Value(l);
1954 aProjector1.Init(P1, S);
1955 aProjector2.Init(P2, S);
1956
1957 if(aProjector1.IsDone() && aProjector2.IsDone()) {
1958 Standard_Real U=0., V=0.;
1959 aProjector1.LowerDistanceParameters(U, V);
1960 gp_Pnt2d p1(U, V);
1961
1962 aProjector2.LowerDistanceParameters(U, V);
1963 gp_Pnt2d p2(U, V);
1964
1965 if(p1.Distance(p2) > gp::Resolution()) {
1966 TColgp_Array1OfPnt2d poles(1,2);
1967 TColStd_Array1OfReal knots(1,2);
1968 TColStd_Array1OfInteger mults(1,2);
1969 poles(1) = p1;
1970 poles(2) = p2;
1971 knots(1) = f;
1972 knots(2) = l;
1973 mults(1) = mults(2) = 2;
1974
1975 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
1976
1977 // compute reached tolerance.begin
1978 gp_Pnt PMid = C->Value((f + l) * 0.5);
1979 aProjector1.Perform(PMid);
1980
1981 if(aProjector1.IsDone()) {
1982 aProjector1.LowerDistanceParameters(U, V);
1983 gp_Pnt2d pmidproj(U, V);
1984 gp_Pnt2d pmidcurve2d = C2d->Value((f + l) * 0.5);
1985 Standard_Real adist = pmidcurve2d.Distance(pmidproj);
1986 Tol = (adist > Tol) ? adist : Tol;
1987 }
1988 // compute reached tolerance.end
1989 }
1990 }
1991 }
1992 }
1993 //
1994 S->Bounds(umin, umax, vmin, vmax);
1995
1996 if (S->IsUPeriodic() && !C2d.IsNull()) {
0fc4f2e2 1997 // Recadre dans le domaine UV de la face
7fd59977 1998 Standard_Real period, U0, du, aEps;
1999
2000 du =0.0;
2001 aEps=Precision::PConfusion();
2002 period = S->UPeriod();
2003 gp_Pnt2d Pf = C2d->Value(f);
2004 U0=Pf.X();
2005 //
2006 gp_Pnt2d Pl = C2d->Value(l);
2007
2008 U0 = Min(Pl.X(), U0);
2009// while(U0-umin<aEps) {
2010 while(U0-umin<-aEps) {
2011 U0+=period;
2012 du+=period;
2013 }
2014 //
2015 while(U0-umax>aEps) {
2016 U0-=period;
2017 du-=period;
2018 }
2019 if (du != 0) {
2020 gp_Vec2d T1(du,0.);
2021 C2d->Translate(T1);
2022 }
2023 }
2024 }
2025 if (C2d.IsNull()) {
2026 BOPTColStd_Dump::PrintMessage("BuildPCurves()=> Echec ProjLib\n");
2027 }
2028}
2029
2030//=======================================================================
2031//function : Parameters
2032//purpose :
2033//=======================================================================
2034 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
2035 const Handle(GeomAdaptor_HSurface)& HS2,
2036 const gp_Pnt& Ptref,
2037 Standard_Real& U1,
2038 Standard_Real& V1,
2039 Standard_Real& U2,
2040 Standard_Real& V2)
2041{
2042
2043 IntSurf_Quadric quad1,quad2;
2044 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2045
2046 switch (typs) {
2047 case GeomAbs_Plane:
2048 quad1.SetValue(HS1->Surface().Plane());
2049 break;
2050 case GeomAbs_Cylinder:
2051 quad1.SetValue(HS1->Surface().Cylinder());
2052 break;
2053 case GeomAbs_Cone:
2054 quad1.SetValue(HS1->Surface().Cone());
2055 break;
2056 case GeomAbs_Sphere:
2057 quad1.SetValue(HS1->Surface().Sphere());
2058 break;
2059 default:
2060 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2061 }
2062
2063 typs = HS2->Surface().GetType();
2064 switch (typs) {
2065 case GeomAbs_Plane:
2066 quad2.SetValue(HS2->Surface().Plane());
2067 break;
2068 case GeomAbs_Cylinder:
2069 quad2.SetValue(HS2->Surface().Cylinder());
2070 break;
2071 case GeomAbs_Cone:
2072 quad2.SetValue(HS2->Surface().Cone());
2073 break;
2074 case GeomAbs_Sphere:
2075 quad2.SetValue(HS2->Surface().Sphere());
2076 break;
2077 default:
2078 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2079 }
2080
2081 quad1.Parameters(Ptref,U1,V1);
2082 quad2.Parameters(Ptref,U2,V2);
2083}
2084
2085//=======================================================================
2086//function : MakeBSpline
2087//purpose :
2088//=======================================================================
2089Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
2090 const Standard_Integer ideb,
2091 const Standard_Integer ifin)
2092{
2093 Standard_Integer i,nbpnt = ifin-ideb+1;
2094 TColgp_Array1OfPnt poles(1,nbpnt);
2095 TColStd_Array1OfReal knots(1,nbpnt);
2096 TColStd_Array1OfInteger mults(1,nbpnt);
2097 Standard_Integer ipidebm1;
2098 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2099 poles(i) = WL->Point(ipidebm1).Value();
2100 mults(i) = 1;
2101 knots(i) = i-1;
2102 }
2103 mults(1) = mults(nbpnt) = 2;
2104 return
2105 new Geom_BSplineCurve(poles,knots,mults,1);
2106}
2107//
2108
2109//=======================================================================
2110//function : MakeBSpline2d
2111//purpose :
2112//=======================================================================
2113Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
2114 const Standard_Integer ideb,
2115 const Standard_Integer ifin,
2116 const Standard_Boolean onFirst)
2117{
2118 Standard_Integer i, nbpnt = ifin-ideb+1;
2119 TColgp_Array1OfPnt2d poles(1,nbpnt);
2120 TColStd_Array1OfReal knots(1,nbpnt);
2121 TColStd_Array1OfInteger mults(1,nbpnt);
2122 Standard_Integer ipidebm1;
2123
2124 for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) {
2125 Standard_Real U, V;
2126 if(onFirst)
2127 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
2128 else
2129 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
2130 poles(i).SetCoord(U, V);
2131 mults(i) = 1;
2132 knots(i) = i-1;
2133 }
2134 mults(1) = mults(nbpnt) = 2;
2135
2136 return new Geom2d_BSplineCurve(poles,knots,mults,1);
2137}
2138//=======================================================================
2139//function : PrepareLines3D
2140//purpose :
2141//=======================================================================
2142 void IntTools_FaceFace::PrepareLines3D()
2143{
2144 Standard_Integer i, aNbCurves, j, aNbNewCurves;
2145 IntTools_SequenceOfCurves aNewCvs;
2146
2147 //
0fc4f2e2 2148 // 1. Treatment of periodic and closed curves
7fd59977 2149 aNbCurves=mySeqOfCurve.Length();
2150 for (i=1; i<=aNbCurves; i++) {
2151 const IntTools_Curve& aIC=mySeqOfCurve(i);
2152 // DEBUG
2153 // const Handle(Geom_Curve)& aC3D =aIC.Curve();
2154 // const Handle(Geom2d_Curve)& aC2D1=aIC.FirstCurve2d();
2155 // const Handle(Geom2d_Curve)& aC2D2=aIC.SecondCurve2d();
2156 //
2157 IntTools_SequenceOfCurves aSeqCvs;
2158 aNbNewCurves=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2159
2160 if (aNbNewCurves) {
2161 for (j=1; j<=aNbNewCurves; j++) {
2162 const IntTools_Curve& aICNew=aSeqCvs(j);
2163 aNewCvs.Append(aICNew);
2164 }
2165 }
2166 //
2167 else {
2168 aNewCvs.Append(aIC);
2169 }
2170 }
2171 //
2172 // 2. Plane\Cone intersection when we had 4 curves
2173 GeomAbs_SurfaceType aType1, aType2;
2174 BRepAdaptor_Surface aBS1, aBS2;
2175
2176 aBS1.Initialize(myFace1);
2177 aType1=aBS1.GetType();
2178
2179 aBS2.Initialize(myFace2);
2180 aType2=aBS2.GetType();
2181
2182 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2183 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
2184 aNbCurves=aNewCvs.Length();
2185 if (aNbCurves==4) {
2186 GeomAbs_CurveType aCType1=aNewCvs(1).Type();
2187 if (aCType1==GeomAbs_Line) {
2188 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2189 //
2190 for (i=1; i<=aNbCurves; i++) {
2191 const IntTools_Curve& aIC=aNewCvs(i);
2192 aSeqIn.Append(aIC);
2193 }
2194 //
2195 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2196 //
2197 aNewCvs.Clear();
2198 aNbCurves=aSeqOut.Length();
2199 for (i=1; i<=aNbCurves; i++) {
2200 const IntTools_Curve& aIC=aSeqOut(i);
2201 aNewCvs.Append(aIC);
2202 }
2203 //
2204 }
2205 }
2206 }// end of if ((aType1==GeomAbs_Plane && ...
2207 //
2208 // 3. Fill mySeqOfCurve
2209 mySeqOfCurve.Clear();
2210 aNbCurves=aNewCvs.Length();
2211 for (i=1; i<=aNbCurves; i++) {
2212 const IntTools_Curve& aIC=aNewCvs(i);
2213 mySeqOfCurve.Append(aIC);
2214 }
2215
2216}
2217
2218
2219//=======================================================================
2220//function : CorrectSurfaceBoundaries
2221//purpose :
2222//=======================================================================
2223 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
2224 const Standard_Real theTolerance,
2225 Standard_Real& theumin,
2226 Standard_Real& theumax,
2227 Standard_Real& thevmin,
2228 Standard_Real& thevmax)
2229{
2230 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2231 Standard_Real uinf, usup, vinf, vsup, delta;
2232 GeomAbs_SurfaceType aType;
2233 Handle(Geom_Surface) aSurface;
2234 //
2235 aSurface = BRep_Tool::Surface(theFace);
2236 aSurface->Bounds(uinf, usup, vinf, vsup);
2237 delta = theTolerance;
2238 enlarge = Standard_False;
2239 //
2240 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2241 //
2242 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2243 Handle(Geom_Surface) aBasisSurface =
2244 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2245
2246 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2247 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2248 return;
2249 }
2250 }
2251 //
2252 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2253 Handle(Geom_Surface) aBasisSurface =
2254 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2255
2256 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2257 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2258 return;
2259 }
2260 }
2261 //
2262 isuperiodic = anAdaptorSurface.IsUPeriodic();
2263 isvperiodic = anAdaptorSurface.IsVPeriodic();
2264 //
2265 aType=anAdaptorSurface.GetType();
2266 if((aType==GeomAbs_BezierSurface) ||
2267 (aType==GeomAbs_BSplineSurface) ||
2268 (aType==GeomAbs_SurfaceOfExtrusion) ||
2269 (aType==GeomAbs_SurfaceOfRevolution)) {
2270 enlarge=Standard_True;
2271 }
2272 //
2273 if(!isuperiodic && enlarge) {
2274
2275 if((theumin - uinf) > delta )
2276 theumin -= delta;
2277 else {
2278 theumin = uinf;
2279 }
2280
2281 if((usup - theumax) > delta )
2282 theumax += delta;
2283 else
2284 theumax = usup;
2285 }
2286 //
2287 if(!isvperiodic && enlarge) {
2288 if((thevmin - vinf) > delta ) {
2289 thevmin -= delta;
2290 }
2291 else {
2292 thevmin = vinf;
2293 }
2294 if((vsup - thevmax) > delta ) {
2295 thevmax += delta;
2296 }
2297 else {
2298 thevmax = vsup;
2299 }
2300 }
2301 //
2302 {
2303 Standard_Integer aNbP;
2304 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2305 //
2306 aTolPA=Precision::Angular();
2307 // U
2308 if (isuperiodic) {
2309 aXP=anAdaptorSurface.UPeriod();
2310 dXfact=theumax-theumin;
2311 if (dXfact-aTolPA>aXP) {
2312 aXmid=0.5*(theumax+theumin);
2313 aNbP=RealToInt(aXmid/aXP);
2314 if (aXmid<0.) {
2315 aNbP=aNbP-1;
2316 }
2317 aX1=aNbP*aXP;
0fc4f2e2
P
2318 if (theumin>aTolPA) {
2319 aX1=theumin+aNbP*aXP;
2320 }
7fd59977 2321 aX2=aX1+aXP;
2322 if (theumin<aX1) {
2323 theumin=aX1;
2324 }
2325 if (theumax>aX2) {
2326 theumax=aX2;
2327 }
2328 }
2329 }
2330 // V
2331 if (isvperiodic) {
2332 aXP=anAdaptorSurface.VPeriod();
2333 dXfact=thevmax-thevmin;
2334 if (dXfact-aTolPA>aXP) {
2335 aXmid=0.5*(thevmax+thevmin);
2336 aNbP=RealToInt(aXmid/aXP);
2337 if (aXmid<0.) {
2338 aNbP=aNbP-1;
2339 }
2340 aX1=aNbP*aXP;
0fc4f2e2
P
2341 if (thevmin>aTolPA) {
2342 aX1=thevmin+aNbP*aXP;
2343 }
7fd59977 2344 aX2=aX1+aXP;
2345 if (thevmin<aX1) {
2346 thevmin=aX1;
2347 }
2348 if (thevmax>aX2) {
2349 thevmax=aX2;
2350 }
2351 }
2352 }
2353 }
2354 //
2355 if(isuperiodic || isvperiodic) {
2356 Standard_Boolean correct = Standard_False;
2357 Standard_Boolean correctU = Standard_False;
2358 Standard_Boolean correctV = Standard_False;
2359 Bnd_Box2d aBox;
2360 TopExp_Explorer anExp;
2361
2362 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2363 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
2364 correct = Standard_True;
2365 Standard_Real f, l;
2366 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2367
2368 for(Standard_Integer i = 0; i < 2; i++) {
2369 if(i==0) {
2370 anEdge.Orientation(TopAbs_FORWARD);
2371 }
2372 else {
2373 anEdge.Orientation(TopAbs_REVERSED);
2374 }
2375 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2376
2377 if(aCurve.IsNull()) {
2378 correct = Standard_False;
2379 break;
2380 }
2381 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2382
2383 if(aLine.IsNull()) {
2384 correct = Standard_False;
2385 break;
2386 }
2387 gp_Dir2d anUDir(1., 0.);
2388 gp_Dir2d aVDir(0., 1.);
2389 Standard_Real anAngularTolerance = Precision::Angular();
2390
2391 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2392 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2393
2394 gp_Pnt2d pp1 = aCurve->Value(f);
2395 aBox.Add(pp1);
2396 gp_Pnt2d pp2 = aCurve->Value(l);
2397 aBox.Add(pp2);
2398 }
2399 if(!correct)
2400 break;
2401 }
2402 }
2403
2404 if(correct) {
2405 Standard_Real umin, vmin, umax, vmax;
2406 aBox.Get(umin, vmin, umax, vmax);
2407
2408 if(isuperiodic && correctU) {
2409
2410 if(theumin < umin)
2411 theumin = umin;
2412
2413 if(theumax > umax) {
2414 theumax = umax;
2415 }
2416 }
2417 if(isvperiodic && correctV) {
2418
2419 if(thevmin < vmin)
2420 thevmin = vmin;
2421 if(thevmax > vmax)
2422 thevmax = vmax;
2423 }
2424 }
2425 }
2426}
2427//
2428//
2429// The block is dedicated to determine whether WLine [ifprm, ilprm]
2430// crosses the degenerated zone on each given surface or not.
2431// If Yes -> We will not use info about surfaces during approximation
2432// because inside degenerated zone of the surface the approx. alogo.
2433// uses wrong values of normal, etc., and resulting curve will have
2434// oscillations that we would not like to have.
2435// PKV Tue Feb 12 2002
2436
2437
2438static
2439 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2440 const Handle(Geom_Surface)& aS,
2441 const Standard_Integer iDir);
2442static
2443 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2444 const TopoDS_Face& aF1,
2445 const TopoDS_Face& aF2);
2446//=======================================================================
2447//function : NotUseSurfacesForApprox
2448//purpose :
2449//=======================================================================
2450Standard_Boolean NotUseSurfacesForApprox(const TopoDS_Face& aF1,
2451 const TopoDS_Face& aF2,
2452 const Handle(IntPatch_WLine)& WL,
2453 const Standard_Integer ifprm,
2454 const Standard_Integer ilprm)
2455{
2456 Standard_Boolean bPInDZ;
2457
2458 Handle(IntSurf_LineOn2S) aLineOn2S=WL->Curve();
2459
2460 const IntSurf_PntOn2S& aP2Sfprm=aLineOn2S->Value(ifprm);
2461 bPInDZ=IsPointInDegeneratedZone(aP2Sfprm, aF1, aF2);
2462 if (bPInDZ) {
2463 return bPInDZ;
2464 }
2465
2466 const IntSurf_PntOn2S& aP2Slprm=aLineOn2S->Value(ilprm);
2467 bPInDZ=IsPointInDegeneratedZone(aP2Slprm, aF1, aF2);
2468
2469 return bPInDZ;
2470}
2471//=======================================================================
2472//function : IsPointInDegeneratedZone
2473//purpose :
2474//=======================================================================
2475Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2476 const TopoDS_Face& aF1,
2477 const TopoDS_Face& aF2)
2478
2479{
2480 Standard_Boolean bFlag=Standard_True;
2481 Standard_Real US11, US12, VS11, VS12, US21, US22, VS21, VS22;
2482 Standard_Real U1, V1, U2, V2, aDelta, aD;
2483 gp_Pnt2d aP2d;
2484
2485 Handle(Geom_Surface)aS1 = BRep_Tool::Surface(aF1);
2486 aS1->Bounds(US11, US12, VS11, VS12);
2487 GeomAdaptor_Surface aGAS1(aS1);
2488
2489 Handle(Geom_Surface)aS2 = BRep_Tool::Surface(aF2);
2490 aS1->Bounds(US21, US22, VS21, VS22);
2491 GeomAdaptor_Surface aGAS2(aS2);
2492 //
2493 //const gp_Pnt& aP=aP2S.Value();
2494 aP2S.Parameters(U1, V1, U2, V2);
2495 //
2496 aDelta=1.e-7;
2497 // Check on Surf 1
2498 aD=aGAS1.UResolution(aDelta);
2499 aP2d.SetCoord(U1, V1);
2500 if (fabs(U1-US11) < aD) {
2501 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2502 if (bFlag) {
2503 return bFlag;
2504 }
2505 }
2506 if (fabs(U1-US12) < aD) {
2507 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2508 if (bFlag) {
2509 return bFlag;
2510 }
2511 }
2512 aD=aGAS1.VResolution(aDelta);
2513 if (fabs(V1-VS11) < aDelta) {
2514 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2515 if (bFlag) {
2516 return bFlag;
2517 }
2518 }
2519 if (fabs(V1-VS12) < aDelta) {
2520 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2521 if (bFlag) {
2522 return bFlag;
2523 }
2524 }
2525 // Check on Surf 2
2526 aD=aGAS2.UResolution(aDelta);
2527 aP2d.SetCoord(U2, V2);
2528 if (fabs(U2-US21) < aDelta) {
2529 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2530 if (bFlag) {
2531 return bFlag;
2532 }
2533 }
2534 if (fabs(U2-US22) < aDelta) {
2535 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2536 if (bFlag) {
2537 return bFlag;
2538 }
2539 }
2540 aD=aGAS2.VResolution(aDelta);
2541 if (fabs(V2-VS21) < aDelta) {
2542 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2543 if (bFlag) {
2544 return bFlag;
2545 }
2546 }
2547 if (fabs(V2-VS22) < aDelta) {
2548 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2549 if (bFlag) {
2550 return bFlag;
2551 }
2552 }
2553 return !bFlag;
2554}
2555
2556//=======================================================================
2557//function : IsDegeneratedZone
2558//purpose :
2559//=======================================================================
2560Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2561 const Handle(Geom_Surface)& aS,
2562 const Standard_Integer iDir)
2563{
2564 Standard_Boolean bFlag=Standard_True;
2565 Standard_Real US1, US2, VS1, VS2, dY, dX, d1, d2, dD;
2566 Standard_Real aXm, aYm, aXb, aYb, aXe, aYe;
2567 aS->Bounds(US1, US2, VS1, VS2);
2568
2569 gp_Pnt aPm, aPb, aPe;
2570
2571 aXm=aP2d.X();
2572 aYm=aP2d.Y();
2573
2574 aS->D0(aXm, aYm, aPm);
2575
2576 dX=1.e-5;
2577 dY=1.e-5;
2578 dD=1.e-12;
2579
2580 if (iDir==1) {
2581 aXb=aXm;
2582 aXe=aXm;
2583 aYb=aYm-dY;
2584 if (aYb < VS1) {
2585 aYb=VS1;
2586 }
2587 aYe=aYm+dY;
2588 if (aYe > VS2) {
2589 aYe=VS2;
2590 }
2591 aS->D0(aXb, aYb, aPb);
2592 aS->D0(aXe, aYe, aPe);
2593
2594 d1=aPm.Distance(aPb);
2595 d2=aPm.Distance(aPe);
2596 if (d1 < dD && d2 < dD) {
2597 return bFlag;
2598 }
2599 return !bFlag;
2600 }
2601 //
2602 else if (iDir==2) {
2603 aYb=aYm;
2604 aYe=aYm;
2605 aXb=aXm-dX;
2606 if (aXb < US1) {
2607 aXb=US1;
2608 }
2609 aXe=aXm+dX;
2610 if (aXe > US2) {
2611 aXe=US2;
2612 }
2613 aS->D0(aXb, aYb, aPb);
2614 aS->D0(aXe, aYe, aPe);
2615
2616 d1=aPm.Distance(aPb);
2617 d2=aPm.Distance(aPe);
2618 if (d1 < dD && d2 < dD) {
2619 return bFlag;
2620 }
2621 return !bFlag;
2622 }
2623 return !bFlag;
2624}
2625
2626//=========================================================================
2627// static function : ComputePurgedWLine
2628// purpose : Removes equal points (leave one of equal points) from theWLine
2629// and recompute vertex parameters.
2630// Returns new WLine or null WLine if the number
2631// of the points is less than 2.
2632//=========================================================================
2633Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
2634 Handle(IntPatch_WLine) aResult;
2635 Handle(IntPatch_WLine) aLocalWLine;
2636 Handle(IntPatch_WLine) aTmpWLine = theWLine;
2637
2638 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
2639 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2640 Standard_Integer i, k, v, nb, nbvtx;
2641 nbvtx = theWLine->NbVertex();
2642 nb = theWLine->NbPnts();
2643
2644 for(i = 1; i <= nb; i++) {
2645 aLineOn2S->Add(theWLine->Point(i));
2646 }
2647
2648 for(v = 1; v <= nbvtx; v++) {
2649 aLocalWLine->AddVertex(theWLine->Vertex(v));
2650 }
2651
2652 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
2653 Standard_Integer aStartIndex = i + 1;
2654 Standard_Integer anEndIndex = i + 5;
2655 nb = aLineOn2S->NbPoints();
2656 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
2657
2658 if((aStartIndex >= nb) || (anEndIndex <= 1)) {
2659 continue;
2660 }
2661 k = aStartIndex;
2662
2663 while(k <= anEndIndex) {
2664
2665 if(i != k) {
2666 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
2667 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
2668
2669 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2670 aTmpWLine = aLocalWLine;
2671 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2672
2673 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
2674 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
2675 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
2676
2677 if(avertexindex >= k) {
2678 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
2679 }
2680 aLocalWLine->AddVertex(aVertex);
2681 }
2682 aLineOn2S->RemovePoint(k);
2683 anEndIndex--;
2684 continue;
2685 }
2686 }
2687 k++;
2688 }
2689 }
2690
2691 if(aLineOn2S->NbPoints() > 1) {
2692 aResult = aLocalWLine;
2693 }
2694 return aResult;
2695}
2696
2697//=======================================================================
2698//function : TolR3d
2699//purpose :
2700//=======================================================================
2701void TolR3d(const TopoDS_Face& aF1,
2702 const TopoDS_Face& aF2,
2703 Standard_Real& myTolReached3d)
2704{
2705 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
2706
2707 aTolTresh=2.999999e-3;
2708 aTolF1 = BRep_Tool::Tolerance(aF1);
2709 aTolF2 = BRep_Tool::Tolerance(aF2);
2710 aTolFMax=Max(aTolF1, aTolF2);
2711
2712 if (aTolFMax>aTolTresh) {
2713 myTolReached3d=aTolFMax;
2714 }
2715}
2716//=======================================================================
2717//function : AdjustPeriodic
2718//purpose :
2719//=======================================================================
2720Standard_Real AdjustPeriodic(const Standard_Real theParameter,
2721 const Standard_Real parmin,
2722 const Standard_Real parmax,
2723 const Standard_Real thePeriod,
2724 Standard_Real& theOffset)
2725{
2726 Standard_Real aresult;
2727 //
2728 theOffset = 0.;
2729 aresult = theParameter;
2730 while(aresult < parmin) {
2731 aresult += thePeriod;
2732 theOffset += thePeriod;
2733 }
2734
2735 while(aresult > parmax) {
2736 aresult -= thePeriod;
2737 theOffset -= thePeriod;
2738 }
2739 return aresult;
2740}
2741//=======================================================================
2742//function : IsPointOnBoundary
2743//purpose :
2744//=======================================================================
2745Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
2746 const Standard_Real theFirstBoundary,
2747 const Standard_Real theSecondBoundary,
2748 const Standard_Real theResolution,
2749 Standard_Boolean& IsOnFirstBoundary)
2750{
2751 Standard_Boolean bRet;
2752 Standard_Integer i;
2753 Standard_Real adist;
2754 //
2755 bRet=Standard_False;
2756 for(i = 0; i < 2; ++i) {
2757 IsOnFirstBoundary = (i == 0);
2758 if (IsOnFirstBoundary) {
2759 adist = fabs(theParameter - theFirstBoundary);
2760 }
2761 else {
2762 adist = fabs(theParameter - theSecondBoundary);
2763 }
2764 if(adist < theResolution) {
2765 return !bRet;
2766 }
2767 }
2768 return bRet;
2769}
2770// ------------------------------------------------------------------------------------------------
2771// static function: FindPoint
2772// purpose:
2773// ------------------------------------------------------------------------------------------------
2774Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
2775 const gp_Pnt2d& theLastPoint,
2776 const Standard_Real theUmin,
2777 const Standard_Real theUmax,
2778 const Standard_Real theVmin,
2779 const Standard_Real theVmax,
2780 gp_Pnt2d& theNewPoint) {
2781
2782 gp_Vec2d aVec(theFirstPoint, theLastPoint);
2783 Standard_Integer i = 0, j = 0;
2784
2785 for(i = 0; i < 4; i++) {
2786 gp_Vec2d anOtherVec;
2787 gp_Vec2d anOtherVecNormal;
2788 gp_Pnt2d aprojpoint = theLastPoint;
2789
2790 if((i % 2) == 0) {
2791 anOtherVec.SetX(0.);
2792 anOtherVec.SetY(1.);
2793 anOtherVecNormal.SetX(1.);
2794 anOtherVecNormal.SetY(0.);
2795
2796 if(i < 2)
2797 aprojpoint.SetX(theUmin);
2798 else
2799 aprojpoint.SetX(theUmax);
2800 }
2801 else {
2802 anOtherVec.SetX(1.);
2803 anOtherVec.SetY(0.);
2804 anOtherVecNormal.SetX(0.);
2805 anOtherVecNormal.SetY(1.);
2806
2807 if(i < 2)
2808 aprojpoint.SetY(theVmin);
2809 else
2810 aprojpoint.SetY(theVmax);
2811 }
2812 gp_Vec2d anormvec = aVec;
2813 anormvec.Normalize();
2814 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
2815
2816 if(fabs(adot1) < Precision::Angular())
2817 continue;
2818 Standard_Real adist = 0.;
2819 Standard_Boolean bIsOut = Standard_False;
2820
2821 if((i % 2) == 0) {
2822 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
2823 bIsOut = (i < 2) ? (theLastPoint.X() < theUmin) : (theLastPoint.X() > theUmax);
2824 }
2825 else {
2826 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
2827 bIsOut = (i < 2) ? (theLastPoint.Y() < theVmin) : (theLastPoint.Y() > theVmax);
2828 }
2829 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
2830
2831 for(j = 0; j < 2; j++) {
2832 anoffset = (j == 0) ? anoffset : -anoffset;
2833 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
2834 gp_Vec2d acurvec(theLastPoint, acurpoint);
2835 if ( bIsOut )
2836 acurvec.Reverse();
2837
9e9df9d9
P
2838 Standard_Real aDotX, anAngleX;
2839 //
2840 aDotX = aVec.Dot(acurvec);
2841 anAngleX = aVec.Angle(acurvec);
2842 //
2843 if(aDotX > 0. && fabs(anAngleX) < Precision::PConfusion()) {
7fd59977 2844 if((i % 2) == 0) {
2845 if((acurpoint.Y() >= theVmin) &&
2846 (acurpoint.Y() <= theVmax)) {
2847 theNewPoint = acurpoint;
2848 return Standard_True;
2849 }
2850 }
2851 else {
2852 if((acurpoint.X() >= theUmin) &&
2853 (acurpoint.X() <= theUmax)) {
2854 theNewPoint = acurpoint;
2855 return Standard_True;
2856 }
2857 }
2858 }
2859 }
2860 }
2861 return Standard_False;
2862}
2863
2864
2865// ------------------------------------------------------------------------------------------------
2866// static function: FindPoint
2867// purpose: Find point on the boundary of radial tangent zone
2868// ------------------------------------------------------------------------------------------------
2869Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
2870 const gp_Pnt2d& theLastPoint,
2871 const Standard_Real theUmin,
2872 const Standard_Real theUmax,
2873 const Standard_Real theVmin,
2874 const Standard_Real theVmax,
2875 const gp_Pnt2d& theTanZoneCenter,
2876 const Standard_Real theZoneRadius,
2877 Handle(GeomAdaptor_HSurface) theGASurface,
2878 gp_Pnt2d& theNewPoint) {
2879 theNewPoint = theLastPoint;
2880
2881 if ( !IsInsideTanZone( theLastPoint, theTanZoneCenter, theZoneRadius, theGASurface) )
2882 return Standard_False;
2883
2884 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
2885 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
2886
2887 Standard_Real aRadius = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
2888 gp_Ax22d anAxis( theTanZoneCenter, gp_Dir2d(1, 0), gp_Dir2d(0, 1) );
2889 gp_Circ2d aCircle( anAxis, aRadius );
2890
2891 //
2892 gp_Vec2d aDir( theLastPoint.XY() - theFirstPoint.XY() );
2893 Standard_Real aLength = aDir.Magnitude();
2894 if ( aLength <= gp::Resolution() )
2895 return Standard_False;
2896 gp_Lin2d aLine( theFirstPoint, aDir );
2897
2898 //
2899 Handle(Geom2d_Line) aCLine = new Geom2d_Line( aLine );
2900 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve( aCLine, 0, aLength );
2901 Handle(Geom2d_Circle) aC2 = new Geom2d_Circle( aCircle );
2902
2903 Standard_Real aTol = aRadius * 0.001;
2904 aTol = ( aTol < Precision::PConfusion() ) ? Precision::PConfusion() : aTol;
2905
2906 Geom2dAPI_InterCurveCurve anIntersector;
2907 anIntersector.Init( aC1, aC2, aTol );
2908
2909 if ( anIntersector.NbPoints() == 0 )
2910 return Standard_False;
2911
2912 Standard_Boolean aFound = Standard_False;
2913 Standard_Real aMinDist = aLength * aLength;
2914 Standard_Integer i = 0;
2915 for ( i = 1; i <= anIntersector.NbPoints(); i++ ) {
2916 gp_Pnt2d aPInt = anIntersector.Point( i );
2917 if ( aPInt.SquareDistance( theFirstPoint ) < aMinDist ) {
2918 if ( ( aPInt.X() >= theUmin ) && ( aPInt.X() <= theUmax ) &&
2919 ( aPInt.Y() >= theVmin ) && ( aPInt.Y() <= theVmax ) ) {
2920 theNewPoint = aPInt;
2921 aFound = Standard_True;
2922 }
2923 }
2924 }
2925
2926 return aFound;
2927}
2928
2929// ------------------------------------------------------------------------------------------------
2930// static function: IsInsideTanZone
2931// purpose: Check if point is inside a radial tangent zone
2932// ------------------------------------------------------------------------------------------------
2933Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
2934 const gp_Pnt2d& theTanZoneCenter,
2935 const Standard_Real theZoneRadius,
2936 Handle(GeomAdaptor_HSurface) theGASurface) {
2937
2938 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
2939 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
2940 Standard_Real aRadiusSQR = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
2941 aRadiusSQR *= aRadiusSQR;
2942 if ( thePoint.SquareDistance( theTanZoneCenter ) <= aRadiusSQR )
2943 return Standard_True;
2944 return Standard_False;
2945}
2946
2947// ------------------------------------------------------------------------------------------------
2948// static function: CheckTangentZonesExist
2949// purpose: Check if tangent zone exists
2950// ------------------------------------------------------------------------------------------------
2951Standard_Boolean CheckTangentZonesExist( const Handle(GeomAdaptor_HSurface)& theSurface1,
2952 const Handle(GeomAdaptor_HSurface)& theSurface2 )
2953{
2954 if ( ( theSurface1->GetType() != GeomAbs_Torus ) ||
2955 ( theSurface2->GetType() != GeomAbs_Torus ) )
2956 return Standard_False;
2957
2958 IntTools_Context aContext;
2959
2960 gp_Torus aTor1 = theSurface1->Torus();
2961 gp_Torus aTor2 = theSurface2->Torus();
2962
2963 if ( aTor1.Location().Distance( aTor2.Location() ) > Precision::Confusion() )
2964 return Standard_False;
2965
2966 if ( ( fabs( aTor1.MajorRadius() - aTor2.MajorRadius() ) > Precision::Confusion() ) ||
2967 ( fabs( aTor1.MinorRadius() - aTor2.MinorRadius() ) > Precision::Confusion() ) )
2968 return Standard_False;
2969
2970 if ( ( aTor1.MajorRadius() < aTor1.MinorRadius() ) ||
2971 ( aTor2.MajorRadius() < aTor2.MinorRadius() ) )
2972 return Standard_False;
2973 return Standard_True;
2974}
2975
2976// ------------------------------------------------------------------------------------------------
2977// static function: ComputeTangentZones
2978// purpose:
2979// ------------------------------------------------------------------------------------------------
2980Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
2981 const Handle(GeomAdaptor_HSurface)& theSurface2,
2982 const TopoDS_Face& theFace1,
2983 const TopoDS_Face& theFace2,
2984 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
2985 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
2986 Handle(TColStd_HArray1OfReal)& theResultRadius) {
2987 Standard_Integer aResult = 0;
2988 if ( !CheckTangentZonesExist( theSurface1, theSurface2 ) )
2989 return aResult;
2990
2991 IntTools_Context aContext;
2992
2993 TColgp_SequenceOfPnt2d aSeqResultS1, aSeqResultS2;
2994 TColStd_SequenceOfReal aSeqResultRad;
2995
2996 gp_Torus aTor1 = theSurface1->Torus();
2997 gp_Torus aTor2 = theSurface2->Torus();
2998
2999 gp_Ax2 anax1( aTor1.Location(), aTor1.Axis().Direction() );
3000 gp_Ax2 anax2( aTor2.Location(), aTor2.Axis().Direction() );
3001 Standard_Integer j = 0;
3002
3003 for ( j = 0; j < 2; j++ ) {
3004 Standard_Real aCoef = ( j == 0 ) ? -1 : 1;
3005 Standard_Real aRadius1 = fabs(aTor1.MajorRadius() + aCoef * aTor1.MinorRadius());
3006 Standard_Real aRadius2 = fabs(aTor2.MajorRadius() + aCoef * aTor2.MinorRadius());
3007
3008 gp_Circ aCircle1( anax1, aRadius1 );
3009 gp_Circ aCircle2( anax2, aRadius2 );
3010
3011 // roughly compute radius of tangent zone for perpendicular case
3012 Standard_Real aCriteria = Precision::Confusion() * 0.5;
3013
3014 Standard_Real aT1 = aCriteria;
3015 Standard_Real aT2 = aCriteria;
3016 if ( j == 0 ) {
3017 // internal tangency
3018 Standard_Real aR = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3019 //aT1 = aCriteria * aCriteria + aR * aR - ( aR - aCriteria ) * ( aR - aCriteria );
3020 aT1 = 2. * aR * aCriteria;
3021 aT2 = aT1;
3022 }
3023 else {
3024 // external tangency
3025 Standard_Real aRb = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3026 Standard_Real aRm = ( aRadius1 < aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3027 Standard_Real aDelta = aRb - aCriteria;
3028 aDelta *= aDelta;
3029 aDelta -= aRm * aRm;
3030 aDelta /= 2. * (aRb - aRm);
3031 aDelta -= 0.5 * (aRb - aRm);
3032
3033 aT1 = 2. * aRm * (aRm - aDelta);
3034 aT2 = aT1;
3035 }
3036 aCriteria = ( aT1 > aT2) ? aT1 : aT2;
3037 if ( aCriteria > 0 )
3038 aCriteria = sqrt( aCriteria );
3039
3040 if ( aCriteria > 0.5 * aTor1.MinorRadius() ) {
3041 // too big zone -> drop to minimum
3042 aCriteria = Precision::Confusion();
3043 }
3044
3045 GeomAdaptor_Curve aC1( new Geom_Circle(aCircle1) );
3046 GeomAdaptor_Curve aC2( new Geom_Circle(aCircle2) );
3047 Extrema_ExtCC anExtrema(aC1, aC2, 0, 2.*Standard_PI, 0, 2.*Standard_PI,
3048 Precision::PConfusion(), Precision::PConfusion());
3049
3050 if ( anExtrema.IsDone() ) {
3051
3052 Standard_Integer i = 0;
3053 for ( i = 1; i <= anExtrema.NbExt(); i++ ) {
3054 if ( anExtrema.SquareDistance(i) > aCriteria * aCriteria )
3055 continue;
3056
3057 Extrema_POnCurv P1, P2;
3058 anExtrema.Points( i, P1, P2 );
3059
3060 Standard_Boolean bFoundResult = Standard_True;
3061 gp_Pnt2d pr1, pr2;
3062
3063 Standard_Integer surfit = 0;
3064 for ( surfit = 0; surfit < 2; surfit++ ) {
3065 GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aContext.ProjPS(theFace1) : aContext.ProjPS(theFace2);
3066
3067 gp_Pnt aP3d = (surfit == 0) ? P1.Value() : P2.Value();
3068 aProjector.Perform(aP3d);
3069
3070 if(!aProjector.IsDone())
3071 bFoundResult = Standard_False;
3072 else {
3073 if(aProjector.LowerDistance() > aCriteria) {
3074 bFoundResult = Standard_False;
3075 }
3076 else {
3077 Standard_Real foundU = 0, foundV = 0;
3078 aProjector.LowerDistanceParameters(foundU, foundV);
3079 if ( surfit == 0 )
3080 pr1 = gp_Pnt2d( foundU, foundV );
3081 else
3082 pr2 = gp_Pnt2d( foundU, foundV );
3083 }
3084 }
3085 }
3086 if ( bFoundResult ) {
3087 aSeqResultS1.Append( pr1 );
3088 aSeqResultS2.Append( pr2 );
3089 aSeqResultRad.Append( aCriteria );
3090
3091 // torus is u and v periodic
3092 const Standard_Real twoPI = Standard_PI + Standard_PI;
3093 Standard_Real arr1tmp[2] = {pr1.X(), pr1.Y()};
3094 Standard_Real arr2tmp[2] = {pr2.X(), pr2.Y()};
3095
3096 // iteration on period bounds
3097 for ( Standard_Integer k1 = 0; k1 < 2; k1++ ) {
3098 Standard_Real aBound = ( k1 == 0 ) ? 0 : twoPI;
3099 Standard_Real aShift = ( k1 == 0 ) ? twoPI : -twoPI;
3100
3101 // iteration on surfaces
3102 for ( Standard_Integer k2 = 0; k2 < 2; k2++ ) {
3103 Standard_Real* arr1 = ( k2 == 0 ) ? arr1tmp : arr2tmp;
3104 Standard_Real* arr2 = ( k2 != 0 ) ? arr1tmp : arr2tmp;
3105 TColgp_SequenceOfPnt2d& aSeqS1 = ( k2 == 0 ) ? aSeqResultS1 : aSeqResultS2;
3106 TColgp_SequenceOfPnt2d& aSeqS2 = ( k2 != 0 ) ? aSeqResultS1 : aSeqResultS2;
3107
3108 if (fabs(arr1[0] - aBound) < Precision::PConfusion()) {
3109 aSeqS1.Append( gp_Pnt2d( arr1[0] + aShift, arr1[1] ) );
3110 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3111 aSeqResultRad.Append( aCriteria );
3112 }
3113 if (fabs(arr1[1] - aBound) < Precision::PConfusion()) {
3114 aSeqS1.Append( gp_Pnt2d( arr1[0], arr1[1] + aShift) );
3115 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3116 aSeqResultRad.Append( aCriteria );
3117 }
3118 }
3119 } //
3120 }
3121 }
3122 }
3123 }
3124 aResult = aSeqResultRad.Length();
3125
3126 if ( aResult > 0 ) {
3127 theResultOnS1 = new TColgp_HArray1OfPnt2d( 1, aResult );
3128 theResultOnS2 = new TColgp_HArray1OfPnt2d( 1, aResult );
3129 theResultRadius = new TColStd_HArray1OfReal( 1, aResult );
3130
3131 for ( Standard_Integer i = 1 ; i <= aResult; i++ ) {
3132 theResultOnS1->SetValue( i, aSeqResultS1.Value(i) );
3133 theResultOnS2->SetValue( i, aSeqResultS2.Value(i) );
3134 theResultRadius->SetValue( i, aSeqResultRad.Value(i) );
3135 }
3136 }
3137 return aResult;
3138}
3139
3140// ------------------------------------------------------------------------------------------------
3141// static function: AdjustByNeighbour
3142// purpose:
3143// ------------------------------------------------------------------------------------------------
3144gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
3145 const gp_Pnt2d& theOriginalPoint,
3146 Handle(GeomAdaptor_HSurface) theGASurface) {
3147
3148 gp_Pnt2d ap1 = theaNeighbourPoint;
3149 gp_Pnt2d ap2 = theOriginalPoint;
3150
3151 if ( theGASurface->IsUPeriodic() ) {
3152 Standard_Real aPeriod = theGASurface->UPeriod();
3153 gp_Pnt2d aPTest = ap2;
3154 Standard_Real aSqDistMin = 1.e+100;
3155
3156 for ( Standard_Integer pIt = -1; pIt <= 1; pIt++) {
3157 aPTest.SetX( theOriginalPoint.X() + aPeriod * pIt );
3158 Standard_Real dd = ap1.SquareDistance( aPTest );
3159
3160 if ( dd < aSqDistMin ) {
3161 ap2 = aPTest;
3162 aSqDistMin = dd;
3163 }
3164 }
3165 }
3166 if ( theGASurface->IsVPeriodic() ) {
3167 Standard_Real aPeriod = theGASurface->VPeriod();
3168 gp_Pnt2d aPTest = ap2;
3169 Standard_Real aSqDistMin = 1.e+100;
3170
3171 for ( Standard_Integer pIt = -1; pIt <= 1; pIt++) {
3172 aPTest.SetY( theOriginalPoint.Y() + aPeriod * pIt );
3173 Standard_Real dd = ap1.SquareDistance( aPTest );
3174
3175 if ( dd < aSqDistMin ) {
3176 ap2 = aPTest;
3177 aSqDistMin = dd;
3178 }
3179 }
3180 }
3181 return ap2;
3182}
3183
3184// ------------------------------------------------------------------------------------------------
3185//function: DecompositionOfWLine
3186// purpose:
3187// ------------------------------------------------------------------------------------------------
3188Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
3189 const Handle(GeomAdaptor_HSurface)& theSurface1,
3190 const Handle(GeomAdaptor_HSurface)& theSurface2,
3191 const TopoDS_Face& theFace1,
3192 const TopoDS_Face& theFace2,
3193 const IntTools_LineConstructor& theLConstructor,
3194 const Standard_Boolean theAvoidLConstructor,
3195 IntPatch_SequenceOfLine& theNewLines,
3196 Standard_Real& theReachedTol3d) {
3197
3198 Standard_Boolean bRet, bAvoidLineConstructor;
3199 Standard_Integer aNbPnts, aNbParts;
3200 //
3201 bRet=Standard_False;
3202 aNbPnts=theWLine->NbPnts();
3203 bAvoidLineConstructor=theAvoidLConstructor;
3204 //
3205 if(!aNbPnts){
3206 return bRet;
3207 }
3208 if (!bAvoidLineConstructor) {
3209 aNbParts=theLConstructor.NbParts();
3210 if (!aNbParts) {
3211 return bRet;
3212 }
3213 }
3214 //
3215 Standard_Boolean bIsPrevPointOnBoundary, bIsPointOnBoundary, bIsCurrentPointOnBoundary;
3216 Standard_Integer nblines, pit, i, j;
3217 Standard_Real aTol;
3218 TColStd_Array1OfListOfInteger anArrayOfLines(1, aNbPnts);
3219 TColStd_Array1OfInteger anArrayOfLineType(1, aNbPnts);
3220 TColStd_ListOfInteger aListOfPointIndex;
3221 IntTools_Context aContext;
3222
3223 Handle(TColgp_HArray1OfPnt2d) aTanZoneS1;
3224 Handle(TColgp_HArray1OfPnt2d) aTanZoneS2;
3225 Handle(TColStd_HArray1OfReal) aTanZoneRadius;
3226 Standard_Integer aNbZone = ComputeTangentZones( theSurface1, theSurface2, theFace1, theFace2,
3227 aTanZoneS1, aTanZoneS2, aTanZoneRadius );
3228
3229 //
3230 nblines=0;
3231 aTol=Precision::Confusion();
3232 aTol=0.5*aTol;
3233 bIsPrevPointOnBoundary=Standard_False;
3234 bIsPointOnBoundary=Standard_False;
3235 //
3236 // 1. ...
3237 //
3238 // Points
3239 for(pit = 1; pit <= aNbPnts; ++pit) {
3240 Standard_Boolean bIsOnFirstBoundary, isperiodic;
3241 Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
3242 Standard_Real aParameter, anoffset, anAdjustPar;
3243 Standard_Real umin, umax, vmin, vmax;
3244 //
3245 bIsCurrentPointOnBoundary = Standard_False;
3246 const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
3247 //
3248 // Surface
3249 for(i = 0; i < 2; ++i) {
3250 Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
3251 aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
3252 if(!i) {
3253 aPoint.ParametersOnS1(U, V);
3254 }
3255 else {
3256 aPoint.ParametersOnS2(U, V);
3257 }
3258 // U, V
3259 for(j = 0; j < 2; j++) {
3260 isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
3261 if(!isperiodic){
3262 continue;
3263 }
3264 //
3265 if (!j) {
3266 aResolution=aGASurface->UResolution(aTol);
3267 aPeriod=aGASurface->UPeriod();
3268 alowerboundary=umin;
3269 aupperboundary=umax;
3270 aParameter=U;
3271 }
3272 else {
3273 aResolution=aGASurface->VResolution(aTol);
3274 aPeriod=aGASurface->VPeriod();
3275 alowerboundary=vmin;
3276 aupperboundary=vmax;
3277 aParameter=V;
3278 }
3279
3280 anoffset = 0.;
3281 anAdjustPar = AdjustPeriodic(aParameter,
3282 alowerboundary,
3283 aupperboundary,
3284 aPeriod,
3285 anoffset);
3286 //
3287 bIsOnFirstBoundary = Standard_True;// ?
3288 bIsPointOnBoundary=
3289 IsPointOnBoundary(anAdjustPar,
3290 alowerboundary,
3291 aupperboundary,
3292 aResolution,
3293 bIsOnFirstBoundary);
3294 //
3295 if(bIsPointOnBoundary) {
3296 bIsCurrentPointOnBoundary = Standard_True;
3297 break;
3298 }
3299 else {
3300 // check if a point belong to a tangent zone. Begin
3301 Standard_Integer zIt = 0;
3302 for ( zIt = 1; zIt <= aNbZone; zIt++ ) {
3303 gp_Pnt2d aPZone = (i == 0) ? aTanZoneS1->Value(zIt) : aTanZoneS2->Value(zIt);
3304 Standard_Real aZoneRadius = aTanZoneRadius->Value(zIt);
3305
3306 if ( IsInsideTanZone(gp_Pnt2d( U, V ), aPZone, aZoneRadius, aGASurface ) ) {
3307 // set boundary flag to split the curve by a tangent zone
3308 bIsPointOnBoundary = Standard_True;
3309 bIsCurrentPointOnBoundary = Standard_True;
3310 if ( theReachedTol3d < aZoneRadius ) {
3311 theReachedTol3d = aZoneRadius;
3312 }
3313 break;
3314 }
3315 }
3316 }
3317 }//for(j = 0; j < 2; j++) {
3318
3319 if(bIsCurrentPointOnBoundary){
3320 break;
3321 }
3322 }//for(i = 0; i < 2; ++i) {
3323 //
3324 if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
3325 if(!aListOfPointIndex.IsEmpty()) {
3326 nblines++;
3327 anArrayOfLines.SetValue(nblines, aListOfPointIndex);
3328 anArrayOfLineType.SetValue(nblines, bIsPrevPointOnBoundary);
3329 aListOfPointIndex.Clear();
3330 }
3331 bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
3332 }
3333 aListOfPointIndex.Append(pit);
3334 } //for(pit = 1; pit <= aNbPnts; ++pit) {
3335 //
3336 if(!aListOfPointIndex.IsEmpty()) {
3337 nblines++;
3338 anArrayOfLines.SetValue(nblines, aListOfPointIndex);
3339 anArrayOfLineType.SetValue(nblines, bIsPrevPointOnBoundary);
3340 aListOfPointIndex.Clear();
3341 }
3342 //
3343 if(nblines<=1) {
3344 return bRet; //Standard_False;
3345 }
3346 //
3347 //
3348 // 2. Correct wlines.begin
3349 TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
3350 Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S();
3351 //
3352 for(i = 1; i <= nblines; i++) {
3353 if(anArrayOfLineType.Value(i) != 0) {
3354 continue;
3355 }
3356 const TColStd_ListOfInteger& aListOfIndex = anArrayOfLines.Value(i);
3357 if(aListOfIndex.Extent() < 2) {
3358 continue;
3359 }
3360 TColStd_ListOfInteger aListOfFLIndex;
3361
3362 for(j = 0; j < 2; j++) {
3363 Standard_Integer aneighbourindex = (j == 0) ? (i - 1) : (i + 1);
3364
3365 if((aneighbourindex < 1) || (aneighbourindex > nblines))
3366 continue;
3367
3368 if(anArrayOfLineType.Value(aneighbourindex) == 0)
3369 continue;
3370 const TColStd_ListOfInteger& aNeighbour = anArrayOfLines.Value(aneighbourindex);
3371 Standard_Integer anIndex = (j == 0) ? aNeighbour.Last() : aNeighbour.First();
3372 const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
3373
3374 IntSurf_PntOn2S aNewP = aPoint;
3375
3376 for(Standard_Integer surfit = 0; surfit < 2; surfit++) {
3377
3378 Handle(GeomAdaptor_HSurface) aGASurface = (surfit == 0) ? theSurface1 : theSurface2;
3379 Standard_Real umin=0., umax=0., vmin=0., vmax=0.;
3380 aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
3381 Standard_Real U=0., V=0.;
3382
3383 if(surfit == 0)
3384 aNewP.ParametersOnS1(U, V);
3385 else
3386 aNewP.ParametersOnS2(U, V);
3387 Standard_Integer nbboundaries = 0;
3388
3389 Standard_Boolean bIsNearBoundary = Standard_False;
3390 Standard_Integer aZoneIndex = 0;
3391 Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
3392 Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
3393
3394
3395 for(Standard_Integer parit = 0; parit < 2; parit++) {
3396 Standard_Boolean isperiodic = (parit == 0) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
3397
3398 Standard_Real aResolution = (parit == 0) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
3399 Standard_Real alowerboundary = (parit == 0) ? umin : vmin;
3400 Standard_Real aupperboundary = (parit == 0) ? umax : vmax;
3401
3402 Standard_Real aParameter = (parit == 0) ? U : V;
3403 Standard_Boolean bIsOnFirstBoundary = Standard_True;
3404
3405 if(!isperiodic) {
3406 bIsPointOnBoundary=
3407 IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
3408 if(bIsPointOnBoundary) {
3409 bIsUBoundary = (parit == 0);
3410 bIsFirstBoundary = bIsOnFirstBoundary;
3411 nbboundaries++;
3412 }
3413 }
3414 else {
3415 Standard_Real aPeriod = (parit == 0) ? aGASurface->UPeriod() : aGASurface->VPeriod();
3416 Standard_Real anoffset = 0.;
3417 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
3418
3419 bIsPointOnBoundary=
3420 IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
3421 if(bIsPointOnBoundary) {
3422 bIsUBoundary = (parit == 0);
3423 bIsFirstBoundary = bIsOnFirstBoundary;
3424 nbboundaries++;
3425 }
3426 else {
3427 //check neighbourhood of boundary
3428 Standard_Real anEpsilon = aResolution * 100.;
3429 Standard_Real aPart = ( aupperboundary - alowerboundary ) * 0.1;
3430 anEpsilon = ( anEpsilon > aPart ) ? aPart : anEpsilon;
3431
3432 bIsNearBoundary = IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary,
3433 anEpsilon, bIsOnFirstBoundary);
3434
3435 }
3436 }
3437 }
3438
3439 // check if a point belong to a tangent zone. Begin
3440 for ( Standard_Integer zIt = 1; zIt <= aNbZone; zIt++ ) {
3441 gp_Pnt2d aPZone = (surfit == 0) ? aTanZoneS1->Value(zIt) : aTanZoneS2->Value(zIt);
3442 Standard_Real aZoneRadius = aTanZoneRadius->Value(zIt);
3443
3444 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
3445 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
3446 Standard_Real nU1, nV1;
3447
3448 if(surfit == 0)
3449 aNeighbourPoint.ParametersOnS1(nU1, nV1);
3450 else
3451 aNeighbourPoint.ParametersOnS2(nU1, nV1);
3452 gp_Pnt2d ap1(nU1, nV1);
3453 gp_Pnt2d ap2 = AdjustByNeighbour( ap1, gp_Pnt2d( U, V ), aGASurface );
3454
3455
3456 if ( IsInsideTanZone( ap2, aPZone, aZoneRadius, aGASurface ) ) {
3457 aZoneIndex = zIt;
3458 bIsNearBoundary = Standard_True;
3459 if ( theReachedTol3d < aZoneRadius ) {
3460 theReachedTol3d = aZoneRadius;
3461 }
3462 }
3463 }
3464 // check if a point belong to a tangent zone. End
3465 Standard_Boolean bComputeLineEnd = Standard_False;
3466
3467 if(nbboundaries == 2) {
3468 //xf
9e9df9d9 3469 bComputeLineEnd = Standard_True;
7fd59977 3470 //xt
3471 }
3472 else if(nbboundaries == 1) {
3473 Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
3474
3475 if(isperiodic) {
3476 Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
3477 Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
3478 Standard_Real aPeriod = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
3479 Standard_Real aParameter = (bIsUBoundary) ? U : V;
3480 Standard_Real anoffset = 0.;
3481 Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
3482
3483 Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
3484 Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
3485 anotherPar += anoffset;
3486 Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
3487 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
3488 Standard_Real nU1, nV1;
3489
3490 if(surfit == 0)
3491 aNeighbourPoint.ParametersOnS1(nU1, nV1);
3492 else
3493 aNeighbourPoint.ParametersOnS2(nU1, nV1);
3494
3495 Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
3496 Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
3497 bComputeLineEnd = Standard_True;
3498 Standard_Boolean bCheckAngle1 = Standard_False;
3499 Standard_Boolean bCheckAngle2 = Standard_False;
3500 gp_Vec2d aNewVec;
3501 Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
3502 Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
3503
3504 if(((adist1 - adist2) > Precision::PConfusion()) &&
3505 (adist2 < (aPeriod / 4.))) {
3506 bCheckAngle1 = Standard_True;
3507 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
3508
3509 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
3510 aNewP.SetValue((surfit == 0), anewU, anewV);
3511 bCheckAngle1 = Standard_False;
3512 }
3513 }
3514 else if(adist1 < (aPeriod / 4.)) {
3515 bCheckAngle2 = Standard_True;
3516 aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
3517
3518 if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
3519 bCheckAngle2 = Standard_False;
3520 }
3521 }
3522
3523 if(bCheckAngle1 || bCheckAngle2) {
3524 // assume there are at least two points in line (see "if" above)
3525 Standard_Integer anindexother = aneighbourpointindex;
3526
3527 while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
3528 anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
3529 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
3530 Standard_Real nU2, nV2;
3531
3532 if(surfit == 0)
3533 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
3534 else
3535 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
3536 gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
3537
3538 if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
3539 continue;
3540 }
3541 else {
3542 Standard_Real anAngle = aNewVec.Angle(aVecOld);
3543
3544 if((fabs(anAngle) < (Standard_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
3545
3546 if(bCheckAngle1) {
3547 Standard_Real U1, U2, V1, V2;
3548 IntSurf_PntOn2S atmppoint = aNewP;
3549 atmppoint.SetValue((surfit == 0), anewU, anewV);
3550 atmppoint.Parameters(U1, V1, U2, V2);
3551 gp_Pnt P1 = theSurface1->Value(U1, V1);
3552 gp_Pnt P2 = theSurface2->Value(U2, V2);
3553 gp_Pnt P0 = aPoint.Value();
3554
3555 if(P0.IsEqual(P1, aTol) &&
3556 P0.IsEqual(P2, aTol) &&
3557 P1.IsEqual(P2, aTol)) {
3558 bComputeLineEnd = Standard_False;
3559 aNewP.SetValue((surfit == 0), anewU, anewV);
3560 }
3561 }
3562
3563 if(bCheckAngle2) {
3564 bComputeLineEnd = Standard_False;
3565 }
3566 }
3567 break;
3568 }
3569 } // end while(anindexother...)
3570 }
3571 }
3572 }
3573 else if ( bIsNearBoundary ) {
3574 bComputeLineEnd = Standard_True;
3575 }
3576
3577 if(bComputeLineEnd) {
3578
3579 gp_Pnt2d anewpoint;
3580 Standard_Boolean found = Standard_False;
3581
3582 if ( bIsNearBoundary ) {
3583 // re-compute point near natural boundary or near tangent zone
3584 Standard_Real u1, v1, u2, v2;
3585 aNewP.Parameters( u1, v1, u2, v2 );
3586 if(surfit == 0)
3587 anewpoint = gp_Pnt2d( u1, v1 );
3588 else
3589 anewpoint = gp_Pnt2d( u2, v2 );
3590
3591 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
3592 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
3593 Standard_Real nU1, nV1;
3594
3595 if(surfit == 0)
3596 aNeighbourPoint.ParametersOnS1(nU1, nV1);
3597 else
3598 aNeighbourPoint.ParametersOnS2(nU1, nV1);
3599 gp_Pnt2d ap1(nU1, nV1);
3600 gp_Pnt2d ap2;
3601
3602
3603 if ( aZoneIndex ) {
3604 // exclude point from a tangent zone
3605 anewpoint = AdjustByNeighbour( ap1, anewpoint, aGASurface );
3606 gp_Pnt2d aPZone = (surfit == 0) ? aTanZoneS1->Value(aZoneIndex) : aTanZoneS2->Value(aZoneIndex);
3607 Standard_Real aZoneRadius = aTanZoneRadius->Value(aZoneIndex);
3608
3609 if ( FindPoint(ap1, anewpoint, umin, umax, vmin, vmax,
3610 aPZone, aZoneRadius, aGASurface, ap2) ) {
3611 anewpoint = ap2;
3612 found = Standard_True;
3613 }
3614 }
3615 else if ( aGASurface->IsUPeriodic() || aGASurface->IsVPeriodic() ) {
3616 // re-compute point near boundary if shifted on a period
3617 ap2 = AdjustByNeighbour( ap1, anewpoint, aGASurface );
3618
3619 if ( ( ap2.X() < umin ) || ( ap2.X() > umax ) ||
3620 ( ap2.Y() < vmin ) || ( ap2.Y() > vmax ) ) {
3621 found = FindPoint(ap1, ap2, umin, umax, vmin, vmax, anewpoint);
3622 }
3623 else {
3624 anewpoint = ap2;
3625 aNewP.SetValue( (surfit == 0), anewpoint.X(), anewpoint.Y() );
3626 }
3627 }
3628 }
3629 else {
3630
3631 Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
3632 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
3633 Standard_Real nU1, nV1;
3634
3635 if(surfit == 0)
3636 aNeighbourPoint.ParametersOnS1(nU1, nV1);
3637 else
3638 aNeighbourPoint.ParametersOnS2(nU1, nV1);
3639 gp_Pnt2d ap1(nU1, nV1);
3640 gp_Pnt2d ap2(nU1, nV1);
3641 Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
3642
3643 while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
3644 aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
3645 const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
3646 Standard_Real nU2, nV2;
3647
3648 if(surfit == 0)
3649 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
3650 else
3651 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
3652 ap2.SetX(nU2);
3653 ap2.SetY(nV2);
3654
3655 if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
3656 break;
3657 }
3658 }
3659 found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
3660 }
3661
3662 if(found) {
3663 // check point
3664 Standard_Real aCriteria = BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
3665 GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aContext.ProjPS(theFace2) : aContext.ProjPS(theFace1);
3666 Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
3667
3668 Handle(GeomAdaptor_HSurface) aSurfaceOther = (surfit == 0) ? theSurface2 : theSurface1;
3669
3670 gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
3671 aProjector.Perform(aP3d);
3672
3673 if(aProjector.IsDone()) {
3674 if(aProjector.LowerDistance() < aCriteria) {
3675 Standard_Real foundU = U, foundV = V;
3676 aProjector.LowerDistanceParameters(foundU, foundV);
3677
3678 //Correction of projected coordinates. Begin
3679 //Note, it may be shifted on a period
3680 Standard_Integer aneindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
3681 const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneindex1);
3682 Standard_Real nUn, nVn;
3683
3684 if(surfit == 0)
3685 aNeighbourPoint.ParametersOnS2(nUn, nVn);
3686 else
3687 aNeighbourPoint.ParametersOnS1(nUn, nVn);
3688 gp_Pnt2d aNeighbour2d(nUn, nVn);
3689 gp_Pnt2d anAdjustedPoint = AdjustByNeighbour( aNeighbour2d, gp_Pnt2d(foundU, foundV), aSurfaceOther );
3690 foundU = anAdjustedPoint.X();
3691 foundV = anAdjustedPoint.Y();
3692
3693 if ( ( anAdjustedPoint.X() < umin ) && ( anAdjustedPoint.X() > umax ) &&
3694 ( anAdjustedPoint.Y() < vmin ) && ( anAdjustedPoint.Y() > vmax ) ) {
3695 // attempt to roughly re-compute point
3696 foundU = ( foundU < umin ) ? umin : foundU;
3697 foundU = ( foundU > umax ) ? umax : foundU;
3698 foundV = ( foundV < vmin ) ? vmin : foundV;
3699 foundV = ( foundV > vmax ) ? vmax : foundV;
3700
3701 GeomAPI_ProjectPointOnSurf& aProjector2 = (surfit == 0) ? aContext.ProjPS(theFace1) : aContext.ProjPS(theFace2);
3702
3703 aP3d = aSurfaceOther->Value(foundU, foundV);
3704 aProjector2.Perform(aP3d);
3705
3706 if(aProjector2.IsDone()) {
3707 if(aProjector2.LowerDistance() < aCriteria) {
3708 Standard_Real foundU2 = anewpoint.X(), foundV2 = anewpoint.Y();
3709 aProjector2.LowerDistanceParameters(foundU2, foundV2);
3710 anewpoint.SetX(foundU2);
3711 anewpoint.SetY(foundV2);
3712 }
3713 }
3714 }
3715 //Correction of projected coordinates. End
3716
3717 if(surfit == 0)
3718 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
3719 else
3720 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
3721 }
3722 }
3723 }
3724 }
3725 }
3726 aSeqOfPntOn2S->Add(aNewP);
3727 aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
3728 }
3729 anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
3730 }
3731 // Correct wlines.end
3732
3733 // Split wlines.begin
3734 Standard_Integer nbiter;
3735 //
3736 nbiter=1;
3737 if (!bAvoidLineConstructor) {
3738 nbiter=theLConstructor.NbParts();
3739 }
3740 //
3741 for(j = 1; j <= nbiter; ++j) {
3742 Standard_Real fprm, lprm;
3743 Standard_Integer ifprm, ilprm;
3744 //
3745 if(bAvoidLineConstructor) {
3746 ifprm = 1;
3747 ilprm = theWLine->NbPnts();
3748 }
3749 else {
3750 theLConstructor.Part(j, fprm, lprm);
3751 ifprm = (Standard_Integer)fprm;
3752 ilprm = (Standard_Integer)lprm;
3753 }
3754
3755 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
3756 //
3757 for(i = 1; i <= nblines; i++) {
3758 if(anArrayOfLineType.Value(i) != 0) {
3759 continue;
3760 }
3761 const TColStd_ListOfInteger& aListOfIndex = anArrayOfLines.Value(i);
3762
3763 if(aListOfIndex.Extent() < 2) {
3764 continue;
3765 }
3766 const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
3767 Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
3768 Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
3769
3770 if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
3771 bhasfirstpoint = (i != 1);
3772 }
3773
3774 if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
3775 bhaslastpoint = (i != nblines);
3776 }
3777 Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
3778 Standard_Boolean bIsLastInside = ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
3779
3780 if(!bIsFirstInside && !bIsLastInside) {
3781 if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
3782 // append whole line, and boundaries if neccesary
3783 if(bhasfirstpoint) {
3784 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
3785 aLineOn2S->Add(aP);
3786 }
3787 TColStd_ListIteratorOfListOfInteger anIt(aListOfIndex);
3788
3789 for(; anIt.More(); anIt.Next()) {
3790 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
3791 aLineOn2S->Add(aP);
3792 }
3793
3794 if(bhaslastpoint) {
3795 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
3796 aLineOn2S->Add(aP);
3797 }
3798
3799 // check end of split line (end is almost always)
3800 Standard_Integer aneighbour = i + 1;
3801 Standard_Boolean bIsEndOfLine = Standard_True;
3802
3803 if(aneighbour <= nblines) {
3804 const TColStd_ListOfInteger& aListOfNeighbourIndex = anArrayOfLines.Value(aneighbour);
3805
3806 if((anArrayOfLineType.Value(aneighbour) != 0) &&
3807 (aListOfNeighbourIndex.IsEmpty())) {
3808 bIsEndOfLine = Standard_False;
3809 }
3810 }
3811
3812 if(bIsEndOfLine) {
3813 if(aLineOn2S->NbPoints() > 1) {
3814 Handle(IntPatch_WLine) aNewWLine =
3815 new IntPatch_WLine(aLineOn2S, Standard_False);
3816 theNewLines.Append(aNewWLine);
3817 }
3818 aLineOn2S = new IntSurf_LineOn2S();
3819 }
3820 }
3821 continue;
3822 }
3823 // end if(!bIsFirstInside && !bIsLastInside)
3824
3825 if(bIsFirstInside && bIsLastInside) {
3826 // append inside points between ifprm and ilprm
3827 TColStd_ListIteratorOfListOfInteger anIt(aListOfIndex);
3828
3829 for(; anIt.More(); anIt.Next()) {
3830 if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
3831 continue;
3832 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
3833 aLineOn2S->Add(aP);
3834 }
3835 }
3836 else {
3837
3838 if(bIsFirstInside) {
3839 // append points from ifprm to last point + boundary point
3840 TColStd_ListIteratorOfListOfInteger anIt(aListOfIndex);
3841
3842 for(; anIt.More(); anIt.Next()) {
3843 if(anIt.Value() < ifprm)
3844 continue;
3845 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
3846 aLineOn2S->Add(aP);
3847 }
3848
3849 if(bhaslastpoint) {
3850 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
3851 aLineOn2S->Add(aP);
3852 }
3853 // check end of split line (end is almost always)
3854 Standard_Integer aneighbour = i + 1;
3855 Standard_Boolean bIsEndOfLine = Standard_True;
3856
3857 if(aneighbour <= nblines) {
3858 const TColStd_ListOfInteger& aListOfNeighbourIndex = anArrayOfLines.Value(aneighbour);
3859
3860 if((anArrayOfLineType.Value(aneighbour) != 0) &&
3861 (aListOfNeighbourIndex.IsEmpty())) {
3862 bIsEndOfLine = Standard_False;
3863 }
3864 }
3865
3866 if(bIsEndOfLine) {
3867 if(aLineOn2S->NbPoints() > 1) {
3868 Handle(IntPatch_WLine) aNewWLine =
3869 new IntPatch_WLine(aLineOn2S, Standard_False);
3870 theNewLines.Append(aNewWLine);
3871 }
3872 aLineOn2S = new IntSurf_LineOn2S();
3873 }
3874 }
3875 // end if(bIsFirstInside)
3876
3877 if(bIsLastInside) {
3878 // append points from first boundary point to ilprm
3879 if(bhasfirstpoint) {
3880 const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
3881 aLineOn2S->Add(aP);
3882 }
3883 TColStd_ListIteratorOfListOfInteger anIt(aListOfIndex);
3884
3885 for(; anIt.More(); anIt.Next()) {
3886 if(anIt.Value() > ilprm)
3887 continue;
3888 const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
3889 aLineOn2S->Add(aP);
3890 }
3891 }
3892 //end if(bIsLastInside)
3893 }
3894 }
3895
3896 if(aLineOn2S->NbPoints() > 1) {
3897 Handle(IntPatch_WLine) aNewWLine =
3898 new IntPatch_WLine(aLineOn2S, Standard_False);
3899 theNewLines.Append(aNewWLine);
3900 }
3901 }
3902 // Split wlines.end
3903
3904 return Standard_True;
3905}
3906
3907// ------------------------------------------------------------------------------------------------
3908// static function: ParameterOutOfBoundary
3909// purpose: Computes a new parameter for given curve. The corresponding 2d points
0fc4f2e2 3910// does not lay on any boundary of given faces
7fd59977 3911// ------------------------------------------------------------------------------------------------
3912Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
3913 const Handle(Geom_Curve)& theCurve,
3914 const TopoDS_Face& theFace1,
3915 const TopoDS_Face& theFace2,
3916 const Standard_Real theOtherParameter,
3917 const Standard_Boolean bIncreasePar,
3918 Standard_Real& theNewParameter) {
3919 Standard_Boolean bIsComputed = Standard_False;
3920 theNewParameter = theParameter;
3921
3922 IntTools_Context aContext;
3923 Standard_Real acurpar = theParameter;
3924 TopAbs_State aState = TopAbs_ON;
3925 Standard_Integer iter = 0;
3926 Standard_Real asumtol = BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
3927 Standard_Real adelta = asumtol * 0.1;
3928 adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
3929 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
3930 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
3931
3932 Standard_Real u1, u2, v1, v2;
3933
3934 GeomAPI_ProjectPointOnSurf aPrj1;
3935 aSurf1->Bounds(u1, u2, v1, v2);
3936 aPrj1.Init(aSurf1, u1, u2, v1, v2);
3937
3938 GeomAPI_ProjectPointOnSurf aPrj2;
3939 aSurf2->Bounds(u1, u2, v1, v2);
3940 aPrj2.Init(aSurf2, u1, u2, v1, v2);
3941
3942 while(aState == TopAbs_ON) {
3943 if(bIncreasePar)
3944 acurpar += adelta;
3945 else
3946 acurpar -= adelta;
3947 gp_Pnt aPCurrent = theCurve->Value(acurpar);
3948 aPrj1.Perform(aPCurrent);
3949 Standard_Real U=0., V=0.;
3950
3951 if(aPrj1.IsDone()) {
3952 aPrj1.LowerDistanceParameters(U, V);
3953 aState = aContext.StatePointFace(theFace1, gp_Pnt2d(U, V));
3954 }
3955
3956 if(aState != TopAbs_ON) {
3957 aPrj2.Perform(aPCurrent);
3958
3959 if(aPrj2.IsDone()) {
3960 aPrj2.LowerDistanceParameters(U, V);
3961 aState = aContext.StatePointFace(theFace2, gp_Pnt2d(U, V));
3962 }
3963 }
3964
3965 if(iter > 11) {
3966 break;
3967 }
3968 iter++;
3969 }
3970
3971 if(iter <= 11) {
3972 theNewParameter = acurpar;
3973 bIsComputed = Standard_True;
3974
3975 if(bIncreasePar) {
3976 if(acurpar >= theOtherParameter)
3977 theNewParameter = theOtherParameter;
3978 }
3979 else {
3980 if(acurpar <= theOtherParameter)
3981 theNewParameter = theOtherParameter;
3982 }
3983 }
3984 return bIsComputed;
3985}
3986
0fc4f2e2
P
3987//=======================================================================
3988//function : IsCurveValid
3989//purpose :
3990//=======================================================================
7fd59977 3991Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve)
3992{
3993 if(thePCurve.IsNull())
3994 return Standard_False;
3995
3996 Standard_Real tolint = 1.e-10;
3997 Geom2dAdaptor_Curve PCA;
3998 IntRes2d_Domain PCD;
3999 Geom2dInt_GInter PCI;
4000
4001 Standard_Real pf = 0., pl = 0.;
4002 gp_Pnt2d pntf, pntl;
4003
4004 if(!thePCurve->IsClosed() && !thePCurve->IsPeriodic()) {
4005 pf = thePCurve->FirstParameter();
4006 pl = thePCurve->LastParameter();
4007 pntf = thePCurve->Value(pf);
4008 pntl = thePCurve->Value(pl);
4009 PCA.Load(thePCurve);
4010 if(!PCA.IsPeriodic()) {
4011 if(PCA.FirstParameter() > pf) pf = PCA.FirstParameter();
4012 if(PCA.LastParameter() < pl) pl = PCA.LastParameter();
4013 }
4014 PCD.SetValues(pntf,pf,tolint,pntl,pl,tolint);
4015 PCI.Perform(PCA,PCD,tolint,tolint);
4016 if(PCI.IsDone())
4017 if(PCI.NbPoints() > 0) {
4018 return Standard_False;
4019 }
4020 }
4021
4022 return Standard_True;
4023}
4024
4025//=======================================================================
4026//static function : ApproxWithPCurves
4027//purpose : for bug 20964 only
4028//=======================================================================
7fd59977 4029Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
4030 const gp_Sphere& theSph)
4031{
4032 Standard_Boolean bRes = Standard_True;
4033 Standard_Real R1 = theCyl.Radius(), R2 = theSph.Radius();
4034
4035 if(R1 < 2.*R2) return bRes;
4036
4037 gp_Lin anCylAx(theCyl.Axis());
4038
4039 Standard_Real aDist = anCylAx.Distance(theSph.Location());
4040 Standard_Real aDRel = Abs(aDist - R1)/R2;
4041
4042 if(aDRel > .2) return bRes;
4043
4044 Standard_Real par = ElCLib::Parameter(anCylAx, theSph.Location());
4045 gp_Pnt aP = ElCLib::Value(par, anCylAx);
4046 gp_Vec aV(aP, theSph.Location());
4047
4048 Standard_Real dd = aV.Dot(theSph.Position().XDirection());
4049
4050 if(aDist < R1 && dd > 0.) return Standard_False;
4051 if(aDist > R1 && dd < 0.) return Standard_False;
4052
4053
4054 return bRes;
4055}
7fd59977 4056//=======================================================================
4057//function : PerformPlanes
4058//purpose :
4059//=======================================================================
7fd59977 4060void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
4061 const Handle(GeomAdaptor_HSurface)& theS2,
4062 const Standard_Real TolAng,
4063 const Standard_Real TolTang,
4064 const Standard_Boolean theApprox1,
4065 const Standard_Boolean theApprox2,
4066 IntTools_SequenceOfCurves& theSeqOfCurve,
4067 Standard_Boolean& theTangentFaces)
4068{
4069
4070 gp_Pln aPln1 = theS1->Surface().Plane();
4071 gp_Pln aPln2 = theS2->Surface().Plane();
4072
4073 IntAna_QuadQuadGeo aPlnInter(aPln1, aPln2, TolAng, TolTang);
4074
4075 if(!aPlnInter.IsDone()) {
4076 theTangentFaces = Standard_False;
4077 return;
4078 }
4079
4080 IntAna_ResultType aResType = aPlnInter.TypeInter();
4081
4082 if(aResType == IntAna_Same) {
4083 theTangentFaces = Standard_True;
4084 return;
4085 }
4086
4087 theTangentFaces = Standard_False;
4088
4089 if(aResType == IntAna_Empty) {
4090 return;
4091 }
4092
4093 gp_Lin aLin = aPlnInter.Line(1);
4094
4095 ProjLib_Plane aProj;
4096
4097 aProj.Init(aPln1);
4098 aProj.Project(aLin);
4099 gp_Lin2d aLin2d1 = aProj.Line();
4100 //
4101 aProj.Init(aPln2);
4102 aProj.Project(aLin);
4103 gp_Lin2d aLin2d2 = aProj.Line();
4104 //
4105 //classify line2d1 relatively first plane
4106 Standard_Real P11, P12;
4107 Standard_Boolean IsCrossed = ClassifyLin2d(theS1, aLin2d1, TolTang, P11, P12);
4108 if(!IsCrossed) return;
4109 //classify line2d2 relatively second plane
4110 Standard_Real P21, P22;
4111 IsCrossed = ClassifyLin2d(theS2, aLin2d2, TolTang, P21, P22);
4112 if(!IsCrossed) return;
4113
4114 //Analysis of parametric intervals: must have common part
4115
4116 if(P21 >= P12) return;
4117 if(P22 <= P11) return;
4118
4119 Standard_Real pmin, pmax;
4120 pmin = Max(P11, P21);
4121 pmax = Min(P12, P22);
4122
4123 if(pmax - pmin <= TolTang) return;
4124
4125 Handle(Geom_Line) aGLin = new Geom_Line(aLin);
4126
4127 IntTools_Curve aCurve;
4128 Handle(Geom_TrimmedCurve) aGTLin = new Geom_TrimmedCurve(aGLin, pmin, pmax);
4129
4130 aCurve.SetCurve(aGTLin);
4131
4132 if(theApprox1) {
4133 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d1);
4134 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
4135 }
4136 else {
4137 Handle(Geom2d_Curve) H1;
4138 aCurve.SetFirstCurve2d(H1);
4139 }
4140 if(theApprox2) {
4141 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d2);
4142 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
4143 }
4144 else {
4145 Handle(Geom2d_Curve) H1;
4146 aCurve.SetFirstCurve2d(H1);
4147 }
4148
4149 theSeqOfCurve.Append(aCurve);
4150
4151}
4152
4153//=======================================================================
4154//function : ClassifyLin2d
4155//purpose :
4156//=======================================================================
4157static inline Standard_Boolean INTER(const Standard_Real d1,
4158 const Standard_Real d2,
4159 const Standard_Real tol)
4160{
4161 return (d1 > tol && d2 < -tol) ||
4162 (d1 < -tol && d2 > tol) ||
4163 ((d1 <= tol && d1 >= -tol) && (d2 > tol || d2 < -tol)) ||
4164 ((d2 <= tol && d2 >= -tol) && (d1 > tol || d1 < -tol));
4165}
4166static inline Standard_Boolean COINC(const Standard_Real d1,
4167 const Standard_Real d2,
4168 const Standard_Real tol)
4169{
4170 return (d1 <= tol && d1 >= -tol) && (d2 <= tol && d2 >= -tol);
4171}
4172Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
4173 const gp_Lin2d& theLin2d,
4174 const Standard_Real theTol,
4175 Standard_Real& theP1,
4176 Standard_Real& theP2)
4177
4178{
4179 Standard_Real xmin, xmax, ymin, ymax, d1, d2, A, B, C;
4180 Standard_Real par[2];
4181 Standard_Integer nbi = 0;
4182
4183 xmin = theS->Surface().FirstUParameter();
4184 xmax = theS->Surface().LastUParameter();
4185 ymin = theS->Surface().FirstVParameter();
4186 ymax = theS->Surface().LastVParameter();
4187
4188 theLin2d.Coefficients(A, B, C);
4189
4190 //xmin, ymin <-> xmin, ymax
4191 d1 = A*xmin + B*ymin + C;
4192 d2 = A*xmin + B*ymax + C;
4193
4194 if(INTER(d1, d2, theTol)) {
4195 //Intersection with boundary
4196 Standard_Real y = -(C + A*xmin)/B;
4197 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, y));
4198 nbi++;
4199 }
4200 else if (COINC(d1, d2, theTol)) {
4201 //Coincidence with boundary
4202 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
4203 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
4204 nbi = 2;
4205 }
4206
4207 if(nbi == 2) {
4208
4209 if(fabs(par[0]-par[1]) > theTol) {
4210 theP1 = Min(par[0], par[1]);
4211 theP2 = Max(par[0], par[1]);
4212 return Standard_True;
4213 }
4214 else return Standard_False;
4215
4216 }
4217
4218 //xmin, ymax <-> xmax, ymax
4219 d1 = d2;
4220 d2 = A*xmax + B*ymax + C;
4221
4222 if(d1 > theTol || d1 < -theTol) {//to avoid checking of
4223 //coincidence with the same point
4224 if(INTER(d1, d2, theTol)) {
4225 Standard_Real x = -(C + B*ymax)/A;
4226 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymax));
4227 nbi++;
4228 }
4229 else if (COINC(d1, d2, theTol)) {
4230 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
4231 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
4232 nbi = 2;
4233 }
4234 }
4235
4236 if(nbi == 2) {
4237
4238 if(fabs(par[0]-par[1]) > theTol) {
4239 theP1 = Min(par[0], par[1]);
4240 theP2 = Max(par[0], par[1]);
4241 return Standard_True;
4242 }
4243 else return Standard_False;
4244
4245 }
4246
4247 //xmax, ymax <-> xmax, ymin
4248 d1 = d2;
4249 d2 = A*xmax + B*ymin + C;
4250
4251 if(d1 > theTol || d1 < -theTol) {
4252 if(INTER(d1, d2, theTol)) {
4253 Standard_Real y = -(C + A*xmax)/B;
4254 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, y));
4255 nbi++;
4256 }
4257 else if (COINC(d1, d2, theTol)) {
4258 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
4259 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
4260 nbi = 2;
4261 }
4262 }
4263
4264 if(nbi == 2) {
4265 if(fabs(par[0]-par[1]) > theTol) {
4266 theP1 = Min(par[0], par[1]);
4267 theP2 = Max(par[0], par[1]);
4268 return Standard_True;
4269 }
4270 else return Standard_False;
4271 }
4272
4273 //xmax, ymin <-> xmin, ymin
4274 d1 = d2;
4275 d2 = A*xmin + B*ymin + C;
4276
4277 if(d1 > theTol || d1 < -theTol) {
4278 if(INTER(d1, d2, theTol)) {
4279 Standard_Real x = -(C + B*ymin)/A;
4280 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymin));
4281 nbi++;
4282 }
4283 else if (COINC(d1, d2, theTol)) {
4284 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
4285 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
4286 nbi = 2;
4287 }
4288 }
4289
4290 if(nbi == 2) {
4291 if(fabs(par[0]-par[1]) > theTol) {
4292 theP1 = Min(par[0], par[1]);
4293 theP2 = Max(par[0], par[1]);
4294 return Standard_True;
4295 }
4296 else return Standard_False;
4297 }
4298
4299 return Standard_False;
4300
4301}
4302//
7fd59977 4303//=======================================================================
4304//function : ApproxParameters
4305//purpose :
4306//=======================================================================
4307void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
4308 const Handle(GeomAdaptor_HSurface)& aHS2,
4309 Standard_Integer& iDegMin,
0fc4f2e2 4310 Standard_Integer& iDegMax)
7fd59977 4311{
4312 GeomAbs_SurfaceType aTS1, aTS2;
0fc4f2e2 4313
7fd59977 4314 //
4315 iDegMin=4;
4316 iDegMax=8;
7fd59977 4317 //
4318 aTS1=aHS1->Surface().GetType();
4319 aTS2=aHS2->Surface().GetType();
4320 //
4321 // Cylinder/Torus
4322 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
4323 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
0fc4f2e2 4324 Standard_Real aRC, aRT, dR, aPC;
7fd59977 4325 gp_Cylinder aCylinder;
4326 gp_Torus aTorus;
4327 //
4328 aPC=Precision::Confusion();
4329 //
0fc4f2e2
P
4330 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
4331 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
7fd59977 4332 //
4333 aRC=aCylinder.Radius();
4334 aRT=aTorus.MinorRadius();
4335 dR=aRC-aRT;
4336 if (dR<0.) {
4337 dR=-dR;
4338 }
4339 //
4340 if (dR<aPC) {
0fc4f2e2
P
4341 iDegMax=6;
4342 }
4343 }
4344}
4345//=======================================================================
4346//function : Tolerances
4347//purpose :
4348//=======================================================================
4349void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
4350 const Handle(GeomAdaptor_HSurface)& aHS2,
4351 Standard_Real& ,//aTolArc,
4352 Standard_Real& aTolTang,
4353 Standard_Real& ,//aUVMaxStep,
4354 Standard_Real& )//aDeflection)
4355{
4356 GeomAbs_SurfaceType aTS1, aTS2;
4357 //
4358 aTS1=aHS1->Surface().GetType();
4359 aTS2=aHS2->Surface().GetType();
4360 //
4361 // Cylinder/Torus
4362 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
4363 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
4364 Standard_Real aRC, aRT, dR, aPC;
4365 gp_Cylinder aCylinder;
4366 gp_Torus aTorus;
4367 //
4368 aPC=Precision::Confusion();
4369 //
4370 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Surface().Cylinder() : aHS2->Surface().Cylinder();
4371 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Surface().Torus() : aHS2->Surface().Torus();
4372 //
4373 aRC=aCylinder.Radius();
4374 aRT=aTorus.MinorRadius();
4375 dR=aRC-aRT;
4376 if (dR<0.) {
4377 dR=-dR;
7fd59977 4378 }
0fc4f2e2
P
4379 //
4380 if (dR<aPC) {
4381 aTolTang=0.1*aTolTang;
4382 }
4383 }
4384}
4385//modified by NIZNHY-PKV Tue Feb 15 10:15:31 2011f
4386//=======================================================================
4387//function : SortTypes
4388//purpose :
4389//=======================================================================
4390Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
4391 const GeomAbs_SurfaceType aType2)
4392{
4393 Standard_Boolean bRet;
4394 Standard_Integer aI1, aI2;
4395 //
4396 bRet=Standard_False;
4397 //
4398 aI1=IndexType(aType1);
4399 aI2=IndexType(aType2);
4400 if (aI1<aI2){
4401 bRet=!bRet;
4402 }
4403 return bRet;
4404}
4405//=======================================================================
4406//function : IndexType
4407//purpose :
4408//=======================================================================
4409Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
4410{
4411 Standard_Integer aIndex;
4412 //
4413 aIndex=11;
4414 //
4415 if (aType==GeomAbs_Plane) {
4416 aIndex=0;
7fd59977 4417 }
0fc4f2e2
P
4418 else if (aType==GeomAbs_Cylinder) {
4419 aIndex=1;
4420 }
4421 else if (aType==GeomAbs_Cone) {
4422 aIndex=2;
4423 }
4424 else if (aType==GeomAbs_Sphere) {
4425 aIndex=3;
4426 }
4427 else if (aType==GeomAbs_Torus) {
4428 aIndex=4;
4429 }
4430 else if (aType==GeomAbs_BezierSurface) {
4431 aIndex=5;
4432 }
4433 else if (aType==GeomAbs_BSplineSurface) {
4434 aIndex=6;
4435 }
4436 else if (aType==GeomAbs_SurfaceOfRevolution) {
4437 aIndex=7;
4438 }
4439 else if (aType==GeomAbs_SurfaceOfExtrusion) {
4440 aIndex=8;
4441 }
4442 else if (aType==GeomAbs_OffsetSurface) {
4443 aIndex=9;
4444 }
4445 else if (aType==GeomAbs_OtherSurface) {
4446 aIndex=10;
4447 }
4448 return aIndex;
7fd59977 4449}
0fc4f2e2 4450//modified by NIZNHY-PKV Tue Feb 15 10:15:39 2011t