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