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_Line.hxx> |
28 | #include <Geom2d_TrimmedCurve.hxx> |
42cf5bc1 |
29 | #include <GeomAdaptor.hxx> |
30 | #include <GeomAdaptor_HSurface.hxx> |
31 | #include <GeomInt.hxx> |
4e14c88f |
32 | #include <GeomInt_LineTool.hxx> |
42cf5bc1 |
33 | #include <GeomInt_WLApprox.hxx> |
7fd59977 |
34 | #include <GeomLib_Check2dBSplineCurve.hxx> |
42cf5bc1 |
35 | #include <GeomLib_CheckBSplineCurve.hxx> |
7fd59977 |
36 | #include <GeomProjLib.hxx> |
4e14c88f |
37 | #include <Geom_BSplineCurve.hxx> |
38 | #include <Geom_Circle.hxx> |
39 | #include <Geom_Ellipse.hxx> |
40 | #include <Geom_Hyperbola.hxx> |
41 | #include <Geom_Line.hxx> |
42 | #include <Geom_Parabola.hxx> |
43 | #include <Geom_TrimmedCurve.hxx> |
42cf5bc1 |
44 | #include <IntPatch_GLine.hxx> |
d4b867e6 |
45 | #include <IntPatch_RLine.hxx> |
42cf5bc1 |
46 | #include <IntPatch_WLine.hxx> |
7a91ad6e |
47 | #include <IntRes2d_IntersectionSegment.hxx> |
4e14c88f |
48 | #include <IntSurf_Quadric.hxx> |
e2e0498b |
49 | #include <Precision.hxx> |
7fd59977 |
50 | |
51 | //======================================================================= |
4e14c88f |
52 | //function : AdjustUPeriodic |
7fd59977 |
53 | //purpose : |
54 | //======================================================================= |
4e14c88f |
55 | static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D) |
7fd59977 |
56 | { |
4e14c88f |
57 | if (aC2D.IsNull() || !aS->IsUPeriodic()) |
58 | return; |
7fd59977 |
59 | // |
4e14c88f |
60 | const Standard_Real aEps=Precision::PConfusion();//1.e-9 |
61 | const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15 |
62 | // |
63 | Standard_Real umin,umax,vmin,vmax; |
64 | aS->Bounds(umin,umax,vmin,vmax); |
65 | const Standard_Real aPeriod = aS->UPeriod(); |
66 | |
67 | const Standard_Real aT1=aC2D->FirstParameter(); |
68 | const Standard_Real aT2=aC2D->LastParameter(); |
69 | const Standard_Real aTx=aT1+0.467*(aT2-aT1); |
70 | const gp_Pnt2d aPx=aC2D->Value(aTx); |
71 | // |
72 | Standard_Real aUx=aPx.X(); |
73 | if (fabs(aUx)<aEpsilon) |
74 | aUx=0.; |
75 | if (fabs(aUx-aPeriod)<aEpsilon) |
76 | aUx=aPeriod; |
77 | // |
78 | Standard_Real dU=0.; |
79 | while(aUx <(umin-aEps)) { |
80 | aUx+=aPeriod; |
81 | dU+=aPeriod; |
82 | } |
83 | while(aUx>(umax+aEps)) { |
84 | aUx-=aPeriod; |
85 | dU-=aPeriod; |
86 | } |
87 | // |
88 | if (dU!=0.) { |
89 | gp_Vec2d aV2D(dU, 0.); |
90 | aC2D->Translate(aV2D); |
91 | } |
7fd59977 |
92 | } |
4e14c88f |
93 | |
94 | //======================================================================= |
95 | //function : GetQuadric |
7fd59977 |
96 | //purpose : |
97 | //======================================================================= |
4e14c88f |
98 | static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1) |
7fd59977 |
99 | { |
4e14c88f |
100 | switch (HS1->Surface().GetType()) |
101 | { |
102 | case GeomAbs_Plane: quad1.SetValue(HS1->Surface().Plane()); break; |
103 | case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break; |
104 | case GeomAbs_Cone: quad1.SetValue(HS1->Surface().Cone()); break; |
105 | case GeomAbs_Sphere: quad1.SetValue(HS1->Surface().Sphere()); break; |
106 | case GeomAbs_Torus: quad1.SetValue(HS1->Surface().Torus()); break; |
9775fa61 |
107 | default: throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve"); |
7fd59977 |
108 | } |
109 | } |
4e14c88f |
110 | |
111 | //======================================================================= |
112 | //function : Parameters |
113 | //purpose : |
114 | //======================================================================= |
115 | static void Parameters( const Handle(GeomAdaptor_HSurface)& HS1, |
116 | const Handle(GeomAdaptor_HSurface)& HS2, |
117 | const gp_Pnt& Ptref, |
118 | Standard_Real& U1, |
119 | Standard_Real& V1, |
120 | Standard_Real& U2, |
121 | Standard_Real& V2) |
122 | { |
123 | IntSurf_Quadric quad1,quad2; |
124 | // |
125 | GetQuadric(HS1, quad1); |
126 | GetQuadric(HS2, quad2); |
127 | // |
128 | quad1.Parameters(Ptref,U1,V1); |
129 | quad2.Parameters(Ptref,U2,V2); |
130 | } |
131 | |
7fd59977 |
132 | //======================================================================= |
4e14c88f |
133 | //function : ParametersOfNearestPointOnSurface |
7fd59977 |
134 | //purpose : |
135 | //======================================================================= |
4e14c88f |
136 | static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr, |
137 | Standard_Real& theU, |
138 | Standard_Real& theV) |
7fd59977 |
139 | { |
4e14c88f |
140 | if(!theExtr.IsDone() || !theExtr.NbExt()) |
141 | return Standard_False; |
142 | |
143 | Standard_Integer anIndex = 1; |
144 | Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex); |
145 | for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++) |
146 | { |
147 | Standard_Real aSQD = theExtr.SquareDistance(i); |
148 | if (aSQD < aMinSQDist) |
149 | { |
150 | aMinSQDist = aSQD; |
151 | anIndex = i; |
152 | } |
153 | } |
154 | |
155 | theExtr.Point(anIndex).Parameter(theU, theV); |
156 | |
157 | return Standard_True; |
7fd59977 |
158 | } |
4e14c88f |
159 | |
7fd59977 |
160 | //======================================================================= |
4e14c88f |
161 | //function : GetSegmentBoundary |
7fd59977 |
162 | //purpose : |
163 | //======================================================================= |
4e14c88f |
164 | static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm, |
165 | const Handle(Geom2d_Curve)& theCurve, |
166 | GeomInt_VectorOfReal& theArrayOfParameters) |
7fd59977 |
167 | { |
4e14c88f |
168 | Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter(); |
169 | |
170 | if(theSegm.HasFirstPoint()) |
171 | { |
172 | const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint(); |
173 | aU1 = anIPF.ParamOnFirst(); |
174 | } |
175 | |
176 | if(theSegm.HasLastPoint()) |
177 | { |
178 | const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint(); |
179 | aU2 = anIPL.ParamOnFirst(); |
180 | } |
181 | |
182 | theArrayOfParameters.Append(aU1); |
183 | theArrayOfParameters.Append(aU2); |
7fd59977 |
184 | } |
4e14c88f |
185 | |
7fd59977 |
186 | //======================================================================= |
4e14c88f |
187 | //function : IntersectCurveAndBoundary |
7fd59977 |
188 | //purpose : |
189 | //======================================================================= |
4e14c88f |
190 | static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d, |
191 | const Handle(Geom2d_Curve)* const theArrBounds, |
192 | const Standard_Integer theNumberOfCurves, |
193 | const Standard_Real theTol, |
194 | GeomInt_VectorOfReal& theArrayOfParameters) |
7fd59977 |
195 | { |
4e14c88f |
196 | if(theC2d.IsNull()) |
197 | return; |
198 | |
199 | Geom2dAdaptor_Curve anAC1(theC2d); |
200 | for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++) |
201 | { |
202 | if(theArrBounds[aCurID].IsNull()) |
203 | continue; |
204 | |
205 | Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]); |
206 | Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol); |
207 | |
208 | if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty()) |
209 | continue; |
210 | |
211 | for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++) |
212 | { |
213 | const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst(); |
214 | theArrayOfParameters.Append(aParam); |
215 | } |
216 | |
217 | for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++) |
218 | { |
219 | GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters); |
220 | } |
221 | } |
7fd59977 |
222 | } |
7fd59977 |
223 | |
b55bd023 |
224 | //======================================================================= |
225 | //function : isDegenerated |
226 | //purpose : Check if theAHC2d corresponds to a degenerated edge. |
227 | //======================================================================= |
228 | static Standard_Boolean isDegenerated(const Handle(GeomAdaptor_HSurface)& theGAHS, |
229 | const Handle(Adaptor2d_HCurve2d)& theAHC2d, |
230 | const Standard_Real theFirstPar, |
231 | const Standard_Real theLastPar) |
232 | { |
233 | const Standard_Real aSqTol = Precision::Confusion()*Precision::Confusion(); |
234 | gp_Pnt2d aP2d; |
235 | gp_Pnt aP1, aP2; |
236 | |
237 | theAHC2d->D0(theFirstPar, aP2d); |
238 | theGAHS->D0(aP2d.X(), aP2d.Y(), aP1); |
239 | |
240 | theAHC2d->D0(theLastPar, aP2d); |
241 | theGAHS->D0(aP2d.X(), aP2d.Y(), aP2); |
242 | |
243 | if(aP1.SquareDistance(aP2) > aSqTol) |
244 | return Standard_False; |
245 | |
246 | theAHC2d->D0(0.5*(theFirstPar+theLastPar), aP2d); |
247 | theGAHS->D0(aP2d.X(), aP2d.Y(), aP2); |
248 | |
249 | if(aP1.SquareDistance(aP2) > aSqTol) |
250 | return Standard_False; |
251 | |
252 | return Standard_True; |
253 | } |
254 | |
7fd59977 |
255 | //======================================================================= |
256 | //function : MakeCurve |
257 | //purpose : |
258 | //======================================================================= |
d4b867e6 |
259 | void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, |
4e14c88f |
260 | const Handle(Adaptor3d_TopolTool) & dom1, |
261 | const Handle(Adaptor3d_TopolTool) & dom2, |
262 | const Standard_Real Tol, |
263 | const Standard_Boolean Approx, |
264 | const Standard_Boolean ApproxS1, |
265 | const Standard_Boolean ApproxS2) |
7fd59977 |
266 | |
267 | { |
268 | Standard_Boolean myApprox1, myApprox2, myApprox; |
269 | Standard_Real Tolpc, myTolApprox; |
270 | IntPatch_IType typl; |
271 | Handle(Geom2d_BSplineCurve) H1; |
272 | Handle(Geom_Surface) aS1, aS2; |
273 | // |
274 | Tolpc = Tol; |
275 | myApprox=Approx; |
276 | myApprox1=ApproxS1; |
277 | myApprox2=ApproxS2; |
278 | myTolApprox=0.0000001; |
279 | // |
280 | aS1=myHS1->ChangeSurface().Surface(); |
281 | aS2=myHS2->ChangeSurface().Surface(); |
282 | // |
283 | Handle(IntPatch_Line) L = myIntersector.Line(Index); |
284 | typl = L->ArcType(); |
285 | // |
286 | if(typl==IntPatch_Walking) { |
4e14c88f |
287 | Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L)); |
288 | if(aWLine.IsNull()) { |
7fd59977 |
289 | return; |
290 | } |
4e14c88f |
291 | L = aWLine; |
7fd59977 |
292 | } |
293 | // |
294 | // Line Constructor |
295 | myLConstruct.Perform(L); |
296 | if (!myLConstruct.IsDone() || myLConstruct.NbParts() <= 0) { |
297 | return; |
298 | } |
299 | // Do the Curve |
300 | Standard_Boolean ok; |
301 | Standard_Integer i, j, aNbParts; |
302 | Standard_Real fprm, lprm; |
303 | Handle(Geom_Curve) newc; |
304 | |
305 | switch (typl) { |
e618b526 |
306 | //######################################## |
307 | // Line, Parabola, Hyperbola |
308 | //######################################## |
7fd59977 |
309 | case IntPatch_Lin: |
310 | case IntPatch_Parabola: |
311 | case IntPatch_Hyperbola: { |
312 | if (typl == IntPatch_Lin) { |
313 | newc=new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line()); |
314 | } |
315 | else if (typl == IntPatch_Parabola) { |
316 | newc=new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola()); |
317 | } |
318 | else if (typl == IntPatch_Hyperbola) { |
319 | newc=new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola()); |
320 | } |
321 | // |
322 | aNbParts=myLConstruct.NbParts(); |
323 | for (i=1; i<=aNbParts; i++) { |
324 | myLConstruct.Part(i, fprm, lprm); |
e618b526 |
325 | |
7fd59977 |
326 | if (!Precision::IsNegativeInfinite(fprm) && |
e618b526 |
327 | !Precision::IsPositiveInfinite(lprm)) { |
328 | Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm); |
329 | sline.Append(aCT3D); |
330 | // |
331 | if(myApprox1) { |
332 | Handle (Geom2d_Curve) C2d; |
333 | BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d); |
334 | if(Tolpc>myTolReached2d || myTolReached2d==0.) { |
335 | myTolReached2d=Tolpc; |
336 | } |
337 | slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm)); |
338 | } |
339 | else { |
340 | slineS1.Append(H1); |
341 | } |
342 | // |
343 | if(myApprox2) { |
344 | Handle (Geom2d_Curve) C2d; |
345 | BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d); |
346 | if(Tolpc>myTolReached2d || myTolReached2d==0.) { |
347 | myTolReached2d=Tolpc; |
348 | } |
349 | // |
350 | slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm)); |
351 | } |
352 | else { |
353 | slineS2.Append(H1); |
354 | } |
7fd59977 |
355 | } // if (!Precision::IsNegativeInfinite(fprm) && !Precision::IsPositiveInfinite(lprm)) |
356 | |
357 | else { |
7c4e9501 |
358 | GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType(); |
359 | GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType(); |
360 | if( typS1 == GeomAbs_SurfaceOfExtrusion || |
361 | typS1 == GeomAbs_OffsetSurface || |
362 | typS1 == GeomAbs_SurfaceOfRevolution || |
363 | typS2 == GeomAbs_SurfaceOfExtrusion || |
364 | typS2 == GeomAbs_OffsetSurface || |
365 | typS2 == GeomAbs_SurfaceOfRevolution) { |
366 | sline.Append(newc); |
367 | slineS1.Append(H1); |
368 | slineS2.Append(H1); |
369 | continue; |
370 | } |
371 | Standard_Boolean bFNIt, bLPIt; |
372 | Standard_Real aTestPrm, dT=100.; |
373 | Standard_Real u1, v1, u2, v2, TolX; |
374 | // |
375 | bFNIt=Precision::IsNegativeInfinite(fprm); |
376 | bLPIt=Precision::IsPositiveInfinite(lprm); |
377 | |
378 | aTestPrm=0.; |
379 | |
380 | if (bFNIt && !bLPIt) { |
381 | aTestPrm=lprm-dT; |
382 | } |
383 | else if (!bFNIt && bLPIt) { |
384 | aTestPrm=fprm+dT; |
385 | } |
386 | // |
387 | gp_Pnt ptref(newc->Value(aTestPrm)); |
388 | // |
389 | TolX = Precision::Confusion(); |
390 | Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2); |
391 | ok = (dom1->Classify(gp_Pnt2d(u1, v1), TolX) != TopAbs_OUT); |
392 | if(ok) { |
393 | ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT); |
394 | } |
395 | if (ok) { |
396 | sline.Append(newc); |
397 | slineS1.Append(H1); |
398 | slineS2.Append(H1); |
399 | } |
7fd59977 |
400 | } |
401 | }// end of for (i=1; i<=myLConstruct.NbParts(); i++) |
e618b526 |
402 | }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola: |
403 | break; |
7fd59977 |
404 | |
e618b526 |
405 | //######################################## |
406 | // Circle and Ellipse |
407 | //######################################## |
7fd59977 |
408 | case IntPatch_Circle: |
409 | case IntPatch_Ellipse: { |
410 | |
411 | if (typl == IntPatch_Circle) { |
412 | newc = new Geom_Circle |
e618b526 |
413 | (Handle(IntPatch_GLine)::DownCast(L)->Circle()); |
7fd59977 |
414 | } |
415 | else { |
416 | newc = new Geom_Ellipse |
e618b526 |
417 | (Handle(IntPatch_GLine)::DownCast(L)->Ellipse()); |
7fd59977 |
418 | } |
419 | // |
96a95605 |
420 | Standard_Real aPeriod, aRealEpsilon; |
7fd59977 |
421 | // |
422 | aRealEpsilon=RealEpsilon(); |
c6541a0c |
423 | aPeriod=M_PI+M_PI; |
7fd59977 |
424 | // |
425 | aNbParts=myLConstruct.NbParts(); |
426 | // |
427 | for (i=1; i<=aNbParts; i++) { |
428 | myLConstruct.Part(i, fprm, lprm); |
429 | // |
430 | if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) { |
e618b526 |
431 | //============================================== |
432 | Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm); |
433 | // |
434 | sline.Append(aTC3D); |
435 | // |
436 | fprm=aTC3D->FirstParameter(); |
437 | lprm=aTC3D->LastParameter (); |
438 | //// |
439 | if(myApprox1) { |
440 | Handle (Geom2d_Curve) C2d; |
441 | BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d); |
442 | if(Tolpc>myTolReached2d || myTolReached2d==0.) { |
443 | myTolReached2d=Tolpc; |
444 | } |
445 | slineS1.Append(C2d); |
446 | } |
447 | else { //// |
448 | slineS1.Append(H1); |
449 | } |
450 | // |
451 | if(myApprox2) { |
452 | Handle (Geom2d_Curve) C2d; |
453 | BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d); |
454 | if(Tolpc>myTolReached2d || myTolReached2d==0) { |
455 | myTolReached2d=Tolpc; |
456 | } |
457 | slineS2.Append(C2d); |
458 | } |
459 | else { |
460 | slineS2.Append(H1); |
461 | } |
462 | //============================================== |
c6541a0c |
463 | } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon()) |
7fd59977 |
464 | // |
465 | else {// on regarde si on garde |
e618b526 |
466 | // |
467 | if (aNbParts==1) { |
468 | if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) { |
469 | Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm); |
470 | // |
471 | sline.Append(aTC3D); |
472 | fprm=aTC3D->FirstParameter(); |
473 | lprm=aTC3D->LastParameter (); |
474 | |
475 | if(myApprox1) { |
476 | Handle (Geom2d_Curve) C2d; |
477 | BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d); |
478 | if(Tolpc>myTolReached2d || myTolReached2d==0) { |
479 | myTolReached2d=Tolpc; |
480 | } |
481 | slineS1.Append(C2d); |
482 | } |
483 | else { //// |
484 | slineS1.Append(H1); |
485 | } |
486 | |
487 | if(myApprox2) { |
488 | Handle (Geom2d_Curve) C2d; |
489 | BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d); |
490 | if(Tolpc>myTolReached2d || myTolReached2d==0) { |
491 | myTolReached2d=Tolpc; |
492 | } |
493 | slineS2.Append(C2d); |
494 | } |
495 | else { |
496 | slineS2.Append(H1); |
497 | } |
498 | break; |
499 | } |
500 | } |
501 | // |
502 | Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX; |
503 | // |
504 | aTwoPIdiv17=2.*M_PI/17.; |
505 | // |
506 | for (j=0; j<=17; j++) { |
507 | gp_Pnt ptref (newc->Value (j*aTwoPIdiv17)); |
508 | TolX = Precision::Confusion(); |
509 | |
510 | Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2); |
511 | ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT); |
512 | if(ok) { |
513 | ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT); |
514 | } |
515 | if (ok) { |
516 | sline.Append(newc); |
517 | //============================================== |
518 | if(myApprox1) { |
519 | Handle (Geom2d_Curve) C2d; |
520 | BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d); |
521 | if(Tolpc>myTolReached2d || myTolReached2d==0) { |
522 | myTolReached2d=Tolpc; |
523 | } |
524 | slineS1.Append(C2d); |
525 | } |
526 | else { |
527 | slineS1.Append(H1); |
528 | } |
529 | |
530 | if(myApprox2) { |
531 | Handle (Geom2d_Curve) C2d; |
532 | BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d); |
533 | if(Tolpc>myTolReached2d || myTolReached2d==0) { |
534 | myTolReached2d=Tolpc; |
535 | } |
536 | slineS2.Append(C2d); |
537 | } |
538 | else { |
539 | slineS2.Append(H1); |
540 | } |
541 | break; |
542 | }// end of if (ok) { |
543 | }// end of for (Standard_Integer j=0; j<=17; j++) |
7fd59977 |
544 | }// end of else { on regarde si on garde |
545 | }// for (i=1; i<=myLConstruct.NbParts(); i++) |
e618b526 |
546 | }// IntPatch_Circle: IntPatch_Ellipse |
547 | break; |
548 | |
549 | //######################################## |
550 | // Analytic |
551 | //######################################## |
e2e0498b |
552 | case IntPatch_Analytic: |
553 | //This case was processed earlier (in IntPatch_Intersection) |
e618b526 |
554 | |
e618b526 |
555 | break; |
556 | |
4e14c88f |
557 | //######################################## |
558 | // Walking |
559 | //######################################## |
7fd59977 |
560 | case IntPatch_Walking:{ |
561 | Handle(IntPatch_WLine) WL = |
562 | Handle(IntPatch_WLine)::DownCast(L); |
4e14c88f |
563 | |
77dbd1f1 |
564 | #ifdef GEOMINT_INTSS_DEBUG |
565 | WL->Dump(0); |
4e14c88f |
566 | #endif |
567 | |
7fd59977 |
568 | // |
569 | Standard_Integer ifprm, ilprm; |
570 | // |
571 | if (!myApprox) { |
572 | aNbParts=myLConstruct.NbParts(); |
573 | for (i=1; i<=aNbParts; i++) { |
e618b526 |
574 | myLConstruct.Part(i, fprm, lprm); |
575 | ifprm=(Standard_Integer)fprm; |
576 | ilprm=(Standard_Integer)lprm; |
577 | // |
578 | Handle(Geom2d_BSplineCurve) aH1, aH2; |
579 | |
580 | if(myApprox1) { |
581 | aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True); |
582 | } |
583 | if(myApprox2) { |
584 | aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False); |
585 | } |
586 | // |
587 | Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm); |
588 | // |
589 | sline.Append(aBSp); |
590 | slineS1.Append(aH1); |
591 | slineS2.Append(aH2); |
7fd59977 |
592 | } |
593 | } |
594 | // |
595 | else { |
596 | Standard_Boolean bIsDecomposited; |
597 | Standard_Integer nbiter, aNbSeqOfL; |
598 | GeomInt_WLApprox theapp3d; |
599 | IntPatch_SequenceOfLine aSeqOfL; |
600 | Standard_Real tol2d, aTolSS; |
601 | // |
602 | tol2d = myTolApprox; |
603 | aTolSS=2.e-7; |
4e14c88f |
604 | theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2); |
7fd59977 |
605 | // |
606 | bIsDecomposited = |
4e14c88f |
607 | GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL); |
7fd59977 |
608 | // |
609 | aNbParts=myLConstruct.NbParts(); |
610 | aNbSeqOfL=aSeqOfL.Length(); |
611 | // |
612 | nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts; |
613 | // |
614 | for(i = 1; i <= nbiter; i++) { |
e618b526 |
615 | if(bIsDecomposited) { |
616 | WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i)); |
617 | ifprm = 1; |
618 | ilprm = WL->NbPnts(); |
619 | } |
620 | else { |
621 | myLConstruct.Part(i, fprm, lprm); |
622 | ifprm = (Standard_Integer)fprm; |
623 | ilprm = (Standard_Integer)lprm; |
624 | } |
625 | //-- lbr : |
626 | //-- Si une des surfaces est un plan , on approxime en 2d |
627 | //-- sur cette surface et on remonte les points 2d en 3d. |
628 | GeomAbs_SurfaceType typs1, typs2; |
629 | typs1 = myHS1->Surface().GetType(); |
630 | typs2 = myHS2->Surface().GetType(); |
631 | // |
632 | if(typs1 == GeomAbs_Plane) { |
633 | theapp3d.Perform(myHS1, myHS2, WL, Standard_False, |
634 | Standard_True, myApprox2, |
635 | ifprm, ilprm); |
636 | } |
637 | else if(typs2 == GeomAbs_Plane) { |
638 | theapp3d.Perform(myHS1,myHS2,WL,Standard_False, |
639 | myApprox1,Standard_True, |
640 | ifprm, ilprm); |
641 | } |
642 | else { |
643 | // |
644 | if (myHS1 != myHS2){ |
645 | if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) && |
646 | (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) { |
647 | |
4e14c88f |
648 | theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True); |
e618b526 |
649 | //Standard_Boolean bUseSurfaces; |
650 | //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm); |
651 | //if (bUseSurfaces) { |
652 | //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False); |
653 | //} |
654 | } |
655 | } |
656 | // |
657 | theapp3d.Perform(myHS1,myHS2,WL,Standard_True, |
658 | myApprox1,myApprox2, |
659 | ifprm, ilprm); |
660 | } |
661 | |
662 | if (!theapp3d.IsDone()) { |
663 | // |
664 | Handle(Geom2d_BSplineCurve) aH1, aH2; |
665 | // |
666 | Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm); |
667 | if(myApprox1) { |
668 | aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True); |
669 | } |
670 | if(myApprox2) { |
671 | aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False); |
672 | } |
673 | // |
674 | sline.Append(aBSp); |
675 | slineS1.Append(aH1); |
676 | slineS2.Append(aH2); |
677 | }//if (!theapp3d.IsDone()) |
678 | |
679 | else { |
680 | if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) { |
681 | if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) { |
682 | myTolReached2d = theapp3d.TolReached2d(); |
683 | } |
684 | } |
685 | if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) { |
686 | myTolReached3d = myTolReached2d; |
687 | } |
688 | else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) { |
689 | myTolReached3d = theapp3d.TolReached3d(); |
690 | } |
691 | |
692 | Standard_Integer aNbMultiCurves, nbpoles; |
693 | // |
694 | aNbMultiCurves=theapp3d.NbMultiCurves(); |
695 | for (j=1; j<=aNbMultiCurves; j++) { |
696 | if(typs1 == GeomAbs_Plane) { |
697 | const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j); |
698 | nbpoles = mbspc.NbPoles(); |
699 | |
700 | TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); |
701 | TColgp_Array1OfPnt tpoles(1,nbpoles); |
702 | |
703 | mbspc.Curve(1,tpoles2d); |
704 | const gp_Pln& Pln = myHS1->Surface().Plane(); |
705 | // |
706 | Standard_Integer ik; |
707 | for(ik = 1; ik<= nbpoles; ik++) { |
708 | tpoles.SetValue(ik, |
709 | ElSLib::Value(tpoles2d.Value(ik).X(), |
710 | tpoles2d.Value(ik).Y(), |
711 | Pln)); |
712 | } |
713 | // |
714 | Handle(Geom_BSplineCurve) BS = |
715 | new Geom_BSplineCurve(tpoles, |
716 | mbspc.Knots(), |
717 | mbspc.Multiplicities(), |
718 | mbspc.Degree()); |
719 | GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck); |
720 | Check.FixTangent(Standard_True, Standard_True); |
721 | // |
722 | sline.Append(BS); |
723 | // |
724 | if(myApprox1) { |
725 | Handle(Geom2d_BSplineCurve) BS1 = |
726 | new Geom2d_BSplineCurve(tpoles2d, |
727 | mbspc.Knots(), |
728 | mbspc.Multiplicities(), |
729 | mbspc.Degree()); |
730 | GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck); |
731 | Check1.FixTangent(Standard_True,Standard_True); |
732 | // |
733 | AdjustUPeriodic (aS1, BS1); |
734 | // |
735 | slineS1.Append(BS1); |
736 | } |
737 | else { |
738 | slineS1.Append(H1); |
739 | } |
740 | |
741 | if(myApprox2) { |
742 | mbspc.Curve(2, tpoles2d); |
743 | |
744 | Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d, |
745 | mbspc.Knots(), |
746 | mbspc.Multiplicities(), |
747 | mbspc.Degree()); |
748 | GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck); |
749 | newCheck.FixTangent(Standard_True,Standard_True); |
750 | // |
751 | AdjustUPeriodic (aS2, BS2); |
752 | // |
753 | slineS2.Append(BS2); |
754 | } |
755 | else { |
756 | slineS2.Append(H1); |
757 | } |
758 | }//if(typs1 == GeomAbs_Plane) |
759 | // |
760 | else if(typs2 == GeomAbs_Plane) { |
761 | const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j); |
762 | nbpoles = mbspc.NbPoles(); |
763 | |
764 | TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); |
765 | TColgp_Array1OfPnt tpoles(1,nbpoles); |
766 | mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d); |
767 | const gp_Pln& Pln = myHS2->Surface().Plane(); |
768 | // |
769 | Standard_Integer ik; |
770 | for(ik = 1; ik<= nbpoles; ik++) { |
771 | tpoles.SetValue(ik, |
772 | ElSLib::Value(tpoles2d.Value(ik).X(), |
773 | tpoles2d.Value(ik).Y(), |
774 | Pln)); |
775 | |
776 | } |
777 | // |
778 | Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles, |
779 | mbspc.Knots(), |
780 | mbspc.Multiplicities(), |
781 | mbspc.Degree()); |
782 | GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck); |
783 | Check.FixTangent(Standard_True,Standard_True); |
784 | // |
785 | sline.Append(BS); |
786 | // |
787 | if(myApprox2) { |
788 | Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d, |
789 | mbspc.Knots(), |
790 | mbspc.Multiplicities(), |
791 | mbspc.Degree()); |
792 | GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck); |
793 | Check1.FixTangent(Standard_True,Standard_True); |
794 | // |
795 | // |
796 | AdjustUPeriodic (aS2, BS1); |
797 | // |
798 | slineS2.Append(BS1); |
799 | } |
800 | else { |
801 | slineS2.Append(H1); |
802 | } |
803 | |
804 | if(myApprox1) { |
805 | mbspc.Curve(1,tpoles2d); |
806 | Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d, |
807 | mbspc.Knots(), |
808 | mbspc.Multiplicities(), |
809 | mbspc.Degree()); |
810 | GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck); |
811 | Check2.FixTangent(Standard_True,Standard_True); |
812 | // |
813 | // |
814 | AdjustUPeriodic (aS1, BS2); |
815 | // |
816 | slineS1.Append(BS2); |
817 | } |
818 | else { |
819 | slineS1.Append(H1); |
820 | } |
821 | } // else if(typs2 == GeomAbs_Plane) |
822 | // |
823 | else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane |
824 | const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j); |
825 | nbpoles = mbspc.NbPoles(); |
826 | TColgp_Array1OfPnt tpoles(1,nbpoles); |
827 | mbspc.Curve(1,tpoles); |
828 | Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles, |
829 | mbspc.Knots(), |
830 | mbspc.Multiplicities(), |
831 | mbspc.Degree()); |
832 | GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck); |
833 | Check.FixTangent(Standard_True,Standard_True); |
834 | // |
835 | //Check IsClosed() |
836 | Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(), |
837 | BS->EndPoint().XYZ().SquareModulus()); |
838 | Standard_Real eps = Epsilon(aDist); |
94f71cad |
839 | if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps) |
e618b526 |
840 | { |
94f71cad |
841 | // Avoid creating B-splines containing two coincident poles only |
842 | if (mbspc.Degree() == 1 && nbpoles == 2) |
843 | continue; |
844 | |
845 | if (!BS->IsClosed() && !BS->IsPeriodic()) |
846 | { |
847 | //force Closed() |
848 | gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.); |
849 | BS->SetPole(1, aPm); |
850 | BS->SetPole(BS->NbPoles(), aPm); |
851 | } |
e618b526 |
852 | } |
853 | sline.Append(BS); |
854 | |
855 | if(myApprox1) { |
856 | TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); |
857 | mbspc.Curve(2,tpoles2d); |
858 | Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d, |
859 | mbspc.Knots(), |
860 | mbspc.Multiplicities(), |
861 | mbspc.Degree()); |
862 | GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck); |
863 | newCheck.FixTangent(Standard_True,Standard_True); |
864 | // |
865 | AdjustUPeriodic (aS1, BS1); |
866 | // |
867 | slineS1.Append(BS1); |
868 | } |
869 | else { |
870 | slineS1.Append(H1); |
871 | } |
872 | if(myApprox2) { |
873 | TColgp_Array1OfPnt2d tpoles2d(1,nbpoles); |
874 | mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d); |
875 | Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d, |
876 | mbspc.Knots(), |
877 | mbspc.Multiplicities(), |
878 | mbspc.Degree()); |
879 | GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck); |
880 | newCheck.FixTangent(Standard_True,Standard_True); |
881 | // |
882 | AdjustUPeriodic (aS2, BS2); |
883 | // |
884 | slineS2.Append(BS2); |
885 | } |
886 | else { |
887 | slineS2.Append(H1); |
888 | } |
889 | }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane |
890 | }// for (j=1; j<=aNbMultiCurves; j++ |
7c4e9501 |
891 | } |
7fd59977 |
892 | } |
893 | } |
894 | } |
e618b526 |
895 | break; |
896 | |
7fd59977 |
897 | case IntPatch_Restriction: |
e618b526 |
898 | { |
d4b867e6 |
899 | Handle(IntPatch_RLine) RL = |
900 | Handle(IntPatch_RLine)::DownCast(L); |
901 | Handle(Geom_Curve) aC3d; |
902 | Handle(Geom2d_Curve) aC2d1, aC2d2; |
903 | Standard_Real aTolReached; |
904 | TreatRLine(RL, myHS1, myHS2, aC3d, |
905 | aC2d1, aC2d2, aTolReached); |
906 | |
907 | if(aC3d.IsNull()) |
908 | break; |
909 | |
910 | Bnd_Box2d aBox1, aBox2; |
911 | |
912 | const Standard_Real aU1f = myHS1->FirstUParameter(), |
913 | aV1f = myHS1->FirstVParameter(), |
914 | aU1l = myHS1->LastUParameter(), |
915 | aV1l = myHS1->LastVParameter(); |
916 | const Standard_Real aU2f = myHS2->FirstUParameter(), |
917 | aV2f = myHS2->FirstVParameter(), |
918 | aU2l = myHS2->LastUParameter(), |
919 | aV2l = myHS2->LastVParameter(); |
920 | |
921 | aBox1.Add(gp_Pnt2d(aU1f, aV1f)); |
922 | aBox1.Add(gp_Pnt2d(aU1l, aV1l)); |
923 | aBox2.Add(gp_Pnt2d(aU2f, aV2f)); |
924 | aBox2.Add(gp_Pnt2d(aU2l, aV2l)); |
925 | |
926 | GeomInt_VectorOfReal anArrayOfParameters; |
927 | |
928 | //We consider here that the intersection line is same-parameter-line |
929 | anArrayOfParameters.Append(aC3d->FirstParameter()); |
930 | anArrayOfParameters.Append(aC3d->LastParameter()); |
931 | |
932 | TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters); |
933 | |
934 | const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1; |
935 | |
936 | //Trim RLine found. |
937 | for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++) |
e618b526 |
938 | { |
d4b867e6 |
939 | const Standard_Real aParF = anArrayOfParameters(anInd), |
940 | aParL = anArrayOfParameters(anInd+1); |
941 | |
942 | if((aParL - aParF) <= Precision::PConfusion()) |
943 | continue; |
944 | |
945 | const Standard_Real aPar = 0.5*(aParF + aParL); |
946 | gp_Pnt2d aPt; |
947 | |
948 | Handle(Geom2d_Curve) aCurv2d1, aCurv2d2; |
949 | if(!aC2d1.IsNull()) |
950 | { |
951 | aC2d1->D0(aPar, aPt); |
952 | |
953 | if(aBox1.IsOut(aPt)) |
954 | continue; |
955 | |
956 | if(myApprox1) |
957 | aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL); |
958 | } |
959 | |
960 | if(!aC2d2.IsNull()) |
961 | { |
962 | aC2d2->D0(aPar, aPt); |
963 | |
964 | if(aBox2.IsOut(aPt)) |
965 | continue; |
966 | |
967 | if(myApprox2) |
968 | aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL); |
969 | } |
970 | |
971 | Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL); |
972 | |
973 | sline.Append(aCurv3d); |
974 | slineS1.Append(aCurv2d1); |
975 | slineS2.Append(aCurv2d2); |
e618b526 |
976 | } |
977 | } |
7fd59977 |
978 | break; |
7fd59977 |
979 | } |
980 | } |
4e14c88f |
981 | |
7fd59977 |
982 | //======================================================================= |
4e14c88f |
983 | //function : TreatRLine |
984 | //purpose : Approx of Restriction line |
7fd59977 |
985 | //======================================================================= |
4e14c88f |
986 | void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, |
987 | const Handle(GeomAdaptor_HSurface)& theHS1, |
988 | const Handle(GeomAdaptor_HSurface)& theHS2, |
989 | Handle(Geom_Curve)& theC3d, |
990 | Handle(Geom2d_Curve)& theC2d1, |
991 | Handle(Geom2d_Curve)& theC2d2, |
992 | Standard_Real& theTolReached) |
7fd59977 |
993 | { |
4e14c88f |
994 | Handle(GeomAdaptor_HSurface) aGAHS; |
995 | Handle(Adaptor2d_HCurve2d) anAHC2d; |
996 | Standard_Real tf, tl; |
997 | gp_Lin2d aL; |
998 | // It is assumed that 2d curve is 2d line (rectangular surface domain) |
999 | if(theRL->IsArcOnS1()) |
1000 | { |
1001 | aGAHS = theHS1; |
1002 | anAHC2d = theRL->ArcOnS1(); |
1003 | theRL->ParamOnS1(tf, tl); |
1004 | theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d()); |
1005 | tf = Max(tf, theC2d1->FirstParameter()); |
1006 | tl = Min(tl, theC2d1->LastParameter()); |
1007 | theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl); |
7fd59977 |
1008 | } |
4e14c88f |
1009 | else if (theRL->IsArcOnS2()) |
7fd59977 |
1010 | { |
4e14c88f |
1011 | aGAHS = theHS2; |
1012 | anAHC2d = theRL->ArcOnS2(); |
1013 | theRL->ParamOnS2(tf, tl); |
1014 | theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d()); |
1015 | tf = Max(tf, theC2d2->FirstParameter()); |
1016 | tl = Min(tl, theC2d2->LastParameter()); |
1017 | theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl); |
d4b867e6 |
1018 | } |
1019 | else |
1020 | { |
1021 | return; |
1022 | } |
b55bd023 |
1023 | |
1024 | //Restriction line can correspond to a degenerated edge. |
1025 | //In this case we return null-curve. |
1026 | if(isDegenerated(aGAHS, anAHC2d, tf, tl)) |
1027 | return; |
1028 | |
d4b867e6 |
1029 | // |
1030 | //To provide sameparameter it is necessary to get 3d curve as |
1031 | //approximation of curve on surface. |
1032 | Standard_Integer aMaxDeg = 8; |
1033 | Standard_Integer aMaxSeg = 1000; |
1034 | Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(), |
1035 | GeomAbs_C1, aMaxDeg, aMaxSeg, |
1036 | 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->Surface()); |
1046 | BuildPCurves (tf, tl, aTol, |
1047 | aS, theC3d, theC2d2); |
1048 | } |
1049 | if(theRL->IsArcOnS2()) |
1050 | { |
1051 | Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface()); |
1052 | BuildPCurves (tf, tl, aTol, |
1053 | aS, theC3d, theC2d1); |
1054 | } |
1055 | theTolReached = Max(theTolReached, aTol); |
1056 | } |
1057 | |
1058 | //======================================================================= |
1059 | //function : BuildPCurves |
7fd59977 |
1060 | //purpose : |
1061 | //======================================================================= |
d4b867e6 |
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) |
7fd59977 |
1068 | { |
d4b867e6 |
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); |
d4b867e6 |
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 | } |
8f8398f6 |
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 | } |
d4b867e6 |
1101 | } |
1102 | else { |
7a91ad6e |
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 |
d4b867e6 |
1151 | } |
d4b867e6 |
1152 | } |
1153 | } |
1154 | } |
1155 | } |
7fd59977 |
1156 | // |
d4b867e6 |
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 | //======================================================================= |
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 | |
7a91ad6e |
1275 | const Standard_Real anIntTol = 10.0*Precision::Confusion(); |
d4b867e6 |
1276 | |
7a91ad6e |
1277 | IntersectCurveAndBoundary(theC2d1, aCurS1Bounds, |
1278 | aNumberOfCurves, anIntTol, theArrayOfParameters); |
d4b867e6 |
1279 | |
7a91ad6e |
1280 | IntersectCurveAndBoundary(theC2d2, aCurS2Bounds, |
1281 | aNumberOfCurves, anIntTol, theArrayOfParameters); |
d4b867e6 |
1282 | |
1283 | std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end()); |
7fd59977 |
1284 | } |
4e14c88f |
1285 | |
1286 | //======================================================================= |
1287 | //function : MakeBSpline |
1288 | //purpose : |
1289 | //======================================================================= |
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 | //======================================================================= |
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 | } |