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