1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
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
19 #include <BSplCLib.hxx>
20 #include <Convert_CircleToBSplineCurve.hxx>
21 #include <Convert_ConicToBSplineCurve.hxx>
22 #include <Convert_EllipseToBSplineCurve.hxx>
23 #include <Convert_HyperbolaToBSplineCurve.hxx>
24 #include <Convert_ParabolaToBSplineCurve.hxx>
26 #include <Geom2d_BSplineCurve.hxx>
27 #include <Geom_BezierCurve.hxx>
28 #include <Geom_BSplineCurve.hxx>
29 #include <Geom_BSplineSurface.hxx>
30 #include <Geom_Circle.hxx>
31 #include <Geom_Conic.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Ellipse.hxx>
34 #include <Geom_Geometry.hxx>
35 #include <Geom_Hyperbola.hxx>
36 #include <Geom_Line.hxx>
37 #include <Geom_OffsetCurve.hxx>
38 #include <Geom_Parabola.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <GeomConvert.hxx>
42 #include <GeomConvert_ApproxCurve.hxx>
43 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
44 #include <GeomLProp.hxx>
47 #include <gp_Circ2d.hxx>
48 #include <gp_Elips2d.hxx>
49 #include <gp_Hypr2d.hxx>
51 #include <gp_Parab2d.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <gp_Trsf.hxx>
58 #include <Precision.hxx>
59 #include <Standard_ConstructionError.hxx>
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>
70 //=======================================================================
71 //function : BSplineCurveBuilder
73 //=======================================================================
74 static Handle(Geom_BSplineCurve) BSplineCurveBuilder
75 (const Handle(Geom_Conic)& TheConic,
76 const Convert_ConicToBSplineCurve& Convert)
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);
89 for (i = 1; i <= NbPoles; i++) {
90 P2d = Convert.Pole (i);
91 P3d.SetCoord (P2d.X(), P2d.Y(), 0.0);
93 Weights (i) = Convert.Weight (i);
95 for (i = 1; i <= NbKnots; i++) {
96 Knots (i) = Convert.Knot (i);
97 Mults (i) = Convert.Multiplicity (i);
100 new Geom_BSplineCurve (Poles, Weights, Knots, Mults,
101 Convert.Degree(), Convert.IsPeriodic());
103 T.SetTransformation (TheConic->Position(), gp::XOY());
104 Handle(Geom_BSplineCurve) Cres;
105 Cres = Handle(Geom_BSplineCurve)::DownCast(TheCurve->Transformed (T));
111 //=======================================================================
112 //function : SplitBSplineCurve
114 //=======================================================================
116 Handle(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)
122 Standard_Integer TheFirst = C->FirstUKnotIndex ();
123 Standard_Integer TheLast = C->LastUKnotIndex ();
124 if (FromK1 == ToK2) Standard_DomainError::Raise();
125 Standard_Integer FirstK = Min (FromK1, ToK2);
126 Standard_Integer LastK = Max (FromK1, ToK2);
127 if (FirstK < TheFirst || LastK > TheLast) Standard_DomainError::Raise();
129 Handle(Geom_BSplineCurve) C1
130 = Handle(Geom_BSplineCurve)::DownCast(C->Copy ());
132 C1->Segment( C->Knot(FirstK),C->Knot(LastK));
134 if (C->IsPeriodic()) {
135 if (!SameOrientation) C1->Reverse();
138 if (FromK1 > ToK2) C1->Reverse();
144 //=======================================================================
145 //function : SplitBSplineCurve
147 //=======================================================================
149 Handle(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 )
156 Standard_Real FirstU = Min( FromU1, ToU2);
157 Standard_Real LastU = Max( FromU1, ToU2);
159 Handle (Geom_BSplineCurve) C1
160 = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
162 C1->Segment(FirstU, LastU);
164 if (C->IsPeriodic()) {
165 if (!SameOrientation) C1->Reverse();
168 if (FromU1 > ToU2) C1->Reverse();
177 //=======================================================================
178 //function : CurveToBSplineCurve
180 //=======================================================================
182 Handle(Geom_BSplineCurve) GeomConvert::CurveToBSplineCurve
183 (const Handle(Geom_Curve)& C,
184 const Convert_ParameterisationType Parameterisation)
186 Handle (Geom_BSplineCurve) TheCurve;
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();
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();
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);
210 TColStd_Array1OfReal Knots (1, 2);
211 Knots (1) = Ctrim->FirstParameter ();
212 Knots (2) = Ctrim->LastParameter ();
213 TColStd_Array1OfInteger Mults (1, 2);
216 Standard_Integer Degree = 1;
217 TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
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,
228 TheCurve = BSplineCurveBuilder (TheConic, Convert);
232 Convert_CircleToBSplineCurve Convert (C2d,
236 TheCurve = BSplineCurveBuilder (TheConic, Convert);
238 else { // split circle to avoide numerical
239 // overflow when U2 - U1 =~ 2*PI
241 Standard_Real Umed = (U1 + U2) * .5;
242 Convert_CircleToBSplineCurve Convert1 (C2d,
247 Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
249 Convert_CircleToBSplineCurve Convert2 (C2d,
254 Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
256 GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
259 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
262 TheCurve = CCTBSpl.BSplineCurve();
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,
278 TheCurve = BSplineCurveBuilder (TheConic, Convert);
282 Convert_EllipseToBSplineCurve Convert (E2d,
286 TheCurve = BSplineCurveBuilder (TheConic, Convert);
288 else { // split ellipse to avoide numerical
289 // overflow when U2 - U1 =~ 2*PI
291 Standard_Real Umed = (U1 + U2) * .5;
292 Convert_EllipseToBSplineCurve Convert1 (E2d,
297 Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
299 Convert_EllipseToBSplineCurve Convert2 (E2d,
304 Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
306 GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
309 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
312 TheCurve = CCTBSpl.BSplineCurve();
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);
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);
332 else if (Curv->IsKind (STANDARD_TYPE(Geom_BezierCurve))) {
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);
344 Mults (1) = Degree + 1;
345 Mults (2) = Degree + 1;
347 if (CBez->IsRational()) {
348 TColStd_Array1OfReal Weights (1, NbPoles);
349 CBez->Weights (Weights);
351 new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
355 new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
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())
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();
370 ///////////////////////////////////////////////
371 TheCurve->Segment(U1,U2);
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();
381 else Standard_ConstructionError::Raise();
383 else { Standard_DomainError::Raise("No such curve"); }
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) {
393 Standard_DomainError::Raise(); }
395 else if ( Parameterisation == Convert_QuasiAngular) {
396 Convert_EllipseToBSplineCurve Convert (E2d,
401 TheCurve = BSplineCurveBuilder (TheConic, Convert);
402 TheCurve->SetPeriodic();
405 Convert_EllipseToBSplineCurve Convert (E2d,
407 TheCurve = BSplineCurveBuilder (TheConic, Convert);
408 TheCurve->SetPeriodic(); // pour polynomial et quasi angular
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) {
417 Standard_DomainError::Raise(); }
419 else if ( Parameterisation == Convert_QuasiAngular) {
420 Convert_CircleToBSplineCurve Convert (C2d,
425 TheCurve = BSplineCurveBuilder (TheConic, Convert);
428 Convert_CircleToBSplineCurve Convert (C2d,
430 TheCurve = BSplineCurveBuilder (TheConic, Convert);
431 TheCurve->SetPeriodic();
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);
444 Mults (1) = Degree + 1;
445 Mults (2) = Degree + 1;
447 if (CBez->IsRational()) {
448 TColStd_Array1OfReal Weights (1, NbPoles);
449 CBez->Weights (Weights);
451 new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
454 TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
458 else if (C->IsKind (STANDARD_TYPE(Geom_BSplineCurve))) {
459 TheCurve = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
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();
470 else Standard_ConstructionError::Raise();
472 else { Standard_DomainError::Raise("No such curve"); }
479 //=======================================================================
480 //class : law_evaluator
481 //purpose : usefull to estimate the value of a function
482 //=======================================================================
484 class GeomConvert_law_evaluator : public BSplCLib_EvaluatorFunction
489 GeomConvert_law_evaluator (const Handle(Geom2d_BSplineCurve)& theAncore)
490 : myAncore (theAncore) {}
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
499 if (!myAncore.IsNull() &&
500 theParameter >= theStartEnd[0] &&
501 theParameter <= theStartEnd[1] &&
502 theDerivativeRequest == 0)
505 myAncore->D0 (theParameter, aPoint);
506 theResult = aPoint.Coord(2);
514 Handle(Geom2d_BSplineCurve) myAncore;
518 //=======================================================================
519 //function : MultNumandDenom
520 //purpose : Multiply two BSpline curves to make one
521 //=======================================================================
524 static Handle(Geom_BSplineCurve) MultNumandDenom(const Handle(Geom2d_BSplineCurve)& a ,
525 const Handle(Geom_BSplineCurve)& BS )
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,
544 BS->Knots(BSKnots); //storage of the two BSpline
545 BS->Multiplicities(BSMults); //features
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;
556 a->Multiplicities(aMults);
557 BSplCLib::Reparametrize(BS->FirstParameter(),BS->LastParameter(),aKnots);
558 Handle(Geom2d_BSplineCurve) anAncore = new Geom2d_BSplineCurve (aPoles, aKnots, aMults, a->Degree());
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));
574 GeomConvert_law_evaluator ev (anAncore);
576 BSplCLib::FunctionMultiply(ev,
585 BSplCLib::FunctionMultiply(ev,
593 for (ii=1;ii<=resNbPoles;ii++)
595 resPoles(ii).SetCoord(jj,resNumPoles(ii).Coord(jj)/resDenPoles(ii));
596 res = new Geom_BSplineCurve(resPoles,resDenPoles,resKnots->Array1(),resMults->Array1(),degree);
600 //=======================================================================
601 //function : Pretreatment
602 //purpose : Put the two first and two last weigths at one if they are
604 //=======================================================================
606 static void Pretreatment(TColGeom_Array1OfBSplineCurve& tab)
608 {Standard_Integer i,j;
611 for (i=0;i<=(tab.Length()-1);i++){
612 if (tab(i)->IsRational()) {
614 if ((tab(i)->Weight(2)==a)&&
615 (tab(i)->Weight(tab(i)->NbPoles()-1)==a)&&
616 (tab(i)->Weight(tab(i)->NbPoles())==a))
618 for (j=1;j<=tab(i)->NbPoles();j++)
619 tab(i)->SetWeight(j,tab(i)->Weight(j)/a);
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 //=======================================================================
630 static Standard_Boolean NeedToBeTreated(const Handle(Geom_BSplineCurve)& BS)
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;
647 return Standard_False;
650 return Standard_False ;
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 //=======================================================================
660 static Standard_Boolean Need2DegRepara(const TColGeom_Array1OfBSplineCurve& tab)
665 Standard_Real Rapport=1.0e0;
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();
672 if ((Rapport<=(1.0e0+Precision::Confusion()))&&(Rapport>=(1.0e0-Precision::Confusion())))
673 return Standard_False;
675 return Standard_True;
678 //=======================================================================
679 //function : Indexmin
680 //purpose : Give the index of the curve which has the lowest degree
681 //=======================================================================
683 static Standard_Integer Indexmin(const TColGeom_Array1OfBSplineCurve& tab)
685 Standard_Integer i = 0, index = 0, degree = 0;
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();
696 //=======================================================================
697 //function : NewTabClosedG1
698 //purpose : Sort the array of BSplines to start at the nb_vertex_group0 index
699 //=======================================================================
701 static void ReorderArrayOfG1Curves(TColGeom_Array1OfBSplineCurve& ArrayOfCurves,
702 TColStd_Array1OfReal& ArrayOfToler,
703 TColStd_Array1OfBoolean& tabG1,
704 const Standard_Integer StartIndex,
705 const Standard_Real ClosedTolerance)
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);
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);
719 ArraybisOfCurves(i)=ArrayOfCurves(i);
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);
730 ArrayOfToler(ArrayOfCurves.Length()-(StartIndex+2))=ClosedTolerance;
731 tabG1(ArrayOfCurves.Length()-(StartIndex+2))=Standard_True;
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)));
740 ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
744 //=======================================================================
745 //class : reparameterise_evaluator
747 //=======================================================================
749 class GeomConvert_reparameterise_evaluator : public BSplCLib_EvaluatorFunction
754 GeomConvert_reparameterise_evaluator (const Standard_Real thePolynomialCoefficient[3])
756 memcpy (myPolynomialCoefficient, thePolynomialCoefficient, sizeof(myPolynomialCoefficient));
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
766 PLib::EvalPolynomial (theParameter,
767 theDerivativeRequest,
770 *((Standard_Real* )myPolynomialCoefficient), // function really only read values from this array
776 Standard_Real myPolynomialCoefficient[3];
780 //=======================================================================
781 //function : ConcatG1
783 //=======================================================================
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)
791 {Standard_Integer nb_curve=ArrayOfCurves.Length(),
797 Standard_Real lambda, //G1 coefficient
799 Standard_Real PreLast = 0.;
801 gp_Vec Vec1,Vec2; //concecutive tangential vectors
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) ;
808 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
809 local_tolerance(i) = ArrayOfToler(i) ;
811 for (i=0 ;i<nb_curve; i++){
813 First=ArrayOfCurves(i)->FirstParameter();
814 Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
817 Standard_True,Standard_True);
819 Standard_ConstructionError::Raise("GeomConvert curves not C0") ;
821 if (Cont>=GeomAbs_G1)
822 tabG1(i-1)=Standard_True; //True=G1 continuity
824 tabG1(i-1)=Standard_False;
827 PreLast=ArrayOfCurves(i)->LastParameter();
831 while (index<=nb_curve-1){ //determination of the Wire features
833 while(((index+nb_vertexG1)<=nb_curve-2)&&
834 (tabG1(index+nb_vertexG1)==Standard_True))
838 nb_vertex_group0=nb_vertexG1;
839 index=index+1+nb_vertexG1;
842 if ((ClosedG1Flag)&&(nb_group!=1)){ //sort of the array
844 ReorderArrayOfG1Curves(ArrayOfCurves,
851 ArrayOfConcatenated = new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
852 Standard_Boolean fusion;
855 Pretreatment(ArrayOfCurves);
856 Standard_Real aPolynomialCoefficient[3];
858 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
859 indexmin=Indexmin(ArrayOfCurves);
860 if (indexmin!=(ArrayOfCurves.Length()-1))
861 ReorderArrayOfG1Curves(ArrayOfCurves,
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);
882 aPolynomialCoefficient[2] = a;
884 aPolynomialCoefficient[1] = b;
886 aPolynomialCoefficient[0] = c;
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);
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
896 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
897 Curve1->Poles(Curve1Poles);
899 for (ii=1;ii<=Curve1->NbKnots();ii++)
900 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
902 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
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));
913 GeomConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
914 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
915 BSplCLib::FunctionReparameterise(ev,
924 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
925 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
926 BSplCLib::FunctionReparameterise(ev,
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());
940 GeomConvert_CompCurveToBSplineCurve C (Curve2);
942 local_tolerance(j-1)); //merge of two consecutive curves
943 if (fusion==Standard_False)
944 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
945 Curve2=C.BSplineCurve();
947 Curve2->SetPeriodic();
948 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
949 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
950 Precision::Confusion());
951 ArrayOfConcatenated->SetValue(0,Curve2);
955 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
956 nb_vertexG1=0; //group
958 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
961 for (j=index;j<=index+nb_vertexG1;j++){ //secondary loop inside each group
962 Curve1=ArrayOfCurves(j);
964 if (index==j) //initialisation at the begining of the loop
965 ArrayOfConcatenated->SetValue(i,Curve1);
967 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i));
968 fusion=C.Add(Curve1,ArrayOfToler(j-1)); //merge of two consecutive curves
969 if (fusion==Standard_False)
970 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
971 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
974 index=index+1+nb_vertexG1;
977 //=======================================================================
978 //function : ConcatC1
980 //=======================================================================
982 void 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)
989 ConcatC1(ArrayOfCurves,
995 Precision::Angular()) ;
997 //=======================================================================
998 //function : ConcatC1
1000 //=======================================================================
1002 void 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)
1010 {Standard_Integer nb_curve=ArrayOfCurves.Length(),
1016 Standard_Real lambda, //G1 coefficient
1018 Standard_Real PreLast = 0.;
1021 gp_Vec Vec1,Vec2; //concecutive tangential vectors
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) ;
1028 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
1029 local_tolerance(i) = ArrayOfToler(i) ;
1031 for (i=0 ;i<nb_curve; i++){
1033 First=ArrayOfCurves(i)->FirstParameter();
1034 Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
1040 local_tolerance(i-1),
1042 if (Cont<GeomAbs_C0)
1043 Standard_ConstructionError::Raise("GeomConvert curves not C0");
1045 if (Cont>=GeomAbs_G1)
1046 tabG1(i-1)=Standard_True; //True=G1 continuity
1048 tabG1(i-1)=Standard_False;
1051 PreLast=ArrayOfCurves(i)->LastParameter();
1055 while (index<=nb_curve-1){ //determination of the Wire features
1057 while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1061 nb_vertex_group0=nb_vertexG1;
1062 index=index+1+nb_vertexG1;
1065 if ((ClosedG1Flag)&&(nb_group!=1)){ //sort of the array
1067 ReorderArrayOfG1Curves(ArrayOfCurves,
1075 new TColStd_HArray1OfInteger(0,nb_group);
1076 ArrayOfConcatenated =
1077 new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
1079 Standard_Boolean fusion;
1080 Standard_Integer k=0;
1082 Pretreatment(ArrayOfCurves);
1083 Standard_Real aPolynomialCoefficient[3];
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,
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));
1099 Curve1=ArrayOfCurves(j);
1101 if (j==0) //initialisation at the begining of the loop
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);
1117 aPolynomialCoefficient[2] = a;
1119 aPolynomialCoefficient[1] = b;
1121 aPolynomialCoefficient[0] = c;
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);
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
1131 TColgp_Array1OfPnt Curve1Poles(1,Curve1->NbPoles());
1132 Curve1->Poles(Curve1Poles);
1134 for (ii=1;ii<=Curve1->NbKnots();ii++)
1135 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
1137 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
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));
1148 GeomConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
1150 BSplCLib::FunctionReparameterise(ev,
1159 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1161 BSplCLib::FunctionReparameterise(ev,
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());
1175 GeomConvert_CompCurveToBSplineCurve C (Curve2);
1176 fusion=C.Add(Curve1,
1177 local_tolerance(j-1)); //merge of two consecutive curves
1178 if (fusion==Standard_False)
1179 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
1180 Curve2=C.BSplineCurve();
1183 Curve2->SetPeriodic(); //only one C1 curve
1184 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
1185 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
1186 Precision::Confusion());
1187 ArrayOfConcatenated->SetValue(0,Curve2);
1191 for (i=0;i<=nb_group-1;i++){ //principal loop on each G1 continuity
1192 nb_vertexG1=0; //group
1194 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1197 if ((!ClosedG1Flag)||(nb_group==1)){ //filling of the array of index which are kept
1199 ArrayOfIndices->SetValue(k-1,index);
1201 ArrayOfIndices->SetValue(k,0);
1205 ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1);
1207 ArrayOfIndices->SetValue(k,nb_vertex_group0+1);
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));
1214 Curve1=ArrayOfCurves(j);
1216 if (index==j) //initialisation at the begining of the loop
1217 ArrayOfConcatenated->SetValue(i,Curve1);
1220 // Merge of two consecutive curves.
1221 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i));
1222 fusion=C.Add(Curve1, local_tolerance(j-1), Standard_True);
1223 if (fusion==Standard_False)
1224 Standard_ConstructionError::Raise("GeomConvert Concatenation Error");
1225 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
1228 index=index+1+nb_vertexG1;
1232 //=======================================================================
1233 //function : C0BSplineToC1BSplineCurve
1235 //=======================================================================
1237 void GeomConvert::C0BSplineToC1BSplineCurve(Handle(Geom_BSplineCurve)& BS,
1238 const Standard_Real tolerance,
1239 const Standard_Real AngularTol)
1242 Standard_Boolean fusion;
1243 Handle(TColGeom_HArray1OfBSplineCurve) ArrayOfConcatenated;
1244 //the array with the resulting curves
1246 GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS, ArrayOfConcatenated,
1247 AngularTol, tolerance);
1249 GeomConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(0));
1250 if (ArrayOfConcatenated->Length()>=2){
1252 for (i=1;i<ArrayOfConcatenated->Length();i++){
1253 fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance);
1254 if (fusion==Standard_False)
1255 Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
1258 BS=C.BSplineCurve();
1261 //=======================================================================
1262 //function : C0BSplineToArrayOfC1BSplineCurve
1264 //=======================================================================
1266 void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
1267 const Handle(Geom_BSplineCurve) & BS,
1268 Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
1269 const Standard_Real tolerance)
1271 C0BSplineToArrayOfC1BSplineCurve(BS,
1273 Precision::Angular(),
1277 //=======================================================================
1278 //function : C0BSplineToArrayOfC1BSplineCurve
1280 //=======================================================================
1282 void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
1283 const Handle(Geom_BSplineCurve) & BS,
1284 Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
1285 const Standard_Real AngularTolerance,
1286 const Standard_Real tolerance)
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 ;
1295 // Standard_Boolean fusion;
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())
1305 TColGeom_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1);
1306 TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2);
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
1317 //with the curves C1 segmented
1318 while (BSMults(j)<BS->Degree() && j < BS->LastUKnotIndex())
1322 Handle(Geom_BSplineCurve)
1323 BSbis=Handle(Geom_BSplineCurve)::DownCast(BS->Copy());
1324 BSbis->Segment(U1,U2);
1325 ArrayOfCurves(i)=BSbis;
1328 Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
1330 BS->D1(BS->FirstParameter(),point,V1);
1331 BS->D1(BS->LastParameter(),point,V2);
1333 if ((BS->IsClosed())&&(V1.IsParallel(V2,AngularTolerance))){
1334 //check if the BSpline is closed G1
1335 closed_flag = Standard_True ;
1338 GeomConvert::ConcatC1(ArrayOfCurves,
1347 tabBS = new TColGeom_HArray1OfBSplineCurve(0,0);
1348 tabBS->SetValue(0,BS);