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