1 // Created on: 1997-04-29
2 // Created by: Stagiaire Francois DUMONT
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Geom2d_BoundedCurve.hxx>
19 #include <Geom2d_BSplineCurve.hxx>
20 #include <Geom2dConvert.hxx>
21 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec2d.hxx>
24 #include <Precision.hxx>
25 #include <TColgp_Array1OfPnt2d.hxx>
26 #include <TColStd_Array1OfInteger.hxx>
27 #include <TColStd_Array1OfReal.hxx>
29 //=======================================================================
30 //function : constructor
32 //=======================================================================
33 Geom2dConvert_CompCurveToBSplineCurve::Geom2dConvert_CompCurveToBSplineCurve (const Convert_ParameterisationType theParameterisation)
34 : myTol (Precision::Confusion()),
35 myType (theParameterisation)
40 //=======================================================================
41 //function : constructor
43 //=======================================================================
44 Geom2dConvert_CompCurveToBSplineCurve::
45 Geom2dConvert_CompCurveToBSplineCurve(const Handle(Geom2d_BoundedCurve)& BasisCurve,
46 const Convert_ParameterisationType Parameterisation) :
47 myTol(Precision::Confusion()),
48 myType(Parameterisation)
50 Handle(Geom2d_BSplineCurve) Bs =
51 Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve);
53 myCurve = Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve->Copy());
56 myCurve = Geom2dConvert::CurveToBSplineCurve (BasisCurve, myType);
60 //=======================================================================
63 //=======================================================================
65 Standard_Boolean Geom2dConvert_CompCurveToBSplineCurve::
66 Add(const Handle(Geom2d_BoundedCurve)& NewCurve,
67 const Standard_Real Tolerance,
68 const Standard_Boolean After)
71 Handle(Geom2d_BSplineCurve) Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve);
74 Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve->Copy());
78 Bs = Geom2dConvert::CurveToBSplineCurve (NewCurve, myType);
88 Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
90 // myCurve est elle fermee ?
91 if (myCurve->Pole(LCb).Distance(myCurve->Pole(1)) < myTol){
94 Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
95 Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
101 Add(myCurve, Bs, Standard_True);
102 return Standard_True;
107 Standard_Real d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
108 Standard_Real d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
114 Add(Bs, myCurve, Standard_False);
115 return Standard_True;
122 Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
123 Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
124 if (( d1 < myTol) || ( d2 < myTol)) {
125 if (d2 < d1) {Bs->Reverse();}
126 Add(myCurve, Bs, Standard_True);
127 return Standard_True;
131 d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
132 d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
133 if ( (d1 < myTol) || (d2 < myTol)) {
134 if (d1 < d2) {Bs->Reverse();}
135 Add(Bs, myCurve, Standard_False );
136 return Standard_True;
140 return Standard_False;
143 //=======================================================================
146 //=======================================================================
148 void Geom2dConvert_CompCurveToBSplineCurve::Add(
149 Handle(Geom2d_BSplineCurve)& FirstCurve,
150 Handle(Geom2d_BSplineCurve)& SecondCurve,
151 const Standard_Boolean After)
153 // Harmonisation des degres.
154 Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
155 if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
156 if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
159 Standard_Real L1, L2, U_de_raccord;
160 Standard_Integer ii, jj;
161 Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
162 Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
163 Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
164 TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
165 TColgp_Array1OfPnt2d Poles (1, NbP1+ NbP2-1);
166 TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
167 TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
169 // Ratio de reparametrisation (C1 si possible)
170 L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
171 L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
173 if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
176 if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
179 // On ne bouge pas la premiere courbe
183 Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
184 U_de_raccord = FirstCurve->LastParameter();
187 // On ne bouge pas la seconde courbe
189 Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
192 U_de_raccord = SecondCurve->FirstParameter();
197 for (ii=1; ii<NbK1; ii++) {
198 Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
199 Mults(ii) = FirstCurve->Multiplicity(ii);
201 Noeuds(NbK1) = U_de_raccord;
202 Mults(NbK1) = FirstCurve->Degree();
203 for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
204 Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
205 Mults(jj) = SecondCurve->Multiplicity(ii);
207 Ratio = FirstCurve->Weight(NbP1) ;
208 Ratio /= SecondCurve->Weight(1) ;
209 // Les Poles et Poids
210 for (ii=1; ii<NbP1; ii++) {
211 Poles(ii) = FirstCurve->Pole(ii);
212 Poids(ii) = FirstCurve->Weight(ii);
214 for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
215 Poles(jj) = SecondCurve->Pole(ii);
217 // attentiion les poids ne se raccord pas forcement C0
220 Poids(jj) = Ratio * SecondCurve->Weight(ii);
223 // Creation de la BSpline
224 myCurve = new (Geom2d_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
226 // Reduction eventuelle de la multiplicite
227 Standard_Boolean Ok = Standard_True;
228 Standard_Integer M = Mults(NbK1);
229 while ( (M>0) && Ok) {
231 Ok = myCurve->RemoveKnot(NbK1, M, myTol);
235 //=======================================================================
236 //function : BSplineCurve
238 //=======================================================================
240 Handle(Geom2d_BSplineCurve) Geom2dConvert_CompCurveToBSplineCurve::BSplineCurve() const
245 //=======================================================================
248 //=======================================================================
250 void Geom2dConvert_CompCurveToBSplineCurve::Clear()