1 // File: GeomliteTest_ApproxCommands
2 // Created: Thu Aug 12 19:33:52 1993
3 // Author: Bruno DUMORTIER
6 // PMN : Ajout de la commande smooth
7 // PMN : 11/07/97 Passage a GeomliteTest de bsmooth.
9 #include <Standard_Stream.hxx>
11 #include <GeomliteTest.hxx>
12 #include <DrawTrSurf.hxx>
14 #include <Draw_Appli.hxx>
15 #include <Draw_Interpretor.hxx>
16 #include <Precision.hxx>
17 #include <Draw_Marker3D.hxx>
18 #include <Draw_Marker2D.hxx>
19 #include <TColgp_HArray1OfPnt.hxx>
20 #include <TColgp_SequenceOfPnt.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <Geom_BezierCurve.hxx>
23 #include <TColgp_HArray1OfPnt2d.hxx>
24 #include <TColgp_SequenceOfPnt2d.hxx>
26 #include <Geom2d_BSplineCurve.hxx>
27 #include <Geom2d_BezierCurve.hxx>
28 #include <DrawTrSurf_BSplineCurve.hxx>
29 #include <DrawTrSurf_BezierCurve.hxx>
30 #include <DrawTrSurf_BSplineCurve2d.hxx>
31 #include <DrawTrSurf_BezierCurve2d.hxx>
32 #include <TColgp_HArray1OfPnt.hxx>
33 #include <TColgp_Array1OfPnt.hxx>
34 #include <TColgp_Array1OfPnt2d.hxx>
35 #include <TColgp_HArray1OfVec.hxx>
36 #include <TColgp_Array1OfVec.hxx>
37 #include <TColStd_Array1OfReal.hxx>
38 #include <TColStd_HArray1OfReal.hxx>
39 #include <TColStd_HArray1OfBoolean.hxx>
40 #include <Handle_TColStd_HArray1OfReal.hxx>
41 #include <Handle_TColStd_HArray1OfBoolean.hxx>
43 #include <AppParCurves_MultiBSpCurve.hxx>
44 #include <AppParCurves_MultiCurve.hxx>
45 #include <AppDef_MultiLine.hxx>
46 #include <AppDef_TheVariational.hxx>
47 #include <AppDef_Compute.hxx>
48 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
49 #include <AppParCurves_ConstraintCouple.hxx>
50 #include <AppDef_HArray1OfMultiPointConstraint.hxx>
51 #include <AppDef_Array1OfMultiPointConstraint.hxx>
52 #include <math_Vector.hxx>
56 Standard_IMPORT Draw_Viewer dout;
59 //Draw_Color DrawTrSurf_CurveColor(const Draw_Color);
61 //=======================================================================
62 //function : NbConstraint
63 //=======================================================================
64 static Standard_Integer NbConstraint(const AppParCurves_Constraint C1,
65 const AppParCurves_Constraint C2)
67 Standard_Integer N =0;
69 case AppParCurves_PassPoint :
74 case AppParCurves_TangencyPoint :
79 case AppParCurves_CurvaturePoint :
91 case AppParCurves_PassPoint :
96 case AppParCurves_TangencyPoint :
101 case AppParCurves_CurvaturePoint :
113 //=======================================================================
114 //function : PointsByPick
115 //=======================================================================
116 static Standard_Integer PointsByPick
117 (Handle(AppDef_HArray1OfMultiPointConstraint)& MPC, Draw_Interpretor& di)
119 Standard_Integer id,XX,YY,b, i;
121 di << "Pick points "<< "\n";
122 dout.Select(id, XX, YY, b);
123 Standard_Real zoom = dout.Zoom(id);
124 if (b != 1) return 0;
125 if (id < 0) return 0;
129 //Standard_Boolean newcurve;
133 Handle(Draw_Marker3D) mark;
134 TColgp_SequenceOfPnt ThePoints;
135 P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
136 ThePoints.Append (P);
137 mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
143 dout.Select(id,XX,YY,b, Standard_False);
146 P.SetCoord( (Standard_Real)XX/zoom,
147 (Standard_Real)YY/zoom, 0.0);
149 mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
155 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
156 AppDef_MultiPointConstraint mpc(1,0);
157 MPC->ChangeArray1().Init(mpc);
158 for (i=1; i<=ThePoints.Length(); i++) {
159 AppDef_MultiPointConstraint mpc(1,0);
160 mpc.SetPoint(1, ThePoints.Value(i));
161 MPC->SetValue(i, mpc);
167 Handle(Draw_Marker2D) mark;
168 TColgp_SequenceOfPnt2d ThePoints;
169 P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
170 ThePoints.Append(P2d);
171 mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
177 dout.Select(id,XX,YY,b, Standard_False);
181 P2d.SetCoord( (Standard_Real)XX/zoom, (Standard_Real)YY/zoom );
182 ThePoints.Append (P2d);
183 mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
189 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
190 for (i=1; i<=ThePoints.Length(); i++) {
191 AppDef_MultiPointConstraint mpc(0,1);
192 mpc.SetPoint2d(1, ThePoints.Value(i));
193 MPC->SetValue(i, mpc);
199 //=======================================================================
200 //function : PointsByFile
201 //=======================================================================
202 static void PointsByFile(Handle(AppDef_HArray1OfMultiPointConstraint)& MPC,
203 Handle(AppParCurves_HArray1OfConstraintCouple)& TABofCC,
205 Draw_Interpretor& di)
207 Standard_Integer nbp, i, nbc;
209 Standard_Real x, y, z;
215 if (!strcmp(dimen,"3d")) {
216 Handle(Draw_Marker3D) mark;
217 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
219 for (i = 1; i <= nbp; i++) {
220 iFile >> x >> y >> z;
221 AppDef_MultiPointConstraint mpc(1,0);
222 mpc.SetPoint(1, gp_Pnt(x, y, z));
223 MPC->SetValue(i,mpc);
224 mark = new Draw_Marker3D(gp_Pnt(x, y, z), Draw_X, Draw_orange);
227 Standard_Boolean HasConstrainte = Standard_False;
229 if ( IsControl( (Standard_Character)c) ) {
230 if (iFile.get(c)) HasConstrainte = Standard_True;
232 else HasConstrainte = Standard_True;
235 if (HasConstrainte) {
236 Standard_Integer num, ordre;
238 if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
239 AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
240 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
241 for(i=1; i<=nbp; i++){
242 AppParCurves_ConstraintCouple ACC(i,Constraint);
243 TABofCC->SetValue(i,ACC);
245 for(i=1; i<=nbc; i++) {
246 iFile >> num >> ordre;
247 if ((num<1)||(num>nbp)) {
248 di << "Error on point Index in constrainte" << "\n";
251 Constraint = (AppParCurves_Constraint) (ordre+1);
252 TABofCC->ChangeValue(num).SetConstraint(Constraint);
253 if (Constraint >= AppParCurves_TangencyPoint) {
254 iFile >> x >> y >> z;
255 MPC->ChangeValue(num).SetTang(1, gp_Vec(x,y,z));
257 if (Constraint >= AppParCurves_CurvaturePoint) {
258 iFile >> x >> y >> z;
259 MPC->ChangeValue(num).SetCurv(1, gp_Vec(x,y,z));
265 else if (!strcmp(dimen,"2d")) {
266 Handle(Draw_Marker2D) mark;
267 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
269 for (i = 1; i <= nbp; i++) {
271 AppDef_MultiPointConstraint mpc(0,1);
272 mpc.SetPoint2d(1, gp_Pnt2d(x, y));
273 MPC->SetValue(i, mpc);
274 mark = new Draw_Marker2D(gp_Pnt2d(x, y), Draw_X, Draw_orange);
278 Standard_Boolean HasConstrainte = Standard_False;
280 if ( IsControl( (Standard_Character)c) ) {
281 if (iFile.get(c)) HasConstrainte = Standard_True;
283 else HasConstrainte = Standard_True;
286 if (HasConstrainte) {
287 Standard_Integer num, ordre;
289 if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
290 AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
291 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
292 for(i=1; i<=nbp; i++){
293 AppParCurves_ConstraintCouple ACC(i,Constraint);
294 TABofCC->SetValue(i,ACC);
296 for(i=1; i<=nbc; i++) {
297 iFile >> num >> ordre;
298 if ((num<1)||(num>nbp)) {
299 di << "Error on point Index in constrainte" << "\n";
302 Constraint = (AppParCurves_Constraint) (ordre+1);
303 TABofCC->ChangeValue(num).SetConstraint(Constraint);
304 if (Constraint >= AppParCurves_TangencyPoint) {
306 MPC->ChangeValue(num).SetTang2d(1, gp_Vec2d(x,y));
308 if (Constraint >= AppParCurves_CurvaturePoint) {
310 MPC->ChangeValue(num).SetCurv2d(1, gp_Vec2d(x,y));
319 //==================================================================================
320 static Standard_Integer smoothing (Draw_Interpretor& di,Standard_Integer n, const char** a)
321 //==================================================================================
322 // Tolerance < 0 lissage "filtre"
323 // Tolerance > 0 lissage avec respect de l'erreur max
324 // Tolerance = 0 interpolation.
327 Standard_Real Tolerance=0;
329 AppParCurves_Constraint Constraint;
331 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
333 Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
335 Handle(AppDef_HArray1OfMultiPointConstraint) Points;
336 Standard_Integer id = 0, DegMax = -1;
339 di <<"give a name to your curve !" << "\n";
343 di <<"give a tolerance to your curve !" << "\n";
347 Tolerance = atof(a[2]);
348 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
349 Constraint = AppParCurves_PassPoint;
352 Constraint = AppParCurves_NoConstraint;
354 // Designation Graphique ------------------------
355 id = PointsByPick(Points, di);
358 Standard_Integer ific = 3;
359 Tolerance = atof(a[2]);
360 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
361 Constraint = AppParCurves_PassPoint;
364 Constraint = AppParCurves_NoConstraint;
367 if (! strcmp(a[3],"-D")) {
373 // lecture du fichier.
374 // nbpoints, 2d ou 3d, puis valeurs.
375 const char* nomfic = a[ific];
376 ifstream iFile(nomfic, ios::in);
378 di << a[ific] <<"do not exist !" << "\n";
381 PointsByFile(Points, TABofCC, iFile, di);
384 // Designation Graphique
385 id = PointsByPick(Points, di);
389 AppDef_MultiLine AML(Points->Array1());
391 // Compute --------------
393 if (Points->Value(1).NbPoints()==0){
395 Handle(TColgp_HArray1OfPnt2d) ThePoints;
397 Standard_Integer NbPoints = Points->Length();
398 if (TABofCC.IsNull()) {
399 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
400 for(i=1; i<=NbPoints; i++){
401 AppParCurves_ConstraintCouple ACC(i,Constraint);
402 TABofCC->SetValue(i,ACC);
406 AppDef_TheVariational Variation(AML,
411 if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
412 else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
413 Variation.SetMaxDegree(DegMax);
415 Variation.SetTolerance( Abs(Tolerance));
416 if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
417 Variation.Approximate();
420 //Variation.Dump(cout);
421 Standard_SStream aSStream;
422 Variation.Dump(aSStream);
426 AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
428 TColgp_Array1OfPnt2d ThePoles (1, AnMuC.NbPoles() );
429 AnMuC.Curve(1, ThePoles);
430 Handle(Geom2d_BSplineCurve) Cvliss = new (Geom2d_BSplineCurve)
433 AnMuC. Multiplicities(),
436 Handle(DrawTrSurf_BSplineCurve2d)
437 DC = new DrawTrSurf_BSplineCurve2d(Cvliss);
440 if (id!=0) dout.RepaintView(id);
443 Standard_Integer NbPoints = Points->Length();
444 if (TABofCC.IsNull()) {
445 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
446 for(i=1; i<=NbPoints; i++){
447 AppParCurves_ConstraintCouple ACC(i,Constraint);
448 TABofCC->SetValue(i,ACC);
452 AppDef_TheVariational Variation(AML,
457 if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
458 else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
459 Variation.SetMaxDegree(DegMax);
461 Variation.SetTolerance( Abs(Tolerance));
462 if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
463 Variation.Approximate();
465 //Variation.Dump(cout);
466 Standard_SStream aSStream;
467 Variation.Dump(aSStream);
471 AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
473 TColgp_Array1OfPnt ThePoles (1, AnMuC.NbPoles() );
474 AnMuC.Curve(1, ThePoles);
475 Handle(Geom_BSplineCurve) Cvliss = new (Geom_BSplineCurve)
478 AnMuC. Multiplicities(),
481 Handle(DrawTrSurf_BSplineCurve)
482 DC = new DrawTrSurf_BSplineCurve(Cvliss);
485 if (id!=0) dout.RepaintView(id);
490 //=============================================================================
491 static Standard_Integer smoothingbybezier (Draw_Interpretor& di,
494 //============================================================================
496 Standard_Real Tolerance=0;
498 AppParCurves_Constraint Constraint;
500 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
502 Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
503 Handle(AppDef_HArray1OfMultiPointConstraint) Points;
505 Standard_Integer id = 0;
506 Standard_Integer methode=0;
507 Standard_Integer Degree = 8;
510 di <<"give a name to your curve !" << "\n";
514 di <<"give a tolerance to your curve !" << "\n";
518 di <<"give a max degree!" << "\n";
523 di <<"give an option!" << "\n";
527 Tolerance = atof(a[2]);
529 if (! strcmp(a[4],"-GR")) {
532 else if (! strcmp(a[4],"-PR")) {
537 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
538 Constraint = AppParCurves_PassPoint;
541 Constraint = AppParCurves_NoConstraint;
544 // Designation Graphique ------------------------
545 id = PointsByPick(Points, di);
547 // lecture du fichier.
548 // nbpoints, 2d ou 3d, puis valeurs.
549 const char* nomfic = a[5];
550 ifstream iFile(nomfic, ios::in);
552 di << a[6] <<"do not exist !" << "\n";
555 PointsByFile(Points, TABofCC, iFile, di);
559 AppDef_MultiLine AML(Points->Array1());
561 // Compute --------------
563 if (Points->Value(1).NbPoints()==0){
565 Handle(TColgp_HArray1OfPnt2d) ThePoints;
567 Standard_Integer NbPoints = Points->Length();
568 if (TABofCC.IsNull()) {
569 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
570 for(i=1; i<=NbPoints; i++){
571 AppParCurves_ConstraintCouple ACC(i,Constraint);
572 TABofCC->SetValue(i,ACC);
575 AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
576 if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
577 TABofCC->SetValue(1, AC1);
579 AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
580 if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
581 TABofCC->SetValue(NbPoints, AC2);
585 Standard_Boolean mySquare = (methode == 2);
586 Standard_Integer degmin = 4;
587 Standard_Integer NbIteration = 5;
589 Standard_Integer NbConst =
591 NbConstraint(TABofCC->Value(1).Constraint(),
592 TABofCC->Value(NbPoints).Constraint());
594 if (Degree < 4) degmin = Max(1, Degree -1);
595 degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),
596 TABofCC->Value(NbPoints).Constraint()) );
598 AppDef_Compute Appr(degmin, Degree,
599 Abs(Tolerance), Abs(Tolerance),
600 NbIteration, Standard_False,
601 Approx_ChordLength, mySquare);
603 Appr.SetConstraints(TABofCC->Value(1).Constraint(),
604 TABofCC->Value(NbPoints).Constraint());
608 if (! Appr.IsAllApproximated()) {
609 di << " No result" << "\n";
611 AppParCurves_MultiCurve AnMuC = Appr.Value();
612 ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() );
613 AnMuC.Curve(1, ThePoints->ChangeArray1());
614 Standard_Real err, err2d;
615 Appr.Error(1, err, err2d);
616 di <<" Error2D is : " << err2d << "\n";
619 AppDef_TheVariational Varia(AML,
623 Varia.SetTolerance(Abs(Tolerance));
626 if (! Varia.IsDone()) {
627 di << " No result" << "\n";
630 AppParCurves_MultiBSpCurve AnMuC = Varia.Value();
631 di <<" Error2D is : " << Varia.MaxError() << "\n";
632 ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() );
633 AnMuC.Curve(1, ThePoints->ChangeArray1());
636 Handle(Geom2d_BezierCurve) Cvliss =
637 new (Geom2d_BezierCurve)(ThePoints->Array1());
639 Handle(DrawTrSurf_BezierCurve2d) DC =
640 new (DrawTrSurf_BezierCurve2d) (Cvliss);
642 if (id!=0) dout.RepaintView(id);
646 Handle(TColgp_HArray1OfPnt) ThePoints;
647 Standard_Integer NbPoints = Points->Length();
648 if (TABofCC.IsNull()) {
649 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
650 for(i=1; i<=NbPoints; i++){
651 AppParCurves_ConstraintCouple ACC(i,Constraint);
652 TABofCC->SetValue(i,ACC);
656 AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
657 if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
658 TABofCC->SetValue(1, AC1);
660 AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
661 if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
662 TABofCC->SetValue(NbPoints, AC2);
666 Standard_Boolean mySquare = (methode == 2);
667 Standard_Integer degmin = 4;
668 Standard_Integer NbIteration = 5;
669 if (Degree < 4) degmin = Max(1, Degree - 1);
670 degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),
671 TABofCC->Value(NbPoints).Constraint()) );
673 AppDef_Compute Appr(degmin, Degree,
674 Abs(Tolerance), Abs(Tolerance),
675 NbIteration, Standard_False,
676 Approx_ChordLength, mySquare);
678 Appr.SetConstraints(TABofCC->Value(1).Constraint(),
679 TABofCC->Value(NbPoints).Constraint());
683 if (! Appr.IsAllApproximated()) {
684 di << " No result" << "\n";
686 AppParCurves_MultiCurve AnMuC = Appr.Value();
687 ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() );
688 AnMuC.Curve(1, ThePoints->ChangeArray1());
689 Standard_Real err, err2d;
690 Appr.Error(1, err, err2d);
691 di <<" Error3D is : " << err << "\n";
694 AppDef_TheVariational Varia(AML,
699 Varia.SetTolerance(Abs(Tolerance));
701 if (! Varia.IsDone()) {
702 di << " No result" << "\n";
705 AppParCurves_MultiBSpCurve AnMuC = Varia.Value();
706 di <<" Error3D is : " << Varia.MaxError() << "\n";
707 ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() );
708 AnMuC.Curve(1, ThePoints->ChangeArray1());
711 Handle(Geom_BezierCurve) Cvliss =
712 new (Geom_BezierCurve)(ThePoints->Array1());
714 Handle(DrawTrSurf_BezierCurve)
715 DC = new DrawTrSurf_BezierCurve(Cvliss);
717 if (id!=0) dout.RepaintView(id);
722 //=======================================================================
723 //function : ConstraintCommands
725 //=======================================================================
728 void GeomliteTest::ApproxCommands(Draw_Interpretor& theCommands)
731 static Standard_Boolean loaded = Standard_False;
733 loaded = Standard_True;
735 DrawTrSurf::BasicCommands(theCommands);
738 // constrained constructs
739 g = "GEOMETRY Constraints";
742 theCommands.Add("bsmooth",
743 "bsmooth cname tol [-D degree] [fic]",
747 theCommands.Add("bzsmooth",
748 "bzsmooth cname tol degree option [fic]",
750 smoothingbybezier, g);