b311480e |
1 | // Created on: 1993-08-25 |
2 | // Created by: Bruno DUMORTIER |
3 | // Copyright (c) 1993-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 | |
17 | // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 |
18 | |
19 | #include <GeomAbs_SurfaceType.hxx> |
20 | #include <Standard_NoSuchObject.hxx> |
21 | #include <Standard_NotImplemented.hxx> |
22 | #include <ProjLib_ProjectedCurve.hxx> |
23 | #include <ProjLib_CompProjectedCurve.hxx> |
24 | #include <ProjLib_HCompProjectedCurve.hxx> |
25 | #include <ProjLib_ComputeApproxOnPolarSurface.hxx> |
26 | #include <ProjLib_ComputeApprox.hxx> |
27 | #include <ProjLib_Projector.hxx> |
7fd59977 |
28 | #include <Adaptor3d_HCurve.hxx> |
29 | #include <Adaptor3d_HSurface.hxx> |
30 | #include <Approx_CurveOnSurface.hxx> |
31 | #include <ProjLib_Plane.hxx> |
32 | #include <ProjLib_Cylinder.hxx> |
33 | #include <ProjLib_Cone.hxx> |
34 | #include <ProjLib_Sphere.hxx> |
35 | #include <ProjLib_Torus.hxx> |
36 | #include <Precision.hxx> |
7fd59977 |
37 | #include <Geom2d_BSplineCurve.hxx> |
7fd59977 |
38 | #include <Geom2d_BezierCurve.hxx> |
7fd59977 |
39 | #include <gp_Vec2d.hxx> |
40 | #include <StdFail_NotDone.hxx> |
41 | #include <gp_XY.hxx> |
42 | #include <TColgp_HArray1OfPnt2d.hxx> |
43 | #include <TColStd_HArray1OfReal.hxx> |
44 | #include <Geom2dConvert_CompCurveToBSplineCurve.hxx> |
45 | #include <TColStd_Array1OfReal.hxx> |
46 | #include <TColStd_Array1OfInteger.hxx> |
47 | #include <TColgp_Array1OfPnt2d.hxx> |
48 | #include <TColgp_HArray1OfVec2d.hxx> |
49 | #include <TColStd_HArray1OfBoolean.hxx> |
50 | #include <BSplCLib.hxx> |
51 | #include <GeomAbs_IsoType.hxx> |
bd82d4b2 |
52 | #include <Geom2d_Line.hxx> |
53 | #include <Geom2d_TrimmedCurve.hxx> |
54 | #include <ElCLib.hxx> |
55 | #include <GeomLib.hxx> |
7fd59977 |
56 | |
57 | //======================================================================= |
58 | //function : IsoIsDeg |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S, |
63 | const Standard_Real Param, |
64 | const GeomAbs_IsoType IT, |
65 | const Standard_Real TolMin, |
66 | const Standard_Real TolMax) |
67 | { |
68 | Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T; |
69 | Standard_Boolean Along = Standard_True; |
70 | U1 = S.FirstUParameter(); |
71 | U2 = S.LastUParameter(); |
72 | V1 = S.FirstVParameter(); |
73 | V2 = S.LastVParameter(); |
74 | gp_Vec D1U,D1V; |
75 | gp_Pnt P; |
76 | Standard_Real Step,D1NormMax; |
77 | if (IT == GeomAbs_IsoV) |
78 | { |
79 | Step = (U2 - U1)/10; |
80 | D1NormMax=0.; |
81 | for (T=U1;T<=U2;T=T+Step) |
82 | { |
83 | S.D1(T,Param,P,D1U,D1V); |
84 | D1NormMax=Max(D1NormMax,D1U.Magnitude()); |
85 | } |
86 | |
87 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
88 | Along = Standard_False; |
89 | } |
90 | else |
91 | { |
92 | Step = (V2 - V1)/10; |
93 | D1NormMax=0.; |
94 | for (T=V1;T<=V2;T=T+Step) |
95 | { |
96 | S.D1(Param,T,P,D1U,D1V); |
97 | D1NormMax=Max(D1NormMax,D1V.Magnitude()); |
98 | } |
99 | |
100 | if (D1NormMax >TolMax || D1NormMax < TolMin ) |
101 | Along = Standard_False; |
102 | |
103 | |
104 | } |
105 | return Along; |
106 | } |
107 | |
7fd59977 |
108 | //======================================================================= |
109 | //function : TrimC3d |
110 | //purpose : |
111 | //======================================================================= |
112 | |
113 | static void TrimC3d(Handle(Adaptor3d_HCurve)& myCurve, |
114 | Standard_Boolean* IsTrimmed, |
115 | const Standard_Real dt, |
bd82d4b2 |
116 | const gp_Pnt& Pole, |
117 | Standard_Integer* SingularCase, |
118 | const Standard_Integer NumberOfSingularCase) |
7fd59977 |
119 | { |
120 | Standard_Real f = myCurve->FirstParameter(); |
121 | Standard_Real l = myCurve->LastParameter(); |
122 | |
123 | gp_Pnt P = myCurve->Value(f); |
124 | |
125 | if(P.Distance(Pole) < Precision::Confusion()) { |
126 | IsTrimmed[0] = Standard_True; |
127 | f = f+dt; |
128 | myCurve = myCurve->Trim(f, l, Precision::Confusion()); |
bd82d4b2 |
129 | SingularCase[0] = NumberOfSingularCase; |
7fd59977 |
130 | } |
131 | |
132 | P = myCurve->Value(l); |
133 | if(P.Distance(Pole) < Precision::Confusion()) { |
134 | IsTrimmed[1] = Standard_True; |
135 | l = l-dt; |
136 | myCurve = myCurve->Trim(f, l, Precision::Confusion()); |
bd82d4b2 |
137 | SingularCase[1] = NumberOfSingularCase; |
7fd59977 |
138 | } |
139 | } |
140 | |
141 | //======================================================================= |
142 | //function : ExtendC2d |
143 | //purpose : |
144 | //======================================================================= |
145 | |
35e08fe8 |
146 | static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes, |
147 | const Standard_Real /*t*/, |
148 | const Standard_Real /*dt*/, |
149 | const Standard_Real u1, |
150 | const Standard_Real u2, |
151 | const Standard_Real v1, |
152 | const Standard_Real v2, |
153 | const Standard_Integer FirstOrLast, |
154 | const Standard_Integer NumberOfSingularCase) |
7fd59977 |
155 | { |
bd82d4b2 |
156 | Standard_Real theParam = (FirstOrLast == 0)? aRes->FirstParameter() |
157 | : aRes->LastParameter(); |
158 | |
159 | gp_Pnt2d aPBnd; |
160 | gp_Vec2d aVBnd; |
161 | gp_Dir2d aDBnd; |
162 | Handle(Geom2d_TrimmedCurve) aSegment; |
163 | Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aRes, Convert_RationalC1); |
164 | Standard_Real aTol = Precision::Confusion(); |
165 | |
166 | aRes->D1(theParam, aPBnd, aVBnd); |
167 | aDBnd.SetXY(aVBnd.XY()); |
168 | gp_Lin2d aLin(aPBnd, aDBnd); //line in direction of derivative |
169 | |
170 | gp_Pnt2d thePole; |
171 | gp_Dir2d theBoundDir; |
172 | switch (NumberOfSingularCase) |
173 | { |
174 | case 1: |
175 | { |
176 | thePole.SetCoord(u1, v1); |
177 | theBoundDir.SetCoord(0., 1.); |
178 | break; |
179 | } |
180 | case 2: |
181 | { |
182 | thePole.SetCoord(u2, v1); |
183 | theBoundDir.SetCoord(0., 1.); |
184 | break; |
185 | } |
186 | case 3: |
187 | { |
188 | thePole.SetCoord(u1, v1); |
189 | theBoundDir.SetCoord(1., 0.); |
190 | break; |
191 | } |
192 | case 4: |
193 | { |
194 | thePole.SetCoord(u1, v2); |
195 | theBoundDir.SetCoord(1., 0.); |
196 | break; |
197 | } |
198 | } |
199 | gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle |
200 | |
201 | Standard_Real U1x = BoundLin.Direction().X(); |
202 | Standard_Real U1y = BoundLin.Direction().Y(); |
203 | Standard_Real U2x = aLin.Direction().X(); |
204 | Standard_Real U2y = aLin.Direction().Y(); |
205 | Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X(); |
206 | Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y(); |
207 | |
208 | Standard_Real D = U1y*U2x-U1x*U2y; |
209 | |
210 | Standard_Real ParOnLin = (Uo21y * U1x - Uo21x * U1y)/D; //parameter of intersection point |
211 | |
212 | Handle(Geom2d_Line) aSegLine = new Geom2d_Line(aLin); |
213 | aSegment = (FirstOrLast == 0)? |
214 | new Geom2d_TrimmedCurve(aSegLine, ParOnLin, 0.) : |
215 | new Geom2d_TrimmedCurve(aSegLine, 0., ParOnLin); |
216 | |
217 | aCompCurve.Add(aSegment, aTol); |
218 | aRes = aCompCurve.BSplineCurve(); |
4e18e72a |
219 | } |
7fd59977 |
220 | |
221 | //======================================================================= |
222 | //function : Project |
223 | //purpose : |
224 | //======================================================================= |
225 | |
226 | static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C) |
227 | { |
228 | GeomAbs_CurveType CType = C->GetType(); |
229 | switch (CType) { |
230 | case GeomAbs_Line: |
231 | P.Project(C->Line()); |
232 | break; |
233 | case GeomAbs_Circle: |
234 | P.Project(C->Circle()); |
235 | break; |
236 | case GeomAbs_Ellipse: |
237 | P.Project(C->Ellipse()); |
238 | break; |
239 | case GeomAbs_Hyperbola: |
240 | P.Project(C->Hyperbola()); |
241 | break; |
242 | case GeomAbs_Parabola: |
243 | P.Project(C->Parabola()); |
244 | break; |
245 | case GeomAbs_BSplineCurve: |
246 | case GeomAbs_BezierCurve: |
247 | case GeomAbs_OtherCurve: // try the approximation |
248 | break; |
249 | default: |
250 | Standard_NoSuchObject::Raise(" "); |
251 | } |
252 | } |
253 | |
254 | //======================================================================= |
255 | //function : ProjLib_ProjectedCurve |
256 | //purpose : |
257 | //======================================================================= |
258 | |
259 | ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() |
260 | |
261 | { |
cfb6776e |
262 | myTolerance = Precision::Confusion(); |
7fd59977 |
263 | } |
264 | |
265 | |
266 | //======================================================================= |
267 | //function : ProjLib_ProjectedCurve |
268 | //purpose : |
269 | //======================================================================= |
270 | |
271 | ProjLib_ProjectedCurve::ProjLib_ProjectedCurve |
272 | (const Handle(Adaptor3d_HSurface)& S) |
273 | { |
cfb6776e |
274 | myTolerance = Precision::Confusion(); |
7fd59977 |
275 | Load(S); |
276 | } |
277 | |
278 | |
279 | //======================================================================= |
280 | //function : ProjLib_ProjectedCurve |
281 | //purpose : |
282 | //======================================================================= |
283 | |
284 | ProjLib_ProjectedCurve::ProjLib_ProjectedCurve |
285 | (const Handle(Adaptor3d_HSurface)& S, |
286 | const Handle(Adaptor3d_HCurve)& C) |
287 | { |
cfb6776e |
288 | myTolerance = Precision::Confusion(); |
7fd59977 |
289 | Load(S); |
290 | Load(C); |
291 | } |
292 | |
293 | |
294 | //======================================================================= |
295 | //function : ProjLib_ProjectedCurve |
296 | //purpose : |
297 | //======================================================================= |
298 | |
299 | ProjLib_ProjectedCurve::ProjLib_ProjectedCurve |
300 | (const Handle(Adaptor3d_HSurface)& S, |
301 | const Handle(Adaptor3d_HCurve)& C, |
302 | const Standard_Real Tol) |
303 | { |
cfb6776e |
304 | myTolerance = Max(Tol, Precision::Confusion()); |
7fd59977 |
305 | Load(S); |
306 | Load(C); |
307 | } |
308 | |
309 | |
310 | //======================================================================= |
311 | //function : Load |
312 | //purpose : |
313 | //======================================================================= |
314 | |
315 | void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S) |
316 | { |
317 | mySurface = S ; |
318 | } |
319 | |
320 | |
321 | //======================================================================= |
322 | //function : Load |
323 | //purpose : |
324 | //======================================================================= |
325 | |
326 | void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) |
327 | { |
cfb6776e |
328 | myTolerance = Max(myTolerance, Precision::Confusion()); |
7fd59977 |
329 | myCurve = C; |
bd82d4b2 |
330 | Standard_Real FirstPar = C->FirstParameter(); |
331 | Standard_Real LastPar = C->LastParameter(); |
7fd59977 |
332 | GeomAbs_SurfaceType SType = mySurface->GetType(); |
333 | GeomAbs_CurveType CType = myCurve->GetType(); |
334 | |
335 | switch (SType) { |
336 | |
337 | case GeomAbs_Plane: |
338 | { |
339 | ProjLib_Plane P(mySurface->Plane()); |
340 | Project(P,myCurve); |
341 | myResult = P; |
342 | } |
343 | break; |
344 | |
345 | case GeomAbs_Cylinder: |
346 | { |
347 | ProjLib_Cylinder P(mySurface->Cylinder()); |
348 | Project(P,myCurve); |
349 | myResult = P; |
350 | } |
351 | break; |
352 | |
353 | case GeomAbs_Cone: |
354 | { |
355 | ProjLib_Cone P(mySurface->Cone()); |
356 | Project(P,myCurve); |
357 | myResult = P; |
358 | } |
359 | break; |
360 | |
361 | case GeomAbs_Sphere: |
362 | { |
363 | ProjLib_Sphere P(mySurface->Sphere()); |
364 | Project(P,myCurve); |
365 | if ( P.IsDone()) { |
366 | // on met dans la pseudo-periode ( car Sphere n'est pas |
367 | // periodique en V !) |
368 | P.SetInBounds(myCurve->FirstParameter()); |
369 | } |
370 | myResult = P; |
371 | } |
372 | break; |
373 | |
374 | case GeomAbs_Torus: |
375 | { |
376 | ProjLib_Torus P(mySurface->Torus()); |
377 | Project(P,myCurve); |
378 | myResult = P; |
379 | } |
380 | break; |
381 | |
382 | case GeomAbs_BezierSurface: |
383 | case GeomAbs_BSplineSurface: |
384 | { |
385 | |
386 | Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False}; |
bd82d4b2 |
387 | Standard_Integer SingularCase[2]; |
7fd59977 |
388 | Standard_Real f, l, dt; |
389 | const Standard_Real eps = 0.01; |
390 | f = myCurve->FirstParameter(); |
391 | l = myCurve->LastParameter(); |
392 | dt = (l-f)*eps; |
393 | |
394 | Standard_Real U1=0.,U2=0.,V1=0.,V2=0; |
395 | const Adaptor3d_Surface& S = mySurface->Surface(); |
396 | U1 = S.FirstUParameter(); |
397 | U2 = S.LastUParameter(); |
398 | V1 = S.FirstVParameter(); |
399 | V2 = S.LastVParameter(); |
400 | |
074028c6 |
401 | if(IsoIsDeg(S, U1, GeomAbs_IsoU, 0., myTolerance) ) { |
7fd59977 |
402 | //Surface has pole at U = Umin |
403 | gp_Pnt Pole = mySurface->Value(U1, V1); |
bd82d4b2 |
404 | TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1); |
7fd59977 |
405 | } |
406 | |
074028c6 |
407 | if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance) ) { |
7fd59977 |
408 | //Surface has pole at U = Umax |
409 | gp_Pnt Pole = mySurface->Value(U2, V1); |
bd82d4b2 |
410 | TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2); |
7fd59977 |
411 | } |
412 | |
074028c6 |
413 | if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance) ) { |
7fd59977 |
414 | //Surface has pole at V = Vmin |
415 | gp_Pnt Pole = mySurface->Value(U1, V1); |
bd82d4b2 |
416 | TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3); |
7fd59977 |
417 | } |
418 | |
074028c6 |
419 | if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance) ) { |
7fd59977 |
420 | //Surface has pole at V = Vmax |
421 | gp_Pnt Pole = mySurface->Value(U1, V2); |
bd82d4b2 |
422 | TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4); |
7fd59977 |
423 | } |
424 | |
425 | ProjLib_ComputeApproxOnPolarSurface polar(myCurve, |
426 | mySurface, |
427 | myTolerance); |
428 | |
429 | Handle(Geom2d_BSplineCurve) aRes = polar.BSpline(); |
430 | |
431 | if(IsTrimmed[0] || IsTrimmed[1]) { |
432 | if(IsTrimmed[0]) { |
433 | //Add segment before start of curve |
434 | f = myCurve->FirstParameter(); |
bd82d4b2 |
435 | ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]); |
7fd59977 |
436 | } |
437 | if(IsTrimmed[1]) { |
438 | //Add segment after end of curve |
439 | l = myCurve->LastParameter(); |
bd82d4b2 |
440 | ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]); |
7fd59977 |
441 | } |
bd82d4b2 |
442 | Handle(Geom2d_Curve) NewCurve2d; |
443 | GeomLib::SameRange(Precision::PConfusion(), aRes, |
444 | aRes->FirstParameter(), aRes->LastParameter(), |
445 | FirstPar, LastPar, |
446 | NewCurve2d); |
447 | aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d); |
448 | } |
7fd59977 |
449 | myResult.SetBSpline(aRes); |
450 | myResult.Done(); |
451 | myResult.SetType(GeomAbs_BSplineCurve); |
452 | } |
453 | break; |
454 | |
455 | default: |
456 | { |
457 | Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False}; |
d20d815b |
458 | Standard_Real Vsingular[2] = { 0.0 , 0.0 }; //for surfaces of revolution |
1d47d8d0 |
459 | Standard_Real f = 0., l = 0., dt = 0.; |
7fd59977 |
460 | const Standard_Real eps = 0.01; |
461 | |
462 | if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution) { |
463 | //Check possible singularity |
464 | |
465 | gp_Pnt P = mySurface->AxeOfRevolution().Location(); |
466 | gp_Dir N = mySurface->AxeOfRevolution().Direction(); |
467 | |
468 | gp_Lin L(P, N); |
469 | |
470 | f = myCurve->FirstParameter(); |
471 | l = myCurve->LastParameter(); |
472 | dt = (l-f)*eps; |
473 | |
474 | P = myCurve->Value(f); |
475 | if(L.Distance(P) < Precision::Confusion()) { |
476 | IsTrimmed[0] = Standard_True; |
477 | f = f+dt; |
478 | myCurve = myCurve->Trim(f, l, Precision::Confusion()); |
bd82d4b2 |
479 | Vsingular[0] = ElCLib::Parameter(L, P); |
480 | //SingularCase[0] = 3; |
7fd59977 |
481 | } |
482 | |
483 | P = myCurve->Value(l); |
484 | if(L.Distance(P) < Precision::Confusion()) { |
485 | IsTrimmed[1] = Standard_True; |
486 | l = l-dt; |
487 | myCurve = myCurve->Trim(f, l, Precision::Confusion()); |
bd82d4b2 |
488 | Vsingular[1] = ElCLib::Parameter(L, P); |
489 | //SingularCase[1] = 3; |
7fd59977 |
490 | } |
491 | } |
492 | |
493 | ProjLib_CompProjectedCurve Projector(mySurface,myCurve, |
494 | myTolerance,myTolerance); |
495 | Handle(ProjLib_HCompProjectedCurve) HProjector = |
496 | new ProjLib_HCompProjectedCurve(); |
497 | HProjector->Set(Projector); |
498 | |
499 | // Normalement, dans le cadre de ProjLib, le resultat |
500 | // doit etre une et une seule courbe !!! |
501 | // De plus, cette courbe ne doit pas etre Single point |
502 | Standard_Integer NbCurves = Projector.NbCurves(); |
1d47d8d0 |
503 | Standard_Real Udeb = 0.,Ufin = 0.; |
7fd59977 |
504 | if (NbCurves > 0) { |
505 | Projector.Bounds(1,Udeb,Ufin); |
506 | } |
507 | else { |
508 | StdFail_NotDone::Raise("ProjLib CompProjectedCurve Not Done"); |
509 | } |
510 | // Approximons cette courbe algorithmique. |
511 | Standard_Boolean Only3d = Standard_False; |
512 | Standard_Boolean Only2d = Standard_True; |
513 | GeomAbs_Shape Continuity = GeomAbs_C1; |
514 | Standard_Integer MaxDegree = 14; |
515 | Standard_Integer MaxSeg = 16; |
516 | |
517 | Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, |
518 | myTolerance, |
519 | Continuity, MaxDegree, MaxSeg, |
520 | Only3d, Only2d); |
521 | |
522 | Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d(); |
523 | |
524 | if(IsTrimmed[0] || IsTrimmed[1]) { |
525 | // Treatment only for surface of revolution |
526 | Standard_Real u1, u2, v1, v2; |
527 | u1 = mySurface->FirstUParameter(); |
528 | u2 = mySurface->LastUParameter(); |
529 | v1 = mySurface->FirstVParameter(); |
530 | v2 = mySurface->LastVParameter(); |
531 | |
532 | if(IsTrimmed[0]) { |
533 | //Add segment before start of curve |
bd82d4b2 |
534 | ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3); |
7fd59977 |
535 | } |
536 | if(IsTrimmed[1]) { |
537 | //Add segment after end of curve |
bd82d4b2 |
538 | ExtendC2d(aRes, l, dt, u1, u2, Vsingular[1], v2, 1, 3); |
7fd59977 |
539 | } |
bd82d4b2 |
540 | Handle(Geom2d_Curve) NewCurve2d; |
541 | GeomLib::SameRange(Precision::PConfusion(), aRes, |
542 | aRes->FirstParameter(), aRes->LastParameter(), |
543 | FirstPar, LastPar, |
544 | NewCurve2d); |
545 | aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d); |
7fd59977 |
546 | } |
547 | |
548 | myResult.SetBSpline(aRes); |
549 | myResult.Done(); |
550 | myResult.SetType(GeomAbs_BSplineCurve); |
551 | } |
552 | } |
553 | if ( !myResult.IsDone()) { |
554 | ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance); |
555 | myResult.Done(); |
556 | |
557 | // set the type |
558 | if ( SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve) { |
559 | myResult.SetType(GeomAbs_BezierCurve); |
560 | myResult.SetBezier(Comp.Bezier()) ; |
561 | } |
562 | else { |
563 | myResult.SetType(GeomAbs_BSplineCurve); |
564 | myResult.SetBSpline(Comp.BSpline()) ; |
565 | } |
566 | // set the periodicity flag |
567 | if ( SType == GeomAbs_Plane && |
568 | CType == GeomAbs_BSplineCurve && |
569 | myCurve->IsPeriodic() ) { |
570 | myResult.SetPeriodic(); |
571 | } |
572 | myTolerance = Comp.Tolerance(); |
573 | } |
574 | |
575 | else { |
576 | // On remet arbitrairement la tol atteinte a une valeur |
577 | // petite en attendant mieux. dub lbo 11/03/97 |
578 | myTolerance = Min(myTolerance,Precision::Confusion()); |
579 | |
580 | // Translate the projected curve to keep the first point |
581 | // In the canonical boundaries of periodic surfaces. |
582 | if (mySurface->IsUPeriodic()) { |
583 | // xf |
584 | Standard_Real aT1, aT2, aU1, aU2, aUPeriod, aUr, aUm, aUmid, dUm, dUr; |
585 | GeomAbs_CurveType aTypeR; |
586 | ProjLib_Projector aResult; |
587 | // |
588 | aT1=myCurve->FirstParameter(); |
589 | aT2=myCurve->LastParameter(); |
590 | aU1=mySurface->FirstUParameter(); |
591 | aU2=mySurface->LastUParameter(); |
592 | aUPeriod=mySurface->UPeriod(); |
593 | // |
594 | aTypeR=myResult.GetType(); |
595 | if ((aU2-aU1)<(aUPeriod-myTolerance) && aTypeR == GeomAbs_Line) { |
596 | aResult=myResult; |
597 | aResult.UFrame(aT1, aT2, aU1, aUPeriod); |
598 | // |
599 | gp_Lin2d &aLr = (gp_Lin2d &) aResult.Line(); |
600 | aUr=aLr.Location().X(); |
601 | gp_Lin2d &aLm = (gp_Lin2d &) myResult.Line(); |
602 | aUm=aLm.Location().X(); |
603 | // |
604 | aUmid=0.5*(aU2+aU1); |
605 | dUm=fabs(aUm-aUmid); |
606 | dUr=fabs(aUr-aUmid); |
607 | if (dUr<dUm) { |
608 | myResult=aResult; |
609 | } |
610 | } |
611 | else { |
612 | myResult.UFrame(aT1, aT2, aU1, aUPeriod); |
613 | } |
614 | // |
615 | /* |
616 | myResult.UFrame(myCurve->FirstParameter(), |
617 | myCurve->LastParameter(), |
618 | mySurface->FirstUParameter(), |
619 | mySurface->UPeriod()); |
620 | */ |
621 | //xt |
622 | // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin |
623 | // Correct the U isoline in periodical surface |
624 | // to be inside restriction boundaries. |
625 | if (myResult.GetType() == GeomAbs_Line) { |
626 | gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line(); |
627 | |
628 | Standard_Real aPeriod = mySurface->UPeriod(); |
629 | Standard_Real aFUPar = mySurface->FirstUParameter(); |
630 | Standard_Real aLUPar = mySurface->LastUParameter(); |
631 | |
632 | // Check if the parametric range is lower then the period. |
633 | if (aLUPar - aFUPar < aPeriod - myTolerance) { |
634 | Standard_Real aU = aLine.Location().X(); |
635 | |
636 | if (Abs(aU + aPeriod - aFUPar) < myTolerance || |
637 | Abs(aU - aPeriod - aFUPar) < myTolerance) { |
638 | gp_Pnt2d aNewLoc(aFUPar, aLine.Location().Y()); |
639 | |
640 | aLine.SetLocation(aNewLoc); |
641 | } else if (Abs(aU + aPeriod - aLUPar) < myTolerance || |
642 | Abs(aU - aPeriod - aLUPar) < myTolerance) { |
643 | gp_Pnt2d aNewLoc(aLUPar, aLine.Location().Y()); |
644 | |
645 | aLine.SetLocation(aNewLoc); |
646 | } |
647 | } |
648 | } |
649 | } |
650 | // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End |
651 | |
652 | if (mySurface->IsVPeriodic()) { |
653 | myResult.VFrame(myCurve->FirstParameter(), |
654 | myCurve->LastParameter(), |
655 | mySurface->FirstVParameter(), |
656 | mySurface->VPeriod()); |
657 | // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin |
658 | // Correct the V isoline in a periodical surface |
659 | // to be inside restriction boundaries. |
660 | if (myResult.GetType() == GeomAbs_Line) { |
661 | gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line(); |
662 | |
663 | Standard_Real aPeriod = mySurface->VPeriod(); |
664 | Standard_Real aFVPar = mySurface->FirstVParameter(); |
665 | Standard_Real aLVPar = mySurface->LastVParameter(); |
666 | |
667 | // Check if the parametric range is lower then the period. |
668 | if (aLVPar - aFVPar < aPeriod - myTolerance) { |
669 | Standard_Real aV = aLine.Location().Y(); |
670 | |
671 | if (Abs(aV + aPeriod - aFVPar) < myTolerance || |
672 | Abs(aV - aPeriod - aFVPar) < myTolerance) { |
673 | gp_Pnt2d aNewLoc(aLine.Location().X(), aFVPar); |
674 | |
675 | aLine.SetLocation(aNewLoc); |
676 | } else if (Abs(aV + aPeriod - aLVPar) < myTolerance || |
677 | Abs(aV - aPeriod - aLVPar) < myTolerance) { |
678 | gp_Pnt2d aNewLoc(aLine.Location().X(), aLVPar); |
679 | |
680 | aLine.SetLocation(aNewLoc); |
681 | } |
682 | } |
683 | } |
684 | } |
685 | // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End |
686 | } |
687 | } |
688 | |
689 | |
690 | //======================================================================= |
691 | //function : GetSurface |
692 | //purpose : |
693 | //======================================================================= |
694 | |
695 | const Handle(Adaptor3d_HSurface)& ProjLib_ProjectedCurve::GetSurface() const |
696 | { |
697 | return mySurface; |
698 | } |
699 | |
700 | |
701 | //======================================================================= |
702 | //function : GetCurve |
703 | //purpose : |
704 | //======================================================================= |
705 | |
706 | const Handle(Adaptor3d_HCurve)& ProjLib_ProjectedCurve::GetCurve() const |
707 | { |
708 | return myCurve; |
709 | } |
710 | |
711 | |
712 | //======================================================================= |
713 | //function : GetTolerance |
714 | //purpose : |
715 | //======================================================================= |
716 | |
717 | Standard_Real ProjLib_ProjectedCurve::GetTolerance() const |
718 | { |
719 | return myTolerance; |
720 | } |
721 | |
722 | |
723 | //======================================================================= |
724 | //function : FirstParameter |
725 | //purpose : |
726 | //======================================================================= |
727 | |
728 | Standard_Real ProjLib_ProjectedCurve::FirstParameter() const |
729 | { |
730 | return myCurve->FirstParameter(); |
731 | } |
732 | |
733 | |
734 | //======================================================================= |
735 | //function : LastParameter |
736 | //purpose : |
737 | //======================================================================= |
738 | |
739 | Standard_Real ProjLib_ProjectedCurve::LastParameter() const |
740 | { |
741 | return myCurve->LastParameter(); |
742 | } |
743 | |
744 | |
745 | //======================================================================= |
746 | //function : Continuity |
747 | //purpose : |
748 | //======================================================================= |
749 | |
750 | GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const |
751 | { |
752 | Standard_NotImplemented::Raise(""); |
753 | return GeomAbs_C0; |
754 | } |
755 | |
756 | |
757 | //======================================================================= |
758 | //function : NbIntervals |
759 | //purpose : |
760 | //======================================================================= |
761 | |
762 | Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const |
763 | { |
764 | Standard_NotImplemented::Raise(""); |
765 | return 0; |
766 | } |
767 | |
768 | |
769 | //======================================================================= |
770 | //function : Intervals |
771 | //purpose : |
772 | //======================================================================= |
773 | |
774 | //void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& T, |
775 | void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& , |
776 | const GeomAbs_Shape ) const |
777 | { |
778 | Standard_NotImplemented::Raise(""); |
779 | } |
780 | |
781 | |
782 | //======================================================================= |
783 | //function : IsClosed |
784 | //purpose : |
785 | //======================================================================= |
786 | |
787 | Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const |
788 | { |
789 | Standard_NotImplemented::Raise(""); |
790 | return Standard_True; |
791 | } |
792 | |
793 | |
794 | //======================================================================= |
795 | //function : IsPeriodic |
796 | //purpose : |
797 | //======================================================================= |
798 | |
799 | Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const |
800 | { |
801 | return myResult.IsPeriodic(); |
802 | } |
803 | |
804 | |
805 | //======================================================================= |
806 | //function : Period |
807 | //purpose : |
808 | //======================================================================= |
809 | |
810 | Standard_Real ProjLib_ProjectedCurve::Period() const |
811 | { |
812 | Standard_NotImplemented::Raise(""); |
813 | return 0.; |
814 | } |
815 | |
816 | |
817 | //======================================================================= |
818 | //function : Value |
819 | //purpose : |
820 | //======================================================================= |
821 | |
822 | gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const |
823 | { |
824 | Standard_NotImplemented::Raise(""); |
825 | return gp_Pnt2d(0.,0.); |
826 | } |
827 | |
828 | |
829 | //======================================================================= |
830 | //function : D0 |
831 | //purpose : |
832 | //======================================================================= |
833 | |
834 | void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const |
835 | { |
836 | Standard_NotImplemented::Raise(""); |
837 | } |
838 | |
839 | |
840 | //======================================================================= |
841 | //function : D1 |
842 | //purpose : |
843 | //======================================================================= |
844 | |
845 | void ProjLib_ProjectedCurve::D1(const Standard_Real , |
846 | gp_Pnt2d& , |
847 | gp_Vec2d& ) const |
848 | { |
849 | Standard_NotImplemented::Raise(""); |
850 | } |
851 | |
852 | |
853 | //======================================================================= |
854 | //function : D2 |
855 | //purpose : |
856 | //======================================================================= |
857 | |
858 | void ProjLib_ProjectedCurve::D2(const Standard_Real , |
859 | gp_Pnt2d& , |
860 | gp_Vec2d& , |
861 | gp_Vec2d& ) const |
862 | { |
863 | Standard_NotImplemented::Raise(""); |
864 | } |
865 | |
866 | |
867 | //======================================================================= |
868 | //function : D3 |
869 | //purpose : |
870 | //======================================================================= |
871 | |
872 | void ProjLib_ProjectedCurve::D3(const Standard_Real, |
873 | gp_Pnt2d&, |
874 | gp_Vec2d&, |
875 | gp_Vec2d&, |
876 | gp_Vec2d&) const |
877 | { |
878 | Standard_NotImplemented::Raise(""); |
879 | } |
880 | |
881 | |
882 | //======================================================================= |
883 | //function : DN |
884 | //purpose : |
885 | //======================================================================= |
886 | |
887 | gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real, |
888 | const Standard_Integer) const |
889 | { |
890 | Standard_NotImplemented::Raise(""); |
891 | return gp_Vec2d(0.,0.); |
892 | } |
893 | |
894 | |
895 | //======================================================================= |
896 | //function : Resolution |
897 | //purpose : |
898 | //======================================================================= |
899 | |
900 | Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const |
901 | { |
902 | Standard_NotImplemented::Raise(""); |
903 | return 0.; |
904 | } |
905 | |
906 | |
907 | //======================================================================= |
908 | //function : GetType |
909 | //purpose : |
910 | //======================================================================= |
911 | |
912 | GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const |
913 | { |
914 | return myResult.GetType(); |
915 | } |
916 | |
917 | |
918 | //======================================================================= |
919 | //function : Line |
920 | //purpose : |
921 | //======================================================================= |
922 | |
923 | gp_Lin2d ProjLib_ProjectedCurve::Line() const |
924 | { |
925 | return myResult.Line(); |
926 | } |
927 | |
928 | |
929 | //======================================================================= |
930 | //function : Circle |
931 | //purpose : |
932 | //======================================================================= |
933 | |
934 | gp_Circ2d ProjLib_ProjectedCurve::Circle() const |
935 | { |
936 | return myResult.Circle(); |
937 | } |
938 | |
939 | |
940 | //======================================================================= |
941 | //function : Ellipse |
942 | //purpose : |
943 | //======================================================================= |
944 | |
945 | gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const |
946 | { |
947 | return myResult.Ellipse(); |
948 | } |
949 | |
950 | |
951 | //======================================================================= |
952 | //function : Hyperbola |
953 | //purpose : |
954 | //======================================================================= |
955 | |
956 | gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const |
957 | { |
958 | return myResult.Hyperbola(); |
959 | } |
960 | |
961 | |
962 | //======================================================================= |
963 | //function : Parabola |
964 | //purpose : |
965 | //======================================================================= |
966 | |
967 | gp_Parab2d ProjLib_ProjectedCurve::Parabola() const |
968 | { |
969 | return myResult.Parabola(); |
970 | } |
971 | |
972 | |
973 | |
974 | //======================================================================= |
975 | //function : Degree |
976 | //purpose : |
977 | //======================================================================= |
978 | |
979 | Standard_Integer ProjLib_ProjectedCurve::Degree() const |
980 | { |
981 | Standard_NoSuchObject_Raise_if |
982 | ( (GetType() != GeomAbs_BSplineCurve) && |
983 | (GetType() != GeomAbs_BezierCurve), |
984 | "ProjLib_ProjectedCurve:Degree"); |
985 | if (GetType() == GeomAbs_BSplineCurve) { |
986 | return myResult.BSpline()->Degree(); |
987 | } |
988 | else if (GetType() == GeomAbs_BezierCurve) { |
989 | return myResult.Bezier()->Degree(); |
990 | } |
991 | |
992 | // portage WNT |
993 | return 0; |
994 | } |
995 | |
996 | //======================================================================= |
997 | //function : IsRational |
998 | //purpose : |
999 | //======================================================================= |
1000 | |
1001 | Standard_Boolean ProjLib_ProjectedCurve::IsRational() const |
1002 | { |
1003 | Standard_NoSuchObject_Raise_if |
1004 | ( (GetType() != GeomAbs_BSplineCurve) && |
1005 | (GetType() != GeomAbs_BezierCurve), |
1006 | "ProjLib_ProjectedCurve:IsRational"); |
1007 | if (GetType() == GeomAbs_BSplineCurve) { |
1008 | return myResult.BSpline()->IsRational(); |
1009 | } |
1010 | else if (GetType() == GeomAbs_BezierCurve) { |
1011 | return myResult.Bezier()->IsRational(); |
1012 | } |
1013 | // portage WNT |
1014 | return Standard_False; |
1015 | } |
1016 | |
1017 | //======================================================================= |
1018 | //function : NbPoles |
1019 | //purpose : |
1020 | //======================================================================= |
1021 | |
1022 | Standard_Integer ProjLib_ProjectedCurve::NbPoles() const |
1023 | { |
1024 | Standard_NoSuchObject_Raise_if |
1025 | ( (GetType() != GeomAbs_BSplineCurve) && |
1026 | (GetType() != GeomAbs_BezierCurve) |
1027 | ,"ProjLib_ProjectedCurve:NbPoles" ); |
1028 | if (GetType() == GeomAbs_BSplineCurve) { |
1029 | return myResult.BSpline()->NbPoles(); |
1030 | } |
1031 | else if (GetType() == GeomAbs_BezierCurve) { |
1032 | return myResult.Bezier()->NbPoles(); |
1033 | } |
1034 | |
1035 | // portage WNT |
1036 | return 0; |
1037 | } |
1038 | |
1039 | //======================================================================= |
1040 | //function : NbKnots |
1041 | //purpose : |
1042 | //======================================================================= |
1043 | |
1044 | Standard_Integer ProjLib_ProjectedCurve::NbKnots() const |
1045 | { |
1046 | Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve, |
1047 | "ProjLib_ProjectedCurve:NbKnots"); |
1048 | return myResult.BSpline()->NbKnots(); |
1049 | } |
1050 | |
1051 | //======================================================================= |
1052 | //function : Bezier |
1053 | //purpose : |
1054 | //======================================================================= |
1055 | |
1056 | Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const |
1057 | { |
1058 | return myResult.Bezier() ; |
1059 | } |
1060 | |
1061 | //======================================================================= |
1062 | //function : BSpline |
1063 | //purpose : |
1064 | //======================================================================= |
1065 | |
1066 | Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const |
1067 | { |
1068 | return myResult.BSpline() ; |
1069 | } |
1070 | //======================================================================= |
1071 | //function : Trim |
1072 | //purpose : |
1073 | //======================================================================= |
1074 | |
1075 | Handle(Adaptor2d_HCurve2d) ProjLib_ProjectedCurve::Trim |
1076 | //(const Standard_Real First, |
1077 | // const Standard_Real Last, |
1078 | // const Standard_Real Tolerance) const |
1079 | (const Standard_Real , |
1080 | const Standard_Real , |
1081 | const Standard_Real ) const |
1082 | { |
1083 | Standard_NotImplemented::Raise(""); |
1084 | return NULL ; |
1085 | } |
1086 | |