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