Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
b311480e | 14 | |
7fd59977 | 15 | //Jean-Claude Vauthier Novembre 1991 |
16 | //Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline | |
17 | ||
42cf5bc1 | 18 | #include <BSplCLib.hxx> |
7fd59977 | 19 | #include <Convert_CircleToBSplineCurve.hxx> |
42cf5bc1 | 20 | #include <Convert_ConicToBSplineCurve.hxx> |
7fd59977 | 21 | #include <Convert_EllipseToBSplineCurve.hxx> |
22 | #include <Convert_HyperbolaToBSplineCurve.hxx> | |
23 | #include <Convert_ParabolaToBSplineCurve.hxx> | |
42cf5bc1 | 24 | #include <Geom2d_BezierCurve.hxx> |
25 | #include <Geom2d_BSplineCurve.hxx> | |
7fd59977 | 26 | #include <Geom2d_Circle.hxx> |
42cf5bc1 | 27 | #include <Geom2d_Conic.hxx> |
28 | #include <Geom2d_Curve.hxx> | |
7fd59977 | 29 | #include <Geom2d_Ellipse.hxx> |
42cf5bc1 | 30 | #include <Geom2d_Geometry.hxx> |
7fd59977 | 31 | #include <Geom2d_Hyperbola.hxx> |
42cf5bc1 | 32 | #include <Geom2d_Line.hxx> |
33 | #include <Geom2d_OffsetCurve.hxx> | |
7fd59977 | 34 | #include <Geom2d_Parabola.hxx> |
7fd59977 | 35 | #include <Geom2d_TrimmedCurve.hxx> |
42cf5bc1 | 36 | #include <Geom2dConvert.hxx> |
7fd59977 | 37 | #include <Geom2dConvert_ApproxCurve.hxx> |
42cf5bc1 | 38 | #include <Geom2dConvert_CompCurveToBSplineCurve.hxx> |
7fd59977 | 39 | #include <GeomAbs_Shape.hxx> |
42cf5bc1 | 40 | #include <gp.hxx> |
41 | #include <gp_Circ2d.hxx> | |
42 | #include <gp_Dir2d.hxx> | |
43 | #include <gp_Elips2d.hxx> | |
44 | #include <gp_Hypr2d.hxx> | |
45 | #include <gp_Lin.hxx> | |
46 | #include <gp_Parab2d.hxx> | |
47 | #include <gp_Pnt2d.hxx> | |
48 | #include <gp_Trsf2d.hxx> | |
49 | #include <gp_Vec2d.hxx> | |
7fd59977 | 50 | #include <Hermit.hxx> |
7fd59977 | 51 | #include <PLib.hxx> |
42cf5bc1 | 52 | #include <Precision.hxx> |
53 | #include <Standard_ConstructionError.hxx> | |
54 | #include <Standard_DomainError.hxx> | |
55 | #include <Standard_OutOfRange.hxx> | |
56 | #include <TColgp_Array1OfPnt2d.hxx> | |
7fd59977 | 57 | #include <TColStd_Array1OfBoolean.hxx> |
7fd59977 | 58 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 | 59 | #include <TColStd_Array1OfReal.hxx> |
60 | #include <TColStd_HArray1OfReal.hxx> | |
7fd59977 | 61 | |
62 | typedef gp_Circ2d Circ2d; | |
63 | typedef gp_Elips2d Elips2d; | |
64 | typedef gp_Hypr2d Hypr2d; | |
65 | typedef gp_Parab2d Parab2d; | |
66 | typedef gp_Pnt2d Pnt2d; | |
67 | typedef gp_Trsf2d Trsf2d; | |
7fd59977 | 68 | typedef Geom2d_Curve Curve; |
69 | typedef Geom2d_BSplineCurve BSplineCurve; | |
7fd59977 | 70 | typedef TColStd_Array1OfReal Array1OfReal; |
71 | typedef TColStd_Array1OfInteger Array1OfInteger; | |
72 | typedef TColgp_Array1OfPnt2d Array1OfPnt2d; | |
73 | ||
7fd59977 | 74 | //======================================================================= |
75 | //function : BSplineCurveBuilder | |
76 | //purpose : | |
77 | //======================================================================= | |
78 | ||
c04c30b3 | 79 | static Handle(Geom2d_BSplineCurve) BSplineCurveBuilder ( |
7fd59977 | 80 | |
c04c30b3 | 81 | const Handle(Geom2d_Conic)& TheConic, |
7fd59977 | 82 | const Convert_ConicToBSplineCurve& Convert |
83 | ) { | |
84 | ||
c04c30b3 | 85 | Handle(Geom2d_BSplineCurve) TheCurve; |
7fd59977 | 86 | Standard_Integer NbPoles = Convert.NbPoles(); |
87 | Standard_Integer NbKnots = Convert.NbKnots(); | |
88 | Array1OfPnt2d Poles (1, NbPoles); | |
89 | Array1OfReal Weights (1, NbPoles); | |
90 | Array1OfReal Knots (1, NbKnots); | |
91 | Array1OfInteger Mults (1, NbKnots); | |
92 | Standard_Integer i; | |
93 | for (i = 1; i <= NbPoles; i++) { | |
94 | Poles (i) = Convert.Pole (i); | |
95 | Weights (i) = Convert.Weight (i); | |
96 | } | |
97 | for (i = 1; i <= NbKnots; i++) { | |
98 | Knots (i) = Convert.Knot (i); | |
99 | Mults (i) = Convert.Multiplicity (i); | |
100 | } | |
101 | TheCurve = new BSplineCurve ( | |
102 | Poles, Weights, Knots, Mults, | |
103 | Convert.Degree(), Convert.IsPeriodic()); | |
104 | ||
105 | gp_Ax22d Axis = TheConic->Position(); | |
106 | if ( ( Axis.XDirection() ^ Axis.YDirection()) < 0.) { | |
107 | // Then the axis is left-handed, apply a symetry to the curve. | |
108 | gp_Trsf2d Sym; | |
109 | Sym.SetMirror(gp::OX2d()); | |
110 | TheCurve->Transform(Sym); | |
111 | } | |
112 | ||
113 | Trsf2d T; | |
114 | T.SetTransformation (TheConic->XAxis(), gp::OX2d()); | |
c04c30b3 | 115 | Handle(Geom2d_BSplineCurve) Cres = |
116 | Handle(Geom2d_BSplineCurve)::DownCast(TheCurve->Transformed (T)); | |
7fd59977 | 117 | return Cres; |
118 | } | |
119 | ||
120 | ||
121 | //======================================================================= | |
122 | //function : SplitBSplineCurve | |
123 | //purpose : | |
124 | //======================================================================= | |
125 | ||
c04c30b3 | 126 | Handle(Geom2d_BSplineCurve) Geom2dConvert::SplitBSplineCurve ( |
7fd59977 | 127 | |
c04c30b3 | 128 | const Handle(Geom2d_BSplineCurve)& C, |
7fd59977 | 129 | const Standard_Integer FromK1, |
130 | const Standard_Integer ToK2, | |
131 | const Standard_Boolean SameOrientation | |
132 | ) { | |
133 | ||
134 | Standard_Integer TheFirst = C->FirstUKnotIndex (); | |
135 | Standard_Integer TheLast = C->LastUKnotIndex (); | |
9775fa61 | 136 | if (FromK1 == ToK2) throw Standard_DomainError(); |
7fd59977 | 137 | Standard_Integer FirstK = Min (FromK1, ToK2); |
138 | Standard_Integer LastK = Max (FromK1, ToK2); | |
9775fa61 | 139 | if (FirstK < TheFirst || LastK > TheLast) throw Standard_OutOfRange(); |
7fd59977 | 140 | |
c04c30b3 | 141 | Handle(Geom2d_BSplineCurve) NewCurve = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy()); |
7fd59977 | 142 | |
143 | NewCurve->Segment(C->Knot(FirstK),C->Knot(LastK)); | |
144 | ||
145 | if (C->IsPeriodic()) { | |
146 | if (!SameOrientation) NewCurve->Reverse(); | |
147 | } | |
148 | else { | |
149 | if (FromK1 > ToK2) NewCurve->Reverse(); | |
150 | } | |
151 | return NewCurve; | |
152 | } | |
153 | ||
154 | ||
155 | //======================================================================= | |
156 | //function : SplitBSplineCurve | |
157 | //purpose : | |
158 | //======================================================================= | |
159 | ||
c04c30b3 | 160 | Handle(Geom2d_BSplineCurve) Geom2dConvert::SplitBSplineCurve ( |
7fd59977 | 161 | |
c04c30b3 | 162 | const Handle(Geom2d_BSplineCurve)& C, |
7fd59977 | 163 | const Standard_Real FromU1, |
164 | const Standard_Real ToU2, | |
165 | const Standard_Real, // ParametricTolerance, | |
166 | const Standard_Boolean SameOrientation | |
167 | ) | |
168 | { | |
169 | Standard_Real FirstU = Min( FromU1, ToU2); | |
170 | Standard_Real LastU = Max( FromU1, ToU2); | |
171 | ||
172 | Handle (Geom2d_BSplineCurve) C1 | |
173 | = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy()); | |
174 | ||
175 | C1->Segment(FirstU, LastU); | |
176 | ||
177 | if (C->IsPeriodic()) { | |
178 | if (!SameOrientation) C1->Reverse(); | |
179 | } | |
180 | else { | |
181 | if (FromU1 > ToU2) C1->Reverse(); | |
182 | } | |
183 | ||
184 | return C1; | |
185 | } | |
186 | ||
187 | ||
188 | //======================================================================= | |
189 | //function : CurveToBSplineCurve | |
190 | //purpose : | |
191 | //======================================================================= | |
192 | ||
c04c30b3 | 193 | Handle(Geom2d_BSplineCurve) Geom2dConvert::CurveToBSplineCurve ( |
7fd59977 | 194 | |
c04c30b3 | 195 | const Handle(Geom2d_Curve)& C, |
7fd59977 | 196 | const Convert_ParameterisationType Parameterisation) |
197 | { | |
198 | ||
199 | Handle (BSplineCurve) TheCurve; | |
200 | ||
201 | if (C->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) { | |
202 | Handle (Curve) Curv; | |
c04c30b3 | 203 | Handle(Geom2d_TrimmedCurve) Ctrim = Handle(Geom2d_TrimmedCurve)::DownCast(C); |
7fd59977 | 204 | Curv = Ctrim->BasisCurve(); |
205 | Standard_Real U1 = Ctrim->FirstParameter(); | |
206 | Standard_Real U2 = Ctrim->LastParameter(); | |
207 | ||
208 | // Si la courbe n'est pas vraiment restreinte, on ne risque pas | |
209 | // le Raise dans le BS->Segment. | |
210 | if (!Curv->IsPeriodic()) { | |
211 | if (U1 < Curv->FirstParameter()) | |
212 | U1 = Curv->FirstParameter(); | |
213 | if (U2 > Curv->LastParameter()) | |
214 | U2 = Curv->LastParameter(); | |
215 | } | |
216 | ||
217 | if (Curv->IsKind(STANDARD_TYPE(Geom2d_Line))) { | |
218 | gp_Pnt2d Pdeb = Ctrim->StartPoint(); | |
219 | gp_Pnt2d Pfin = Ctrim->EndPoint(); | |
220 | Array1OfPnt2d Poles (1, 2); | |
221 | Poles (1) = Pdeb; | |
222 | Poles (2) = Pfin; | |
223 | Array1OfReal Knots (1, 2); | |
224 | Knots (1) = Ctrim->FirstParameter (); | |
225 | Knots (2) = Ctrim->LastParameter(); | |
226 | Array1OfInteger Mults (1, 2); | |
227 | Mults (1) = 2; | |
228 | Mults (2) = 2; | |
229 | Standard_Integer Degree = 1; | |
230 | TheCurve = new Geom2d_BSplineCurve (Poles, Knots, Mults, Degree); | |
231 | } | |
232 | ||
233 | else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Circle))) { | |
c04c30b3 | 234 | Handle(Geom2d_Circle) TheConic= Handle(Geom2d_Circle)::DownCast(Curv); |
7fd59977 | 235 | Circ2d C2d (gp::OX2d(), TheConic->Radius()); |
236 | if(Parameterisation != Convert_RationalC1) { | |
237 | Convert_CircleToBSplineCurve Convert (C2d, | |
238 | U1, | |
239 | U2, | |
240 | Parameterisation); | |
241 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
242 | } | |
243 | else { | |
244 | if(U2 - U1 < 6.) { | |
245 | Convert_CircleToBSplineCurve Convert (C2d, | |
246 | U1, | |
247 | U2, | |
248 | Parameterisation); | |
249 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
250 | } | |
251 | else { // split circle to avoide numerical | |
252 | // overflow when U2 - U1 =~ 2*PI | |
253 | ||
254 | Standard_Real Umed = (U1 + U2) * .5; | |
255 | Convert_CircleToBSplineCurve Convert1 (C2d, | |
256 | U1, | |
257 | Umed, | |
258 | Parameterisation); | |
259 | ||
260 | Handle (BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1); | |
261 | ||
262 | Convert_CircleToBSplineCurve Convert2 (C2d, | |
263 | Umed, | |
264 | U2, | |
265 | Parameterisation); | |
266 | ||
267 | Handle (BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2); | |
268 | ||
269 | Geom2dConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1, | |
270 | Parameterisation); | |
271 | ||
272 | CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True); | |
273 | ||
274 | ||
275 | TheCurve = CCTBSpl.BSplineCurve(); | |
276 | } | |
277 | } | |
278 | } | |
279 | ||
280 | else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { | |
c04c30b3 | 281 | Handle(Geom2d_Ellipse) TheConic = Handle(Geom2d_Ellipse)::DownCast(Curv); |
7fd59977 | 282 | |
283 | Elips2d E2d (gp::OX2d(), | |
284 | TheConic->MajorRadius(), | |
285 | TheConic->MinorRadius()); | |
286 | if(Parameterisation != Convert_RationalC1) { | |
287 | Convert_EllipseToBSplineCurve Convert (E2d, | |
288 | U1, | |
289 | U2, | |
290 | Parameterisation); | |
291 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
292 | } | |
293 | else { | |
294 | if(U2 - U1 < 6.) { | |
295 | Convert_EllipseToBSplineCurve Convert (E2d, | |
296 | U1, | |
297 | U2, | |
298 | Parameterisation); | |
299 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
300 | } | |
301 | else { // split ellipse to avoide numerical | |
302 | // overflow when U2 - U1 =~ 2*PI | |
303 | ||
304 | Standard_Real Umed = (U1 + U2) * .5; | |
305 | Convert_EllipseToBSplineCurve Convert1 (E2d, | |
306 | U1, | |
307 | Umed, | |
308 | Parameterisation); | |
309 | ||
310 | Handle (BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1); | |
311 | ||
312 | Convert_EllipseToBSplineCurve Convert2 (E2d, | |
313 | Umed, | |
314 | U2, | |
315 | Parameterisation); | |
316 | ||
317 | Handle (BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2); | |
318 | ||
319 | Geom2dConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1, | |
320 | Parameterisation); | |
321 | ||
322 | CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True); | |
323 | ||
324 | ||
325 | TheCurve = CCTBSpl.BSplineCurve(); | |
326 | } | |
327 | } | |
328 | } | |
329 | ||
330 | else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) { | |
c04c30b3 | 331 | Handle(Geom2d_Hyperbola) TheConic = Handle(Geom2d_Hyperbola)::DownCast(Curv); |
7fd59977 | 332 | |
333 | Hypr2d H2d (gp::OX2d(), | |
334 | TheConic->MajorRadius(), TheConic->MinorRadius()); | |
335 | Convert_HyperbolaToBSplineCurve Convert (H2d, U1, U2); | |
336 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
337 | } | |
338 | ||
339 | else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Parabola))) { | |
c04c30b3 | 340 | Handle(Geom2d_Parabola) TheConic = Handle(Geom2d_Parabola)::DownCast(Curv); |
7fd59977 | 341 | |
342 | Parab2d Prb2d (gp::OX2d(), TheConic->Focal()); | |
343 | Convert_ParabolaToBSplineCurve Convert (Prb2d, U1, U2); | |
344 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
345 | } | |
346 | ||
347 | else if (Curv->IsKind (STANDARD_TYPE(Geom2d_BezierCurve))) { | |
348 | ||
c04c30b3 | 349 | Handle(Geom2d_BezierCurve) CBez = Handle(Geom2d_BezierCurve)::DownCast(Curv->Copy()); |
7fd59977 | 350 | |
351 | CBez->Segment (U1, U2); | |
352 | Standard_Integer NbPoles = CBez->NbPoles(); | |
353 | Standard_Integer Degree = CBez->Degree(); | |
354 | Array1OfPnt2d Poles (1, NbPoles); | |
355 | Array1OfReal Knots (1, 2); | |
356 | Array1OfInteger Mults (1, 2); | |
357 | Knots (1) = 0.0; | |
358 | Knots (2) = 1.0; | |
359 | Mults (1) = Degree + 1; | |
360 | Mults (2) = Degree + 1; | |
361 | CBez->Poles (Poles); | |
362 | if (CBez->IsRational()) { | |
363 | Array1OfReal Weights (1, NbPoles); | |
364 | CBez->Weights (Weights); | |
365 | TheCurve = new BSplineCurve (Poles, Weights, Knots, Mults, Degree); | |
366 | } | |
367 | else { | |
368 | TheCurve = new BSplineCurve (Poles, Knots, Mults, Degree); | |
369 | } | |
370 | } | |
371 | ||
372 | else if (Curv->IsKind (STANDARD_TYPE(Geom2d_BSplineCurve))) { | |
373 | TheCurve = Handle(Geom2d_BSplineCurve)::DownCast(Curv->Copy()); | |
374 | TheCurve->Segment(U1,U2); | |
375 | } | |
376 | ||
377 | else if (Curv->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) { | |
378 | ||
379 | Standard_Real Tol2d = 1.e-4; | |
380 | GeomAbs_Shape Order = GeomAbs_C2; | |
381 | Standard_Integer MaxSegments = 16, MaxDegree = 14; | |
382 | Geom2dConvert_ApproxCurve ApprCOffs(C, Tol2d, Order, | |
383 | MaxSegments, MaxDegree); | |
384 | if (ApprCOffs.HasResult()) | |
385 | TheCurve = ApprCOffs.Curve(); | |
9775fa61 | 386 | else throw Standard_ConstructionError(); |
7fd59977 | 387 | } |
388 | ||
9775fa61 | 389 | else { throw Standard_DomainError("No such curve"); } |
7fd59977 | 390 | |
391 | } | |
392 | ||
393 | ||
394 | else { | |
395 | ||
396 | if (C->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) { | |
c04c30b3 | 397 | Handle(Geom2d_Ellipse) TheConic = Handle(Geom2d_Ellipse)::DownCast(C); |
7fd59977 | 398 | |
399 | Elips2d E2d (gp::OX2d(), | |
400 | TheConic->MajorRadius(), TheConic->MinorRadius()); | |
401 | Convert_EllipseToBSplineCurve Convert (E2d, | |
402 | Parameterisation); | |
403 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
404 | TheCurve->SetPeriodic(); | |
405 | } | |
406 | ||
407 | else if (C->IsKind(STANDARD_TYPE(Geom2d_Circle))) { | |
c04c30b3 | 408 | Handle(Geom2d_Circle) TheConic = Handle(Geom2d_Circle)::DownCast(C); |
7fd59977 | 409 | |
410 | Circ2d C2d (gp::OX2d(), TheConic->Radius()); | |
411 | Convert_CircleToBSplineCurve Convert (C2d, | |
412 | Parameterisation); | |
413 | TheCurve = BSplineCurveBuilder (TheConic, Convert); | |
414 | TheCurve->SetPeriodic(); | |
415 | } | |
416 | ||
417 | else if (C->IsKind (STANDARD_TYPE(Geom2d_BezierCurve))) { | |
c04c30b3 | 418 | Handle(Geom2d_BezierCurve) CBez = Handle(Geom2d_BezierCurve)::DownCast(C); |
7fd59977 | 419 | |
420 | Standard_Integer NbPoles = CBez->NbPoles(); | |
421 | Standard_Integer Degree = CBez->Degree(); | |
422 | Array1OfPnt2d Poles (1, NbPoles); | |
423 | Array1OfReal Knots (1, 2); | |
424 | Array1OfInteger Mults (1, 2); | |
425 | Knots (1) = 0.0; | |
426 | Knots (2) = 1.0; | |
427 | Mults (1) = Degree + 1; | |
428 | Mults (2) = Degree + 1; | |
429 | CBez->Poles (Poles); | |
430 | if (CBez->IsRational()) { | |
431 | Array1OfReal Weights (1, NbPoles); | |
432 | CBez->Weights (Weights); | |
433 | TheCurve = new BSplineCurve (Poles, Weights, Knots, Mults, Degree); | |
434 | } | |
435 | else { | |
436 | TheCurve = new BSplineCurve (Poles, Knots, Mults, Degree); | |
437 | } | |
438 | } | |
439 | else if (C->IsKind (STANDARD_TYPE(Geom2d_BSplineCurve))) { | |
440 | TheCurve = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy()); | |
441 | } | |
442 | ||
443 | else if (C->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) { | |
444 | ||
445 | Standard_Real Tol2d = 1.e-4; | |
446 | GeomAbs_Shape Order = GeomAbs_C2; | |
447 | Standard_Integer MaxSegments = 16, MaxDegree = 14; | |
448 | Geom2dConvert_ApproxCurve ApprCOffs(C, Tol2d, Order, | |
449 | MaxSegments, MaxDegree); | |
450 | if (ApprCOffs.HasResult()) | |
451 | TheCurve = ApprCOffs.Curve(); | |
9775fa61 | 452 | else throw Standard_ConstructionError(); |
7fd59977 | 453 | } |
454 | ||
9775fa61 | 455 | else { throw Standard_DomainError(); } |
7fd59977 | 456 | } |
457 | ||
458 | return TheCurve; | |
459 | } | |
460 | ||
7fd59977 | 461 | //======================================================================= |
41194117 | 462 | //class : law_evaluator |
7fd59977 | 463 | //purpose : |
464 | //======================================================================= | |
465 | ||
41194117 K |
466 | class Geom2dConvert_law_evaluator : public BSplCLib_EvaluatorFunction |
467 | { | |
468 | ||
469 | public: | |
470 | ||
471 | Geom2dConvert_law_evaluator (const Handle(Geom2d_BSplineCurve)& theAncore) | |
472 | : myAncore (theAncore) {} | |
473 | ||
474 | virtual void Evaluate (const Standard_Integer theDerivativeRequest, | |
475 | const Standard_Real* theStartEnd, | |
476 | const Standard_Real theParameter, | |
477 | Standard_Real& theResult, | |
478 | Standard_Integer& theErrorCode) const | |
479 | { | |
480 | theErrorCode = 0; | |
481 | if (!myAncore.IsNull() && | |
482 | theParameter >= theStartEnd[0] && | |
483 | theParameter <= theStartEnd[1] && | |
484 | theDerivativeRequest == 0) | |
485 | { | |
486 | gp_Pnt2d aPoint; | |
487 | myAncore->D0 (theParameter, aPoint); | |
488 | theResult = aPoint.Coord (2); | |
489 | } | |
490 | else | |
491 | theErrorCode = 1; | |
492 | } | |
493 | ||
494 | private: | |
495 | ||
496 | Handle(Geom2d_BSplineCurve) myAncore; | |
497 | ||
498 | }; | |
499 | ||
7fd59977 | 500 | |
501 | //======================================================================= | |
502 | //function : MultNumandDenom | |
503 | //purpose : Multiply two BSpline curves to make one | |
504 | //======================================================================= | |
505 | ||
506 | ||
507 | static Handle(Geom2d_BSplineCurve) MultNumandDenom(const Handle(Geom2d_BSplineCurve)& a , | |
508 | const Handle(Geom2d_BSplineCurve)& BS ) | |
509 | ||
510 | { TColStd_Array1OfReal aKnots(1,a->NbKnots()); | |
511 | TColStd_Array1OfReal BSKnots(1,BS->NbKnots()); | |
512 | TColStd_Array1OfReal BSFlatKnots(1,BS->NbPoles()+BS->Degree()+1); | |
513 | TColStd_Array1OfReal BSWeights(1,BS->NbPoles()); | |
514 | TColStd_Array1OfInteger aMults(1,a->NbKnots()); | |
515 | TColStd_Array1OfInteger BSMults(1,BS->NbKnots()); | |
516 | TColgp_Array1OfPnt2d aPoles(1,a->NbPoles()); | |
517 | TColgp_Array1OfPnt2d BSPoles(1,BS->NbPoles()); | |
518 | Handle(Geom2d_BSplineCurve) res; | |
519 | Handle(TColStd_HArray1OfReal) resKnots; | |
520 | Handle(TColStd_HArray1OfInteger) resMults; | |
521 | Standard_Real start_value,end_value; | |
522 | Standard_Real tolerance=Precision::Confusion(); | |
523 | Standard_Integer resNbPoles,degree, | |
524 | ii,jj, | |
525 | Status; | |
526 | ||
527 | BS->Knots(BSKnots); | |
528 | BS->Multiplicities(BSMults); | |
529 | BS->Poles(BSPoles); | |
530 | BS->Weights(BSWeights); | |
531 | BS->KnotSequence(BSFlatKnots); | |
532 | start_value = BSKnots(1); | |
533 | end_value = BSKnots(BS->NbKnots()); | |
534 | ||
535 | a->Knots(aKnots); | |
536 | a->Poles(aPoles); | |
537 | a->Multiplicities(aMults); | |
538 | BSplCLib::Reparametrize(BS->FirstParameter(),BS->LastParameter(),aKnots); | |
41194117 | 539 | Handle(Geom2d_BSplineCurve) anAncore = new Geom2d_BSplineCurve (aPoles, aKnots, aMults, a->Degree()); |
7fd59977 | 540 | |
541 | BSplCLib::MergeBSplineKnots(tolerance,start_value,end_value, | |
542 | a->Degree(),aKnots,aMults, | |
543 | BS->Degree(),BSKnots,BSMults, | |
544 | resNbPoles,resKnots,resMults); | |
545 | degree=BS->Degree()+a->Degree(); | |
546 | TColgp_Array1OfPnt2d resNumPoles(1,resNbPoles); | |
547 | TColStd_Array1OfReal resDenPoles(1,resNbPoles); | |
548 | TColgp_Array1OfPnt2d resPoles(1,resNbPoles); | |
549 | TColStd_Array1OfReal resFlatKnots(1,resNbPoles+degree+1); | |
550 | BSplCLib::KnotSequence(resKnots->Array1(),resMults->Array1(),resFlatKnots); | |
551 | for (ii=1;ii<=BS->NbPoles();ii++) | |
552 | for (jj=1;jj<=2;jj++) | |
553 | BSPoles(ii).SetCoord(jj,BSPoles(ii).Coord(jj)*BSWeights(ii)); | |
554 | //POP pour NT | |
41194117 | 555 | Geom2dConvert_law_evaluator ev (anAncore); |
7fd59977 | 556 | BSplCLib::FunctionMultiply(ev, |
557 | BS->Degree(), | |
558 | BSFlatKnots, | |
559 | BSPoles, | |
560 | resFlatKnots, | |
561 | degree, | |
562 | resNumPoles, | |
563 | Status); | |
564 | BSplCLib::FunctionMultiply(ev, | |
565 | BS->Degree(), | |
566 | BSFlatKnots, | |
567 | BSWeights, | |
568 | resFlatKnots, | |
569 | degree, | |
570 | resDenPoles, | |
571 | Status); | |
572 | // BSplCLib::FunctionMultiply(law_evaluator, | |
573 | // BS->Degree(), | |
574 | // BSFlatKnots, | |
575 | // BSPoles, | |
576 | // resFlatKnots, | |
577 | // degree, | |
578 | // resNumPoles, | |
579 | // Status); | |
580 | // BSplCLib::FunctionMultiply(law_evaluator, | |
581 | // BS->Degree(), | |
582 | // BSFlatKnots, | |
583 | // BSWeights, | |
584 | // resFlatKnots, | |
585 | // degree, | |
586 | // resDenPoles, | |
587 | // Status); | |
588 | for (ii=1;ii<=resNbPoles;ii++) | |
589 | for(jj=1;jj<=2;jj++) | |
590 | resPoles(ii).SetCoord(jj,resNumPoles(ii).Coord(jj)/resDenPoles(ii)); | |
591 | res = new Geom2d_BSplineCurve(resPoles,resDenPoles,resKnots->Array1(),resMults->Array1(),degree); | |
592 | return res; | |
593 | } | |
594 | ||
595 | //======================================================================= | |
596 | //function : Pretreatment | |
597 | //purpose : Put the two first and two last weigths at one if they are | |
598 | // equal | |
599 | //======================================================================= | |
600 | ||
601 | static void Pretreatment(TColGeom2d_Array1OfBSplineCurve& tab) | |
602 | ||
603 | {Standard_Integer i,j; | |
604 | Standard_Real a; | |
605 | ||
606 | for (i=0;i<=(tab.Length()-1);i++){ | |
607 | if (tab(i)->IsRational()) { | |
608 | a=tab(i)->Weight(1) ; | |
609 | if ((tab(i)->Weight(2)==a)&& | |
610 | (tab(i)->Weight(tab(i)->NbPoles()-1)==a) && | |
611 | (tab(i)->Weight(tab(i)->NbPoles())==a)) | |
612 | ||
613 | for (j=1;j<=tab(i)->NbPoles();j++) | |
614 | tab(i)->SetWeight(j,tab(i)->Weight(j)/a) ; | |
615 | } | |
616 | } | |
617 | } | |
618 | ||
619 | //======================================================================= | |
620 | //function : NeedToBeTreated | |
621 | //purpose : Say if the BSpline is rationnal and if the two first and two | |
622 | // last weigths are different | |
623 | //======================================================================= | |
624 | ||
625 | static Standard_Boolean NeedToBeTreated(const Handle(Geom2d_BSplineCurve)& BS) | |
626 | ||
627 | { | |
628 | TColStd_Array1OfReal tabWeights(1,BS->NbPoles()); | |
629 | if (BS->IsRational()) { | |
630 | BS->Weights(tabWeights); | |
631 | if ((BSplCLib::IsRational(tabWeights,1,BS->NbPoles()))&& | |
632 | ((BS->Weight(1)<(1-Precision::Confusion()))|| | |
633 | (BS->Weight(1)>(1+Precision::Confusion()))|| | |
634 | (BS->Weight(2)<(1-Precision::Confusion()))|| | |
635 | (BS->Weight(2)>(1+Precision::Confusion()))|| | |
636 | (BS->Weight(BS->NbPoles()-1)<(1-Precision::Confusion()))|| | |
637 | (BS->Weight(BS->NbPoles()-1)>(1+Precision::Confusion()))|| | |
638 | (BS->Weight(BS->NbPoles())<(1-Precision::Confusion()))|| | |
639 | (BS->Weight(BS->NbPoles())>(1+Precision::Confusion())))) | |
640 | return Standard_True; | |
641 | else | |
642 | return Standard_False; | |
643 | } | |
644 | else | |
645 | return Standard_False ; | |
646 | ||
647 | } | |
648 | ||
649 | //======================================================================= | |
650 | //function : Need2DegRepara | |
651 | //purpose : in the case of wire closed G1 it says if you will to use a | |
652 | // two degree reparametrisation to close it C1 | |
653 | //======================================================================= | |
654 | ||
655 | static Standard_Boolean Need2DegRepara(const TColGeom2d_Array1OfBSplineCurve& tab) | |
656 | ||
657 | {Standard_Integer i; | |
658 | gp_Vec2d Vec1,Vec2; | |
659 | gp_Pnt2d Pint; | |
660 | Standard_Real Rapport=1.0e0; | |
661 | ||
662 | for (i=0;i<=tab.Length()-2;i++){ | |
663 | tab(i+1)->D1(tab(i+1)->FirstParameter(),Pint,Vec1); | |
664 | tab(i)->D1(tab(i)->LastParameter(),Pint,Vec2); | |
665 | Rapport=Rapport*Vec2.Magnitude()/Vec1.Magnitude(); | |
666 | } | |
667 | if ((Rapport<=(1.0e0 +Precision::Confusion()))&&(Rapport>=(1.0e0-Precision::Confusion()))) | |
668 | return Standard_False; | |
669 | else | |
670 | return Standard_True; | |
671 | } | |
672 | ||
673 | //======================================================================= | |
674 | //function : Indexmin | |
675 | //purpose : Give the index of the curve which has the lowest degree | |
676 | //======================================================================= | |
677 | ||
678 | static Standard_Integer Indexmin(const TColGeom2d_Array1OfBSplineCurve& tab) | |
679 | { | |
680 | Standard_Integer i,index=0,degree; | |
681 | ||
682 | degree=tab(0)->Degree(); | |
683 | for (i=0;i<=tab.Length()-1;i++) | |
684 | if (tab(i)->Degree()<=degree){ | |
685 | degree=tab(i)->Degree(); | |
686 | index=i; | |
687 | } | |
688 | return index; | |
689 | } | |
690 | ||
691 | //======================================================================= | |
692 | //function : NewTabClosedG1 | |
693 | //purpose : | |
694 | //======================================================================= | |
695 | ||
696 | static void ReorderArrayOfG1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves, | |
697 | TColStd_Array1OfReal& ArrayOfToler, | |
698 | TColStd_Array1OfBoolean& tabG1, | |
699 | const Standard_Integer StartIndex, | |
700 | const Standard_Real ClosedTolerance) | |
701 | ||
702 | {Standard_Integer i; | |
703 | TColGeom2d_Array1OfBSplineCurve ArraybisOfCurves(0,ArrayOfCurves.Length()-1); | |
704 | TColStd_Array1OfReal ArraybisOfToler(0,ArrayOfToler.Length()-1); | |
705 | TColStd_Array1OfBoolean tabbisG1(0,tabG1.Length()-1); | |
706 | ||
707 | for (i=0;i<=ArrayOfCurves.Length()-1;i++){ | |
708 | if (i!=ArrayOfCurves.Length()-1){ | |
709 | ArraybisOfCurves(i)=ArrayOfCurves(i); | |
710 | ArraybisOfToler(i)=ArrayOfToler(i); | |
711 | tabbisG1(i)=tabG1(i); | |
712 | } | |
713 | else | |
714 | ArraybisOfCurves(i)=ArrayOfCurves(i); | |
715 | } | |
716 | ||
717 | for (i=0;i<=(ArrayOfCurves.Length()-(StartIndex+2));i++){ | |
718 | ArrayOfCurves(i)=ArraybisOfCurves(i+StartIndex+1); | |
719 | if (i!=(ArrayOfCurves.Length()-(StartIndex+2))){ | |
720 | ArrayOfToler(i)=ArraybisOfToler(i+StartIndex+1); | |
721 | tabG1(i)=tabbisG1(i+StartIndex+1); | |
722 | } | |
723 | } | |
724 | ||
725 | ArrayOfToler(ArrayOfCurves.Length()-(StartIndex+2))=ClosedTolerance; | |
726 | tabG1(ArrayOfCurves.Length()-(StartIndex+2))=Standard_True; | |
727 | ||
728 | for (i=(ArrayOfCurves.Length()-(StartIndex+1));i<=(ArrayOfCurves.Length()-1);i++){ | |
729 | if (i!=ArrayOfCurves.Length()-1){ | |
730 | ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1))); | |
731 | ArrayOfToler(i)=ArraybisOfToler(i-(ArrayOfCurves.Length()-(StartIndex+1))); | |
732 | tabG1(i)=tabbisG1(i-(ArrayOfCurves.Length()-(StartIndex+1))); | |
733 | } | |
734 | else | |
735 | ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1))); | |
736 | } | |
737 | } | |
738 | ||
739 | //======================================================================= | |
740 | //function : GeomAbsToInteger | |
741 | //purpose : | |
742 | //======================================================================= | |
743 | ||
744 | static Standard_Integer GeomAbsToInteger(const GeomAbs_Shape gcont) | |
745 | { | |
746 | Standard_Integer cont=0 ; | |
747 | switch (gcont) { | |
748 | case GeomAbs_C0 : | |
749 | cont = 0 ; | |
750 | break ; | |
751 | case GeomAbs_G1 : | |
752 | cont = 1 ; | |
753 | break ; | |
754 | case GeomAbs_C1 : | |
755 | cont = 2 ; | |
756 | break ; | |
757 | case GeomAbs_G2 : | |
758 | cont = 3 ; | |
759 | break ; | |
760 | case GeomAbs_C2 : | |
761 | cont = 4 ; | |
762 | break ; | |
763 | case GeomAbs_C3 : | |
764 | cont = 5 ; | |
765 | break ; | |
766 | case GeomAbs_CN : | |
767 | cont = 6 ; | |
768 | break ; | |
769 | } | |
770 | return cont ; | |
771 | } | |
772 | //======================================================================= | |
773 | //function : Continuity | |
774 | //purpose : | |
775 | //======================================================================= | |
776 | ||
777 | static GeomAbs_Shape Continuity(const Handle(Geom2d_Curve)& C1, | |
778 | const Handle(Geom2d_Curve)& C2, | |
779 | const Standard_Real u1, | |
780 | const Standard_Real u2, | |
781 | const Standard_Boolean r1, | |
782 | const Standard_Boolean r2, | |
783 | const Standard_Real tl, | |
784 | const Standard_Real ta) | |
785 | { | |
786 | GeomAbs_Shape cont = GeomAbs_C0; | |
787 | Standard_Integer index1, | |
788 | index2 ; | |
789 | Standard_Real tolerance,value ; | |
790 | // Standard_Boolean fini = Standard_False; | |
791 | gp_Vec2d d1,d2; | |
792 | // gp_Dir2d dir1,dir2; | |
793 | gp_Pnt2d point1, point2 ; | |
794 | Standard_Integer cont1, cont2 ; | |
795 | GeomAbs_Shape gcont1 = C1->Continuity(), gcont2 = C2->Continuity(); | |
796 | cont1 = GeomAbsToInteger(gcont1) ; | |
797 | cont2 = GeomAbsToInteger(gcont2) ; | |
798 | ||
799 | Handle(Geom2d_Curve) aCurve1 = C1 ; | |
800 | Handle(Geom2d_Curve) aCurve2 = C2 ; | |
801 | if (C1->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))){ | |
802 | Handle(Geom2d_TrimmedCurve) aTrimmed = Handle(Geom2d_TrimmedCurve) ::DownCast(aCurve1) ; | |
803 | aCurve1 = aTrimmed->BasisCurve() ; | |
804 | } | |
805 | if (C2->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))){ | |
806 | Handle(Geom2d_TrimmedCurve) aTrimmed = Handle(Geom2d_TrimmedCurve) ::DownCast(aCurve2) ; | |
807 | aCurve2 = aTrimmed->BasisCurve() ; | |
808 | } | |
809 | if (aCurve1->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))){ | |
810 | Handle(Geom2d_BSplineCurve) BSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(aCurve1) ; | |
811 | BSplineCurve->Resolution(tl, | |
812 | tolerance) ; | |
813 | BSplineCurve->LocateU(u1, | |
814 | tolerance, | |
815 | index1, | |
816 | index2) ; | |
817 | ||
818 | if (index1 > 1 && index2 < BSplineCurve->NbKnots() && index1 == index2) { | |
819 | cont1 = BSplineCurve->Degree() - BSplineCurve->Multiplicity(index1) ; | |
820 | } | |
821 | else { | |
822 | cont1 = 5 ; | |
823 | } | |
824 | } | |
825 | if (aCurve2->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))){ | |
826 | Handle(Geom2d_BSplineCurve) BSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(aCurve2) ; | |
827 | BSplineCurve->Resolution(tl, | |
828 | tolerance) ; | |
829 | BSplineCurve->LocateU(u2, | |
830 | tolerance, | |
831 | index1, | |
832 | index2) ; | |
833 | ||
834 | if (index1 > 1 && index2 < BSplineCurve->NbKnots() && index1 == index2) { | |
835 | cont2 = BSplineCurve->Degree() - BSplineCurve->Multiplicity(index1) ; | |
836 | } | |
837 | else { | |
838 | cont2 = 5 ; | |
839 | } | |
840 | } | |
841 | aCurve1->D1(u1, | |
842 | point1, | |
843 | d1) ; | |
844 | aCurve2->D1(u2, | |
845 | point2, | |
846 | d2) ; | |
847 | if (point1.SquareDistance(point2) <= tl * tl) { | |
848 | if (cont1 != 0 && | |
849 | cont2 != 0) { | |
850 | ||
851 | if (d1.SquareMagnitude() >= tl * tl && | |
852 | d2.SquareMagnitude() >= tl * tl) { | |
853 | if (r1) { | |
854 | d1.SetCoord(-d1.X(),-d1.Y()) ; | |
855 | } | |
856 | if (r2) { | |
857 | d2.SetCoord(-d2.X(),-d2.Y()) ; | |
858 | } | |
859 | value = d1.Dot(d2) ; | |
860 | if ((d1.Magnitude()<=(d2.Magnitude()+tl))&& | |
861 | (d1.Magnitude()>=(d2.Magnitude()-tl))&& | |
862 | (value/(d1.Magnitude()*d2.Magnitude()) >= 1.0e0 - ta * ta)) { | |
863 | cont = GeomAbs_C1 ; | |
864 | } | |
865 | else { | |
866 | d1.Normalize() ; | |
867 | d2.Normalize() ; | |
868 | value = Abs(d1.Dot(d2)) ; | |
869 | if (value >= 1.0e0 - ta * ta) { | |
870 | cont = GeomAbs_G1 ; | |
871 | } | |
872 | } | |
873 | ||
874 | } | |
875 | } | |
876 | } | |
877 | else | |
9775fa61 | 878 | throw Standard_Failure("Courbes non jointives"); |
7fd59977 | 879 | return cont ; |
880 | } | |
881 | ||
882 | //======================================================================= | |
883 | //function : Continuity | |
884 | //purpose : | |
885 | //======================================================================= | |
886 | ||
887 | static GeomAbs_Shape Continuity(const Handle(Geom2d_Curve)& C1, | |
888 | const Handle(Geom2d_Curve)& C2, | |
889 | const Standard_Real u1, | |
890 | const Standard_Real u2, | |
891 | const Standard_Boolean r1, | |
892 | const Standard_Boolean r2) | |
893 | { | |
894 | return Continuity(C1,C2,u1,u2,r1,r2, | |
895 | Precision::Confusion(),Precision::Angular()); | |
896 | } | |
897 | ||
898 | //======================================================================= | |
41194117 | 899 | //class :reparameterise_evaluator |
7fd59977 | 900 | //purpose : |
901 | //======================================================================= | |
902 | ||
41194117 K |
903 | class Geom2dConvert_reparameterise_evaluator : public BSplCLib_EvaluatorFunction |
904 | { | |
905 | ||
906 | public: | |
907 | ||
908 | Geom2dConvert_reparameterise_evaluator (const Standard_Real thePolynomialCoefficient[3]) | |
909 | { | |
910 | memcpy(myPolynomialCoefficient, thePolynomialCoefficient, sizeof(myPolynomialCoefficient)); | |
911 | } | |
912 | ||
913 | virtual void Evaluate (const Standard_Integer theDerivativeRequest, | |
914 | const Standard_Real* /*theStartEnd*/, | |
915 | const Standard_Real theParameter, | |
916 | Standard_Real& theResult, | |
917 | Standard_Integer& theErrorCode) const | |
918 | { | |
919 | theErrorCode = 0; | |
920 | PLib::EvalPolynomial (theParameter, | |
921 | theDerivativeRequest, | |
922 | 2, | |
923 | 1, | |
924 | *((Standard_Real* )myPolynomialCoefficient), // function really only read values from this array | |
925 | theResult); | |
926 | } | |
927 | ||
928 | private: | |
929 | ||
930 | Standard_Real myPolynomialCoefficient[3]; | |
931 | ||
932 | }; | |
7fd59977 | 933 | |
934 | //======================================================================= | |
935 | //function : ConcatG1 | |
936 | //purpose : | |
937 | //======================================================================= | |
938 | ||
939 | void Geom2dConvert::ConcatG1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves, | |
940 | const TColStd_Array1OfReal& ArrayOfToler, | |
941 | Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated, | |
942 | const Standard_Boolean ClosedFlag, | |
943 | const Standard_Real ClosedTolerance) | |
944 | ||
945 | {Standard_Integer nb_curve=ArrayOfCurves.Length(), | |
946 | nb_vertexG1, | |
947 | nb_group=0, | |
948 | index=0,i,ii,j,jj, | |
949 | indexmin, | |
950 | nb_vertex_group0=0; | |
951 | Standard_Real lambda, //coeff de raccord G1 | |
952 | First,PreLast=0; | |
953 | gp_Vec2d Vec1,Vec2; //vecteurs tangents consecutifs | |
954 | gp_Pnt2d Pint; | |
955 | Handle(Geom2d_BSplineCurve) Curve1,Curve2; | |
956 | TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //tableau de continuite G1 aux raccords | |
957 | TColStd_Array1OfReal local_tolerance(0, | |
958 | ArrayOfToler.Length()-1) ; | |
959 | ||
960 | for (i= 0; i < ArrayOfToler.Length() ; i++) { | |
961 | local_tolerance(i) = ArrayOfToler(i) ; | |
962 | } | |
963 | for (i=0 ;i<nb_curve; i++){ | |
964 | if (i >= 1){ | |
965 | First=ArrayOfCurves(i)->FirstParameter(); | |
966 | if (Continuity(ArrayOfCurves(i-1), | |
967 | ArrayOfCurves(i), | |
968 | PreLast,First, | |
969 | Standard_True, | |
970 | Standard_True)<GeomAbs_C0) | |
9775fa61 | 971 | throw Standard_ConstructionError("Geom2dConvert curves not C0") ; //renvoi d'une erreur |
7fd59977 | 972 | else{ |
973 | if (Continuity(ArrayOfCurves(i-1), | |
974 | ArrayOfCurves(i), | |
975 | PreLast,First, | |
976 | Standard_True, | |
977 | Standard_True)>=GeomAbs_G1) | |
978 | tabG1(i-1)=Standard_True; //True=Continuite G1 | |
979 | else | |
980 | tabG1(i-1)=Standard_False; | |
981 | } | |
982 | } | |
983 | PreLast=ArrayOfCurves(i)->LastParameter(); | |
984 | } | |
985 | ||
986 | ||
987 | while (index<=nb_curve-1){ //determination des caracteristiques du Wire | |
988 | nb_vertexG1=0; | |
989 | while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True)) | |
990 | nb_vertexG1++; | |
991 | nb_group++; | |
992 | if (index==0) | |
993 | nb_vertex_group0=nb_vertexG1; | |
994 | index=index+1+nb_vertexG1; | |
995 | } | |
996 | ||
997 | if ((ClosedFlag)&&(nb_group!=1)){ //rearrangement du tableau | |
998 | nb_group--; | |
999 | ReorderArrayOfG1(ArrayOfCurves, | |
1000 | local_tolerance, | |
1001 | tabG1, | |
1002 | nb_vertex_group0, | |
1003 | ClosedTolerance); | |
1004 | } | |
1005 | ||
1006 | ArrayOfConcatenated = new | |
1007 | TColGeom2d_HArray1OfBSplineCurve(0,nb_group-1); | |
1008 | ||
1009 | Standard_Boolean fusion; | |
1010 | // Standard_Integer k=0; | |
1011 | index=0; | |
1012 | Pretreatment(ArrayOfCurves); | |
1013 | ||
41194117 K |
1014 | Standard_Real aPolynomialCoefficient[3]; |
1015 | ||
7fd59977 | 1016 | if ((nb_group==1) && (ClosedFlag)){ //traitement d'un cas particulier |
1017 | indexmin=Indexmin(ArrayOfCurves); | |
1018 | if (indexmin!=(ArrayOfCurves.Length()-1)) | |
1019 | ReorderArrayOfG1(ArrayOfCurves, | |
1020 | local_tolerance, | |
1021 | tabG1, | |
1022 | indexmin, | |
1023 | ClosedTolerance); | |
1024 | Curve2=ArrayOfCurves(0); | |
1025 | for (j=1;j<=nb_curve-1;j++){ //boucle secondaire a l'interieur de chaque groupe | |
1026 | Curve1=ArrayOfCurves(j); | |
1027 | if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){ | |
d30895f5 | 1028 | const Standard_Integer aNewCurveDegree = Min(2 * Curve1->Degree(), Geom2d_BSplineCurve::MaxDegree()); |
7fd59977 | 1029 | Curve2->D1(Curve2->LastParameter(),Pint,Vec1); |
1030 | Curve1->D1(Curve1->FirstParameter(),Pint,Vec2); | |
1031 | lambda=Vec2.Magnitude()/Vec1.Magnitude(); | |
1032 | TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots()); | |
1033 | Curve1->Knots(KnotC1); | |
1034 | Curve1->D1(Curve1->LastParameter(),Pint,Vec2); | |
1035 | ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1); | |
1036 | Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude(); | |
1037 | Standard_Real tmax,a,b,c, | |
1038 | umin=Curve1->FirstParameter(),umax=Curve1->LastParameter(); | |
1039 | tmax=2*lambda*(umax-umin)/(1+lambda*lambda2); | |
1040 | a=(lambda*lambda2-1)/(2*lambda*tmax); | |
41194117 | 1041 | aPolynomialCoefficient[2] = a; |
7fd59977 | 1042 | b=(1/lambda); |
41194117 | 1043 | aPolynomialCoefficient[1] = b; |
7fd59977 | 1044 | c=umin; |
41194117 | 1045 | aPolynomialCoefficient[0] = c; |
7fd59977 | 1046 | TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1); |
1047 | TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots()); | |
1048 | Curve1->Multiplicities(KnotC1Mults); | |
1049 | BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots); | |
1050 | KnotC1(1)=0.0; | |
1051 | for (ii=2;ii<=KnotC1.Length();ii++) { | |
1052 | // KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); | |
1053 | KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); //ifv 17.05.00 buc60667 | |
1054 | } | |
1055 | TColgp_Array1OfPnt2d Curve1Poles(1,Curve1->NbPoles()); | |
1056 | Curve1->Poles(Curve1Poles); | |
1057 | ||
1058 | for (ii=1;ii<=Curve1->NbKnots();ii++) | |
1059 | KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii)); | |
1060 | ||
1061 | TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots())); | |
1062 | ||
1063 | BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots); | |
1064 | TColgp_Array1OfPnt2d NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1)); | |
1065 | Standard_Integer Status; | |
1066 | TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles()); | |
1067 | Curve1->Weights(Curve1Weights); | |
1068 | for (ii=1;ii<=Curve1->NbPoles();ii++) | |
1069 | for (jj=1;jj<=2;jj++) | |
1070 | Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii)); | |
1071 | //POP pour NT | |
41194117 | 1072 | Geom2dConvert_reparameterise_evaluator ev (aPolynomialCoefficient); |
7fd59977 | 1073 | BSplCLib::FunctionReparameterise(ev, |
1074 | Curve1->Degree(), | |
1075 | Curve1FlatKnots, | |
1076 | Curve1Poles, | |
1077 | FlatKnots, | |
d30895f5 | 1078 | aNewCurveDegree, |
7fd59977 | 1079 | NewPoles, |
1080 | Status | |
1081 | ); | |
1082 | TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1)); | |
1083 | BSplCLib::FunctionReparameterise(ev, | |
1084 | Curve1->Degree(), | |
1085 | Curve1FlatKnots, | |
1086 | Curve1Weights, | |
1087 | FlatKnots, | |
d30895f5 | 1088 | aNewCurveDegree, |
7fd59977 | 1089 | NewWeights, |
1090 | Status | |
1091 | ); | |
1092 | // BSplCLib::FunctionReparameterise(reparameterise_evaluator, | |
1093 | // Curve1->Degree(), | |
1094 | // Curve1FlatKnots, | |
1095 | // Curve1Poles, | |
1096 | // FlatKnots, | |
1097 | // 2*Curve1->Degree(), | |
1098 | // NewPoles, | |
1099 | // Status | |
1100 | // ); | |
1101 | // TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1)); | |
1102 | // BSplCLib::FunctionReparameterise(reparameterise_evaluator, | |
1103 | // Curve1->Degree(), | |
1104 | // Curve1FlatKnots, | |
1105 | // Curve1Weights, | |
1106 | // FlatKnots, | |
1107 | // 2*Curve1->Degree(), | |
1108 | // NewWeights, | |
1109 | // Status | |
1110 | // ); | |
1111 | for (ii=1;ii<=NewPoles.Length();ii++) | |
1112 | for (jj=1;jj<=2;jj++) | |
1113 | NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii)); | |
d30895f5 | 1114 | Curve1 = new Geom2d_BSplineCurve(NewPoles, NewWeights, KnotC1, KnotC1Mults, aNewCurveDegree); |
7fd59977 | 1115 | } |
a9dde4a3 | 1116 | Geom2dConvert_CompCurveToBSplineCurve C(Curve2); |
7fd59977 | 1117 | fusion=C.Add(Curve1, |
1118 | local_tolerance(j-1)); //fusion de deux courbes adjacentes | |
1119 | if (fusion==Standard_False) | |
9775fa61 | 1120 | throw Standard_ConstructionError("Geom2dConvert Concatenation Error") ; |
7fd59977 | 1121 | Curve2=C.BSplineCurve(); |
1122 | } | |
7fd59977 | 1123 | Curve2->SetPeriodic(); //1 seule courbe C1 |
96a95605 | 1124 | Curve2->RemoveKnot(Curve2->LastUKnotIndex(), |
7fd59977 | 1125 | Curve2->Multiplicity(Curve2->LastUKnotIndex())-1, |
1126 | Precision::Confusion()); | |
1127 | ArrayOfConcatenated->SetValue(0,Curve2); | |
1128 | } | |
1129 | ||
1130 | else | |
1131 | for (i=0;i<=nb_group-1;i++){ //boucle principale sur chaque groupe de | |
1132 | nb_vertexG1=0; //continuite interne G1 | |
1133 | ||
1134 | while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True)) | |
1135 | nb_vertexG1++; | |
1136 | ||
1137 | for (j=index;j<=index+nb_vertexG1;j++){ //boucle secondaire a l'interieur de chaque groupe | |
1138 | Curve1=ArrayOfCurves(j); | |
1139 | ||
1140 | if (index==j) //initialisation en debut de groupe | |
1141 | ArrayOfConcatenated->SetValue(i,Curve1); | |
1142 | else{ | |
a9dde4a3 | 1143 | Geom2dConvert_CompCurveToBSplineCurve C(ArrayOfConcatenated->Value(i)); |
7fd59977 | 1144 | fusion=C.Add(Curve1,ArrayOfToler(j-1)); //fusion de deux courbes adjacentes |
1145 | if (fusion==Standard_False) | |
9775fa61 | 1146 | throw Standard_ConstructionError("Geom2dConvert Concatenation Error") ; |
7fd59977 | 1147 | ArrayOfConcatenated->SetValue(i,C.BSplineCurve()); |
1148 | } | |
1149 | } | |
1150 | index=index+1+nb_vertexG1; | |
1151 | } | |
1152 | } | |
1153 | //======================================================================= | |
1154 | //function : ConcatC1 | |
1155 | //purpose : | |
1156 | //======================================================================= | |
1157 | ||
1158 | void Geom2dConvert::ConcatC1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves, | |
1159 | const TColStd_Array1OfReal& ArrayOfToler, | |
1160 | Handle(TColStd_HArray1OfInteger)& ArrayOfIndices, | |
1161 | Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated, | |
1162 | const Standard_Boolean ClosedFlag, | |
1163 | const Standard_Real ClosedTolerance) | |
1164 | { | |
1165 | ConcatC1(ArrayOfCurves, | |
1166 | ArrayOfToler, | |
1167 | ArrayOfIndices, | |
1168 | ArrayOfConcatenated, | |
1169 | ClosedFlag, | |
1170 | ClosedTolerance, | |
1171 | Precision::Angular()) ; | |
1172 | } | |
1173 | //======================================================================= | |
1174 | //function : ConcatC1 | |
1175 | //purpose : | |
1176 | //======================================================================= | |
1177 | ||
1178 | void Geom2dConvert::ConcatC1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves, | |
1179 | const TColStd_Array1OfReal& ArrayOfToler, | |
1180 | Handle(TColStd_HArray1OfInteger)& ArrayOfIndices, | |
1181 | Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated, | |
1182 | const Standard_Boolean ClosedFlag, | |
1183 | const Standard_Real ClosedTolerance, | |
1184 | const Standard_Real AngularTolerance) | |
1185 | ||
1186 | {Standard_Integer nb_curve=ArrayOfCurves.Length(), | |
1187 | nb_vertexG1, | |
1188 | nb_group=0, | |
1189 | index=0,i,ii,j,jj, | |
1190 | indexmin, | |
1191 | nb_vertex_group0=0; | |
1192 | Standard_Real lambda, //coeff de raccord G1 | |
1193 | First,PreLast=0; | |
1194 | gp_Vec2d Vec1,Vec2; //vecteurs tangents consecutifs | |
1195 | gp_Pnt2d Pint; | |
1196 | Handle(Geom2d_BSplineCurve) Curve1,Curve2; | |
1197 | TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //tableau de continuite G1 aux raccords | |
1198 | TColStd_Array1OfReal local_tolerance(0, | |
1199 | ArrayOfToler.Length()-1) ; | |
1200 | ||
1201 | ||
1202 | ||
1203 | for (i=0 ; i < ArrayOfToler.Length() ; i++) { | |
1204 | local_tolerance(i) = ArrayOfToler(i) ; | |
1205 | } | |
1206 | for (i=0 ;i<nb_curve; i++){ | |
1207 | if (i >= 1){ | |
1208 | First=ArrayOfCurves(i)->FirstParameter(); | |
1209 | if (Continuity(ArrayOfCurves(i-1), | |
1210 | ArrayOfCurves(i), | |
1211 | PreLast,First, | |
1212 | Standard_True, | |
1213 | Standard_True, | |
1214 | ArrayOfToler(i-1), | |
1215 | AngularTolerance)<GeomAbs_C0) | |
9775fa61 | 1216 | throw Standard_ConstructionError("Geom2dConvert curves not C0") ; //renvoi d'une erreur |
7fd59977 | 1217 | else{ |
1218 | if (Continuity(ArrayOfCurves(i-1), | |
1219 | ArrayOfCurves(i), | |
1220 | PreLast, | |
1221 | First, | |
1222 | Standard_True, | |
1223 | Standard_True, | |
1224 | ArrayOfToler(i-1), | |
1225 | AngularTolerance)>=GeomAbs_G1) | |
1226 | tabG1(i-1)=Standard_True; //True=Continuite G1 | |
1227 | else | |
1228 | tabG1(i-1)=Standard_False; | |
1229 | } | |
1230 | } | |
1231 | PreLast=ArrayOfCurves(i)->LastParameter(); | |
1232 | } | |
1233 | ||
1234 | ||
1235 | while (index<=nb_curve-1){ //determination des caracteristiques du Wire | |
1236 | nb_vertexG1=0; | |
1237 | while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True)) | |
1238 | nb_vertexG1++; | |
1239 | nb_group++; | |
1240 | if (index==0) | |
1241 | nb_vertex_group0=nb_vertexG1; | |
1242 | index=index+1+nb_vertexG1; | |
1243 | } | |
1244 | ||
1245 | if ((ClosedFlag)&&(nb_group!=1)){ //rearrangement du tableau | |
1246 | nb_group--; | |
1247 | ReorderArrayOfG1(ArrayOfCurves, | |
1248 | local_tolerance, | |
1249 | tabG1, | |
1250 | nb_vertex_group0, | |
1251 | ClosedTolerance); | |
1252 | } | |
1253 | ||
1254 | ArrayOfIndices = new TColStd_HArray1OfInteger(0,nb_group); | |
1255 | ArrayOfConcatenated = new TColGeom2d_HArray1OfBSplineCurve(0,nb_group-1); | |
1256 | ||
1257 | Standard_Boolean fusion; | |
1258 | Standard_Integer k=0; | |
1259 | index=0; | |
1260 | Pretreatment(ArrayOfCurves); | |
41194117 | 1261 | Standard_Real aPolynomialCoefficient[3]; |
7fd59977 | 1262 | |
1263 | if ((nb_group==1) && (ClosedFlag)){ //traitement d'un cas particulier | |
1264 | ArrayOfIndices->SetValue(0,0); | |
1265 | ArrayOfIndices->SetValue(1,0); | |
1266 | indexmin=Indexmin(ArrayOfCurves); | |
1267 | if (indexmin!=(ArrayOfCurves.Length()-1)) | |
1268 | ReorderArrayOfG1(ArrayOfCurves, | |
1269 | local_tolerance, | |
1270 | tabG1, | |
1271 | indexmin, | |
1272 | ClosedTolerance); | |
1273 | for (j=0;j<=nb_curve-1;j++){ //boucle secondaire a l'interieur de chaque groupe | |
1274 | if (NeedToBeTreated(ArrayOfCurves(j))) { | |
1275 | Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j)); | |
1276 | } | |
1277 | else | |
1278 | Curve1=ArrayOfCurves(j); | |
1279 | ||
d30895f5 | 1280 | const Standard_Integer aNewCurveDegree = Min(2 * Curve1->Degree(), Geom2d_BSplineCurve::MaxDegree()); |
1281 | ||
7fd59977 | 1282 | if (j==0) //initialisation en debut de groupe |
1283 | Curve2=Curve1; | |
1284 | else{ | |
1285 | if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){ | |
1286 | Curve2->D1(Curve2->LastParameter(),Pint,Vec1); | |
1287 | Curve1->D1(Curve1->FirstParameter(),Pint,Vec2); | |
1288 | lambda=Vec2.Magnitude()/Vec1.Magnitude(); | |
1289 | TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots()); | |
1290 | Curve1->Knots(KnotC1); | |
1291 | Curve1->D1(Curve1->LastParameter(),Pint,Vec2); | |
1292 | ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1); | |
1293 | Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude(); | |
1294 | Standard_Real tmax,a,b,c, | |
1295 | umin=Curve1->FirstParameter(),umax=Curve1->LastParameter(); | |
1296 | tmax=2*lambda*(umax-umin)/(1+lambda*lambda2); | |
1297 | a=(lambda*lambda2-1)/(2*lambda*tmax); | |
41194117 | 1298 | aPolynomialCoefficient[2] = a; |
7fd59977 | 1299 | b=(1/lambda); |
41194117 | 1300 | aPolynomialCoefficient[1] = b; |
7fd59977 | 1301 | c=umin; |
41194117 | 1302 | aPolynomialCoefficient[0] = c; |
7fd59977 | 1303 | TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1); |
1304 | TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots()); | |
1305 | Curve1->Multiplicities(KnotC1Mults); | |
1306 | BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots); | |
1307 | KnotC1(1)=0.0; | |
1308 | for (ii=2;ii<=KnotC1.Length();ii++) { | |
1309 | // KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); | |
1310 | KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); //ifv 17.05.00 buc60667 | |
1311 | } | |
1312 | TColgp_Array1OfPnt2d Curve1Poles(1,Curve1->NbPoles()); | |
1313 | Curve1->Poles(Curve1Poles); | |
1314 | ||
1315 | for (ii=1;ii<=Curve1->NbKnots();ii++) | |
1316 | KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii)); | |
1317 | ||
1318 | TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots())); | |
1319 | ||
1320 | BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots); | |
d30895f5 | 1321 | TColgp_Array1OfPnt2d NewPoles(1, FlatKnots.Length() - (aNewCurveDegree + 1)); |
7fd59977 | 1322 | Standard_Integer Status; |
1323 | TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles()); | |
1324 | Curve1->Weights(Curve1Weights); | |
1325 | for (ii=1;ii<=Curve1->NbPoles();ii++) | |
1326 | for (jj=1;jj<=2;jj++) | |
1327 | Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii)); | |
1328 | //POP pour NT | |
41194117 | 1329 | Geom2dConvert_reparameterise_evaluator ev (aPolynomialCoefficient); |
7fd59977 | 1330 | // BSplCLib::FunctionReparameterise(reparameterise_evaluator, |
1331 | BSplCLib::FunctionReparameterise(ev, | |
1332 | Curve1->Degree(), | |
1333 | Curve1FlatKnots, | |
1334 | Curve1Poles, | |
1335 | FlatKnots, | |
d30895f5 | 1336 | aNewCurveDegree, |
7fd59977 | 1337 | NewPoles, |
1338 | Status | |
1339 | ); | |
d30895f5 | 1340 | TColStd_Array1OfReal NewWeights(1, FlatKnots.Length() - (aNewCurveDegree + 1)); |
7fd59977 | 1341 | // BSplCLib::FunctionReparameterise(reparameterise_evaluator, |
1342 | BSplCLib::FunctionReparameterise(ev, | |
1343 | Curve1->Degree(), | |
1344 | Curve1FlatKnots, | |
1345 | Curve1Weights, | |
1346 | FlatKnots, | |
d30895f5 | 1347 | aNewCurveDegree, |
7fd59977 | 1348 | NewWeights, |
1349 | Status | |
1350 | ); | |
1351 | for (ii=1;ii<=NewPoles.Length();ii++) { | |
1352 | for (jj=1;jj<=2;jj++) | |
1353 | NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii)); | |
1354 | } | |
d30895f5 | 1355 | Curve1 = new Geom2d_BSplineCurve(NewPoles, NewWeights, KnotC1, KnotC1Mults, aNewCurveDegree); |
7fd59977 | 1356 | } |
a9dde4a3 | 1357 | Geom2dConvert_CompCurveToBSplineCurve C(Curve2); |
7fd59977 | 1358 | fusion=C.Add(Curve1, |
1359 | local_tolerance(j-1)); //fusion de deux courbes adjacentes | |
1360 | if (fusion==Standard_False) | |
9775fa61 | 1361 | throw Standard_ConstructionError("Geom2dConvert Concatenation Error") ; |
7fd59977 | 1362 | Curve2=C.BSplineCurve(); |
1363 | } | |
1364 | } | |
7fd59977 | 1365 | Curve2->SetPeriodic(); //1 seule courbe C1 |
96a95605 | 1366 | Curve2->RemoveKnot(Curve2->LastUKnotIndex(), |
7fd59977 | 1367 | Curve2->Multiplicity(Curve2->LastUKnotIndex())-1, |
1368 | Precision::Confusion()); | |
1369 | ArrayOfConcatenated->SetValue(0,Curve2); | |
1370 | } | |
1371 | ||
1372 | else | |
1373 | for (i=0;i<=nb_group-1;i++){ //boucle principale sur chaque groupe de | |
1374 | nb_vertexG1=0; //continuite interne G1 | |
1375 | ||
1376 | while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True)) | |
1377 | nb_vertexG1++; | |
1378 | ||
1379 | if ((!ClosedFlag)||(nb_group==1)){ //remplissage du tableau des indices conserves | |
1380 | k++; | |
1381 | ArrayOfIndices->SetValue(k-1,index); | |
1382 | if (k==nb_group) | |
1383 | ArrayOfIndices->SetValue(k,0); | |
1384 | } | |
1385 | else{ | |
1386 | k++; | |
1387 | ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1); | |
1388 | if (k==nb_group) | |
1389 | ArrayOfIndices->SetValue(k,nb_vertex_group0+1); | |
1390 | } | |
1391 | ||
1392 | for (j=index;j<=index+nb_vertexG1;j++){ //boucle secondaire a l'interieur de chaque groupe | |
1393 | if (NeedToBeTreated(ArrayOfCurves(j))) | |
1394 | Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j)); | |
1395 | else | |
1396 | Curve1=ArrayOfCurves(j); | |
1397 | ||
1398 | if (index==j) //initialisation en debut de groupe | |
1399 | ArrayOfConcatenated->SetValue(i,Curve1); | |
1400 | else{ | |
a9dde4a3 | 1401 | Geom2dConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i)); |
7fd59977 | 1402 | fusion=C.Add(Curve1,ArrayOfToler(j-1)); //fusion de deux courbes adjacentes |
1403 | if (fusion==Standard_False) | |
9775fa61 | 1404 | throw Standard_ConstructionError("Geom2dConvert Concatenation Error") ; |
7fd59977 | 1405 | ArrayOfConcatenated->SetValue(i,C.BSplineCurve()); |
1406 | } | |
1407 | } | |
1408 | index=index+1+nb_vertexG1; | |
1409 | } | |
1410 | } | |
1411 | ||
1412 | //======================================================================= | |
1413 | //function : C0BSplineToC1BSplineCurve | |
1414 | //purpose : | |
1415 | //======================================================================= | |
1416 | ||
1417 | void Geom2dConvert::C0BSplineToC1BSplineCurve(Handle(Geom2d_BSplineCurve)& BS, | |
1418 | const Standard_Real tolerance) | |
1419 | ||
1420 | { | |
1421 | TColStd_Array1OfInteger BSMults(1,BS->NbKnots()); | |
1422 | TColStd_Array1OfReal BSKnots(1,BS->NbKnots()); | |
1423 | Standard_Integer i,j,nbcurveC1=1; | |
1424 | Standard_Real U1,U2; | |
1425 | Standard_Boolean closed_flag = Standard_False ; | |
d30895f5 | 1426 | gp_Pnt2d point1, point2; |
7fd59977 | 1427 | gp_Vec2d V1,V2; |
1428 | Standard_Boolean fusion; | |
1429 | ||
1430 | BS->Knots(BSKnots); | |
1431 | BS->Multiplicities(BSMults); | |
9e20ed57 | 1432 | for (i=BS->FirstUKnotIndex() + 1;i<=(BS->LastUKnotIndex()-1);i++){ |
7fd59977 | 1433 | if (BSMults(i)==BS->Degree()) |
1434 | nbcurveC1++; | |
1435 | } | |
1436 | ||
1437 | nbcurveC1 = Min(nbcurveC1, BS->NbKnots() - 1); | |
1438 | ||
1439 | if (nbcurveC1>1){ | |
1440 | TColGeom2d_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1); | |
1441 | TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2); | |
1442 | ||
1443 | for (i=0;i<=nbcurveC1-2;i++) | |
1444 | ArrayOfToler(i)=tolerance; | |
1445 | U2=BS->FirstParameter() ; | |
1446 | j=BS->FirstUKnotIndex() + 1 ; | |
1447 | for (i=0;i<nbcurveC1;i++){ | |
1448 | U1=U2; | |
1449 | ||
9e20ed57 | 1450 | while (j < BS->LastUKnotIndex() && BSMults(j) < BS->Degree()) |
1451 | j++; | |
7fd59977 | 1452 | |
1453 | U2=BSKnots(j); | |
1454 | j++; | |
c04c30b3 | 1455 | Handle(Geom2d_BSplineCurve) BSbis=Handle(Geom2d_BSplineCurve)::DownCast(BS->Copy()); |
7fd59977 | 1456 | BSbis->Segment(U1,U2); |
1457 | ArrayOfCurves(i)=BSbis; | |
1458 | } | |
d30895f5 | 1459 | |
1460 | const Standard_Real anAngularToler = 1.0e-7; | |
7fd59977 | 1461 | Handle(TColStd_HArray1OfInteger) ArrayOfIndices; |
1462 | Handle(TColGeom2d_HArray1OfBSplineCurve) ArrayOfConcatenated; | |
1463 | ||
d30895f5 | 1464 | BS->D1(BS->FirstParameter(),point1,V1); //a verifier |
1465 | BS->D1(BS->LastParameter(),point2,V2); | |
7fd59977 | 1466 | |
d30895f5 | 1467 | if ((point1.SquareDistance(point2) < gp::Resolution()) && |
1468 | (V1.IsParallel(V2, anAngularToler))) | |
1469 | { | |
1470 | closed_flag = Standard_True; | |
1471 | } | |
1472 | ||
7fd59977 | 1473 | Geom2dConvert::ConcatC1(ArrayOfCurves, |
1474 | ArrayOfToler, | |
1475 | ArrayOfIndices, | |
1476 | ArrayOfConcatenated, | |
1477 | closed_flag, | |
1478 | tolerance); | |
1479 | ||
a9dde4a3 | 1480 | Geom2dConvert_CompCurveToBSplineCurve C(ArrayOfConcatenated->Value(0)); |
7fd59977 | 1481 | if (ArrayOfConcatenated->Length()>=2){ |
1482 | for (i=1;i<ArrayOfConcatenated->Length();i++){ | |
2dad173d | 1483 | fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance, Standard_True); |
7fd59977 | 1484 | if (fusion==Standard_False) |
9775fa61 | 1485 | throw Standard_ConstructionError("Geom2dConvert Concatenation Error") ; |
7fd59977 | 1486 | } |
1487 | } | |
1488 | BS=C.BSplineCurve(); | |
1489 | } | |
1490 | } | |
1491 | //======================================================================= | |
1492 | //function : C0BSplineToArrayOfC1BSplineCurve | |
1493 | //purpose : | |
1494 | //======================================================================= | |
1495 | ||
1496 | void Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve) & BS, | |
1497 | Handle(TColGeom2d_HArray1OfBSplineCurve) & tabBS, | |
1498 | const Standard_Real tolerance) | |
1499 | { | |
1500 | C0BSplineToArrayOfC1BSplineCurve(BS, | |
1501 | tabBS, | |
1502 | tolerance, | |
1503 | Precision::Angular()); | |
1504 | } | |
1505 | //======================================================================= | |
1506 | //function : C0BSplineToArrayOfC1BSplineCurve | |
1507 | //purpose : | |
1508 | //======================================================================= | |
1509 | ||
1510 | void Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve) & BS, | |
1511 | Handle(TColGeom2d_HArray1OfBSplineCurve) & tabBS, | |
1512 | const Standard_Real AngularTolerance, | |
1513 | const Standard_Real Tolerance) | |
1514 | ||
1515 | { | |
1516 | TColStd_Array1OfInteger BSMults(1,BS->NbKnots()); | |
1517 | TColStd_Array1OfReal BSKnots(1,BS->NbKnots()); | |
1518 | Standard_Integer i,j,nbcurveC1=1; | |
1519 | Standard_Real U1,U2; | |
1520 | Standard_Boolean closed_flag = Standard_False ; | |
d30895f5 | 1521 | gp_Pnt2d point1, point2; |
7fd59977 | 1522 | gp_Vec2d V1,V2; |
1523 | // Standard_Boolean fusion; | |
1524 | ||
1525 | BS->Knots(BSKnots); | |
1526 | BS->Multiplicities(BSMults); | |
1527 | for (i=BS->FirstUKnotIndex() ;i<=(BS->LastUKnotIndex()-1);i++){ | |
1528 | if (BSMults(i)==BS->Degree()) | |
1529 | nbcurveC1++; | |
1530 | } | |
1531 | ||
1532 | nbcurveC1 = Min(nbcurveC1, BS->NbKnots() - 1); | |
1533 | ||
1534 | if (nbcurveC1>1){ | |
1535 | TColGeom2d_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1); | |
1536 | TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2); | |
1537 | ||
1538 | for (i=0;i<=nbcurveC1-2;i++) | |
1539 | ArrayOfToler(i)=Tolerance; | |
1540 | U2=BS->FirstParameter() ; | |
1541 | j=BS->FirstUKnotIndex()+ 1 ; | |
1542 | for (i=0;i<nbcurveC1;i++){ | |
1543 | U1=U2; | |
1544 | while (j < BS->LastUKnotIndex() && BSMults(j)<BS->Degree()) | |
1545 | j++; | |
1546 | U2=BSKnots(j); | |
1547 | j++; | |
c04c30b3 | 1548 | Handle(Geom2d_BSplineCurve) BSbis=Handle(Geom2d_BSplineCurve)::DownCast(BS->Copy()); |
7fd59977 | 1549 | BSbis->Segment(U1,U2); |
1550 | ArrayOfCurves(i)=BSbis; | |
1551 | } | |
1552 | ||
1553 | Handle(TColStd_HArray1OfInteger) ArrayOfIndices; | |
1554 | ||
d30895f5 | 1555 | BS->D1(BS->FirstParameter(),point1,V1); |
1556 | BS->D1(BS->LastParameter(),point2,V2); | |
7fd59977 | 1557 | |
d30895f5 | 1558 | if (((point1.SquareDistance(point2) < gp::Resolution())) && |
1559 | (V1.IsParallel(V2, AngularTolerance))) | |
1560 | { | |
1561 | closed_flag = Standard_True; | |
1562 | } | |
7fd59977 | 1563 | |
1564 | Geom2dConvert::ConcatC1(ArrayOfCurves, | |
1565 | ArrayOfToler, | |
1566 | ArrayOfIndices, | |
1567 | tabBS, | |
1568 | closed_flag, | |
1569 | Tolerance, | |
1570 | AngularTolerance) ; | |
1571 | } | |
1572 | else{ | |
1573 | tabBS = new TColGeom2d_HArray1OfBSplineCurve(0,0); | |
1574 | tabBS->SetValue(0,BS); | |
1575 | } | |
1576 | } | |
1577 | ||
1578 | ||
1579 | ||
1580 | ||
1581 | ||
1582 | ||
1583 | ||
1584 | ||
1585 | ||
1586 | ||
1587 | ||
1588 | ||
1589 | ||
1590 | ||
1591 | ||
1592 | ||
1593 | ||
1594 | ||
1595 | ||
1596 | ||
1597 | ||
1598 | ||
1599 | ||
1600 | ||
1601 | ||
1602 | ||
1603 | ||
1604 | ||
1605 | ||
1606 | ||
1607 | ||
1608 | ||
1609 | ||
1610 | ||
1611 | ||
1612 | ||
1613 | ||
1614 | ||
1615 | ||
1616 | ||
1617 | ||
1618 |