0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / Geom2dConvert / Geom2dConvert_CompCurveToBSplineCurve.cxx
... / ...
CommitLineData
1// Created on: 1997-04-29
2// Created by: Stagiaire Francois DUMONT
3// Copyright (c) 1997-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
21#include <Geom2dConvert_CompCurveToBSplineCurve.ixx>
22
23#include <Geom2d_BSplineCurve.hxx>
24#include <Geom2dConvert.hxx>
25
26#include <TColStd_Array1OfReal.hxx>
27#include <TColStd_Array1OfInteger.hxx>
28
29#include <TColgp_Array1OfPnt2d.hxx>
30#include <gp_Vec2d.hxx>
31#include <gp_Pnt2d.hxx>
32#include <Precision.hxx>
33
34//=======================================================================
35//function : constructor
36//purpose :
37//=======================================================================
38Geom2dConvert_CompCurveToBSplineCurve::Geom2dConvert_CompCurveToBSplineCurve (const Convert_ParameterisationType theParameterisation)
39: myTol (Precision::Confusion()),
40 myType (theParameterisation)
41{
42 //
43}
44
45//=======================================================================
46//function : constructor
47//purpose :
48//=======================================================================
49Geom2dConvert_CompCurveToBSplineCurve::
50Geom2dConvert_CompCurveToBSplineCurve(const Handle(Geom2d_BoundedCurve)& BasisCurve,
51 const Convert_ParameterisationType Parameterisation) :
52 myTol(Precision::Confusion()),
53 myType(Parameterisation)
54{
55 Handle(Geom2d_BSplineCurve) Bs =
56 Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve);
57 if (!Bs.IsNull()) {
58 myCurve = Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve->Copy());
59 }
60 else {
61 myCurve = Geom2dConvert::CurveToBSplineCurve (BasisCurve, myType);
62 }
63}
64
65//=======================================================================
66//function : Add
67//purpose :
68//=======================================================================
69
70Standard_Boolean Geom2dConvert_CompCurveToBSplineCurve::
71Add(const Handle(Geom2d_BoundedCurve)& NewCurve,
72 const Standard_Real Tolerance,
73 const Standard_Boolean After)
74{
75 // conversion
76 Handle(Geom2d_BSplineCurve) Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve);
77 if (!Bs.IsNull())
78 {
79 Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve->Copy());
80 }
81 else
82 {
83 Bs = Geom2dConvert::CurveToBSplineCurve (NewCurve, myType);
84 }
85 if (myCurve.IsNull())
86 {
87 myCurve = Bs;
88 return Standard_True;
89 }
90
91 myTol = Tolerance;
92
93 Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
94
95 // myCurve est elle fermee ?
96 if (myCurve->Pole(LCb).Distance(myCurve->Pole(1))< myTol){
97 if(After){
98 // Ajout Apres ?
99 if (myCurve->Pole(LCb).Distance(Bs->Pole(LBs)) < myTol) {Bs->Reverse();}
100 if (myCurve->Pole(LCb).Distance(Bs->Pole(1)) < myTol) {
101 Add(myCurve, Bs, Standard_True);
102 return Standard_True;
103 }
104 }
105 else{
106 // Ajout avant ?
107 if (myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol) {Bs->Reverse();}
108 if (myCurve->Pole(1).Distance(Bs->Pole(LBs)) < myTol) {
109 Add(Bs, myCurve, Standard_False);
110 return Standard_True;
111 }
112 }
113 }
114 // Ajout Apres ?
115 else {
116
117 Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
118 Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
119 if (( d1 < myTol) || ( d2 < myTol)) {
120 if (d2 < d1) {Bs->Reverse();}
121 Add(myCurve, Bs, Standard_True);
122 return Standard_True;
123 }
124 // Ajout avant ?
125 else {
126 d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
127 d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
128 if ( (d1 < myTol) || (d2 < myTol)) {
129 if (d1 < d2) {Bs->Reverse();}
130 Add(Bs, myCurve, Standard_False );
131 return Standard_True;
132 }
133 }
134 }
135 return Standard_False;
136}
137
138//=======================================================================
139//function : Add
140//purpose :
141//=======================================================================
142
143void Geom2dConvert_CompCurveToBSplineCurve::Add(
144 Handle(Geom2d_BSplineCurve)& FirstCurve,
145 Handle(Geom2d_BSplineCurve)& SecondCurve,
146 const Standard_Boolean After)
147{
148// Harmonisation des degres.
149 Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
150 if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
151 if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
152
153// Declarationd
154 Standard_Real L1, L2, U_de_raccord;
155 Standard_Integer ii, jj;
156 Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
157 Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
158 Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
159 TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
160 TColgp_Array1OfPnt2d Poles (1, NbP1+ NbP2-1);
161 TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
162 TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
163
164 // Ratio de reparametrisation (C1 si possible)
165 L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
166 L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
167
168 if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
169 Ratio = L1 / L2;
170 }
171 if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
172
173 if (After) {
174// On ne bouge pas la premiere courbe
175 Ratio1 = 1;
176 Delta1 = 0;
177 Ratio2 = 1/Ratio;
178 Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
179 U_de_raccord = FirstCurve->LastParameter();
180 }
181 else {
182// On ne bouge pas la seconde courbe
183 Ratio1 = Ratio;
184 Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
185 Ratio2 = 1;
186 Delta2 = 0;
187 U_de_raccord = SecondCurve->FirstParameter();
188 }
189
190// Les Noeuds
191
192 for (ii=1; ii<NbK1; ii++) {
193 Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
194 Mults(ii) = FirstCurve->Multiplicity(ii);
195 }
196 Noeuds(NbK1) = U_de_raccord;
197 Mults(NbK1) = FirstCurve->Degree();
198 for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
199 Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
200 Mults(jj) = SecondCurve->Multiplicity(ii);
201 }
202 Ratio = FirstCurve->Weight(NbP1) ;
203 Ratio /= SecondCurve->Weight(1) ;
204// Les Poles et Poids
205 for (ii=1; ii<NbP1; ii++) {
206 Poles(ii) = FirstCurve->Pole(ii);
207 Poids(ii) = FirstCurve->Weight(ii);
208 }
209 for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
210 Poles(jj) = SecondCurve->Pole(ii);
211//
212// attentiion les poids ne se raccord pas forcement C0
213// d'ou Ratio
214//
215 Poids(jj) = Ratio * SecondCurve->Weight(ii);
216 }
217
218// Creation de la BSpline
219 myCurve = new (Geom2d_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
220
221// Reduction eventuelle de la multiplicite
222 Standard_Boolean Ok = Standard_True;
223 Standard_Integer M = Mults(NbK1);
224 while ( (M>0) && Ok) {
225 M--;
226 Ok = myCurve->RemoveKnot(NbK1, M, myTol);
227 }
228}
229
230//=======================================================================
231//function : BSplineCurve
232//purpose :
233//=======================================================================
234
235Handle(Geom2d_BSplineCurve) Geom2dConvert_CompCurveToBSplineCurve::BSplineCurve() const
236{
237 return myCurve;
238}
239
240//=======================================================================
241//function : Clear
242//purpose :
243//=======================================================================
244
245void Geom2dConvert_CompCurveToBSplineCurve::Clear()
246{
247 myCurve.Nullify();
248}