0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / GeomConvert / GeomConvert.cxx
CommitLineData
7fd59977 1// File GeomConvert.cxx
2// Jean-Claude Vauthier Novembre 1991
3// Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline + Debug
4// Modif JCV correction bug le 2/08/1993
5
6#include <GeomConvert.ixx>
7
8#include <BSplCLib.hxx>
9#include <Convert_ConicToBSplineCurve.hxx>
10#include <Convert_CircleToBSplineCurve.hxx>
11#include <Convert_EllipseToBSplineCurve.hxx>
12#include <Convert_HyperbolaToBSplineCurve.hxx>
13#include <Convert_ParabolaToBSplineCurve.hxx>
14
15
16#include <gp.hxx>
17
18#include <gp_Circ2d.hxx>
19#include <gp_Elips2d.hxx>
20#include <gp_Parab2d.hxx>
21#include <gp_Hypr2d.hxx>
22#include <gp_Pnt2d.hxx>
23#include <gp_Lin.hxx>
24#include <gp_Ax3.hxx>
25#include <gp_Trsf.hxx>
26#include <gp_Vec.hxx>
27#include <gp_Pnt.hxx>
28
29#include <Geom2d_BSplineCurve.hxx>
30
31#include <Geom_Curve.hxx>
32#include <Geom_Line.hxx>
33#include <GeomLProp.hxx>
34#include <Geom_Circle.hxx>
35#include <Geom_Ellipse.hxx>
36#include <Geom_Hyperbola.hxx>
37#include <Geom_Parabola.hxx>
38#include <Geom_Geometry.hxx>
39#include <Geom_BSplineCurve.hxx>
40#include <Geom_BezierCurve.hxx>
41#include <Geom_TrimmedCurve.hxx>
42#include <Geom_Conic.hxx>
43#include <GeomConvert_CompCurveToBSplineCurve.hxx>
44
45#include <TColStd_Array1OfReal.hxx>
46#include <TColStd_Array1OfInteger.hxx>
47#include <TColStd_HArray1OfReal.hxx>
48#include <TColStd_HArray1OfInteger.hxx>
49#include <TColStd_Array1OfBoolean.hxx>
50#include <TColgp_Array1OfPnt.hxx>
51#include <TColgp_Array1OfPnt2d.hxx>
52#include <TColGeom_Array1OfCurve.hxx>
53
54#include <Hermit.hxx>
55
56#include <PLib.hxx>
57
58#include <Precision.hxx>
59
60#include <Standard_DomainError.hxx>
61#include <Standard_ConstructionError.hxx>
62#include <Geom_OffsetCurve.hxx>
63#include <GeomConvert_ApproxCurve.hxx>
64
65#include <ElCLib.hxx>
66
67//=======================================================================
68//function : BSplineCurveBuilder
69//purpose :
70//=======================================================================
71
72static Handle(Geom_BSplineCurve) BSplineCurveBuilder
73 (const Handle(Geom_Conic)& TheConic,
74 const Convert_ConicToBSplineCurve& Convert)
75
76{
77 Handle(Geom_BSplineCurve) TheCurve;
78 Standard_Integer NbPoles = Convert.NbPoles();
79 Standard_Integer NbKnots = Convert.NbKnots();
80 TColgp_Array1OfPnt Poles (1, NbPoles);
81 TColStd_Array1OfReal Weights (1, NbPoles);
82 TColStd_Array1OfReal Knots (1, NbKnots);
83 TColStd_Array1OfInteger Mults (1, NbKnots);
84 Standard_Integer i;
85 gp_Pnt2d P2d;
86 gp_Pnt P3d;
87 for (i = 1; i <= NbPoles; i++) {
88 P2d = Convert.Pole (i);
89 P3d.SetCoord (P2d.X(), P2d.Y(), 0.0);
90 Poles (i) = P3d;
91 Weights (i) = Convert.Weight (i);
92 }
93 for (i = 1; i <= NbKnots; i++) {
94 Knots (i) = Convert.Knot (i);
95 Mults (i) = Convert.Multiplicity (i);
96 }
97 TheCurve =
98 new Geom_BSplineCurve (Poles, Weights, Knots, Mults,
99 Convert.Degree(), Convert.IsPeriodic());
100 gp_Trsf T;
101 T.SetTransformation (TheConic->Position(), gp::XOY());
102 Handle(Geom_BSplineCurve) Cres;
103 Cres = Handle(Geom_BSplineCurve)::DownCast(TheCurve->Transformed (T));
104 return Cres;
105}
106
107
108
109//=======================================================================
110//function : SplitBSplineCurve
111//purpose :
112//=======================================================================
113
114Handle(Geom_BSplineCurve) GeomConvert::SplitBSplineCurve
115 (const Handle(Geom_BSplineCurve)& C,
116 const Standard_Integer FromK1,
117 const Standard_Integer ToK2,
118 const Standard_Boolean SameOrientation)
119{
120 Standard_Integer TheFirst = C->FirstUKnotIndex ();
121 Standard_Integer TheLast = C->LastUKnotIndex ();
122 if (FromK1 == ToK2) Standard_DomainError::Raise();
123 Standard_Integer FirstK = Min (FromK1, ToK2);
124 Standard_Integer LastK = Max (FromK1, ToK2);
125 if (FirstK < TheFirst || LastK > TheLast) Standard_DomainError::Raise();
126
127 Handle(Geom_BSplineCurve) C1
128 = Handle(Geom_BSplineCurve)::DownCast(C->Copy ());
129
130 C1->Segment( C->Knot(FirstK),C->Knot(LastK));
131
132 if (C->IsPeriodic()) {
133 if (!SameOrientation) C1->Reverse();
134 }
135 else {
136 if (FromK1 > ToK2) C1->Reverse();
137 }
138 return C1;
139}
140
141
142//=======================================================================
143//function : SplitBSplineCurve
144//purpose :
145//=======================================================================
146
147Handle(Geom_BSplineCurve) GeomConvert::SplitBSplineCurve
148 (const Handle(Geom_BSplineCurve)& C,
149 const Standard_Real FromU1,
150 const Standard_Real ToU2,
151 const Standard_Real , //ParametricTolerance,
152 const Standard_Boolean SameOrientation )
153{
154 Standard_Real FirstU = Min( FromU1, ToU2);
155 Standard_Real LastU = Max( FromU1, ToU2);
156
157 Handle (Geom_BSplineCurve) C1
158 = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
159
160 C1->Segment(FirstU, LastU);
161
162 if (C->IsPeriodic()) {
163 if (!SameOrientation) C1->Reverse();
164 }
165 else {
166 if (FromU1 > ToU2) C1->Reverse();
167 }
168
169 return C1;
170}
171
172
173
174
175//=======================================================================
176//function : CurveToBSplineCurve
177//purpose :
178//=======================================================================
179
180Handle(Geom_BSplineCurve) GeomConvert::CurveToBSplineCurve
181 (const Handle(Geom_Curve)& C,
182 const Convert_ParameterisationType Parameterisation)
183{
184 Handle (Geom_BSplineCurve) TheCurve;
185
186 if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
187 Handle(Geom_Curve) Curv;
188 Handle(Geom_TrimmedCurve) Ctrim = Handle(Geom_TrimmedCurve)::DownCast(C);
189 Curv = Ctrim->BasisCurve();
190 Standard_Real U1 = Ctrim->FirstParameter();
191 Standard_Real U2 = Ctrim->LastParameter();
192
193 // Si la courbe n'est pas vraiment restreinte, on ne risque pas
194 // le Raise dans le BS->Segment.
195 if (!Curv->IsPeriodic()) {
196 if (U1 < Curv->FirstParameter())
197 U1 = Curv->FirstParameter();
198 if (U2 > Curv->LastParameter())
199 U2 = Curv->LastParameter();
200 }
201
202 if (Curv->IsKind(STANDARD_TYPE(Geom_Line))) {
203 gp_Pnt Pdeb = Ctrim->StartPoint();
204 gp_Pnt Pfin = Ctrim->EndPoint();
205 TColgp_Array1OfPnt Poles (1, 2);
206 Poles (1) = Pdeb;
207 Poles (2) = Pfin;
208 TColStd_Array1OfReal Knots (1, 2);
209 Knots (1) = Ctrim->FirstParameter ();
210 Knots (2) = Ctrim->LastParameter ();
211 TColStd_Array1OfInteger Mults (1, 2);
212 Mults (1) = 2;
213 Mults (2) = 2;
214 Standard_Integer Degree = 1;
215 TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
216 }
217
218 else if (Curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
219 Handle(Geom_Circle) TheConic = Handle(Geom_Circle)::DownCast(Curv);
220 gp_Circ2d C2d (gp::OX2d(), TheConic->Radius());
221 if(Parameterisation != Convert_RationalC1) {
222 Convert_CircleToBSplineCurve Convert (C2d,
223 U1,
224 U2,
225 Parameterisation);
226 TheCurve = BSplineCurveBuilder (TheConic, Convert);
227 }
228 else {
229 if(U2 - U1 < 6.) {
230 Convert_CircleToBSplineCurve Convert (C2d,
231 U1,
232 U2,
233 Parameterisation);
234 TheCurve = BSplineCurveBuilder (TheConic, Convert);
235 }
236 else { // split circle to avoide numerical
237 // overflow when U2 - U1 =~ 2*PI
238
239 Standard_Real Umed = (U1 + U2) * .5;
240 Convert_CircleToBSplineCurve Convert1 (C2d,
241 U1,
242 Umed,
243 Parameterisation);
244
245 Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
246
247 Convert_CircleToBSplineCurve Convert2 (C2d,
248 Umed,
249 U2,
250 Parameterisation);
251
252 Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
253
254 GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
255 Parameterisation);
256
257 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
258
259
260 TheCurve = CCTBSpl.BSplineCurve();
261 }
262 }
263
264 }
265
266 else if (Curv->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
267 Handle(Geom_Ellipse) TheConic = Handle(Geom_Ellipse)::DownCast(Curv);
268 gp_Elips2d E2d (gp::OX2d(),
269 TheConic->MajorRadius(),
270 TheConic->MinorRadius());
271 if(Parameterisation != Convert_RationalC1) {
272 Convert_EllipseToBSplineCurve Convert (E2d,
273 U1,
274 U2,
275 Parameterisation);
276 TheCurve = BSplineCurveBuilder (TheConic, Convert);
277 }
278 else {
279 if(U2 - U1 < 6.) {
280 Convert_EllipseToBSplineCurve Convert (E2d,
281 U1,
282 U2,
283 Parameterisation);
284 TheCurve = BSplineCurveBuilder (TheConic, Convert);
285 }
286 else { // split ellipse to avoide numerical
287 // overflow when U2 - U1 =~ 2*PI
288
289 Standard_Real Umed = (U1 + U2) * .5;
290 Convert_EllipseToBSplineCurve Convert1 (E2d,
291 U1,
292 Umed,
293 Parameterisation);
294
295 Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
296
297 Convert_EllipseToBSplineCurve Convert2 (E2d,
298 Umed,
299 U2,
300 Parameterisation);
301
302 Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
303
304 GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
305 Parameterisation);
306
307 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
308
309
310 TheCurve = CCTBSpl.BSplineCurve();
311 }
312 }
313 }
314
315 else if (Curv->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
316 Handle(Geom_Hyperbola) TheConic = Handle(Geom_Hyperbola)::DownCast(Curv);
317 gp_Hypr2d H2d (gp::OX2d(),
318 TheConic->MajorRadius(), TheConic->MinorRadius());
319 Convert_HyperbolaToBSplineCurve Convert (H2d, U1, U2);
320 TheCurve = BSplineCurveBuilder (TheConic, Convert);
321 }
322
323 else if (Curv->IsKind(STANDARD_TYPE(Geom_Parabola))) {
324 Handle(Geom_Parabola) TheConic = Handle(Geom_Parabola)::DownCast(Curv);
325 gp_Parab2d Prb2d (gp::OX2d(), TheConic->Focal());
326 Convert_ParabolaToBSplineCurve Convert (Prb2d, U1, U2);
327 TheCurve = BSplineCurveBuilder (TheConic, Convert);
328 }
329
330 else if (Curv->IsKind (STANDARD_TYPE(Geom_BezierCurve))) {
331
332 Handle(Geom_BezierCurve) CBez
333 = Handle(Geom_BezierCurve)::DownCast(Curv->Copy());
334 CBez->Segment (U1, U2);
335 Standard_Integer NbPoles = CBez->NbPoles();
336 Standard_Integer Degree = CBez->Degree();
337 TColgp_Array1OfPnt Poles (1, NbPoles);
338 TColStd_Array1OfReal Knots (1, 2);
339 TColStd_Array1OfInteger Mults (1, 2);
340 Knots (1) = 0.0;
341 Knots (2) = 1.0;
342 Mults (1) = Degree + 1;
343 Mults (2) = Degree + 1;
344 CBez->Poles (Poles);
345 if (CBez->IsRational()) {
346 TColStd_Array1OfReal Weights (1, NbPoles);
347 CBez->Weights (Weights);
348 TheCurve =
349 new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
350 }
351 else {
352 TheCurve =
353 new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
354 }
355 }
356 else if (Curv->IsKind (STANDARD_TYPE(Geom_BSplineCurve))) {
357 TheCurve = Handle(Geom_BSplineCurve)::DownCast(Curv->Copy());
358 //// modified by jgv, 14.01.05 for OCC7355 ////
359 if (TheCurve->IsPeriodic())
360 {
361 Standard_Real Uf = TheCurve->FirstParameter();
362 Standard_Real Ul = TheCurve->LastParameter();
363 ElCLib::AdjustPeriodic( Uf, Ul, Precision::Confusion(), U1, U2 );
364 if (Abs(U1 - Uf) <= Precision::Confusion() &&
365 Abs(U2 - Ul) <= Precision::Confusion())
366 TheCurve->SetNotPeriodic();
367 }
368 ///////////////////////////////////////////////
369 TheCurve->Segment(U1,U2);
370 }
371 else if (Curv->IsKind (STANDARD_TYPE(Geom_OffsetCurve))) {
372 Standard_Real Tol3d = 1.e-4;
373 GeomAbs_Shape Order = GeomAbs_C2;
374 Standard_Integer MaxSegments = 16, MaxDegree = 14;
375 GeomConvert_ApproxCurve ApprCOffs(C, Tol3d, Order,
376 MaxSegments, MaxDegree);
377 if (ApprCOffs.HasResult())
378 TheCurve = ApprCOffs.Curve();
379 else Standard_ConstructionError::Raise();
380 }
381 else { Standard_DomainError::Raise("No such curve"); }
382 }
383
384 else {
385 if (C->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
386 Handle(Geom_Ellipse) TheConic= Handle(Geom_Ellipse)::DownCast(C);
387 gp_Elips2d E2d (gp::OX2d(),
388 TheConic->MajorRadius(), TheConic->MinorRadius());
389/* if (Parameterisation == Convert_TgtThetaOver2_1 ||
390 Parameterisation == Convert_TgtThetaOver2_2) {
391 Standard_DomainError::Raise(); }
392
393 else if ( Parameterisation == Convert_QuasiAngular) {
394 Convert_EllipseToBSplineCurve Convert (E2d,
395 0.0e0,
c6541a0c 396 2.0e0 * M_PI,
7fd59977 397 Parameterisation);
398
399 TheCurve = BSplineCurveBuilder (TheConic, Convert);
400 TheCurve->SetPeriodic();
401 }
402 else {*/
403 Convert_EllipseToBSplineCurve Convert (E2d,
404 Parameterisation);
405 TheCurve = BSplineCurveBuilder (TheConic, Convert);
406 TheCurve->SetPeriodic(); // pour polynomial et quasi angular
407// }
408 }
409
410 else if (C->IsKind(STANDARD_TYPE(Geom_Circle))) {
411 Handle(Geom_Circle) TheConic = Handle(Geom_Circle)::DownCast(C);
412 gp_Circ2d C2d (gp::OX2d(), TheConic->Radius());
413/* if (Parameterisation == Convert_TgtThetaOver2_1 ||
414 Parameterisation == Convert_TgtThetaOver2_2) {
415 Standard_DomainError::Raise(); }
416
417 else if ( Parameterisation == Convert_QuasiAngular) {
418 Convert_CircleToBSplineCurve Convert (C2d,
419 0.0e0,
c6541a0c 420 2.0e0 * M_PI,
7fd59977 421 Parameterisation);
422
423 TheCurve = BSplineCurveBuilder (TheConic, Convert);
424 }
425 else {*/
426 Convert_CircleToBSplineCurve Convert (C2d,
427 Parameterisation);
428 TheCurve = BSplineCurveBuilder (TheConic, Convert);
429 TheCurve->SetPeriodic();
430// }
431 }
432
433 else if (C->IsKind (STANDARD_TYPE(Geom_BezierCurve))) {
434 Handle(Geom_BezierCurve) CBez= Handle(Geom_BezierCurve)::DownCast(C);
435 Standard_Integer NbPoles = CBez->NbPoles();
436 Standard_Integer Degree = CBez->Degree();
437 TColgp_Array1OfPnt Poles (1, NbPoles);
438 TColStd_Array1OfReal Knots (1, 2);
439 TColStd_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 TColStd_Array1OfReal Weights (1, NbPoles);
447 CBez->Weights (Weights);
448 TheCurve =
449 new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
450 }
451 else {
452 TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
453 }
454 }
455
456 else if (C->IsKind (STANDARD_TYPE(Geom_BSplineCurve))) {
457 TheCurve = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
458 }
459
460 else if (C->IsKind (STANDARD_TYPE(Geom_OffsetCurve))) {
461 Standard_Real Tol3d = 1.e-4;
462 GeomAbs_Shape Order = GeomAbs_C2;
463 Standard_Integer MaxSegments = 16, MaxDegree = 14;
464 GeomConvert_ApproxCurve ApprCOffs(C, Tol3d, Order,
465 MaxSegments, MaxDegree);
466 if (ApprCOffs.HasResult())
467 TheCurve = ApprCOffs.Curve();
468 else Standard_ConstructionError::Raise();
469 }
470 else { Standard_DomainError::Raise("No such curve"); }
471 }
472
473 return TheCurve;
474}
475
476
477//=======================================================================
478//function : law_evaluator
479//purpose : usefull to estimate the value of a function
480//=======================================================================
481
482static Handle(Geom2d_BSplineCurve) Ancore = NULL ;
483
484static void law_evaluator(const Standard_Integer DerivativeRequest,
485 const Standard_Real *StartEnd,
486 const Standard_Real Parameter,
487 Standard_Real & Result,
488 Standard_Integer & ErrorCode)
489{ErrorCode = 0 ;
490 if (!Ancore.IsNull() &&
491 Parameter >= StartEnd[0] &&
492 Parameter <= StartEnd[1] &&
493 DerivativeRequest == 0){
494 gp_Pnt2d a_point ;
495 Ancore->D0(Parameter,
496 a_point) ;
497 Result = a_point.Coord(2) ;
498 }
499 else
500 ErrorCode = 1 ;
501}
502
503//=======================================================================
504//function : MultNumandDenom
505//purpose : Multiply two BSpline curves to make one
506//=======================================================================
507
508
509static Handle(Geom_BSplineCurve) MultNumandDenom(const Handle(Geom2d_BSplineCurve)& a ,
510 const Handle(Geom_BSplineCurve)& BS )
511
512{ TColStd_Array1OfReal aKnots(1,a->NbKnots());
513 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
514 TColStd_Array1OfReal BSFlatKnots(1,BS->NbPoles()+BS->Degree()+1);
515 TColStd_Array1OfReal BSWeights(1,BS->NbPoles());
516 TColStd_Array1OfInteger aMults(1,a->NbKnots());
517 TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
518 TColgp_Array1OfPnt2d aPoles(1,a->NbPoles());
519 TColgp_Array1OfPnt BSPoles(1,BS->NbPoles());
520 Handle(Geom_BSplineCurve) res;
521 Handle(TColStd_HArray1OfReal) resKnots;
522 Handle(TColStd_HArray1OfInteger) resMults;
523 Standard_Real start_value,end_value;
524 Standard_Real tolerance=Precision::PConfusion();
525 Standard_Integer resNbPoles,degree,
526 ii,jj,
527 Status;
528
529 BS->Knots(BSKnots); //storage of the two BSpline
530 BS->Multiplicities(BSMults); //features
531 BS->Poles(BSPoles);
532 BS->Weights(BSWeights);
533 BS->KnotSequence(BSFlatKnots);
534 start_value = BSKnots(1);
535 end_value = BSKnots(BS->NbKnots());
536 if ((end_value - start_value)/5 < tolerance)
537 tolerance = (end_value - start_value)/5;
538
539 a->Knots(aKnots);
540 a->Poles(aPoles);
541 a->Multiplicities(aMults);
542 BSplCLib::Reparametrize(BS->FirstParameter(),BS->LastParameter(),aKnots);
543 Ancore= new Geom2d_BSplineCurve(aPoles,aKnots,aMults,a->Degree()); //call of the law-evaluator
544
545 BSplCLib::MergeBSplineKnots(tolerance,start_value,end_value, //merge of the knots
546 a->Degree(),aKnots,aMults,
547 BS->Degree(),BSKnots,BSMults,
548 resNbPoles,resKnots,resMults);
549 degree=BS->Degree()+a->Degree();
550 TColgp_Array1OfPnt resNumPoles(1,resNbPoles);
551 TColStd_Array1OfReal resDenPoles(1,resNbPoles);
552 TColgp_Array1OfPnt resPoles(1,resNbPoles);
553 TColStd_Array1OfReal resFlatKnots(1,resNbPoles+degree+1);
554 BSplCLib::KnotSequence(resKnots->Array1(),resMults->Array1(),resFlatKnots);
555 for (ii=1;ii<=BS->NbPoles();ii++)
556 for (jj=1;jj<=3;jj++)
557 BSPoles(ii).SetCoord(jj,BSPoles(ii).Coord(jj)*BSWeights(ii));
558//POP pour WNT
559 BSplCLib_EvaluatorFunction ev = law_evaluator;
560
561 BSplCLib::FunctionMultiply(ev,
562 BS->Degree(),
563 BSFlatKnots,
564 BSPoles,
565 resFlatKnots,
566 degree,
567 resNumPoles,
568 Status);
569
570 BSplCLib::FunctionMultiply(ev,
571 BS->Degree(),
572 BSFlatKnots,
573 BSWeights,
574 resFlatKnots,
575 degree,
576 resDenPoles,
577 Status);
578 for (ii=1;ii<=resNbPoles;ii++)
579 for(jj=1;jj<=3;jj++)
580 resPoles(ii).SetCoord(jj,resNumPoles(ii).Coord(jj)/resDenPoles(ii));
581 res = new Geom_BSplineCurve(resPoles,resDenPoles,resKnots->Array1(),resMults->Array1(),degree);
582 return res;
583}
584
585//=======================================================================
586//function : Pretreatment
587//purpose : Put the two first and two last weigths at one if they are
588// equal
589//=======================================================================
590
591static void Pretreatment(TColGeom_Array1OfBSplineCurve& tab)
592
593{Standard_Integer i,j;
594 Standard_Real a;
595
596 for (i=0;i<=(tab.Length()-1);i++){
597 if (tab(i)->IsRational()) {
598 a=tab(i)->Weight(1);
599 if ((tab(i)->Weight(2)==a)&&
600 (tab(i)->Weight(tab(i)->NbPoles()-1)==a)&&
601 (tab(i)->Weight(tab(i)->NbPoles())==a))
602
603 for (j=1;j<=tab(i)->NbPoles();j++)
604 tab(i)->SetWeight(j,tab(i)->Weight(j)/a);
605 }
606 }
607}
608
609//=======================================================================
610//function : NeedToBeTreated
611//purpose : Say if the BSpline is rationnal and if the two first and two
612// last weigths are different
613//=======================================================================
614
615static Standard_Boolean NeedToBeTreated(const Handle(Geom_BSplineCurve)& BS)
616
617{
618 TColStd_Array1OfReal tabWeights(1,BS->NbPoles());
619 if (BS->IsRational()) {
620 BS->Weights(tabWeights);
621 if ((BSplCLib::IsRational(tabWeights,1,BS->NbPoles()))&&
622 ((BS->Weight(1)<(1-Precision::Confusion()))||
623 (BS->Weight(1)>(1+Precision::Confusion()))||
624 (BS->Weight(2)<(1-Precision::Confusion()))||
625 (BS->Weight(2)>(1+Precision::Confusion()))||
626 (BS->Weight(BS->NbPoles()-1)<(1-Precision::Confusion()))||
627 (BS->Weight(BS->NbPoles()-1)>(1+Precision::Confusion()))||
628 (BS->Weight(BS->NbPoles())<(1-Precision::Confusion()))||
629 (BS->Weight(BS->NbPoles())>(1+Precision::Confusion()))))
630 return Standard_True;
631 else
632 return Standard_False;
633 }
634 else
635 return Standard_False ;
636
637}
638
639//=======================================================================
640//function : Need2DegRepara
641//purpose : in the case of wire closed G1 it says if you will to use a
642// two degree reparametrisation to close it C1
643//=======================================================================
644
645static Standard_Boolean Need2DegRepara(const TColGeom_Array1OfBSplineCurve& tab)
646
647{Standard_Integer i;
648 gp_Vec Vec1,Vec2;
649 gp_Pnt Pint;
650 Standard_Real Rapport=1.0e0;
651
652 for (i=0;i<=tab.Length()-2;i++){
653 tab(i+1)->D1(tab(i+1)->FirstParameter(),Pint,Vec1);
654 tab(i)->D1(tab(i)->LastParameter(),Pint,Vec2);
655 Rapport=Rapport*Vec2.Magnitude()/Vec1.Magnitude();
656 }
657 if ((Rapport<=(1.0e0+Precision::Confusion()))&&(Rapport>=(1.0e0-Precision::Confusion())))
658 return Standard_False;
659 else
660 return Standard_True;
661}
662
663//=======================================================================
664//function : Indexmin
665//purpose : Give the index of the curve which has the lowest degree
666//=======================================================================
667
668static Standard_Integer Indexmin(const TColGeom_Array1OfBSplineCurve& tab)
669{
670 Standard_Integer i = 0, index = 0, degree = 0;
671
672 degree=tab(0)->Degree();
673 for (i=0;i<=tab.Length()-1;i++)
674 if (tab(i)->Degree()<=degree){
675 degree=tab(i)->Degree();
676 index=i;
677 }
678 return index;
679}
680
681//=======================================================================
682//function : NewTabClosedG1
683//purpose : Sort the array of BSplines to start at the nb_vertex_group0 index
684//=======================================================================
685
686static void ReorderArrayOfG1Curves(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
687 TColStd_Array1OfReal& ArrayOfToler,
688 TColStd_Array1OfBoolean& tabG1,
689 const Standard_Integer StartIndex,
690 const Standard_Real ClosedTolerance)
691
692{Standard_Integer i;
693 TColGeom_Array1OfBSplineCurve ArraybisOfCurves(0,ArrayOfCurves.Length()-1); //temporary
694 TColStd_Array1OfReal ArraybisOfToler(0,ArrayOfToler.Length()-1); //arrays
695 TColStd_Array1OfBoolean tabbisG1(0,tabG1.Length()-1);
696
697 for (i=0;i<=ArrayOfCurves.Length()-1;i++){
698 if (i!=ArrayOfCurves.Length()-1){
699 ArraybisOfCurves(i)=ArrayOfCurves(i);
700 ArraybisOfToler(i)=ArrayOfToler(i);
701 tabbisG1(i)=tabG1(i);
702 }
703 else
704 ArraybisOfCurves(i)=ArrayOfCurves(i);
705 }
706
707 for (i=0;i<=(ArrayOfCurves.Length()-(StartIndex+2));i++){
708 ArrayOfCurves(i)=ArraybisOfCurves(i+StartIndex+1);
709 if (i!=(ArrayOfCurves.Length()-(StartIndex+2))){
710 ArrayOfToler(i)=ArraybisOfToler(i+StartIndex+1);
711 tabG1(i)=tabbisG1(i+StartIndex+1);
712 }
713 }
714
715 ArrayOfToler(ArrayOfCurves.Length()-(StartIndex+2))=ClosedTolerance;
716 tabG1(ArrayOfCurves.Length()-(StartIndex+2))=Standard_True;
717
718 for (i=(ArrayOfCurves.Length()-(StartIndex+1));i<=(ArrayOfCurves.Length()-1);i++){
719 if (i!=ArrayOfCurves.Length()-1){
720 ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
721 ArrayOfToler(i)=ArraybisOfToler(i-(ArrayOfCurves.Length()-(StartIndex+1)));
722 tabG1(i)=tabbisG1(i-(ArrayOfCurves.Length()-(StartIndex+1)));
723 }
724 else
725 ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
726 }
727}
728
729//=======================================================================
730//function :reparameterise_evaluator
731//purpose :
732//=======================================================================
733
734static Standard_Real polynomial_coefficient[3] ;
735
736static void reparameterise_evaluator(
737 const Standard_Integer DerivativeRequest,
738// const Standard_Real *StartEnd,
739 const Standard_Real *,
740 const Standard_Real Parameter,
741 Standard_Real & Result,
742 Standard_Integer & ErrorCode) {
743 ErrorCode = 0 ;
744 PLib::EvalPolynomial(Parameter,
745 DerivativeRequest,
746 2,
747 1,
748 polynomial_coefficient[0],
749 Result) ;
750}
751
752//=======================================================================
753//function : ConcatG1
754//purpose :
755//=======================================================================
756
757 void GeomConvert::ConcatG1(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
758 const TColStd_Array1OfReal& ArrayOfToler,
759 Handle(TColGeom_HArray1OfBSplineCurve) & ArrayOfConcatenated,
760 const Standard_Boolean ClosedG1Flag,
761 const Standard_Real ClosedTolerance)
762
763{Standard_Integer nb_curve=ArrayOfCurves.Length(),
764 nb_vertexG1=0,
765 nb_group=0,
766 index=0,i,ii,j,jj,
767 indexmin,
768 nb_vertex_group0=0;
769 Standard_Real lambda, //G1 coefficient
770 First;
771 Standard_Real PreLast = 0.;
772 GeomAbs_Shape Cont;
773 gp_Vec Vec1,Vec2; //concecutive tangential vectors
774 gp_Pnt Pint;
775 Handle(Geom_BSplineCurve) Curve1,Curve2;
776 TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //array of the G1 continuity at the intersections
777 TColStd_Array1OfReal local_tolerance(0,
778 ArrayOfToler.Length()-1) ;
779
780 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
781 local_tolerance(i) = ArrayOfToler(i) ;
782 }
783 for (i=0 ;i<nb_curve; i++){
784 if (i >= 1){
785 First=ArrayOfCurves(i)->FirstParameter();
786 Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
787 ArrayOfCurves(i),
788 PreLast,First,
789 Standard_True,Standard_True);
790 if (Cont<GeomAbs_C0)
791 Standard_ConstructionError::Raise("GeomConvert curves not C0") ;
792 else{
793 if (Cont>=GeomAbs_G1)
794 tabG1(i-1)=Standard_True; //True=G1 continuity
795 else
796 tabG1(i-1)=Standard_False;
797 }
798 }
799 PreLast=ArrayOfCurves(i)->LastParameter();
800 }
801
802
803 while (index<=nb_curve-1){ //determination of the Wire features
804 nb_vertexG1=0;
805 while(((index+nb_vertexG1)<=nb_curve-2)&&
806 (tabG1(index+nb_vertexG1)==Standard_True))
807 nb_vertexG1++;
808 nb_group++;
809 if (index==0)
810 nb_vertex_group0=nb_vertexG1;
811 index=index+1+nb_vertexG1;
812 }
813
814 if ((ClosedG1Flag)&&(nb_group!=1)){ //sort of the array
815 nb_group--;
816 ReorderArrayOfG1Curves(ArrayOfCurves,
817 local_tolerance,
818 tabG1,
819 nb_vertex_group0,
820 ClosedTolerance);
821 }
822
823 ArrayOfConcatenated = new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
824 Standard_Boolean fusion;
825
826 index=0;
827 Pretreatment(ArrayOfCurves);
828
829 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
830 indexmin=Indexmin(ArrayOfCurves);
831 if (indexmin!=(ArrayOfCurves.Length()-1))
832 ReorderArrayOfG1Curves(ArrayOfCurves,
833 local_tolerance,
834 tabG1,
835 indexmin,
836 ClosedTolerance);
837 Curve2=ArrayOfCurves(0);
838 for (j=1;j<=nb_curve-1;j++){ //secondary loop inside each group
839 Curve1=ArrayOfCurves(j);
840 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
841 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
842 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
843 lambda=Vec2.Magnitude()/Vec1.Magnitude();
844 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
845 Curve1->Knots(KnotC1);
846 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
847 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
848 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
849 Standard_Real tmax,a,b,c,
850 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
851 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
852 a=(lambda*lambda2-1)/(2*lambda*tmax);
853 polynomial_coefficient[2]=a;
854 b=(1/lambda);
855 polynomial_coefficient[1]=b;
856 c=umin;
857 polynomial_coefficient[0]=c;
858 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
859 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
860 Curve1->Multiplicities(KnotC1Mults);
861 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
862 KnotC1(1)=0.0;
863 for (ii=2;ii<=KnotC1.Length();ii++) {
864// KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
865 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
866 }
867 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
868 Curve1->Poles(Curve1Poles);
869
870 for (ii=1;ii<=Curve1->NbKnots();ii++)
871 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
872
873 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
874
875 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
876 TColgp_Array1OfPnt NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
877 Standard_Integer Status;
878 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
879 Curve1->Weights(Curve1Weights);
880 for (ii=1;ii<=Curve1->NbPoles();ii++)
881 for (jj=1;jj<=3;jj++)
882 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
883//POP pour WNT
884 BSplCLib_EvaluatorFunction ev = reparameterise_evaluator;
885// BSplCLib::FunctionReparameterise(reparameterise_evaluator,
886 BSplCLib::FunctionReparameterise(ev,
887 Curve1->Degree(),
888 Curve1FlatKnots,
889 Curve1Poles,
890 FlatKnots,
891 2*Curve1->Degree(),
892 NewPoles,
893 Status
894 );
895 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
896// BSplCLib::FunctionReparameterise(reparameterise_evaluator,
897 BSplCLib::FunctionReparameterise(ev,
898 Curve1->Degree(),
899 Curve1FlatKnots,
900 Curve1Weights,
901 FlatKnots,
902 2*Curve1->Degree(),
903 NewWeights,
904 Status
905 );
906 for (ii=1;ii<=NewPoles.Length();ii++)
907 for (jj=1;jj<=3;jj++)
908 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
909 Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
910 }
911 GeomConvert_CompCurveToBSplineCurve C(Handle(Geom_BSplineCurve)::DownCast(Curve2));
912 fusion=C.Add(Curve1,
913 local_tolerance(j-1)); //merge of two consecutive curves
914 if (fusion==Standard_False)
915 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
916 Curve2=C.BSplineCurve();
917 }
918 Standard_Boolean rm;
919 Curve2->SetPeriodic();
920 rm=Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
921 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
922 Precision::Confusion());
923 ArrayOfConcatenated->SetValue(0,Curve2);
924 }
925
926 else
927 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
928 nb_vertexG1=0; //group
929
930 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
931 nb_vertexG1++;
932
933 for (j=index;j<=index+nb_vertexG1;j++){ //secondary loop inside each group
934 Curve1=ArrayOfCurves(j);
935
936 if (index==j) //initialisation at the begining of the loop
937 ArrayOfConcatenated->SetValue(i,Curve1);
938 else{
939 GeomConvert_CompCurveToBSplineCurve C(Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(i)));
940 fusion=C.Add(Curve1,ArrayOfToler(j-1)); //merge of two consecutive curves
941 if (fusion==Standard_False)
942 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
943 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
944 }
945 }
946 index=index+1+nb_vertexG1;
947 }
948}
949//=======================================================================
950//function : ConcatC1
951//purpose :
952//=======================================================================
953
954void GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
955 const TColStd_Array1OfReal& ArrayOfToler,
956 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
957 Handle(TColGeom_HArray1OfBSplineCurve)& ArrayOfConcatenated,
958 const Standard_Boolean ClosedG1Flag,
959 const Standard_Real ClosedTolerance)
960{
961 ConcatC1(ArrayOfCurves,
962 ArrayOfToler,
963 ArrayOfIndices,
964 ArrayOfConcatenated,
965 ClosedG1Flag,
966 ClosedTolerance,
967 Precision::Angular()) ;
968}
969//=======================================================================
970//function : ConcatC1
971//purpose :
972//=======================================================================
973
974void GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
975 const TColStd_Array1OfReal& ArrayOfToler,
976 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
977 Handle(TColGeom_HArray1OfBSplineCurve)& ArrayOfConcatenated,
978 const Standard_Boolean ClosedG1Flag,
979 const Standard_Real ClosedTolerance,
980 const Standard_Real AngularTolerance)
981
982{Standard_Integer nb_curve=ArrayOfCurves.Length(),
983 nb_vertexG1,
984 nb_group=0,
985 index=0,i,ii,j,jj,
986 indexmin,
987 nb_vertex_group0=0;
988 Standard_Real lambda, //G1 coefficient
989 First;
990 Standard_Real PreLast = 0.;
991
992 GeomAbs_Shape Cont;
993 gp_Vec Vec1,Vec2; //concecutive tangential vectors
994 gp_Pnt Pint;
995 Handle(Geom_BSplineCurve) Curve1,Curve2;
996 TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //array of the G1 continuity at the intersections
997 TColStd_Array1OfReal local_tolerance(0,
998 ArrayOfToler.Length()-1) ;
999
1000 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
1001 local_tolerance(i) = ArrayOfToler(i) ;
1002 }
1003 for (i=0 ;i<nb_curve; i++){
1004 if (i >= 1){
1005 First=ArrayOfCurves(i)->FirstParameter();
1006 Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
1007 ArrayOfCurves(i),
1008 PreLast,
1009 First,
1010 Standard_True,
1011 Standard_True,
1012 local_tolerance(i-1),
1013 AngularTolerance);
1014 if (Cont<GeomAbs_C0)
1015 Standard_ConstructionError::Raise("GeomConvert curves not C0");
1016 else{
1017 if (Cont>=GeomAbs_G1)
1018 tabG1(i-1)=Standard_True; //True=G1 continuity
1019 else
1020 tabG1(i-1)=Standard_False;
1021 }
1022 }
1023 PreLast=ArrayOfCurves(i)->LastParameter();
1024 }
1025
1026
1027 while (index<=nb_curve-1){ //determination of the Wire features
1028 nb_vertexG1=0;
1029 while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1030 nb_vertexG1++;
1031 nb_group++;
1032 if (index==0)
1033 nb_vertex_group0=nb_vertexG1;
1034 index=index+1+nb_vertexG1;
1035 }
1036
1037 if ((ClosedG1Flag)&&(nb_group!=1)){ //sort of the array
1038 nb_group--;
1039 ReorderArrayOfG1Curves(ArrayOfCurves,
1040 local_tolerance,
1041 tabG1,
1042 nb_vertex_group0,
1043 ClosedTolerance);
1044 }
1045
1046 ArrayOfIndices =
1047 new TColStd_HArray1OfInteger(0,nb_group);
1048 ArrayOfConcatenated =
1049 new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
1050
1051 Standard_Boolean fusion;
1052 Standard_Integer k=0;
1053 index=0;
1054 Pretreatment(ArrayOfCurves);
1055
1056 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
1057 ArrayOfIndices->SetValue(0,0);
1058 ArrayOfIndices->SetValue(1,0);
1059 indexmin=Indexmin(ArrayOfCurves);
1060 if (indexmin!=(ArrayOfCurves.Length()-1))
1061 ReorderArrayOfG1Curves(ArrayOfCurves,
1062 local_tolerance,
1063 tabG1,
1064 indexmin,
1065 ClosedTolerance);
1066 for (j=0;j<=nb_curve-1;j++){ //secondary loop inside each group
1067 if (NeedToBeTreated(ArrayOfCurves(j)))
1068 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1069 else
1070 Curve1=ArrayOfCurves(j);
1071
1072 if (j==0) //initialisation at the begining of the loop
1073 Curve2=Curve1;
1074 else{
1075 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
1076 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
1077 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
1078 lambda=Vec2.Magnitude()/Vec1.Magnitude();
1079 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
1080 Curve1->Knots(KnotC1);
1081 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
1082 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
1083 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
1084 Standard_Real tmax,a,b,c,
1085 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
1086 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
1087 a=(lambda*lambda2-1)/(2*lambda*tmax);
1088 polynomial_coefficient[2]=a;
1089 b=(1/lambda);
1090 polynomial_coefficient[1]=b;
1091 c=umin;
1092 polynomial_coefficient[0]=c;
1093 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
1094 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
1095 Curve1->Multiplicities(KnotC1Mults);
1096 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
1097 KnotC1(1)=0.0;
1098 for (ii=2;ii<=KnotC1.Length();ii++) {
1099// KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
1100 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
1101 }
1102 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
1103 Curve1->Poles(Curve1Poles);
1104
1105 for (ii=1;ii<=Curve1->NbKnots();ii++)
1106 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
1107
1108 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
1109
1110 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
1111 TColgp_Array1OfPnt NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1112 Standard_Integer Status;
1113 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
1114 Curve1->Weights(Curve1Weights);
1115 for (ii=1;ii<=Curve1->NbPoles();ii++)
1116 for (jj=1;jj<=3;jj++)
1117 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
1118//POP pour WNT
1119 BSplCLib_EvaluatorFunction ev = reparameterise_evaluator;
1120
1121 BSplCLib::FunctionReparameterise(ev,
1122 Curve1->Degree(),
1123 Curve1FlatKnots,
1124 Curve1Poles,
1125 FlatKnots,
1126 2*Curve1->Degree(),
1127 NewPoles,
1128 Status
1129 );
1130 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1131
1132 BSplCLib::FunctionReparameterise(ev,
1133 Curve1->Degree(),
1134 Curve1FlatKnots,
1135 Curve1Weights,
1136 FlatKnots,
1137 2*Curve1->Degree(),
1138 NewWeights,
1139 Status
1140 );
1141 for (ii=1;ii<=NewPoles.Length();ii++)
1142 for (jj=1;jj<=3;jj++)
1143 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
1144 Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
1145 }
1146 GeomConvert_CompCurveToBSplineCurve C(Handle(Geom_BSplineCurve)::DownCast(Curve2));
1147 fusion=C.Add(Curve1,
1148 local_tolerance(j-1)); //merge of two consecutive curves
1149 if (fusion==Standard_False)
1150 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
1151 Curve2=C.BSplineCurve();
1152 }
1153 }
1154 Standard_Boolean rm;
1155 Curve2->SetPeriodic(); //only one C1 curve
1156 rm=Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
1157 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
1158 Precision::Confusion());
1159 ArrayOfConcatenated->SetValue(0,Curve2);
1160 }
1161
1162 else
1163 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
1164 nb_vertexG1=0; //group
1165
1166 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1167 nb_vertexG1++;
1168
1169 if ((!ClosedG1Flag)||(nb_group==1)){ //filling of the array of index which are kept
1170 k++;
1171 ArrayOfIndices->SetValue(k-1,index);
1172 if (k==nb_group)
1173 ArrayOfIndices->SetValue(k,0);
1174 }
1175 else{
1176 k++;
1177 ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1);
1178 if (k==nb_group)
1179 ArrayOfIndices->SetValue(k,nb_vertex_group0+1);
1180 }
1181
1182 for (j=index;j<=index+nb_vertexG1;j++){ //secondary loop inside each group
1183 if (NeedToBeTreated(ArrayOfCurves(j)))
1184 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1185 else
1186 Curve1=ArrayOfCurves(j);
1187
1188 if (index==j) //initialisation at the begining of the loop
1189 ArrayOfConcatenated->SetValue(i,Curve1);
1190 else{
1191 GeomConvert_CompCurveToBSplineCurve C(Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(i)));
1192 fusion=C.Add(Curve1,
1193 local_tolerance(j-1)); //merge of two consecutive curves
1194 if (fusion==Standard_False)
1195 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
1196 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
1197 }
1198 }
1199 index=index+1+nb_vertexG1;
1200 }
1201}
1202
1203//=======================================================================
1204//function : C0BSplineToC1BSplineCurve
1205//purpose :
1206//=======================================================================
1207
1208void GeomConvert::C0BSplineToC1BSplineCurve(Handle(Geom_BSplineCurve)& BS,
1209 const Standard_Real tolerance,
1210 const Standard_Real AngularTol)
1211
1212{
1213 Standard_Boolean fusion;
1214 Handle(TColGeom_HArray1OfBSplineCurve) ArrayOfConcatenated;
1215 //the array with the resulting curves
1216
1217 GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS, ArrayOfConcatenated,
1218 AngularTol, tolerance);
1219
1220 GeomConvert_CompCurveToBSplineCurve C
1221 (Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(0)));
1222 if (ArrayOfConcatenated->Length()>=2){
1223 Standard_Integer i;
1224 for (i=1;i<ArrayOfConcatenated->Length();i++){
1225 fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance);
1226 if (fusion==Standard_False)
1227 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
1228 }
1229 }
1230 BS=C.BSplineCurve();
1231}
1232
1233//=======================================================================
1234//function : C0BSplineToArrayOfC1BSplineCurve
1235//purpose :
1236//=======================================================================
1237
1238void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
1239 const Handle(Geom_BSplineCurve) & BS,
1240 Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
1241 const Standard_Real tolerance)
1242{
1243 C0BSplineToArrayOfC1BSplineCurve(BS,
1244 tabBS,
1245 Precision::Angular(),
1246 tolerance) ;
1247}
1248
1249//=======================================================================
1250//function : C0BSplineToArrayOfC1BSplineCurve
1251//purpose :
1252//=======================================================================
1253
1254void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
1255 const Handle(Geom_BSplineCurve) & BS,
1256 Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
1257 const Standard_Real AngularTolerance,
1258 const Standard_Real tolerance)
1259
1260{TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
1261 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
1262 Standard_Integer i,j,nbcurveC1=1;
1263 Standard_Real U1,U2;
1264 Standard_Boolean closed_flag= Standard_False ;
1265 gp_Pnt point;
1266 gp_Vec V1,V2;
1267// Standard_Boolean fusion;
1268
1269 BS->Knots(BSKnots);
1270 BS->Multiplicities(BSMults);
1271 for (i=BS->FirstUKnotIndex() ;i<=(BS->LastUKnotIndex()-1);i++){ //give the number of C1 curves
1272 if (BSMults(i)==BS->Degree())
1273 nbcurveC1++;
1274 }
1275
1276 if (nbcurveC1>1){
1277 TColGeom_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1);
1278 TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2);
1279
1280 for (i=0;i<=nbcurveC1-2;i++)
1281 //filling of the array of tolerances
1282 ArrayOfToler(i)=tolerance;
1283 //with the variable tolerance
1284 U2=BS->FirstParameter() ;
1285 j=BS->FirstUKnotIndex() + 1;
1286 for (i=0;i<nbcurveC1;i++){
1287 //filling of the array of curves
1288 U1=U2;
1289 //with the curves C1 segmented
1290 while (BSMults(j)<BS->Degree() && j < BS->LastUKnotIndex())
1291 j++;
1292 U2=BSKnots(j);
1293 j++;
1294 Handle(Geom_BSplineCurve)
1295 BSbis=Handle(Geom_BSplineCurve::DownCast(BS->Copy()));
1296 BSbis->Segment(U1,U2);
1297 ArrayOfCurves(i)=BSbis;
1298 }
1299
1300 Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
1301
1302 BS->D1(BS->FirstParameter(),point,V1);
1303 BS->D1(BS->LastParameter(),point,V2);
1304
1305 if ((BS->IsClosed())&&(V1.IsParallel(V2,AngularTolerance))){
1306 //check if the BSpline is closed G1
1307 closed_flag = Standard_True ;
1308 }
1309
1310 GeomConvert::ConcatC1(ArrayOfCurves,
1311 ArrayOfToler,
1312 ArrayOfIndices,
1313 tabBS,
1314 closed_flag,
1315 tolerance,
1316 AngularTolerance);
1317 }
1318 else{
1319 tabBS = new TColGeom_HArray1OfBSplineCurve(0,0);
1320 tabBS->SetValue(0,BS);
1321 }
1322}
1323
1324
1325
1326
1327