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