1 // Created on: 1995-01-17
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-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.
17 #include <GeomAPI_PointsToBSplineSurface.ixx>
19 #include <Geom_BSplineCurve.hxx>
20 #include <GeomFill_SectionGenerator.hxx>
21 #include <GeomFill_Line.hxx>
22 #include <GeomFill_AppSurf.hxx>
23 #include <GeomAPI_PointsToBSpline.hxx>
24 #include <AppDef_BSplineCompute.hxx>
25 #include <AppDef_MultiLine.hxx>
26 #include <AppDef_MultiPointConstraint.hxx>
27 #include <BSplCLib.hxx>
28 #include <Precision.hxx>
30 #include <TColgp_Array1OfPnt.hxx>
31 #include <math_Vector.hxx>
32 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
33 #include <AppParCurves_ConstraintCouple.hxx>
34 #include <AppDef_TheVariational.hxx>
37 //=======================================================================
38 //function : GeomAPI_PointsToBSplineSurface
40 //=======================================================================
42 GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface()
43 : myIsDone ( Standard_False)
48 //=======================================================================
49 //function : GeomAPI_PointsToBSplineSurface
51 //=======================================================================
53 GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface
54 (const TColgp_Array2OfPnt& Points,
55 const Standard_Integer DegMin,
56 const Standard_Integer DegMax,
57 const GeomAbs_Shape Continuity,
58 const Standard_Real Tol3D)
59 : myIsDone ( Standard_False)
61 Init(Points,DegMin,DegMax,Continuity,Tol3D);
64 //=======================================================================
65 //function : GeomAPI_PointsToBSplineSurface
67 //=======================================================================
69 GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface
70 (const TColgp_Array2OfPnt& Points,
71 const Approx_ParametrizationType ParType,
72 const Standard_Integer DegMin,
73 const Standard_Integer DegMax,
74 const GeomAbs_Shape Continuity,
75 const Standard_Real Tol3D)
76 : myIsDone ( Standard_False)
78 Init(Points,ParType,DegMin,DegMax,Continuity,Tol3D);
81 //=======================================================================
82 //function : GeomAPI_PointsToBSplineSurface
84 //=======================================================================
86 GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface
87 (const TColgp_Array2OfPnt& Points,
88 const Standard_Real Weight1,
89 const Standard_Real Weight2,
90 const Standard_Real Weight3,
91 const Standard_Integer DegMax,
92 const GeomAbs_Shape Continuity,
93 const Standard_Real Tol3D)
94 : myIsDone ( Standard_False)
96 Init(Points,Weight1,Weight2,Weight3,DegMax,Continuity,Tol3D);
101 //=======================================================================
102 //function : GeomAPI_PointsToBSplineSurface
104 //=======================================================================
106 GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface
107 (const TColStd_Array2OfReal& ZPoints,
108 const Standard_Real X0,
109 const Standard_Real dX,
110 const Standard_Real Y0,
111 const Standard_Real dY,
112 const Standard_Integer DegMin,
113 const Standard_Integer DegMax,
114 const GeomAbs_Shape Continuity,
115 const Standard_Real Tol3D)
116 : myIsDone ( Standard_False)
118 Init(ZPoints,X0,dX,Y0,dY,DegMin,DegMax,Continuity,Tol3D);
123 //=======================================================================
124 //function : Interpolate
126 //=======================================================================
128 void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Points)
130 Interpolate(Points, Approx_ChordLength);
133 //=======================================================================
134 //function : Interpolate
136 //=======================================================================
138 void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Points,
139 const Approx_ParametrizationType ParType)
141 Standard_Integer DegMin, DegMax;
143 GeomAbs_Shape CC = GeomAbs_C2;
144 Standard_Real Tol3d = -1.0;
145 Init(Points, ParType, DegMin, DegMax, CC, Tol3d);
149 //=======================================================================
152 //=======================================================================
154 void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
155 const Standard_Integer DegMin,
156 const Standard_Integer DegMax,
157 const GeomAbs_Shape Continuity,
158 const Standard_Real Tol3D)
160 Init(Points, Approx_ChordLength, DegMin, DegMax, Continuity, Tol3D);
162 //=======================================================================
165 //=======================================================================
167 void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
168 const Approx_ParametrizationType ParType,
169 const Standard_Integer DegMin,
170 const Standard_Integer DegMax,
171 const GeomAbs_Shape Continuity,
172 const Standard_Real Tol3D)
174 Standard_Integer Imin = Points.LowerRow();
175 Standard_Integer Imax = Points.UpperRow();
176 Standard_Integer Jmin = Points.LowerCol();
177 Standard_Integer Jmax = Points.UpperCol();
179 Standard_Real Tol2D = Tol3D;
181 // first approximate the V isos:
182 AppDef_MultiLine Line(Jmax-Jmin+1);
183 Standard_Integer i, j;
184 // Standard_Real X, Y;
186 for (j = Jmin; j <= Jmax; j++) {
187 AppDef_MultiPointConstraint MP(Imax-Imin+1, 0);
188 for (i = Imin; i <= Imax; i++) {
189 MP.SetPoint(i, Points(i,j));
191 Line.SetValue(j, MP);
194 Standard_Integer nbit = 2;
195 Standard_Boolean UseSquares = Standard_False;
196 if(Tol3D <= 1.e-3) UseSquares = Standard_True;
198 AppDef_BSplineCompute TheComputer
199 (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
201 switch( Continuity) {
203 TheComputer.SetContinuity(0); break;
207 TheComputer.SetContinuity(1); break;
211 TheComputer.SetContinuity(2); break;
214 TheComputer.SetContinuity(3);
218 TheComputer.Interpol(Line);
221 TheComputer.Perform(Line);
224 const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
226 Standard_Integer VDegree = TheCurve.Degree();
227 TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
228 const TColStd_Array1OfReal& VKnots = TheCurve.Knots();
229 const TColStd_Array1OfInteger& VMults = TheCurve.Multiplicities();
232 Standard_Integer nbisosu = Imax-Imin+1;
233 AppDef_MultiLine Line2(nbisosu);
235 for (i = 1; i <= nbisosu; i++) {
236 TheCurve.Curve(i, Poles);
237 AppDef_MultiPointConstraint MP(Poles.Upper(),0);
238 for (j = 1; j <= Poles.Upper(); j++) {
239 MP.SetPoint(j, Poles(j));
241 Line2.SetValue(i, MP);
245 // approximate the resulting poles:
247 AppDef_BSplineCompute TheComputer2
248 (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
250 TheComputer2.Interpol(Line2);
253 TheComputer2.Perform(Line2);
256 const AppParCurves_MultiBSpCurve& TheCurve2 = TheComputer2.Value();
258 Standard_Integer UDegree = TheCurve2.Degree();
259 TColgp_Array1OfPnt Poles2(1,TheCurve2.NbPoles());
260 const TColStd_Array1OfReal& UKnots = TheCurve2.Knots();
261 const TColStd_Array1OfInteger& UMults = TheCurve2.Multiplicities();
264 // computing the surface
265 TColgp_Array2OfPnt ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
266 for ( j = 1; j <= Poles.Upper(); j++) {
267 TheCurve2.Curve(j, Poles2);
268 for (i = 1; i<= Poles2.Upper(); i++) {
269 ThePoles(i, j) = Poles2(i);
274 mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults,
277 myIsDone = Standard_True;
281 //=======================================================================
284 //=======================================================================
286 void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
287 const Standard_Real Weight1,
288 const Standard_Real Weight2,
289 const Standard_Real Weight3,
290 const Standard_Integer DegMax,
291 const GeomAbs_Shape Continuity,
292 const Standard_Real Tol3D)
294 Standard_Integer Imin = Points.LowerRow();
295 Standard_Integer Imax = Points.UpperRow();
296 Standard_Integer Jmin = Points.LowerCol();
297 Standard_Integer Jmax = Points.UpperCol();
299 Standard_Integer nbit = 2;
300 if(Tol3D <= 1.e-3) nbit = 0;
302 // first approximate the V isos:
303 Standard_Integer NbPointJ = Jmax-Jmin+1;
304 Standard_Integer NbPointI = Imax-Imin+1;
305 Standard_Integer i, j;
307 AppDef_MultiLine Line(NbPointJ);
309 for (j = Jmin; j <= Jmax; j++) {
310 AppDef_MultiPointConstraint MP(NbPointI, 0);
311 for (i = Imin; i <= Imax; i++) {
312 MP.SetPoint(i, Points(i,j));
314 Line.SetValue(j, MP);
318 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC =
319 new AppParCurves_HArray1OfConstraintCouple(1, NbPointJ);
320 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
322 for(i = 1; i <= NbPointJ; ++i) {
323 AppParCurves_ConstraintCouple ACC(i,Constraint);
324 TABofCC->SetValue(i,ACC);
328 AppDef_TheVariational Variation(Line, 1, NbPointJ, TABofCC);
330 //===================================
331 Standard_Integer theMaxSegments = 1000;
332 Standard_Boolean theWithMinMax = Standard_False;
333 //===================================
335 Variation.SetMaxDegree(DegMax);
336 Variation.SetContinuity(Continuity);
337 Variation.SetMaxSegment(theMaxSegments);
339 Variation.SetTolerance(Tol3D);
340 Variation.SetWithMinMax(theWithMinMax);
341 Variation.SetNbIterations(nbit);
343 Variation.SetCriteriumWeight(Weight1, Weight2, Weight3);
345 if(!Variation.IsCreated()) {
349 if(Variation.IsOverConstrained()) {
354 Variation.Approximate();
356 catch (Standard_Failure) {
360 if(!Variation.IsDone()) {
364 const AppParCurves_MultiBSpCurve& TheCurve = Variation.Value();
366 Standard_Integer VDegree = TheCurve.Degree();
367 TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
368 const TColStd_Array1OfReal& VKnots = TheCurve.Knots();
369 const TColStd_Array1OfInteger& VMults = TheCurve.Multiplicities();
372 AppDef_MultiLine Line2(NbPointI);
374 for (i = 1; i <= NbPointI; i++) {
375 TheCurve.Curve(i, Poles);
376 AppDef_MultiPointConstraint MP(Poles.Upper(),0);
377 for (j = 1; j <= Poles.Upper(); j++) {
378 MP.SetPoint(j, Poles(j));
380 Line2.SetValue(i, MP);
384 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC2 =
385 new AppParCurves_HArray1OfConstraintCouple(1, NbPointI);
387 for(i = 1; i <= NbPointI; ++i) {
388 AppParCurves_ConstraintCouple ACC(i,Constraint);
389 TABofCC2->SetValue(i,ACC);
393 AppDef_TheVariational Variation2(Line2, 1, NbPointI, TABofCC2);
395 Variation2.SetMaxDegree(DegMax);
396 Variation2.SetContinuity(Continuity);
397 Variation2.SetMaxSegment(theMaxSegments);
399 Variation2.SetTolerance(Tol3D);
400 Variation2.SetWithMinMax(theWithMinMax);
401 Variation2.SetNbIterations(nbit);
403 Variation2.SetCriteriumWeight(Weight1, Weight2, Weight3);
405 if(!Variation2.IsCreated()) {
409 if(Variation2.IsOverConstrained()) {
414 Variation2.Approximate();
416 catch (Standard_Failure) {
420 if(!Variation2.IsDone()) {
424 const AppParCurves_MultiBSpCurve& TheCurve2 = Variation2.Value();
426 Standard_Integer UDegree = TheCurve2.Degree();
427 TColgp_Array1OfPnt Poles2(1,TheCurve2.NbPoles());
428 const TColStd_Array1OfReal& UKnots = TheCurve2.Knots();
429 const TColStd_Array1OfInteger& UMults = TheCurve2.Multiplicities();
432 // computing the surface
433 TColgp_Array2OfPnt ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
434 for ( j = 1; j <= Poles.Upper(); j++) {
435 TheCurve2.Curve(j, Poles2);
436 for (i = 1; i<= Poles2.Upper(); i++) {
437 ThePoles(i, j) = Poles2(i);
442 mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults,
445 myIsDone = Standard_True;
447 //=======================================================================
450 //=======================================================================
452 void GeomAPI_PointsToBSplineSurface::Interpolate(const TColStd_Array2OfReal& ZPoints,
453 const Standard_Real X0,
454 const Standard_Real dX,
455 const Standard_Real Y0,
456 const Standard_Real dY)
458 Standard_Integer DegMin, DegMax;
460 Standard_Real Tol3D = -1.0;
461 GeomAbs_Shape CC = GeomAbs_C2;
462 Init(ZPoints, X0, dX, Y0, dY, DegMin, DegMax, CC, Tol3D);
465 //=======================================================================
468 //=======================================================================
470 void GeomAPI_PointsToBSplineSurface::Init(const TColStd_Array2OfReal& ZPoints,
471 const Standard_Real X0,
472 const Standard_Real dX,
473 const Standard_Real Y0,
474 const Standard_Real dY,
475 const Standard_Integer DegMin,
476 const Standard_Integer DegMax,
477 const GeomAbs_Shape Continuity,
478 const Standard_Real Tol3D)
480 Standard_Integer Imin = ZPoints.LowerRow();
481 Standard_Integer Imax = ZPoints.UpperRow();
482 Standard_Integer Jmin = ZPoints.LowerCol();
483 Standard_Integer Jmax = ZPoints.UpperCol();
484 Standard_Real length;
486 Standard_Real Tol2D = Tol3D;
488 // first approximate the V isos:
489 AppDef_MultiLine Line(Jmax-Jmin+1);
490 math_Vector Param(Jmin, Jmax);
491 Standard_Integer i, j;
492 // Standard_Real X, Y;
493 length = dY * (Jmax-Jmin);
495 for (j = Jmin; j <= Jmax; j++) {
496 AppDef_MultiPointConstraint MP(0, Imax-Imin+1);
497 for (i = Imin; i <= Imax; i++) {
498 MP.SetPoint2d(i, gp_Pnt2d(0.0, ZPoints(i, j)));
500 Param(j) = (Standard_Real)(j-Jmin)/(Standard_Real)(Jmax-Jmin);
501 Line.SetValue(j, MP);
504 AppDef_BSplineCompute TheComputer
505 (Param, DegMin,DegMax,Tol3D,Tol2D,0, Standard_True, Standard_True);
507 switch( Continuity) {
509 TheComputer.SetContinuity(0); break;
513 TheComputer.SetContinuity(1); break;
517 TheComputer.SetContinuity(2); break;
520 TheComputer.SetContinuity(3);
524 TheComputer.Interpol(Line);
527 TheComputer.Perform(Line);
531 const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
533 Standard_Integer VDegree = TheCurve.Degree();
534 TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
535 Standard_Integer nk = TheCurve.Knots().Length();
536 TColStd_Array1OfReal VKnots(1,nk);
537 TColStd_Array1OfInteger VMults(1,nk);
540 // compute Y values for the poles
541 TColStd_Array1OfReal YPoles(1,Poles.Upper());
544 TColStd_Array1OfReal TempPoles(1,2);
545 TColStd_Array1OfReal TempKnots(1,2);
546 TColStd_Array1OfInteger TempMults(1,2);
549 TempPoles(2) = Y0 + length;
553 // increase the Degree
554 TColStd_Array1OfReal NewTempPoles(1,VDegree+1);
555 TColStd_Array1OfReal NewTempKnots(1,2);
556 TColStd_Array1OfInteger NewTempMults(1,2);
557 BSplCLib::IncreaseDegree(1,VDegree,Standard_False,1,
558 TempPoles,TempKnots,TempMults,
559 NewTempPoles,NewTempKnots,NewTempMults);
563 BSplCLib::InsertKnots(VDegree,Standard_False,1,
564 NewTempPoles,NewTempKnots,NewTempMults,
565 TheCurve.Knots(),TheCurve.Multiplicities(),
566 YPoles,VKnots,VMults,
570 for (i = 1; i <= nk; i++) {
571 VKnots(i) = Y0 + length * VKnots(i);
575 Standard_Integer nbisosu = Imax-Imin+1;
576 AppDef_MultiLine Line2(nbisosu);
577 math_Vector Param2(1, nbisosu);
578 length = dX*(Imax-Imin);
580 for (i = 1; i <= nbisosu; i++) {
581 TheCurve.Curve(i, Poles);
582 AppDef_MultiPointConstraint MP(0, Poles.Upper());
583 for (j = 1; j <= Poles.Upper(); j++) {
584 MP.SetPoint2d(j, gp_Pnt2d(0.0, Poles(j).Y()));
586 Param2(i) = (Standard_Real)(i-1)/(Standard_Real)(nbisosu-1);
587 Line2.SetValue(i, MP);
591 // approximate the resulting poles:
593 AppDef_BSplineCompute TheComputer2
594 (Param2, DegMin,DegMax,Tol3D,Tol2D,0, Standard_True, Standard_True);
596 TheComputer2.Interpol(Line2);
599 TheComputer2.Perform(Line2);
602 const AppParCurves_MultiBSpCurve& TheCurve2 = TheComputer2.Value();
604 Standard_Integer UDegree = TheCurve2.Degree();
605 TColgp_Array1OfPnt2d Poles2(1,TheCurve2.NbPoles());
606 Standard_Integer nk2 = TheCurve2.Knots().Length();
607 TColStd_Array1OfReal UKnots(1,nk2);
608 TColStd_Array1OfInteger UMults(1,nk2);
611 // compute X values for the poles
612 TColStd_Array1OfReal XPoles(1,Poles2.Upper());
616 TempPoles(2) = X0 + length;
619 TempMults(1) = TempMults(2) = 2;
621 // increase the Degree
622 TColStd_Array1OfReal NewTempPoles2(1,UDegree+1);
623 BSplCLib::IncreaseDegree(1,UDegree,Standard_False,1,
624 TempPoles,TempKnots,TempMults,
625 NewTempPoles2,NewTempKnots,NewTempMults);
629 BSplCLib::InsertKnots(UDegree,Standard_False,1,
630 NewTempPoles2,NewTempKnots,NewTempMults,
631 TheCurve2.Knots(),TheCurve2.Multiplicities(),
632 XPoles,UKnots,UMults,
636 for (i = 1; i <= nk2; i++) {
637 UKnots(i) = X0 + length * UKnots(i);
640 // creating the surface
641 TColgp_Array2OfPnt ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
643 for ( j = 1; j <= Poles.Upper(); j++) {
644 TheCurve2.Curve(j, Poles2);
645 for (i = 1; i<= Poles2.Upper(); i++) {
646 ThePoles(i, j).SetCoord(XPoles(i), YPoles(j), Poles2(i).Y());
651 mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults,
654 myIsDone = Standard_True;
659 //=======================================================================
660 //function : Handle_Geom_BSplineSurface&
662 //=======================================================================
664 const Handle(Geom_BSplineSurface)& GeomAPI_PointsToBSplineSurface::Surface()
667 StdFail_NotDone_Raise_if
669 "GeomAPI_PointsToBSplineSurface: Surface not done");
676 //=======================================================================
679 //=======================================================================
681 GeomAPI_PointsToBSplineSurface::operator Handle(Geom_BSplineSurface)() const
686 //=======================================================================
689 //=======================================================================
691 Standard_Boolean GeomAPI_PointsToBSplineSurface::IsDone () const