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