// Created on: 1993-08-12 // Created by: Bruno DUMORTIER // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. // PMN : Ajout de la commande smooth // PMN : 11/07/97 Passage a GeomliteTest de bsmooth. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WNT #include Standard_IMPORT Draw_Viewer dout; #endif //Draw_Color DrawTrSurf_CurveColor(const Draw_Color); //======================================================================= //function : NbConstraint //======================================================================= static Standard_Integer NbConstraint(const AppParCurves_Constraint C1, const AppParCurves_Constraint C2) { Standard_Integer N =0; switch (C1) { case AppParCurves_PassPoint : { N = 1; break; } case AppParCurves_TangencyPoint : { N =2; break; } case AppParCurves_CurvaturePoint : { N = 3; break; } default: break; } switch (C2) { case AppParCurves_PassPoint : { N++; break; } case AppParCurves_TangencyPoint : { N += 2; break; } case AppParCurves_CurvaturePoint : { N += 3; break; } default: break; } return N; } //======================================================================= //function : PointsByPick //======================================================================= static Standard_Integer PointsByPick (Handle(AppDef_HArray1OfMultiPointConstraint)& MPC, Draw_Interpretor& di) { Standard_Integer id,XX,YY,b, i; di << "Pick points "<< "\n"; dout.Select(id, XX, YY, b); Standard_Real zoom = dout.Zoom(id); if (b != 1) return 0; if (id < 0) return 0; gp_Pnt P; gp_Pnt2d P2d; //Standard_Boolean newcurve; if (dout.Is3D(id)) { // Cas du 3D ------- Handle(Draw_Marker3D) mark; TColgp_SequenceOfPnt ThePoints; P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0); ThePoints.Append (P); mark = new Draw_Marker3D(P, Draw_X, Draw_orange); dout << mark; dout.Flush(); i = 1; while (b != 3) { dout.Select(id,XX,YY,b, Standard_False); if (b == 1) { i++; P.SetCoord( (Standard_Real)XX/zoom, (Standard_Real)YY/zoom, 0.0); ThePoints.Append(P); mark = new Draw_Marker3D(P, Draw_X, Draw_orange); dout << mark; dout.Flush(); } } MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length()); AppDef_MultiPointConstraint mpc(1,0); MPC->ChangeArray1().Init(mpc); for (i=1; i<=ThePoints.Length(); i++) { AppDef_MultiPointConstraint mpc(1,0); mpc.SetPoint(1, ThePoints.Value(i)); MPC->SetValue(i, mpc); } } else { // Cas du 2D ------- Handle(Draw_Marker2D) mark; TColgp_SequenceOfPnt2d ThePoints; P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom); ThePoints.Append(P2d); mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange); dout << mark; dout.Flush(); i = 1; while (b != 3) { dout.Select(id,XX,YY,b, Standard_False); if (b == 1) { i++; P2d.SetCoord( (Standard_Real)XX/zoom, (Standard_Real)YY/zoom ); ThePoints.Append (P2d); mark = new Draw_Marker2D(P2d, Draw_X, Draw_orange); dout << mark; dout.Flush(); } } MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, ThePoints.Length()); for (i=1; i<=ThePoints.Length(); i++) { AppDef_MultiPointConstraint mpc(0,1); mpc.SetPoint2d(1, ThePoints.Value(i)); MPC->SetValue(i, mpc); } } return id; } //======================================================================= //function : PointsByFile //======================================================================= static void PointsByFile(Handle(AppDef_HArray1OfMultiPointConstraint)& MPC, Handle(AppParCurves_HArray1OfConstraintCouple)& TABofCC, ifstream& iFile, Draw_Interpretor& di) { Standard_Integer nbp, i, nbc; char c; Standard_Real x, y, z; iFile >> nbp; char dimen[3]; iFile >> dimen; if (!strcmp(dimen,"3d")) { Handle(Draw_Marker3D) mark; MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp); for (i = 1; i <= nbp; i++) { iFile >> x >> y >> z; AppDef_MultiPointConstraint mpc(1,0); mpc.SetPoint(1, gp_Pnt(x, y, z)); MPC->SetValue(i,mpc); mark = new Draw_Marker3D(gp_Pnt(x, y, z), Draw_X, Draw_orange); dout << mark; } Standard_Boolean HasConstrainte = Standard_False; if (iFile.get(c)) { if ( IsControl( (Standard_Character)c) ) { if (iFile.get(c)) HasConstrainte = Standard_True; } else HasConstrainte = Standard_True; } if (HasConstrainte) { Standard_Integer num, ordre; iFile >> nbc; if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme AppParCurves_Constraint Constraint = AppParCurves_NoConstraint; TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp); for(i=1; i<=nbp; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } for(i=1; i<=nbc; i++) { iFile >> num >> ordre; if ((num<1)||(num>nbp)) { di << "Error on point Index in constrainte" << "\n"; return; } Constraint = (AppParCurves_Constraint) (ordre+1); TABofCC->ChangeValue(num).SetConstraint(Constraint); if (Constraint >= AppParCurves_TangencyPoint) { iFile >> x >> y >> z; MPC->ChangeValue(num).SetTang(1, gp_Vec(x,y,z)); } if (Constraint >= AppParCurves_CurvaturePoint) { iFile >> x >> y >> z; MPC->ChangeValue(num).SetCurv(1, gp_Vec(x,y,z)); } } } } else if (!strcmp(dimen,"2d")) { Handle(Draw_Marker2D) mark; MPC = new (AppDef_HArray1OfMultiPointConstraint)(1, nbp); for (i = 1; i <= nbp; i++) { iFile >> x >> y; AppDef_MultiPointConstraint mpc(0,1); mpc.SetPoint2d(1, gp_Pnt2d(x, y)); MPC->SetValue(i, mpc); mark = new Draw_Marker2D(gp_Pnt2d(x, y), Draw_X, Draw_orange); dout << mark; } Standard_Boolean HasConstrainte = Standard_False; if (iFile.get(c)) { if ( IsControl( (Standard_Character)c) ) { if (iFile.get(c)) HasConstrainte = Standard_True; } else HasConstrainte = Standard_True; } if (HasConstrainte) { Standard_Integer num, ordre; iFile >> nbc; if ((nbc < 1) || (nbc>nbp)) return; // Y a comme un probleme AppParCurves_Constraint Constraint = AppParCurves_NoConstraint; TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, nbp); for(i=1; i<=nbp; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } for(i=1; i<=nbc; i++) { iFile >> num >> ordre; if ((num<1)||(num>nbp)) { di << "Error on point Index in constrainte" << "\n"; return; } Constraint = (AppParCurves_Constraint) (ordre+1); TABofCC->ChangeValue(num).SetConstraint(Constraint); if (Constraint >= AppParCurves_TangencyPoint) { iFile >> x >> y; MPC->ChangeValue(num).SetTang2d(1, gp_Vec2d(x,y)); } if (Constraint >= AppParCurves_CurvaturePoint) { iFile >> x >> y; MPC->ChangeValue(num).SetCurv2d(1, gp_Vec2d(x,y)); } } } } } //================================================================================== static Standard_Integer smoothing (Draw_Interpretor& di,Standard_Integer n, const char** a) //================================================================================== // Tolerance < 0 lissage "filtre" // Tolerance > 0 lissage avec respect de l'erreur max // Tolerance = 0 interpolation. // { Standard_Real Tolerance=0; #ifdef DEB AppParCurves_Constraint Constraint; #else AppParCurves_Constraint Constraint=AppParCurves_NoConstraint; #endif Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC; TABofCC.Nullify(); Handle(AppDef_HArray1OfMultiPointConstraint) Points; Standard_Integer id = 0, DegMax = -1; if (n == 1) { di <<"give a name to your curve !" << "\n"; return 0; } if (n == 2) { di <<"give a tolerance to your curve !" << "\n"; return 0; } if (n == 3) { Tolerance = Draw::Atof(a[2]); if (Abs(Tolerance) < Precision::Confusion()*1.e-7) { Constraint = AppParCurves_PassPoint; } else { Constraint = AppParCurves_NoConstraint; } // Designation Graphique ------------------------ id = PointsByPick(Points, di); } else if (n >= 4) { Standard_Integer ific = 3; Tolerance = Draw::Atof(a[2]); if (Abs(Tolerance) < Precision::Confusion()*1.e-7) { Constraint = AppParCurves_PassPoint; } else { Constraint = AppParCurves_NoConstraint; } if (! strcmp(a[3],"-D")) { DegMax = Draw::Atoi(a[4]); ific = 5; } if (n > ific) { // lecture du fichier. // nbpoints, 2d ou 3d, puis valeurs. const char* nomfic = a[ific]; ifstream iFile(nomfic, ios::in); if (!iFile) { di << a[ific] <<"do not exist !" << "\n"; return 1; } PointsByFile(Points, TABofCC, iFile, di); } else { // Designation Graphique id = PointsByPick(Points, di); } } AppDef_MultiLine AML(Points->Array1()); // Compute -------------- Standard_Integer i; if (Points->Value(1).NbPoints()==0){ // Cas 2d Handle(TColgp_HArray1OfPnt2d) ThePoints; // Calcul du lissage Standard_Integer NbPoints = Points->Length(); if (TABofCC.IsNull()) { TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints); for(i=1; i<=NbPoints; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } } AppDef_TheVariational Variation(AML, 1, NbPoints, TABofCC); if (DegMax > 0) { if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0); else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1); Variation.SetMaxDegree(DegMax); } Variation.SetTolerance( Abs(Tolerance)); if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);} Variation.Approximate(); # ifdef DEB //Variation.Dump(cout); Standard_SStream aSStream; Variation.Dump(aSStream); di << aSStream; # endif AppParCurves_MultiBSpCurve AnMuC = Variation.Value(); TColgp_Array1OfPnt2d ThePoles (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoles); Handle(Geom2d_BSplineCurve) Cvliss = new (Geom2d_BSplineCurve) (ThePoles, AnMuC.Knots(), AnMuC. Multiplicities(), AnMuC.Degree() ); Handle(DrawTrSurf_BSplineCurve2d) DC = new DrawTrSurf_BSplineCurve2d(Cvliss); DC->ClearPoles(); Draw::Set(a[1], DC); if (id!=0) dout.RepaintView(id); } else { Standard_Integer NbPoints = Points->Length(); if (TABofCC.IsNull()) { TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints); for(i=1; i<=NbPoints; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } } AppDef_TheVariational Variation(AML, 1, NbPoints, TABofCC); if (DegMax > 0) { if (DegMax < 3) Variation.SetContinuity(GeomAbs_C0); else if (DegMax <5) Variation.SetContinuity(GeomAbs_C1); Variation.SetMaxDegree(DegMax); } Variation.SetTolerance( Abs(Tolerance)); if (Tolerance>0) { Variation.SetWithMinMax(Standard_True);} Variation.Approximate(); # ifdef DEB //Variation.Dump(cout); Standard_SStream aSStream; Variation.Dump(aSStream); di << aSStream; # endif AppParCurves_MultiBSpCurve AnMuC = Variation.Value(); TColgp_Array1OfPnt ThePoles (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoles); Handle(Geom_BSplineCurve) Cvliss = new (Geom_BSplineCurve) (ThePoles, AnMuC.Knots(), AnMuC. Multiplicities(), AnMuC.Degree() ); Handle(DrawTrSurf_BSplineCurve) DC = new DrawTrSurf_BSplineCurve(Cvliss); DC->ClearPoles(); Draw::Set(a[1], DC); if (id!=0) dout.RepaintView(id); } return 0; } //============================================================================= static Standard_Integer smoothingbybezier (Draw_Interpretor& di, Standard_Integer n, const char** a) //============================================================================ { Standard_Real Tolerance=0; #ifdef DEB AppParCurves_Constraint Constraint; #else AppParCurves_Constraint Constraint=AppParCurves_NoConstraint; #endif Handle(AppParCurves_HArray1OfConstraintCouple)TABofCC; Handle(AppDef_HArray1OfMultiPointConstraint) Points; Standard_Integer id = 0; Standard_Integer methode=0; Standard_Integer Degree = 8; if (n == 1) { di <<"give a name to your curve !" << "\n"; return 0; } if (n == 2) { di <<"give a tolerance to your curve !" << "\n"; return 0; } if (n == 3) { di <<"give a max degree!" << "\n"; return 0; } if (n == 4) { di <<"give an option!" << "\n"; return 0; } if (n >= 5) { Tolerance = Draw::Atof(a[2]); Degree = Draw::Atoi(a[3]); if (! strcmp(a[4],"-GR")) { methode = 1; } else if (! strcmp(a[4],"-PR")) { methode = 2; } else { methode = 3;} if (Abs(Tolerance) < Precision::Confusion()*1.e-7) { Constraint = AppParCurves_PassPoint; } else { Constraint = AppParCurves_NoConstraint; } if (n==5) // Designation Graphique ------------------------ id = PointsByPick(Points, di); else { // lecture du fichier. // nbpoints, 2d ou 3d, puis valeurs. const char* nomfic = a[5]; ifstream iFile(nomfic, ios::in); if (!iFile) { di << a[6] <<"do not exist !" << "\n"; return 1; } PointsByFile(Points, TABofCC, iFile, di); } } AppDef_MultiLine AML(Points->Array1()); // Compute -------------- Standard_Integer i; if (Points->Value(1).NbPoints()==0){ // Cas 2d Handle(TColgp_HArray1OfPnt2d) ThePoints; // Calcul du lissage Standard_Integer NbPoints = Points->Length(); if (TABofCC.IsNull()) { TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints); for(i=1; i<=NbPoints; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint); if (TABofCC->Value(1).Constraint()SetValue(1, AC1); AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint); if (TABofCC->Value(NbPoints).Constraint()SetValue(NbPoints, AC2); } if (methode < 3) { Standard_Boolean mySquare = (methode == 2); Standard_Integer degmin = 4; Standard_Integer NbIteration = 5; if (Degree < 4) degmin = Max(1, Degree -1); degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(), TABofCC->Value(NbPoints).Constraint()) ); AppDef_Compute Appr(degmin, Degree, Abs(Tolerance), Abs(Tolerance), NbIteration, Standard_False, Approx_ChordLength, mySquare); Appr.SetConstraints(TABofCC->Value(1).Constraint(), TABofCC->Value(NbPoints).Constraint()); Appr.Perform (AML); if (! Appr.IsAllApproximated()) { di << " No result" << "\n"; } AppParCurves_MultiCurve AnMuC = Appr.Value(); ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoints->ChangeArray1()); Standard_Real err, err2d; Appr.Error(1, err, err2d); di <<" Error2D is : " << err2d << "\n"; } else { AppDef_TheVariational Varia(AML, 1, NbPoints, TABofCC, Degree, 1); Varia.SetTolerance(Abs(Tolerance)); Varia.Approximate(); if (! Varia.IsDone()) { di << " No result" << "\n"; } AppParCurves_MultiBSpCurve AnMuC = Varia.Value(); di <<" Error2D is : " << Varia.MaxError() << "\n"; ThePoints = new (TColgp_HArray1OfPnt2d) (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoints->ChangeArray1()); } Handle(Geom2d_BezierCurve) Cvliss = new (Geom2d_BezierCurve)(ThePoints->Array1()); Handle(DrawTrSurf_BezierCurve2d) DC = new (DrawTrSurf_BezierCurve2d) (Cvliss); Draw::Set(a[1], DC); if (id!=0) dout.RepaintView(id); } else { // Cas 3d Handle(TColgp_HArray1OfPnt) ThePoints; Standard_Integer NbPoints = Points->Length(); if (TABofCC.IsNull()) { TABofCC = new AppParCurves_HArray1OfConstraintCouple(1, NbPoints); for(i=1; i<=NbPoints; i++){ AppParCurves_ConstraintCouple ACC(i,Constraint); TABofCC->SetValue(i,ACC); } AppParCurves_ConstraintCouple AC1(1, AppParCurves_PassPoint); if (TABofCC->Value(1).Constraint()SetValue(1, AC1); AppParCurves_ConstraintCouple AC2(NbPoints, AppParCurves_PassPoint); if (TABofCC->Value(NbPoints).Constraint()SetValue(NbPoints, AC2); } if (methode < 3) { Standard_Boolean mySquare = (methode == 2); Standard_Integer degmin = 4; Standard_Integer NbIteration = 5; if (Degree < 4) degmin = Max(1, Degree - 1); degmin = Max(degmin, NbConstraint(TABofCC->Value(1).Constraint(), TABofCC->Value(NbPoints).Constraint()) ); AppDef_Compute Appr(degmin, Degree, Abs(Tolerance), Abs(Tolerance), NbIteration, Standard_False, Approx_ChordLength, mySquare); Appr.SetConstraints(TABofCC->Value(1).Constraint(), TABofCC->Value(NbPoints).Constraint()); Appr.Perform (AML); if (! Appr.IsAllApproximated()) { di << " No result" << "\n"; } AppParCurves_MultiCurve AnMuC = Appr.Value(); ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoints->ChangeArray1()); Standard_Real err, err2d; Appr.Error(1, err, err2d); di <<" Error3D is : " << err << "\n"; } else { AppDef_TheVariational Varia(AML, 1, NbPoints, TABofCC, Degree, 1); Varia.SetTolerance(Abs(Tolerance)); Varia.Approximate(); if (! Varia.IsDone()) { di << " No result" << "\n"; } AppParCurves_MultiBSpCurve AnMuC = Varia.Value(); di <<" Error3D is : " << Varia.MaxError() << "\n"; ThePoints = new (TColgp_HArray1OfPnt) (1, AnMuC.NbPoles() ); AnMuC.Curve(1, ThePoints->ChangeArray1()); } Handle(Geom_BezierCurve) Cvliss = new (Geom_BezierCurve)(ThePoints->Array1()); Handle(DrawTrSurf_BezierCurve) DC = new DrawTrSurf_BezierCurve(Cvliss); Draw::Set(a[1], DC); if (id!=0) dout.RepaintView(id); } return 0; } //======================================================================= //function : ConstraintCommands //purpose : //======================================================================= void GeomliteTest::ApproxCommands(Draw_Interpretor& theCommands) { static Standard_Boolean loaded = Standard_False; if (loaded) return; loaded = Standard_True; DrawTrSurf::BasicCommands(theCommands); const char* g; // constrained constructs g = "GEOMETRY Constraints"; theCommands.Add("bsmooth", "bsmooth cname tol [-D degree] [fic]", __FILE__, smoothing, g); theCommands.Add("bzsmooth", "bzsmooth cname tol degree option [fic]", __FILE__, smoothingbybezier, g); }