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
18 #include <BSplCLib.hxx>
19 #include <Convert_CircleToBSplineCurve.hxx>
20 #include <Convert_ConicToBSplineCurve.hxx>
21 #include <Convert_EllipseToBSplineCurve.hxx>
22 #include <Convert_HyperbolaToBSplineCurve.hxx>
23 #include <Convert_ParabolaToBSplineCurve.hxx>
24 #include <Geom2d_BezierCurve.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom2d_Conic.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Ellipse.hxx>
30 #include <Geom2d_Geometry.hxx>
31 #include <Geom2d_Hyperbola.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_OffsetCurve.hxx>
34 #include <Geom2d_Parabola.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Geom2dConvert.hxx>
37 #include <Geom2dConvert_ApproxCurve.hxx>
38 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
39 #include <GeomAbs_Shape.hxx>
41 #include <gp_Circ2d.hxx>
42 #include <gp_Dir2d.hxx>
43 #include <gp_Elips2d.hxx>
44 #include <gp_Hypr2d.hxx>
46 #include <gp_Parab2d.hxx>
47 #include <gp_Pnt2d.hxx>
48 #include <gp_Trsf2d.hxx>
49 #include <gp_Vec2d.hxx>
52 #include <Precision.hxx>
53 #include <Standard_ConstructionError.hxx>
54 #include <Standard_DomainError.hxx>
55 #include <Standard_OutOfRange.hxx>
56 #include <TColgp_Array1OfPnt2d.hxx>
57 #include <TColStd_Array1OfBoolean.hxx>
58 #include <TColStd_Array1OfInteger.hxx>
59 #include <TColStd_Array1OfReal.hxx>
60 #include <TColStd_HArray1OfReal.hxx>
62 typedef gp_Circ2d Circ2d;
63 typedef gp_Elips2d Elips2d;
64 typedef gp_Hypr2d Hypr2d;
65 typedef gp_Parab2d Parab2d;
66 typedef gp_Pnt2d Pnt2d;
67 typedef gp_Trsf2d Trsf2d;
68 typedef Geom2d_Curve Curve;
69 typedef Geom2d_BSplineCurve BSplineCurve;
70 typedef TColStd_Array1OfReal Array1OfReal;
71 typedef TColStd_Array1OfInteger Array1OfInteger;
72 typedef TColgp_Array1OfPnt2d Array1OfPnt2d;
74 //=======================================================================
75 //function : BSplineCurveBuilder
77 //=======================================================================
79 static Handle(Geom2d_BSplineCurve) BSplineCurveBuilder (
81 const Handle(Geom2d_Conic)& TheConic,
82 const Convert_ConicToBSplineCurve& Convert
85 Handle(Geom2d_BSplineCurve) TheCurve;
86 Standard_Integer NbPoles = Convert.NbPoles();
87 Standard_Integer NbKnots = Convert.NbKnots();
88 Array1OfPnt2d Poles (1, NbPoles);
89 Array1OfReal Weights (1, NbPoles);
90 Array1OfReal Knots (1, NbKnots);
91 Array1OfInteger Mults (1, NbKnots);
93 for (i = 1; i <= NbPoles; i++) {
94 Poles (i) = Convert.Pole (i);
95 Weights (i) = Convert.Weight (i);
97 for (i = 1; i <= NbKnots; i++) {
98 Knots (i) = Convert.Knot (i);
99 Mults (i) = Convert.Multiplicity (i);
101 TheCurve = new BSplineCurve (
102 Poles, Weights, Knots, Mults,
103 Convert.Degree(), Convert.IsPeriodic());
105 gp_Ax22d Axis = TheConic->Position();
106 if ( ( Axis.XDirection() ^ Axis.YDirection()) < 0.) {
107 // Then the axis is left-handed, apply a symetry to the curve.
109 Sym.SetMirror(gp::OX2d());
110 TheCurve->Transform(Sym);
114 T.SetTransformation (TheConic->XAxis(), gp::OX2d());
115 Handle(Geom2d_BSplineCurve) Cres =
116 Handle(Geom2d_BSplineCurve)::DownCast(TheCurve->Transformed (T));
121 //=======================================================================
122 //function : SplitBSplineCurve
124 //=======================================================================
126 Handle(Geom2d_BSplineCurve) Geom2dConvert::SplitBSplineCurve (
128 const Handle(Geom2d_BSplineCurve)& C,
129 const Standard_Integer FromK1,
130 const Standard_Integer ToK2,
131 const Standard_Boolean SameOrientation
134 Standard_Integer TheFirst = C->FirstUKnotIndex ();
135 Standard_Integer TheLast = C->LastUKnotIndex ();
136 if (FromK1 == ToK2) Standard_DomainError::Raise();
137 Standard_Integer FirstK = Min (FromK1, ToK2);
138 Standard_Integer LastK = Max (FromK1, ToK2);
139 if (FirstK < TheFirst || LastK > TheLast) Standard_OutOfRange::Raise();
141 Handle(Geom2d_BSplineCurve) NewCurve = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy());
143 NewCurve->Segment(C->Knot(FirstK),C->Knot(LastK));
145 if (C->IsPeriodic()) {
146 if (!SameOrientation) NewCurve->Reverse();
149 if (FromK1 > ToK2) NewCurve->Reverse();
155 //=======================================================================
156 //function : SplitBSplineCurve
158 //=======================================================================
160 Handle(Geom2d_BSplineCurve) Geom2dConvert::SplitBSplineCurve (
162 const Handle(Geom2d_BSplineCurve)& C,
163 const Standard_Real FromU1,
164 const Standard_Real ToU2,
165 const Standard_Real, // ParametricTolerance,
166 const Standard_Boolean SameOrientation
169 Standard_Real FirstU = Min( FromU1, ToU2);
170 Standard_Real LastU = Max( FromU1, ToU2);
172 Handle (Geom2d_BSplineCurve) C1
173 = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy());
175 C1->Segment(FirstU, LastU);
177 if (C->IsPeriodic()) {
178 if (!SameOrientation) C1->Reverse();
181 if (FromU1 > ToU2) C1->Reverse();
188 //=======================================================================
189 //function : CurveToBSplineCurve
191 //=======================================================================
193 Handle(Geom2d_BSplineCurve) Geom2dConvert::CurveToBSplineCurve (
195 const Handle(Geom2d_Curve)& C,
196 const Convert_ParameterisationType Parameterisation)
199 Handle (BSplineCurve) TheCurve;
201 if (C->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
203 Handle(Geom2d_TrimmedCurve) Ctrim = Handle(Geom2d_TrimmedCurve)::DownCast(C);
204 Curv = Ctrim->BasisCurve();
205 Standard_Real U1 = Ctrim->FirstParameter();
206 Standard_Real U2 = Ctrim->LastParameter();
208 // Si la courbe n'est pas vraiment restreinte, on ne risque pas
209 // le Raise dans le BS->Segment.
210 if (!Curv->IsPeriodic()) {
211 if (U1 < Curv->FirstParameter())
212 U1 = Curv->FirstParameter();
213 if (U2 > Curv->LastParameter())
214 U2 = Curv->LastParameter();
217 if (Curv->IsKind(STANDARD_TYPE(Geom2d_Line))) {
218 gp_Pnt2d Pdeb = Ctrim->StartPoint();
219 gp_Pnt2d Pfin = Ctrim->EndPoint();
220 Array1OfPnt2d Poles (1, 2);
223 Array1OfReal Knots (1, 2);
224 Knots (1) = Ctrim->FirstParameter ();
225 Knots (2) = Ctrim->LastParameter();
226 Array1OfInteger Mults (1, 2);
229 Standard_Integer Degree = 1;
230 TheCurve = new Geom2d_BSplineCurve (Poles, Knots, Mults, Degree);
233 else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Circle))) {
234 Handle(Geom2d_Circle) TheConic= Handle(Geom2d_Circle)::DownCast(Curv);
235 Circ2d C2d (gp::OX2d(), TheConic->Radius());
236 if(Parameterisation != Convert_RationalC1) {
237 Convert_CircleToBSplineCurve Convert (C2d,
241 TheCurve = BSplineCurveBuilder (TheConic, Convert);
245 Convert_CircleToBSplineCurve Convert (C2d,
249 TheCurve = BSplineCurveBuilder (TheConic, Convert);
251 else { // split circle to avoide numerical
252 // overflow when U2 - U1 =~ 2*PI
254 Standard_Real Umed = (U1 + U2) * .5;
255 Convert_CircleToBSplineCurve Convert1 (C2d,
260 Handle (BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
262 Convert_CircleToBSplineCurve Convert2 (C2d,
267 Handle (BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
269 Geom2dConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
272 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
275 TheCurve = CCTBSpl.BSplineCurve();
280 else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
281 Handle(Geom2d_Ellipse) TheConic = Handle(Geom2d_Ellipse)::DownCast(Curv);
283 Elips2d E2d (gp::OX2d(),
284 TheConic->MajorRadius(),
285 TheConic->MinorRadius());
286 if(Parameterisation != Convert_RationalC1) {
287 Convert_EllipseToBSplineCurve Convert (E2d,
291 TheCurve = BSplineCurveBuilder (TheConic, Convert);
295 Convert_EllipseToBSplineCurve Convert (E2d,
299 TheCurve = BSplineCurveBuilder (TheConic, Convert);
301 else { // split ellipse to avoide numerical
302 // overflow when U2 - U1 =~ 2*PI
304 Standard_Real Umed = (U1 + U2) * .5;
305 Convert_EllipseToBSplineCurve Convert1 (E2d,
310 Handle (BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);
312 Convert_EllipseToBSplineCurve Convert2 (E2d,
317 Handle (BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);
319 Geom2dConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
322 CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);
325 TheCurve = CCTBSpl.BSplineCurve();
330 else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
331 Handle(Geom2d_Hyperbola) TheConic = Handle(Geom2d_Hyperbola)::DownCast(Curv);
333 Hypr2d H2d (gp::OX2d(),
334 TheConic->MajorRadius(), TheConic->MinorRadius());
335 Convert_HyperbolaToBSplineCurve Convert (H2d, U1, U2);
336 TheCurve = BSplineCurveBuilder (TheConic, Convert);
339 else if (Curv->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
340 Handle(Geom2d_Parabola) TheConic = Handle(Geom2d_Parabola)::DownCast(Curv);
342 Parab2d Prb2d (gp::OX2d(), TheConic->Focal());
343 Convert_ParabolaToBSplineCurve Convert (Prb2d, U1, U2);
344 TheCurve = BSplineCurveBuilder (TheConic, Convert);
347 else if (Curv->IsKind (STANDARD_TYPE(Geom2d_BezierCurve))) {
349 Handle(Geom2d_BezierCurve) CBez = Handle(Geom2d_BezierCurve)::DownCast(Curv->Copy());
351 CBez->Segment (U1, U2);
352 Standard_Integer NbPoles = CBez->NbPoles();
353 Standard_Integer Degree = CBez->Degree();
354 Array1OfPnt2d Poles (1, NbPoles);
355 Array1OfReal Knots (1, 2);
356 Array1OfInteger Mults (1, 2);
359 Mults (1) = Degree + 1;
360 Mults (2) = Degree + 1;
362 if (CBez->IsRational()) {
363 Array1OfReal Weights (1, NbPoles);
364 CBez->Weights (Weights);
365 TheCurve = new BSplineCurve (Poles, Weights, Knots, Mults, Degree);
368 TheCurve = new BSplineCurve (Poles, Knots, Mults, Degree);
372 else if (Curv->IsKind (STANDARD_TYPE(Geom2d_BSplineCurve))) {
373 TheCurve = Handle(Geom2d_BSplineCurve)::DownCast(Curv->Copy());
374 TheCurve->Segment(U1,U2);
377 else if (Curv->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) {
379 Standard_Real Tol2d = 1.e-4;
380 GeomAbs_Shape Order = GeomAbs_C2;
381 Standard_Integer MaxSegments = 16, MaxDegree = 14;
382 Geom2dConvert_ApproxCurve ApprCOffs(C, Tol2d, Order,
383 MaxSegments, MaxDegree);
384 if (ApprCOffs.HasResult())
385 TheCurve = ApprCOffs.Curve();
386 else Standard_ConstructionError::Raise();
389 else { Standard_DomainError::Raise("No such curve"); }
396 if (C->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
397 Handle(Geom2d_Ellipse) TheConic = Handle(Geom2d_Ellipse)::DownCast(C);
399 Elips2d E2d (gp::OX2d(),
400 TheConic->MajorRadius(), TheConic->MinorRadius());
401 Convert_EllipseToBSplineCurve Convert (E2d,
403 TheCurve = BSplineCurveBuilder (TheConic, Convert);
404 TheCurve->SetPeriodic();
407 else if (C->IsKind(STANDARD_TYPE(Geom2d_Circle))) {
408 Handle(Geom2d_Circle) TheConic = Handle(Geom2d_Circle)::DownCast(C);
410 Circ2d C2d (gp::OX2d(), TheConic->Radius());
411 Convert_CircleToBSplineCurve Convert (C2d,
413 TheCurve = BSplineCurveBuilder (TheConic, Convert);
414 TheCurve->SetPeriodic();
417 else if (C->IsKind (STANDARD_TYPE(Geom2d_BezierCurve))) {
418 Handle(Geom2d_BezierCurve) CBez = Handle(Geom2d_BezierCurve)::DownCast(C);
420 Standard_Integer NbPoles = CBez->NbPoles();
421 Standard_Integer Degree = CBez->Degree();
422 Array1OfPnt2d Poles (1, NbPoles);
423 Array1OfReal Knots (1, 2);
424 Array1OfInteger Mults (1, 2);
427 Mults (1) = Degree + 1;
428 Mults (2) = Degree + 1;
430 if (CBez->IsRational()) {
431 Array1OfReal Weights (1, NbPoles);
432 CBez->Weights (Weights);
433 TheCurve = new BSplineCurve (Poles, Weights, Knots, Mults, Degree);
436 TheCurve = new BSplineCurve (Poles, Knots, Mults, Degree);
439 else if (C->IsKind (STANDARD_TYPE(Geom2d_BSplineCurve))) {
440 TheCurve = Handle(Geom2d_BSplineCurve)::DownCast(C->Copy());
443 else if (C->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) {
445 Standard_Real Tol2d = 1.e-4;
446 GeomAbs_Shape Order = GeomAbs_C2;
447 Standard_Integer MaxSegments = 16, MaxDegree = 14;
448 Geom2dConvert_ApproxCurve ApprCOffs(C, Tol2d, Order,
449 MaxSegments, MaxDegree);
450 if (ApprCOffs.HasResult())
451 TheCurve = ApprCOffs.Curve();
452 else Standard_ConstructionError::Raise();
455 else { Standard_DomainError::Raise(); }
461 //=======================================================================
462 //class : law_evaluator
464 //=======================================================================
466 class Geom2dConvert_law_evaluator : public BSplCLib_EvaluatorFunction
471 Geom2dConvert_law_evaluator (const Handle(Geom2d_BSplineCurve)& theAncore)
472 : myAncore (theAncore) {}
474 virtual void Evaluate (const Standard_Integer theDerivativeRequest,
475 const Standard_Real* theStartEnd,
476 const Standard_Real theParameter,
477 Standard_Real& theResult,
478 Standard_Integer& theErrorCode) const
481 if (!myAncore.IsNull() &&
482 theParameter >= theStartEnd[0] &&
483 theParameter <= theStartEnd[1] &&
484 theDerivativeRequest == 0)
487 myAncore->D0 (theParameter, aPoint);
488 theResult = aPoint.Coord (2);
496 Handle(Geom2d_BSplineCurve) myAncore;
501 //=======================================================================
502 //function : MultNumandDenom
503 //purpose : Multiply two BSpline curves to make one
504 //=======================================================================
507 static Handle(Geom2d_BSplineCurve) MultNumandDenom(const Handle(Geom2d_BSplineCurve)& a ,
508 const Handle(Geom2d_BSplineCurve)& BS )
510 { TColStd_Array1OfReal aKnots(1,a->NbKnots());
511 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
512 TColStd_Array1OfReal BSFlatKnots(1,BS->NbPoles()+BS->Degree()+1);
513 TColStd_Array1OfReal BSWeights(1,BS->NbPoles());
514 TColStd_Array1OfInteger aMults(1,a->NbKnots());
515 TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
516 TColgp_Array1OfPnt2d aPoles(1,a->NbPoles());
517 TColgp_Array1OfPnt2d BSPoles(1,BS->NbPoles());
518 Handle(Geom2d_BSplineCurve) res;
519 Handle(TColStd_HArray1OfReal) resKnots;
520 Handle(TColStd_HArray1OfInteger) resMults;
521 Standard_Real start_value,end_value;
522 Standard_Real tolerance=Precision::Confusion();
523 Standard_Integer resNbPoles,degree,
528 BS->Multiplicities(BSMults);
530 BS->Weights(BSWeights);
531 BS->KnotSequence(BSFlatKnots);
532 start_value = BSKnots(1);
533 end_value = BSKnots(BS->NbKnots());
537 a->Multiplicities(aMults);
538 BSplCLib::Reparametrize(BS->FirstParameter(),BS->LastParameter(),aKnots);
539 Handle(Geom2d_BSplineCurve) anAncore = new Geom2d_BSplineCurve (aPoles, aKnots, aMults, a->Degree());
541 BSplCLib::MergeBSplineKnots(tolerance,start_value,end_value,
542 a->Degree(),aKnots,aMults,
543 BS->Degree(),BSKnots,BSMults,
544 resNbPoles,resKnots,resMults);
545 degree=BS->Degree()+a->Degree();
546 TColgp_Array1OfPnt2d resNumPoles(1,resNbPoles);
547 TColStd_Array1OfReal resDenPoles(1,resNbPoles);
548 TColgp_Array1OfPnt2d resPoles(1,resNbPoles);
549 TColStd_Array1OfReal resFlatKnots(1,resNbPoles+degree+1);
550 BSplCLib::KnotSequence(resKnots->Array1(),resMults->Array1(),resFlatKnots);
551 for (ii=1;ii<=BS->NbPoles();ii++)
552 for (jj=1;jj<=2;jj++)
553 BSPoles(ii).SetCoord(jj,BSPoles(ii).Coord(jj)*BSWeights(ii));
555 Geom2dConvert_law_evaluator ev (anAncore);
556 BSplCLib::FunctionMultiply(ev,
564 BSplCLib::FunctionMultiply(ev,
572 // BSplCLib::FunctionMultiply(law_evaluator,
580 // BSplCLib::FunctionMultiply(law_evaluator,
588 for (ii=1;ii<=resNbPoles;ii++)
590 resPoles(ii).SetCoord(jj,resNumPoles(ii).Coord(jj)/resDenPoles(ii));
591 res = new Geom2d_BSplineCurve(resPoles,resDenPoles,resKnots->Array1(),resMults->Array1(),degree);
595 //=======================================================================
596 //function : Pretreatment
597 //purpose : Put the two first and two last weigths at one if they are
599 //=======================================================================
601 static void Pretreatment(TColGeom2d_Array1OfBSplineCurve& tab)
603 {Standard_Integer i,j;
606 for (i=0;i<=(tab.Length()-1);i++){
607 if (tab(i)->IsRational()) {
608 a=tab(i)->Weight(1) ;
609 if ((tab(i)->Weight(2)==a)&&
610 (tab(i)->Weight(tab(i)->NbPoles()-1)==a) &&
611 (tab(i)->Weight(tab(i)->NbPoles())==a))
613 for (j=1;j<=tab(i)->NbPoles();j++)
614 tab(i)->SetWeight(j,tab(i)->Weight(j)/a) ;
619 //=======================================================================
620 //function : NeedToBeTreated
621 //purpose : Say if the BSpline is rationnal and if the two first and two
622 // last weigths are different
623 //=======================================================================
625 static Standard_Boolean NeedToBeTreated(const Handle(Geom2d_BSplineCurve)& BS)
628 TColStd_Array1OfReal tabWeights(1,BS->NbPoles());
629 if (BS->IsRational()) {
630 BS->Weights(tabWeights);
631 if ((BSplCLib::IsRational(tabWeights,1,BS->NbPoles()))&&
632 ((BS->Weight(1)<(1-Precision::Confusion()))||
633 (BS->Weight(1)>(1+Precision::Confusion()))||
634 (BS->Weight(2)<(1-Precision::Confusion()))||
635 (BS->Weight(2)>(1+Precision::Confusion()))||
636 (BS->Weight(BS->NbPoles()-1)<(1-Precision::Confusion()))||
637 (BS->Weight(BS->NbPoles()-1)>(1+Precision::Confusion()))||
638 (BS->Weight(BS->NbPoles())<(1-Precision::Confusion()))||
639 (BS->Weight(BS->NbPoles())>(1+Precision::Confusion()))))
640 return Standard_True;
642 return Standard_False;
645 return Standard_False ;
649 //=======================================================================
650 //function : Need2DegRepara
651 //purpose : in the case of wire closed G1 it says if you will to use a
652 // two degree reparametrisation to close it C1
653 //=======================================================================
655 static Standard_Boolean Need2DegRepara(const TColGeom2d_Array1OfBSplineCurve& tab)
660 Standard_Real Rapport=1.0e0;
662 for (i=0;i<=tab.Length()-2;i++){
663 tab(i+1)->D1(tab(i+1)->FirstParameter(),Pint,Vec1);
664 tab(i)->D1(tab(i)->LastParameter(),Pint,Vec2);
665 Rapport=Rapport*Vec2.Magnitude()/Vec1.Magnitude();
667 if ((Rapport<=(1.0e0 +Precision::Confusion()))&&(Rapport>=(1.0e0-Precision::Confusion())))
668 return Standard_False;
670 return Standard_True;
673 //=======================================================================
674 //function : Indexmin
675 //purpose : Give the index of the curve which has the lowest degree
676 //=======================================================================
678 static Standard_Integer Indexmin(const TColGeom2d_Array1OfBSplineCurve& tab)
680 Standard_Integer i,index=0,degree;
682 degree=tab(0)->Degree();
683 for (i=0;i<=tab.Length()-1;i++)
684 if (tab(i)->Degree()<=degree){
685 degree=tab(i)->Degree();
691 //=======================================================================
692 //function : NewTabClosedG1
694 //=======================================================================
696 static void ReorderArrayOfG1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves,
697 TColStd_Array1OfReal& ArrayOfToler,
698 TColStd_Array1OfBoolean& tabG1,
699 const Standard_Integer StartIndex,
700 const Standard_Real ClosedTolerance)
703 TColGeom2d_Array1OfBSplineCurve ArraybisOfCurves(0,ArrayOfCurves.Length()-1);
704 TColStd_Array1OfReal ArraybisOfToler(0,ArrayOfToler.Length()-1);
705 TColStd_Array1OfBoolean tabbisG1(0,tabG1.Length()-1);
707 for (i=0;i<=ArrayOfCurves.Length()-1;i++){
708 if (i!=ArrayOfCurves.Length()-1){
709 ArraybisOfCurves(i)=ArrayOfCurves(i);
710 ArraybisOfToler(i)=ArrayOfToler(i);
711 tabbisG1(i)=tabG1(i);
714 ArraybisOfCurves(i)=ArrayOfCurves(i);
717 for (i=0;i<=(ArrayOfCurves.Length()-(StartIndex+2));i++){
718 ArrayOfCurves(i)=ArraybisOfCurves(i+StartIndex+1);
719 if (i!=(ArrayOfCurves.Length()-(StartIndex+2))){
720 ArrayOfToler(i)=ArraybisOfToler(i+StartIndex+1);
721 tabG1(i)=tabbisG1(i+StartIndex+1);
725 ArrayOfToler(ArrayOfCurves.Length()-(StartIndex+2))=ClosedTolerance;
726 tabG1(ArrayOfCurves.Length()-(StartIndex+2))=Standard_True;
728 for (i=(ArrayOfCurves.Length()-(StartIndex+1));i<=(ArrayOfCurves.Length()-1);i++){
729 if (i!=ArrayOfCurves.Length()-1){
730 ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
731 ArrayOfToler(i)=ArraybisOfToler(i-(ArrayOfCurves.Length()-(StartIndex+1)));
732 tabG1(i)=tabbisG1(i-(ArrayOfCurves.Length()-(StartIndex+1)));
735 ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
739 //=======================================================================
740 //function : GeomAbsToInteger
742 //=======================================================================
744 static Standard_Integer GeomAbsToInteger(const GeomAbs_Shape gcont)
746 Standard_Integer cont=0 ;
772 //=======================================================================
773 //function : Continuity
775 //=======================================================================
777 static GeomAbs_Shape Continuity(const Handle(Geom2d_Curve)& C1,
778 const Handle(Geom2d_Curve)& C2,
779 const Standard_Real u1,
780 const Standard_Real u2,
781 const Standard_Boolean r1,
782 const Standard_Boolean r2,
783 const Standard_Real tl,
784 const Standard_Real ta)
786 GeomAbs_Shape cont = GeomAbs_C0;
787 Standard_Integer index1,
789 Standard_Real tolerance,value ;
790 // Standard_Boolean fini = Standard_False;
792 // gp_Dir2d dir1,dir2;
793 gp_Pnt2d point1, point2 ;
794 Standard_Integer cont1, cont2 ;
795 GeomAbs_Shape gcont1 = C1->Continuity(), gcont2 = C2->Continuity();
796 cont1 = GeomAbsToInteger(gcont1) ;
797 cont2 = GeomAbsToInteger(gcont2) ;
799 Handle(Geom2d_Curve) aCurve1 = C1 ;
800 Handle(Geom2d_Curve) aCurve2 = C2 ;
801 if (C1->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))){
802 Handle(Geom2d_TrimmedCurve) aTrimmed = Handle(Geom2d_TrimmedCurve) ::DownCast(aCurve1) ;
803 aCurve1 = aTrimmed->BasisCurve() ;
805 if (C2->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))){
806 Handle(Geom2d_TrimmedCurve) aTrimmed = Handle(Geom2d_TrimmedCurve) ::DownCast(aCurve2) ;
807 aCurve2 = aTrimmed->BasisCurve() ;
809 if (aCurve1->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))){
810 Handle(Geom2d_BSplineCurve) BSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(aCurve1) ;
811 BSplineCurve->Resolution(tl,
813 BSplineCurve->LocateU(u1,
818 if (index1 > 1 && index2 < BSplineCurve->NbKnots() && index1 == index2) {
819 cont1 = BSplineCurve->Degree() - BSplineCurve->Multiplicity(index1) ;
825 if (aCurve2->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))){
826 Handle(Geom2d_BSplineCurve) BSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(aCurve2) ;
827 BSplineCurve->Resolution(tl,
829 BSplineCurve->LocateU(u2,
834 if (index1 > 1 && index2 < BSplineCurve->NbKnots() && index1 == index2) {
835 cont2 = BSplineCurve->Degree() - BSplineCurve->Multiplicity(index1) ;
847 if (point1.SquareDistance(point2) <= tl * tl) {
851 if (d1.SquareMagnitude() >= tl * tl &&
852 d2.SquareMagnitude() >= tl * tl) {
854 d1.SetCoord(-d1.X(),-d1.Y()) ;
857 d2.SetCoord(-d2.X(),-d2.Y()) ;
860 if ((d1.Magnitude()<=(d2.Magnitude()+tl))&&
861 (d1.Magnitude()>=(d2.Magnitude()-tl))&&
862 (value/(d1.Magnitude()*d2.Magnitude()) >= 1.0e0 - ta * ta)) {
868 value = Abs(d1.Dot(d2)) ;
869 if (value >= 1.0e0 - ta * ta) {
878 Standard_Failure::Raise("Courbes non jointives");
882 //=======================================================================
883 //function : Continuity
885 //=======================================================================
887 static GeomAbs_Shape Continuity(const Handle(Geom2d_Curve)& C1,
888 const Handle(Geom2d_Curve)& C2,
889 const Standard_Real u1,
890 const Standard_Real u2,
891 const Standard_Boolean r1,
892 const Standard_Boolean r2)
894 return Continuity(C1,C2,u1,u2,r1,r2,
895 Precision::Confusion(),Precision::Angular());
898 //=======================================================================
899 //class :reparameterise_evaluator
901 //=======================================================================
903 class Geom2dConvert_reparameterise_evaluator : public BSplCLib_EvaluatorFunction
908 Geom2dConvert_reparameterise_evaluator (const Standard_Real thePolynomialCoefficient[3])
910 memcpy(myPolynomialCoefficient, thePolynomialCoefficient, sizeof(myPolynomialCoefficient));
913 virtual void Evaluate (const Standard_Integer theDerivativeRequest,
914 const Standard_Real* /*theStartEnd*/,
915 const Standard_Real theParameter,
916 Standard_Real& theResult,
917 Standard_Integer& theErrorCode) const
920 PLib::EvalPolynomial (theParameter,
921 theDerivativeRequest,
924 *((Standard_Real* )myPolynomialCoefficient), // function really only read values from this array
930 Standard_Real myPolynomialCoefficient[3];
934 //=======================================================================
935 //function : ConcatG1
937 //=======================================================================
939 void Geom2dConvert::ConcatG1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves,
940 const TColStd_Array1OfReal& ArrayOfToler,
941 Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated,
942 const Standard_Boolean ClosedFlag,
943 const Standard_Real ClosedTolerance)
945 {Standard_Integer nb_curve=ArrayOfCurves.Length(),
951 Standard_Real lambda, //coeff de raccord G1
953 gp_Vec2d Vec1,Vec2; //vecteurs tangents consecutifs
955 Handle(Geom2d_BSplineCurve) Curve1,Curve2;
956 TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //tableau de continuite G1 aux raccords
957 TColStd_Array1OfReal local_tolerance(0,
958 ArrayOfToler.Length()-1) ;
960 for (i= 0; i < ArrayOfToler.Length() ; i++) {
961 local_tolerance(i) = ArrayOfToler(i) ;
963 for (i=0 ;i<nb_curve; i++){
965 First=ArrayOfCurves(i)->FirstParameter();
966 if (Continuity(ArrayOfCurves(i-1),
970 Standard_True)<GeomAbs_C0)
971 Standard_ConstructionError::Raise("Geom2dConvert curves not C0") ; //renvoi d'une erreur
973 if (Continuity(ArrayOfCurves(i-1),
977 Standard_True)>=GeomAbs_G1)
978 tabG1(i-1)=Standard_True; //True=Continuite G1
980 tabG1(i-1)=Standard_False;
983 PreLast=ArrayOfCurves(i)->LastParameter();
987 while (index<=nb_curve-1){ //determination des caracteristiques du Wire
989 while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
993 nb_vertex_group0=nb_vertexG1;
994 index=index+1+nb_vertexG1;
997 if ((ClosedFlag)&&(nb_group!=1)){ //rearrangement du tableau
999 ReorderArrayOfG1(ArrayOfCurves,
1006 ArrayOfConcatenated = new
1007 TColGeom2d_HArray1OfBSplineCurve(0,nb_group-1);
1009 Standard_Boolean fusion;
1010 // Standard_Integer k=0;
1012 Pretreatment(ArrayOfCurves);
1014 Standard_Real aPolynomialCoefficient[3];
1016 if ((nb_group==1) && (ClosedFlag)){ //traitement d'un cas particulier
1017 indexmin=Indexmin(ArrayOfCurves);
1018 if (indexmin!=(ArrayOfCurves.Length()-1))
1019 ReorderArrayOfG1(ArrayOfCurves,
1024 Curve2=ArrayOfCurves(0);
1025 for (j=1;j<=nb_curve-1;j++){ //boucle secondaire a l'interieur de chaque groupe
1026 Curve1=ArrayOfCurves(j);
1027 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
1028 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
1029 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
1030 lambda=Vec2.Magnitude()/Vec1.Magnitude();
1031 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
1032 Curve1->Knots(KnotC1);
1033 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
1034 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
1035 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
1036 Standard_Real tmax,a,b,c,
1037 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
1038 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
1039 a=(lambda*lambda2-1)/(2*lambda*tmax);
1040 aPolynomialCoefficient[2] = a;
1042 aPolynomialCoefficient[1] = b;
1044 aPolynomialCoefficient[0] = c;
1045 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
1046 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
1047 Curve1->Multiplicities(KnotC1Mults);
1048 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
1050 for (ii=2;ii<=KnotC1.Length();ii++) {
1051 // KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
1052 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); //ifv 17.05.00 buc60667
1054 TColgp_Array1OfPnt2d Curve1Poles(1,Curve1->NbPoles());
1055 Curve1->Poles(Curve1Poles);
1057 for (ii=1;ii<=Curve1->NbKnots();ii++)
1058 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
1060 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
1062 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
1063 TColgp_Array1OfPnt2d NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1064 Standard_Integer Status;
1065 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
1066 Curve1->Weights(Curve1Weights);
1067 for (ii=1;ii<=Curve1->NbPoles();ii++)
1068 for (jj=1;jj<=2;jj++)
1069 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
1071 Geom2dConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
1072 BSplCLib::FunctionReparameterise(ev,
1081 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1082 BSplCLib::FunctionReparameterise(ev,
1091 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
1092 // Curve1->Degree(),
1096 // 2*Curve1->Degree(),
1100 // TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1101 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
1102 // Curve1->Degree(),
1106 // 2*Curve1->Degree(),
1110 for (ii=1;ii<=NewPoles.Length();ii++)
1111 for (jj=1;jj<=2;jj++)
1112 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
1113 Curve1= new Geom2d_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
1115 Geom2dConvert_CompCurveToBSplineCurve C(Curve2);
1116 fusion=C.Add(Curve1,
1117 local_tolerance(j-1)); //fusion de deux courbes adjacentes
1118 if (fusion==Standard_False)
1119 Standard_ConstructionError::Raise("Geom2dConvert Concatenation Error") ;
1120 Curve2=C.BSplineCurve();
1122 Curve2->SetPeriodic(); //1 seule courbe C1
1123 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
1124 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
1125 Precision::Confusion());
1126 ArrayOfConcatenated->SetValue(0,Curve2);
1130 for (i=0;i<=nb_group-1;i++){ //boucle principale sur chaque groupe de
1131 nb_vertexG1=0; //continuite interne G1
1133 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1136 for (j=index;j<=index+nb_vertexG1;j++){ //boucle secondaire a l'interieur de chaque groupe
1137 Curve1=ArrayOfCurves(j);
1139 if (index==j) //initialisation en debut de groupe
1140 ArrayOfConcatenated->SetValue(i,Curve1);
1142 Geom2dConvert_CompCurveToBSplineCurve C(ArrayOfConcatenated->Value(i));
1143 fusion=C.Add(Curve1,ArrayOfToler(j-1)); //fusion de deux courbes adjacentes
1144 if (fusion==Standard_False)
1145 Standard_ConstructionError::Raise("Geom2dConvert Concatenation Error") ;
1146 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
1149 index=index+1+nb_vertexG1;
1152 //=======================================================================
1153 //function : ConcatC1
1155 //=======================================================================
1157 void Geom2dConvert::ConcatC1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves,
1158 const TColStd_Array1OfReal& ArrayOfToler,
1159 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
1160 Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated,
1161 const Standard_Boolean ClosedFlag,
1162 const Standard_Real ClosedTolerance)
1164 ConcatC1(ArrayOfCurves,
1167 ArrayOfConcatenated,
1170 Precision::Angular()) ;
1172 //=======================================================================
1173 //function : ConcatC1
1175 //=======================================================================
1177 void Geom2dConvert::ConcatC1(TColGeom2d_Array1OfBSplineCurve& ArrayOfCurves,
1178 const TColStd_Array1OfReal& ArrayOfToler,
1179 Handle(TColStd_HArray1OfInteger)& ArrayOfIndices,
1180 Handle(TColGeom2d_HArray1OfBSplineCurve) & ArrayOfConcatenated,
1181 const Standard_Boolean ClosedFlag,
1182 const Standard_Real ClosedTolerance,
1183 const Standard_Real AngularTolerance)
1185 {Standard_Integer nb_curve=ArrayOfCurves.Length(),
1191 Standard_Real lambda, //coeff de raccord G1
1193 gp_Vec2d Vec1,Vec2; //vecteurs tangents consecutifs
1195 Handle(Geom2d_BSplineCurve) Curve1,Curve2;
1196 TColStd_Array1OfBoolean tabG1(0,nb_curve-2); //tableau de continuite G1 aux raccords
1197 TColStd_Array1OfReal local_tolerance(0,
1198 ArrayOfToler.Length()-1) ;
1202 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
1203 local_tolerance(i) = ArrayOfToler(i) ;
1205 for (i=0 ;i<nb_curve; i++){
1207 First=ArrayOfCurves(i)->FirstParameter();
1208 if (Continuity(ArrayOfCurves(i-1),
1214 AngularTolerance)<GeomAbs_C0)
1215 Standard_ConstructionError::Raise("Geom2dConvert curves not C0") ; //renvoi d'une erreur
1217 if (Continuity(ArrayOfCurves(i-1),
1224 AngularTolerance)>=GeomAbs_G1)
1225 tabG1(i-1)=Standard_True; //True=Continuite G1
1227 tabG1(i-1)=Standard_False;
1230 PreLast=ArrayOfCurves(i)->LastParameter();
1234 while (index<=nb_curve-1){ //determination des caracteristiques du Wire
1236 while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1240 nb_vertex_group0=nb_vertexG1;
1241 index=index+1+nb_vertexG1;
1244 if ((ClosedFlag)&&(nb_group!=1)){ //rearrangement du tableau
1246 ReorderArrayOfG1(ArrayOfCurves,
1253 ArrayOfIndices = new TColStd_HArray1OfInteger(0,nb_group);
1254 ArrayOfConcatenated = new TColGeom2d_HArray1OfBSplineCurve(0,nb_group-1);
1256 Standard_Boolean fusion;
1257 Standard_Integer k=0;
1259 Pretreatment(ArrayOfCurves);
1260 Standard_Real aPolynomialCoefficient[3];
1262 if ((nb_group==1) && (ClosedFlag)){ //traitement d'un cas particulier
1263 ArrayOfIndices->SetValue(0,0);
1264 ArrayOfIndices->SetValue(1,0);
1265 indexmin=Indexmin(ArrayOfCurves);
1266 if (indexmin!=(ArrayOfCurves.Length()-1))
1267 ReorderArrayOfG1(ArrayOfCurves,
1272 for (j=0;j<=nb_curve-1;j++){ //boucle secondaire a l'interieur de chaque groupe
1273 if (NeedToBeTreated(ArrayOfCurves(j))) {
1274 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1277 Curve1=ArrayOfCurves(j);
1279 if (j==0) //initialisation en debut de groupe
1282 if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){
1283 Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
1284 Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
1285 lambda=Vec2.Magnitude()/Vec1.Magnitude();
1286 TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
1287 Curve1->Knots(KnotC1);
1288 Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
1289 ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
1290 Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
1291 Standard_Real tmax,a,b,c,
1292 umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
1293 tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
1294 a=(lambda*lambda2-1)/(2*lambda*tmax);
1295 aPolynomialCoefficient[2] = a;
1297 aPolynomialCoefficient[1] = b;
1299 aPolynomialCoefficient[0] = c;
1300 TColStd_Array1OfReal Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
1301 TColStd_Array1OfInteger KnotC1Mults(1,Curve1->NbKnots());
1302 Curve1->Multiplicities(KnotC1Mults);
1303 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
1305 for (ii=2;ii<=KnotC1.Length();ii++) {
1306 // KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
1307 KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); //ifv 17.05.00 buc60667
1309 TColgp_Array1OfPnt2d Curve1Poles(1,Curve1->NbPoles());
1310 Curve1->Poles(Curve1Poles);
1312 for (ii=1;ii<=Curve1->NbKnots();ii++)
1313 KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
1315 TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
1317 BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
1318 TColgp_Array1OfPnt2d NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1319 Standard_Integer Status;
1320 TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
1321 Curve1->Weights(Curve1Weights);
1322 for (ii=1;ii<=Curve1->NbPoles();ii++)
1323 for (jj=1;jj<=2;jj++)
1324 Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
1326 Geom2dConvert_reparameterise_evaluator ev (aPolynomialCoefficient);
1327 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
1328 BSplCLib::FunctionReparameterise(ev,
1337 TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
1338 // BSplCLib::FunctionReparameterise(reparameterise_evaluator,
1339 BSplCLib::FunctionReparameterise(ev,
1348 for (ii=1;ii<=NewPoles.Length();ii++) {
1349 for (jj=1;jj<=2;jj++)
1350 NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
1352 Curve1= new Geom2d_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
1354 Geom2dConvert_CompCurveToBSplineCurve C(Curve2);
1355 fusion=C.Add(Curve1,
1356 local_tolerance(j-1)); //fusion de deux courbes adjacentes
1357 if (fusion==Standard_False)
1358 Standard_ConstructionError::Raise("Geom2dConvert Concatenation Error") ;
1359 Curve2=C.BSplineCurve();
1362 Curve2->SetPeriodic(); //1 seule courbe C1
1363 Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
1364 Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
1365 Precision::Confusion());
1366 ArrayOfConcatenated->SetValue(0,Curve2);
1370 for (i=0;i<=nb_group-1;i++){ //boucle principale sur chaque groupe de
1371 nb_vertexG1=0; //continuite interne G1
1373 while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
1376 if ((!ClosedFlag)||(nb_group==1)){ //remplissage du tableau des indices conserves
1378 ArrayOfIndices->SetValue(k-1,index);
1380 ArrayOfIndices->SetValue(k,0);
1384 ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1);
1386 ArrayOfIndices->SetValue(k,nb_vertex_group0+1);
1389 for (j=index;j<=index+nb_vertexG1;j++){ //boucle secondaire a l'interieur de chaque groupe
1390 if (NeedToBeTreated(ArrayOfCurves(j)))
1391 Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
1393 Curve1=ArrayOfCurves(j);
1395 if (index==j) //initialisation en debut de groupe
1396 ArrayOfConcatenated->SetValue(i,Curve1);
1398 Geom2dConvert_CompCurveToBSplineCurve C (ArrayOfConcatenated->Value(i));
1399 fusion=C.Add(Curve1,ArrayOfToler(j-1)); //fusion de deux courbes adjacentes
1400 if (fusion==Standard_False)
1401 Standard_ConstructionError::Raise("Geom2dConvert Concatenation Error") ;
1402 ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
1405 index=index+1+nb_vertexG1;
1409 //=======================================================================
1410 //function : C0BSplineToC1BSplineCurve
1412 //=======================================================================
1414 void Geom2dConvert::C0BSplineToC1BSplineCurve(Handle(Geom2d_BSplineCurve)& BS,
1415 const Standard_Real tolerance)
1418 TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
1419 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
1420 Standard_Integer i,j,nbcurveC1=1;
1421 Standard_Real U1,U2;
1422 Standard_Boolean closed_flag = Standard_False ;
1425 Standard_Boolean fusion;
1428 BS->Multiplicities(BSMults);
1429 for (i=BS->FirstUKnotIndex() + 1;i<=(BS->LastUKnotIndex()-1);i++){
1430 if (BSMults(i)==BS->Degree())
1434 nbcurveC1 = Min(nbcurveC1, BS->NbKnots() - 1);
1437 TColGeom2d_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1);
1438 TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2);
1440 for (i=0;i<=nbcurveC1-2;i++)
1441 ArrayOfToler(i)=tolerance;
1442 U2=BS->FirstParameter() ;
1443 j=BS->FirstUKnotIndex() + 1 ;
1444 for (i=0;i<nbcurveC1;i++){
1447 while (j < BS->LastUKnotIndex() && BSMults(j) < BS->Degree())
1452 Handle(Geom2d_BSplineCurve) BSbis=Handle(Geom2d_BSplineCurve)::DownCast(BS->Copy());
1453 BSbis->Segment(U1,U2);
1454 ArrayOfCurves(i)=BSbis;
1456 Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
1457 Handle(TColGeom2d_HArray1OfBSplineCurve) ArrayOfConcatenated;
1459 BS->D1(BS->FirstParameter(),point,V1); //a verifier
1460 BS->D1(BS->LastParameter(),point,V2);
1462 if ((BS->IsClosed())&&(V1.IsParallel(V2,Precision::Confusion())))
1463 closed_flag = Standard_True ;
1465 Geom2dConvert::ConcatC1(ArrayOfCurves,
1468 ArrayOfConcatenated,
1472 Geom2dConvert_CompCurveToBSplineCurve C(ArrayOfConcatenated->Value(0));
1473 if (ArrayOfConcatenated->Length()>=2){
1474 for (i=1;i<ArrayOfConcatenated->Length();i++){
1475 fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance);
1476 if (fusion==Standard_False)
1477 Standard_ConstructionError::Raise("Geom2dConvert Concatenation Error") ;
1480 BS=C.BSplineCurve();
1483 //=======================================================================
1484 //function : C0BSplineToArrayOfC1BSplineCurve
1486 //=======================================================================
1488 void Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve) & BS,
1489 Handle(TColGeom2d_HArray1OfBSplineCurve) & tabBS,
1490 const Standard_Real tolerance)
1492 C0BSplineToArrayOfC1BSplineCurve(BS,
1495 Precision::Angular());
1497 //=======================================================================
1498 //function : C0BSplineToArrayOfC1BSplineCurve
1500 //=======================================================================
1502 void Geom2dConvert::C0BSplineToArrayOfC1BSplineCurve(const Handle(Geom2d_BSplineCurve) & BS,
1503 Handle(TColGeom2d_HArray1OfBSplineCurve) & tabBS,
1504 const Standard_Real AngularTolerance,
1505 const Standard_Real Tolerance)
1508 TColStd_Array1OfInteger BSMults(1,BS->NbKnots());
1509 TColStd_Array1OfReal BSKnots(1,BS->NbKnots());
1510 Standard_Integer i,j,nbcurveC1=1;
1511 Standard_Real U1,U2;
1512 Standard_Boolean closed_flag = Standard_False ;
1515 // Standard_Boolean fusion;
1518 BS->Multiplicities(BSMults);
1519 for (i=BS->FirstUKnotIndex() ;i<=(BS->LastUKnotIndex()-1);i++){
1520 if (BSMults(i)==BS->Degree())
1524 nbcurveC1 = Min(nbcurveC1, BS->NbKnots() - 1);
1527 TColGeom2d_Array1OfBSplineCurve ArrayOfCurves(0,nbcurveC1-1);
1528 TColStd_Array1OfReal ArrayOfToler(0,nbcurveC1-2);
1530 for (i=0;i<=nbcurveC1-2;i++)
1531 ArrayOfToler(i)=Tolerance;
1532 U2=BS->FirstParameter() ;
1533 j=BS->FirstUKnotIndex()+ 1 ;
1534 for (i=0;i<nbcurveC1;i++){
1536 while (j < BS->LastUKnotIndex() && BSMults(j)<BS->Degree())
1540 Handle(Geom2d_BSplineCurve) BSbis=Handle(Geom2d_BSplineCurve)::DownCast(BS->Copy());
1541 BSbis->Segment(U1,U2);
1542 ArrayOfCurves(i)=BSbis;
1545 Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
1547 BS->D1(BS->FirstParameter(),point,V1);
1548 BS->D1(BS->LastParameter(),point,V2);
1550 if ((BS->IsClosed())&&(V1.IsParallel(V2,AngularTolerance)))
1551 closed_flag = Standard_True ;
1553 Geom2dConvert::ConcatC1(ArrayOfCurves,
1562 tabBS = new TColGeom2d_HArray1OfBSplineCurve(0,0);
1563 tabBS->SetValue(0,BS);