Warnings on vc14 were eliminated
[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,
542 Status;
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,
583 Status);
584
585 BSplCLib::FunctionMultiply(ev,
586 BS->Degree(),
587 BSFlatKnots,
588 BSWeights,
589 resFlatKnots,
590 degree,
591 resDenPoles,
592 Status);
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,
788 const Standard_Boolean ClosedG1Flag,
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
858 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
859 indexmin=Indexmin(ArrayOfCurves);
860 if (indexmin!=(ArrayOfCurves.Length()-1))
861 ReorderArrayOfG1Curves(ArrayOfCurves,
862 local_tolerance,
863 tabG1,
864 indexmin,
865 ClosedTolerance);
866 Curve2=ArrayOfCurves(0);
867 for (j=1;j<=nb_curve-1;j++){ //secondary loop inside each group
868 Curve1=ArrayOfCurves(j);
869 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
870 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
871 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
872 lambda=Vec2.Magnitude()/Vec1.Magnitude();
873 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
874 Curve1->Knots(KnotC1);
875 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
876 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
877 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
878 Standard_Real tmax,a,b,c,
879 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
880 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
881 a=(lambda*lambda2-1)/(2*lambda*tmax);
41194117 882 aPolynomialCoefficient[2] = a;
7fd59977 883 b=(1/lambda);
41194117 884 aPolynomialCoefficient[1] = b;
7fd59977 885 c=umin;
41194117 886 aPolynomialCoefficient[0] = c;
7fd59977 887 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
888 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
889 Curve1->Multiplicities(KnotC1Mults);
890 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
891 KnotC1(1)=0.0;
892 for (ii=2;ii<=KnotC1.Length();ii++) {
893// KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
894 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
895 }
896 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
897 Curve1->Poles(Curve1Poles);
898
899 for (ii=1;ii<=Curve1->NbKnots();ii++)
900 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
901
902 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
903
904 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
905 TColgp_Array1OfPnt NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
906 Standard_Integer Status;
907 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
908 Curve1->Weights(Curve1Weights);
909 for (ii=1;ii<=Curve1->NbPoles();ii++)
910 for (jj=1;jj<=3;jj++)
911 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
912//POP pour WNT
41194117 913 GeomConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
7fd59977 914// BSplCLib::FunctionReparameterise(reparameterise_evaluator,
915 BSplCLib::FunctionReparameterise(ev,
916 Curve1->Degree(),
917 Curve1FlatKnots,
918 Curve1Poles,
919 FlatKnots,
920 2*Curve1->Degree(),
921 NewPoles,
922 Status
923 );
924 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
925// BSplCLib::FunctionReparameterise(reparameterise_evaluator,
926 BSplCLib::FunctionReparameterise(ev,
927 Curve1->Degree(),
928 Curve1FlatKnots,
929 Curve1Weights,
930 FlatKnots,
931 2*Curve1->Degree(),
932 NewWeights,
933 Status
934 );
935 for (ii=1;ii<=NewPoles.Length();ii++)
936 for (jj=1;jj<=3;jj++)
937 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
938 Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
939 }
a9dde4a3 940 GeomConvert_CompCurveToBSplineCurve C (Curve2);
7fd59977 941 fusion=C.Add(Curve1,
942 local_tolerance(j-1)); //merge of two consecutive curves
943 if (fusion==Standard_False)
9775fa61 944 throw Standard_ConstructionError("GeomConvert Concatenation Error") ;
7fd59977 945 Curve2=C.BSplineCurve();
946 }
7fd59977 947 Curve2->SetPeriodic();
96a95605 948 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
7fd59977 949 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
950 Precision::Confusion());
951 ArrayOfConcatenated->SetValue(0,Curve2);
952 }
953
954 else
955 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
956 nb_vertexG1=0; //group
957
958 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
959 nb_vertexG1++;
960
961 for (j=index;j<=index+nb_vertexG1;j++){ //secondary loop inside each group
962 Curve1=ArrayOfCurves(j);
963
964 if (index==j) //initialisation at the begining of the loop
965 ArrayOfConcatenated->SetValue(i,Curve1);
966 else{
a9dde4a3 967 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i));
7fd59977 968 fusion=C.Add(Curve1,ArrayOfToler(j-1)); //merge of two consecutive curves
969 if (fusion==Standard_False)
9775fa61 970 throw Standard_ConstructionError("GeomConvert Concatenation Error") ;
7fd59977 971 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
972 }
973 }
974 index=index+1+nb_vertexG1;
975 }
976}
977//=======================================================================
978//function : ConcatC1
979//purpose :
980//=======================================================================
981
982void GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
983 const TColStd_Array1OfReal& ArrayOfToler,
984 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
985 Handle(TColGeom_HArray1OfBSplineCurve)& ArrayOfConcatenated,
986 const Standard_Boolean ClosedG1Flag,
987 const Standard_Real ClosedTolerance)
988{
989 ConcatC1(ArrayOfCurves,
990 ArrayOfToler,
991 ArrayOfIndices,
992 ArrayOfConcatenated,
993 ClosedG1Flag,
994 ClosedTolerance,
995 Precision::Angular()) ;
996}
997//=======================================================================
998//function : ConcatC1
999//purpose :
1000//=======================================================================
1001
1002void GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
1003 const TColStd_Array1OfReal& ArrayOfToler,
1004 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
1005 Handle(TColGeom_HArray1OfBSplineCurve)& ArrayOfConcatenated,
1006 const Standard_Boolean ClosedG1Flag,
1007 const Standard_Real ClosedTolerance,
1008 const Standard_Real AngularTolerance)
1009
1010{Standard_Integer nb_curve=ArrayOfCurves.Length(),
1011 nb_vertexG1,
1012 nb_group=0,
1013 index=0,i,ii,j,jj,
1014 indexmin,
1015 nb_vertex_group0=0;
1016 Standard_Real lambda, //G1 coefficient
1017 First;
1018 Standard_Real PreLast = 0.;
1019
1020 GeomAbs_Shape Cont;
1021 gp_Vec Vec1,Vec2; //concecutive tangential vectors
1022 gp_Pnt Pint;
1023 Handle(Geom_BSplineCurve) Curve1,Curve2;
1024 TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //array of the G1 continuity at the intersections
1025 TColStd_Array1OfReal local_tolerance(0,
1026 ArrayOfToler.Length()-1) ;
1027
1028 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
1029 local_tolerance(i) = ArrayOfToler(i) ;
1030 }
1031 for (i=0 ;i<nb_curve; i++){
1032 if (i >= 1){
1033 First=ArrayOfCurves(i)->FirstParameter();
1034 Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
1035 ArrayOfCurves(i),
1036 PreLast,
1037 First,
1038 Standard_True,
1039 Standard_True,
1040 local_tolerance(i-1),
1041 AngularTolerance);
1042 if (Cont<GeomAbs_C0)
9775fa61 1043 throw Standard_ConstructionError("GeomConvert curves not C0");
7fd59977 1044 else{
1045 if (Cont>=GeomAbs_G1)
1046 tabG1(i-1)=Standard_True; //True=G1 continuity
1047 else
1048 tabG1(i-1)=Standard_False;
1049 }
1050 }
1051 PreLast=ArrayOfCurves(i)->LastParameter();
1052 }
1053
1054
1055 while (index<=nb_curve-1){ //determination of the Wire features
1056 nb_vertexG1=0;
1057 while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1058 nb_vertexG1++;
1059 nb_group++;
1060 if (index==0)
1061 nb_vertex_group0=nb_vertexG1;
1062 index=index+1+nb_vertexG1;
1063 }
1064
1065 if ((ClosedG1Flag)&&(nb_group!=1)){ //sort of the array
1066 nb_group--;
1067 ReorderArrayOfG1Curves(ArrayOfCurves,
1068 local_tolerance,
1069 tabG1,
1070 nb_vertex_group0,
1071 ClosedTolerance);
1072 }
1073
1074 ArrayOfIndices =
1075 new TColStd_HArray1OfInteger(0,nb_group);
1076 ArrayOfConcatenated =
1077 new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
1078
1079 Standard_Boolean fusion;
1080 Standard_Integer k=0;
1081 index=0;
1082 Pretreatment(ArrayOfCurves);
41194117 1083 Standard_Real aPolynomialCoefficient[3];
7fd59977 1084
1085 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
1086 ArrayOfIndices->SetValue(0,0);
1087 ArrayOfIndices->SetValue(1,0);
1088 indexmin=Indexmin(ArrayOfCurves);
1089 if (indexmin!=(ArrayOfCurves.Length()-1))
1090 ReorderArrayOfG1Curves(ArrayOfCurves,
1091 local_tolerance,
1092 tabG1,
1093 indexmin,
1094 ClosedTolerance);
1095 for (j=0;j<=nb_curve-1;j++){ //secondary loop inside each group
1096 if (NeedToBeTreated(ArrayOfCurves(j)))
1097 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1098 else
1099 Curve1=ArrayOfCurves(j);
1100
1101 if (j==0) //initialisation at the begining of the loop
1102 Curve2=Curve1;
1103 else{
1104 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
1105 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
1106 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
1107 lambda=Vec2.Magnitude()/Vec1.Magnitude();
1108 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
1109 Curve1->Knots(KnotC1);
1110 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
1111 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
1112 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
1113 Standard_Real tmax,a,b,c,
1114 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
1115 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
1116 a=(lambda*lambda2-1)/(2*lambda*tmax);
41194117 1117 aPolynomialCoefficient[2] = a;
7fd59977 1118 b=(1/lambda);
41194117 1119 aPolynomialCoefficient[1] = b;
7fd59977 1120 c=umin;
41194117 1121 aPolynomialCoefficient[0] = c;
7fd59977 1122 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
1123 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
1124 Curve1->Multiplicities(KnotC1Mults);
1125 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
1126 KnotC1(1)=0.0;
1127 for (ii=2;ii<=KnotC1.Length();ii++) {
1128// KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
1129 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
1130 }
1131 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
1132 Curve1->Poles(Curve1Poles);
1133
1134 for (ii=1;ii<=Curve1->NbKnots();ii++)
1135 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
1136
1137 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
1138
1139 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
1140 TColgp_Array1OfPnt NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1141 Standard_Integer Status;
1142 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
1143 Curve1->Weights(Curve1Weights);
1144 for (ii=1;ii<=Curve1->NbPoles();ii++)
1145 for (jj=1;jj<=3;jj++)
1146 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
1147//POP pour WNT
41194117 1148 GeomConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
7fd59977 1149
1150 BSplCLib::FunctionReparameterise(ev,
1151 Curve1->Degree(),
1152 Curve1FlatKnots,
1153 Curve1Poles,
1154 FlatKnots,
1155 2*Curve1->Degree(),
1156 NewPoles,
1157 Status
1158 );
1159 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1160
1161 BSplCLib::FunctionReparameterise(ev,
1162 Curve1->Degree(),
1163 Curve1FlatKnots,
1164 Curve1Weights,
1165 FlatKnots,
1166 2*Curve1->Degree(),
1167 NewWeights,
1168 Status
1169 );
1170 for (ii=1;ii<=NewPoles.Length();ii++)
1171 for (jj=1;jj<=3;jj++)
1172 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
1173 Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
1174 }
a9dde4a3 1175 GeomConvert_CompCurveToBSplineCurve C (Curve2);
7fd59977 1176 fusion=C.Add(Curve1,
1177 local_tolerance(j-1)); //merge of two consecutive curves
1178 if (fusion==Standard_False)
9775fa61 1179 throw Standard_ConstructionError("GeomConvert Concatenation Error") ;
7fd59977 1180 Curve2=C.BSplineCurve();
1181 }
1182 }
7fd59977 1183 Curve2->SetPeriodic(); //only one C1 curve
96a95605 1184 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
7fd59977 1185 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
1186 Precision::Confusion());
1187 ArrayOfConcatenated->SetValue(0,Curve2);
1188 }
1189
1190 else
1191 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
1192 nb_vertexG1=0; //group
1193
1194 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1195 nb_vertexG1++;
1196
1197 if ((!ClosedG1Flag)||(nb_group==1)){ //filling of the array of index which are kept
1198 k++;
1199 ArrayOfIndices->SetValue(k-1,index);
1200 if (k==nb_group)
1201 ArrayOfIndices->SetValue(k,0);
1202 }
1203 else{
1204 k++;
1205 ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1);
1206 if (k==nb_group)
1207 ArrayOfIndices->SetValue(k,nb_vertex_group0+1);
1208 }
1209
1210 for (j=index;j<=index+nb_vertexG1;j++){ //secondary loop inside each group
1211 if (NeedToBeTreated(ArrayOfCurves(j)))
1212 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1213 else
1214 Curve1=ArrayOfCurves(j);
1215
1216 if (index==j) //initialisation at the begining of the loop
1217 ArrayOfConcatenated->SetValue(i,Curve1);
3ceb4c3c 1218 else
1219 {
1220 // Merge of two consecutive curves.
a9dde4a3 1221 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i));
3ceb4c3c 1222 fusion=C.Add(Curve1, local_tolerance(j-1), Standard_True);
1223 if (fusion==Standard_False)
9775fa61 1224 throw Standard_ConstructionError("GeomConvert Concatenation Error");
3ceb4c3c 1225 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
7fd59977 1226 }
1227 }
1228 index=index+1+nb_vertexG1;
1229 }
1230}
1231
1232//=======================================================================
1233//function : C0BSplineToC1BSplineCurve
1234//purpose :
1235//=======================================================================
1236
1237void GeomConvert::C0BSplineToC1BSplineCurve(Handle(Geom_BSplineCurve)& BS,
1238 const Standard_Real tolerance,
1239 const Standard_Real AngularTol)
1240
1241{
1242 Standard_Boolean fusion;
1243 Handle(TColGeom_HArray1OfBSplineCurve) ArrayOfConcatenated;
1244 //the array with the resulting curves
1245
1246 GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS, ArrayOfConcatenated,
1247 AngularTol, tolerance);
1248
a9dde4a3 1249 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(0));
7fd59977 1250 if (ArrayOfConcatenated->Length()>=2){
1251 Standard_Integer i;
1252 for (i=1;i<ArrayOfConcatenated->Length();i++){
1253 fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance);
1254 if (fusion==Standard_False)
9775fa61 1255 throw Standard_ConstructionError("GeomConvert Concatenation Error") ;
7fd59977 1256 }
1257 }
1258 BS=C.BSplineCurve();
1259}
1260
1261//=======================================================================
1262//function : C0BSplineToArrayOfC1BSplineCurve
1263//purpose :
1264//=======================================================================
1265
1266void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
1267 const Handle(Geom_BSplineCurve) & BS,
1268 Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
1269 const Standard_Real tolerance)
1270{
1271 C0BSplineToArrayOfC1BSplineCurve(BS,
1272 tabBS,
1273 Precision::Angular(),
1274 tolerance) ;
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 AngularTolerance,
1286 const Standard_Real tolerance)
1287
1288{TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
1289 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
1290 Standard_Integer i,j,nbcurveC1=1;
1291 Standard_Real U1,U2;
1292 Standard_Boolean closed_flag= Standard_False ;
1293 gp_Pnt point;
1294 gp_Vec V1,V2;
1295// Standard_Boolean fusion;
1296
1297 BS->Knots(BSKnots);
1298 BS->Multiplicities(BSMults);
1299 for (i=BS->FirstUKnotIndex() ;i<=(BS->LastUKnotIndex()-1);i++){ //give the number of C1 curves
1300 if (BSMults(i)==BS->Degree())
1301 nbcurveC1++;
1302 }
1303
1304 if (nbcurveC1>1){
1305 TColGeom_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1);
1306 TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2);
1307
1308 for (i=0;i<=nbcurveC1-2;i++)
1309 //filling of the array of tolerances
1310 ArrayOfToler(i)=tolerance;
1311 //with the variable tolerance
1312 U2=BS->FirstParameter() ;
1313 j=BS->FirstUKnotIndex() + 1;
1314 for (i=0;i<nbcurveC1;i++){
1315 //filling of the array of curves
1316 U1=U2;
1317 //with the curves C1 segmented
1318 while (BSMults(j)<BS->Degree() && j < BS->LastUKnotIndex())
1319 j++;
1320 U2=BSKnots(j);
1321 j++;
1322 Handle(Geom_BSplineCurve)
c04c30b3 1323 BSbis=Handle(Geom_BSplineCurve)::DownCast(BS->Copy());
7fd59977 1324 BSbis->Segment(U1,U2);
1325 ArrayOfCurves(i)=BSbis;
1326 }
1327
1328 Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
1329
1330 BS->D1(BS->FirstParameter(),point,V1);
1331 BS->D1(BS->LastParameter(),point,V2);
1332
1333 if ((BS->IsClosed())&&(V1.IsParallel(V2,AngularTolerance))){
1334 //check if the BSpline is closed G1
1335 closed_flag = Standard_True ;
1336 }
1337
1338 GeomConvert::ConcatC1(ArrayOfCurves,
1339 ArrayOfToler,
1340 ArrayOfIndices,
1341 tabBS,
1342 closed_flag,
1343 tolerance,
1344 AngularTolerance);
1345 }
1346 else{
1347 tabBS = new TColGeom_HArray1OfBSplineCurve(0,0);
1348 tabBS->SetValue(0,BS);
1349 }
1350}
1351
1352
1353
1354
1355