0027322: geom/revolution_00/A1: Incorrect pcurve creation
[occt.git] / src / GeomInt / GeomInt_IntSS_1.cxx
CommitLineData
b311480e 1// Created on: 1995-01-27
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
4e14c88f 17#include <algorithm>
18#include <GeomInt_IntSS.hxx>
7fd59977 19
20#include <Adaptor3d_TopolTool.hxx>
42cf5bc1 21#include <Approx_CurveOnSurface.hxx>
42cf5bc1 22#include <ElSLib.hxx>
23#include <Extrema_ExtPS.hxx>
42cf5bc1 24#include <Geom2dAdaptor.hxx>
25#include <Geom2dAdaptor_Curve.hxx>
26#include <Geom2dInt_GInter.hxx>
4e14c88f 27#include <Geom2d_Curve.hxx>
28#include <Geom2d_Line.hxx>
29#include <Geom2d_TrimmedCurve.hxx>
42cf5bc1 30#include <GeomAdaptor.hxx>
31#include <GeomAdaptor_HSurface.hxx>
32#include <GeomInt.hxx>
4e14c88f 33#include <GeomInt_LineTool.hxx>
42cf5bc1 34#include <GeomInt_WLApprox.hxx>
7fd59977 35#include <GeomLib_Check2dBSplineCurve.hxx>
42cf5bc1 36#include <GeomLib_CheckBSplineCurve.hxx>
7fd59977 37#include <GeomProjLib.hxx>
4e14c88f 38#include <Geom_BSplineCurve.hxx>
39#include <Geom_Circle.hxx>
40#include <Geom_Ellipse.hxx>
41#include <Geom_Hyperbola.hxx>
42#include <Geom_Line.hxx>
43#include <Geom_Parabola.hxx>
44#include <Geom_TrimmedCurve.hxx>
42cf5bc1 45#include <IntPatch_ALine.hxx>
46#include <IntPatch_ALineToWLine.hxx>
47#include <IntPatch_GLine.hxx>
d4b867e6 48#include <IntPatch_RLine.hxx>
42cf5bc1 49#include <IntPatch_WLine.hxx>
7a91ad6e 50#include <IntRes2d_IntersectionSegment.hxx>
4e14c88f 51#include <IntSurf_Quadric.hxx>
52#include <Geom_Surface.hxx>
7fd59977 53
54//=======================================================================
4e14c88f 55//function : AdjustUPeriodic
7fd59977 56//purpose :
57//=======================================================================
4e14c88f 58 static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
7fd59977 59{
4e14c88f 60 if (aC2D.IsNull() || !aS->IsUPeriodic())
61 return;
7fd59977 62 //
4e14c88f 63 const Standard_Real aEps=Precision::PConfusion();//1.e-9
64 const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15
65 //
66 Standard_Real umin,umax,vmin,vmax;
67 aS->Bounds(umin,umax,vmin,vmax);
68 const Standard_Real aPeriod = aS->UPeriod();
69
70 const Standard_Real aT1=aC2D->FirstParameter();
71 const Standard_Real aT2=aC2D->LastParameter();
72 const Standard_Real aTx=aT1+0.467*(aT2-aT1);
73 const gp_Pnt2d aPx=aC2D->Value(aTx);
74 //
75 Standard_Real aUx=aPx.X();
76 if (fabs(aUx)<aEpsilon)
77 aUx=0.;
78 if (fabs(aUx-aPeriod)<aEpsilon)
79 aUx=aPeriod;
80 //
81 Standard_Real dU=0.;
82 while(aUx <(umin-aEps)) {
83 aUx+=aPeriod;
84 dU+=aPeriod;
85 }
86 while(aUx>(umax+aEps)) {
87 aUx-=aPeriod;
88 dU-=aPeriod;
89 }
90 //
91 if (dU!=0.) {
92 gp_Vec2d aV2D(dU, 0.);
93 aC2D->Translate(aV2D);
94 }
7fd59977 95}
4e14c88f 96
97 //=======================================================================
98//function : GetQuadric
7fd59977 99//purpose :
100//=======================================================================
4e14c88f 101 static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
7fd59977 102{
4e14c88f 103 switch (HS1->Surface().GetType())
104 {
105 case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break;
106 case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
107 case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break;
108 case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break;
109 case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break;
110 default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
7fd59977 111 }
112}
4e14c88f 113
114//=======================================================================
115//function : Parameters
116//purpose :
117//=======================================================================
118 static void Parameters( const Handle(GeomAdaptor_HSurface)& HS1,
119 const Handle(GeomAdaptor_HSurface)& HS2,
120 const gp_Pnt& Ptref,
121 Standard_Real& U1,
122 Standard_Real& V1,
123 Standard_Real& U2,
124 Standard_Real& V2)
125{
126 IntSurf_Quadric quad1,quad2;
127 //
128 GetQuadric(HS1, quad1);
129 GetQuadric(HS2, quad2);
130 //
131 quad1.Parameters(Ptref,U1,V1);
132 quad2.Parameters(Ptref,U2,V2);
133}
134
7fd59977 135//=======================================================================
4e14c88f 136//function : ParametersOfNearestPointOnSurface
7fd59977 137//purpose :
138//=======================================================================
4e14c88f 139static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
140 Standard_Real& theU,
141 Standard_Real& theV)
7fd59977 142{
4e14c88f 143 if(!theExtr.IsDone() || !theExtr.NbExt())
144 return Standard_False;
145
146 Standard_Integer anIndex = 1;
147 Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
148 for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
149 {
150 Standard_Real aSQD = theExtr.SquareDistance(i);
151 if (aSQD < aMinSQDist)
152 {
153 aMinSQDist = aSQD;
154 anIndex = i;
155 }
156 }
157
158 theExtr.Point(anIndex).Parameter(theU, theV);
159
160 return Standard_True;
7fd59977 161}
4e14c88f 162
7fd59977 163//=======================================================================
4e14c88f 164//function : GetSegmentBoundary
7fd59977 165//purpose :
166//=======================================================================
4e14c88f 167static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
168 const Handle(Geom2d_Curve)& theCurve,
169 GeomInt_VectorOfReal& theArrayOfParameters)
7fd59977 170{
4e14c88f 171 Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
172
173 if(theSegm.HasFirstPoint())
174 {
175 const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
176 aU1 = anIPF.ParamOnFirst();
177 }
178
179 if(theSegm.HasLastPoint())
180 {
181 const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
182 aU2 = anIPL.ParamOnFirst();
183 }
184
185 theArrayOfParameters.Append(aU1);
186 theArrayOfParameters.Append(aU2);
7fd59977 187}
4e14c88f 188
7fd59977 189//=======================================================================
4e14c88f 190//function : IntersectCurveAndBoundary
7fd59977 191//purpose :
192//=======================================================================
4e14c88f 193static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
194 const Handle(Geom2d_Curve)* const theArrBounds,
195 const Standard_Integer theNumberOfCurves,
196 const Standard_Real theTol,
197 GeomInt_VectorOfReal& theArrayOfParameters)
7fd59977 198{
4e14c88f 199 if(theC2d.IsNull())
200 return;
201
202 Geom2dAdaptor_Curve anAC1(theC2d);
203 for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
204 {
205 if(theArrBounds[aCurID].IsNull())
206 continue;
207
208 Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
209 Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
210
211 if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
212 continue;
213
214 for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
215 {
216 const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
217 theArrayOfParameters.Append(aParam);
218 }
219
220 for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
221 {
222 GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
223 }
224 }
7fd59977 225}
7fd59977 226
227//=======================================================================
228//function : MakeCurve
229//purpose :
230//=======================================================================
d4b867e6 231void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
4e14c88f 232 const Handle(Adaptor3d_TopolTool) & dom1,
233 const Handle(Adaptor3d_TopolTool) & dom2,
234 const Standard_Real Tol,
235 const Standard_Boolean Approx,
236 const Standard_Boolean ApproxS1,
237 const Standard_Boolean ApproxS2)
7fd59977 238
239{
240 Standard_Boolean myApprox1, myApprox2, myApprox;
241 Standard_Real Tolpc, myTolApprox;
242 IntPatch_IType typl;
243 Handle(Geom2d_BSplineCurve) H1;
244 Handle(Geom_Surface) aS1, aS2;
245 //
246 Tolpc = Tol;
247 myApprox=Approx;
248 myApprox1=ApproxS1;
249 myApprox2=ApproxS2;
250 myTolApprox=0.0000001;
251 //
252 aS1=myHS1->ChangeSurface().Surface();
253 aS2=myHS2->ChangeSurface().Surface();
254 //
255 Handle(IntPatch_Line) L = myIntersector.Line(Index);
256 typl = L->ArcType();
257 //
258 if(typl==IntPatch_Walking) {
4e14c88f 259 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
260 if(aWLine.IsNull()) {
7fd59977 261 return;
262 }
4e14c88f 263 L = aWLine;
7fd59977 264 }
265 //
266 // Line Constructor
267 myLConstruct.Perform(L);
268 if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) {
269 return;
270 }
271 // Do the Curve
272 Standard_Boolean ok;
273 Standard_Integer i, j, aNbParts;
274 Standard_Real fprm, lprm;
275 Handle(Geom_Curve) newc;
276
277 switch (typl) {
e618b526 278 //########################################
279 // Line, Parabola, Hyperbola
280 //########################################
7fd59977 281 case IntPatch_Lin:
282 case IntPatch_Parabola:
283 case IntPatch_Hyperbola: {
284 if (typl == IntPatch_Lin) {
285 newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
286 }
287 else if (typl == IntPatch_Parabola) {
288 newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
289 }
290 else if (typl == IntPatch_Hyperbola) {
291 newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
292 }
293 //
294 aNbParts=myLConstruct.NbParts();
295 for (i=1; i<=aNbParts; i++) {
296 myLConstruct.Part(i, fprm, lprm);
e618b526 297
7fd59977 298 if (!Precision::IsNegativeInfinite(fprm) &&
e618b526 299 !Precision::IsPositiveInfinite(lprm)) {
300 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
301 sline.Append(aCT3D);
302 //
303 if(myApprox1) {
304 Handle (Geom2d_Curve) C2d;
305 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
306 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
307 myTolReached2d=Tolpc;
308 }
309 slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
310 }
311 else {
312 slineS1.Append(H1);
313 }
314 //
315 if(myApprox2) {
316 Handle (Geom2d_Curve) C2d;
317 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
318 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
319 myTolReached2d=Tolpc;
320 }
321 //
322 slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
323 }
324 else {
325 slineS2.Append(H1);
326 }
7fd59977 327 } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm))
328
329 else {
7c4e9501 330 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
331 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
332 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
333 typS1 == GeomAbs_OffsetSurface ||
334 typS1 == GeomAbs_SurfaceOfRevolution ||
335 typS2 == GeomAbs_SurfaceOfExtrusion ||
336 typS2 == GeomAbs_OffsetSurface ||
337 typS2 == GeomAbs_SurfaceOfRevolution) {
338 sline.Append(newc);
339 slineS1.Append(H1);
340 slineS2.Append(H1);
341 continue;
342 }
343 Standard_Boolean bFNIt, bLPIt;
344 Standard_Real aTestPrm, dT=100.;
345 Standard_Real u1, v1, u2, v2, TolX;
346 //
347 bFNIt=Precision::IsNegativeInfinite(fprm);
348 bLPIt=Precision::IsPositiveInfinite(lprm);
349
350 aTestPrm=0.;
351
352 if (bFNIt && !bLPIt) {
353 aTestPrm=lprm-dT;
354 }
355 else if (!bFNIt && bLPIt) {
356 aTestPrm=fprm+dT;
357 }
358 //
359 gp_Pnt ptref(newc->Value(aTestPrm));
360 //
361 TolX = Precision::Confusion();
362 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
363 ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT);
364 if(ok) {
365 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
366 }
367 if (ok) {
368 sline.Append(newc);
369 slineS1.Append(H1);
370 slineS2.Append(H1);
371 }
7fd59977 372 }
373 }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
e618b526 374 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
375 break;
7fd59977 376
e618b526 377 //########################################
378 // Circle and Ellipse
379 //########################################
7fd59977 380 case IntPatch_Circle:
381 case IntPatch_Ellipse: {
382
383 if (typl == IntPatch_Circle) {
384 newc = new Geom_Circle
e618b526 385 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
7fd59977 386 }
387 else {
388 newc = new Geom_Ellipse
e618b526 389 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
7fd59977 390 }
391 //
96a95605 392 Standard_Real aPeriod, aRealEpsilon;
7fd59977 393 //
394 aRealEpsilon=RealEpsilon();
c6541a0c 395 aPeriod=M_PI+M_PI;
7fd59977 396 //
397 aNbParts=myLConstruct.NbParts();
398 //
399 for (i=1; i<=aNbParts; i++) {
400 myLConstruct.Part(i, fprm, lprm);
401 //
402 if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
e618b526 403 //==============================================
404 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
405 //
406 sline.Append(aTC3D);
407 //
408 fprm=aTC3D->FirstParameter();
409 lprm=aTC3D->LastParameter ();
410 ////
411 if(myApprox1) {
412 Handle (Geom2d_Curve) C2d;
413 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
414 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
415 myTolReached2d=Tolpc;
416 }
417 slineS1.Append(C2d);
418 }
419 else { ////
420 slineS1.Append(H1);
421 }
422 //
423 if(myApprox2) {
424 Handle (Geom2d_Curve) C2d;
425 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
426 if(Tolpc>myTolReached2d || myTolReached2d==0) {
427 myTolReached2d=Tolpc;
428 }
429 slineS2.Append(C2d);
430 }
431 else {
432 slineS2.Append(H1);
433 }
434 //==============================================
c6541a0c 435 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
7fd59977 436 //
437 else {// on regarde si on garde
e618b526 438 //
439 if (aNbParts==1) {
440 if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
441 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
442 //
443 sline.Append(aTC3D);
444 fprm=aTC3D->FirstParameter();
445 lprm=aTC3D->LastParameter ();
446
447 if(myApprox1) {
448 Handle (Geom2d_Curve) C2d;
449 BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
450 if(Tolpc>myTolReached2d || myTolReached2d==0) {
451 myTolReached2d=Tolpc;
452 }
453 slineS1.Append(C2d);
454 }
455 else { ////
456 slineS1.Append(H1);
457 }
458
459 if(myApprox2) {
460 Handle (Geom2d_Curve) C2d;
461 BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
462 if(Tolpc>myTolReached2d || myTolReached2d==0) {
463 myTolReached2d=Tolpc;
464 }
465 slineS2.Append(C2d);
466 }
467 else {
468 slineS2.Append(H1);
469 }
470 break;
471 }
472 }
473 //
474 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
475 //
476 aTwoPIdiv17=2.*M_PI/17.;
477 //
478 for (j=0; j<=17; j++) {
479 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
480 TolX = Precision::Confusion();
481
482 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
483 ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
484 if(ok) {
485 ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
486 }
487 if (ok) {
488 sline.Append(newc);
489 //==============================================
490 if(myApprox1) {
491 Handle (Geom2d_Curve) C2d;
492 BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
493 if(Tolpc>myTolReached2d || myTolReached2d==0) {
494 myTolReached2d=Tolpc;
495 }
496 slineS1.Append(C2d);
497 }
498 else {
499 slineS1.Append(H1);
500 }
501
502 if(myApprox2) {
503 Handle (Geom2d_Curve) C2d;
504 BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
505 if(Tolpc>myTolReached2d || myTolReached2d==0) {
506 myTolReached2d=Tolpc;
507 }
508 slineS2.Append(C2d);
509 }
510 else {
511 slineS2.Append(H1);
512 }
513 break;
514 }// end of if (ok) {
515 }// end of for (Standard_Integer j=0; j<=17; j++)
7fd59977 516 }// end of else { on regarde si on garde
517 }// for (i=1; i<=myLConstruct.NbParts(); i++)
e618b526 518 }// IntPatch_Circle: IntPatch_Ellipse
519 break;
520
521 //########################################
522 // Analytic
523 //########################################
7fd59977 524 case IntPatch_Analytic: {
525 IntSurf_Quadric quad1,quad2;
526 //
527 GetQuadric(myHS1, quad1);
528 GetQuadric(myHS2, quad2);
529 //=========
530 IntPatch_ALineToWLine convert (quad1, quad2);
e618b526 531
7fd59977 532 if (!myApprox) {
533 Handle(Geom2d_BSplineCurve) aH1, aH2;
534 //
535 aNbParts=myLConstruct.NbParts();
536 for (i=1; i<=aNbParts; i++) {
e618b526 537 myLConstruct.Part(i, fprm, lprm);
538 Handle(IntPatch_WLine) WL =
539 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
540 //
541 if(myApprox1) {
542 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
543 }
544
545 if(myApprox2) {
546 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
547 }
548 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
549 slineS1.Append(aH1);
550 slineS2.Append(aH2);
7fd59977 551 }
552 } // if (!myApprox)
553
554 else { // myApprox=TRUE
555 GeomInt_WLApprox theapp3d;
556 Standard_Real tol2d = myTolApprox;
557 //
4e14c88f 558 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
e618b526 559
7fd59977 560 aNbParts=myLConstruct.NbParts();
561 for (i=1; i<=aNbParts; i++) {
e618b526 562 myLConstruct.Part(i, fprm, lprm);
563 Handle(IntPatch_WLine) WL =
564 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
565
566 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
567 if (!theapp3d.IsDone()) {
568 //
569 Handle(Geom2d_BSplineCurve) aH1, aH2;
570
571 if(myApprox1) {
572 aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
573 }
574
575 if(myApprox2) {
576 aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
577 }
578 sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
579 slineS1.Append(aH1);
580 slineS2.Append(aH1);
581 }
582 //
583 else {
584 if(myApprox1 || myApprox2) {
585 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
586 myTolReached2d = theapp3d.TolReached2d();
587 }
588 }
589
590 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
591 myTolReached3d = theapp3d.TolReached3d();
592 }
593
594 Standard_Integer aNbMultiCurves, nbpoles;
595 aNbMultiCurves=theapp3d.NbMultiCurves();
596 for (j=1; j<=aNbMultiCurves; j++) {
597 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
598
599 nbpoles = mbspc.NbPoles();
600 TColgp_Array1OfPnt tpoles(1, nbpoles);
601 mbspc.Curve(1, tpoles);
602 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
603 mbspc.Knots(),
604 mbspc.Multiplicities(),
605 mbspc.Degree());
606
607 GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
608 Check.FixTangent(Standard_True,Standard_True);
609 //
610 sline.Append(BS);
611 //
612 if(myApprox1) {
613 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
614 mbspc.Curve(2,tpoles2d);
615 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
616 mbspc.Knots(),
617 mbspc.Multiplicities(),
618 mbspc.Degree());
619
620 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
621 newCheck.FixTangent(Standard_True,Standard_True);
622 slineS1.Append(BS2);
623 }
624 else {
625 slineS1.Append(H1);
626 }
627
628 if(myApprox2) {
629 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
630 Standard_Integer TwoOrThree;
631 TwoOrThree=myApprox1 ? 3 : 2;
632 mbspc.Curve(TwoOrThree, tpoles2d);
633 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
634 mbspc.Knots(),
635 mbspc.Multiplicities(),
636 mbspc.Degree());
637
638 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
639 newCheck.FixTangent(Standard_True,Standard_True);
640 //
641 slineS2.Append(BS2);
642 }
643 else {
644 slineS2.Append(H1);
645 }
646 //
647 }// for (j=1; j<=aNbMultiCurves; j++) {
648 }// else from if (!theapp3d.IsDone())
7fd59977 649 }// for (i=1; i<=aNbParts; i++) {
650 }// else { // myApprox=TRUE
651 }// case IntPatch_Analytic:
e618b526 652 break;
653
4e14c88f 654 //########################################
655 // Walking
656 //########################################
7fd59977 657 case IntPatch_Walking:{
658 Handle(IntPatch_WLine) WL =
659 Handle(IntPatch_WLine)::DownCast(L);
4e14c88f 660
77dbd1f1 661#ifdef GEOMINT_INTSS_DEBUG
662 WL->Dump(0);
4e14c88f 663#endif
664
7fd59977 665 //
666 Standard_Integer ifprm, ilprm;
667 //
668 if (!myApprox) {
669 aNbParts=myLConstruct.NbParts();
670 for (i=1; i<=aNbParts; i++) {
e618b526 671 myLConstruct.Part(i, fprm, lprm);
672 ifprm=(Standard_Integer)fprm;
673 ilprm=(Standard_Integer)lprm;
674 //
675 Handle(Geom2d_BSplineCurve) aH1, aH2;
676
677 if(myApprox1) {
678 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
679 }
680 if(myApprox2) {
681 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
682 }
683 //
684 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
685 //
686 sline.Append(aBSp);
687 slineS1.Append(aH1);
688 slineS2.Append(aH2);
7fd59977 689 }
690 }
691 //
692 else {
693 Standard_Boolean bIsDecomposited;
694 Standard_Integer nbiter, aNbSeqOfL;
695 GeomInt_WLApprox theapp3d;
696 IntPatch_SequenceOfLine aSeqOfL;
697 Standard_Real tol2d, aTolSS;
698 //
699 tol2d = myTolApprox;
700 aTolSS=2.e-7;
4e14c88f 701 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2);
7fd59977 702 //
703 bIsDecomposited =
4e14c88f 704 GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
7fd59977 705 //
706 aNbParts=myLConstruct.NbParts();
707 aNbSeqOfL=aSeqOfL.Length();
708 //
709 nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
710 //
711 for(i = 1; i <= nbiter; i++) {
e618b526 712 if(bIsDecomposited) {
713 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
714 ifprm = 1;
715 ilprm = WL->NbPnts();
716 }
717 else {
718 myLConstruct.Part(i, fprm, lprm);
719 ifprm = (Standard_Integer)fprm;
720 ilprm = (Standard_Integer)lprm;
721 }
722 //-- lbr :
723 //-- Si une des surfaces est un plan , on approxime en 2d
724 //-- sur cette surface et on remonte les points 2d en 3d.
725 GeomAbs_SurfaceType typs1, typs2;
726 typs1 = myHS1->Surface().GetType();
727 typs2 = myHS2->Surface().GetType();
728 //
729 if(typs1 == GeomAbs_Plane) {
730 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
731 Standard_True, myApprox2,
732 ifprm, ilprm);
733 }
734 else if(typs2 == GeomAbs_Plane) {
735 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
736 myApprox1,Standard_True,
737 ifprm, ilprm);
738 }
739 else {
740 //
741 if (myHS1 != myHS2){
742 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
743 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
744
4e14c88f 745 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
e618b526 746 //Standard_Boolean bUseSurfaces;
747 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
748 //if (bUseSurfaces) {
749 //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
750 //}
751 }
752 }
753 //
754 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
755 myApprox1,myApprox2,
756 ifprm, ilprm);
757 }
758
759 if (!theapp3d.IsDone()) {
760 //
761 Handle(Geom2d_BSplineCurve) aH1, aH2;
762 //
763 Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
764 if(myApprox1) {
765 aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
766 }
767 if(myApprox2) {
768 aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
769 }
770 //
771 sline.Append(aBSp);
772 slineS1.Append(aH1);
773 slineS2.Append(aH2);
774 }//if (!theapp3d.IsDone())
775
776 else {
777 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
778 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
779 myTolReached2d = theapp3d.TolReached2d();
780 }
781 }
782 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
783 myTolReached3d = myTolReached2d;
784 }
785 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
786 myTolReached3d = theapp3d.TolReached3d();
787 }
788
789 Standard_Integer aNbMultiCurves, nbpoles;
790 //
791 aNbMultiCurves=theapp3d.NbMultiCurves();
792 for (j=1; j<=aNbMultiCurves; j++) {
793 if(typs1 == GeomAbs_Plane) {
794 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
795 nbpoles = mbspc.NbPoles();
796
797 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
798 TColgp_Array1OfPnt tpoles(1,nbpoles);
799
800 mbspc.Curve(1,tpoles2d);
801 const gp_Pln& Pln = myHS1->Surface().Plane();
802 //
803 Standard_Integer ik;
804 for(ik = 1; ik<= nbpoles; ik++) {
805 tpoles.SetValue(ik,
806 ElSLib::Value(tpoles2d.Value(ik).X(),
807 tpoles2d.Value(ik).Y(),
808 Pln));
809 }
810 //
811 Handle(Geom_BSplineCurve) BS =
812 new Geom_BSplineCurve(tpoles,
813 mbspc.Knots(),
814 mbspc.Multiplicities(),
815 mbspc.Degree());
816 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
817 Check.FixTangent(Standard_True, Standard_True);
818 //
819 sline.Append(BS);
820 //
821 if(myApprox1) {
822 Handle(Geom2d_BSplineCurve) BS1 =
823 new Geom2d_BSplineCurve(tpoles2d,
824 mbspc.Knots(),
825 mbspc.Multiplicities(),
826 mbspc.Degree());
827 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
828 Check1.FixTangent(Standard_True,Standard_True);
829 //
830 AdjustUPeriodic (aS1, BS1);
831 //
832 slineS1.Append(BS1);
833 }
834 else {
835 slineS1.Append(H1);
836 }
837
838 if(myApprox2) {
839 mbspc.Curve(2, tpoles2d);
840
841 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
842 mbspc.Knots(),
843 mbspc.Multiplicities(),
844 mbspc.Degree());
845 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
846 newCheck.FixTangent(Standard_True,Standard_True);
847 //
848 AdjustUPeriodic (aS2, BS2);
849 //
850 slineS2.Append(BS2);
851 }
852 else {
853 slineS2.Append(H1);
854 }
855 }//if(typs1 == GeomAbs_Plane)
856 //
857 else if(typs2 == GeomAbs_Plane) {
858 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
859 nbpoles = mbspc.NbPoles();
860
861 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
862 TColgp_Array1OfPnt tpoles(1,nbpoles);
863 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
864 const gp_Pln& Pln = myHS2->Surface().Plane();
865 //
866 Standard_Integer ik;
867 for(ik = 1; ik<= nbpoles; ik++) {
868 tpoles.SetValue(ik,
869 ElSLib::Value(tpoles2d.Value(ik).X(),
870 tpoles2d.Value(ik).Y(),
871 Pln));
872
873 }
874 //
875 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
876 mbspc.Knots(),
877 mbspc.Multiplicities(),
878 mbspc.Degree());
879 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
880 Check.FixTangent(Standard_True,Standard_True);
881 //
882 sline.Append(BS);
883 //
884 if(myApprox2) {
885 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
886 mbspc.Knots(),
887 mbspc.Multiplicities(),
888 mbspc.Degree());
889 GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
890 Check1.FixTangent(Standard_True,Standard_True);
891 //
892 //
893 AdjustUPeriodic (aS2, BS1);
894 //
895 slineS2.Append(BS1);
896 }
897 else {
898 slineS2.Append(H1);
899 }
900
901 if(myApprox1) {
902 mbspc.Curve(1,tpoles2d);
903 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
904 mbspc.Knots(),
905 mbspc.Multiplicities(),
906 mbspc.Degree());
907 GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
908 Check2.FixTangent(Standard_True,Standard_True);
909 //
910 //
911 AdjustUPeriodic (aS1, BS2);
912 //
913 slineS1.Append(BS2);
914 }
915 else {
916 slineS1.Append(H1);
917 }
918 } // else if(typs2 == GeomAbs_Plane)
919 //
920 else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
921 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
922 nbpoles = mbspc.NbPoles();
923 TColgp_Array1OfPnt tpoles(1,nbpoles);
924 mbspc.Curve(1,tpoles);
925 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
926 mbspc.Knots(),
927 mbspc.Multiplicities(),
928 mbspc.Degree());
929 GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
930 Check.FixTangent(Standard_True,Standard_True);
931 //
932 //Check IsClosed()
933 Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
934 BS->EndPoint().XYZ().SquareModulus());
935 Standard_Real eps = Epsilon(aDist);
94f71cad 936 if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
e618b526 937 {
94f71cad 938 // Avoid creating B-splines containing two coincident poles only
939 if (mbspc.Degree() == 1 && nbpoles == 2)
940 continue;
941
942 if (!BS->IsClosed() && !BS->IsPeriodic())
943 {
944 //force Closed()
945 gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
946 BS->SetPole(1, aPm);
947 BS->SetPole(BS->NbPoles(), aPm);
948 }
e618b526 949 }
950 sline.Append(BS);
951
952 if(myApprox1) {
953 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
954 mbspc.Curve(2,tpoles2d);
955 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
956 mbspc.Knots(),
957 mbspc.Multiplicities(),
958 mbspc.Degree());
959 GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
960 newCheck.FixTangent(Standard_True,Standard_True);
961 //
962 AdjustUPeriodic (aS1, BS1);
963 //
964 slineS1.Append(BS1);
965 }
966 else {
967 slineS1.Append(H1);
968 }
969 if(myApprox2) {
970 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
971 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
972 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
973 mbspc.Knots(),
974 mbspc.Multiplicities(),
975 mbspc.Degree());
976 GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
977 newCheck.FixTangent(Standard_True,Standard_True);
978 //
979 AdjustUPeriodic (aS2, BS2);
980 //
981 slineS2.Append(BS2);
982 }
983 else {
984 slineS2.Append(H1);
985 }
986 }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
987 }// for (j=1; j<=aNbMultiCurves; j++
7c4e9501 988 }
7fd59977 989 }
990 }
991 }
e618b526 992 break;
993
7fd59977 994 case IntPatch_Restriction:
e618b526 995 {
d4b867e6 996 Handle(IntPatch_RLine) RL =
997 Handle(IntPatch_RLine)::DownCast(L);
998 Handle(Geom_Curve) aC3d;
999 Handle(Geom2d_Curve) aC2d1, aC2d2;
1000 Standard_Real aTolReached;
1001 TreatRLine(RL, myHS1, myHS2, aC3d,
1002 aC2d1, aC2d2, aTolReached);
1003
1004 if(aC3d.IsNull())
1005 break;
1006
1007 Bnd_Box2d aBox1, aBox2;
1008
1009 const Standard_Real aU1f = myHS1->FirstUParameter(),
1010 aV1f = myHS1->FirstVParameter(),
1011 aU1l = myHS1->LastUParameter(),
1012 aV1l = myHS1->LastVParameter();
1013 const Standard_Real aU2f = myHS2->FirstUParameter(),
1014 aV2f = myHS2->FirstVParameter(),
1015 aU2l = myHS2->LastUParameter(),
1016 aV2l = myHS2->LastVParameter();
1017
1018 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1019 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1020 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1021 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1022
1023 GeomInt_VectorOfReal anArrayOfParameters;
1024
1025 //We consider here that the intersection line is same-parameter-line
1026 anArrayOfParameters.Append(aC3d->FirstParameter());
1027 anArrayOfParameters.Append(aC3d->LastParameter());
1028
1029 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1030
1031 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1032
1033 //Trim RLine found.
1034 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
e618b526 1035 {
d4b867e6 1036 const Standard_Real aParF = anArrayOfParameters(anInd),
1037 aParL = anArrayOfParameters(anInd+1);
1038
1039 if((aParL - aParF) <= Precision::PConfusion())
1040 continue;
1041
1042 const Standard_Real aPar = 0.5*(aParF + aParL);
1043 gp_Pnt2d aPt;
1044
1045 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1046 if(!aC2d1.IsNull())
1047 {
1048 aC2d1->D0(aPar, aPt);
1049
1050 if(aBox1.IsOut(aPt))
1051 continue;
1052
1053 if(myApprox1)
1054 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
1055 }
1056
1057 if(!aC2d2.IsNull())
1058 {
1059 aC2d2->D0(aPar, aPt);
1060
1061 if(aBox2.IsOut(aPt))
1062 continue;
1063
1064 if(myApprox2)
1065 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1066 }
1067
1068 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1069
1070 sline.Append(aCurv3d);
1071 slineS1.Append(aCurv2d1);
1072 slineS2.Append(aCurv2d2);
e618b526 1073 }
1074 }
7fd59977 1075 break;
7fd59977 1076 }
1077}
4e14c88f 1078
7fd59977 1079//=======================================================================
4e14c88f 1080//function : TreatRLine
1081//purpose : Approx of Restriction line
7fd59977 1082//=======================================================================
4e14c88f 1083void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
1084 const Handle(GeomAdaptor_HSurface)& theHS1,
1085 const Handle(GeomAdaptor_HSurface)& theHS2,
1086 Handle(Geom_Curve)& theC3d,
1087 Handle(Geom2d_Curve)& theC2d1,
1088 Handle(Geom2d_Curve)& theC2d2,
1089 Standard_Real& theTolReached)
7fd59977 1090{
4e14c88f 1091 Handle(GeomAdaptor_HSurface) aGAHS;
1092 Handle(Adaptor2d_HCurve2d) anAHC2d;
1093 Standard_Real tf, tl;
1094 gp_Lin2d aL;
1095 // It is assumed that 2d curve is 2d line (rectangular surface domain)
1096 if(theRL->IsArcOnS1())
1097 {
1098 aGAHS = theHS1;
1099 anAHC2d = theRL->ArcOnS1();
1100 theRL->ParamOnS1(tf, tl);
1101 theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
1102 tf = Max(tf, theC2d1->FirstParameter());
1103 tl = Min(tl, theC2d1->LastParameter());
1104 theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl);
7fd59977 1105 }
4e14c88f 1106 else if (theRL->IsArcOnS2())
7fd59977 1107 {
4e14c88f 1108 aGAHS = theHS2;
1109 anAHC2d = theRL->ArcOnS2();
1110 theRL->ParamOnS2(tf, tl);
1111 theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
1112 tf = Max(tf, theC2d2->FirstParameter());
1113 tl = Min(tl, theC2d2->LastParameter());
1114 theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl);
d4b867e6 1115 }
1116 else
1117 {
1118 return;
1119 }
1120 //
1121 //To provide sameparameter it is necessary to get 3d curve as
1122 //approximation of curve on surface.
1123 Standard_Integer aMaxDeg = 8;
1124 Standard_Integer aMaxSeg = 1000;
1125 Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
1126 GeomAbs_C1, aMaxDeg, aMaxSeg,
1127 Standard_True, Standard_False);
1128 if(!anApp.HasResult())
1129 return;
1130
1131 theC3d = anApp.Curve3d();
1132 theTolReached = anApp.MaxError3d();
1133 Standard_Real aTol = Precision::Confusion();
1134 if(theRL->IsArcOnS1())
1135 {
1136 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
1137 BuildPCurves (tf, tl, aTol,
1138 aS, theC3d, theC2d2);
1139 }
1140 if(theRL->IsArcOnS2())
1141 {
1142 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
1143 BuildPCurves (tf, tl, aTol,
1144 aS, theC3d, theC2d1);
1145 }
1146 theTolReached = Max(theTolReached, aTol);
1147}
1148
1149//=======================================================================
1150//function : BuildPCurves
7fd59977 1151//purpose :
1152//=======================================================================
d4b867e6 1153void GeomInt_IntSS::BuildPCurves (Standard_Real f,
1154 Standard_Real l,
1155 Standard_Real& Tol,
1156 const Handle (Geom_Surface)& S,
1157 const Handle (Geom_Curve)& C,
1158 Handle (Geom2d_Curve)& C2d)
7fd59977 1159{
d4b867e6 1160 if (!C2d.IsNull()) {
1161 return;
1162 }
1163 //
1164 Standard_Real umin,umax,vmin,vmax;
1165 //
1166 S->Bounds(umin, umax, vmin, vmax);
1167 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
1168 if((l - f) > 2.e-09) {
1169 C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
d4b867e6 1170 if (C2d.IsNull()) {
1171 // proj. a circle that goes through the pole on a sphere to the sphere
1172 Tol += Precision::Confusion();
1173 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
1174 }
8f8398f6 1175 const Handle(Standard_Type)& aType = C2d->DynamicType();
1176 if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve))
1177 {
1178 //Check first, last knots to avoid problems with trimming
1179 //First, last knots can differ from f, l because of numerical error
1180 //of projection and approximation
1181 //The same checking as in Geom2d_TrimmedCurve
1182 if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
1183 (l - C2d->LastParameter() > Precision::PConfusion()))
1184 {
1185 Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1186 TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
1187 aBspl->Knots(aKnots);
1188 BSplCLib::Reparametrize(f, l, aKnots);
1189 aBspl->SetKnots(aKnots);
1190 }
1191 }
d4b867e6 1192 }
1193 else {
7a91ad6e 1194 if((l - f) > Epsilon(Abs(f)))
1195 {
1196 //The domain of C2d is [Epsilon(Abs(f)), 2.e-09]
1197 //On this small range C2d can be considered as segment
1198 //of line.
1199
1200 Standard_Real aU=0., aV=0.;
1201 GeomAdaptor_Surface anAS;
1202 anAS.Load(S);
1203 Extrema_ExtPS anExtr;
1204 const gp_Pnt aP3d1 = C->Value(f);
1205 const gp_Pnt aP3d2 = C->Value(l);
1206
1207 anExtr.SetAlgo(Extrema_ExtAlgo_Grad);
1208 anExtr.Initialize(anAS, umin, umax, vmin, vmax,
1209 Precision::Confusion(), Precision::Confusion());
1210 anExtr.Perform(aP3d1);
1211
1212 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1213 {
1214 const gp_Pnt2d aP2d1(aU, aV);
1215
1216 anExtr.Perform(aP3d2);
1217
1218 if(ParametersOfNearestPointOnSurface(anExtr, aU, aV))
1219 {
1220 const gp_Pnt2d aP2d2(aU, aV);
1221
1222 if(aP2d1.Distance(aP2d2) > gp::Resolution())
1223 {
1224 TColgp_Array1OfPnt2d poles(1,2);
1225 TColStd_Array1OfReal knots(1,2);
1226 TColStd_Array1OfInteger mults(1,2);
1227 poles(1) = aP2d1;
1228 poles(2) = aP2d2;
1229 knots(1) = f;
1230 knots(2) = l;
1231 mults(1) = mults(2) = 2;
1232
1233 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
1234
1235 //Check same parameter in middle point .begin
1236 const gp_Pnt PMid(C->Value(0.5*(f+l)));
1237 const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY()));
1238 const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y()));
1239 const Standard_Real aDist = PMid.Distance(aPC);
1240 Tol = Max(aDist, Tol);
1241 //Check same parameter in middle point .end
d4b867e6 1242 }
d4b867e6 1243 }
1244 }
1245 }
1246 }
7fd59977 1247 //
d4b867e6 1248 if (S->IsUPeriodic() && !C2d.IsNull()) {
1249 // Recadre dans le domaine UV de la face
1250 Standard_Real aTm, U0, aEps, period, du, U0x;
1251 Standard_Boolean bAdjust;
1252 //
1253 aEps = Precision::PConfusion();
1254 period = S->UPeriod();
1255 //
1256 aTm = .5*(f + l);
1257 gp_Pnt2d pm = C2d->Value(aTm);
1258 U0 = pm.X();
1259 //
1260 bAdjust =
1261 GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps);
1262 if (bAdjust) {
1263 gp_Vec2d T1(du, 0.);
1264 C2d->Translate(T1);
1265 }
1266 }
1267}
1268
1269//=======================================================================
1270//function : TrimILineOnSurfBoundaries
1271//purpose : This function finds intersection points of given curves with
1272// surface boundaries and fills theArrayOfParameters by parameters
1273// along the given curves corresponding of these points.
1274//=======================================================================
1275void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d1,
1276 const Handle(Geom2d_Curve)& theC2d2,
1277 const Bnd_Box2d& theBound1,
1278 const Bnd_Box2d& theBound2,
1279 GeomInt_VectorOfReal& theArrayOfParameters)
1280{
1281 //Rectangular boundaries of two surfaces: [0]:U=Ufirst, [1]:U=Ulast,
1282 // [2]:V=Vfirst, [3]:V=Vlast
1283 const Standard_Integer aNumberOfCurves = 4;
1284 Handle(Geom2d_Curve) aCurS1Bounds[aNumberOfCurves];
1285 Handle(Geom2d_Curve) aCurS2Bounds[aNumberOfCurves];
1286
1287 Standard_Real aU1f=0.0, aV1f=0.0, aU1l=0.0, aV1l=0.0;
1288 Standard_Real aU2f=0.0, aV2f=0.0, aU2l=0.0, aV2l=0.0;
1289
1290 theBound1.Get(aU1f, aV1f, aU1l, aV1l);
1291 theBound2.Get(aU2f, aV2f, aU2l, aV2l);
1292
1293 Standard_Real aDelta = aV1l-aV1f;
1294 if(Abs(aDelta) > RealSmall())
1295 {
1296 if(!Precision::IsInfinite(aU1f))
1297 {
1298 aCurS1Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(0.0, 1.0));
1299
1300 if(!Precision::IsInfinite(aDelta))
1301 aCurS1Bounds[0] = new Geom2d_TrimmedCurve(aCurS1Bounds[0], 0, aDelta);
1302 }
1303
1304 if(!Precision::IsInfinite(aU1l))
1305 {
1306 aCurS1Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1f), gp_Dir2d(0.0, 1.0));
1307 if(!Precision::IsInfinite(aDelta))
1308 aCurS1Bounds[1] = new Geom2d_TrimmedCurve(aCurS1Bounds[1], 0, aDelta);
1309 }
1310 }
1311
1312 aDelta = aU1l-aU1f;
1313 if(Abs(aDelta) > RealSmall())
1314 {
1315 if(!Precision::IsInfinite(aV1f))
1316 {
1317 aCurS1Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU1f, aV1f), gp_Dir2d(1.0, 0.0));
1318 if(!Precision::IsInfinite(aDelta))
1319 aCurS1Bounds[2] = new Geom2d_TrimmedCurve(aCurS1Bounds[2], 0, aDelta);
1320 }
1321
1322 if(!Precision::IsInfinite(aV1l))
1323 {
1324 aCurS1Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU1l, aV1l), gp_Dir2d(1.0, 0.0));
1325 if(!Precision::IsInfinite(aDelta))
1326 aCurS1Bounds[3] = new Geom2d_TrimmedCurve(aCurS1Bounds[3], 0, aDelta);
1327 }
1328 }
1329
1330 aDelta = aV2l-aV2f;
1331 if(Abs(aDelta) > RealSmall())
1332 {
1333 if(!Precision::IsInfinite(aU2f))
1334 {
1335 aCurS2Bounds[0] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(0.0, 1.0));
1336 if(!Precision::IsInfinite(aDelta))
1337 aCurS2Bounds[0] = new Geom2d_TrimmedCurve(aCurS2Bounds[0], 0, aDelta);
1338 }
1339
1340 if(!Precision::IsInfinite(aU2l))
1341 {
1342 aCurS2Bounds[1] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2f), gp_Dir2d(0.0, 1.0));
1343 if(!Precision::IsInfinite(aDelta))
1344 aCurS2Bounds[1] = new Geom2d_TrimmedCurve(aCurS2Bounds[1], 0, aDelta);
1345 }
1346 }
1347
1348 aDelta = aU2l-aU2f;
1349 if(Abs(aDelta) > RealSmall())
1350 {
1351 if(!Precision::IsInfinite(aV2f))
1352 {
1353 aCurS2Bounds[2] = new Geom2d_Line(gp_Pnt2d(aU2f, aV2f), gp_Dir2d(1.0, 0.0));
1354 if(!Precision::IsInfinite(aDelta))
1355 aCurS2Bounds[2] = new Geom2d_TrimmedCurve(aCurS2Bounds[2], 0, aDelta);
1356 }
1357
1358 if(!Precision::IsInfinite(aV2l))
1359 {
1360 aCurS2Bounds[3] = new Geom2d_Line(gp_Pnt2d(aU2l, aV2l), gp_Dir2d(1.0, 0.0));
1361 if(!Precision::IsInfinite(aDelta))
1362 aCurS2Bounds[3] = new Geom2d_TrimmedCurve(aCurS2Bounds[3], 0, aDelta);
1363 }
1364 }
1365
7a91ad6e 1366 const Standard_Real anIntTol = 10.0*Precision::Confusion();
d4b867e6 1367
7a91ad6e 1368 IntersectCurveAndBoundary(theC2d1, aCurS1Bounds,
1369 aNumberOfCurves, anIntTol, theArrayOfParameters);
d4b867e6 1370
7a91ad6e 1371 IntersectCurveAndBoundary(theC2d2, aCurS2Bounds,
1372 aNumberOfCurves, anIntTol, theArrayOfParameters);
d4b867e6 1373
1374 std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());
7fd59977 1375}
4e14c88f 1376
1377//=======================================================================
1378//function : MakeBSpline
1379//purpose :
1380//=======================================================================
1381Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline (const Handle(IntPatch_WLine)& WL,
1382 const Standard_Integer ideb,
1383 const Standard_Integer ifin)
1384{
1385 const Standard_Integer nbpnt = ifin-ideb+1;
1386 TColgp_Array1OfPnt poles(1,nbpnt);
1387 TColStd_Array1OfReal knots(1,nbpnt);
1388 TColStd_Array1OfInteger mults(1,nbpnt);
1389 Standard_Integer i = 1, ipidebm1 = ideb;
1390 for(; i<=nbpnt; ipidebm1++, i++)
1391 {
1392 poles(i) = WL->Point(ipidebm1).Value();
1393 mults(i) = 1;
1394 knots(i) = i-1;
1395 }
1396 mults(1) = mults(nbpnt) = 2;
1397 return new Geom_BSplineCurve(poles,knots,mults,1);
1398}
1399
1400//=======================================================================
1401//function : MakeBSpline2d
1402//purpose :
1403//=======================================================================
1404Handle(Geom2d_BSplineCurve) GeomInt_IntSS::
1405 MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
1406 const Standard_Integer ideb,
1407 const Standard_Integer ifin,
1408 const Standard_Boolean onFirst)
1409{
1410 const Standard_Integer nbpnt = ifin-ideb+1;
1411 TColgp_Array1OfPnt2d poles(1,nbpnt);
1412 TColStd_Array1OfReal knots(1,nbpnt);
1413 TColStd_Array1OfInteger mults(1,nbpnt);
1414 Standard_Integer i = 1, ipidebm1 = ideb;
1415 for(; i <= nbpnt; ipidebm1++, i++)
1416 {
1417 Standard_Real U, V;
1418 if(onFirst)
1419 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
1420 else
1421 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
1422 poles(i).SetCoord(U, V);
1423 mults(i) = 1;
1424 knots(i) = i-1;
1425 }
1426
1427 mults(1) = mults(nbpnt) = 2;
1428 return new Geom2d_BSplineCurve(poles,knots,mults,1);
1429}