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