1 // Created on: 1993-08-12
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-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 // PMN : Ajout de la commande smooth
18 // PMN : 11/07/97 Passage a GeomliteTest de bsmooth.
20 #include <Standard_Stream.hxx>
22 #include <GeomliteTest.hxx>
23 #include <DrawTrSurf.hxx>
25 #include <Draw_Appli.hxx>
26 #include <Draw_Interpretor.hxx>
27 #include <Precision.hxx>
28 #include <Draw_Marker3D.hxx>
29 #include <Draw_Marker2D.hxx>
30 #include <TColgp_HArray1OfPnt.hxx>
31 #include <TColgp_SequenceOfPnt.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <Geom_BezierCurve.hxx>
34 #include <TColgp_HArray1OfPnt2d.hxx>
35 #include <TColgp_SequenceOfPnt2d.hxx>
37 #include <Geom2d_BSplineCurve.hxx>
38 #include <Geom2d_BezierCurve.hxx>
39 #include <DrawTrSurf_BSplineCurve.hxx>
40 #include <DrawTrSurf_BezierCurve.hxx>
41 #include <DrawTrSurf_BSplineCurve2d.hxx>
42 #include <DrawTrSurf_BezierCurve2d.hxx>
43 #include <TColgp_HArray1OfPnt.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColgp_Array1OfPnt2d.hxx>
46 #include <TColgp_HArray1OfVec.hxx>
47 #include <TColgp_Array1OfVec.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_HArray1OfReal.hxx>
50 #include <TColStd_HArray1OfBoolean.hxx>
52 #include <AppParCurves_MultiBSpCurve.hxx>
53 #include <AppParCurves_MultiCurve.hxx>
54 #include <AppDef_MultiLine.hxx>
55 #include <AppDef_Variational.hxx>
56 #include <AppDef_Compute.hxx>
57 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
58 #include <AppParCurves_ConstraintCouple.hxx>
59 #include <AppDef_HArray1OfMultiPointConstraint.hxx>
60 #include <AppDef_Array1OfMultiPointConstraint.hxx>
61 #include <math_Vector.hxx>
68 Standard_IMPORT Draw_Viewer dout;
71 //Draw_Color DrawTrSurf_CurveColor(const Draw_Color);
73 //=======================================================================
74 //function : NbConstraint
75 //=======================================================================
76 static Standard_Integer NbConstraint(const AppParCurves_Constraint C1,
77 const AppParCurves_Constraint C2)
79 Standard_Integer N =0;
81 case AppParCurves_PassPoint :
86 case AppParCurves_TangencyPoint :
91 case AppParCurves_CurvaturePoint :
101 case AppParCurves_PassPoint :
106 case AppParCurves_TangencyPoint :
111 case AppParCurves_CurvaturePoint :
121 //=======================================================================
122 //function : PointsByPick
123 //=======================================================================
124 static Standard_Integer PointsByPick
125 (Handle(AppDef_HArray1OfMultiPointConstraint)& MPC, Draw_Interpretor& di)
127 Standard_Integer id,XX,YY,b, i;
129 di << "Pick points "<< "\n";
130 dout.Select(id, XX, YY, b);
131 Standard_Real zoom = dout.Zoom(id);
132 if (b != 1) return 0;
133 if (id < 0) return 0;
137 //Standard_Boolean newcurve;
141 Handle(Draw_Marker3D) mark;
142 TColgp_SequenceOfPnt ThePoints;
143 P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
144 ThePoints.Append (P);
145 mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
151 dout.Select(id,XX,YY,b, Standard_False);
154 P.SetCoord( (Standard_Real)XX/zoom,
155 (Standard_Real)YY/zoom, 0.0);
157 mark = new Draw_Marker3D(P, Draw_X, Draw_orange);
163 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
164 AppDef_MultiPointConstraint mpc(1,0);
165 MPC->ChangeArray1().Init(mpc);
166 for (i=1; i<=ThePoints.Length(); i++) {
167 AppDef_MultiPointConstraint aLocalMpc(1,0);
168 aLocalMpc.SetPoint(1, ThePoints.Value(i));
169 MPC->SetValue(i, aLocalMpc);
175 Handle(Draw_Marker2D) mark;
176 TColgp_SequenceOfPnt2d ThePoints;
177 P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
178 ThePoints.Append(P2d);
179 mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
185 dout.Select(id,XX,YY,b, Standard_False);
189 P2d.SetCoord( (Standard_Real)XX/zoom, (Standard_Real)YY/zoom );
190 ThePoints.Append (P2d);
191 mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange);
197 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length());
198 for (i=1; i<=ThePoints.Length(); i++) {
199 AppDef_MultiPointConstraint mpc(0,1);
200 mpc.SetPoint2d(1, ThePoints.Value(i));
201 MPC->SetValue(i, mpc);
207 //=======================================================================
208 //function : PointsByFile
209 //=======================================================================
210 static void PointsByFile(Handle(AppDef_HArray1OfMultiPointConstraint)& MPC,
211 Handle(AppParCurves_HArray1OfConstraintCouple)& TABofCC,
213 Draw_Interpretor& di)
215 Standard_Integer nbp, i, nbc;
217 Standard_Real x, y, z;
223 if (!strcmp(dimen,"3d")) {
224 Handle(Draw_Marker3D) mark;
225 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
227 for (i = 1; i <= nbp; i++) {
228 iFile >> x >> y >> z;
229 AppDef_MultiPointConstraint mpc(1,0);
230 mpc.SetPoint(1, gp_Pnt(x, y, z));
231 MPC->SetValue(i,mpc);
232 mark = new Draw_Marker3D(gp_Pnt(x, y, z), Draw_X, Draw_orange);
235 Standard_Boolean HasConstrainte = Standard_False;
237 if ( IsControl( (Standard_Character)c) ) {
238 if (iFile.get(c)) HasConstrainte = Standard_True;
240 else HasConstrainte = Standard_True;
243 if (HasConstrainte) {
244 Standard_Integer num, ordre;
246 if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
247 AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
248 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
249 for(i=1; i<=nbp; i++){
250 AppParCurves_ConstraintCouple ACC(i,Constraint);
251 TABofCC->SetValue(i,ACC);
253 for(i=1; i<=nbc; i++) {
254 iFile >> num >> ordre;
255 if ((num<1)||(num>nbp)) {
256 di << "Error on point Index in constrainte" << "\n";
259 Constraint = (AppParCurves_Constraint) (ordre+1);
260 TABofCC->ChangeValue(num).SetConstraint(Constraint);
261 if (Constraint >= AppParCurves_TangencyPoint) {
262 iFile >> x >> y >> z;
263 MPC->ChangeValue(num).SetTang(1, gp_Vec(x,y,z));
265 if (Constraint >= AppParCurves_CurvaturePoint) {
266 iFile >> x >> y >> z;
267 MPC->ChangeValue(num).SetCurv(1, gp_Vec(x,y,z));
273 else if (!strcmp(dimen,"2d")) {
274 Handle(Draw_Marker2D) mark;
275 MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp);
277 for (i = 1; i <= nbp; i++) {
279 AppDef_MultiPointConstraint mpc(0,1);
280 mpc.SetPoint2d(1, gp_Pnt2d(x, y));
281 MPC->SetValue(i, mpc);
282 mark = new Draw_Marker2D(gp_Pnt2d(x, y), Draw_X, Draw_orange);
286 Standard_Boolean HasConstrainte = Standard_False;
288 if ( IsControl( (Standard_Character)c) ) {
289 if (iFile.get(c)) HasConstrainte = Standard_True;
291 else HasConstrainte = Standard_True;
294 if (HasConstrainte) {
295 Standard_Integer num, ordre;
297 if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme
298 AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
299 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp);
300 for(i=1; i<=nbp; i++){
301 AppParCurves_ConstraintCouple ACC(i,Constraint);
302 TABofCC->SetValue(i,ACC);
304 for(i=1; i<=nbc; i++) {
305 iFile >> num >> ordre;
306 if ((num<1)||(num>nbp)) {
307 di << "Error on point Index in constrainte" << "\n";
310 Constraint = (AppParCurves_Constraint) (ordre+1);
311 TABofCC->ChangeValue(num).SetConstraint(Constraint);
312 if (Constraint >= AppParCurves_TangencyPoint) {
314 MPC->ChangeValue(num).SetTang2d(1, gp_Vec2d(x,y));
316 if (Constraint >= AppParCurves_CurvaturePoint) {
318 MPC->ChangeValue(num).SetCurv2d(1, gp_Vec2d(x,y));
327 //==================================================================================
328 static Standard_Integer smoothing (Draw_Interpretor& di,Standard_Integer n, const char** a)
329 //==================================================================================
330 // Tolerance < 0 lissage "filtre"
331 // Tolerance > 0 lissage avec respect de l'erreur max
332 // Tolerance = 0 interpolation.
335 Standard_Real Tolerance=0;
337 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
339 Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
341 Handle(AppDef_HArray1OfMultiPointConstraint) Points;
342 Standard_Integer id = 0, DegMax = -1;
345 di <<"give a name to your curve !" << "\n";
349 di <<"give a tolerance to your curve !" << "\n";
353 Tolerance = Draw::Atof(a[2]);
354 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
355 Constraint = AppParCurves_PassPoint;
358 Constraint = AppParCurves_NoConstraint;
360 // Designation Graphique ------------------------
361 id = PointsByPick(Points, di);
364 Standard_Integer ific = 3;
365 Tolerance = Draw::Atof(a[2]);
366 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
367 Constraint = AppParCurves_PassPoint;
370 Constraint = AppParCurves_NoConstraint;
373 if (! strcmp(a[3],"-D")) {
374 DegMax = Draw::Atoi(a[4]);
379 // lecture du fichier.
380 // nbpoints, 2d ou 3d, puis valeurs.
381 const char* nomfic = a[ific];
382 ifstream iFile(nomfic, ios::in);
384 di << a[ific] <<"do not exist !" << "\n";
387 PointsByFile(Points, TABofCC, iFile, di);
390 // Designation Graphique
391 id = PointsByPick(Points, di);
395 AppDef_MultiLine AML(Points->Array1());
397 // Compute --------------
399 if (Points->Value(1).NbPoints()==0){
401 Handle(TColgp_HArray1OfPnt2d) ThePoints;
403 Standard_Integer NbPoints = Points->Length();
404 if (TABofCC.IsNull()) {
405 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
406 for(i=1; i<=NbPoints; i++){
407 AppParCurves_ConstraintCouple ACC(i,Constraint);
408 TABofCC->SetValue(i,ACC);
412 AppDef_Variational Variation(AML,
417 if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
418 else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
419 Variation.SetMaxDegree(DegMax);
421 Variation.SetTolerance( Abs(Tolerance));
422 if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
423 Variation.Approximate();
425 # ifdef GEOMLITETEST_DEB
426 //Variation.Dump(cout);
427 Standard_SStream aSStream;
428 Variation.Dump(aSStream);
432 AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
434 TColgp_Array1OfPnt2d ThePoles (1, AnMuC.NbPoles() );
435 AnMuC.Curve(1, ThePoles);
436 Handle(Geom2d_BSplineCurve) Cvliss = new (Geom2d_BSplineCurve)
439 AnMuC. Multiplicities(),
442 Handle(DrawTrSurf_BSplineCurve2d)
443 DC = new DrawTrSurf_BSplineCurve2d(Cvliss);
446 if (id!=0) dout.RepaintView(id);
449 Standard_Integer NbPoints = Points->Length();
450 if (TABofCC.IsNull()) {
451 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
452 for(i=1; i<=NbPoints; i++){
453 AppParCurves_ConstraintCouple ACC(i,Constraint);
454 TABofCC->SetValue(i,ACC);
458 AppDef_Variational Variation(AML,
463 if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0);
464 else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1);
465 Variation.SetMaxDegree(DegMax);
467 Variation.SetTolerance( Abs(Tolerance));
468 if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);}
469 Variation.Approximate();
470 # ifdef GEOMLITETEST_DEB
471 //Variation.Dump(cout);
472 Standard_SStream aSStream;
473 Variation.Dump(aSStream);
477 AppParCurves_MultiBSpCurve AnMuC = Variation.Value();
479 TColgp_Array1OfPnt ThePoles (1, AnMuC.NbPoles() );
480 AnMuC.Curve(1, ThePoles);
481 Handle(Geom_BSplineCurve) Cvliss = new (Geom_BSplineCurve)
484 AnMuC. Multiplicities(),
487 Handle(DrawTrSurf_BSplineCurve)
488 DC = new DrawTrSurf_BSplineCurve(Cvliss);
491 if (id!=0) dout.RepaintView(id);
496 //=============================================================================
497 static Standard_Integer smoothingbybezier (Draw_Interpretor& di,
500 //============================================================================
502 Standard_Real Tolerance=0;
503 AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
504 Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC;
505 Handle(AppDef_HArray1OfMultiPointConstraint) Points;
507 Standard_Integer id = 0;
508 Standard_Integer methode=0;
509 Standard_Integer Degree = 8;
512 di <<"give a name to your curve !" << "\n";
516 di <<"give a tolerance to your curve !" << "\n";
520 di <<"give a max degree!" << "\n";
525 di <<"give an option!" << "\n";
529 Tolerance = Draw::Atof(a[2]);
530 Degree = Draw::Atoi(a[3]);
531 if (! strcmp(a[4],"-GR")) {
534 else if (! strcmp(a[4],"-PR")) {
539 if (Abs(Tolerance) < Precision::Confusion()*1.e-7) {
540 Constraint = AppParCurves_PassPoint;
543 Constraint = AppParCurves_NoConstraint;
546 // Designation Graphique ------------------------
547 id = PointsByPick(Points, di);
549 // lecture du fichier.
550 // nbpoints, 2d ou 3d, puis valeurs.
551 const char* nomfic = a[5];
552 ifstream iFile(nomfic, ios::in);
554 di << a[6] <<"do not exist !" << "\n";
557 PointsByFile(Points, TABofCC, iFile, di);
561 AppDef_MultiLine AML(Points->Array1());
563 // Compute --------------
565 if (Points->Value(1).NbPoints()==0){
567 Handle(TColgp_HArray1OfPnt2d) ThePoints;
569 Standard_Integer NbPoints = Points->Length();
570 if (TABofCC.IsNull()) {
571 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
572 for(i=1; i<=NbPoints; i++){
573 AppParCurves_ConstraintCouple ACC(i,Constraint);
574 TABofCC->SetValue(i,ACC);
577 AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
578 if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
579 TABofCC->SetValue(1, AC1);
581 AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
582 if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
583 TABofCC->SetValue(NbPoints, AC2);
587 Standard_Boolean mySquare = (methode == 2);
588 Standard_Integer degmin = 4;
589 Standard_Integer NbIteration = 5;
591 if (Degree < 4) degmin = Max(1, Degree -1);
592 degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),
593 TABofCC->Value(NbPoints).Constraint()) );
595 AppDef_Compute Appr(degmin, Degree,
596 Abs(Tolerance), Abs(Tolerance),
597 NbIteration, Standard_False,
598 Approx_ChordLength, mySquare);
600 Appr.SetConstraints(TABofCC->Value(1).Constraint(),
601 TABofCC->Value(NbPoints).Constraint());
605 if (! Appr.IsAllApproximated()) {
606 di << " No result" << "\n";
608 AppParCurves_MultiCurve AnMuC = Appr.Value();
609 ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() );
610 AnMuC.Curve(1, ThePoints->ChangeArray1());
611 Standard_Real err, err2d;
612 Appr.Error(1, err, err2d);
613 di <<" Error2D is : " << err2d << "\n";
616 AppDef_Variational Varia(AML,
620 Varia.SetTolerance(Abs(Tolerance));
623 if (! Varia.IsDone()) {
624 di << " No result" << "\n";
627 AppParCurves_MultiBSpCurve AnMuC = Varia.Value();
628 di <<" Error2D is : " << Varia.MaxError() << "\n";
629 ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() );
630 AnMuC.Curve(1, ThePoints->ChangeArray1());
633 Handle(Geom2d_BezierCurve) Cvliss =
634 new (Geom2d_BezierCurve)(ThePoints->Array1());
636 Handle(DrawTrSurf_BezierCurve2d) DC =
637 new (DrawTrSurf_BezierCurve2d) (Cvliss);
639 if (id!=0) dout.RepaintView(id);
643 Handle(TColgp_HArray1OfPnt) ThePoints;
644 Standard_Integer NbPoints = Points->Length();
645 if (TABofCC.IsNull()) {
646 TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints);
647 for(i=1; i<=NbPoints; i++){
648 AppParCurves_ConstraintCouple ACC(i,Constraint);
649 TABofCC->SetValue(i,ACC);
653 AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint);
654 if (TABofCC->Value(1).Constraint()<AppParCurves_PassPoint)
655 TABofCC->SetValue(1, AC1);
657 AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint);
658 if (TABofCC->Value(NbPoints).Constraint()<AppParCurves_PassPoint)
659 TABofCC->SetValue(NbPoints, AC2);
663 Standard_Boolean mySquare = (methode == 2);
664 Standard_Integer degmin = 4;
665 Standard_Integer NbIteration = 5;
666 if (Degree < 4) degmin = Max(1, Degree - 1);
667 degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(),
668 TABofCC->Value(NbPoints).Constraint()) );
670 AppDef_Compute Appr(degmin, Degree,
671 Abs(Tolerance), Abs(Tolerance),
672 NbIteration, Standard_False,
673 Approx_ChordLength, mySquare);
675 Appr.SetConstraints(TABofCC->Value(1).Constraint(),
676 TABofCC->Value(NbPoints).Constraint());
680 if (! Appr.IsAllApproximated()) {
681 di << " No result" << "\n";
683 AppParCurves_MultiCurve AnMuC = Appr.Value();
684 ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() );
685 AnMuC.Curve(1, ThePoints->ChangeArray1());
686 Standard_Real err, err2d;
687 Appr.Error(1, err, err2d);
688 di <<" Error3D is : " << err << "\n";
691 AppDef_Variational Varia(AML,
696 Varia.SetTolerance(Abs(Tolerance));
698 if (! Varia.IsDone()) {
699 di << " No result" << "\n";
702 AppParCurves_MultiBSpCurve AnMuC = Varia.Value();
703 di <<" Error3D is : " << Varia.MaxError() << "\n";
704 ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() );
705 AnMuC.Curve(1, ThePoints->ChangeArray1());
708 Handle(Geom_BezierCurve) Cvliss =
709 new (Geom_BezierCurve)(ThePoints->Array1());
711 Handle(DrawTrSurf_BezierCurve)
712 DC = new DrawTrSurf_BezierCurve(Cvliss);
714 if (id!=0) dout.RepaintView(id);
719 //=======================================================================
720 //function : ConstraintCommands
722 //=======================================================================
725 void GeomliteTest::ApproxCommands(Draw_Interpretor& theCommands)
728 static Standard_Boolean loaded = Standard_False;
730 loaded = Standard_True;
732 DrawTrSurf::BasicCommands(theCommands);
735 // constrained constructs
736 g = "GEOMETRY Constraints";
739 theCommands.Add("bsmooth",
740 "bsmooth cname tol [-D degree] [fic]",
744 theCommands.Add("bzsmooth",
745 "bzsmooth cname tol degree option [fic]",
747 smoothingbybezier, g);