1 // Created on: 1994-03-23
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-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 <AppDef_BSplineCompute.hxx>
19 #include <AppDef_MultiLine.hxx>
20 #include <AppDef_MultiPointConstraint.hxx>
21 #include <AppDef_Variational.hxx>
22 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
23 #include <AppParCurves_MultiBSpCurve.hxx>
24 #include <BSplCLib.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom2dAPI_PointsToBSpline.hxx>
27 #include <math_Vector.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <StdFail_NotDone.hxx>
30 #include <TColgp_Array1OfPnt2d.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_Array1OfReal.hxx>
34 //=======================================================================
35 //function : Geom2dAPI_PointsToBSpline
37 //=======================================================================
38 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline()
40 myIsDone = Standard_False;
44 //=======================================================================
45 //function : Geom2dAPI_PointsToBSpline
47 //=======================================================================
49 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
50 (const TColgp_Array1OfPnt2d& Points,
51 const Standard_Integer DegMin,
52 const Standard_Integer DegMax,
53 const GeomAbs_Shape Continuity,
54 const Standard_Real Tol2D)
56 Init(Points,DegMin,DegMax,Continuity,Tol2D);
60 //=======================================================================
61 //function : Geom2dAPI_PointsToBSpline
63 //=======================================================================
65 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
66 (const TColStd_Array1OfReal& YValues,
67 const Standard_Real X0,
68 const Standard_Real DX,
69 const Standard_Integer DegMin,
70 const Standard_Integer DegMax,
71 const GeomAbs_Shape Continuity,
72 const Standard_Real Tol2D)
74 Init(YValues,X0,DX,DegMin,DegMax,Continuity,Tol2D);
77 //=======================================================================
78 //function : Geom2dAPI_PointsToBSpline
80 //=======================================================================
82 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
83 (const TColgp_Array1OfPnt2d& Points,
84 const Approx_ParametrizationType ParType,
85 const Standard_Integer DegMin,
86 const Standard_Integer DegMax,
87 const GeomAbs_Shape Continuity,
88 const Standard_Real Tol2D)
90 myIsDone = Standard_False;
91 Init(Points,ParType,DegMin,DegMax,Continuity,Tol2D);
94 //=======================================================================
95 //function : Geom2dAPI_PointsToBSpline
97 //=======================================================================
99 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
100 (const TColgp_Array1OfPnt2d& Points,
101 const TColStd_Array1OfReal& Params,
102 const Standard_Integer DegMin,
103 const Standard_Integer DegMax,
104 const GeomAbs_Shape Continuity,
105 const Standard_Real Tol2D)
107 myIsDone = Standard_False;
108 Init(Points,Params,DegMin,DegMax,Continuity,Tol2D);
112 //=======================================================================
113 //function : Geom2dAPI_PointsToBSpline
115 //=======================================================================
117 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
118 (const TColgp_Array1OfPnt2d& Points,
119 const Standard_Real W1,
120 const Standard_Real W2,
121 const Standard_Real W3,
122 const Standard_Integer DegMax,
123 const GeomAbs_Shape Continuity,
124 const Standard_Real Tol2D)
126 myIsDone = Standard_False;
127 Init(Points,W1,W2,W3,DegMax,Continuity,Tol2D);
131 //=======================================================================
134 //=======================================================================
136 void Geom2dAPI_PointsToBSpline::Init
137 (const TColgp_Array1OfPnt2d& Points,
138 const Approx_ParametrizationType ParType,
139 const Standard_Integer DegMin,
140 const Standard_Integer DegMax,
141 const GeomAbs_Shape Continuity,
142 const Standard_Real Tol2D)
144 Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
147 Standard_Integer nbit = 2;
148 Standard_Boolean UseSquares = Standard_False;
149 if(Tol2D <= 1.e-3) UseSquares = Standard_True;
151 AppDef_BSplineCompute TheComputer
152 (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
154 switch( Continuity) {
156 TheComputer.SetContinuity(0); break;
160 TheComputer.SetContinuity(1); break;
164 TheComputer.SetContinuity(2); break;
167 TheComputer.SetContinuity(3);
170 TheComputer.Perform(Points);
172 AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
174 TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
176 TheCurve.Curve(1, Poles);
178 myCurve = new Geom2d_BSplineCurve(Poles,
180 TheCurve.Multiplicities(),
182 myIsDone = Standard_True;
185 //=======================================================================
188 //=======================================================================
190 void Geom2dAPI_PointsToBSpline::Init
191 (const TColStd_Array1OfReal& YValues,
192 const Standard_Real X0,
193 const Standard_Real DX,
194 const Standard_Integer DegMin,
195 const Standard_Integer DegMax,
196 const GeomAbs_Shape Continuity,
197 const Standard_Real Tol2D)
199 // first approximate the Y values (with dummy 0 as X values)
201 Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
202 TColgp_Array1OfPnt2d Points(YValues.Lower(),YValues.Upper());
203 math_Vector Param(YValues.Lower(),YValues.Upper());
204 Standard_Real length = DX * (YValues.Upper() - YValues.Lower());
207 for (i = YValues.Lower(); i <= YValues.Upper(); i++) {
208 Param(i) = (X0+(i-1)*DX)/(X0+length);
209 Points(i).SetCoord(0.0, YValues(i));
212 AppDef_BSplineCompute TheComputer
213 (Param, DegMin,DegMax,Tol3D,Tol2D,0, Standard_True, Standard_True);
215 switch( Continuity) {
217 TheComputer.SetContinuity(0); break;
221 TheComputer.SetContinuity(1); break;
225 TheComputer.SetContinuity(2); break;
228 TheComputer.SetContinuity(3);
231 TheComputer.Perform(Points);
233 const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
235 Standard_Integer Degree = TheCurve.Degree();
236 TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
237 Standard_Integer nk = TheCurve.Knots().Length();
238 TColStd_Array1OfReal Knots(1,nk);
239 TColStd_Array1OfInteger Mults(1,nk);
241 TheCurve.Curve(1, Poles);
245 // compute X values for the poles
246 TColStd_Array1OfReal XPoles(1,Poles.Upper());
249 TColStd_Array1OfReal TempPoles(1,2);
250 TColStd_Array1OfReal TempKnots(1,2);
251 TColStd_Array1OfInteger TempMults(1,2);
254 TempPoles(2) = X0 + length;
258 // increase the Degree
259 TColStd_Array1OfReal NewTempPoles(1,Degree+1);
260 TColStd_Array1OfReal NewTempKnots(1,2);
261 TColStd_Array1OfInteger NewTempMults(1,2);
262 BSplCLib::IncreaseDegree(1,Degree,Standard_False,1,
263 TempPoles,TempKnots,TempMults,
264 NewTempPoles,NewTempKnots,NewTempMults);
268 BSplCLib::InsertKnots(Degree,Standard_False,1,
269 NewTempPoles,NewTempKnots,NewTempMults,
270 TheCurve.Knots(),&TheCurve.Multiplicities(),
275 for (i = 1; i <= nk; i++) {
276 Knots(i) = X0 + length * Knots(i);
280 for (i = 1; i <= Poles.Upper(); i++) {
281 Poles(i).SetX(XPoles(i));
286 myCurve = new Geom2d_BSplineCurve(Poles, Knots, Mults, Degree);
287 myIsDone = Standard_True;
290 //=======================================================================
293 //=======================================================================
295 void Geom2dAPI_PointsToBSpline::Init
296 (const TColgp_Array1OfPnt2d& Points,
297 const Standard_Integer DegMin,
298 const Standard_Integer DegMax,
299 const GeomAbs_Shape Continuity,
300 const Standard_Real Tol2D)
302 myIsDone = Standard_False;
303 Init(Points,Approx_ChordLength,DegMin,DegMax,Continuity,Tol2D);
307 //=======================================================================
310 //=======================================================================
312 void Geom2dAPI_PointsToBSpline::Init
313 (const TColgp_Array1OfPnt2d& Points,
314 const TColStd_Array1OfReal& Params,
315 const Standard_Integer DegMin,
316 const Standard_Integer DegMax,
317 const GeomAbs_Shape Continuity,
318 const Standard_Real Tol2D)
320 if (Params.Length() != Points.Length()) throw Standard_OutOfRange ("Geom2dAPI_PointsToBSpline::Init() - invalid input");
322 Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
323 Standard_Integer Nbp = Params.Length();
324 math_Vector theParams(1,Nbp);
328 Standard_Real Uf = Params(Params.Lower());
329 Standard_Real Ul = Params(Params.Upper()) - Uf;
330 for (Standard_Integer i=2; i<Nbp; i++) {
331 theParams(i) = (Params(i)-Uf)/Ul;
334 AppDef_BSplineCompute TheComputer
335 (DegMin,DegMax,Tol3D,Tol2D,0,
336 Standard_True,Approx_IsoParametric,Standard_True);
338 TheComputer.SetParameters(theParams);
340 switch( Continuity) {
342 TheComputer.SetContinuity(0); break;
346 TheComputer.SetContinuity(1); break;
350 TheComputer.SetContinuity(2); break;
353 TheComputer.SetContinuity(3);
356 TheComputer.Perform(Points);
358 AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
360 TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
362 TheCurve.Curve(1, Poles);
364 myCurve = new Geom2d_BSplineCurve(Poles,
366 TheCurve.Multiplicities(),
368 myIsDone = Standard_True;
373 //=======================================================================
376 //=======================================================================
378 void Geom2dAPI_PointsToBSpline::Init
379 (const TColgp_Array1OfPnt2d& Points,
380 const Standard_Real W1,
381 const Standard_Real W2,
382 const Standard_Real W3,
383 const Standard_Integer DegMax,
384 const GeomAbs_Shape Continuity,
385 const Standard_Real Tol2D)
387 Standard_Integer NbPoint = Points.Length(), i;
390 Standard_Integer nbit = 2;
391 if(Tol2D <= 1.e-3) nbit = 0;
395 AppDef_MultiLine multL(NbPoint);
396 for(i = 1; i <= NbPoint; ++i) {
397 AppDef_MultiPointConstraint mpc(0, 1);
398 mpc.SetPoint2d(1, Points.Value(Points.Lower() + i - 1));
399 multL.SetValue(i, mpc);
402 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC =
403 new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
404 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
406 for(i = 1; i <= NbPoint; ++i) {
407 AppParCurves_ConstraintCouple ACC(i,Constraint);
408 TABofCC->SetValue(i,ACC);
412 AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
414 //===================================
415 Standard_Integer theMaxSegments = 1000;
416 Standard_Boolean theWithMinMax = Standard_False;
417 //===================================
419 Variation.SetMaxDegree(DegMax);
420 Variation.SetContinuity(Continuity);
421 Variation.SetMaxSegment(theMaxSegments);
423 Variation.SetTolerance(Tol2D);
424 Variation.SetWithMinMax(theWithMinMax);
425 Variation.SetNbIterations(nbit);
427 Variation.SetCriteriumWeight(W1, W2, W3);
429 if(!Variation.IsCreated()) {
433 if(Variation.IsOverConstrained()) {
438 Variation.Approximate();
440 catch (Standard_Failure const&) {
444 if(!Variation.IsDone()) {
448 AppParCurves_MultiBSpCurve TheCurve = Variation.Value();
450 TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
452 TheCurve.Curve(1, Poles);
454 myCurve = new Geom2d_BSplineCurve(Poles,
456 TheCurve.Multiplicities(),
459 myIsDone = Standard_True;
463 //=======================================================================
464 //function : Handle(Geom2d_BSplineCurve)&
466 //=======================================================================
468 const Handle(Geom2d_BSplineCurve)& Geom2dAPI_PointsToBSpline::Curve() const
471 throw StdFail_NotDone(" ");
477 //=======================================================================
478 //function : Geom2d_BSplineCurve
480 //=======================================================================
482 Geom2dAPI_PointsToBSpline::operator Handle(Geom2d_BSplineCurve)() const
487 //=======================================================================
488 //function : Geom2d_BSplineCurve
490 //=======================================================================
492 Standard_Boolean Geom2dAPI_PointsToBSpline::IsDone() const