#include <StdFail_NotDone.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
-#include <AppDef_TheVariational.hxx>
+#include <AppDef_Variational.hxx>
static Standard_Boolean scal = 1;
#ifdef DEB
TABofCC->ChangeValue(1).SetConstraint(Cfirst);
TABofCC->ChangeValue(NbPoint).SetConstraint(Clast);
- AppDef_TheVariational Variation(multL, 1, NbPoint, TABofCC);
+ AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
//===================================
Standard_Integer theMaxSegments = 1000;
-- Note: a CurvaturePoint is also a PassPoint and a TangencyPoint.
-- A TangencyPoint is also a PassPoint.
-uses AppParCurves, Approx, gp, TColgp, TCollection, Standard, MMgt
+uses AppParCurves, Approx, gp, TColgp, TCollection, Standard, MMgt, math, FEmTool, TColStd, GeomAbs, PLib
is
-- AppParCurves and Approx. For Approx, the tool will not addd points
-- if the algorithms want some.
+deferred class SmoothCriterion;
+class LinearCriteria;
+
+class Variational;
+ ---Purpose: computes the approximation of a Multiline by
+ -- Variational optimization.
--- Classes instanciees:
class TheLeastSquares instantiates LeastSquare from AppParCurves
(MultiLine from AppDef,
MyLineTool from AppDef);
-
-class TheVariational instantiates Variational from AppParCurves
- (MultiLine from AppDef,
- MyLineTool from AppDef);
+
class TheResol instantiates ResolConstraint from AppParCurves
(MultiLine from AppDef,
--- /dev/null
+-- Created on: 1997-09-11
+-- Created by: Philippe MANGIN
+-- Copyright (c) 1997-1999 Matra Datavision
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- This library is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU Lesser General Public License version 2.1 as published
+-- by the Free Software Foundation, with special exception defined in the file
+-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+-- distribution for complete text of the license and disclaimer of any warranty.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+class LinearCriteria from AppDef inherits SmoothCriterion from AppDef
+
+ ---Purpose: defined an Linear Criteria to used in variational
+ -- Smoothing of points.
+
+
+uses
+ Vector from math,
+ Matrix from math,
+ Curve from FEmTool,
+ HAssemblyTable from FEmTool,
+ ElementaryCriterion from FEmTool,
+ HArray2OfInteger from TColStd,
+ HArray1OfReal from TColStd,
+ Array1OfReal from TColStd,
+ MultiLine from AppDef,
+ MyLineTool from AppDef
+
+raises
+ NotImplemented,
+ DomainError
+
+
+
+is
+ Create(SSP: MultiLine from AppDef;
+ FirstPoint, LastPoint: Integer) returns LinearCriteria;
+
+ SetParameters(me : mutable; Parameters : HArray1OfReal);
+
+ SetCurve(me : mutable; C :Curve from FEmTool)
+ is static;
+
+ GetCurve(me; C : out Curve from FEmTool)
+ is static;
+
+ SetEstimation(me : mutable; E1, E2, E3 : Real)
+ is static;
+
+ EstLength(me : mutable)
+ ---C++: return &
+ returns Real is static;
+
+ GetEstimation(me; E1, E2, E3 : out Real)
+ is static;
+
+ AssemblyTable(me)
+ returns HAssemblyTable from FEmTool
+ is static;
+
+ DependenceTable(me)
+ returns HArray2OfInteger from TColStd
+ is static;
+
+
+ QualityValues (me : mutable; J1min, J2min, J3min : Real;
+ J1, J2, J3 : out Real)
+ returns Integer is static;
+
+ ErrorValues(me : mutable;
+ MaxError, QuadraticError, AverageError : out Real)
+ is static;
+
+ Hessian(me : mutable ;
+ Element : Integer;
+ Dimension1 : Integer;
+ Dimension2 : Integer;
+ H : out Matrix from math)
+ raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
+ is static;
+
+
+ Gradient(me : mutable;
+ Element : Integer;
+ Dimension : Integer;
+ G : out Vector from math)
+ is static;
+
+ InputVector(me : mutable; X : Vector from math;
+ AssTable : HAssemblyTable from FEmTool)
+ ---Purpose: Convert the assembly Vector in an Curve;
+ --
+ raises DomainError;
+
+ SetWeight(me: mutable;
+ QuadraticWeight, QualityWeight : Real;
+ percentJ1, percentJ2, percentJ3 : Real)
+ is static;
+
+ GetWeight(me; QuadraticWeight, QualityWeight : out Real)
+ is static;
+
+ SetWeight(me: mutable;
+ Weight : Array1OfReal)
+ is static;
+
+ BuildCache(me: mutable; E : Integer) is private;
+
+fields
+mySSP : MultiLine from AppDef;
+myParameters : HArray1OfReal;
+myCache : HArray1OfReal;
+myCriteria : ElementaryCriterion from FEmTool[3];
+myEstimation: Real[3];
+myQuadraticWeight, myQualityWeight : Real;
+myPercent : Real[3];
+myPntWeight : Array1OfReal;
+myCurve : Curve from FEmTool;
+myLength : Real;
+myE : Integer;
+IF, IL : Integer;
+end LinearCriteria;
+
+
--- /dev/null
+// Created on: 1998-11-30
+// Created by: Igor FEOKTISTOV
+// Copyright (c) 1998-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AppDef_LinearCriteria.ixx>
+
+#include <PLib_Base.hxx>
+#include <PLib_JacobiPolynomial.hxx>
+#include <PLib_HermitJacobi.hxx>
+#include <GeomAbs_Shape.hxx>
+#include <TColStd_HArray2OfReal.hxx>
+#include <FEmTool_LinearTension.hxx>
+#include <FEmTool_LinearFlexion.hxx>
+#include <FEmTool_LinearJerk.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Pnt.hxx>
+#include <math_Matrix.hxx>
+#include <math_Gauss.hxx>
+#include <AppDef_MyLineTool.hxx>
+
+static Standard_Integer order(const Handle(PLib_Base)& B)
+{
+ return (*( Handle(PLib_HermitJacobi)*)&B)->NivConstr();
+}
+
+
+//=======================================================================
+//function :
+//purpose :
+//=======================================================================
+AppDef_LinearCriteria::AppDef_LinearCriteria(const AppDef_MultiLine& SSP,
+ const Standard_Integer FirstPoint,
+ const Standard_Integer LastPoint):
+ mySSP(SSP),
+ myPntWeight(FirstPoint, LastPoint),
+ myE(0)
+{
+ myPntWeight.Init(1.);
+}
+
+
+//=======================================================================
+//function :
+//purpose :
+//=======================================================================
+
+void AppDef_LinearCriteria::SetParameters(const Handle(TColStd_HArray1OfReal)& Parameters)
+{
+ myParameters = Parameters;
+ myE = 0; // Cache become invalid.
+}
+
+
+
+//=======================================================================
+//function : SetCurve
+//purpose :
+//=======================================================================
+
+void AppDef_LinearCriteria::SetCurve(const Handle(FEmTool_Curve)& C)
+{
+
+ if(myCurve.IsNull()) {
+ myCurve = C;
+
+ Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
+ NbDim = myCurve->Dimension(),
+ Order = order(myCurve->Base());
+
+ GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
+ switch (Order) {
+ case 0 : ConstraintOrder = GeomAbs_C0;
+ break;
+ case 1 : ConstraintOrder = GeomAbs_C1;
+ break;
+ case 2 : ConstraintOrder = GeomAbs_C2;
+ }
+
+ myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
+ myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
+ myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
+
+ Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
+
+ myCriteria[0]->Set(Coeff);
+ myCriteria[1]->Set(Coeff);
+ myCriteria[2]->Set(Coeff);
+ }
+ else if (myCurve != C) {
+
+ Standard_Integer OldMxDeg = myCurve->Base()->WorkDegree(),
+ OldNbDim = myCurve->Dimension(),
+ OldOrder = order(myCurve->Base());
+
+ myCurve = C;
+
+ Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
+ NbDim = myCurve->Dimension(),
+ Order = order(myCurve->Base());
+
+ if(MxDeg != OldMxDeg || Order != OldOrder) {
+
+ GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
+ switch (Order) {
+ case 0 : ConstraintOrder = GeomAbs_C0;
+ break;
+ case 1 : ConstraintOrder = GeomAbs_C1;
+ break;
+ case 2 : ConstraintOrder = GeomAbs_C2;
+ }
+
+ myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
+ myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
+ myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
+
+ Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
+
+ myCriteria[0]->Set(Coeff);
+ myCriteria[1]->Set(Coeff);
+ myCriteria[2]->Set(Coeff);
+ }
+ else if(NbDim != OldNbDim) {
+
+ Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
+
+ myCriteria[0]->Set(Coeff);
+ myCriteria[1]->Set(Coeff);
+ myCriteria[2]->Set(Coeff);
+ }
+ }
+}
+
+
+
+//=======================================================================
+//function : GetCurve
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::GetCurve(Handle(FEmTool_Curve)& C) const
+{
+ C = myCurve;
+}
+
+
+//=======================================================================
+//function : SetEstimation
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::SetEstimation(const Standard_Real E1,
+ const Standard_Real E2,
+ const Standard_Real E3)
+{
+ myEstimation[0] = E1;
+ myEstimation[1] = E2;
+ myEstimation[2] = E3;
+}
+
+Standard_Real& AppDef_LinearCriteria::EstLength()
+{
+ return myLength;
+}
+
+
+//=======================================================================
+//function : GetEstimation
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::GetEstimation(Standard_Real& E1,
+ Standard_Real& E2,
+ Standard_Real& E3) const
+{
+ E1 = myEstimation[0];
+ E2 = myEstimation[1];
+ E3 = myEstimation[2];
+}
+
+
+
+//=======================================================================
+//function : AssemblyTable
+//purpose :
+//=======================================================================
+Handle(FEmTool_HAssemblyTable) AppDef_LinearCriteria::AssemblyTable() const
+{
+ if(myCurve.IsNull()) Standard_DomainError::Raise("AppDef_LinearCriteria::AssemblyTable");
+
+ Standard_Integer NbDim = myCurve->Dimension(),
+ NbElm = myCurve->NbElements(),
+ nc1 = order(myCurve->Base()) + 1;
+ Standard_Integer MxDeg = myCurve->Base()->WorkDegree() ;
+
+ Handle(FEmTool_HAssemblyTable) AssTable = new FEmTool_HAssemblyTable(1, NbDim, 1, NbElm);
+
+ Handle(TColStd_HArray1OfInteger) GlobIndex, Aux;
+
+ Standard_Integer i, el = 1, dim = 1, NbGlobVar = 0, gi0;
+
+ // For dim = 1
+ // For first element (el = 1)
+ GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
+
+ for(i = 0; i < nc1; i++) {
+ NbGlobVar++;
+ GlobIndex->SetValue(i, NbGlobVar);
+ }
+ gi0 = MxDeg - 2 * nc1 + 1;
+ for(i = nc1; i < 2*nc1; i++) {
+ NbGlobVar++;
+ GlobIndex->SetValue(i, NbGlobVar + gi0);
+ }
+ for(i = 2*nc1; i <= MxDeg; i++) {
+ NbGlobVar++;
+ GlobIndex->SetValue(i, NbGlobVar - nc1);
+ }
+ gi0 = NbGlobVar - nc1 + 1;
+ AssTable->SetValue(dim, el, GlobIndex);
+
+ // For rest elements
+ for(el = 2; el <= NbElm; el++) {
+ GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
+ for(i = 0; i < nc1; i++) GlobIndex->SetValue(i, gi0 + i);
+
+ gi0 = MxDeg - 2 * nc1 + 1;
+ for(i = nc1; i < 2*nc1; i++) {
+ NbGlobVar++;
+ GlobIndex->SetValue(i, NbGlobVar + gi0);
+ }
+ for(i = 2*nc1; i <= MxDeg; i++) {
+ NbGlobVar++;
+ GlobIndex->SetValue(i, NbGlobVar - nc1);
+ }
+ gi0 = NbGlobVar - nc1 + 1;
+ AssTable->SetValue(dim, el, GlobIndex);
+ }
+
+ // For other dimensions
+ gi0 = NbGlobVar;
+ for(dim = 2; dim <= NbDim; dim++) {
+ for(el = 1; el <= NbElm; el++) {
+ Aux = AssTable->Value(1, el);
+ GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
+ for(i = 0; i <= MxDeg; i++) GlobIndex->SetValue(i, Aux->Value(i) + NbGlobVar);
+ AssTable->SetValue(dim, el, GlobIndex);
+ }
+ NbGlobVar += gi0;
+ }
+
+ return AssTable;
+}
+
+
+
+
+//=======================================================================
+//function :
+//purpose :
+//=======================================================================
+Handle(TColStd_HArray2OfInteger) AppDef_LinearCriteria::DependenceTable() const
+{
+ if(myCurve.IsNull()) Standard_DomainError::Raise("AppDef_LinearCriteria::DependenceTable");
+
+ Standard_Integer Dim = myCurve->Dimension();
+
+ Handle(TColStd_HArray2OfInteger) DepTab =
+ new TColStd_HArray2OfInteger(1, Dim, 1, Dim, 0);
+ Standard_Integer i;
+ for(i=1; i <= Dim; i++) DepTab->SetValue(i,i,1);
+
+ return DepTab;
+}
+
+
+//=======================================================================
+//function : QualityValues
+//purpose :
+//=======================================================================
+
+Standard_Integer AppDef_LinearCriteria::QualityValues(const Standard_Real J1min,
+ const Standard_Real J2min,
+ const Standard_Real J3min,
+ Standard_Real& J1,
+ Standard_Real& J2,
+ Standard_Real& J3)
+{
+ if(myCurve.IsNull()) Standard_DomainError::Raise("AppDef_LinearCriteria::QualityValues");
+
+ Standard_Integer NbDim = myCurve->Dimension(),
+ NbElm = myCurve->NbElements();
+
+ TColStd_Array1OfReal& Knots = myCurve->Knots();
+ Handle(TColStd_HArray2OfReal) Coeff;
+
+ Standard_Integer el, deg = 0, curdeg, i;
+ Standard_Real UFirst, ULast;
+
+ J1 = J2 = J3 = 0.;
+ for(el = 1; el <= NbElm; el++) {
+
+ curdeg = myCurve->Degree(el);
+ if(deg != curdeg) {
+ deg = curdeg;
+ Coeff = new TColStd_HArray2OfReal(0, deg, 1, NbDim);
+ }
+
+ myCurve->GetElement(el, Coeff->ChangeArray2());
+
+ UFirst = Knots(el); ULast = Knots(el + 1);
+
+ myCriteria[0]->Set(Coeff);
+ myCriteria[0]->Set(UFirst, ULast);
+ J1 = J1 + myCriteria[0]->Value();
+
+ myCriteria[1]->Set(Coeff);
+ myCriteria[1]->Set(UFirst, ULast);
+ J2 = J2 + myCriteria[1]->Value();
+
+ myCriteria[2]->Set(Coeff);
+ myCriteria[2]->Set(UFirst, ULast);
+ J3 = J3 + myCriteria[2]->Value();
+
+ }
+
+// Calculation of ICDANA - see MOTEST.f
+// Standard_Real JEsMin[3] = {.01, .001, .001}; // from MOTLIS.f
+ Standard_Real JEsMin[3]; JEsMin[0] = J1min; JEsMin[1] = J2min; JEsMin[2] = J3min;
+ Standard_Real ValCri[3]; ValCri[0] = J1; ValCri[1] = J2; ValCri[2] = J3;
+
+ Standard_Integer ICDANA = 0;
+
+// (2) Test l'amelioration des estimations
+// (critere sureleve => Non minimisation )
+
+ for(i = 0; i <= 2; i++)
+ if((ValCri[i] < 0.8 * myEstimation[i]) && (myEstimation[i] > JEsMin[i])) {
+ if(ICDANA < 1) ICDANA = 1;
+ if(ValCri[i] < 0.1 * myEstimation[i]) ICDANA = 2;
+ myEstimation[i] = Max(1.05*ValCri[i], JEsMin[i]);
+ }
+
+
+// (3) Mise a jours des Estimation
+// (critere sous-estimer => mauvais conditionement)
+
+ if (ValCri[0] > myEstimation[0] * 2) {
+ myEstimation[0] += ValCri[0] * .1;
+ if (ICDANA == 0) {
+ if (ValCri[0] > myEstimation[0] * 10) {
+ ICDANA = 2;
+ }
+ else ICDANA = 1;
+ }
+ else {
+ ICDANA = 2;
+ }
+ }
+ if (ValCri[1] > myEstimation[1] * 20) {
+ myEstimation[1] += ValCri[1] * .1;
+ if (ICDANA == 0) {
+ if (ValCri[1] > myEstimation[1] * 100) {
+ ICDANA = 2;
+ }
+ else ICDANA = 1;
+ }
+ else {
+ ICDANA = 2;
+ }
+ }
+ if (ValCri[2] > myEstimation[2] * 20) {
+ myEstimation[2] += ValCri[2] * .05;
+ if (ICDANA == 0) {
+ if (ValCri[2] > myEstimation[2] * 100) {
+ ICDANA = 2;
+ }
+ else ICDANA = 1;
+ }
+ else {
+ ICDANA = 2;
+ }
+ }
+
+
+ return ICDANA;
+}
+
+
+//=======================================================================
+//function : ErrorValues
+//purpose :
+//=======================================================================
+
+void AppDef_LinearCriteria::ErrorValues(Standard_Real& MaxError,
+ Standard_Real& QuadraticError,
+ Standard_Real& AverageError)
+{
+ if(myCurve.IsNull()) Standard_DomainError::Raise("AppDef_LinearCriteria::ErrorValues");
+
+ Standard_Integer NbDim = myCurve->Dimension();
+
+ Standard_Integer myNbP2d = AppDef_MyLineTool::NbP2d(mySSP), myNbP3d = AppDef_MyLineTool::NbP3d(mySSP);
+
+ if(NbDim != (2*myNbP2d + 3*myNbP3d)) Standard_DomainError::Raise("AppDef_LinearCriteria::ErrorValues");
+
+ TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
+ TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
+ TColStd_Array1OfReal BasePoint(1,NbDim);
+ gp_Pnt2d P2d;
+ gp_Pnt P3d;
+
+ Standard_Integer i, ipnt, c0 = 0;
+ Standard_Real SqrDist, Dist;
+
+ MaxError = QuadraticError = AverageError = 0.;
+
+ for(i = myParameters->Lower(); i <= myParameters->Upper(); i++) {
+
+ myCurve->D0(myParameters->Value(i), BasePoint);
+
+
+ c0 = 0;
+ AppDef_MyLineTool::Value(mySSP, i, TabP3d);
+ for(ipnt = 1; ipnt <= myNbP3d; ipnt++) {
+ P3d.SetCoord(BasePoint(c0+1), BasePoint(c0+2), BasePoint(c0+3));
+ SqrDist = P3d.SquareDistance(TabP3d(ipnt)); Dist = Sqrt(SqrDist);
+ MaxError = Max(MaxError, Dist);
+ QuadraticError += SqrDist;
+ AverageError += Dist;
+ c0 += 3;
+ }
+
+ if(myNbP3d == 0) AppDef_MyLineTool::Value(mySSP, i, TabP2d);
+ else AppDef_MyLineTool::Value(mySSP, i, TabP3d, TabP2d);
+ for(ipnt = 1; ipnt <= myNbP2d; ipnt++) {
+ P2d.SetCoord(BasePoint(c0+1), BasePoint(c0+2));
+ SqrDist = P2d.SquareDistance(TabP2d(ipnt)); Dist = Sqrt(SqrDist);
+ MaxError = Max(MaxError, Dist);
+ QuadraticError += SqrDist;
+ AverageError += Dist;
+ c0 += 2;
+ }
+ }
+}
+
+
+//=======================================================================
+//function : Hessian
+//purpose :
+//=======================================================================
+
+void AppDef_LinearCriteria::Hessian(const Standard_Integer Element,
+ const Standard_Integer Dimension1,
+ const Standard_Integer Dimension2,
+ math_Matrix& H)
+{
+ if(myCurve.IsNull()) Standard_DomainError::Raise("AppDef_LinearCriteria::Hessian");
+
+ if(DependenceTable()->Value(Dimension1, Dimension2) == 0)
+ Standard_DomainError::Raise("AppDef_LinearCriteria::Hessian");
+
+ Standard_Integer //NbDim = myCurve->Dimension(),
+ MxDeg = myCurve->Base()->WorkDegree(),
+// Deg = myCurve->Degree(Element),
+ Order = order(myCurve->Base());
+
+
+ math_Matrix AuxH(0, H.RowNumber()-1, 0, H.ColNumber()-1, 0.);
+
+ TColStd_Array1OfReal& Knots = myCurve->Knots();
+ Standard_Real UFirst, ULast;
+
+ UFirst = Knots(Element); ULast = Knots(Element + 1);
+
+ Standard_Integer icrit;
+
+ // Quality criterion part of Hessian
+
+ H.Init(0);
+
+ for(icrit = 0; icrit <= 2; icrit++) {
+ myCriteria[icrit]->Set(UFirst, ULast);
+ myCriteria[icrit]->Hessian(Dimension1, Dimension2, AuxH);
+ H += (myQualityWeight*myPercent[icrit]/myEstimation[icrit]) * AuxH;
+ }
+
+ // Least square part of Hessian
+
+ AuxH.Init(0.);
+
+ Standard_Real coeff = (ULast - UFirst)/2., curcoeff, poid;
+ Standard_Integer ipnt, ii, degH = 2 * Order+1;
+
+
+ Handle(PLib_Base) myBase = myCurve->Base();
+ Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1,
+ di = myPntWeight.Lower() - myParameters->Lower();
+
+ //BuilCache
+ if (myE != Element) BuildCache(Element);
+
+ // Compute the least square Hessian
+ for(ii=1, ipnt = IF; ipnt <= IL; ipnt++, ii+=(MxDeg+1)) {
+ poid = myPntWeight(di + ipnt) * 2.;
+ const Standard_Real * BV = &myCache->Value(ii);
+
+ // Hermite*Hermite part of matrix
+ for(i = 0; i <= degH; i++) {
+ k1 = (i <= Order)? i : i - Order - 1;
+ curcoeff = Pow(coeff, k1) * poid * BV[i];
+
+ // Hermite*Hermite part of matrix
+ for(j = i; j <= degH; j++) {
+ k2 = (j <= Order)? j : j - Order - 1;
+ AuxH(i, j) += curcoeff * Pow(coeff, k2) * BV[j];
+ }
+ // Hermite*Jacobi part of matrix
+ for(j = degH + 1; j <= MxDeg; j++) {
+ AuxH(i, j) += curcoeff * BV[j];
+ }
+ }
+
+ // Jacoby*Jacobi part of matrix
+ for(i = degH+1; i <= MxDeg; i++) {
+ curcoeff = BV[i] * poid;
+ for(j = i; j <= MxDeg; j++) {
+ AuxH(i, j) += curcoeff * BV[j];
+ }
+ }
+ }
+
+ i1 = i0;
+ for(i = 0; i <= MxDeg; i++) {
+ j1 = j0 + i;
+ for(j = i; j <= MxDeg; j++) {
+ H(i1, j1) += myQuadraticWeight * AuxH(i, j);
+ H(j1, i1) = H(i1, j1);
+ j1++;
+ }
+ i1++;
+ }
+
+}
+
+//=======================================================================
+//function : Gradient
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::Gradient(const Standard_Integer Element,
+ const Standard_Integer Dimension,
+ math_Vector& G)
+{
+ if(myCurve.IsNull())
+ Standard_DomainError::Raise("AppDef_LinearCriteria::ErrorValues");
+
+ Standard_Integer myNbP2d = AppDef_MyLineTool::NbP2d(mySSP), myNbP3d = AppDef_MyLineTool::NbP3d(mySSP);
+
+ if(Dimension > (2*myNbP2d + 3*myNbP3d))
+ Standard_DomainError::Raise("AppDef_LinearCriteria::ErrorValues");
+
+ TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
+ TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
+
+ Standard_Boolean In3d;
+ Standard_Integer IndPnt, IndCrd;
+
+ if(Dimension <= 3*myNbP3d) {
+ In3d = Standard_True;
+ IndCrd = Dimension % 3;
+ IndPnt = Dimension / 3;
+ if(IndCrd == 0) IndCrd = 3;
+ else IndPnt++;
+ }
+ else {
+ In3d = Standard_False;
+ IndCrd = (Dimension - 3*myNbP3d) % 2;
+ IndPnt = (Dimension - 3*myNbP3d) / 2;
+ if(IndCrd == 0) IndCrd = 2;
+ else IndPnt++;
+ }
+
+ TColStd_Array1OfReal& Knots = myCurve->Knots();
+ Standard_Real UFirst, ULast, Pnt;
+ UFirst = Knots(Element); ULast = Knots(Element + 1);
+ Standard_Real coeff = (ULast-UFirst)/2;
+
+ Standard_Integer //Deg = myCurve->Degree(Element),
+ Order = order(myCurve->Base());
+
+ Handle(PLib_Base) myBase = myCurve->Base();
+ Standard_Integer MxDeg = myBase->WorkDegree();
+
+ Standard_Real curcoeff;
+ Standard_Integer degH = 2 * Order + 1;
+ Standard_Integer ipnt, k, i, ii, i0 = G.Lower(),
+ di = myPntWeight.Lower() - myParameters->Lower();
+
+ if (myE != Element) BuildCache(Element);
+ const Standard_Real * BV = &myCache->Value(1);
+ BV--;
+
+ G.Init(0.);
+
+ for(ii=1,ipnt = IF; ipnt <= IL; ipnt++) {
+ if(In3d) {
+ AppDef_MyLineTool::Value(mySSP, ipnt, TabP3d);
+ Pnt = TabP3d(IndPnt).Coord(IndCrd);
+ }
+ else {
+ if(myNbP3d == 0) AppDef_MyLineTool::Value(mySSP, ipnt, TabP2d);
+ else AppDef_MyLineTool::Value(mySSP, ipnt, TabP3d, TabP2d);
+ Pnt = TabP2d(IndPnt).Coord(IndCrd);
+ }
+
+ curcoeff = Pnt * myPntWeight(di + ipnt);
+ for(i = 0; i <= MxDeg; i++,ii++)
+ G(i0 + i) += BV[ii] * curcoeff;
+ }
+
+
+ G *= 2. * myQuadraticWeight;
+
+ for(i = 0; i <= degH; i++) {
+ k = (i <= Order)? i : i - Order - 1;
+ curcoeff = Pow(coeff, k);
+ G(i0 + i) *= curcoeff;
+ }
+}
+
+
+//=======================================================================
+//function : InputVector
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::InputVector(const math_Vector& X,
+ const Handle(FEmTool_HAssemblyTable)& AssTable)
+{
+ Standard_Integer NbDim = myCurve->Dimension(),
+ NbElm = myCurve->NbElements() ;
+ Standard_Integer MxDeg = 0 ;
+ MxDeg = myCurve->Base()->WorkDegree();
+ TColStd_Array2OfReal CoeffEl(0, MxDeg, 1, NbDim);
+
+
+ Handle(TColStd_HArray1OfInteger) GlobIndex;
+
+ Standard_Integer el, dim, i, i0 = X.Lower() - 1;
+
+ for(el = 1; el <= NbElm; el++) {
+ for(dim = 1; dim <= NbDim; dim++) {
+ GlobIndex = AssTable->Value(dim, el);
+ for(i = 0; i <= MxDeg; i++) CoeffEl(i, dim) = X(i0 + GlobIndex->Value(i));
+ }
+ myCurve->SetDegree(el, MxDeg);
+ myCurve->SetElement(el, CoeffEl);
+ }
+}
+
+
+//=======================================================================
+//function : SetWeight
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::SetWeight(const Standard_Real QuadraticWeight,
+ const Standard_Real QualityWeight,
+ const Standard_Real percentJ1,
+ const Standard_Real percentJ2,
+ const Standard_Real percentJ3)
+{
+ if (QuadraticWeight < 0. || QualityWeight < 0.)
+ Standard_DomainError::Raise("AppDef_LinearCriteria::SetWeight");
+ if (percentJ1 < 0. || percentJ2 < 0. || percentJ3 < 0.)
+ Standard_DomainError::Raise("AppDef_LinearCriteria::SetWeight");
+
+ myQuadraticWeight = QuadraticWeight; myQualityWeight = QualityWeight;
+
+ Standard_Real Total = percentJ1 + percentJ2 + percentJ3;
+ myPercent[0] = percentJ1 / Total;
+ myPercent[1] = percentJ2 / Total;
+ myPercent[2] = percentJ3 / Total;
+}
+
+
+//=======================================================================
+//function : GetWeight
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::GetWeight(Standard_Real& QuadraticWeight,
+ Standard_Real& QualityWeight) const
+{
+
+ QuadraticWeight = myQuadraticWeight; QualityWeight = myQualityWeight;
+
+}
+
+//=======================================================================
+//function : SetWeight
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::SetWeight(const TColStd_Array1OfReal& Weight)
+{
+ myPntWeight = Weight;
+}
+
+
+//=======================================================================
+//function : BuildCache
+//purpose :
+//=======================================================================
+void AppDef_LinearCriteria::BuildCache(const Standard_Integer Element)
+{
+ Standard_Real t;
+ Standard_Real UFirst, ULast;
+ Standard_Integer ipnt;
+
+ UFirst = myCurve->Knots()(Element);
+ ULast = myCurve->Knots()(Element + 1);
+
+ IF = 0;
+ for(ipnt = myParameters->Lower(); ipnt <= myParameters->Upper(); ipnt++) {
+ t = myParameters->Value(ipnt);
+ if((t > UFirst && t <= ULast) || (Element == 1 && t == UFirst)) {
+ if (IF == 0) IF=ipnt;
+ IL = ipnt;
+ }
+ else if (t>ULast) break;
+ }
+
+ if (IF != 0) {
+ Handle(PLib_Base) myBase = myCurve->Base();
+ Standard_Integer order = myBase->WorkDegree()+1, ii;
+ myCache = new TColStd_HArray1OfReal (1, (IL-IF+1)*(order));
+
+ ii =1;
+ for(ipnt = IF, ii=1; ipnt <= IL; ipnt++, ii+=order) {
+ Standard_Real * cache = &myCache->ChangeValue(ii);
+ TColStd_Array1OfReal BasicValue(cache[0], 0, order-1);
+ t = myParameters->Value(ipnt);
+ Standard_Real coeff = 2./(ULast - UFirst), c0 = -(ULast + UFirst)/2., s;
+ s = (t + c0) * coeff;
+ myBase->D0(s, BasicValue);
+ }
+ }
+ else { //pas de points dans l'interval.
+ IF = IL;
+ IL--;
+ }
+ myE = Element;
+}
--- /dev/null
+-- Created on: 1997-09-11
+-- Created by: Philippe MANGIN
+-- Copyright (c) 1997-1999 Matra Datavision
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- This library is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU Lesser General Public License version 2.1 as published
+-- by the Free Software Foundation, with special exception defined in the file
+-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+-- distribution for complete text of the license and disclaimer of any warranty.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+deferred class SmoothCriterion from AppDef
+inherits TShared from MMgt
+
+ ---Purpose: defined criterion to smooth points in curve
+
+
+uses
+ Vector from math,
+ Matrix from math,
+ Curve from FEmTool,
+ HAssemblyTable from FEmTool,
+ HArray2OfInteger from TColStd,
+ HArray1OfReal from TColStd,
+ Array1OfReal from TColStd
+
+raises
+ NotImplemented,
+ DomainError
+
+
+
+is
+ SetParameters(me : mutable; Parameters : HArray1OfReal)
+ is deferred;
+
+ SetCurve(me : mutable; C :Curve from FEmTool)
+ is deferred;
+
+ GetCurve(me; C : out Curve from FEmTool)
+ is deferred;
+
+ SetEstimation(me : mutable; E1, E2, E3 : Real)
+ is deferred;
+
+ EstLength(me : mutable)
+ ---C++: return &
+ returns Real is deferred;
+
+ GetEstimation(me; E1, E2, E3 : out Real)
+ is deferred;
+
+ AssemblyTable(me)
+ returns HAssemblyTable from FEmTool
+ is deferred;
+
+ DependenceTable(me)
+ returns HArray2OfInteger from TColStd
+ is deferred;
+
+ QualityValues (me : mutable; J1min, J2min, J3min : Real;
+ J1, J2, J3 : out Real)
+ returns Integer is deferred;
+
+ ErrorValues(me : mutable;
+ MaxError, QuadraticError, AverageError : out Real)
+ is deferred;
+
+ Hessian(me : mutable ;
+ Element : Integer;
+ Dimension1 : Integer;
+ Dimension2 : Integer;
+ H : out Matrix from math)
+ raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
+ is deferred;
+
+
+ Gradient(me : mutable;
+ Element : Integer;
+ Dimension : Integer;
+ G : out Vector from math)
+ is deferred;
+
+ InputVector(me : mutable; X : Vector from math;
+ AssTable : HAssemblyTable from FEmTool)
+ ---Purpose: Convert the assembly Vector in an Curve;
+ --
+ raises DomainError is deferred;
+
+ SetWeight(me: mutable;
+ QuadraticWeight, QualityWeight : Real;
+ percentJ1, percentJ2, percentJ3 : Real)
+ is deferred;
+
+ GetWeight(me; QuadraticWeight, QualityWeight : out Real)
+ is deferred;
+
+ SetWeight(me: mutable;
+ Weight : Array1OfReal)
+ is deferred;
+
+end SmoothCriterion;
+
+
--- /dev/null
+// Created on: 1998-11-30
+// Created by: Igor FEOKTISTOV
+// Copyright (c) 1998-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AppDef_SmoothCriterion.ixx>
--- /dev/null
+-- Created on: 1996-05-14
+-- Created by: Philippe MANGIN / Jeannine PANCIATICI
+-- Copyright (c) 1996-1999 Matra Datavision
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- This library is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU Lesser General Public License version 2.1 as published
+-- by the Free Software Foundation, with special exception defined in the file
+-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+-- distribution for complete text of the license and disclaimer of any warranty.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+-- Igor FEOKTISTOV - correction 14/12/98
+
+
+class Variational from AppDef
+
+
+ ---Purpose: This class is used to smooth N points with constraints
+ -- by minimization of quadratic criterium but also
+ -- variational criterium in order to obtain " fair Curve "
+ --
+
+uses Matrix from math,
+ Vector from math,
+ HArray1OfReal from TColStd,
+ Array1OfReal from TColStd,
+ HArray1OfInteger from TColStd,
+ Shape from GeomAbs,
+ HArray1OfConstraintCouple from AppParCurves,
+ MultiBSpCurve from AppParCurves,
+ SmoothCriterion from AppDef,
+ Curve from FEmTool,
+ Assembly from FEmTool,
+ Base from PLib,
+ Constraint from AppParCurves,
+ MultiLine from AppDef,
+ MyLineTool from AppDef
+
+raises OutOfRange from Standard,
+ DimensionError from Standard,
+ DomainError from Standard,
+ ConstructionError from Standard,
+ NotDone from StdFail,
+ VectorWithNullMagnitude from gp
+
+
+is
+ Create(SSP: MultiLine from AppDef;
+ FirstPoint, LastPoint: Integer;
+ TheConstraints: HArray1OfConstraintCouple;
+ MaxDegree: Integer = 14;
+ MaxSegment: Integer = 100;
+ Continuity : Shape from GeomAbs = GeomAbs_C2;
+ WithMinMax : Boolean = Standard_False;
+ WithCutting: Boolean = Standard_True;
+ Tolerance : Real = 1.0;
+ NbIterations: Integer = 2)
+ ---Purpose: Constructor.
+ -- Initialization of the fields.
+ -- warning : Nc0 : number of PassagePoint consraints
+ -- Nc2 : number of TangencyPoint constraints
+ -- Nc3 : number of CurvaturePoint constraints
+ -- if
+ -- ((MaxDegree-Continuity)*MaxSegment -Nc0 - 2*Nc1
+ -- -3*Nc2)
+ -- is negative
+ -- The problem is over-constrained.
+ --
+ -- Limitation : The MultiLine from AppDef has to be composed by
+ -- only one Line ( Dimension 2 or 3).
+
+ returns Variational from AppDef;
+
+
+ Approximate(me : in out)
+ ---Purpose: Makes the approximation with the current fields.
+ raises NotDone from StdFail
+ is static;
+
+
+
+-- ==================== The Selectors ===========================
+
+ IsCreated(me)
+ ---Purpose: returns True if the creation is done
+ -- and correspond to the current fields.
+ returns Boolean
+ is static;
+
+
+ IsDone(me)
+ ---Purpose: returns True if the approximation is ok
+ -- and correspond to the current fields.
+ returns Boolean
+ is static;
+
+ IsOverConstrained(me)
+ ---Purpose: returns True if the problem is overconstrained
+ -- in this case, approximation cannot be done.
+ returns Boolean
+ is static;
+
+ Value(me)
+ ---Purpose: returns all the BSpline curves approximating the
+ -- MultiLine from AppDef SSP after minimization of the parameter.
+
+ returns MultiBSpCurve from AppParCurves
+ raises NotDone from StdFail
+ is static;
+
+
+ MaxError(me)
+ ---Purpose: returns the maximum of the distances between
+ -- the points of the multiline and the approximation
+ -- curves.
+ returns Real
+ raises NotDone from StdFail
+ is static;
+
+ MaxErrorIndex(me)
+ ---Purpose: returns the index of the MultiPoint of ErrorMax
+ returns Integer
+
+ raises NotDone from StdFail
+ is static;
+
+
+ QuadraticError(me)
+ ---Purpose: returns the quadratic average of the distances between
+ -- the points of the multiline and the approximation
+ -- curves.
+ returns Real
+ raises NotDone from StdFail
+ is static;
+
+ Distance(me : in out ; mat : out Matrix from math)
+ ---Purpose: returns the distances between the points of the
+ -- multiline and the approximation curves.
+ raises NotDone from StdFail
+ is static;
+
+ AverageError(me)
+ ---Purpose: returns the average error between
+ -- the MultiLine from AppDef and the approximation.
+
+ returns Real
+ raises NotDone from StdFail
+ is static;
+
+ Parameters(me)
+ ---Purpose: returns the parameters uses to the approximations
+ ---C++: return const&
+
+ returns HArray1OfReal
+ raises NotDone from StdFail
+ is static;
+
+ Knots(me)
+ ---Purpose: returns the knots uses to the approximations
+ ---C++: return const&
+ returns HArray1OfReal
+ raises NotDone from StdFail
+ is static;
+
+ Criterium(me; VFirstOrder,
+ VSecondOrder,
+ VThirdOrder : out Real)
+ ---Purpose: returns the values of the quality criterium.
+ raises NotDone from StdFail
+ is static;
+
+ CriteriumWeight(me ;
+ Percent1, Percent2, Percent3 : out Real)
+ ---Purpose: returns the Weights (as percent) associed to the criterium used in
+ -- the optimization.
+ is static;
+
+ MaxDegree(me)
+ ---Purpose: returns the Maximum Degree used in the approximation
+ returns Integer
+ is static;
+
+ MaxSegment(me)
+ ---Purpose: returns the Maximum of segment used in the approximation
+ returns Integer
+ is static;
+
+ Continuity(me)
+ ---Purpose: returns the Continuity used in the approximation
+ returns Shape from GeomAbs
+ is static;
+
+
+ WithMinMax(me)
+ ---Purpose: returns if the approximation search to minimize the
+ -- maximum Error or not.
+ returns Boolean
+ is static;
+
+ WithCutting(me)
+ ---Purpose: returns if the approximation can insert new Knots or not.
+ returns Boolean
+ is static;
+
+ Tolerance(me)
+ ---Purpose: returns the tolerance used in the approximation.
+ returns Real
+ is static;
+
+ NbIterations(me)
+ ---Purpose: returns the number of iterations used in the approximation.
+ returns Integer
+ is static;
+
+ Dump(me ; o : in out OStream)
+ ---Purpose: Prints on the stream o information on the current state
+ -- of the object.
+ -- MaxError,MaxErrorIndex,AverageError,QuadraticError,Criterium
+ -- Distances,Degre,Nombre de poles, parametres, noeuds
+ is static;
+
+ SetConstraints(me:in out; aConstrainst:HArray1OfConstraintCouple)
+ ---Purpose: Define the constraints to approximate
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ is static;
+
+ SetParameters(me:in out; param : HArray1OfReal)
+ ---Purpose: Defines the parameters used by the approximations.
+ raises DimensionError
+ is static;
+
+ SetKnots(me:in out; knots : HArray1OfReal)
+ ---Purpose: Defines the knots used by the approximations
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ raises DimensionError,
+ DomainError
+ is static;
+
+ SetMaxDegree(me: in out; Degree : Integer)
+ ---Purpose: Define the Maximum Degree used in the approximation
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ is static;
+
+ SetMaxSegment(me: in out; NbSegment : Integer)
+ ---Purpose: Define the maximum number of segments used in the approximation
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ is static;
+
+ SetContinuity(me: in out; C : Shape from GeomAbs)
+ ---Purpose: Define the Continuity used in the approximation
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ raises ConstructionError from Standard
+ is static;
+
+
+ SetWithMinMax(me: in out; MinMax : Boolean)
+ ---Purpose: Define if the approximation search to minimize the
+ -- maximum Error or not.
+ is static;
+
+ SetWithCutting(me : in out; Cutting : Boolean )
+ ---Purpose: Define if the approximation can insert new Knots or not.
+ -- If this value is incompatible with the others fields
+ -- this method modify nothing and returns false
+ returns Boolean
+ is static;
+
+ SetCriteriumWeight(me : in out;
+ Percent1, Percent2, Percent3 : Real)
+ ---Purpose: define the Weights (as percent) associed to the criterium used in
+ -- the optimization.
+ --
+ raises DomainError -- if Percent <= 0
+ is static;
+
+ SetCriteriumWeight(me : in out;
+ Order : Integer;
+ Percent : Real)
+ ---Purpose: define the Weight (as percent) associed to the
+ -- criterium Order used in the optimization : Others
+ -- weights are updated.
+ raises DomainError, -- if Percent < 0
+ OutOfRange -- if Order < 1 or Order > 3
+ is static;
+
+ SetTolerance(me:in out; Tol : Real)
+ ---Purpose: define the tolerance used in the approximation.
+ is static;
+
+ SetNbIterations(me:in out; Iter : Integer)
+ ---Purpose: define the number of iterations used in the approximation.
+ raises DomainError -- if Iter < 1
+ is static;
+
+
+-- ====================== The Private methods ======================
+
+ TheMotor(me : in out;
+ J : in out SmoothCriterion from AppDef;
+ WQuadratic, WQuality : Real;
+ TheCurve : in out Curve from FEmTool;
+ Ecarts : out Array1OfReal from TColStd) is private;
+
+ Adjusting(me : in out;
+ J : in out SmoothCriterion from AppDef;
+ WQuadratic, WQuality : in out Real;
+ TheCurve : in out Curve from FEmTool;
+ Ecarts : out Array1OfReal from TColStd) is private;
+
+ Optimization(me;
+ J : in out SmoothCriterion from AppDef;
+ A : in out Assembly from FEmTool;
+ ToAssemble : in Boolean;
+ EpsDeg : Real;
+ Curve : out Curve from FEmTool;
+ Parameters : Array1OfReal from TColStd) is private;
+
+ Project(me; C : Curve from FEmTool;
+ Ti : Array1OfReal from TColStd;
+ ProjTi : out Array1OfReal from TColStd;
+ Distance : out Array1OfReal from TColStd;
+ NumPoints : out Integer;
+ MaxErr, QuaErr, AveErr : out Real;
+ NbIterations: Integer=2) is private;
+
+ ACR(me; Curve : in out Curve from FEmTool;
+ Ti : in out Array1OfReal from TColStd;
+ Decima: Integer) is private;
+
+ SplitCurve(me; InCurve : Curve from FEmTool;
+ Ti : Array1OfReal from TColStd;
+ CurveTol: Real;
+ OutCurve: out Curve from FEmTool;
+ iscut : out Boolean) is private;
+
+ Init(me : in out)
+ raises NotDone from StdFail,
+ ConstructionError from Standard,
+ DimensionError from Standard
+ is private;
+
+ InitSmoothCriterion(me : in out)
+ is private;
+
+ InitParameters(me : in out; Length : out Real)
+ raises ConstructionError from Standard
+ is private;
+
+ InitCriterionEstimations(me; Length : Real; J1, J2, J3 : out Real)
+ is private;
+
+ EstTangent(me; ipnt : Integer; VTang : out Vector from math)
+ is private;
+
+ EstSecnd(me; ipnt : Integer; VTang1, VTang2 : Vector from math;
+ Length : Real; VScnd : out Vector from math)
+ is private;
+
+ InitCutting(me; aBase : Base from PLib; CurvTol : Real;
+ aCurve : out Curve from FEmTool)
+ raises ConstructionError from Standard
+ is private;
+
+ AssemblingConstraints(me; Curve : Curve from FEmTool;
+ Parameters : Array1OfReal from TColStd;
+ CBLONG : Real from Standard;
+ A : out Assembly from FEmTool)
+ is private;
+
+ InitTthetaF(me : in out; ndimen : Integer from Standard;
+ typcon : Constraint from AppParCurves;
+ begin : Integer from Standard;
+ jndex : Integer from Standard)
+ returns Boolean
+ is private;
+
+
+fields
+ -- Description of the points to smooth and the constraints
+mySSP : MultiLine from AppDef;
+myNbP3d : Integer;
+myNbP2d : Integer;
+myDimension : Integer;
+myFirstPoint : Integer;
+myLastPoint : Integer;
+myNbPoints : Integer;
+myTabPoints : HArray1OfReal;
+myConstraints : HArray1OfConstraintCouple;
+myNbConstraints : Integer;
+myTabConstraints : HArray1OfReal;
+myNbPassPoints : Integer;
+myNbTangPoints : Integer;
+myNbCurvPoints : Integer;
+myTypConstraints : HArray1OfInteger;
+myTtheta : HArray1OfReal;
+myTfthet : HArray1OfReal;
+
+ -- Context parameters
+myMaxDegree : Integer;
+myMaxSegment : Integer;
+myNbIterations: Integer;
+myTolerance : Real;
+
+ -- Options
+myContinuity : Shape from GeomAbs;
+myNivCont : Integer;
+myWithMinMax : Boolean;
+myWithCutting: Boolean;
+myPercent : Real[3];
+myCriterium : Real[4];
+mySmoothCriterion : SmoothCriterion from AppDef;
+
+ -- output
+myParameters : HArray1OfReal;
+myKnots : HArray1OfReal;
+myMBSpCurve : MultiBSpCurve;
+
+myMaxError : Real;
+myMaxErrorIndex: Integer;
+myAverageError : Real;
+myIsCreated : Boolean;
+myIsDone : Boolean;
+myIsOverConstr : Boolean;
+
+end Variational;
--- /dev/null
+// Copyright (c) 1996-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+// Jeannine PANCIATICI le 06/06/96
+// Igor FEOKTISTOV 14/12/98 - correction of Approximate() and Init().
+// Approximation d une MultiLine de points decrite par le tool MLineTool.
+// avec criteres variationnels
+
+#include <AppDef_Variational.ixx>
+
+#define No_Standard_RangeError
+#define No_Standard_OutOfRange
+#define No_Standard_DimensionError
+#define No_Standard_ConstructionError
+
+#include <Standard_Stream.hxx>
+
+#include <AppParCurves.hxx>
+#include <AppParCurves_Constraint.hxx>
+#include <AppParCurves_HArray1OfConstraintCouple.hxx>
+#include <AppParCurves_Array1OfMultiPoint.hxx>
+#include <AppParCurves_MultiPoint.hxx>
+#include <AppParCurves_MultiBSpCurve.hxx>
+#include <AppDef_LinearCriteria.hxx>
+#include <Convert_CompPolynomialToPoles.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec.hxx>
+#include <gp_Vec2d.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColgp_Array1OfVec.hxx>
+#include <TColgp_Array1OfVec2d.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_HArray2OfReal.hxx>
+#include <StdFail_NotDone.hxx>
+#include <Standard_SStream.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <Precision.hxx>
+#include <AppDef_MyLineTool.hxx>
+
+#include <SortTools_StraightInsertionSortOfReal.hxx>
+#include <SortTools_ShellSortOfReal.hxx>
+#include <TCollection_CompareOfReal.hxx>
+#include <TColStd_HArray2OfInteger.hxx>
+#include <TColStd_Array2OfInteger.hxx>
+#include <TColStd_Array2OfReal.hxx>
+#include <FEmTool_Assembly.hxx>
+#include <FEmTool_AssemblyTable.hxx>
+#include <FEmTool_Curve.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+#include <PLib_Base.hxx>
+#include <PLib_JacobiPolynomial.hxx>
+#include <PLib_HermitJacobi.hxx>
+#include <FEmTool_HAssemblyTable.hxx>
+
+#if defined(WNT)
+# include <stdio.h>
+# include <stdarg.h>
+#endif /* WNT */
+
+//
+//=======================================================================
+//function : AppDef_Variational
+//purpose : Initialization of the fields.
+//=======================================================================
+//
+AppDef_Variational::AppDef_Variational(const AppDef_MultiLine& SSP,
+ const Standard_Integer FirstPoint,
+ const Standard_Integer LastPoint,
+ const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
+ const Standard_Integer MaxDegree,
+ const Standard_Integer MaxSegment,
+ const GeomAbs_Shape Continuity,
+ const Standard_Boolean WithMinMax,
+ const Standard_Boolean WithCutting,
+ const Standard_Real Tolerance,
+ const Standard_Integer NbIterations):
+mySSP(SSP),
+myFirstPoint(FirstPoint),
+myLastPoint(LastPoint),
+myConstraints(TheConstraints),
+myMaxDegree(MaxDegree),
+myMaxSegment(MaxSegment),
+myNbIterations(NbIterations),
+myTolerance(Tolerance),
+myContinuity(Continuity),
+myWithMinMax(WithMinMax),
+myWithCutting(WithCutting)
+{
+ // Verifications:
+ if (myMaxDegree < 1) Standard_DomainError::Raise();
+ myMaxDegree = Min (30, myMaxDegree);
+ //
+ if (myMaxSegment < 1) Standard_DomainError::Raise();
+ //
+ if (myWithMinMax != 0 && myWithMinMax !=1 ) Standard_DomainError::Raise();
+ if (myWithCutting != 0 && myWithCutting !=1 ) Standard_DomainError::Raise();
+ //
+ myIsOverConstr = Standard_False;
+ myIsCreated = Standard_False;
+ myIsDone = Standard_False;
+ switch (myContinuity) {
+ case GeomAbs_C0:
+ myNivCont=0;
+ break ;
+ case GeomAbs_C1:
+ myNivCont=1;
+ break ;
+ case GeomAbs_C2:
+ myNivCont=2;
+ break ;
+ default:
+ Standard_ConstructionError::Raise();
+ }
+ //
+ myNbP2d = AppDef_MyLineTool::NbP2d(SSP);
+ myNbP3d = AppDef_MyLineTool::NbP3d(SSP);
+ myDimension = 2 * myNbP2d + 3* myNbP3d ;
+ //
+ myPercent[0]=0.4;
+ myPercent[1]=0.2;
+ myPercent[2]=0.4;
+ myKnots= new TColStd_HArray1OfReal(1,2);
+ myKnots->SetValue(1,0.);
+ myKnots->SetValue(2,1.);
+
+ // Declaration
+ //
+ mySmoothCriterion = new AppDef_LinearCriteria(mySSP, myFirstPoint, myLastPoint);
+ myParameters = new TColStd_HArray1OfReal(myFirstPoint, myLastPoint);
+ myNbPoints=myLastPoint-myFirstPoint+1;
+ if (myNbPoints <= 0) Standard_ConstructionError::Raise();
+ //
+ myTabPoints= new TColStd_HArray1OfReal(1,myDimension*myNbPoints);
+ //
+ // Table of Points initialization
+ //
+ Standard_Integer ipoint,jp2d,jp3d,index;
+ TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
+ TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
+ gp_Pnt2d P2d;
+ gp_Pnt P3d;
+ index=1;
+
+ for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
+ {
+
+ if(myNbP2d !=0 && myNbP3d ==0 ) {
+ AppDef_MyLineTool::Value(mySSP,ipoint,TabP2d);
+
+ for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
+ { P2d = TabP2d.Value(jp2d);
+
+ myTabPoints->SetValue(index++,P2d.X());
+ myTabPoints->SetValue(index++,P2d.Y());
+ }
+ }
+ if(myNbP3d !=0 && myNbP2d == 0 ) {
+ AppDef_MyLineTool::Value(mySSP,ipoint,TabP3d);
+
+ for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
+
+ { P3d=TabP3d.Value(jp3d);
+
+ myTabPoints->SetValue(index++,P3d.X());
+ myTabPoints->SetValue(index++,P3d.Y());
+ myTabPoints->SetValue(index++,P3d.Z());
+
+ }
+ }
+ if(myNbP3d !=0 && myNbP2d != 0 ) {
+ AppDef_MyLineTool::Value(mySSP,ipoint,TabP3d,TabP2d);
+
+ for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
+
+ { P3d=TabP3d.Value(jp3d);
+
+ myTabPoints->SetValue(index++,P3d.X());
+ myTabPoints->SetValue(index++,P3d.Y());
+ myTabPoints->SetValue(index++,P3d.Z());
+
+ }
+ for ( jp2d = 1 ; jp2d <= myNbP2d ; jp2d++)
+
+ { P2d=TabP2d.Value(jp2d);
+
+ myTabPoints->SetValue(index++,P2d.X());
+ myTabPoints->SetValue(index++,P2d.Y());
+ }
+ }
+ }
+ Init();
+}
+//
+//=======================================================================
+//function : Init
+//purpose : Initializes the tables of constraints
+// and verifies if the problem is not over-constrained.
+// This method is used in the Create and the method SetConstraint.
+//=======================================================================
+//
+void AppDef_Variational::Init()
+{
+
+ Standard_Integer ipoint,jp2d,jp3d,index,jndex;
+ Standard_Integer CurMultyPoint;
+ TColgp_Array1OfVec TabV3d(1, Max(1,myNbP3d));
+ TColgp_Array1OfVec2d TabV2d(1, Max(1,myNbP2d));
+ TColgp_Array1OfVec TabV3dcurv(1, Max(1,myNbP3d));
+ TColgp_Array1OfVec2d TabV2dcurv(1, Max(1,myNbP2d));
+
+ gp_Vec Vt3d, Vc3d;
+ gp_Vec2d Vt2d, Vc2d;
+
+ myNbConstraints=myConstraints->Length();
+ if (myNbConstraints < 0) Standard_ConstructionError::Raise();
+
+ myTypConstraints = new TColStd_HArray1OfInteger(1,Max(1,2*myNbConstraints));
+ myTabConstraints = new TColStd_HArray1OfReal(1,Max(1,2*myDimension*myNbConstraints));
+ myTtheta = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
+ myTfthet = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
+
+
+ //
+ // Table of types initialization
+ Standard_Integer iconstr;
+ index=1;
+ jndex=1;
+ CurMultyPoint = 1;
+ myNbPassPoints=0;
+ myNbTangPoints=0;
+ myNbCurvPoints=0;
+ AppParCurves_Constraint valcontr;
+
+ for ( iconstr = myConstraints->Lower() ; iconstr <= myConstraints->Upper() ; iconstr++)
+ {
+ ipoint=(myConstraints->Value(iconstr)).Index();
+
+ valcontr=(myConstraints->Value(iconstr)).Constraint();
+ switch (valcontr) {
+ case AppParCurves_NoConstraint:
+ CurMultyPoint -= myNbP3d * 6 + myNbP2d * 2;
+ break ;
+ case AppParCurves_PassPoint:
+ myTypConstraints->SetValue(index++,ipoint);
+ myTypConstraints->SetValue(index++,0);
+ myNbPassPoints++;
+ if(myNbP2d !=0 ) jndex=jndex+4*myNbP2d;
+ if(myNbP3d !=0 ) jndex=jndex+6*myNbP3d;
+ break ;
+ case AppParCurves_TangencyPoint:
+ myTypConstraints->SetValue(index++,ipoint);
+ myTypConstraints->SetValue(index++,1);
+ myNbTangPoints++;
+ if(myNbP2d !=0 && myNbP3d == 0 )
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV2d) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ Vt2d=TabV2d.Value(jp2d);
+ Vt2d.Normalize();
+ myTabConstraints->SetValue(jndex++,Vt2d.X());
+ myTabConstraints->SetValue(jndex++,Vt2d.Y());
+ jndex=jndex+2;
+ InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
+ }
+ }
+ if(myNbP3d !=0 && myNbP2d == 0)
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV3d) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp3d=1;jp3d<=myNbP3d;jp3d++)
+ {
+ Vt3d=TabV3d.Value(jp3d);
+ Vt3d.Normalize();
+ myTabConstraints->SetValue(jndex++,Vt3d.X());
+
+ myTabConstraints->SetValue(jndex++,Vt3d.Y());
+
+ myTabConstraints->SetValue(jndex++,Vt3d.Z());
+ jndex=jndex+3;
+ InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
+ }
+ }
+ if(myNbP3d !=0 && myNbP2d != 0)
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp3d=1;jp3d<=myNbP3d;jp3d++)
+ {
+ Vt3d=TabV3d.Value(jp3d);
+ Vt3d.Normalize();
+ myTabConstraints->SetValue(jndex++,Vt3d.X());
+ myTabConstraints->SetValue(jndex++,Vt3d.Y());
+ myTabConstraints->SetValue(jndex++,Vt3d.Z());
+ jndex=jndex+3;
+ InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
+ }
+
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ Vt2d=TabV2d.Value(jp2d);
+ Vt2d.Normalize();
+ myTabConstraints->SetValue(jndex++,Vt2d.X());
+ myTabConstraints->SetValue(jndex++,Vt2d.Y());
+ jndex=jndex+2;
+ InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
+ }
+ }
+
+
+ break ;
+
+ case AppParCurves_CurvaturePoint:
+ myTypConstraints->SetValue(index++,ipoint);
+ myTypConstraints->SetValue(index++,2);
+ myNbCurvPoints++;
+ if(myNbP2d !=0 && myNbP3d == 0)
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV2d) == Standard_False )
+ Standard_ConstructionError::Raise();
+ if (AppDef_MyLineTool::Curvature(mySSP,ipoint,TabV2dcurv) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ Vt2d=TabV2d.Value(jp2d);
+ Vt2d.Normalize();
+ Vc2d=TabV2dcurv.Value(jp2d);
+ if (Abs(Abs(Vc2d.Angle(Vt2d)) - M_PI/2.) > Precision::Angular())
+ Standard_ConstructionError::Raise();
+ myTabConstraints->SetValue(jndex++,Vt2d.X());
+ myTabConstraints->SetValue(jndex++,Vt2d.Y());
+ myTabConstraints->SetValue(jndex++,Vc2d.X());
+ myTabConstraints->SetValue(jndex++,Vc2d.Y());
+ InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
+ }
+ }
+
+ if(myNbP3d !=0 && myNbP2d == 0 )
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV3d) == Standard_False )
+ Standard_ConstructionError::Raise();
+ if (AppDef_MyLineTool::Curvature(mySSP,ipoint,TabV3dcurv) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp3d=1;jp3d<=myNbP3d;jp3d++)
+ {
+ Vt3d=TabV3d.Value(jp3d);
+ Vt3d.Normalize();
+ Vc3d=TabV3dcurv.Value(jp3d);
+ if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
+ Standard_ConstructionError::Raise();
+ myTabConstraints->SetValue(jndex++,Vt3d.X());
+ myTabConstraints->SetValue(jndex++,Vt3d.Y());
+ myTabConstraints->SetValue(jndex++,Vt3d.Z());
+ myTabConstraints->SetValue(jndex++,Vc3d.X());
+ myTabConstraints->SetValue(jndex++,Vc3d.Y());
+ myTabConstraints->SetValue(jndex++,Vc3d.Z());
+ InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
+ }
+ }
+ if(myNbP3d !=0 && myNbP2d != 0 )
+ {
+ if (AppDef_MyLineTool::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False )
+ Standard_ConstructionError::Raise();
+ if (AppDef_MyLineTool::Curvature(mySSP,ipoint,TabV3dcurv,TabV2dcurv) == Standard_False)
+ Standard_ConstructionError::Raise();
+ for (jp3d=1;jp3d<=myNbP3d;jp3d++)
+ {
+ Vt3d=TabV3d.Value(jp3d);
+ Vt3d.Normalize();
+ Vc3d=TabV3dcurv.Value(jp3d);
+ if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
+ Standard_ConstructionError::Raise();
+ myTabConstraints->SetValue(jndex++,Vt3d.X());
+ myTabConstraints->SetValue(jndex++,Vt3d.Y());
+ myTabConstraints->SetValue(jndex++,Vt3d.Z());
+ myTabConstraints->SetValue(jndex++,Vc3d.X());
+ myTabConstraints->SetValue(jndex++,Vc3d.Y());
+ myTabConstraints->SetValue(jndex++,Vc3d.Z());
+ InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
+ }
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ Vt2d=TabV2d.Value(jp2d);
+ Vt2d.Normalize();
+ Vc2d=TabV2dcurv.Value(jp2d);
+ if (Abs(Abs(Vc2d.Angle(Vt2d)) - M_PI/2.) > Precision::Angular())
+ Standard_ConstructionError::Raise();
+ myTabConstraints->SetValue(jndex++,Vt2d.X());
+ myTabConstraints->SetValue(jndex++,Vt2d.Y());
+ myTabConstraints->SetValue(jndex++,Vc2d.X());
+ myTabConstraints->SetValue(jndex++,Vc2d.Y());
+ InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
+ }
+
+ }
+ break ;
+ default:
+ Standard_ConstructionError::Raise();
+ }
+ CurMultyPoint += myNbP3d * 6 + myNbP2d * 2;
+ }
+ // OverConstraint Detection
+ Standard_Integer MaxSeg;
+ if(myWithCutting == Standard_True) MaxSeg = myMaxSegment ;
+ else MaxSeg = 1;
+ if (((myMaxDegree-myNivCont)*MaxSeg-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ {
+ myIsOverConstr =Standard_True;
+ myIsCreated = Standard_False;
+ }
+ else {
+ InitSmoothCriterion();
+ myIsCreated = Standard_True;
+ }
+
+
+}
+//
+//=======================================================================
+//function : Approximate
+//purpose : Makes the approximation with the current fields.
+//=======================================================================
+//
+void AppDef_Variational::Approximate()
+
+{
+ if (myIsCreated == Standard_False ) StdFail_NotDone:: Raise();
+
+
+ Standard_Real WQuadratic, WQuality;
+
+ TColStd_Array1OfReal Ecarts(myFirstPoint, myLastPoint);
+
+ mySmoothCriterion->GetWeight(WQuadratic, WQuality);
+
+ Handle(FEmTool_Curve) TheCurve;
+
+ mySmoothCriterion->GetCurve(TheCurve);
+
+ //---------------------------------------------------------------------
+
+ TheMotor(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
+
+
+ if(myWithMinMax && myTolerance < myMaxError)
+ Adjusting(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
+
+ //---------------------------------------------------------------------
+
+ Standard_Integer jp2d,jp3d,index,ipole,
+ NbElem = TheCurve->NbElements();
+
+ TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
+ TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
+ Standard_Real debfin[2] = {-1., 1};
+
+ gp_Pnt2d P2d;
+ gp_Pnt P3d;
+
+ index=0;
+
+ {
+ Handle(TColStd_HArray2OfReal) PolynomialIntervalsPtr =
+ new TColStd_HArray2OfReal(1,NbElem,1,2) ;
+
+ Handle(TColStd_HArray1OfInteger) NbCoeffPtr =
+ new TColStd_HArray1OfInteger(1, myMaxSegment);
+
+ Standard_Integer size = myMaxSegment * (myMaxDegree + 1) * myDimension ;
+ Handle(TColStd_HArray1OfReal) CoeffPtr = new TColStd_HArray1OfReal(1,size);
+
+ CoeffPtr->Init(0.);
+
+ Handle(TColStd_HArray1OfReal) IntervallesPtr =
+ new TColStd_HArray1OfReal(1, NbElem + 1);
+
+ IntervallesPtr->ChangeArray1() = TheCurve->Knots();
+
+ TheCurve->GetPolynom(CoeffPtr->ChangeArray1());
+
+ Standard_Integer ii;
+
+ for(ii = 1; ii <= NbElem; ii++)
+ NbCoeffPtr->SetValue(ii, TheCurve->Degree(ii)+1);
+
+
+ for (ii = PolynomialIntervalsPtr->LowerRow() ;
+ ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
+ {
+ PolynomialIntervalsPtr->SetValue(ii,1,debfin[0]) ;
+ PolynomialIntervalsPtr->SetValue(ii,2,debfin[1]) ;
+ }
+ /*
+ printf("\n =========== Parameters for converting\n");
+ printf("nb_courbes : %d \n", NbElem);
+ printf("tab_option[4] : %d \n", myNivCont);
+ printf("myDimension : %d \n", myDimension);
+ printf("myMaxDegree : %d \n", myMaxDegree);
+ printf("\n NbcoeffPtr :\n");
+ for(ii = 1; ii <= NbElem; ii++) printf("NbCoeffPtr(%d) = %d \n", ii, NbCoeffPtr->Value(ii));
+ size = NbElem*(myMaxDegree + 1) * myDimension;
+ printf("\n CoeffPtr :\n");
+ for(ii = 1; ii <= size; ii++) printf("CoeffPtr(%d) = %.8e \n", ii, CoeffPtr->Value(ii));
+ printf("\n PolinimialIntervalsPtr :\n");
+ for (ii = PolynomialIntervalsPtr->LowerRow() ;
+ ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
+ {
+ printf(" %d : [%f, %f] \n", ii, PolynomialIntervalsPtr->Value(ii,1),
+ PolynomialIntervalsPtr->Value(ii,2)) ;
+ }
+ printf("\n IntervallesPtr :\n");
+ for (ii = IntervallesPtr->Lower();
+ ii <= IntervallesPtr->Upper() - 1; ii++)
+ {
+ printf(" %d : [%f, %f] \n", ii, IntervallesPtr->Value(ii),
+ IntervallesPtr->Value(ii+1)) ;
+ }
+ */
+ Convert_CompPolynomialToPoles AConverter(NbElem,
+ myNivCont,
+ myDimension,
+ myMaxDegree,
+ NbCoeffPtr,
+ CoeffPtr,
+ PolynomialIntervalsPtr,
+ IntervallesPtr) ;
+ if (AConverter.IsDone())
+ {
+ Handle(TColStd_HArray2OfReal) PolesPtr ;
+ Handle(TColStd_HArray1OfInteger) Mults;
+ Standard_Integer NbPoles=AConverter.NbPoles();
+ // Standard_Integer Deg=AConverter.Degree();
+ AppParCurves_Array1OfMultiPoint TabMU(1,NbPoles);
+ AConverter.Poles(PolesPtr) ;
+ AConverter.Knots(myKnots) ;
+ AConverter.Multiplicities(Mults) ;
+
+ for (ipole=PolesPtr->LowerRow();ipole<=PolesPtr->UpperRow();ipole++)
+ {
+ index=PolesPtr->LowerCol();
+ /* if(myNbP2d !=0 )
+ {
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ P2d.SetX(PolesPtr->Value(ipole,index++));
+ P2d.SetY(PolesPtr->Value(ipole,index++));
+ TabP2d.SetValue(jp2d,P2d);
+ }
+ }*/
+ if(myNbP3d !=0 )
+ {
+ for (jp3d=1;jp3d<=myNbP3d;jp3d++)
+ {
+ // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
+ P3d.SetX(PolesPtr->Value(ipole,index++));
+ // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
+ P3d.SetY(PolesPtr->Value(ipole,index++));
+ // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
+ P3d.SetZ(PolesPtr->Value(ipole,index++));
+ TabP3d.SetValue(jp3d,P3d);
+ }
+ }
+ if(myNbP2d !=0 )
+ {
+ for (jp2d=1;jp2d<=myNbP2d;jp2d++)
+ {
+ P2d.SetX(PolesPtr->Value(ipole,index++));
+ P2d.SetY(PolesPtr->Value(ipole,index++));
+ TabP2d.SetValue(jp2d,P2d);
+ }
+ }
+ if(myNbP2d !=0 && myNbP3d !=0)
+ {
+ AppParCurves_MultiPoint aMultiPoint(TabP3d,TabP2d);
+ TabMU.SetValue(ipole,aMultiPoint);
+ }
+ else if (myNbP2d !=0)
+ {
+ AppParCurves_MultiPoint aMultiPoint(TabP2d);
+ TabMU.SetValue(ipole,aMultiPoint);
+ }
+ else
+ {
+
+ AppParCurves_MultiPoint aMultiPoint(TabP3d);
+ TabMU.SetValue(ipole,aMultiPoint);
+ }
+
+ }
+ AppParCurves_MultiBSpCurve aCurve(TabMU,myKnots->Array1(),Mults->Array1());
+ myMBSpCurve=aCurve;
+ myIsDone = Standard_True;
+ }
+ }
+
+}
+//
+//=======================================================================
+//function : IsCreated
+//purpose : returns True if the creation is done
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::IsCreated() const
+{
+ return myIsCreated;
+}
+//
+//=======================================================================
+//function : IsDone
+//purpose : returns True if the approximation is ok
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::IsDone() const
+{
+ return myIsDone;
+}
+//
+//=======================================================================
+//function : IsOverConstrained
+//purpose : returns True if the problem is overconstrained
+// in this case, approximation cannot be done.
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::IsOverConstrained() const
+{
+ return myIsOverConstr;
+}
+//
+//=======================================================================
+//function : Value
+//purpose : returns all the BSpline curves approximating the
+// MultiLine SSP after minimization of the parameter.
+
+//=======================================================================
+//
+AppParCurves_MultiBSpCurve AppDef_Variational::Value() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myMBSpCurve;
+
+}
+//
+//=======================================================================
+//function : MaxError
+//purpose : returns the maximum of the distances between
+// the points of the multiline and the approximation
+// curves.
+//=======================================================================
+//
+Standard_Real AppDef_Variational::MaxError() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myMaxError;
+}
+//
+//=======================================================================
+//function : MaxErrorIndex
+//purpose : returns the index of the MultiPoint of ErrorMax
+//=======================================================================
+//
+Standard_Integer AppDef_Variational::MaxErrorIndex() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myMaxErrorIndex;
+}
+//
+//=======================================================================
+//function : QuadraticError
+//purpose : returns the quadratic average of the distances between
+// the points of the multiline and the approximation
+// curves.
+//=======================================================================
+//
+Standard_Real AppDef_Variational::QuadraticError() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myCriterium[0];
+}
+//
+//=======================================================================
+//function : Distance
+//purpose : returns the distances between the points of the
+// multiline and the approximation curves.
+//=======================================================================
+//
+void AppDef_Variational::Distance(math_Matrix& mat)
+
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ Standard_Integer ipoint,jp2d,jp3d,index;
+ TColgp_Array1OfPnt TabP3d(1,Max(1,myNbP3d));
+ TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
+ Standard_Integer j0 = mat.LowerCol() - myFirstPoint;
+
+ gp_Pnt2d P2d;
+ gp_Pnt P3d;
+
+
+ gp_Pnt Pt3d;
+ gp_Pnt2d Pt2d;
+
+ for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
+ {
+ index=1;
+ if(myNbP3d !=0 ) {
+ AppDef_MyLineTool::Value(mySSP,ipoint,TabP3d);
+
+ for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
+
+ { P3d=TabP3d.Value(jp3d);
+ myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt3d);
+ mat(index++, j0 + ipoint)=P3d.Distance(Pt3d);
+
+ }
+ }
+ if(myNbP2d !=0 ) {
+ if(myNbP3d == 0 ) AppDef_MyLineTool::Value(mySSP,ipoint,TabP2d);
+ else AppDef_MyLineTool::Value(mySSP,ipoint,TabP3d,TabP2d);
+ for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
+
+ { P2d = TabP2d.Value(jp2d);
+ myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt2d);
+ mat(index++, j0 + ipoint)=P2d.Distance(Pt2d);
+ }
+ }
+ }
+
+}
+//
+//=======================================================================
+//function : AverageError
+//purpose : returns the average error between
+// the MultiLine and the approximation.
+//=======================================================================
+//
+Standard_Real AppDef_Variational::AverageError() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myAverageError;
+}
+//
+//=======================================================================
+//function : Parameters
+//purpose : returns the parameters uses to the approximations
+//=======================================================================
+//
+const Handle(TColStd_HArray1OfReal)& AppDef_Variational::Parameters() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myParameters;
+}
+//
+//=======================================================================
+//function : Knots
+//purpose : returns the knots uses to the approximations
+//=======================================================================
+//
+const Handle(TColStd_HArray1OfReal)& AppDef_Variational::Knots() const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ return myKnots;
+}
+//
+//=======================================================================
+//function : Criterium
+//purpose : returns the values of the quality criterium.
+//=======================================================================
+//
+void AppDef_Variational::Criterium(Standard_Real& VFirstOrder, Standard_Real& VSecondOrder, Standard_Real& VThirdOrder) const
+{
+ if (myIsDone == Standard_False) StdFail_NotDone::Raise();
+ VFirstOrder=myCriterium[1] ;
+ VSecondOrder=myCriterium[2];
+ VThirdOrder=myCriterium[3];
+}
+//
+//=======================================================================
+//function : CriteriumWeight
+//purpose : returns the Weights (as percent) associed to the criterium used in
+// the optimization.
+//=======================================================================
+//
+void AppDef_Variational::CriteriumWeight(Standard_Real& Percent1, Standard_Real& Percent2, Standard_Real& Percent3) const
+{
+ Percent1 = myPercent[0];
+ Percent2 = myPercent[1];
+ Percent3 = myPercent[2] ;
+}
+//
+//=======================================================================
+//function : MaxDegree
+//purpose : returns the Maximum Degree used in the approximation
+//=======================================================================
+//
+Standard_Integer AppDef_Variational::MaxDegree() const
+{
+ return myMaxDegree;
+}
+//
+//=======================================================================
+//function : MaxSegment
+//purpose : returns the Maximum of segment used in the approximation
+//=======================================================================
+//
+Standard_Integer AppDef_Variational::MaxSegment() const
+{
+ return myMaxSegment;
+}
+//
+//=======================================================================
+//function : Continuity
+//purpose : returns the Continuity used in the approximation
+//=======================================================================
+//
+GeomAbs_Shape AppDef_Variational::Continuity() const
+{
+ return myContinuity;
+}
+//
+//=======================================================================
+//function : WithMinMax
+//purpose : returns if the approximation search to minimize the
+// maximum Error or not.
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::WithMinMax() const
+{
+ return myWithMinMax;
+}
+//
+//=======================================================================
+//function : WithCutting
+//purpose : returns if the approximation can insert new Knots or not.
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::WithCutting() const
+{
+ return myWithCutting;
+}
+//
+//=======================================================================
+//function : Tolerance
+//purpose : returns the tolerance used in the approximation.
+//=======================================================================
+//
+Standard_Real AppDef_Variational::Tolerance() const
+{
+ return myTolerance;
+}
+//
+//=======================================================================
+//function : NbIterations
+//purpose : returns the number of iterations used in the approximation.
+//=======================================================================
+//
+Standard_Integer AppDef_Variational::NbIterations() const
+{
+ return myNbIterations;
+}
+//
+//=======================================================================
+//function : Dump
+//purpose : Prints on the stream o information on the current state
+// of the object.
+//=======================================================================
+//
+void AppDef_Variational::Dump(Standard_OStream& o) const
+{
+ o << " \nVariational Smoothing " << endl;
+ o << " Number of multipoints " << myNbPoints << endl;
+ o << " Number of 2d par multipoint " << myNbP2d << endl;
+ o << " Nombre of 3d par multipoint " << myNbP3d << endl;
+ o << " Number of PassagePoint " << myNbPassPoints << endl;
+ o << " Number of TangencyPoints " << myNbTangPoints << endl;
+ o << " Number of CurvaturePoints " << myNbCurvPoints << endl;
+ o << " \nTolerance " << o.setf(ios::scientific) << setprecision(3) << setw(9) << myTolerance;
+ if ( WithMinMax()) { o << " as Max Error." << endl;}
+ else { o << " as size Error." << endl;}
+ o << "CriteriumWeights : " << myPercent[0] << " , "
+ << myPercent[1] << " , " << myPercent[2] << endl;
+
+ if (myIsDone ) {
+ o << " MaxError " << setprecision(3) << setw(9) << myMaxError << endl;
+ o << " Index of MaxError " << myMaxErrorIndex << endl;
+ o << " Average Error " << setprecision(3) << setw(9) << myAverageError << endl;
+ o << " Quadratic Error " << setprecision(3) << setw(9) << myCriterium[0] << endl;
+ o << " Tension Criterium " << setprecision(3) << setw(9) << myCriterium[1] << endl;
+ o << " Flexion Criterium " << setprecision(3) << setw(9) << myCriterium[2] << endl;
+ o << " Jerk Criterium " << setprecision(3) << setw(9) << myCriterium[3] << endl;
+ o << " NbSegments " << myKnots->Length()-1 << endl;
+ }
+ else
+ { if (myIsOverConstr) o << "The probleme is overconstraint " << endl;
+ else o << " Erreur dans l''approximation" << endl;
+ }
+}
+//
+//=======================================================================
+//function : SetConstraints
+//purpose : Define the constraints to approximate
+// If this value is incompatible with the others fields
+// this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetConstraints(const Handle(AppParCurves_HArray1OfConstraintCouple)& aConstraint)
+
+{
+ myConstraints=aConstraint;
+ Init();
+ if (myIsOverConstr ) return Standard_False;
+ else return Standard_True;
+}
+//
+//=======================================================================
+//function : SetParameters
+//purpose : Defines the parameters used by the approximations.
+//=======================================================================
+//
+void AppDef_Variational::SetParameters(const Handle(TColStd_HArray1OfReal)& param)
+{
+ myParameters->ChangeArray1() = param->Array1();
+}
+//
+//=======================================================================
+//function : SetKnots
+//purpose : Defines the knots used by the approximations
+// -- If this value is incompatible with the others fields
+// -- this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetKnots(const Handle(TColStd_HArray1OfReal)& knots)
+{
+ myKnots->ChangeArray1() = knots->Array1();
+ return Standard_True;
+}
+//
+//=======================================================================
+//function : SetMaxDegree
+//purpose : Define the Maximum Degree used in the approximation
+// If this value is incompatible with the others fields
+// this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetMaxDegree(const Standard_Integer Degree)
+{
+ if (((Degree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ return Standard_False;
+ else
+ {
+ myMaxDegree=Degree;
+
+ InitSmoothCriterion();
+
+ return Standard_True;
+ }
+
+}
+//
+//=======================================================================
+//function : SetMaxSegment
+//purpose : Define the maximum number of segments used in the approximation
+// If this value is incompatible with the others fields
+// this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetMaxSegment(const Standard_Integer NbSegment)
+{
+ if ( myWithCutting == Standard_True &&
+ ((myMaxDegree-myNivCont)*NbSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ return Standard_False;
+ else
+ {
+ myMaxSegment=NbSegment;
+ return Standard_True;
+ }
+}
+//
+//=======================================================================
+//function : SetContinuity
+//purpose : Define the Continuity used in the approximation
+// If this value is incompatible with the others fields
+// this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetContinuity(const GeomAbs_Shape C)
+{
+ Standard_Integer NivCont=0;
+ switch (C) {
+ case GeomAbs_C0:
+ NivCont=0;
+ break ;
+ case GeomAbs_C1:
+ NivCont=1;
+ break ;
+ case GeomAbs_C2:
+ NivCont=2;
+ break ;
+ default:
+ Standard_ConstructionError::Raise();
+ }
+ if (((myMaxDegree-NivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ return Standard_False;
+ else
+ {
+ myContinuity= C;
+ myNivCont=NivCont;
+
+ InitSmoothCriterion();
+ return Standard_True;
+ }
+}
+//
+//=======================================================================
+//function : SetWithMinMax
+//purpose : Define if the approximation search to minimize the
+// maximum Error or not.
+//=======================================================================
+//
+void AppDef_Variational::SetWithMinMax(const Standard_Boolean MinMax)
+{
+ myWithMinMax=MinMax;
+
+ InitSmoothCriterion();
+}
+//
+//=======================================================================
+//function : SetWithCutting
+//purpose : Define if the approximation can insert new Knots or not.
+// If this value is incompatible with the others fields
+// this method modify nothing and returns false
+//=======================================================================
+//
+Standard_Boolean AppDef_Variational::SetWithCutting(const Standard_Boolean Cutting)
+{
+ if (Cutting == Standard_False)
+ {
+ if (((myMaxDegree-myNivCont)*myKnots->Length()-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ return Standard_False;
+
+ else
+ {
+ myWithCutting=Cutting;
+ InitSmoothCriterion();
+ return Standard_True;
+ }
+ }
+ else
+ {
+ if (((myMaxDegree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
+ return Standard_False;
+
+ else
+ {
+ myWithCutting=Cutting;
+ InitSmoothCriterion();
+ return Standard_True;
+ }
+ }
+}
+//
+//=======================================================================
+//function : SetCriteriumWeight
+//purpose : define the Weights (as percent) associed to the criterium used in
+// the optimization.
+//=======================================================================
+//
+void AppDef_Variational::SetCriteriumWeight(const Standard_Real Percent1, const Standard_Real Percent2, const Standard_Real Percent3)
+{
+ if (Percent1 < 0 || Percent2 < 0 || Percent3 < 0 ) Standard_DomainError::Raise();
+ Standard_Real Total = Percent1 + Percent2 + Percent3;
+ myPercent[0] = Percent1/Total;
+ myPercent[1] = Percent2/Total;
+ myPercent[2] = Percent3/Total;
+
+ InitSmoothCriterion();
+}
+//
+//=======================================================================
+//function : SetCriteriumWeight
+//purpose : define the Weight (as percent) associed to the
+// criterium Order used in the optimization : Others
+// weights are updated.
+//=======================================================================
+//
+void AppDef_Variational::SetCriteriumWeight(const Standard_Integer Order, const Standard_Real Percent)
+{
+ if ( Percent < 0 ) Standard_DomainError::Raise();
+ if ( Order < 1 || Order > 3 ) Standard_ConstructionError::Raise();
+ myPercent[Order-1] = Percent;
+ Standard_Real Total = myPercent[0] + myPercent[1] + myPercent[2];
+ myPercent[0] = myPercent[0] / Total;
+ myPercent[1] = myPercent[1] / Total;
+ myPercent[2] = myPercent[2] / Total;
+
+ InitSmoothCriterion();
+
+}
+//
+//=======================================================================
+//function : SetTolerance
+//purpose : define the tolerance used in the approximation.
+//=======================================================================
+//
+void AppDef_Variational::SetTolerance(const Standard_Real Tol)
+{
+ myTolerance=Tol;
+ InitSmoothCriterion();
+}
+//
+//=======================================================================
+//function : SetNbIterations
+//purpose : define the number of iterations used in the approximation.
+//=======================================================================
+//
+void AppDef_Variational::SetNbIterations(const Standard_Integer Iter)
+{
+ myNbIterations=Iter;
+}
+
+//====================== Private Methodes =============================//
+//=======================================================================
+//function : TheMotor
+//purpose : Smoothing's motor like STRIM routine "MOTLIS"
+//=======================================================================
+void AppDef_Variational::TheMotor(
+ Handle(AppDef_SmoothCriterion)& J,
+ // const Standard_Real WQuadratic,
+ const Standard_Real ,
+ const Standard_Real WQuality,
+ Handle(FEmTool_Curve)& TheCurve,
+ TColStd_Array1OfReal& Ecarts)
+{
+ // ...
+
+ const Standard_Real BigValue = 1.e37, SmallValue = 1.e-6, SmallestValue = 1.e-9;
+
+ // SortTools_StraightInsertionSortOfReal Sort;
+ TCollection_CompareOfReal CompReal;
+ Handle(TColStd_HArray1OfReal) CurrentTi, NewTi, OldTi;
+ Handle(TColStd_HArray2OfInteger) Dependence;
+ Standard_Boolean lestim, lconst, ToOptim, iscut;
+ Standard_Boolean isnear = Standard_False, again = Standard_True;
+ Standard_Integer NbEst, ICDANA, NumPnt, Iter;
+ Standard_Integer MaxNbEst =5;
+ Standard_Real VOCRI[3] = {BigValue, BigValue, BigValue}, EROLD = BigValue,
+ VALCRI[3], ERRMAX = BigValue, ERRMOY, ERRQUA;
+ Standard_Real CBLONG, LNOLD;
+ Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
+ Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+ Handle(FEmTool_Curve) CCurrent, COld, CNew;
+ Standard_Real EpsLength = SmallValue;
+ Standard_Real EpsDeg;
+
+ Standard_Real e1, e2, e3;
+ Standard_Real J1min, J2min, J3min;
+ Standard_Integer iprog;
+
+ // (0) Init
+
+ J->GetEstimation(e1, e2, e3);
+ J1min = 1.e-8; J2min = J3min = (e1 + 1.e-8) * 1.e-6;
+
+ if(e1 < J1min) e1 = J1min;// Like in
+ if(e2 < J2min) e2 = J2min;// MOTLIS
+ if(e3 < J3min) e3 = J3min;
+
+
+ J->SetEstimation(e1, e2, e3);
+
+ CCurrent = TheCurve;
+ CurrentTi = new TColStd_HArray1OfReal(1, myParameters->Length());
+ CurrentTi->ChangeArray1() = myParameters->Array1();
+ OldTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
+ OldTi->ChangeArray1() = CurrentTi->Array1();
+ COld = CCurrent;
+ LNOLD = CBLONG = J->EstLength();
+ Dependence = J->DependenceTable();
+
+ J->SetCurve(CCurrent);
+ FEmTool_Assembly * TheAssembly =
+ new FEmTool_Assembly (Dependence->Array2(), J->AssemblyTable());
+
+ //============ Optimization ============================
+ // Standard_Integer inagain = 0;
+ while (again) {
+
+ // (1) Loop Optimization / Estimation
+ lestim = Standard_True;
+ lconst = Standard_True;
+ NbEst = 0;
+
+ J->SetCurve(CCurrent);
+
+ while(lestim) {
+
+ // (1.1) Curve's Optimization.
+ EpsLength = SmallValue * CBLONG / NbrPnt;
+ CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
+ CCurrent->NbElements(), CCurrent->Base(), EpsLength);
+ CNew->Knots() = CCurrent->Knots();
+
+ J->SetParameters(CurrentTi);
+ EpsDeg = Min(WQuality * .1, CBLONG * .001);
+
+ Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
+
+ lconst = Standard_False;
+
+ // (1.2) calcul des criteres de qualites et amelioration
+ // des estimation.
+ ICDANA = J->QualityValues(J1min, J2min, J3min,
+ VALCRI[0], VALCRI[1], VALCRI[2]);
+
+ if(ICDANA > 0) lconst = Standard_True;
+
+ J->ErrorValues(ERRMAX, ERRQUA, ERRMOY);
+
+ isnear = ((Sqrt(ERRQUA / NbrPnt) < 2*WQuality) &&
+ (myNbIterations > 1));
+
+ // (1.3) Optimisation des ti par proj orthogonale
+ // et calcul de l'erreur aux points.
+
+ if (isnear) {
+ NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
+ Project(CNew, CurrentTi->Array1(),
+ NewTi->ChangeArray1(),
+ Ecarts, NumPnt,
+ ERRMAX, ERRQUA, ERRMOY, 2);
+ }
+ else NewTi = CurrentTi;
+
+
+ // (1.4) Progression's test
+ iprog = 0;
+ if ((EROLD > WQuality) && (ERRMAX < 0.95*EROLD)) iprog++;
+ if ((EROLD > WQuality) && (ERRMAX < 0.8*EROLD)) iprog++;
+ if ((EROLD > WQuality) && (ERRMAX < WQuality)) iprog++;
+ if ((EROLD > WQuality) && (ERRMAX < 0.99*EROLD)
+ && (ERRMAX < 1.1*WQuality)) iprog++;
+ if ( VALCRI[0] < 0.975 * VOCRI[0]) iprog++;
+ if ( VALCRI[0] < 0.9 * VOCRI[0]) iprog++;
+ if ( VALCRI[1] < 0.95 * VOCRI[1]) iprog++;
+ if ( VALCRI[1] < 0.8 * VOCRI[1]) iprog++;
+ if ( VALCRI[2] < 0.95 * VOCRI[2]) iprog++;
+ if ( VALCRI[2] < 0.8 * VOCRI[2]) iprog++;
+ if ((VOCRI[1]>SmallestValue)&&(VOCRI[2]>SmallestValue)) {
+ if ((VALCRI[1]/VOCRI[1] + 2*VALCRI[2]/VOCRI[2]) < 2.8) iprog++;
+ }
+
+ if (iprog < 2 && NbEst == 0 ) {
+ // (1.5) Invalidation of new knots.
+ VALCRI[0] = VOCRI[0];
+ VALCRI[1] = VOCRI[1];
+ VALCRI[2] = VOCRI[2];
+ ERRMAX = EROLD;
+ CBLONG = LNOLD;
+ CCurrent = COld;
+ CurrentTi = OldTi;
+
+ goto L8000; // exit
+ }
+
+ VOCRI[0] = VALCRI[0];
+ VOCRI[1] = VALCRI[1];
+ VOCRI[2] = VALCRI[2];
+ LNOLD = CBLONG;
+ EROLD = ERRMAX;
+
+ CCurrent = CNew;
+ CurrentTi = NewTi;
+
+ // (1.6) Test if the Estimations seems OK, else repeat
+ NbEst++;
+ lestim = ( (NbEst<MaxNbEst) && (ICDANA == 2)&& (iprog > 0) );
+
+ if (lestim && isnear) {
+ // (1.7) Optimization of ti by ACR.
+ // Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
+ SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
+ Standard_Integer Decima = 4;
+
+ CCurrent->Length(0., 1., CBLONG);
+ J->EstLength() = CBLONG;
+
+ ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
+ lconst = Standard_True;
+
+ }
+ }
+
+
+ // (2) loop of parametric / geometric optimization
+
+ Iter = 1;
+ ToOptim = ((Iter < myNbIterations) && (isnear));
+
+ while(ToOptim) {
+ Iter++;
+ // (2.1) Save curent results
+ VOCRI[0] = VALCRI[0];
+ VOCRI[1] = VALCRI[1];
+ VOCRI[2] = VALCRI[2];
+ EROLD = ERRMAX;
+ LNOLD = CBLONG;
+ COld = CCurrent;
+ OldTi->ChangeArray1() = CurrentTi->Array1();
+
+ // (2.2) Optimization des ti by ACR.
+ // Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
+ SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
+ Standard_Integer Decima = 4;
+
+ CCurrent->Length(0., 1., CBLONG);
+ J->EstLength() = CBLONG;
+
+ ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
+ lconst = Standard_True;
+
+ // (2.3) Optimisation des courbes
+ EpsLength = SmallValue * CBLONG / NbrPnt;
+
+ CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
+ CCurrent->NbElements(), CCurrent->Base(), EpsLength);
+ CNew->Knots() = CCurrent->Knots();
+
+ J->SetParameters(CurrentTi);
+
+ EpsDeg = Min(WQuality * .1, CBLONG * .001);
+ Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
+
+ CCurrent = CNew;
+
+ // (2.4) calcul des criteres de qualites et amelioration
+ // des estimation.
+
+ ICDANA = J->QualityValues(J1min, J2min, J3min, VALCRI[0], VALCRI[1], VALCRI[2]);
+ if(ICDANA > 0) lconst = Standard_True;
+
+ J->GetEstimation(e1, e2, e3);
+ // (2.5) Optimisation des ti par proj orthogonale
+
+ NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
+ Project(CCurrent, CurrentTi->Array1(),
+ NewTi->ChangeArray1(),
+ Ecarts, NumPnt,
+ ERRMAX, ERRQUA, ERRMOY, 2);
+
+ // (2.6) Test de non regression
+
+ Standard_Integer iregre = 0;
+ if (NbrConstraint < NbrPnt) {
+ if ( (ERRMAX > WQuality) && (ERRMAX > 1.05*EROLD)) iregre++;
+ if ( (ERRMAX > WQuality) && (ERRMAX > 2*EROLD)) iregre++;
+ if ( (EROLD > WQuality) && (ERRMAX <= 0.5*EROLD)) iregre--;
+ }
+ Standard_Real E1, E2, E3;
+ J->GetEstimation(E1, E2, E3);
+ if ( (VALCRI[0] > E1) && (VALCRI[0] > 1.1*VOCRI[0])) iregre++;
+ if ( (VALCRI[1] > E2) && (VALCRI[1] > 1.1*VOCRI[1])) iregre++;
+ if ( (VALCRI[2] > E3) && (VALCRI[2] > 1.1*VOCRI[2])) iregre++;
+
+
+ if (iregre >= 2) {
+ // if (iregre >= 1) {
+ // (2.7) on restaure l'iteration precedente
+ VALCRI[0] = VOCRI[0];
+ VALCRI[1] = VOCRI[1];
+ VALCRI[2] = VOCRI[2];
+ ERRMAX = EROLD;
+ CBLONG = LNOLD;
+ CCurrent = COld;
+ CurrentTi->ChangeArray1() = OldTi->Array1();
+ ToOptim = Standard_False;
+ }
+ else { // Iteration is Ok.
+ CCurrent = CNew;
+ CurrentTi = NewTi;
+ }
+ if (Iter >= myNbIterations) ToOptim = Standard_False;
+ }
+
+ // (3) Decoupe eventuelle
+
+ if ( (CCurrent->NbElements() < myMaxSegment) && myWithCutting ) {
+
+ // (3.1) Sauvgarde de l'etat precedent
+ VOCRI[0] = VALCRI[0];
+ VOCRI[1] = VALCRI[1];
+ VOCRI[2] = VALCRI[2];
+ EROLD = ERRMAX;
+ COld = CCurrent;
+ OldTi->ChangeArray1() = CurrentTi->Array1();
+
+ // (3.2) On arrange les ti : Trie + recadrage sur (0,1)
+ // ---> On trie, afin d'assurer l'ordre par la suite.
+ // Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
+ SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
+
+ if ((CurrentTi->Value(1)!= 0.) ||
+ (CurrentTi->Value(NbrPnt)!= 1.)) {
+ Standard_Real t, DelatT =
+ 1.0 /(CurrentTi->Value(NbrPnt)-CurrentTi->Value(1));
+ for (Standard_Integer ii=2; ii<NbrPnt; ii++) {
+ t = (CurrentTi->Value(ii)-CurrentTi->Value(1))*DelatT;
+ CurrentTi->SetValue(ii, t);
+ }
+ CurrentTi->SetValue(1, 0.);
+ CurrentTi->SetValue(NbrPnt, 1.);
+ }
+
+ // (3.3) Insert new Knots
+
+ SplitCurve(CCurrent, CurrentTi->Array1(), EpsLength, CNew, iscut);
+ if (!iscut) again = Standard_False;
+ else {
+ CCurrent = CNew;
+ // New Knots => New Assembly.
+ J->SetCurve(CNew);
+ delete TheAssembly;
+ TheAssembly = new FEmTool_Assembly (Dependence->Array2(),
+ J->AssemblyTable());
+ }
+ }
+ else { again = Standard_False;}
+ }
+
+ // ================ Great loop end ===================
+
+L8000:
+
+ // (4) Compute the best Error.
+ NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
+ Project(CCurrent, CurrentTi->Array1(),
+ NewTi->ChangeArray1(),
+ Ecarts, NumPnt,
+ ERRMAX, ERRQUA, ERRMOY, 10);
+
+ // (5) field's update
+
+ TheCurve = CCurrent;
+ J->EstLength() = CBLONG;
+ myParameters->ChangeArray1() = NewTi->Array1();
+ myCriterium[0] = ERRQUA;
+ myCriterium[1] = Sqrt(VALCRI[0]);
+ myCriterium[2] = Sqrt(VALCRI[1]);
+ myCriterium[3] = Sqrt(VALCRI[2]);
+ myMaxError = ERRMAX;
+ myMaxErrorIndex = NumPnt;
+ if(NbrPnt > NbrConstraint)
+ myAverageError = ERRMOY / (NbrPnt - NbrConstraint);
+ else
+ myAverageError = ERRMOY / NbrConstraint;
+
+ delete TheAssembly;
+}
+
+//=======================================================================
+//function : Optimization
+//purpose : (like FORTRAN subroutine MINIMI)
+//=======================================================================
+void AppDef_Variational::Optimization(Handle(AppDef_SmoothCriterion)& J,
+ FEmTool_Assembly& A,
+ const Standard_Boolean ToAssemble,
+ const Standard_Real EpsDeg,
+ Handle(FEmTool_Curve)& Curve,
+ const TColStd_Array1OfReal& Parameters) const
+{
+ Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
+ NbElm = Curve->NbElements(),
+ NbDim = Curve->Dimension();
+
+ Handle(FEmTool_HAssemblyTable) AssTable;
+
+ math_Matrix H(0, MxDeg, 0, MxDeg);
+ math_Vector G(0, MxDeg), Sol(1, A.NbGlobVar());
+
+ Standard_Integer el, dim;
+
+ A.GetAssemblyTable(AssTable);
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+
+ Standard_Real CBLONG = J->EstLength();
+
+ // Updating Assembly
+ if (ToAssemble)
+ A.NullifyMatrix();
+ A.NullifyVector();
+
+
+ for (el = 1; el <= NbElm; el++) {
+ if (ToAssemble) {
+ J->Hessian(el, 1, 1, H);
+ for(dim = 1; dim <= NbDim; dim++)
+ A.AddMatrix(el, dim, dim, H);
+ }
+
+ for(dim = 1; dim <= NbDim; dim++) {
+ J->Gradient(el, dim, G);
+ A.AddVector(el, dim, G);
+ }
+ }
+
+
+ // Solution of system
+ if (ToAssemble) {
+ if(NbConstr != 0) { //Treatment of constraints
+ AssemblingConstraints(Curve, Parameters, CBLONG, A);
+ }
+ A.Solve();
+ }
+ A.Solution(Sol);
+
+
+ // Updating J
+ J->SetCurve(Curve);
+ J->InputVector(Sol, AssTable);
+
+ // Updating Curve and reduction of degree
+
+ Standard_Integer Newdeg;
+ Standard_Real MaxError;
+
+ if(NbConstr == 0) {
+ for(el = 1; el <= NbElm; el++) {
+ Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
+ }
+ }
+ else {
+
+ TColStd_Array1OfReal& TabInt = Curve->Knots();
+ Standard_Integer Icnt = 1, p0 = Parameters.Lower() - myFirstPoint, point;
+ for(el = 1; el <= NbElm; el++) {
+ while((Icnt < NbConstr) &&
+ (Parameters(p0 + myTypConstraints->Value(2 * Icnt - 1)) <= TabInt(el))) Icnt++;
+ point = p0 + myTypConstraints->Value(2 * Icnt - 1);
+ if(Parameters(point) <= TabInt(el) || Parameters(point) >= TabInt(el + 1))
+ Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
+ else
+ if(Curve->Degree(el) < MxDeg) Curve->SetDegree(el, MxDeg);
+ }
+ }
+}
+
+void AppDef_Variational::Project(const Handle(FEmTool_Curve)& C,
+ const TColStd_Array1OfReal& Ti,
+ TColStd_Array1OfReal& ProjTi,
+ TColStd_Array1OfReal& Distance,
+ Standard_Integer& NumPoints,
+ Standard_Real& MaxErr,
+ Standard_Real& QuaErr,
+ Standard_Real& AveErr,
+ const Standard_Integer NbIterations) const
+
+{
+ // Initialisation
+
+ const Standard_Real Seuil = 1.e-9, Eps = 1.e-12;
+
+ MaxErr = QuaErr = AveErr = 0.;
+
+ Standard_Integer Ipnt, NItCv, Iter, i, i0 = -myDimension, d0 = Distance.Lower() - 1;
+
+ Standard_Real TNew, Dist, T0, Dist0, F1, F2, Aux, DF, Ecart;
+
+ Standard_Boolean EnCour;
+
+ TColStd_Array1OfReal ValOfC(1, myDimension), FirstDerOfC(1, myDimension),
+ SecndDerOfC(1, myDimension);
+
+ for(Ipnt = 1; Ipnt <= ProjTi.Length(); Ipnt++) {
+
+ i0 += myDimension;
+
+ TNew = Ti(Ipnt);
+
+ EnCour = Standard_True;
+ NItCv = 0;
+ Iter = 0;
+ C->D0(TNew, ValOfC);
+
+ Dist = 0;
+ for(i = 1; i <= myDimension; i++) {
+ Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
+ Dist += Aux * Aux;
+ }
+ Dist = Sqrt(Dist);
+
+ // ------- Newton's method for solving (C'(t),C(t) - P) = 0
+
+ while( EnCour ) {
+
+ Iter++;
+ T0 = TNew;
+ Dist0 = Dist;
+
+ C->D2(TNew, SecndDerOfC);
+ C->D1(TNew, FirstDerOfC);
+
+ F1 = F2 = 0.;
+ for(i = 1; i <= myDimension; i++) {
+ Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
+ DF = FirstDerOfC(i);
+ F1 += Aux*DF; // (C'(t),C(t) - P)
+ F2 += DF*DF + Aux * SecndDerOfC(i); // ((C'(t),C(t) - P))'
+ }
+
+ if(Abs(F2) < Eps)
+ EnCour = Standard_False;
+ else {
+ // Formula of Newton x(k+1) = x(k) - F(x(k))/F'(x(k))
+ TNew -= F1 / F2;
+ if(TNew < 0.) TNew = 0.;
+ if(TNew > 1.) TNew = 1.;
+
+
+ // Analysis of result
+
+ C->D0(TNew, ValOfC);
+
+ Dist = 0;
+ for(i = 1; i <= myDimension; i++) {
+ Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
+ Dist += Aux * Aux;
+ }
+ Dist = Sqrt(Dist);
+
+ Ecart = Dist0 - Dist;
+
+ if(Ecart <= -Seuil) {
+ // Pas d'amelioration on s'arrete
+ EnCour = Standard_False;
+ TNew = T0;
+ Dist = Dist0;
+ }
+ else if(Ecart <= Seuil)
+ // Convergence
+ NItCv++;
+ else
+ NItCv = 0;
+
+ if((NItCv >= 2) || (Iter >= NbIterations)) EnCour = Standard_False;
+
+ }
+ }
+
+
+ ProjTi(Ipnt) = TNew;
+ Distance(d0 + Ipnt) = Dist;
+ if(Dist > MaxErr) {
+ MaxErr = Dist;
+ NumPoints = Ipnt;
+ }
+ QuaErr += Dist * Dist;
+ AveErr += Dist;
+ }
+
+ NumPoints = NumPoints + myFirstPoint - 1;// Setting NumPoints to interval [myFirstPoint, myLastPoint]
+
+}
+
+void AppDef_Variational::ACR(Handle(FEmTool_Curve)& Curve,
+ TColStd_Array1OfReal& Ti,
+ const Standard_Integer Decima) const
+{
+
+ const Standard_Real Eps = 1.e-8;
+
+ TColStd_Array1OfReal& Knots = Curve->Knots();
+ Standard_Integer NbrPnt = Ti.Length(), TiFirst = Ti.Lower(), TiLast = Ti.Upper(),
+ KFirst = Knots.Lower(), KLast = Knots.Upper();
+
+ Standard_Real CbLong, DeltaT, VTest, UNew, UOld, DU, TPara, TOld, DTInv, Ratio;
+ Standard_Integer ipnt, ii, IElm, IOld, POld, PCnt, ICnt=0;
+ Standard_Integer NbCntr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+
+ // (1) Calcul de la longueur de courbe
+
+ Curve->Length(Ti(TiFirst), Ti(TiLast), CbLong);
+
+ // (2) Mise de l'acr dans Ti
+
+ if(NbrPnt >= 2) {
+
+ // (2.0) Initialisation
+ DeltaT = (Ti(TiLast) - Ti(TiFirst)) / Decima;
+ VTest = Ti(TiFirst) + DeltaT;
+
+ if(NbCntr > 0) {
+ PCnt = myTypConstraints->Value(1) - myFirstPoint + TiFirst;
+ ICnt = 1;
+ }
+ else
+ PCnt = TiLast + 1;
+
+ UOld = 0.;
+
+ TOld = Ti(TiFirst);
+ POld = TiFirst;
+
+ IElm = KFirst;
+ IOld = IElm;
+
+ Ti(TiFirst) = 0.;
+
+ for(ipnt = TiFirst + 1; ipnt <= TiLast; ipnt++) {
+
+ while((ICnt <= NbCntr) && (PCnt < ipnt)) {
+ ICnt++;
+ PCnt = myTypConstraints->Value(2*ICnt-1) - myFirstPoint + TiFirst;
+ }
+
+ TPara = Ti(ipnt);
+
+ if(TPara >= VTest || PCnt == ipnt) {
+
+ if ( Ti(TiLast) - TPara <= 1.e-2*DeltaT) {
+ ipnt = TiLast;
+ TPara = Ti(ipnt);
+ }
+ // (2.2), (2.3) Cacul la longueur de courbe
+ Curve->Length(Ti(TiFirst), TPara, UNew);
+
+ UNew /= CbLong;
+
+ while(Knots(IElm + 1) < TPara && IElm < KLast - 1) IElm++;
+
+ // (2.4) Mise a jours des parametres de decoupe
+ DTInv = 1. / (TPara - TOld);
+ DU = UNew - UOld;
+
+ for(ii = IOld+1; ii <= IElm; ii++) {
+ Ratio = (Knots(ii) - TOld) * DTInv;
+ Knots(ii) = UOld + Ratio * DU;
+ }
+
+ // (2.5) Mise a jours des parametres de points.
+
+ //Very strange loop, because it never works (POld+1 > ipnt-1)
+ for(ii = POld+1; ii <= ipnt-1; ii++) {
+ Ratio = ( Ti(ii) - TOld ) * DTInv;
+ Ti(ii) = UOld + Ratio * DU;
+ }
+
+ Ti(ipnt) = UNew;
+
+ UOld = UNew;
+ IOld = IElm;
+ TOld = TPara;
+ POld = ipnt;
+
+ }
+ // --> Nouveau seuil parametrique pour le decimage
+
+ if(TPara >= VTest) {
+ // ii = RealToInt((TPara - VTest + Eps) / DeltaT);
+ // VTest += (ii + 1) * DeltaT;
+ VTest += Ceiling((TPara - VTest + Eps) / DeltaT) * DeltaT;
+ if(VTest > 1. - Eps) VTest = 1.;
+ }
+ }
+ }
+
+ // --- On ajuste les valeurs extremes
+
+ Ti(TiFirst) = 0.;
+ Ti(TiLast) = 1.;
+ ii = TiLast - 1;
+ while ( Ti(ii) > Knots(KLast) ) {
+ Ti(ii) = 1.;
+ --ii;
+ }
+ Knots(KFirst) = 0.;
+ Knots(KLast) = 1.;
+
+}
+
+//----------------------------------------------------------//
+// Standard_Integer NearIndex //
+// Purpose: searching nearest index of TabPar corresponding //
+// given value T (is similar to fortran routine MSRRE2) //
+//----------------------------------------------------------//
+
+static Standard_Integer NearIndex(const Standard_Real T,
+ const TColStd_Array1OfReal& TabPar,
+ const Standard_Real Eps, Standard_Integer& Flag)
+{
+ Standard_Integer Loi = TabPar.Lower(), Upi = TabPar.Upper();
+
+ Flag = 0;
+
+ if(T < TabPar(Loi)) { Flag = -1; return Loi;}
+ if(T > TabPar(Upi)) { Flag = 1; return Upi;}
+
+ Standard_Integer Ibeg = Loi, Ifin = Upi, Imidl;
+
+ while(Ibeg + 1 != Ifin) {
+ Imidl = (Ibeg + Ifin) / 2;
+ if((T >= TabPar(Ibeg)) && (T <= TabPar(Imidl)))
+ Ifin = Imidl;
+ else
+ Ibeg = Imidl;
+ }
+
+ if(Abs(T - TabPar(Ifin)) < Eps) return Ifin;
+
+ return Ibeg;
+}
+
+
+//----------------------------------------------------------//
+// void GettingKnots //
+// Purpose: calculating values of new Knots for elements //
+// with degree that is equal Deg //
+//----------------------------------------------------------//
+
+static void GettingKnots(const TColStd_Array1OfReal& TabPar,
+ const Handle(FEmTool_Curve)& InCurve,
+ const Standard_Integer Deg,
+ Standard_Integer& NbElm,
+ TColStd_Array1OfReal& NewKnots)
+
+{
+
+ const Standard_Real Eps = 1.e-12;
+
+ TColStd_Array1OfReal& OldKnots = InCurve->Knots();
+ Standard_Integer NbMaxOld = InCurve->NbElements();
+ Standard_Integer NbMax = NewKnots.Upper(), Ipt, Ipt1, Ipt2;
+ Standard_Integer el = 0, i1 = OldKnots.Lower(), i0 = i1 - 1, Flag;
+ Standard_Real TPar;
+
+ while((NbElm < NbMax) && (el < NbMaxOld)) {
+
+ el++; i0++; i1++; // i0, i1 are indexes of left and right knots of element el
+
+ if(InCurve->Degree(el) == Deg) {
+
+ NbElm++;
+
+ Ipt1 = NearIndex(OldKnots(i0), TabPar, Eps, Flag);
+ if(Flag != 0) Ipt1 = TabPar.Lower();
+ Ipt2 = NearIndex(OldKnots(i1), TabPar, Eps, Flag);
+ if(Flag != 0) Ipt2 = TabPar.Upper();
+
+ if(Ipt2 - Ipt1 >= 1) {
+
+ Ipt = (Ipt1 + Ipt2) / 2;
+ if(2 * Ipt == Ipt1 + Ipt2)
+ TPar = 2. * TabPar(Ipt);
+ else
+ TPar = TabPar(Ipt) + TabPar(Ipt + 1);
+
+ NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1) + TPar) / 4.;
+ }
+ else
+ NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1)) / 2.;
+ }
+ }
+}
+
+void AppDef_Variational::SplitCurve(const Handle(FEmTool_Curve)& InCurve,
+ const TColStd_Array1OfReal& Ti,
+ const Standard_Real CurveTol,
+ Handle(FEmTool_Curve)& OutCurve,
+ Standard_Boolean& iscut) const
+{
+ Standard_Integer NbElmOld = InCurve->NbElements();
+
+ if(NbElmOld >= myMaxSegment) {iscut = Standard_False; return;}
+#ifdef DEB
+ Standard_Integer MaxDegree =
+#endif
+ InCurve->Base()->WorkDegree();
+ Standard_Integer NbElm = NbElmOld;
+ TColStd_Array1OfReal NewKnots(NbElm + 1, myMaxSegment);
+#ifndef DEB
+ GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree(), NbElm, NewKnots);
+ GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree() - 1, NbElm, NewKnots);
+#else
+ GettingKnots(Ti, InCurve, MaxDegree, NbElm, NewKnots);
+ GettingKnots(Ti, InCurve, MaxDegree - 1, NbElm, NewKnots);
+
+#endif
+ if(NbElm > NbElmOld) {
+
+ iscut = Standard_True;
+
+ OutCurve = new FEmTool_Curve(InCurve->Dimension(), NbElm, InCurve->Base(), CurveTol);
+ TColStd_Array1OfReal& OutKnots = OutCurve->Knots();
+ TColStd_Array1OfReal& InKnots = InCurve->Knots();
+
+ Standard_Integer i, i0 = OutKnots.Lower();
+ for(i = InKnots.Lower(); i <= InKnots.Upper(); i++) OutKnots(i) = InKnots(i);
+ for(i = NbElmOld + 1; i <= NbElm; i++) OutKnots(i + i0) = NewKnots(i);
+
+ // SortTools_ShellSortOfReal Sort;
+ TCollection_CompareOfReal CompReal;
+
+ // Sort.Sort(OutKnots, CompReal);
+ SortTools_ShellSortOfReal::Sort(OutKnots, CompReal);
+ }
+ else
+ iscut = Standard_False;
+
+}
+
+//=======================================================================
+//function : InitSmoothCriterion
+//purpose : Initializes the SmoothCriterion
+//=======================================================================
+void AppDef_Variational::InitSmoothCriterion()
+{
+
+ const Standard_Real Eps2 = 1.e-6, Eps3 = 1.e-9;
+ // const Standard_Real J1 = .01, J2 = .001, J3 = .001;
+
+
+
+ Standard_Real Length;
+
+ InitParameters(Length);
+
+ mySmoothCriterion->SetParameters(myParameters);
+
+ Standard_Real E1, E2, E3;
+
+ InitCriterionEstimations(Length, E1, E2, E3);
+ /*
+ J1 = 1.e-8; J2 = J3 = (E1 + 1.e-8) * 1.e-6;
+
+ if(E1 < J1) E1 = J1;
+ if(E2 < J2) E2 = J2;
+ if(E3 < J3) E3 = J3;
+ */
+ mySmoothCriterion->EstLength() = Length;
+ mySmoothCriterion->SetEstimation(E1, E2, E3);
+
+ Standard_Real WQuadratic, WQuality;
+
+ if(!myWithMinMax && myTolerance != 0.)
+ WQuality = myTolerance;
+ else if (myTolerance == 0.)
+ WQuality = 1.;
+ else
+ WQuality = Max(myTolerance, Eps2 * Length);
+
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+ WQuadratic = Sqrt((Standard_Real)(myNbPoints - NbConstr)) * WQuality;
+ if(WQuadratic > Eps3) WQuadratic = 1./ WQuadratic;
+
+ if(WQuadratic == 0.) WQuadratic = Max(Sqrt(E1), 1.);
+
+
+ mySmoothCriterion->SetWeight(WQuadratic, WQuality,
+ myPercent[0], myPercent[1], myPercent[2]);
+
+
+ Handle(PLib_Base) TheBase = new PLib_HermitJacobi(myMaxDegree, myContinuity);
+ Handle(FEmTool_Curve) TheCurve;
+ Standard_Integer NbElem;
+ Standard_Real CurvTol = Eps2 * Length / myNbPoints;
+
+ // Decoupe de l'intervalle en fonction des contraintes
+ if(myWithCutting == Standard_True && NbConstr != 0) {
+
+ InitCutting(TheBase, CurvTol, TheCurve);
+
+ }
+ else {
+
+ NbElem = 1;
+ TheCurve = new FEmTool_Curve(myDimension, NbElem, TheBase, CurvTol);
+ TheCurve->Knots().SetValue(TheCurve->Knots().Lower(),
+ myParameters->Value(myFirstPoint));
+ TheCurve->Knots().SetValue(TheCurve->Knots().Upper(),
+ myParameters->Value(myLastPoint));
+
+ }
+
+ mySmoothCriterion->SetCurve(TheCurve);
+
+ return;
+
+}
+
+//
+//=======================================================================
+//function : InitParameters
+//purpose : Calculation of initial estimation of the multicurve's length
+// and parameters for multipoints.
+//=======================================================================
+//
+void AppDef_Variational::InitParameters(Standard_Real& Length)
+{
+
+ const Standard_Real Eps1 = Precision::Confusion() * .01;
+
+ Standard_Real aux, dist;
+ Standard_Integer i, i0, i1 = 0, ipoint;
+
+
+ Length = 0.;
+ myParameters->SetValue(myFirstPoint, Length);
+
+ for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint; ipoint++) {
+ i0 = i1; i1 += myDimension;
+ dist = 0;
+ for(i = 1; i <= myDimension; i++) {
+ aux = myTabPoints->Value(i1 + i) - myTabPoints->Value(i0 + i);
+ dist += aux * aux;
+ }
+ Length += Sqrt(dist);
+ myParameters->SetValue(ipoint, Length);
+ }
+
+
+ if(Length <= Eps1)
+ Standard_ConstructionError::Raise("AppDef_Variational::InitParameters");
+
+
+ for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint - 1; ipoint++)
+ myParameters->SetValue(ipoint, myParameters->Value(ipoint) / Length);
+
+ myParameters->SetValue(myLastPoint, 1.);
+
+ // Avec peu de point il y a sans doute sous estimation ...
+ if(myNbPoints < 10) Length *= (1. + 0.1 / (myNbPoints - 1));
+}
+
+//
+//=======================================================================
+//function : InitCriterionEstimations
+//purpose : Calculation of initial estimation of the linear criteria
+//
+//=======================================================================
+//
+void AppDef_Variational::InitCriterionEstimations(const Standard_Real Length,
+ Standard_Real& E1,
+ Standard_Real& E2,
+ Standard_Real& E3) const
+{
+ E1 = Length * Length;
+
+ const Standard_Real Eps1 = Precision::Confusion() * .01;
+
+ math_Vector VTang1(1, myDimension), VTang2(1, myDimension), VTang3(1, myDimension),
+ VScnd1(1, myDimension), VScnd2(1, myDimension), VScnd3(1, myDimension);
+
+ // ========== Treatment of first point =================
+
+ Standard_Integer ipnt = myFirstPoint;
+
+ EstTangent(ipnt, VTang1);
+ ipnt++;
+ EstTangent(ipnt, VTang2);
+ ipnt++;
+ EstTangent(ipnt, VTang3);
+
+ ipnt = myFirstPoint;
+ EstSecnd(ipnt, VTang1, VTang2, Length, VScnd1);
+ ipnt++;
+ EstSecnd(ipnt, VTang1, VTang3, Length, VScnd2);
+
+ // Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 Begin
+ // Standard_Real Delta = .5 * (myParameters->Value(ipnt) - myParameters->Value(--ipnt));
+ Standard_Integer anInd = ipnt;
+ Standard_Real Delta = .5 * (myParameters->Value(anInd) - myParameters->Value(--ipnt));
+ // Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 End
+
+ if(Delta <= Eps1) Delta = 1.;
+
+ E2 = VScnd1.Norm2() * Delta;
+
+ E3 = (Delta > Eps1) ? VScnd2.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
+ // ========== Treatment of internal points =================
+
+ Standard_Integer CurrPoint = 2;
+
+ for(ipnt = myFirstPoint + 1; ipnt < myLastPoint; ipnt++) {
+
+ Delta = .5 * (myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1));
+
+ if(CurrPoint == 1) {
+ if(ipnt + 1 != myLastPoint) {
+ EstTangent(ipnt + 2, VTang3);
+ EstSecnd(ipnt + 1, VTang1, VTang3, Length, VScnd2);
+ }
+ else
+ EstSecnd(ipnt + 1, VTang1, VTang2, Length, VScnd2);
+
+ E2 += VScnd1.Norm2() * Delta;
+ E3 += (Delta > Eps1) ? VScnd2.Subtracted(VScnd3).Norm2() / (4. * Delta) : 0.;
+
+ }
+ else if(CurrPoint == 2) {
+ if(ipnt + 1 != myLastPoint) {
+ EstTangent(ipnt + 2, VTang1);
+ EstSecnd(ipnt + 1, VTang2, VTang1, Length, VScnd3);
+ }
+ else
+ EstSecnd(ipnt + 1, VTang2, VTang3, Length, VScnd3);
+
+ E2 += VScnd2.Norm2() * Delta;
+ E3 += (Delta > Eps1) ? VScnd3.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
+
+ }
+ else {
+ if(ipnt + 1 != myLastPoint) {
+ EstTangent(ipnt + 2, VTang2);
+ EstSecnd(ipnt + 1, VTang3, VTang2, Length, VScnd1);
+ }
+ else
+ EstSecnd(ipnt + 1, VTang3, VTang1, Length, VScnd1);
+
+ E2 += VScnd3.Norm2() * Delta;
+ E3 += (Delta > Eps1) ? VScnd1.Subtracted(VScnd2).Norm2() / (4. * Delta) : 0.;
+
+ }
+
+ CurrPoint++; if(CurrPoint == 4) CurrPoint = 1;
+ }
+
+ // ========== Treatment of last point =================
+
+ Delta = .5 * (myParameters->Value(myLastPoint) - myParameters->Value(myLastPoint - 1));
+ if(Delta <= Eps1) Delta = 1.;
+
+ Standard_Real aux;
+
+ if(CurrPoint == 1) {
+
+ E2 += VScnd1.Norm2() * Delta;
+ aux = VScnd1.Subtracted(VScnd3).Norm2();
+ E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
+
+ }
+ else if(CurrPoint == 2) {
+
+ E2 += VScnd2.Norm2() * Delta;
+ aux = VScnd2.Subtracted(VScnd1).Norm2();
+ E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
+
+ }
+ else {
+
+ E2 += VScnd3.Norm2() * Delta;
+ aux = VScnd3.Subtracted(VScnd2).Norm2();
+ E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
+
+ }
+
+ aux = Length * Length;
+
+ E2 *= aux; E3 *= aux;
+
+
+}
+
+//
+//=======================================================================
+//function : EstTangent
+//purpose : Calculation of estimation of the Tangent
+// (see fortran routine MMLIPRI)
+//=======================================================================
+//
+
+void AppDef_Variational::EstTangent(const Standard_Integer ipnt,
+ math_Vector& VTang) const
+
+{
+ Standard_Integer i ;
+ const Standard_Real Eps1 = Precision::Confusion() * .01;
+ const Standard_Real EpsNorm = 1.e-9;
+
+ Standard_Real Wpnt = 1.;
+
+
+ if(ipnt == myFirstPoint) {
+ // Estimation at first point
+ if(myNbPoints < 3)
+ Wpnt = 0.;
+ else {
+
+ Standard_Integer adr1 = 1, adr2 = adr1 + myDimension,
+ adr3 = adr2 + myDimension;
+
+ math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
+ math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
+ math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
+
+ // Parabolic interpolation
+ // if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
+ // first derivative for t=0 is A1 = ((d2-1)*P1 + P2 - d2*P3)/(d*(1-d))
+ // d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*d
+ Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
+ Standard_Real V2 = 0.;
+ if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
+ if(V2 > Eps1) {
+ Standard_Real d = V1 / (V1 + V2), d1;
+ d1 = 1. / (d * (1 - d)); d *= d;
+ VTang = ((d - 1.) * Pnt1 + Pnt2 - d * Pnt3) * d1;
+ }
+ else {
+ // Simple 2-point estimation
+
+ VTang = Pnt2 - Pnt1;
+ }
+ }
+ }
+ else if (ipnt == myLastPoint) {
+ // Estimation at last point
+ if(myNbPoints < 3)
+ Wpnt = 0.;
+ else {
+
+ Standard_Integer adr1 = (myLastPoint - 3) * myDimension + 1,
+ adr2 = adr1 + myDimension,
+ adr3 = adr2 + myDimension;
+
+ math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
+ math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
+ math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
+
+ // Parabolic interpolation
+ // if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
+ // first derivative for t=1 is 2*A2 + A1 = ((d2+1)*P1 - P2 - d2*P3)/(d*(1-d))
+ // d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*(d-2)
+ Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
+ Standard_Real V2 = 0.;
+ if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
+ if(V2 > Eps1) {
+ Standard_Real d = V1 / (V1 + V2), d1;
+ d1 = 1. / (d * (1 - d)); d *= d - 2;
+ VTang = ((d + 1.) * Pnt1 - Pnt2 - d * Pnt3) * d1;
+ }
+ else {
+ // Simple 2-point estimation
+
+ VTang = Pnt3 - Pnt2;
+ }
+ }
+ }
+ else {
+
+ Standard_Integer adr1 = (ipnt - myFirstPoint - 1) * myDimension + 1,
+ adr2 = adr1 + 2 * myDimension;
+
+ math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
+ math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
+
+ VTang = Pnt2 - Pnt1;
+
+ }
+
+ Standard_Real Vnorm = VTang.Norm();
+
+ if(Vnorm <= EpsNorm)
+ VTang.Init(0.);
+ else
+ VTang /= Vnorm;
+
+ // Estimation with constraints
+
+ Standard_Real Wcnt = 0.;
+ Standard_Integer IdCnt = 1;
+
+ // Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
+
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+ math_Vector VCnt(1, myDimension, 0.);
+
+ if(NbConstr > 0) {
+
+ while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
+ IdCnt <= NbConstr) IdCnt++;
+ if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
+ (myTypConstraints->Value(2 * IdCnt) >= 1)) {
+ Wcnt = 1.;
+ Standard_Integer i0 = 2 * myDimension * (IdCnt - 1), k = 0;
+ for( i = 1; i <= myNbP3d; i++) {
+ for(Standard_Integer j = 1; j <= 3; j++)
+ VCnt(++k) = myTabConstraints->Value(++i0);
+ i0 += 3;
+ }
+ for(i = 1; i <= myNbP2d; i++) {
+ for(Standard_Integer j = 1; j <= 2; j++)
+ VCnt(++k) = myTabConstraints->Value(++i0);
+ i0 += 2;
+ }
+ }
+ }
+
+ // Averaging of estimation
+
+ Standard_Real Denom = Wpnt + Wcnt;
+ if(Denom == 0.) Denom = 1.;
+ else Denom = 1. / Denom;
+
+ VTang = (Wpnt * VTang + Wcnt * VCnt) * Denom;
+
+ Vnorm = VTang.Norm();
+
+ if(Vnorm <= EpsNorm)
+ VTang.Init(0.);
+ else
+ VTang /= Vnorm;
+
+
+}
+
+//
+//=======================================================================
+//function : EstSecnd
+//purpose : Calculation of estimation of the second derivative
+// (see fortran routine MLIMSCN)
+//=======================================================================
+//
+void AppDef_Variational::EstSecnd(const Standard_Integer ipnt,
+ const math_Vector& VTang1,
+ const math_Vector& VTang2,
+ const Standard_Real Length,
+ math_Vector& VScnd) const
+{
+ Standard_Integer i ;
+
+ const Standard_Real Eps = 1.e-9;
+
+ Standard_Real Wpnt = 1.;
+
+ Standard_Real aux;
+
+ if(ipnt == myFirstPoint)
+ aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt);
+ else if(ipnt == myLastPoint)
+ aux = myParameters->Value(ipnt) - myParameters->Value(ipnt - 1);
+ else
+ aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1);
+
+ if(aux <= Eps)
+ aux = 1.;
+ else
+ aux = 1. / aux;
+
+ VScnd = (VTang2 - VTang1) * aux;
+
+ // Estimation with constraints
+
+ Standard_Real Wcnt = 0.;
+ Standard_Integer IdCnt = 1;
+
+ // Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
+
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+ math_Vector VCnt(1, myDimension, 0.);
+
+ if(NbConstr > 0) {
+
+ while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
+ IdCnt <= NbConstr) IdCnt++;
+
+ if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
+ (myTypConstraints->Value(2 * IdCnt) >= 2)) {
+ Wcnt = 1.;
+ Standard_Integer i0 = 2 * myDimension * (IdCnt - 1) + 3, k = 0;
+ for( i = 1; i <= myNbP3d; i++) {
+ for(Standard_Integer j = 1; j <= 3; j++)
+ VCnt(++k) = myTabConstraints->Value(++i0);
+ i0 += 3;
+ }
+ i0--;
+ for(i = 1; i <= myNbP2d; i++) {
+ for(Standard_Integer j = 1; j <= 2; j++)
+ VCnt(++k) = myTabConstraints->Value(++i0);
+ i0 += 2;
+ }
+ }
+ }
+
+ // Averaging of estimation
+
+ Standard_Real Denom = Wpnt + Wcnt;
+ if(Denom == 0.) Denom = 1.;
+ else Denom = 1. / Denom;
+
+ VScnd = (Wpnt * VScnd + (Wcnt * Length) * VCnt) * Denom;
+
+}
+
+
+//
+//=======================================================================
+//function : InitCutting
+//purpose : Realisation of curve's cutting a priory accordingly to
+// constraints (see fortran routine MLICUT)
+//=======================================================================
+//
+void AppDef_Variational::InitCutting(const Handle(PLib_Base)& aBase,
+ const Standard_Real CurvTol,
+ Handle(FEmTool_Curve)& aCurve) const
+{
+
+ // Definition of number of elements
+ Standard_Integer ORCMx = -1, NCont = 0, i, kk, NbElem;
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+
+ for(i = 1; i <= NbConstr; i++) {
+ kk = Abs(myTypConstraints->Value(2 * i)) + 1;
+ ORCMx = Max(ORCMx, kk);
+ NCont += kk;
+ }
+
+ if(ORCMx > myMaxDegree - myNivCont)
+ Standard_ConstructionError::Raise("AppDef_Variational::InitCutting");
+
+ Standard_Integer NLibre = Max(myMaxDegree - myNivCont - (myMaxDegree + 1) / 4,
+ myNivCont + 1);
+
+ NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
+
+ while((NbElem > myMaxSegment) && (NLibre < myMaxDegree - myNivCont)) {
+
+ NLibre++;
+ NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
+
+ }
+
+
+ if(NbElem > myMaxSegment)
+ Standard_ConstructionError::Raise("AppDef_Variational::InitCutting");
+
+
+ aCurve = new FEmTool_Curve(myDimension, NbElem, aBase, CurvTol);
+
+ Standard_Integer NCnt = (NCont - 1) / NbElem + 1;
+ Standard_Integer NPlus = NbElem - (NCnt * NbElem - NCont);
+
+ TColStd_Array1OfReal& Knot = aCurve->Knots();
+
+ Standard_Integer IDeb = 0, IFin = NbConstr + 1,
+ NDeb = 0, NFin = 0,
+ IndEl = Knot.Lower(), IUpper = Knot.Upper(),
+ NbEl = 0;
+
+
+ Knot(IndEl) = myParameters->Value(myFirstPoint);
+ Knot(IUpper) = myParameters->Value(myLastPoint);
+
+ while(NbElem - NbEl > 1) {
+
+ IndEl++; NbEl++;
+ if(NPlus == 0) NCnt--;
+
+ while(NDeb < NCnt && IDeb < IFin) {
+ IDeb++;
+ NDeb += Abs(myTypConstraints->Value(2 * IDeb)) + 1;
+ }
+
+ if(NDeb == NCnt) {
+ NDeb = 0;
+ if(NPlus == 1 &&
+ myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) > Knot(IndEl - 1))
+
+ Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
+ else
+ Knot(IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) +
+ myParameters->Value(myTypConstraints->Value(2 * IDeb + 1))) / 2;
+
+ }
+ else {
+ NDeb -= NCnt;
+ Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
+ }
+
+ NPlus--;
+ if(NPlus == 0) NCnt--;
+
+ if(NbElem - NbEl == 1) break;
+
+ NbEl++;
+
+ while(NFin < NCnt && IDeb < IFin) {
+ IFin--;
+ NFin += Abs(myTypConstraints->Value(2 * IFin)) + 1;
+ }
+
+ if(NFin == NCnt) {
+ NFin = 0;
+ Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
+ myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
+ }
+ else {
+ NFin -= NCnt;
+ if(myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) < Knot(IUpper - IndEl + 1))
+ Knot(IUpper + 1 - IndEl) = myParameters->Value(myTypConstraints->Value(2 * IFin - 1));
+ else
+ Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
+ myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
+ }
+ }
+}
+
+//=======================================================================
+//function : Adjusting
+//purpose : Smoothing's adjusting like STRIM routine "MAJLIS"
+//=======================================================================
+void AppDef_Variational::Adjusting(
+ Handle(AppDef_SmoothCriterion)& J,
+ Standard_Real& WQuadratic,
+ Standard_Real& WQuality,
+ Handle(FEmTool_Curve)& TheCurve,
+ TColStd_Array1OfReal& Ecarts)
+{
+
+ // cout << "=========== Adjusting =============" << endl;
+
+ /* Initialized data */
+
+ const Standard_Integer mxiter = 2;
+ const Standard_Real eps1 = 1e-6;
+ Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
+ Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+ Standard_Real CurvTol = eps1 * J->EstLength() / NbrPnt;
+
+
+ /* Local variables */
+ Standard_Integer iter, ipnt;
+ Standard_Real ecart, emold, erold, tpara;
+ Standard_Real vocri[4], j1cibl, vtest, vseuil;
+ Standard_Integer i, numint, flag;
+ TColStd_Array1OfReal tbpoid(myFirstPoint, myLastPoint);
+ Standard_Boolean loptim, lrejet;
+ Handle(AppDef_SmoothCriterion) JNew;
+ Handle(FEmTool_Curve) CNew;
+ Standard_Real E1, E2, E3;
+
+
+ /* (0.b) Initialisations */
+
+ loptim = Standard_True;
+ iter = 0;
+ tbpoid.Init(1.);
+
+
+ /* ============ boucle sur le moteur de lissage ============== */
+
+ vtest = WQuality * .9;
+ j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
+
+ while(loptim) {
+
+ ++iter;
+
+ /* (1) Sauvegarde de l'etat precedents */
+
+ vocri[0] = myCriterium[0];
+ vocri[1] = myCriterium[1];
+ vocri[2] = myCriterium[2];
+ vocri[3] = myCriterium[3];
+ erold = myMaxError;
+ emold = myAverageError;
+
+ /* (2) Augmentation du poids des moindre carre */
+
+ if (j1cibl > vtest) {
+ WQuadratic = j1cibl / vtest * WQuadratic;
+ }
+
+ /* (3) Augmentation du poid associe aux points a problemes */
+
+ vseuil = WQuality * .88;
+
+ for (ipnt = myFirstPoint; ipnt <= myLastPoint; ++ipnt) {
+ if (Ecarts(ipnt) > vtest) {
+ ecart = (Ecarts(ipnt) - vseuil) / WQuality;
+ tbpoid(ipnt) = (ecart * 3 + 1.) * tbpoid(ipnt);
+ }
+ }
+
+ /* (4) Decoupe force */
+
+ if (TheCurve->NbElements() < myMaxSegment && myWithCutting) {
+
+ numint = NearIndex(myParameters->Value(myMaxErrorIndex), TheCurve->Knots(), 0, flag);
+
+ tpara = (TheCurve->Knots()(numint) + TheCurve->Knots()(numint + 1) +
+ myParameters->Value(myMaxErrorIndex) * 2) / 4;
+
+ CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements() + 1,
+ TheCurve->Base(), CurvTol);
+
+ for(i = 1; i <= numint; i++) CNew->Knots()(i) = TheCurve->Knots()(i);
+ for(i = numint + 1; i <= TheCurve->Knots().Length(); i++)
+ CNew->Knots()(i + 1) = TheCurve->Knots()(i);
+
+ CNew->Knots()(numint + 1) = tpara;
+
+ } else {
+
+ CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements(), TheCurve->Base(), CurvTol);
+
+ CNew->Knots() = TheCurve->Knots();
+ }
+
+
+ JNew = new AppDef_LinearCriteria(mySSP, myFirstPoint, myLastPoint);
+
+ JNew->EstLength() = J->EstLength();
+
+ J->GetEstimation(E1, E2, E3);
+
+ JNew->SetEstimation(E1, E2, E3);
+
+ JNew->SetParameters(myParameters);
+
+ JNew->SetWeight(WQuadratic, WQuality, myPercent[0], myPercent[1], myPercent[2]);
+
+ JNew->SetWeight(tbpoid);
+
+ JNew->SetCurve(CNew);
+
+ /* (5) Relissage */
+
+ TheMotor(JNew, WQuadratic, WQuality, CNew, Ecarts);
+
+ /* (6) Tests de rejet */
+
+ j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
+ vseuil = Sqrt(vocri[1]) + (erold - myMaxError) * 4;
+
+ lrejet = ((myMaxError > WQuality) && (myMaxError > erold * 1.01)) || (Sqrt(myCriterium[1]) > vseuil * 1.05);
+
+ if (lrejet) {
+ myCriterium[0] = vocri[0];
+ myCriterium[1] = vocri[1];
+ myCriterium[2] = vocri[2];
+ myCriterium[3] = vocri[3];
+ myMaxError = erold;
+ myAverageError = emold;
+
+ loptim = Standard_False;
+ }
+ else {
+ J = JNew;
+ TheCurve = CNew;
+ J->SetCurve(TheCurve);
+ }
+
+ /* (7) Test de convergence */
+
+ if (((iter >= mxiter) && (myMaxSegment == CNew->NbElements())) || myMaxError < WQuality) {
+ loptim = Standard_False;
+ }
+ }
+}
+
+static Standard_Boolean NotParallel(gp_Vec& T, gp_Vec& V)
+{
+ V = T;
+ V.SetX(V.X() + 1.);
+ if (V.CrossMagnitude(T) > 1.e-12)
+ return Standard_True;
+ V.SetY(V.Y() + 1.);
+ if (V.CrossMagnitude(T) > 1.e-12)
+ return Standard_True;
+ V.SetZ(V.Z() + 1.);
+ if (V.CrossMagnitude(T) > 1.e-12)
+ return Standard_True;
+ return Standard_False;
+}
+
+void AppDef_Variational::AssemblingConstraints(const Handle(FEmTool_Curve)& Curve,
+ const TColStd_Array1OfReal& Parameters,
+ const Standard_Real CBLONG,
+ FEmTool_Assembly& A ) const
+{
+
+ Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
+ NbElm = Curve->NbElements(),
+ NbDim = Curve->Dimension();
+
+ TColStd_Array1OfReal G0(0, MxDeg), G1(0, MxDeg), G2(0, MxDeg);
+ math_Vector V0((Standard_Real*)&G0(0), 0, MxDeg),
+ V1((Standard_Real*)&G1(0), 0, MxDeg),
+ V2((Standard_Real*)&G2(0), 0, MxDeg);
+
+ Standard_Integer IndexOfConstraint, Ng3d, Ng2d, NBeg2d, NPass, NgPC1,
+ NTang3d, NTang2d,
+ Point, TypOfConstr,
+ p0 = Parameters.Lower() - myFirstPoint,
+ curel = 1, el, i, ipnt, ityp, j, k, pnt, curdim,
+ jt, Ntheta = 6 * myNbP3d + 2 * myNbP2d;
+ Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
+
+ // Ng3d = 3 * NbConstr + 2 * myNbTangPoints + 5 * myNbCurvPoints;
+ // Ng2d = 2 * NbConstr + 1 * myNbTangPoints + 3 * myNbCurvPoints;
+ Ng3d = 3 * NbConstr + 3 * myNbTangPoints + 5 * myNbCurvPoints;
+ Ng2d = 2 * NbConstr + 2 * myNbTangPoints + 3 * myNbCurvPoints;
+ NBeg2d = Ng3d * myNbP3d;
+ // NgPC1 = NbConstr + myNbCurvPoints;
+ NgPC1 = NbConstr + myNbTangPoints + myNbCurvPoints;
+ NPass = 0;
+ NTang3d = 3 * NgPC1;
+ NTang2d = 2 * NgPC1;
+
+ TColStd_Array1OfReal& Intervals = Curve->Knots();
+
+ Standard_Real t, R1, R2;
+
+ Handle(PLib_Base) myBase = Curve->Base();
+ Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
+ Standard_Integer Order = myHermitJacobi->NivConstr() + 1;
+
+ Standard_Real UFirst, ULast, coeff, c0, mfact, mfact1;
+
+ A.NullifyConstraint();
+
+ ipnt = -1;
+ ityp = 0;
+ for(i = 1; i <= NbConstr; i++) {
+
+ ipnt += 2; ityp += 2;
+
+ Point = myTypConstraints->Value(ipnt);
+ TypOfConstr = myTypConstraints->Value(ityp);
+
+ t = Parameters(p0 + Point);
+
+ for(el = curel; el <= NbElm; ) {
+ if( t <= Intervals(++el) ) {
+ curel = el - 1;
+ break;
+ }
+ }
+
+
+ UFirst = Intervals(curel); ULast = Intervals(curel + 1);
+ coeff = (ULast - UFirst)/2.; c0 = (ULast + UFirst)/2.;
+
+ t = (t - c0) / coeff;
+
+ if(TypOfConstr == 0) {
+ myBase->D0(t, G0);
+ for(k = 1; k < Order; k++) {
+ mfact = Pow(coeff, k);
+ G0(k) *= mfact;
+ G0(k + Order) *= mfact;
+ }
+ }
+ else if(TypOfConstr == 1) {
+ myBase->D1(t, G0, G1);
+ for(k = 1; k < Order; k++) {
+ mfact = Pow(coeff, k);
+ G0(k) *= mfact;
+ G0(k + Order) *= mfact;
+ G1(k) *= mfact;
+ G1(k + Order) *= mfact;
+ }
+ mfact = 1./coeff;
+ for(k = 0; k <= MxDeg; k++) {
+ G1(k) *= mfact;
+ }
+ }
+ else {
+ myBase->D2(t, G0, G1, G2);
+ for(k = 1; k < Order; k++) {
+ mfact = Pow(coeff, k);
+ G0(k) *= mfact;
+ G0(k + Order) *= mfact;
+ G1(k) *= mfact;
+ G1(k + Order) *= mfact;
+ G2(k) *= mfact;
+ G2(k + Order) *= mfact;
+ }
+ mfact = 1. / coeff;
+ mfact1 = mfact / coeff;
+ for(k = 0; k <= MxDeg; k++) {
+ G1(k) *= mfact;
+ G2(k) *= mfact1;
+ }
+ }
+
+ NPass++;
+
+ j = NbDim * (Point - myFirstPoint);
+ Standard_Integer n0 = NPass;
+ curdim = 0;
+ for(pnt = 1; pnt <= myNbP3d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 3; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ j +=3;
+ n0 += Ng3d;
+ }
+
+ n0 = NPass + NBeg2d;
+ for(pnt = 1; pnt <= myNbP2d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 2; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ j +=2;
+ n0 += Ng2d;
+ }
+
+ /* if(TypOfConstr == 1) {
+
+ IndexOfConstraint = NTang3d + 1;
+ jt = Ntheta * (i - 1);
+ for(pnt = 1; pnt <= myNbP3d; pnt++) {
+ for(k = 1; k <= 3; k++) {
+ A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
+ A.AddConstraint(IndexOfConstraint + 1, curel, k, myTtheta->Value(jt + 3 + k) * V1, 0.);
+ }
+ IndexOfConstraint += Ng3d;
+ jt += 6;
+ }
+
+ IndexOfConstraint = NBeg2d + NTang2d + 1;
+ for(pnt = 1; pnt <= myNbP2d; pnt++) {
+ for(k = 1; k <= 2; k++) {
+ A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
+ }
+ IndexOfConstraint += Ng2d;
+ jt += 2;
+ }
+
+ NTang3d += 2;
+ NTang2d += 1;
+ } */
+ if(TypOfConstr == 1) {
+
+ NPass++;
+ n0 = NPass;
+ j = 2 * NbDim * (i - 1);
+ curdim = 0;
+ for(pnt = 1; pnt <= myNbP3d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 3; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ n0 += Ng3d;
+ j += 6;
+ }
+
+ n0 = NPass + NBeg2d;
+ for(pnt = 1; pnt <= myNbP2d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 2; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ n0 += Ng2d;
+ j += 4;
+ }
+ }
+ if(TypOfConstr == 2) {
+
+ NPass++;
+ n0 = NPass;
+ j = 2 * NbDim * (i - 1);
+ curdim = 0;
+ for(pnt = 1; pnt <= myNbP3d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 3; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ n0 += Ng3d;
+ j += 6;
+ }
+
+ n0 = NPass + NBeg2d;
+ for(pnt = 1; pnt <= myNbP2d; pnt++) {
+ IndexOfConstraint = n0;
+ for(k = 1; k <= 2; k++) {
+ curdim++;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
+ IndexOfConstraint += NgPC1;
+ }
+ n0 += Ng2d;
+ j += 4;
+ }
+
+ j = 2 * NbDim * (i - 1) + 3;
+ jt = Ntheta * (i - 1);
+ IndexOfConstraint = NTang3d + 1;
+ curdim = 0;
+ for(pnt = 1; pnt <= myNbP3d; pnt++) {
+ R1 = 0.; R2 = 0.;
+ for(k = 1; k <= 3; k++) {
+ R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
+ R2 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + 3 + k);
+ }
+ R1 *= CBLONG * CBLONG;
+ R2 *= CBLONG * CBLONG;
+ for(k = 1; k <= 3; k++) {
+ curdim++;
+ if(k > 1) R1 = R2 = 0.;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
+ A.AddConstraint(IndexOfConstraint + 1, curel, curdim, myTfthet->Value(jt + 3 + k) * V2, R2);
+ }
+ IndexOfConstraint += Ng3d;
+ j += 6;
+ jt += 6;
+ }
+
+ j--;
+ IndexOfConstraint = NBeg2d + NTang2d + 1;
+ for(pnt = 1; pnt <= myNbP2d; pnt++) {
+ R1 = 0.;
+ for(k = 1; k <= 2; k++) {
+ R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
+ }
+ R1 *= CBLONG * CBLONG;
+ for(k = 1; k <= 2; k++) {
+ curdim++;
+ if(k > 1) R1 = 0.;
+ A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
+ }
+ IndexOfConstraint += Ng2d;
+ j += 4;
+ jt += 2;
+ }
+
+ NTang3d += 2;
+ NTang2d += 1;
+ }
+
+ }
+
+}
+
+Standard_Boolean AppDef_Variational::InitTthetaF(const Standard_Integer ndimen,
+ const AppParCurves_Constraint typcon,
+ const Standard_Integer begin,
+ const Standard_Integer jndex)
+{
+ if ((ndimen < 2)||(ndimen >3))
+ return Standard_False;
+ gp_Vec T, V;
+ gp_Vec theta1, theta2;
+ gp_Vec F;
+ Standard_Real XX, XY, YY, XZ, YZ, ZZ;
+
+ if ((typcon == AppParCurves_TangencyPoint)||(typcon == AppParCurves_CurvaturePoint))
+ {
+ T.SetX(myTabConstraints->Value(jndex));
+ T.SetY(myTabConstraints->Value(jndex + 1));
+ if (ndimen == 3)
+ T.SetZ(myTabConstraints->Value(jndex + 2));
+ else
+ T.SetZ(0.);
+ if (ndimen == 2)
+ {
+ V.SetX(0.);
+ V.SetY(0.);
+ V.SetZ(1.);
+ }
+ if (ndimen == 3)
+ if (!NotParallel(T, V))
+ return Standard_False;
+ theta1 = V ^ T;
+ theta1.Normalize();
+ myTtheta->SetValue(begin, theta1.X());
+ myTtheta->SetValue(begin + 1, theta1.Y());
+ if (ndimen == 3)
+ {
+ theta2 = T ^ theta1;
+ theta2.Normalize();
+ myTtheta->SetValue(begin + 2, theta1.Z());
+ myTtheta->SetValue(begin + 3, theta2.X());
+ myTtheta->SetValue(begin + 4, theta2.Y());
+ myTtheta->SetValue(begin + 5, theta2.Z());
+ }
+
+ // Calculation of myTfthet
+ if (typcon == AppParCurves_CurvaturePoint)
+ {
+ XX = Pow(T.X(), 2);
+ XY = T.X() * T.Y();
+ YY = Pow(T.Y(), 2);
+ if (ndimen == 2)
+ {
+ F.SetX(YY * theta1.X() - XY * theta1.Y());
+ F.SetY(XX * theta1.Y() - XY * theta1.X());
+ myTfthet->SetValue(begin, F.X());
+ myTfthet->SetValue(begin + 1, F.Y());
+ }
+ if (ndimen == 3)
+ {
+ XZ = T.X() * T.Z();
+ YZ = T.Y() * T.Z();
+ ZZ = Pow(T.Z(), 2);
+
+ F.SetX((ZZ + YY) * theta1.X() - XY * theta1.Y() - XZ * theta1.Z());
+ F.SetY((XX + ZZ) * theta1.Y() - XY * theta1.X() - YZ * theta1.Z());
+ F.SetZ((XX + YY) * theta1.Z() - XZ * theta1.X() - YZ * theta1.Y());
+ myTfthet->SetValue(begin, F.X());
+ myTfthet->SetValue(begin + 1, F.Y());
+ myTfthet->SetValue(begin + 2, F.Z());
+ F.SetX((ZZ + YY) * theta2.X() - XY * theta2.Y() - XZ * theta2.Z());
+ F.SetY((XX + ZZ) * theta2.Y() - XY * theta2.X() - YZ * theta2.Z());
+ F.SetZ((XX + YY) * theta2.Z() - XZ * theta2.X() - YZ * theta2.Y());
+ myTfthet->SetValue(begin + 3, F.X());
+ myTfthet->SetValue(begin + 4, F.Y());
+ myTfthet->SetValue(begin + 5, F.Z());
+ }
+ }
+ }
+ return Standard_True;
+}
+
-- described by the tool MLineTool.
-- The result of the approximation will be a MultiCurve.
-uses math, FEmTool, gp, TColgp, StdFail, TColStd, TCollection, Standard, MMgt, GeomAbs,
- PLib
+uses math, FEmTool, gp, TColgp, StdFail, TColStd, TCollection, Standard, MMgt, GeomAbs, PLib
is
-- sum||C(ui)-Qi||2 with a gradient method.
-- The Result is a Bspline set.
-
- deferred class SmoothCriterion;
- generic class LinearCriteria;
-
- class MyCriterion;
- ---Level: Internal
-
- generic class Variational;
- ---Purpose: computes the approximation of a Multiline by
- -- Variational optimization.
-
-
--- instantiate classes:
--
(ConstraintCouple,Array1OfConstraintCouple);
-
class Array1OfMultiPoint instantiates Array1 from TCollection
(MultiPoint);
+++ /dev/null
--- Created on: 1997-09-11
--- Created by: Philippe MANGIN
--- Copyright (c) 1997-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-generic class LinearCriteria from AppParCurves
- (MultiLine as any;
- ToolLine as any) -- as ToolLine(MultiLine)
-inherits SmoothCriterion from AppParCurves
-
- ---Purpose: defined an Linear Criteria to used in variational
- -- Smoothing of points.
-
-
-uses
- Vector from math,
- Matrix from math,
- Curve from FEmTool,
- HAssemblyTable from FEmTool,
- ElementaryCriterion from FEmTool,
- HArray2OfInteger from TColStd,
- HArray1OfReal from TColStd,
- Array1OfReal from TColStd
-
-raises
- NotImplemented,
- DomainError
-
-
-
-is
- Create(SSP: MultiLine;
- FirstPoint, LastPoint: Integer) returns LinearCriteria;
-
- SetParameters(me : mutable; Parameters : HArray1OfReal);
-
- SetCurve(me : mutable; C :Curve from FEmTool)
- is static;
-
- GetCurve(me; C : out Curve from FEmTool)
- is static;
-
- SetEstimation(me : mutable; E1, E2, E3 : Real)
- is static;
-
- EstLength(me : mutable)
- ---C++: return &
- returns Real is static;
-
- GetEstimation(me; E1, E2, E3 : out Real)
- is static;
-
- AssemblyTable(me)
- returns HAssemblyTable from FEmTool
- is static;
-
- DependenceTable(me)
- returns HArray2OfInteger from TColStd
- is static;
-
-
- QualityValues (me : mutable; J1min, J2min, J3min : Real;
- J1, J2, J3 : out Real)
- returns Integer is static;
-
- ErrorValues(me : mutable;
- MaxError, QuadraticError, AverageError : out Real)
- is static;
-
- Hessian(me : mutable ;
- Element : Integer;
- Dimension1 : Integer;
- Dimension2 : Integer;
- H : out Matrix from math)
- raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
- is static;
-
-
- Gradient(me : mutable;
- Element : Integer;
- Dimension : Integer;
- G : out Vector from math)
- is static;
-
- InputVector(me : mutable; X : Vector from math;
- AssTable : HAssemblyTable from FEmTool)
- ---Purpose: Convert the assembly Vector in an Curve;
- --
- raises DomainError;
-
- SetWeight(me: mutable;
- QuadraticWeight, QualityWeight : Real;
- percentJ1, percentJ2, percentJ3 : Real)
- is static;
-
- GetWeight(me; QuadraticWeight, QualityWeight : out Real)
- is static;
-
- SetWeight(me: mutable;
- Weight : Array1OfReal)
- is static;
-
- BuildCache(me: mutable; E : Integer) is private;
-
-fields
-mySSP : MultiLine;
-myParameters : HArray1OfReal;
-myCache : HArray1OfReal;
-myCriteria : ElementaryCriterion from FEmTool[3];
-myEstimation: Real[3];
-myQuadraticWeight, myQualityWeight : Real;
-myPercent : Real[3];
-myPntWeight : Array1OfReal;
-myCurve : Curve from FEmTool;
-myLength : Real;
-myE : Integer;
-IF, IL : Integer;
-end LinearCriteria;
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-// Created on: 1998-11-30
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <PLib_Base.hxx>
-#include <PLib_JacobiPolynomial.hxx>
-#include <PLib_HermitJacobi.hxx>
-#include <GeomAbs_Shape.hxx>
-#include <TColStd_HArray2OfReal.hxx>
-#include <FEmTool_LinearTension.hxx>
-#include <FEmTool_LinearFlexion.hxx>
-#include <FEmTool_LinearJerk.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Pnt.hxx>
-#include <math_Matrix.hxx>
-#include <math_Gauss.hxx>
-
-static Standard_Integer order(const Handle(PLib_Base)& B)
-{
- return (*( Handle(PLib_HermitJacobi)*)&B)->NivConstr();
-}
-
-
-//=======================================================================
-//function :
-//purpose :
-//=======================================================================
-AppParCurves_LinearCriteria::AppParCurves_LinearCriteria(const MultiLine& SSP,
- const Standard_Integer FirstPoint,
- const Standard_Integer LastPoint):
- mySSP(SSP),
- myPntWeight(FirstPoint, LastPoint),
- myE(0)
-{
- myPntWeight.Init(1.);
-}
-
-
-//=======================================================================
-//function :
-//purpose :
-//=======================================================================
-
-void AppParCurves_LinearCriteria::SetParameters(const Handle(TColStd_HArray1OfReal)& Parameters)
-{
- myParameters = Parameters;
- myE = 0; // Cache become invalid.
-}
-
-
-
-//=======================================================================
-//function : SetCurve
-//purpose :
-//=======================================================================
-
-void AppParCurves_LinearCriteria::SetCurve(const Handle(FEmTool_Curve)& C)
-{
-
- if(myCurve.IsNull()) {
- myCurve = C;
-
- Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
- NbDim = myCurve->Dimension(),
- Order = order(myCurve->Base());
-
- GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
- switch (Order) {
- case 0 : ConstraintOrder = GeomAbs_C0;
- break;
- case 1 : ConstraintOrder = GeomAbs_C1;
- break;
- case 2 : ConstraintOrder = GeomAbs_C2;
- }
-
- myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
- myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
- myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
-
- Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
-
- myCriteria[0]->Set(Coeff);
- myCriteria[1]->Set(Coeff);
- myCriteria[2]->Set(Coeff);
- }
- else if (myCurve != C) {
-
- Standard_Integer OldMxDeg = myCurve->Base()->WorkDegree(),
- OldNbDim = myCurve->Dimension(),
- OldOrder = order(myCurve->Base());
-
- myCurve = C;
-
- Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
- NbDim = myCurve->Dimension(),
- Order = order(myCurve->Base());
-
- if(MxDeg != OldMxDeg || Order != OldOrder) {
-
- GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
- switch (Order) {
- case 0 : ConstraintOrder = GeomAbs_C0;
- break;
- case 1 : ConstraintOrder = GeomAbs_C1;
- break;
- case 2 : ConstraintOrder = GeomAbs_C2;
- }
-
- myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
- myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
- myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
-
- Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
-
- myCriteria[0]->Set(Coeff);
- myCriteria[1]->Set(Coeff);
- myCriteria[2]->Set(Coeff);
- }
- else if(NbDim != OldNbDim) {
-
- Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
-
- myCriteria[0]->Set(Coeff);
- myCriteria[1]->Set(Coeff);
- myCriteria[2]->Set(Coeff);
- }
- }
-}
-
-
-
-//=======================================================================
-//function : GetCurve
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::GetCurve(Handle(FEmTool_Curve)& C) const
-{
- C = myCurve;
-}
-
-
-//=======================================================================
-//function : SetEstimation
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::SetEstimation(const Standard_Real E1,
- const Standard_Real E2,
- const Standard_Real E3)
-{
- myEstimation[0] = E1;
- myEstimation[1] = E2;
- myEstimation[2] = E3;
-}
-
-Standard_Real& AppParCurves_LinearCriteria::EstLength()
-{
- return myLength;
-}
-
-
-//=======================================================================
-//function : GetEstimation
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::GetEstimation(Standard_Real& E1,
- Standard_Real& E2,
- Standard_Real& E3) const
-{
- E1 = myEstimation[0];
- E2 = myEstimation[1];
- E3 = myEstimation[2];
-}
-
-
-
-//=======================================================================
-//function : AssemblyTable
-//purpose :
-//=======================================================================
-Handle(FEmTool_HAssemblyTable) AppParCurves_LinearCriteria::AssemblyTable() const
-{
- if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::AssemblyTable");
-
- Standard_Integer NbDim = myCurve->Dimension(),
- NbElm = myCurve->NbElements(),
- nc1 = order(myCurve->Base()) + 1;
- Standard_Integer MxDeg = myCurve->Base()->WorkDegree() ;
-
- Handle(FEmTool_HAssemblyTable) AssTable = new FEmTool_HAssemblyTable(1, NbDim, 1, NbElm);
-
- Handle(TColStd_HArray1OfInteger) GlobIndex, Aux;
-
- Standard_Integer i, el = 1, dim = 1, NbGlobVar = 0, gi0;
-
- // For dim = 1
- // For first element (el = 1)
- GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
-
- for(i = 0; i < nc1; i++) {
- NbGlobVar++;
- GlobIndex->SetValue(i, NbGlobVar);
- }
- gi0 = MxDeg - 2 * nc1 + 1;
- for(i = nc1; i < 2*nc1; i++) {
- NbGlobVar++;
- GlobIndex->SetValue(i, NbGlobVar + gi0);
- }
- for(i = 2*nc1; i <= MxDeg; i++) {
- NbGlobVar++;
- GlobIndex->SetValue(i, NbGlobVar - nc1);
- }
- gi0 = NbGlobVar - nc1 + 1;
- AssTable->SetValue(dim, el, GlobIndex);
-
- // For rest elements
- for(el = 2; el <= NbElm; el++) {
- GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
- for(i = 0; i < nc1; i++) GlobIndex->SetValue(i, gi0 + i);
-
- gi0 = MxDeg - 2 * nc1 + 1;
- for(i = nc1; i < 2*nc1; i++) {
- NbGlobVar++;
- GlobIndex->SetValue(i, NbGlobVar + gi0);
- }
- for(i = 2*nc1; i <= MxDeg; i++) {
- NbGlobVar++;
- GlobIndex->SetValue(i, NbGlobVar - nc1);
- }
- gi0 = NbGlobVar - nc1 + 1;
- AssTable->SetValue(dim, el, GlobIndex);
- }
-
- // For other dimensions
- gi0 = NbGlobVar;
- for(dim = 2; dim <= NbDim; dim++) {
- for(el = 1; el <= NbElm; el++) {
- Aux = AssTable->Value(1, el);
- GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
- for(i = 0; i <= MxDeg; i++) GlobIndex->SetValue(i, Aux->Value(i) + NbGlobVar);
- AssTable->SetValue(dim, el, GlobIndex);
- }
- NbGlobVar += gi0;
- }
-
- return AssTable;
-}
-
-
-
-
-//=======================================================================
-//function :
-//purpose :
-//=======================================================================
-Handle(TColStd_HArray2OfInteger) AppParCurves_LinearCriteria::DependenceTable() const
-{
- if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::DependenceTable");
-
- Standard_Integer Dim = myCurve->Dimension();
-
- Handle(TColStd_HArray2OfInteger) DepTab =
- new TColStd_HArray2OfInteger(1, Dim, 1, Dim, 0);
- Standard_Integer i;
- for(i=1; i <= Dim; i++) DepTab->SetValue(i,i,1);
-
- return DepTab;
-}
-
-
-//=======================================================================
-//function : QualityValues
-//purpose :
-//=======================================================================
-
-Standard_Integer AppParCurves_LinearCriteria::QualityValues(const Standard_Real J1min,
- const Standard_Real J2min,
- const Standard_Real J3min,
- Standard_Real& J1,
- Standard_Real& J2,
- Standard_Real& J3)
-{
- if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::QualityValues");
-
- Standard_Integer NbDim = myCurve->Dimension(),
- NbElm = myCurve->NbElements();
-
- TColStd_Array1OfReal& Knots = myCurve->Knots();
- Handle(TColStd_HArray2OfReal) Coeff;
-
- Standard_Integer el, deg = 0, curdeg, i;
- Standard_Real UFirst, ULast;
-
- J1 = J2 = J3 = 0.;
- for(el = 1; el <= NbElm; el++) {
-
- curdeg = myCurve->Degree(el);
- if(deg != curdeg) {
- deg = curdeg;
- Coeff = new TColStd_HArray2OfReal(0, deg, 1, NbDim);
- }
-
- myCurve->GetElement(el, Coeff->ChangeArray2());
-
- UFirst = Knots(el); ULast = Knots(el + 1);
-
- myCriteria[0]->Set(Coeff);
- myCriteria[0]->Set(UFirst, ULast);
- J1 = J1 + myCriteria[0]->Value();
-
- myCriteria[1]->Set(Coeff);
- myCriteria[1]->Set(UFirst, ULast);
- J2 = J2 + myCriteria[1]->Value();
-
- myCriteria[2]->Set(Coeff);
- myCriteria[2]->Set(UFirst, ULast);
- J3 = J3 + myCriteria[2]->Value();
-
- }
-
-// Calculation of ICDANA - see MOTEST.f
-// Standard_Real JEsMin[3] = {.01, .001, .001}; // from MOTLIS.f
- Standard_Real JEsMin[3]; JEsMin[0] = J1min; JEsMin[1] = J2min; JEsMin[2] = J3min;
- Standard_Real ValCri[3]; ValCri[0] = J1; ValCri[1] = J2; ValCri[2] = J3;
-
- Standard_Integer ICDANA = 0;
-
-// (2) Test l'amelioration des estimations
-// (critere sureleve => Non minimisation )
-
- for(i = 0; i <= 2; i++)
- if((ValCri[i] < 0.8 * myEstimation[i]) && (myEstimation[i] > JEsMin[i])) {
- if(ICDANA < 1) ICDANA = 1;
- if(ValCri[i] < 0.1 * myEstimation[i]) ICDANA = 2;
- myEstimation[i] = Max(1.05*ValCri[i], JEsMin[i]);
- }
-
-
-// (3) Mise a jours des Estimation
-// (critere sous-estimer => mauvais conditionement)
-
- if (ValCri[0] > myEstimation[0] * 2) {
- myEstimation[0] += ValCri[0] * .1;
- if (ICDANA == 0) {
- if (ValCri[0] > myEstimation[0] * 10) {
- ICDANA = 2;
- }
- else ICDANA = 1;
- }
- else {
- ICDANA = 2;
- }
- }
- if (ValCri[1] > myEstimation[1] * 20) {
- myEstimation[1] += ValCri[1] * .1;
- if (ICDANA == 0) {
- if (ValCri[1] > myEstimation[1] * 100) {
- ICDANA = 2;
- }
- else ICDANA = 1;
- }
- else {
- ICDANA = 2;
- }
- }
- if (ValCri[2] > myEstimation[2] * 20) {
- myEstimation[2] += ValCri[2] * .05;
- if (ICDANA == 0) {
- if (ValCri[2] > myEstimation[2] * 100) {
- ICDANA = 2;
- }
- else ICDANA = 1;
- }
- else {
- ICDANA = 2;
- }
- }
-
-
- return ICDANA;
-}
-
-
-//=======================================================================
-//function : ErrorValues
-//purpose :
-//=======================================================================
-
-void AppParCurves_LinearCriteria::ErrorValues(Standard_Real& MaxError,
- Standard_Real& QuadraticError,
- Standard_Real& AverageError)
-{
- if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
-
- Standard_Integer NbDim = myCurve->Dimension();
-
- Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
-
- if(NbDim != (2*myNbP2d + 3*myNbP3d)) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
-
- TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
- TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
- TColStd_Array1OfReal BasePoint(1,NbDim);
- gp_Pnt2d P2d;
- gp_Pnt P3d;
-
- Standard_Integer i, ipnt, c0 = 0;
- Standard_Real SqrDist, Dist;
-
- MaxError = QuadraticError = AverageError = 0.;
-
- for(i = myParameters->Lower(); i <= myParameters->Upper(); i++) {
-
- myCurve->D0(myParameters->Value(i), BasePoint);
-
-
- c0 = 0;
- ToolLine::Value(mySSP, i, TabP3d);
- for(ipnt = 1; ipnt <= myNbP3d; ipnt++) {
- P3d.SetCoord(BasePoint(c0+1), BasePoint(c0+2), BasePoint(c0+3));
- SqrDist = P3d.SquareDistance(TabP3d(ipnt)); Dist = Sqrt(SqrDist);
- MaxError = Max(MaxError, Dist);
- QuadraticError += SqrDist;
- AverageError += Dist;
- c0 += 3;
- }
-
- if(myNbP3d == 0) ToolLine::Value(mySSP, i, TabP2d);
- else ToolLine::Value(mySSP, i, TabP3d, TabP2d);
- for(ipnt = 1; ipnt <= myNbP2d; ipnt++) {
- P2d.SetCoord(BasePoint(c0+1), BasePoint(c0+2));
- SqrDist = P2d.SquareDistance(TabP2d(ipnt)); Dist = Sqrt(SqrDist);
- MaxError = Max(MaxError, Dist);
- QuadraticError += SqrDist;
- AverageError += Dist;
- c0 += 2;
- }
- }
-}
-
-
-//=======================================================================
-//function : Hessian
-//purpose :
-//=======================================================================
-
-void AppParCurves_LinearCriteria::Hessian(const Standard_Integer Element,
- const Standard_Integer Dimension1,
- const Standard_Integer Dimension2,
- math_Matrix& H)
-{
- if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
-
- if(DependenceTable()->Value(Dimension1, Dimension2) == 0)
- Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
-
- Standard_Integer //NbDim = myCurve->Dimension(),
- MxDeg = myCurve->Base()->WorkDegree(),
-// Deg = myCurve->Degree(Element),
- Order = order(myCurve->Base());
-
-
- math_Matrix AuxH(0, H.RowNumber()-1, 0, H.ColNumber()-1, 0.);
-
- TColStd_Array1OfReal& Knots = myCurve->Knots();
- Standard_Real UFirst, ULast;
-
- UFirst = Knots(Element); ULast = Knots(Element + 1);
-
- Standard_Integer icrit;
-
- // Quality criterion part of Hessian
-
- H.Init(0);
-
- for(icrit = 0; icrit <= 2; icrit++) {
- myCriteria[icrit]->Set(UFirst, ULast);
- myCriteria[icrit]->Hessian(Dimension1, Dimension2, AuxH);
- H += (myQualityWeight*myPercent[icrit]/myEstimation[icrit]) * AuxH;
- }
-
- // Least square part of Hessian
-
- AuxH.Init(0.);
-
- Standard_Real coeff = (ULast - UFirst)/2., curcoeff, poid;
- Standard_Integer ipnt, ii, degH = 2 * Order+1;
-
-
- Handle(PLib_Base) myBase = myCurve->Base();
- Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1,
- di = myPntWeight.Lower() - myParameters->Lower();
-
- //BuilCache
- if (myE != Element) BuildCache(Element);
-
- // Compute the least square Hessian
- for(ii=1, ipnt = IF; ipnt <= IL; ipnt++, ii+=(MxDeg+1)) {
- poid = myPntWeight(di + ipnt) * 2.;
- const Standard_Real * BV = &myCache->Value(ii);
-
- // Hermite*Hermite part of matrix
- for(i = 0; i <= degH; i++) {
- k1 = (i <= Order)? i : i - Order - 1;
- curcoeff = Pow(coeff, k1) * poid * BV[i];
-
- // Hermite*Hermite part of matrix
- for(j = i; j <= degH; j++) {
- k2 = (j <= Order)? j : j - Order - 1;
- AuxH(i, j) += curcoeff * Pow(coeff, k2) * BV[j];
- }
- // Hermite*Jacobi part of matrix
- for(j = degH + 1; j <= MxDeg; j++) {
- AuxH(i, j) += curcoeff * BV[j];
- }
- }
-
- // Jacoby*Jacobi part of matrix
- for(i = degH+1; i <= MxDeg; i++) {
- curcoeff = BV[i] * poid;
- for(j = i; j <= MxDeg; j++) {
- AuxH(i, j) += curcoeff * BV[j];
- }
- }
- }
-
- i1 = i0;
- for(i = 0; i <= MxDeg; i++) {
- j1 = j0 + i;
- for(j = i; j <= MxDeg; j++) {
- H(i1, j1) += myQuadraticWeight * AuxH(i, j);
- H(j1, i1) = H(i1, j1);
- j1++;
- }
- i1++;
- }
-
-}
-
-//=======================================================================
-//function : Gradient
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::Gradient(const Standard_Integer Element,
- const Standard_Integer Dimension,
- math_Vector& G)
-{
- if(myCurve.IsNull())
- Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
-
- Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
-
- if(Dimension > (2*myNbP2d + 3*myNbP3d))
- Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
-
- TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
- TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
-
- Standard_Boolean In3d;
- Standard_Integer IndPnt, IndCrd;
-
- if(Dimension <= 3*myNbP3d) {
- In3d = Standard_True;
- IndCrd = Dimension % 3;
- IndPnt = Dimension / 3;
- if(IndCrd == 0) IndCrd = 3;
- else IndPnt++;
- }
- else {
- In3d = Standard_False;
- IndCrd = (Dimension - 3*myNbP3d) % 2;
- IndPnt = (Dimension - 3*myNbP3d) / 2;
- if(IndCrd == 0) IndCrd = 2;
- else IndPnt++;
- }
-
- TColStd_Array1OfReal& Knots = myCurve->Knots();
- Standard_Real UFirst, ULast, Pnt;
- UFirst = Knots(Element); ULast = Knots(Element + 1);
- Standard_Real coeff = (ULast-UFirst)/2;
-
- Standard_Integer //Deg = myCurve->Degree(Element),
- Order = order(myCurve->Base());
-
- Handle(PLib_Base) myBase = myCurve->Base();
- Standard_Integer MxDeg = myBase->WorkDegree();
-
- Standard_Real curcoeff;
- Standard_Integer degH = 2 * Order + 1;
- Standard_Integer ipnt, k, i, ii, i0 = G.Lower(),
- di = myPntWeight.Lower() - myParameters->Lower();
-
- if (myE != Element) BuildCache(Element);
- const Standard_Real * BV = &myCache->Value(1);
- BV--;
-
- G.Init(0.);
-
- for(ii=1,ipnt = IF; ipnt <= IL; ipnt++) {
- if(In3d) {
- ToolLine::Value(mySSP, ipnt, TabP3d);
- Pnt = TabP3d(IndPnt).Coord(IndCrd);
- }
- else {
- if(myNbP3d == 0) ToolLine::Value(mySSP, ipnt, TabP2d);
- else ToolLine::Value(mySSP, ipnt, TabP3d, TabP2d);
- Pnt = TabP2d(IndPnt).Coord(IndCrd);
- }
-
- curcoeff = Pnt * myPntWeight(di + ipnt);
- for(i = 0; i <= MxDeg; i++,ii++)
- G(i0 + i) += BV[ii] * curcoeff;
- }
-
-
- G *= 2. * myQuadraticWeight;
-
- for(i = 0; i <= degH; i++) {
- k = (i <= Order)? i : i - Order - 1;
- curcoeff = Pow(coeff, k);
- G(i0 + i) *= curcoeff;
- }
-}
-
-
-//=======================================================================
-//function : InputVector
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::InputVector(const math_Vector& X,
- const Handle(FEmTool_HAssemblyTable)& AssTable)
-{
- Standard_Integer NbDim = myCurve->Dimension(),
- NbElm = myCurve->NbElements() ;
- Standard_Integer MxDeg = 0 ;
- MxDeg = myCurve->Base()->WorkDegree();
- TColStd_Array2OfReal CoeffEl(0, MxDeg, 1, NbDim);
-
-
- Handle(TColStd_HArray1OfInteger) GlobIndex;
-
- Standard_Integer el, dim, i, i0 = X.Lower() - 1;
-
- for(el = 1; el <= NbElm; el++) {
- for(dim = 1; dim <= NbDim; dim++) {
- GlobIndex = AssTable->Value(dim, el);
- for(i = 0; i <= MxDeg; i++) CoeffEl(i, dim) = X(i0 + GlobIndex->Value(i));
- }
- myCurve->SetDegree(el, MxDeg);
- myCurve->SetElement(el, CoeffEl);
- }
-}
-
-
-//=======================================================================
-//function : SetWeight
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::SetWeight(const Standard_Real QuadraticWeight,
- const Standard_Real QualityWeight,
- const Standard_Real percentJ1,
- const Standard_Real percentJ2,
- const Standard_Real percentJ3)
-{
- if (QuadraticWeight < 0. || QualityWeight < 0.)
- Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
- if (percentJ1 < 0. || percentJ2 < 0. || percentJ3 < 0.)
- Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
-
- myQuadraticWeight = QuadraticWeight; myQualityWeight = QualityWeight;
-
- Standard_Real Total = percentJ1 + percentJ2 + percentJ3;
- myPercent[0] = percentJ1 / Total;
- myPercent[1] = percentJ2 / Total;
- myPercent[2] = percentJ3 / Total;
-}
-
-
-//=======================================================================
-//function : GetWeight
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::GetWeight(Standard_Real& QuadraticWeight,
- Standard_Real& QualityWeight) const
-{
-
- QuadraticWeight = myQuadraticWeight; QualityWeight = myQualityWeight;
-
-}
-
-//=======================================================================
-//function : SetWeight
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::SetWeight(const TColStd_Array1OfReal& Weight)
-{
- myPntWeight = Weight;
-}
-
-
-//=======================================================================
-//function : BuildCache
-//purpose :
-//=======================================================================
-void AppParCurves_LinearCriteria::BuildCache(const Standard_Integer Element)
-{
- Standard_Real t;
- Standard_Real UFirst, ULast;
- Standard_Integer ipnt;
-
- UFirst = myCurve->Knots()(Element);
- ULast = myCurve->Knots()(Element + 1);
-
- IF = 0;
- for(ipnt = myParameters->Lower(); ipnt <= myParameters->Upper(); ipnt++) {
- t = myParameters->Value(ipnt);
- if((t > UFirst && t <= ULast) || (Element == 1 && t == UFirst)) {
- if (IF == 0) IF=ipnt;
- IL = ipnt;
- }
- else if (t>ULast) break;
- }
-
- if (IF != 0) {
- Handle(PLib_Base) myBase = myCurve->Base();
- Standard_Integer order = myBase->WorkDegree()+1, ii;
- myCache = new TColStd_HArray1OfReal (1, (IL-IF+1)*(order));
-
- ii =1;
- for(ipnt = IF, ii=1; ipnt <= IL; ipnt++, ii+=order) {
- Standard_Real * cache = &myCache->ChangeValue(ii);
- TColStd_Array1OfReal BasicValue(cache[0], 0, order-1);
- t = myParameters->Value(ipnt);
- Standard_Real coeff = 2./(ULast - UFirst), c0 = -(ULast + UFirst)/2., s;
- s = (t + c0) * coeff;
- myBase->D0(s, BasicValue);
- }
- }
- else { //pas de points dans l'interval.
- IF = IL;
- IL--;
- }
- myE = Element;
-}
+++ /dev/null
--- Created on: 1997-09-11
--- Created by: Philippe MANGIN
--- Copyright (c) 1997-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-deferred class SmoothCriterion from AppParCurves
-inherits TShared from MMgt
-
- ---Purpose: defined criterion to smooth points in curve
-
-
-uses
- Vector from math,
- Matrix from math,
- Curve from FEmTool,
- HAssemblyTable from FEmTool,
- HArray2OfInteger from TColStd,
- HArray1OfReal from TColStd,
- Array1OfReal from TColStd
-
-raises
- NotImplemented,
- DomainError
-
-
-
-is
- SetParameters(me : mutable; Parameters : HArray1OfReal)
- is deferred;
-
- SetCurve(me : mutable; C :Curve from FEmTool)
- is deferred;
-
- GetCurve(me; C : out Curve from FEmTool)
- is deferred;
-
- SetEstimation(me : mutable; E1, E2, E3 : Real)
- is deferred;
-
- EstLength(me : mutable)
- ---C++: return &
- returns Real is deferred;
-
- GetEstimation(me; E1, E2, E3 : out Real)
- is deferred;
-
- AssemblyTable(me)
- returns HAssemblyTable from FEmTool
- is deferred;
-
- DependenceTable(me)
- returns HArray2OfInteger from TColStd
- is deferred;
-
- QualityValues (me : mutable; J1min, J2min, J3min : Real;
- J1, J2, J3 : out Real)
- returns Integer is deferred;
-
- ErrorValues(me : mutable;
- MaxError, QuadraticError, AverageError : out Real)
- is deferred;
-
- Hessian(me : mutable ;
- Element : Integer;
- Dimension1 : Integer;
- Dimension2 : Integer;
- H : out Matrix from math)
- raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
- is deferred;
-
-
- Gradient(me : mutable;
- Element : Integer;
- Dimension : Integer;
- G : out Vector from math)
- is deferred;
-
- InputVector(me : mutable; X : Vector from math;
- AssTable : HAssemblyTable from FEmTool)
- ---Purpose: Convert the assembly Vector in an Curve;
- --
- raises DomainError is deferred;
-
- SetWeight(me: mutable;
- QuadraticWeight, QualityWeight : Real;
- percentJ1, percentJ2, percentJ3 : Real)
- is deferred;
-
- GetWeight(me; QuadraticWeight, QualityWeight : out Real)
- is deferred;
-
- SetWeight(me: mutable;
- Weight : Array1OfReal)
- is deferred;
-
-end SmoothCriterion;
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-// Created on: 1998-11-30
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <AppParCurves_SmoothCriterion.ixx>
+++ /dev/null
--- Created on: 1996-05-14
--- Created by: Philippe MANGIN / Jeannine PANCIATICI
--- Copyright (c) 1996-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
--- Igor FEOKTISTOV - correction 14/12/98
-
-
-generic class Variational from AppParCurves
- (MultiLine as any;
- ToolLine as any) -- as ToolLine(MultiLine)
-
-
- ---Purpose: This class is used to smooth N points with constraints
- -- by minimization of quadratic criterium but also
- -- variational criterium in order to obtain " fair Curve "
- --
-
-uses Matrix from math,
- Vector from math,
- HArray1OfReal from TColStd,
- Array1OfReal from TColStd,
- HArray1OfInteger from TColStd,
- Shape from GeomAbs,
- HArray1OfConstraintCouple from AppParCurves,
- MultiBSpCurve from AppParCurves,
- SmoothCriterion from AppParCurves,
- Curve from FEmTool,
- Assembly from FEmTool,
- Base from PLib,
- Constraint from AppParCurves
-
-raises OutOfRange from Standard,
- DimensionError from Standard,
- DomainError from Standard,
- ConstructionError from Standard,
- NotDone from StdFail,
- VectorWithNullMagnitude from gp
-
- class MyCriterion instantiates LinearCriteria from AppParCurves
- (MultiLine, ToolLine);
-
-
-is
- Create(SSP: MultiLine;
- FirstPoint, LastPoint: Integer;
- TheConstraints: HArray1OfConstraintCouple;
- MaxDegree: Integer = 14;
- MaxSegment: Integer = 100;
- Continuity : Shape from GeomAbs = GeomAbs_C2;
- WithMinMax : Boolean = Standard_False;
- WithCutting: Boolean = Standard_True;
- Tolerance : Real = 1.0;
- NbIterations: Integer = 2)
- ---Purpose: Constructor.
- -- Initialization of the fields.
- -- warning : Nc0 : number of PassagePoint consraints
- -- Nc2 : number of TangencyPoint constraints
- -- Nc3 : number of CurvaturePoint constraints
- -- if
- -- ((MaxDegree-Continuity)*MaxSegment -Nc0 - 2*Nc1
- -- -3*Nc2)
- -- is negative
- -- The problem is over-constrained.
- --
- -- Limitation : The MultiLine has to be composed by
- -- only one Line ( Dimension 2 or 3).
-
- returns Variational from AppParCurves;
-
-
- Approximate(me : in out)
- ---Purpose: Makes the approximation with the current fields.
- raises NotDone from StdFail
- is static;
-
-
-
--- ==================== The Selectors ===========================
-
- IsCreated(me)
- ---Purpose: returns True if the creation is done
- -- and correspond to the current fields.
- returns Boolean
- is static;
-
-
- IsDone(me)
- ---Purpose: returns True if the approximation is ok
- -- and correspond to the current fields.
- returns Boolean
- is static;
-
- IsOverConstrained(me)
- ---Purpose: returns True if the problem is overconstrained
- -- in this case, approximation cannot be done.
- returns Boolean
- is static;
-
- Value(me)
- ---Purpose: returns all the BSpline curves approximating the
- -- MultiLine SSP after minimization of the parameter.
-
- returns MultiBSpCurve from AppParCurves
- raises NotDone from StdFail
- is static;
-
-
- MaxError(me)
- ---Purpose: returns the maximum of the distances between
- -- the points of the multiline and the approximation
- -- curves.
- returns Real
- raises NotDone from StdFail
- is static;
-
- MaxErrorIndex(me)
- ---Purpose: returns the index of the MultiPoint of ErrorMax
- returns Integer
-
- raises NotDone from StdFail
- is static;
-
-
- QuadraticError(me)
- ---Purpose: returns the quadratic average of the distances between
- -- the points of the multiline and the approximation
- -- curves.
- returns Real
- raises NotDone from StdFail
- is static;
-
- Distance(me : in out ; mat : out Matrix from math)
- ---Purpose: returns the distances between the points of the
- -- multiline and the approximation curves.
- raises NotDone from StdFail
- is static;
-
- AverageError(me)
- ---Purpose: returns the average error between
- -- the MultiLine and the approximation.
-
- returns Real
- raises NotDone from StdFail
- is static;
-
- Parameters(me)
- ---Purpose: returns the parameters uses to the approximations
- ---C++: return const&
-
- returns HArray1OfReal
- raises NotDone from StdFail
- is static;
-
- Knots(me)
- ---Purpose: returns the knots uses to the approximations
- ---C++: return const&
- returns HArray1OfReal
- raises NotDone from StdFail
- is static;
-
- Criterium(me; VFirstOrder,
- VSecondOrder,
- VThirdOrder : out Real)
- ---Purpose: returns the values of the quality criterium.
- raises NotDone from StdFail
- is static;
-
- CriteriumWeight(me ;
- Percent1, Percent2, Percent3 : out Real)
- ---Purpose: returns the Weights (as percent) associed to the criterium used in
- -- the optimization.
- is static;
-
- MaxDegree(me)
- ---Purpose: returns the Maximum Degree used in the approximation
- returns Integer
- is static;
-
- MaxSegment(me)
- ---Purpose: returns the Maximum of segment used in the approximation
- returns Integer
- is static;
-
- Continuity(me)
- ---Purpose: returns the Continuity used in the approximation
- returns Shape from GeomAbs
- is static;
-
-
- WithMinMax(me)
- ---Purpose: returns if the approximation search to minimize the
- -- maximum Error or not.
- returns Boolean
- is static;
-
- WithCutting(me)
- ---Purpose: returns if the approximation can insert new Knots or not.
- returns Boolean
- is static;
-
- Tolerance(me)
- ---Purpose: returns the tolerance used in the approximation.
- returns Real
- is static;
-
- NbIterations(me)
- ---Purpose: returns the number of iterations used in the approximation.
- returns Integer
- is static;
-
- Dump(me ; o : in out OStream)
- ---Purpose: Prints on the stream o information on the current state
- -- of the object.
- -- MaxError,MaxErrorIndex,AverageError,QuadraticError,Criterium
- -- Distances,Degre,Nombre de poles, parametres, noeuds
- is static;
-
- SetConstraints(me:in out; aConstrainst:HArray1OfConstraintCouple)
- ---Purpose: Define the constraints to approximate
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- is static;
-
- SetParameters(me:in out; param : HArray1OfReal)
- ---Purpose: Defines the parameters used by the approximations.
- raises DimensionError
- is static;
-
- SetKnots(me:in out; knots : HArray1OfReal)
- ---Purpose: Defines the knots used by the approximations
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- raises DimensionError,
- DomainError
- is static;
-
- SetMaxDegree(me: in out; Degree : Integer)
- ---Purpose: Define the Maximum Degree used in the approximation
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- is static;
-
- SetMaxSegment(me: in out; NbSegment : Integer)
- ---Purpose: Define the maximum number of segments used in the approximation
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- is static;
-
- SetContinuity(me: in out; C : Shape from GeomAbs)
- ---Purpose: Define the Continuity used in the approximation
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- raises ConstructionError from Standard
- is static;
-
-
- SetWithMinMax(me: in out; MinMax : Boolean)
- ---Purpose: Define if the approximation search to minimize the
- -- maximum Error or not.
- is static;
-
- SetWithCutting(me : in out; Cutting : Boolean )
- ---Purpose: Define if the approximation can insert new Knots or not.
- -- If this value is incompatible with the others fields
- -- this method modify nothing and returns false
- returns Boolean
- is static;
-
- SetCriteriumWeight(me : in out;
- Percent1, Percent2, Percent3 : Real)
- ---Purpose: define the Weights (as percent) associed to the criterium used in
- -- the optimization.
- --
- raises DomainError -- if Percent <= 0
- is static;
-
- SetCriteriumWeight(me : in out;
- Order : Integer;
- Percent : Real)
- ---Purpose: define the Weight (as percent) associed to the
- -- criterium Order used in the optimization : Others
- -- weights are updated.
- raises DomainError, -- if Percent < 0
- OutOfRange -- if Order < 1 or Order > 3
- is static;
-
- SetTolerance(me:in out; Tol : Real)
- ---Purpose: define the tolerance used in the approximation.
- is static;
-
- SetNbIterations(me:in out; Iter : Integer)
- ---Purpose: define the number of iterations used in the approximation.
- raises DomainError -- if Iter < 1
- is static;
-
-
--- ====================== The Private methods ======================
-
- TheMotor(me : in out;
- J : in out SmoothCriterion from AppParCurves;
- WQuadratic, WQuality : Real;
- TheCurve : in out Curve from FEmTool;
- Ecarts : out Array1OfReal from TColStd) is private;
-
- Adjusting(me : in out;
- J : in out SmoothCriterion from AppParCurves;
- WQuadratic, WQuality : in out Real;
- TheCurve : in out Curve from FEmTool;
- Ecarts : out Array1OfReal from TColStd) is private;
-
- Optimization(me;
- J : in out SmoothCriterion from AppParCurves;
- A : in out Assembly from FEmTool;
- ToAssemble : in Boolean;
- EpsDeg : Real;
- Curve : out Curve from FEmTool;
- Parameters : Array1OfReal from TColStd) is private;
-
- Project(me; C : Curve from FEmTool;
- Ti : Array1OfReal from TColStd;
- ProjTi : out Array1OfReal from TColStd;
- Distance : out Array1OfReal from TColStd;
- NumPoints : out Integer;
- MaxErr, QuaErr, AveErr : out Real;
- NbIterations: Integer=2) is private;
-
- ACR(me; Curve : in out Curve from FEmTool;
- Ti : in out Array1OfReal from TColStd;
- Decima: Integer) is private;
-
- SplitCurve(me; InCurve : Curve from FEmTool;
- Ti : Array1OfReal from TColStd;
- CurveTol: Real;
- OutCurve: out Curve from FEmTool;
- iscut : out Boolean) is private;
-
- Init(me : in out)
- raises NotDone from StdFail,
- ConstructionError from Standard,
- DimensionError from Standard
- is private;
-
- InitSmoothCriterion(me : in out)
- is private;
-
- InitParameters(me : in out; Length : out Real)
- raises ConstructionError from Standard
- is private;
-
- InitCriterionEstimations(me; Length : Real; J1, J2, J3 : out Real)
- is private;
-
- EstTangent(me; ipnt : Integer; VTang : out Vector from math)
- is private;
-
- EstSecnd(me; ipnt : Integer; VTang1, VTang2 : Vector from math;
- Length : Real; VScnd : out Vector from math)
- is private;
-
- InitCutting(me; aBase : Base from PLib; CurvTol : Real;
- aCurve : out Curve from FEmTool)
- raises ConstructionError from Standard
- is private;
-
- AssemblingConstraints(me; Curve : Curve from FEmTool;
- Parameters : Array1OfReal from TColStd;
- CBLONG : Real from Standard;
- A : out Assembly from FEmTool)
- is private;
-
- InitTthetaF(me : in out; ndimen : Integer from Standard;
- typcon : Constraint from AppParCurves;
- begin : Integer from Standard;
- jndex : Integer from Standard)
- returns Boolean
- is private;
-
-
-fields
- -- Description of the points to smooth and the constraints
-mySSP : MultiLine;
-myNbP3d : Integer;
-myNbP2d : Integer;
-myDimension : Integer;
-myFirstPoint : Integer;
-myLastPoint : Integer;
-myNbPoints : Integer;
-myTabPoints : HArray1OfReal;
-myConstraints : HArray1OfConstraintCouple;
-myNbConstraints : Integer;
-myTabConstraints : HArray1OfReal;
-myNbPassPoints : Integer;
-myNbTangPoints : Integer;
-myNbCurvPoints : Integer;
-myTypConstraints : HArray1OfInteger;
-myTtheta : HArray1OfReal;
-myTfthet : HArray1OfReal;
-
- -- Context parameters
-myMaxDegree : Integer;
-myMaxSegment : Integer;
-myNbIterations: Integer;
-myTolerance : Real;
-
- -- Options
-myContinuity : Shape from GeomAbs;
-myNivCont : Integer;
-myWithMinMax : Boolean;
-myWithCutting: Boolean;
-myPercent : Real[3];
-myCriterium : Real[4];
-mySmoothCriterion : SmoothCriterion from AppParCurves;
-
- -- output
-myParameters : HArray1OfReal;
-myKnots : HArray1OfReal;
-myMBSpCurve : MultiBSpCurve;
-
-myMaxError : Real;
-myMaxErrorIndex: Integer;
-myAverageError : Real;
-myIsCreated : Boolean;
-myIsDone : Boolean;
-myIsOverConstr : Boolean;
-
-end Variational;
+++ /dev/null
-// Copyright (c) 1996-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// Jeannine PANCIATICI le 06/06/96
-// Igor FEOKTISTOV 14/12/98 - correction of Approximate() and Init().
-// Approximation d une MultiLine de points decrite par le tool MLineTool.
-// avec criteres variationnels
-
-
-#define No_Standard_RangeError
-#define No_Standard_OutOfRange
-#define No_Standard_DimensionError
-#define No_Standard_ConstructionError
-
-#include <Standard_Stream.hxx>
-
-#include <AppParCurves.hxx>
-#include <AppParCurves_Constraint.hxx>
-#include <AppParCurves_HArray1OfConstraintCouple.hxx>
-#include <AppParCurves_Array1OfMultiPoint.hxx>
-#include <AppParCurves_MultiPoint.hxx>
-#include <AppParCurves_MultiBSpCurve.hxx>
-#include <Convert_CompPolynomialToPoles.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColgp_Array1OfVec.hxx>
-#include <TColgp_Array1OfVec2d.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_HArray1OfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColStd_HArray2OfReal.hxx>
-#include <StdFail_NotDone.hxx>
-#include <Standard_SStream.hxx>
-#include <Standard_NoSuchObject.hxx>
-#include <Precision.hxx>
-//#include <Smoothing.h>
-
-#if defined(WNT)
-# include <stdio.h>
-# include <stdarg.h>
-#endif /* WNT */
-
-
-//
-//=======================================================================
-//function : AppParCurves_Variational
-//purpose : Initialization of the fields.
-//=======================================================================
-//
- AppParCurves_Variational::AppParCurves_Variational(const MultiLine& SSP,
- const Standard_Integer FirstPoint,
- const Standard_Integer LastPoint,
- const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
- const Standard_Integer MaxDegree,
- const Standard_Integer MaxSegment,
- const GeomAbs_Shape Continuity,
- const Standard_Boolean WithMinMax,
- const Standard_Boolean WithCutting,
- const Standard_Real Tolerance,
- const Standard_Integer NbIterations):
- mySSP(SSP),
- myFirstPoint(FirstPoint),
- myLastPoint(LastPoint),
- myConstraints(TheConstraints),
- myMaxDegree(MaxDegree),
- myMaxSegment(MaxSegment),
- myNbIterations(NbIterations),
- myTolerance(Tolerance),
- myContinuity(Continuity),
- myWithMinMax(WithMinMax),
- myWithCutting(WithCutting)
-
-
-{
-// Verifications:
- if (myMaxDegree < 1) Standard_DomainError::Raise();
- myMaxDegree = Min (30, myMaxDegree);
-//
- if (myMaxSegment < 1) Standard_DomainError::Raise();
-//
- if (myWithMinMax != 0 && myWithMinMax !=1 ) Standard_DomainError::Raise();
- if (myWithCutting != 0 && myWithCutting !=1 ) Standard_DomainError::Raise();
-//
- myIsOverConstr = Standard_False;
- myIsCreated = Standard_False;
- myIsDone = Standard_False;
- switch (myContinuity) {
- case GeomAbs_C0:
- myNivCont=0;
- break ;
- case GeomAbs_C1:
- myNivCont=1;
- break ;
- case GeomAbs_C2:
- myNivCont=2;
- break ;
- default:
- Standard_ConstructionError::Raise();
- }
-//
- myNbP2d = ToolLine::NbP2d(SSP);
- myNbP3d = ToolLine::NbP3d(SSP);
- myDimension = 2 * myNbP2d + 3* myNbP3d ;
-//
- myPercent[0]=0.4;
- myPercent[1]=0.2;
- myPercent[2]=0.4;
- myKnots= new TColStd_HArray1OfReal(1,2);
- myKnots->SetValue(1,0.);
- myKnots->SetValue(2,1.);
-
-// Declaration
-//
- mySmoothCriterion = new AppParCurves_MyCriterion(mySSP, myFirstPoint, myLastPoint);
- myParameters = new TColStd_HArray1OfReal(myFirstPoint, myLastPoint);
- myNbPoints=myLastPoint-myFirstPoint+1;
- if (myNbPoints <= 0) Standard_ConstructionError::Raise();
-//
- myTabPoints= new TColStd_HArray1OfReal(1,myDimension*myNbPoints);
-//
-// Table of Points initialization
-//
- Standard_Integer ipoint,jp2d,jp3d,index;
- TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
- TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
- gp_Pnt2d P2d;
- gp_Pnt P3d;
- index=1;
-
- for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
- {
-
- if(myNbP2d !=0 && myNbP3d ==0 ) {
- ToolLine::Value(mySSP,ipoint,TabP2d);
-
- for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
- { P2d = TabP2d.Value(jp2d);
-
- myTabPoints->SetValue(index++,P2d.X());
- myTabPoints->SetValue(index++,P2d.Y());
- }
- }
- if(myNbP3d !=0 && myNbP2d == 0 ) {
- ToolLine::Value(mySSP,ipoint,TabP3d);
-
- for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
-
- { P3d=TabP3d.Value(jp3d);
-
- myTabPoints->SetValue(index++,P3d.X());
- myTabPoints->SetValue(index++,P3d.Y());
- myTabPoints->SetValue(index++,P3d.Z());
-
- }
- }
- if(myNbP3d !=0 && myNbP2d != 0 ) {
- ToolLine::Value(mySSP,ipoint,TabP3d,TabP2d);
-
- for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
-
- { P3d=TabP3d.Value(jp3d);
-
- myTabPoints->SetValue(index++,P3d.X());
- myTabPoints->SetValue(index++,P3d.Y());
- myTabPoints->SetValue(index++,P3d.Z());
-
- }
- for ( jp2d = 1 ; jp2d <= myNbP2d ; jp2d++)
-
- { P2d=TabP2d.Value(jp2d);
-
- myTabPoints->SetValue(index++,P2d.X());
- myTabPoints->SetValue(index++,P2d.Y());
- }
- }
- }
- Init();
-}
-//
-//=======================================================================
-//function : Init
-//purpose : Initializes the tables of constraints
-// and verifies if the problem is not over-constrained.
-// This method is used in the Create and the method SetConstraint.
-//=======================================================================
-//
-void AppParCurves_Variational::Init()
-{
-
- Standard_Integer ipoint,jp2d,jp3d,index,jndex;
- Standard_Integer CurMultyPoint;
- TColgp_Array1OfVec TabV3d(1, Max(1,myNbP3d));
- TColgp_Array1OfVec2d TabV2d(1, Max(1,myNbP2d));
- TColgp_Array1OfVec TabV3dcurv(1, Max(1,myNbP3d));
- TColgp_Array1OfVec2d TabV2dcurv(1, Max(1,myNbP2d));
-
- gp_Vec Vt3d, Vc3d;
- gp_Vec2d Vt2d, Vc2d;
-
- myNbConstraints=myConstraints->Length();
- if (myNbConstraints < 0) Standard_ConstructionError::Raise();
-
- myTypConstraints = new TColStd_HArray1OfInteger(1,Max(1,2*myNbConstraints));
- myTabConstraints = new TColStd_HArray1OfReal(1,Max(1,2*myDimension*myNbConstraints));
- myTtheta = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
- myTfthet = new TColStd_HArray1OfReal(1,Max(1,(2 * myNbP2d + 6 * myNbP3d) * myNbConstraints));
-
-
-//
-// Table of types initialization
- Standard_Integer iconstr;
- index=1;
- jndex=1;
- CurMultyPoint = 1;
- myNbPassPoints=0;
- myNbTangPoints=0;
- myNbCurvPoints=0;
- AppParCurves_Constraint valcontr;
-
- for ( iconstr = myConstraints->Lower() ; iconstr <= myConstraints->Upper() ; iconstr++)
- {
- ipoint=(myConstraints->Value(iconstr)).Index();
-
- valcontr=(myConstraints->Value(iconstr)).Constraint();
- switch (valcontr) {
- case AppParCurves_NoConstraint:
- CurMultyPoint -= myNbP3d * 6 + myNbP2d * 2;
- break ;
- case AppParCurves_PassPoint:
- myTypConstraints->SetValue(index++,ipoint);
- myTypConstraints->SetValue(index++,0);
- myNbPassPoints++;
- if(myNbP2d !=0 ) jndex=jndex+4*myNbP2d;
- if(myNbP3d !=0 ) jndex=jndex+6*myNbP3d;
- break ;
- case AppParCurves_TangencyPoint:
- myTypConstraints->SetValue(index++,ipoint);
- myTypConstraints->SetValue(index++,1);
- myNbTangPoints++;
- if(myNbP2d !=0 && myNbP3d == 0 )
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV2d) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- Vt2d=TabV2d.Value(jp2d);
- Vt2d.Normalize();
- myTabConstraints->SetValue(jndex++,Vt2d.X());
- myTabConstraints->SetValue(jndex++,Vt2d.Y());
- jndex=jndex+2;
- InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
- }
- }
- if(myNbP3d !=0 && myNbP2d == 0)
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV3d) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp3d=1;jp3d<=myNbP3d;jp3d++)
- {
- Vt3d=TabV3d.Value(jp3d);
- Vt3d.Normalize();
- myTabConstraints->SetValue(jndex++,Vt3d.X());
-
- myTabConstraints->SetValue(jndex++,Vt3d.Y());
-
- myTabConstraints->SetValue(jndex++,Vt3d.Z());
- jndex=jndex+3;
- InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
- }
- }
- if(myNbP3d !=0 && myNbP2d != 0)
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp3d=1;jp3d<=myNbP3d;jp3d++)
- {
- Vt3d=TabV3d.Value(jp3d);
- Vt3d.Normalize();
- myTabConstraints->SetValue(jndex++,Vt3d.X());
- myTabConstraints->SetValue(jndex++,Vt3d.Y());
- myTabConstraints->SetValue(jndex++,Vt3d.Z());
- jndex=jndex+3;
- InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
- }
-
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- Vt2d=TabV2d.Value(jp2d);
- Vt2d.Normalize();
- myTabConstraints->SetValue(jndex++,Vt2d.X());
- myTabConstraints->SetValue(jndex++,Vt2d.Y());
- jndex=jndex+2;
- InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
- }
- }
-
-
- break ;
-
- case AppParCurves_CurvaturePoint:
- myTypConstraints->SetValue(index++,ipoint);
- myTypConstraints->SetValue(index++,2);
- myNbCurvPoints++;
- if(myNbP2d !=0 && myNbP3d == 0)
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV2d) == Standard_False )
- Standard_ConstructionError::Raise();
- if (ToolLine::Curvature(mySSP,ipoint,TabV2dcurv) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- Vt2d=TabV2d.Value(jp2d);
- Vt2d.Normalize();
- Vc2d=TabV2dcurv.Value(jp2d);
- if (Abs(Abs(Vc2d.Angle(Vt2d)) - M_PI/2.) > Precision::Angular())
- Standard_ConstructionError::Raise();
- myTabConstraints->SetValue(jndex++,Vt2d.X());
- myTabConstraints->SetValue(jndex++,Vt2d.Y());
- myTabConstraints->SetValue(jndex++,Vc2d.X());
- myTabConstraints->SetValue(jndex++,Vc2d.Y());
- InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2, jndex - 4);
- }
- }
-
- if(myNbP3d !=0 && myNbP2d == 0 )
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV3d) == Standard_False )
- Standard_ConstructionError::Raise();
- if (ToolLine::Curvature(mySSP,ipoint,TabV3dcurv) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp3d=1;jp3d<=myNbP3d;jp3d++)
- {
- Vt3d=TabV3d.Value(jp3d);
- Vt3d.Normalize();
- Vc3d=TabV3dcurv.Value(jp3d);
- if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
- Standard_ConstructionError::Raise();
- myTabConstraints->SetValue(jndex++,Vt3d.X());
- myTabConstraints->SetValue(jndex++,Vt3d.Y());
- myTabConstraints->SetValue(jndex++,Vt3d.Z());
- myTabConstraints->SetValue(jndex++,Vc3d.X());
- myTabConstraints->SetValue(jndex++,Vc3d.Y());
- myTabConstraints->SetValue(jndex++,Vc3d.Z());
- InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
- }
- }
- if(myNbP3d !=0 && myNbP2d != 0 )
- {
- if (ToolLine::Tangency(mySSP,ipoint,TabV3d,TabV2d) == Standard_False )
- Standard_ConstructionError::Raise();
- if (ToolLine::Curvature(mySSP,ipoint,TabV3dcurv,TabV2dcurv) == Standard_False)
- Standard_ConstructionError::Raise();
- for (jp3d=1;jp3d<=myNbP3d;jp3d++)
- {
- Vt3d=TabV3d.Value(jp3d);
- Vt3d.Normalize();
- Vc3d=TabV3dcurv.Value(jp3d);
- if ( (Vc3d.Normalized()).IsNormal(Vt3d,Precision::Angular()) == Standard_False)
- Standard_ConstructionError::Raise();
- myTabConstraints->SetValue(jndex++,Vt3d.X());
- myTabConstraints->SetValue(jndex++,Vt3d.Y());
- myTabConstraints->SetValue(jndex++,Vt3d.Z());
- myTabConstraints->SetValue(jndex++,Vc3d.X());
- myTabConstraints->SetValue(jndex++,Vc3d.Y());
- myTabConstraints->SetValue(jndex++,Vc3d.Z());
- InitTthetaF(3, valcontr, CurMultyPoint + (jp3d - 1) * 6, jndex - 6);
- }
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- Vt2d=TabV2d.Value(jp2d);
- Vt2d.Normalize();
- Vc2d=TabV2dcurv.Value(jp2d);
- if (Abs(Abs(Vc2d.Angle(Vt2d)) - M_PI/2.) > Precision::Angular())
- Standard_ConstructionError::Raise();
- myTabConstraints->SetValue(jndex++,Vt2d.X());
- myTabConstraints->SetValue(jndex++,Vt2d.Y());
- myTabConstraints->SetValue(jndex++,Vc2d.X());
- myTabConstraints->SetValue(jndex++,Vc2d.Y());
- InitTthetaF(2, valcontr, CurMultyPoint + (jp2d - 1) * 2 + myNbP3d * 6, jndex - 4);
- }
-
- }
- break ;
- default:
- Standard_ConstructionError::Raise();
- }
- CurMultyPoint += myNbP3d * 6 + myNbP2d * 2;
- }
-// OverConstraint Detection
- Standard_Integer MaxSeg;
- if(myWithCutting == Standard_True) MaxSeg = myMaxSegment ;
- else MaxSeg = 1;
- if (((myMaxDegree-myNivCont)*MaxSeg-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- {
- myIsOverConstr =Standard_True;
- myIsCreated = Standard_False;
- }
- else {
- InitSmoothCriterion();
- myIsCreated = Standard_True;
- }
-
-
-}
-//
-//=======================================================================
-//function : Approximate
-//purpose : Makes the approximation with the current fields.
-//=======================================================================
-//
-void AppParCurves_Variational::Approximate()
-
-{
- if (myIsCreated == Standard_False ) StdFail_NotDone:: Raise();
-
-
- Standard_Real WQuadratic, WQuality;
-
- TColStd_Array1OfReal Ecarts(myFirstPoint, myLastPoint);
-
- mySmoothCriterion->GetWeight(WQuadratic, WQuality);
-
- Handle(FEmTool_Curve) TheCurve;
-
- mySmoothCriterion->GetCurve(TheCurve);
-
-//---------------------------------------------------------------------
-
- TheMotor(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
-
-
- if(myWithMinMax && myTolerance < myMaxError)
- Adjusting(mySmoothCriterion, WQuadratic, WQuality, TheCurve, Ecarts);
-
-//---------------------------------------------------------------------
-
- Standard_Integer jp2d,jp3d,index,ipole,
- NbElem = TheCurve->NbElements();
-
- TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
- TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
- Standard_Real debfin[2] = {-1., 1};
-
- gp_Pnt2d P2d;
- gp_Pnt P3d;
-
- index=0;
-
- {
- Handle(TColStd_HArray2OfReal) PolynomialIntervalsPtr =
- new TColStd_HArray2OfReal(1,NbElem,1,2) ;
-
- Handle(TColStd_HArray1OfInteger) NbCoeffPtr =
- new TColStd_HArray1OfInteger(1, myMaxSegment);
-
- Standard_Integer size = myMaxSegment * (myMaxDegree + 1) * myDimension ;
- Handle(TColStd_HArray1OfReal) CoeffPtr = new TColStd_HArray1OfReal(1,size);
-
- CoeffPtr->Init(0.);
-
- Handle(TColStd_HArray1OfReal) IntervallesPtr =
- new TColStd_HArray1OfReal(1, NbElem + 1);
-
- IntervallesPtr->ChangeArray1() = TheCurve->Knots();
-
- TheCurve->GetPolynom(CoeffPtr->ChangeArray1());
-
- Standard_Integer ii;
-
- for(ii = 1; ii <= NbElem; ii++)
- NbCoeffPtr->SetValue(ii, TheCurve->Degree(ii)+1);
-
-
- for (ii = PolynomialIntervalsPtr->LowerRow() ;
- ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
- {
- PolynomialIntervalsPtr->SetValue(ii,1,debfin[0]) ;
- PolynomialIntervalsPtr->SetValue(ii,2,debfin[1]) ;
- }
-/*
- printf("\n =========== Parameters for converting\n");
- printf("nb_courbes : %d \n", NbElem);
- printf("tab_option[4] : %d \n", myNivCont);
- printf("myDimension : %d \n", myDimension);
- printf("myMaxDegree : %d \n", myMaxDegree);
- printf("\n NbcoeffPtr :\n");
- for(ii = 1; ii <= NbElem; ii++) printf("NbCoeffPtr(%d) = %d \n", ii, NbCoeffPtr->Value(ii));
- size = NbElem*(myMaxDegree + 1) * myDimension;
- printf("\n CoeffPtr :\n");
- for(ii = 1; ii <= size; ii++) printf("CoeffPtr(%d) = %.8e \n", ii, CoeffPtr->Value(ii));
- printf("\n PolinimialIntervalsPtr :\n");
- for (ii = PolynomialIntervalsPtr->LowerRow() ;
- ii <= PolynomialIntervalsPtr->UpperRow() ;ii++)
- {
- printf(" %d : [%f, %f] \n", ii, PolynomialIntervalsPtr->Value(ii,1),
- PolynomialIntervalsPtr->Value(ii,2)) ;
- }
- printf("\n IntervallesPtr :\n");
- for (ii = IntervallesPtr->Lower();
- ii <= IntervallesPtr->Upper() - 1; ii++)
- {
- printf(" %d : [%f, %f] \n", ii, IntervallesPtr->Value(ii),
- IntervallesPtr->Value(ii+1)) ;
- }
-*/
- Convert_CompPolynomialToPoles AConverter(NbElem,
- myNivCont,
- myDimension,
- myMaxDegree,
- NbCoeffPtr,
- CoeffPtr,
- PolynomialIntervalsPtr,
- IntervallesPtr) ;
- if (AConverter.IsDone())
- {
- Handle(TColStd_HArray2OfReal) PolesPtr ;
- Handle(TColStd_HArray1OfInteger) Mults;
- Standard_Integer NbPoles=AConverter.NbPoles();
-// Standard_Integer Deg=AConverter.Degree();
- AppParCurves_Array1OfMultiPoint TabMU(1,NbPoles);
- AConverter.Poles(PolesPtr) ;
- AConverter.Knots(myKnots) ;
- AConverter.Multiplicities(Mults) ;
-
- for (ipole=PolesPtr->LowerRow();ipole<=PolesPtr->UpperRow();ipole++)
- {
- index=PolesPtr->LowerCol();
-/* if(myNbP2d !=0 )
- {
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- P2d.SetX(PolesPtr->Value(ipole,index++));
- P2d.SetY(PolesPtr->Value(ipole,index++));
- TabP2d.SetValue(jp2d,P2d);
- }
- }*/
- if(myNbP3d !=0 )
- {
- for (jp3d=1;jp3d<=myNbP3d;jp3d++)
- {
- // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
- P3d.SetX(PolesPtr->Value(ipole,index++));
- // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
- P3d.SetY(PolesPtr->Value(ipole,index++));
- // cout << "\n Poles(ipole,1)" << PolesPtr->Value(ipole,index);
- P3d.SetZ(PolesPtr->Value(ipole,index++));
- TabP3d.SetValue(jp3d,P3d);
- }
- }
- if(myNbP2d !=0 )
- {
- for (jp2d=1;jp2d<=myNbP2d;jp2d++)
- {
- P2d.SetX(PolesPtr->Value(ipole,index++));
- P2d.SetY(PolesPtr->Value(ipole,index++));
- TabP2d.SetValue(jp2d,P2d);
- }
- }
- if(myNbP2d !=0 && myNbP3d !=0)
- {
- AppParCurves_MultiPoint aMultiPoint(TabP3d,TabP2d);
- TabMU.SetValue(ipole,aMultiPoint);
- }
- else if (myNbP2d !=0)
- {
- AppParCurves_MultiPoint aMultiPoint(TabP2d);
- TabMU.SetValue(ipole,aMultiPoint);
- }
- else
- {
-
- AppParCurves_MultiPoint aMultiPoint(TabP3d);
- TabMU.SetValue(ipole,aMultiPoint);
- }
-
- }
- AppParCurves_MultiBSpCurve aCurve(TabMU,myKnots->Array1(),Mults->Array1());
- myMBSpCurve=aCurve;
- myIsDone = Standard_True;
- }
- }
-
-}
-//
-//=======================================================================
-//function : IsCreated
-//purpose : returns True if the creation is done
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::IsCreated() const
-{
- return myIsCreated;
-}
-//
-//=======================================================================
-//function : IsDone
-//purpose : returns True if the approximation is ok
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::IsDone() const
-{
- return myIsDone;
-}
-//
-//=======================================================================
-//function : IsOverConstrained
-//purpose : returns True if the problem is overconstrained
-// in this case, approximation cannot be done.
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::IsOverConstrained() const
-{
- return myIsOverConstr;
-}
-//
-//=======================================================================
-//function : Value
-//purpose : returns all the BSpline curves approximating the
-// MultiLine SSP after minimization of the parameter.
-
-//=======================================================================
-//
-AppParCurves_MultiBSpCurve AppParCurves_Variational::Value() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myMBSpCurve;
-
-}
-//
-//=======================================================================
-//function : MaxError
-//purpose : returns the maximum of the distances between
-// the points of the multiline and the approximation
-// curves.
-//=======================================================================
-//
-Standard_Real AppParCurves_Variational::MaxError() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myMaxError;
-}
-//
-//=======================================================================
-//function : MaxErrorIndex
-//purpose : returns the index of the MultiPoint of ErrorMax
-//=======================================================================
-//
-Standard_Integer AppParCurves_Variational::MaxErrorIndex() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myMaxErrorIndex;
-}
-//
-//=======================================================================
-//function : QuadraticError
-//purpose : returns the quadratic average of the distances between
-// the points of the multiline and the approximation
-// curves.
-//=======================================================================
-//
-Standard_Real AppParCurves_Variational::QuadraticError() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myCriterium[0];
-}
-//
-//=======================================================================
-//function : Distance
-//purpose : returns the distances between the points of the
-// multiline and the approximation curves.
-//=======================================================================
-//
-void AppParCurves_Variational::Distance(math_Matrix& mat)
-
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- Standard_Integer ipoint,jp2d,jp3d,index;
- TColgp_Array1OfPnt TabP3d(1,Max(1,myNbP3d));
- TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
- Standard_Integer j0 = mat.LowerCol() - myFirstPoint;
-
- gp_Pnt2d P2d;
- gp_Pnt P3d;
-
-
- gp_Pnt Pt3d;
- gp_Pnt2d Pt2d;
-
- for ( ipoint = myFirstPoint ; ipoint <= myLastPoint ; ipoint++)
- {
- index=1;
- if(myNbP3d !=0 ) {
- ToolLine::Value(mySSP,ipoint,TabP3d);
-
- for ( jp3d = 1 ; jp3d <= myNbP3d ; jp3d++)
-
- { P3d=TabP3d.Value(jp3d);
- myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt3d);
- mat(index++, j0 + ipoint)=P3d.Distance(Pt3d);
-
- }
- }
- if(myNbP2d !=0 ) {
- if(myNbP3d == 0 ) ToolLine::Value(mySSP,ipoint,TabP2d);
- else ToolLine::Value(mySSP,ipoint,TabP3d,TabP2d);
- for ( jp2d = 1 ; jp2d <= myNbP2d ;jp2d++)
-
- { P2d = TabP2d.Value(jp2d);
- myMBSpCurve.Value(index,myParameters->Value(ipoint),Pt2d);
- mat(index++, j0 + ipoint)=P2d.Distance(Pt2d);
- }
- }
- }
-
-}
-//
-//=======================================================================
-//function : AverageError
-//purpose : returns the average error between
-// the MultiLine and the approximation.
-//=======================================================================
-//
-Standard_Real AppParCurves_Variational::AverageError() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myAverageError;
-}
-//
-//=======================================================================
-//function : Parameters
-//purpose : returns the parameters uses to the approximations
-//=======================================================================
-//
-const Handle(TColStd_HArray1OfReal)& AppParCurves_Variational::Parameters() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myParameters;
-}
-//
-//=======================================================================
-//function : Knots
-//purpose : returns the knots uses to the approximations
-//=======================================================================
-//
-const Handle(TColStd_HArray1OfReal)& AppParCurves_Variational::Knots() const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- return myKnots;
-}
-//
-//=======================================================================
-//function : Criterium
-//purpose : returns the values of the quality criterium.
-//=======================================================================
-//
-void AppParCurves_Variational::Criterium(Standard_Real& VFirstOrder, Standard_Real& VSecondOrder, Standard_Real& VThirdOrder) const
-{
- if (myIsDone == Standard_False) StdFail_NotDone::Raise();
- VFirstOrder=myCriterium[1] ;
- VSecondOrder=myCriterium[2];
- VThirdOrder=myCriterium[3];
-}
-//
-//=======================================================================
-//function : CriteriumWeight
-//purpose : returns the Weights (as percent) associed to the criterium used in
-// the optimization.
-//=======================================================================
-//
-void AppParCurves_Variational::CriteriumWeight(Standard_Real& Percent1, Standard_Real& Percent2, Standard_Real& Percent3) const
-{
- Percent1 = myPercent[0];
- Percent2 = myPercent[1];
- Percent3 = myPercent[2] ;
-}
-//
-//=======================================================================
-//function : MaxDegree
-//purpose : returns the Maximum Degree used in the approximation
-//=======================================================================
-//
-Standard_Integer AppParCurves_Variational::MaxDegree() const
-{
- return myMaxDegree;
-}
-//
-//=======================================================================
-//function : MaxSegment
-//purpose : returns the Maximum of segment used in the approximation
-//=======================================================================
-//
-Standard_Integer AppParCurves_Variational::MaxSegment() const
-{
- return myMaxSegment;
- }
-//
-//=======================================================================
-//function : Continuity
-//purpose : returns the Continuity used in the approximation
-//=======================================================================
-//
-GeomAbs_Shape AppParCurves_Variational::Continuity() const
-{
- return myContinuity;
-}
-//
-//=======================================================================
-//function : WithMinMax
-//purpose : returns if the approximation search to minimize the
-// maximum Error or not.
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::WithMinMax() const
-{
- return myWithMinMax;
-}
-//
-//=======================================================================
-//function : WithCutting
-//purpose : returns if the approximation can insert new Knots or not.
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::WithCutting() const
-{
- return myWithCutting;
-}
-//
-//=======================================================================
-//function : Tolerance
-//purpose : returns the tolerance used in the approximation.
-//=======================================================================
-//
-Standard_Real AppParCurves_Variational::Tolerance() const
-{
- return myTolerance;
-}
-//
-//=======================================================================
-//function : NbIterations
-//purpose : returns the number of iterations used in the approximation.
-//=======================================================================
-//
-Standard_Integer AppParCurves_Variational::NbIterations() const
-{
- return myNbIterations;
-}
-//
-//=======================================================================
-//function : Dump
-//purpose : Prints on the stream o information on the current state
-// of the object.
-//=======================================================================
-//
-void AppParCurves_Variational::Dump(Standard_OStream& o) const
-{
- o << " \nVariational Smoothing " << endl;
- o << " Number of multipoints " << myNbPoints << endl;
- o << " Number of 2d par multipoint " << myNbP2d << endl;
- o << " Nombre of 3d par multipoint " << myNbP3d << endl;
- o << " Number of PassagePoint " << myNbPassPoints << endl;
- o << " Number of TangencyPoints " << myNbTangPoints << endl;
- o << " Number of CurvaturePoints " << myNbCurvPoints << endl;
- o << " \nTolerance " << o.setf(ios::scientific) << setprecision(3) << setw(9) << myTolerance;
- if ( WithMinMax()) { o << " as Max Error." << endl;}
- else { o << " as size Error." << endl;}
- o << "CriteriumWeights : " << myPercent[0] << " , "
- << myPercent[1] << " , " << myPercent[2] << endl;
-
- if (myIsDone ) {
- o << " MaxError " << setprecision(3) << setw(9) << myMaxError << endl;
- o << " Index of MaxError " << myMaxErrorIndex << endl;
- o << " Average Error " << setprecision(3) << setw(9) << myAverageError << endl;
- o << " Quadratic Error " << setprecision(3) << setw(9) << myCriterium[0] << endl;
- o << " Tension Criterium " << setprecision(3) << setw(9) << myCriterium[1] << endl;
- o << " Flexion Criterium " << setprecision(3) << setw(9) << myCriterium[2] << endl;
- o << " Jerk Criterium " << setprecision(3) << setw(9) << myCriterium[3] << endl;
- o << " NbSegments " << myKnots->Length()-1 << endl;
- }
- else
- { if (myIsOverConstr) o << "The probleme is overconstraint " << endl;
- else o << " Erreur dans l''approximation" << endl;
- }
-}
-//
-//=======================================================================
-//function : SetConstraints
-//purpose : Define the constraints to approximate
-// If this value is incompatible with the others fields
-// this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetConstraints(const Handle(AppParCurves_HArray1OfConstraintCouple)& aConstraint)
-
-{
- myConstraints=aConstraint;
- Init();
- if (myIsOverConstr ) return Standard_False;
- else return Standard_True;
-}
-//
-//=======================================================================
-//function : SetParameters
-//purpose : Defines the parameters used by the approximations.
-//=======================================================================
-//
-void AppParCurves_Variational::SetParameters(const Handle(TColStd_HArray1OfReal)& param)
-{
- myParameters->ChangeArray1() = param->Array1();
-}
-//
-//=======================================================================
-//function : SetKnots
-//purpose : Defines the knots used by the approximations
-// -- If this value is incompatible with the others fields
-// -- this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetKnots(const Handle(TColStd_HArray1OfReal)& knots)
-{
- myKnots->ChangeArray1() = knots->Array1();
- return Standard_True;
-}
-//
-//=======================================================================
-//function : SetMaxDegree
-//purpose : Define the Maximum Degree used in the approximation
-// If this value is incompatible with the others fields
-// this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetMaxDegree(const Standard_Integer Degree)
-{
- if (((Degree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- return Standard_False;
- else
- {
- myMaxDegree=Degree;
-
- InitSmoothCriterion();
-
- return Standard_True;
- }
-
-}
-//
-//=======================================================================
-//function : SetMaxSegment
-//purpose : Define the maximum number of segments used in the approximation
-// If this value is incompatible with the others fields
-// this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetMaxSegment(const Standard_Integer NbSegment)
-{
- if ( myWithCutting == Standard_True &&
- ((myMaxDegree-myNivCont)*NbSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- return Standard_False;
- else
- {
- myMaxSegment=NbSegment;
- return Standard_True;
- }
-}
-//
-//=======================================================================
-//function : SetContinuity
-//purpose : Define the Continuity used in the approximation
-// If this value is incompatible with the others fields
-// this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetContinuity(const GeomAbs_Shape C)
-{
- Standard_Integer NivCont=0;
- switch (C) {
- case GeomAbs_C0:
- NivCont=0;
- break ;
- case GeomAbs_C1:
- NivCont=1;
- break ;
- case GeomAbs_C2:
- NivCont=2;
- break ;
- default:
- Standard_ConstructionError::Raise();
- }
- if (((myMaxDegree-NivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- return Standard_False;
- else
- {
- myContinuity= C;
- myNivCont=NivCont;
-
- InitSmoothCriterion();
- return Standard_True;
- }
-}
-//
-//=======================================================================
-//function : SetWithMinMax
-//purpose : Define if the approximation search to minimize the
-// maximum Error or not.
-//=======================================================================
-//
-void AppParCurves_Variational::SetWithMinMax(const Standard_Boolean MinMax)
-{
- myWithMinMax=MinMax;
-
- InitSmoothCriterion();
-}
-//
-//=======================================================================
-//function : SetWithCutting
-//purpose : Define if the approximation can insert new Knots or not.
-// If this value is incompatible with the others fields
-// this method modify nothing and returns false
-//=======================================================================
-//
-Standard_Boolean AppParCurves_Variational::SetWithCutting(const Standard_Boolean Cutting)
-{
- if (Cutting == Standard_False)
- {
- if (((myMaxDegree-myNivCont)*myKnots->Length()-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- return Standard_False;
-
- else
- {
- myWithCutting=Cutting;
- InitSmoothCriterion();
- return Standard_True;
- }
- }
- else
- {
- if (((myMaxDegree-myNivCont)*myMaxSegment-myNbPassPoints-2*myNbTangPoints-3*myNbCurvPoints) < 0 )
- return Standard_False;
-
- else
- {
- myWithCutting=Cutting;
- InitSmoothCriterion();
- return Standard_True;
- }
- }
-}
-//
-//=======================================================================
-//function : SetCriteriumWeight
-//purpose : define the Weights (as percent) associed to the criterium used in
-// the optimization.
-//=======================================================================
-//
-void AppParCurves_Variational::SetCriteriumWeight(const Standard_Real Percent1, const Standard_Real Percent2, const Standard_Real Percent3)
-{
- if (Percent1 < 0 || Percent2 < 0 || Percent3 < 0 ) Standard_DomainError::Raise();
- Standard_Real Total = Percent1 + Percent2 + Percent3;
- myPercent[0] = Percent1/Total;
- myPercent[1] = Percent2/Total;
- myPercent[2] = Percent3/Total;
-
- InitSmoothCriterion();
-}
-//
-//=======================================================================
-//function : SetCriteriumWeight
-//purpose : define the Weight (as percent) associed to the
-// criterium Order used in the optimization : Others
-// weights are updated.
-//=======================================================================
-//
-void AppParCurves_Variational::SetCriteriumWeight(const Standard_Integer Order, const Standard_Real Percent)
-{
- if ( Percent < 0 ) Standard_DomainError::Raise();
- if ( Order < 1 || Order > 3 ) Standard_ConstructionError::Raise();
- myPercent[Order-1] = Percent;
- Standard_Real Total = myPercent[0] + myPercent[1] + myPercent[2];
- myPercent[0] = myPercent[0] / Total;
- myPercent[1] = myPercent[1] / Total;
- myPercent[2] = myPercent[2] / Total;
-
- InitSmoothCriterion();
-
-}
-//
-//=======================================================================
-//function : SetTolerance
-//purpose : define the tolerance used in the approximation.
-//=======================================================================
-//
-void AppParCurves_Variational::SetTolerance(const Standard_Real Tol)
-{
- myTolerance=Tol;
- InitSmoothCriterion();
-}
-//
-//=======================================================================
-//function : SetNbIterations
-//purpose : define the number of iterations used in the approximation.
-//=======================================================================
-//
-void AppParCurves_Variational::SetNbIterations(const Standard_Integer Iter)
-{
- myNbIterations=Iter;
-}
-
-
-// Private methods
-#include <AppParCurves_Variational_1.gxx> // TheMotor
-#include <AppParCurves_Variational_2.gxx> // Optimization
-#include <AppParCurves_Variational_3.gxx> // Project
-#include <AppParCurves_Variational_4.gxx> // ACR
-#include <AppParCurves_Variational_5.gxx> // SplitCurve
-#include <AppParCurves_Variational_6.gxx> // InitSmoothCriterion and other Init... methods
-#include <AppParCurves_Variational_7.gxx> // Adjusting
-#include <AppParCurves_Variational_8.gxx> // AssemblingConstraints
-#include <AppParCurves_Variational_9.gxx> // InitTtheta and InitTfthet methods
+++ /dev/null
-// Created on: 1997-09-17
-// Created by: Philippe MANGIN /Igor Feoktistov (1998)
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <SortTools_StraightInsertionSortOfReal.hxx>
-#include <TCollection_CompareOfReal.hxx>
-#include <TColStd_HArray2OfInteger.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColStd_Array2OfInteger.hxx>
-#include <FEmTool_Assembly.hxx>
-#include <FEmTool_AssemblyTable.hxx>
-#include <FEmTool_Curve.hxx>
-
-//====================== Private Methodes =============================//
-//=======================================================================
-//function : TheMotor
-//purpose : Smoothing's motor like STRIM routine "MOTLIS"
-//=======================================================================
-void AppParCurves_Variational::TheMotor(
- Handle(AppParCurves_SmoothCriterion)& J,
-// const Standard_Real WQuadratic,
- const Standard_Real ,
- const Standard_Real WQuality,
- Handle(FEmTool_Curve)& TheCurve,
- TColStd_Array1OfReal& Ecarts)
-{
-// ...
-
- const Standard_Real BigValue = 1.e37, SmallValue = 1.e-6, SmallestValue = 1.e-9;
-
-// SortTools_StraightInsertionSortOfReal Sort;
- TCollection_CompareOfReal CompReal;
- Handle(TColStd_HArray1OfReal) CurrentTi, NewTi, OldTi;
- Handle(TColStd_HArray2OfInteger) Dependence;
- Standard_Boolean lestim, lconst, ToOptim, iscut;
- Standard_Boolean isnear = Standard_False, again = Standard_True;
- Standard_Integer NbEst, ICDANA, NumPnt, Iter;
- Standard_Integer MaxNbEst =5;
- Standard_Real VOCRI[3] = {BigValue, BigValue, BigValue}, EROLD = BigValue,
- VALCRI[3], ERRMAX = BigValue, ERRMOY, ERRQUA;
- Standard_Real CBLONG, LNOLD;
- Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
- Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
- Handle(FEmTool_Curve) CCurrent, COld, CNew;
- Standard_Real EpsLength = SmallValue;
- Standard_Real EpsDeg;
-
- Standard_Real e1, e2, e3;
- Standard_Real J1min, J2min, J3min;
- Standard_Integer iprog;
-
-// (0) Init
-
- J->GetEstimation(e1, e2, e3);
- J1min = 1.e-8; J2min = J3min = (e1 + 1.e-8) * 1.e-6;
-
- if(e1 < J1min) e1 = J1min;// Like in
- if(e2 < J2min) e2 = J2min;// MOTLIS
- if(e3 < J3min) e3 = J3min;
-
-
- J->SetEstimation(e1, e2, e3);
-
- CCurrent = TheCurve;
- CurrentTi = new TColStd_HArray1OfReal(1, myParameters->Length());
- CurrentTi->ChangeArray1() = myParameters->Array1();
- OldTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
- OldTi->ChangeArray1() = CurrentTi->Array1();
- COld = CCurrent;
- LNOLD = CBLONG = J->EstLength();
- Dependence = J->DependenceTable();
-
- J->SetCurve(CCurrent);
- FEmTool_Assembly * TheAssembly =
- new FEmTool_Assembly (Dependence->Array2(), J->AssemblyTable());
-
-//============ Optimization ============================
-// Standard_Integer inagain = 0;
- while (again) {
-
- // (1) Loop Optimization / Estimation
- lestim = Standard_True;
- lconst = Standard_True;
- NbEst = 0;
-
- J->SetCurve(CCurrent);
-
- while(lestim) {
-
- // (1.1) Curve's Optimization.
- EpsLength = SmallValue * CBLONG / NbrPnt;
- CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
- CCurrent->NbElements(), CCurrent->Base(), EpsLength);
- CNew->Knots() = CCurrent->Knots();
-
- J->SetParameters(CurrentTi);
- EpsDeg = Min(WQuality * .1, CBLONG * .001);
-
- Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
-
- lconst = Standard_False;
-
- // (1.2) calcul des criteres de qualites et amelioration
- // des estimation.
- ICDANA = J->QualityValues(J1min, J2min, J3min,
- VALCRI[0], VALCRI[1], VALCRI[2]);
-
- if(ICDANA > 0) lconst = Standard_True;
-
- J->ErrorValues(ERRMAX, ERRQUA, ERRMOY);
-
- isnear = ((Sqrt(ERRQUA / NbrPnt) < 2*WQuality) &&
- (myNbIterations > 1));
-
-// (1.3) Optimisation des ti par proj orthogonale
-// et calcul de l'erreur aux points.
-
- if (isnear) {
- NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
- Project(CNew, CurrentTi->Array1(),
- NewTi->ChangeArray1(),
- Ecarts, NumPnt,
- ERRMAX, ERRQUA, ERRMOY, 2);
- }
- else NewTi = CurrentTi;
-
-
-// (1.4) Progression's test
- iprog = 0;
- if ((EROLD > WQuality) && (ERRMAX < 0.95*EROLD)) iprog++;
- if ((EROLD > WQuality) && (ERRMAX < 0.8*EROLD)) iprog++;
- if ((EROLD > WQuality) && (ERRMAX < WQuality)) iprog++;
- if ((EROLD > WQuality) && (ERRMAX < 0.99*EROLD)
- && (ERRMAX < 1.1*WQuality)) iprog++;
- if ( VALCRI[0] < 0.975 * VOCRI[0]) iprog++;
- if ( VALCRI[0] < 0.9 * VOCRI[0]) iprog++;
- if ( VALCRI[1] < 0.95 * VOCRI[1]) iprog++;
- if ( VALCRI[1] < 0.8 * VOCRI[1]) iprog++;
- if ( VALCRI[2] < 0.95 * VOCRI[2]) iprog++;
- if ( VALCRI[2] < 0.8 * VOCRI[2]) iprog++;
- if ((VOCRI[1]>SmallestValue)&&(VOCRI[2]>SmallestValue)) {
- if ((VALCRI[1]/VOCRI[1] + 2*VALCRI[2]/VOCRI[2]) < 2.8) iprog++;
- }
-
- if (iprog < 2 && NbEst == 0 ) {
- // (1.5) Invalidation of new knots.
- VALCRI[0] = VOCRI[0];
- VALCRI[1] = VOCRI[1];
- VALCRI[2] = VOCRI[2];
- ERRMAX = EROLD;
- CBLONG = LNOLD;
- CCurrent = COld;
- CurrentTi = OldTi;
-
- goto L8000; // exit
- }
-
- VOCRI[0] = VALCRI[0];
- VOCRI[1] = VALCRI[1];
- VOCRI[2] = VALCRI[2];
- LNOLD = CBLONG;
- EROLD = ERRMAX;
-
- CCurrent = CNew;
- CurrentTi = NewTi;
-
- // (1.6) Test if the Estimations seems OK, else repeat
- NbEst++;
- lestim = ( (NbEst<MaxNbEst) && (ICDANA == 2)&& (iprog > 0) );
-
- if (lestim && isnear) {
- // (1.7) Optimization of ti by ACR.
-// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
- SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
- Standard_Integer Decima = 4;
-
- CCurrent->Length(0., 1., CBLONG);
- J->EstLength() = CBLONG;
-
- ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
- lconst = Standard_True;
-
- }
- }
-
-
- // (2) loop of parametric / geometric optimization
-
- Iter = 1;
- ToOptim = ((Iter < myNbIterations) && (isnear));
-
- while(ToOptim) {
- Iter++;
- // (2.1) Save curent results
- VOCRI[0] = VALCRI[0];
- VOCRI[1] = VALCRI[1];
- VOCRI[2] = VALCRI[2];
- EROLD = ERRMAX;
- LNOLD = CBLONG;
- COld = CCurrent;
- OldTi->ChangeArray1() = CurrentTi->Array1();
-
- // (2.2) Optimization des ti by ACR.
-// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
- SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
- Standard_Integer Decima = 4;
-
- CCurrent->Length(0., 1., CBLONG);
- J->EstLength() = CBLONG;
-
- ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
- lconst = Standard_True;
-
- // (2.3) Optimisation des courbes
- EpsLength = SmallValue * CBLONG / NbrPnt;
-
- CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
- CCurrent->NbElements(), CCurrent->Base(), EpsLength);
- CNew->Knots() = CCurrent->Knots();
-
- J->SetParameters(CurrentTi);
-
- EpsDeg = Min(WQuality * .1, CBLONG * .001);
- Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
-
- CCurrent = CNew;
-
- // (2.4) calcul des criteres de qualites et amelioration
- // des estimation.
-
- ICDANA = J->QualityValues(J1min, J2min, J3min, VALCRI[0], VALCRI[1], VALCRI[2]);
- if(ICDANA > 0) lconst = Standard_True;
-
- J->GetEstimation(e1, e2, e3);
- // (2.5) Optimisation des ti par proj orthogonale
-
- NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
- Project(CCurrent, CurrentTi->Array1(),
- NewTi->ChangeArray1(),
- Ecarts, NumPnt,
- ERRMAX, ERRQUA, ERRMOY, 2);
-
- // (2.6) Test de non regression
-
- Standard_Integer iregre = 0;
- if (NbrConstraint < NbrPnt) {
- if ( (ERRMAX > WQuality) && (ERRMAX > 1.05*EROLD)) iregre++;
- if ( (ERRMAX > WQuality) && (ERRMAX > 2*EROLD)) iregre++;
- if ( (EROLD > WQuality) && (ERRMAX <= 0.5*EROLD)) iregre--;
- }
- Standard_Real E1, E2, E3;
- J->GetEstimation(E1, E2, E3);
- if ( (VALCRI[0] > E1) && (VALCRI[0] > 1.1*VOCRI[0])) iregre++;
- if ( (VALCRI[1] > E2) && (VALCRI[1] > 1.1*VOCRI[1])) iregre++;
- if ( (VALCRI[2] > E3) && (VALCRI[2] > 1.1*VOCRI[2])) iregre++;
-
-
- if (iregre >= 2) {
-// if (iregre >= 1) {
- // (2.7) on restaure l'iteration precedente
- VALCRI[0] = VOCRI[0];
- VALCRI[1] = VOCRI[1];
- VALCRI[2] = VOCRI[2];
- ERRMAX = EROLD;
- CBLONG = LNOLD;
- CCurrent = COld;
- CurrentTi->ChangeArray1() = OldTi->Array1();
- ToOptim = Standard_False;
- }
- else { // Iteration is Ok.
- CCurrent = CNew;
- CurrentTi = NewTi;
- }
- if (Iter >= myNbIterations) ToOptim = Standard_False;
- }
-
- // (3) Decoupe eventuelle
-
- if ( (CCurrent->NbElements() < myMaxSegment) && myWithCutting ) {
-
- // (3.1) Sauvgarde de l'etat precedent
- VOCRI[0] = VALCRI[0];
- VOCRI[1] = VALCRI[1];
- VOCRI[2] = VALCRI[2];
- EROLD = ERRMAX;
- COld = CCurrent;
- OldTi->ChangeArray1() = CurrentTi->Array1();
-
- // (3.2) On arrange les ti : Trie + recadrage sur (0,1)
- // ---> On trie, afin d'assurer l'ordre par la suite.
-// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
- SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
-
- if ((CurrentTi->Value(1)!= 0.) ||
- (CurrentTi->Value(NbrPnt)!= 1.)) {
- Standard_Real t, DelatT =
- 1.0 /(CurrentTi->Value(NbrPnt)-CurrentTi->Value(1));
- for (Standard_Integer ii=2; ii<NbrPnt; ii++) {
- t = (CurrentTi->Value(ii)-CurrentTi->Value(1))*DelatT;
- CurrentTi->SetValue(ii, t);
- }
- CurrentTi->SetValue(1, 0.);
- CurrentTi->SetValue(NbrPnt, 1.);
- }
-
- // (3.3) Insert new Knots
-
- SplitCurve(CCurrent, CurrentTi->Array1(), EpsLength, CNew, iscut);
- if (!iscut) again = Standard_False;
- else {
- CCurrent = CNew;
- // New Knots => New Assembly.
- J->SetCurve(CNew);
- delete TheAssembly;
- TheAssembly = new FEmTool_Assembly (Dependence->Array2(),
- J->AssemblyTable());
- }
- }
- else { again = Standard_False;}
- }
-
- // ================ Great loop end ===================
-
- L8000:
-
- // (4) Compute the best Error.
- NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
- Project(CCurrent, CurrentTi->Array1(),
- NewTi->ChangeArray1(),
- Ecarts, NumPnt,
- ERRMAX, ERRQUA, ERRMOY, 10);
-
-// (5) field's update
-
- TheCurve = CCurrent;
- J->EstLength() = CBLONG;
- myParameters->ChangeArray1() = NewTi->Array1();
- myCriterium[0] = ERRQUA;
- myCriterium[1] = Sqrt(VALCRI[0]);
- myCriterium[2] = Sqrt(VALCRI[1]);
- myCriterium[3] = Sqrt(VALCRI[2]);
- myMaxError = ERRMAX;
- myMaxErrorIndex = NumPnt;
- if(NbrPnt > NbrConstraint)
- myAverageError = ERRMOY / (NbrPnt - NbrConstraint);
- else
- myAverageError = ERRMOY / NbrConstraint;
-
- delete TheAssembly;
-}
+++ /dev/null
-// Created on: 1998-12-07
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <math_Matrix.hxx>
-#include <math_Vector.hxx>
-#include <TColStd_Array2OfReal.hxx>
-#include <PLib_Base.hxx>
-#include <PLib_JacobiPolynomial.hxx>
-#include <PLib_HermitJacobi.hxx>
-#include <FEmTool_HAssemblyTable.hxx>
-
-
-
-//=======================================================================
-//function : Optimization
-//purpose : (like FORTRAN subroutine MINIMI)
-//=======================================================================
-void AppParCurves_Variational::Optimization(Handle(AppParCurves_SmoothCriterion)& J,
- FEmTool_Assembly& A,
- const Standard_Boolean ToAssemble,
- const Standard_Real EpsDeg,
- Handle(FEmTool_Curve)& Curve,
- const TColStd_Array1OfReal& Parameters) const
-{
- Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
- NbElm = Curve->NbElements(),
- NbDim = Curve->Dimension();
-
- Handle(FEmTool_HAssemblyTable) AssTable;
-
- math_Matrix H(0, MxDeg, 0, MxDeg);
- math_Vector G(0, MxDeg), Sol(1, A.NbGlobVar());
-
- Standard_Integer el, dim;
-
- A.GetAssemblyTable(AssTable);
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
-
- Standard_Real CBLONG = J->EstLength();
-
- // Updating Assembly
- if (ToAssemble)
- A.NullifyMatrix();
- A.NullifyVector();
-
-
- for (el = 1; el <= NbElm; el++) {
- if (ToAssemble) {
- J->Hessian(el, 1, 1, H);
- for(dim = 1; dim <= NbDim; dim++)
- A.AddMatrix(el, dim, dim, H);
- }
-
- for(dim = 1; dim <= NbDim; dim++) {
- J->Gradient(el, dim, G);
- A.AddVector(el, dim, G);
- }
- }
-
-
- // Solution of system
- if (ToAssemble) {
- if(NbConstr != 0) { //Treatment of constraints
- AssemblingConstraints(Curve, Parameters, CBLONG, A);
- }
- A.Solve();
- }
- A.Solution(Sol);
-
-
- // Updating J
- J->SetCurve(Curve);
- J->InputVector(Sol, AssTable);
-
- // Updating Curve and reduction of degree
-
- Standard_Integer Newdeg;
- Standard_Real MaxError;
-
- if(NbConstr == 0) {
- for(el = 1; el <= NbElm; el++) {
- Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
- }
- }
- else {
-
- TColStd_Array1OfReal& TabInt = Curve->Knots();
- Standard_Integer Icnt = 1, p0 = Parameters.Lower() - myFirstPoint, point;
- for(el = 1; el <= NbElm; el++) {
- while((Icnt < NbConstr) &&
- (Parameters(p0 + myTypConstraints->Value(2 * Icnt - 1)) <= TabInt(el))) Icnt++;
- point = p0 + myTypConstraints->Value(2 * Icnt - 1);
- if(Parameters(point) <= TabInt(el) || Parameters(point) >= TabInt(el + 1))
- Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
- else
- if(Curve->Degree(el) < MxDeg) Curve->SetDegree(el, MxDeg);
- }
- }
-}
-
+++ /dev/null
-// Created on: 1998-12-08
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-void AppParCurves_Variational::Project(const Handle(FEmTool_Curve)& C,
- const TColStd_Array1OfReal& Ti,
- TColStd_Array1OfReal& ProjTi,
- TColStd_Array1OfReal& Distance,
- Standard_Integer& NumPoints,
- Standard_Real& MaxErr,
- Standard_Real& QuaErr,
- Standard_Real& AveErr,
- const Standard_Integer NbIterations) const
-
-{
- // Initialisation
-
- const Standard_Real Seuil = 1.e-9, Eps = 1.e-12;
-
- MaxErr = QuaErr = AveErr = 0.;
-
- Standard_Integer Ipnt, NItCv, Iter, i, i0 = -myDimension, d0 = Distance.Lower() - 1;
-
- Standard_Real TNew, Dist, T0, Dist0, F1, F2, Aux, DF, Ecart;
-
- Standard_Boolean EnCour;
-
- TColStd_Array1OfReal ValOfC(1, myDimension), FirstDerOfC(1, myDimension),
- SecndDerOfC(1, myDimension);
-
- for(Ipnt = 1; Ipnt <= ProjTi.Length(); Ipnt++) {
-
- i0 += myDimension;
-
- TNew = Ti(Ipnt);
-
- EnCour = Standard_True;
- NItCv = 0;
- Iter = 0;
- C->D0(TNew, ValOfC);
-
- Dist = 0;
- for(i = 1; i <= myDimension; i++) {
- Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
- Dist += Aux * Aux;
- }
- Dist = Sqrt(Dist);
-
- // ------- Newton's method for solving (C'(t),C(t) - P) = 0
-
- while( EnCour ) {
-
- Iter++;
- T0 = TNew;
- Dist0 = Dist;
-
- C->D2(TNew, SecndDerOfC);
- C->D1(TNew, FirstDerOfC);
-
- F1 = F2 = 0.;
- for(i = 1; i <= myDimension; i++) {
- Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
- DF = FirstDerOfC(i);
- F1 += Aux*DF; // (C'(t),C(t) - P)
- F2 += DF*DF + Aux * SecndDerOfC(i); // ((C'(t),C(t) - P))'
- }
-
- if(Abs(F2) < Eps)
- EnCour = Standard_False;
- else {
- // Formula of Newton x(k+1) = x(k) - F(x(k))/F'(x(k))
- TNew -= F1 / F2;
- if(TNew < 0.) TNew = 0.;
- if(TNew > 1.) TNew = 1.;
-
-
- // Analysis of result
-
- C->D0(TNew, ValOfC);
-
- Dist = 0;
- for(i = 1; i <= myDimension; i++) {
- Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
- Dist += Aux * Aux;
- }
- Dist = Sqrt(Dist);
-
- Ecart = Dist0 - Dist;
-
- if(Ecart <= -Seuil) {
- // Pas d'amelioration on s'arrete
- EnCour = Standard_False;
- TNew = T0;
- Dist = Dist0;
- }
- else if(Ecart <= Seuil)
- // Convergence
- NItCv++;
- else
- NItCv = 0;
-
- if((NItCv >= 2) || (Iter >= NbIterations)) EnCour = Standard_False;
-
- }
- }
-
-
- ProjTi(Ipnt) = TNew;
- Distance(d0 + Ipnt) = Dist;
- if(Dist > MaxErr) {
- MaxErr = Dist;
- NumPoints = Ipnt;
- }
- QuaErr += Dist * Dist;
- AveErr += Dist;
- }
-
- NumPoints = NumPoints + myFirstPoint - 1;// Setting NumPoints to interval [myFirstPoint, myLastPoint]
-
-}
+++ /dev/null
-// Created on: 1998-12-08
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-void AppParCurves_Variational::ACR(Handle(FEmTool_Curve)& Curve,
- TColStd_Array1OfReal& Ti,
- const Standard_Integer Decima) const
-{
-
- const Standard_Real Eps = 1.e-8;
-
- TColStd_Array1OfReal& Knots = Curve->Knots();
- Standard_Integer NbrPnt = Ti.Length(), TiFirst = Ti.Lower(), TiLast = Ti.Upper(),
- KFirst = Knots.Lower(), KLast = Knots.Upper();
-
- Standard_Real CbLong, DeltaT, VTest, UNew, UOld, DU, TPara, TOld, DTInv, Ratio;
- Standard_Integer ipnt, ii, IElm, IOld, POld, PCnt, ICnt=0;
- Standard_Integer NbCntr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
-
- // (1) Calcul de la longueur de courbe
-
- Curve->Length(Ti(TiFirst), Ti(TiLast), CbLong);
-
- // (2) Mise de l'acr dans Ti
-
- if(NbrPnt >= 2) {
-
- // (2.0) Initialisation
- DeltaT = (Ti(TiLast) - Ti(TiFirst)) / Decima;
- VTest = Ti(TiFirst) + DeltaT;
-
- if(NbCntr > 0) {
- PCnt = myTypConstraints->Value(1) - myFirstPoint + TiFirst;
- ICnt = 1;
- }
- else
- PCnt = TiLast + 1;
-
- UOld = 0.;
-
- TOld = Ti(TiFirst);
- POld = TiFirst;
-
- IElm = KFirst;
- IOld = IElm;
-
- Ti(TiFirst) = 0.;
-
- for(ipnt = TiFirst + 1; ipnt <= TiLast; ipnt++) {
-
- while((ICnt <= NbCntr) && (PCnt < ipnt)) {
- ICnt++;
- PCnt = myTypConstraints->Value(2*ICnt-1) - myFirstPoint + TiFirst;
- }
-
- TPara = Ti(ipnt);
-
- if(TPara >= VTest || PCnt == ipnt) {
-
- if ( Ti(TiLast) - TPara <= 1.e-2*DeltaT) {
- ipnt = TiLast;
- TPara = Ti(ipnt);
- }
- // (2.2), (2.3) Cacul la longueur de courbe
- Curve->Length(Ti(TiFirst), TPara, UNew);
-
- UNew /= CbLong;
-
- while(Knots(IElm + 1) < TPara && IElm < KLast - 1) IElm++;
-
- // (2.4) Mise a jours des parametres de decoupe
- DTInv = 1. / (TPara - TOld);
- DU = UNew - UOld;
-
- for(ii = IOld+1; ii <= IElm; ii++) {
- Ratio = (Knots(ii) - TOld) * DTInv;
- Knots(ii) = UOld + Ratio * DU;
- }
-
- // (2.5) Mise a jours des parametres de points.
-
- //Very strange loop, because it never works (POld+1 > ipnt-1)
- for(ii = POld+1; ii <= ipnt-1; ii++) {
- Ratio = ( Ti(ii) - TOld ) * DTInv;
- Ti(ii) = UOld + Ratio * DU;
- }
-
- Ti(ipnt) = UNew;
-
- UOld = UNew;
- IOld = IElm;
- TOld = TPara;
- POld = ipnt;
-
- }
- // --> Nouveau seuil parametrique pour le decimage
-
- if(TPara >= VTest) {
-// ii = RealToInt((TPara - VTest + Eps) / DeltaT);
-// VTest += (ii + 1) * DeltaT;
- VTest += Ceiling((TPara - VTest + Eps) / DeltaT) * DeltaT;
- if(VTest > 1. - Eps) VTest = 1.;
- }
- }
- }
-
- // --- On ajuste les valeurs extremes
-
- Ti(TiFirst) = 0.;
- Ti(TiLast) = 1.;
- ii = TiLast - 1;
- while ( Ti(ii) > Knots(KLast) ) {
- Ti(ii) = 1.;
- --ii;
- }
- Knots(KFirst) = 0.;
- Knots(KLast) = 1.;
-
-}
-
-
+++ /dev/null
-// Created on: 1998-12-10
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <SortTools_ShellSortOfReal.hxx>
-#include <TCollection_CompareOfReal.hxx>
-#include <PLib_Base.hxx>
-
-//----------------------------------------------------------//
-// Standard_Integer NearIndex //
-// Purpose: searching nearest index of TabPar corresponding //
-// given value T (is similar to fortran routine MSRRE2) //
-//----------------------------------------------------------//
-
-static Standard_Integer NearIndex(const Standard_Real T,
- const TColStd_Array1OfReal& TabPar,
- const Standard_Real Eps, Standard_Integer& Flag)
-{
- Standard_Integer Loi = TabPar.Lower(), Upi = TabPar.Upper();
-
- Flag = 0;
-
- if(T < TabPar(Loi)) { Flag = -1; return Loi;}
- if(T > TabPar(Upi)) { Flag = 1; return Upi;}
-
- Standard_Integer Ibeg = Loi, Ifin = Upi, Imidl;
-
- while(Ibeg + 1 != Ifin) {
- Imidl = (Ibeg + Ifin) / 2;
- if((T >= TabPar(Ibeg)) && (T <= TabPar(Imidl)))
- Ifin = Imidl;
- else
- Ibeg = Imidl;
- }
-
- if(Abs(T - TabPar(Ifin)) < Eps) return Ifin;
-
- return Ibeg;
-}
-
-
-//----------------------------------------------------------//
-// void GettingKnots //
-// Purpose: calculating values of new Knots for elements //
-// with degree that is equal Deg //
-//----------------------------------------------------------//
-
-static void GettingKnots(const TColStd_Array1OfReal& TabPar,
- const Handle(FEmTool_Curve)& InCurve,
- const Standard_Integer Deg,
- Standard_Integer& NbElm,
- TColStd_Array1OfReal& NewKnots)
-
-{
-
- const Standard_Real Eps = 1.e-12;
-
- TColStd_Array1OfReal& OldKnots = InCurve->Knots();
- Standard_Integer NbMaxOld = InCurve->NbElements();
- Standard_Integer NbMax = NewKnots.Upper(), Ipt, Ipt1, Ipt2;
- Standard_Integer el = 0, i1 = OldKnots.Lower(), i0 = i1 - 1, Flag;
- Standard_Real TPar;
-
- while((NbElm < NbMax) && (el < NbMaxOld)) {
-
- el++; i0++; i1++; // i0, i1 are indexes of left and right knots of element el
-
- if(InCurve->Degree(el) == Deg) {
-
- NbElm++;
-
- Ipt1 = NearIndex(OldKnots(i0), TabPar, Eps, Flag);
- if(Flag != 0) Ipt1 = TabPar.Lower();
- Ipt2 = NearIndex(OldKnots(i1), TabPar, Eps, Flag);
- if(Flag != 0) Ipt2 = TabPar.Upper();
-
- if(Ipt2 - Ipt1 >= 1) {
-
- Ipt = (Ipt1 + Ipt2) / 2;
- if(2 * Ipt == Ipt1 + Ipt2)
- TPar = 2. * TabPar(Ipt);
- else
- TPar = TabPar(Ipt) + TabPar(Ipt + 1);
-
- NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1) + TPar) / 4.;
- }
- else
- NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1)) / 2.;
- }
- }
-}
-
-void AppParCurves_Variational::SplitCurve(const Handle(FEmTool_Curve)& InCurve,
- const TColStd_Array1OfReal& Ti,
- const Standard_Real CurveTol,
- Handle(FEmTool_Curve)& OutCurve,
- Standard_Boolean& iscut) const
-{
- Standard_Integer NbElmOld = InCurve->NbElements();
-
- if(NbElmOld >= myMaxSegment) {iscut = Standard_False; return;}
-#ifdef DEB
- Standard_Integer MaxDegree =
-#endif
- InCurve->Base()->WorkDegree();
- Standard_Integer NbElm = NbElmOld;
- TColStd_Array1OfReal NewKnots(NbElm + 1, myMaxSegment);
-#ifndef DEB
- GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree(), NbElm, NewKnots);
- GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree() - 1, NbElm, NewKnots);
-#else
- GettingKnots(Ti, InCurve, MaxDegree, NbElm, NewKnots);
- GettingKnots(Ti, InCurve, MaxDegree - 1, NbElm, NewKnots);
-
-#endif
- if(NbElm > NbElmOld) {
-
- iscut = Standard_True;
-
- OutCurve = new FEmTool_Curve(InCurve->Dimension(), NbElm, InCurve->Base(), CurveTol);
- TColStd_Array1OfReal& OutKnots = OutCurve->Knots();
- TColStd_Array1OfReal& InKnots = InCurve->Knots();
-
- Standard_Integer i, i0 = OutKnots.Lower();
- for(i = InKnots.Lower(); i <= InKnots.Upper(); i++) OutKnots(i) = InKnots(i);
- for(i = NbElmOld + 1; i <= NbElm; i++) OutKnots(i + i0) = NewKnots(i);
-
-// SortTools_ShellSortOfReal Sort;
- TCollection_CompareOfReal CompReal;
-
-// Sort.Sort(OutKnots, CompReal);
- SortTools_ShellSortOfReal::Sort(OutKnots, CompReal);
- }
- else
- iscut = Standard_False;
-
-}
-
-
-
+++ /dev/null
-// Created on: 1998-12-21
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559
-
-#include <PLib_Base.hxx>
-#include <PLib_JacobiPolynomial.hxx>
-#include <PLib_HermitJacobi.hxx>
-#include <FEmTool_Curve.hxx>
-#include <math_Vector.hxx>
-#include <TColStd_Array1OfReal.hxx>
-
-//=======================================================================
-//function : InitSmoothCriterion
-//purpose : Initializes the SmoothCriterion
-//=======================================================================
-void AppParCurves_Variational::InitSmoothCriterion()
-{
-
- const Standard_Real Eps2 = 1.e-6, Eps3 = 1.e-9;
-// const Standard_Real J1 = .01, J2 = .001, J3 = .001;
-
-
-
- Standard_Real Length;
-
- InitParameters(Length);
-
- mySmoothCriterion->SetParameters(myParameters);
-
- Standard_Real E1, E2, E3;
-
- InitCriterionEstimations(Length, E1, E2, E3);
-/*
- J1 = 1.e-8; J2 = J3 = (E1 + 1.e-8) * 1.e-6;
-
- if(E1 < J1) E1 = J1;
- if(E2 < J2) E2 = J2;
- if(E3 < J3) E3 = J3;
-*/
- mySmoothCriterion->EstLength() = Length;
- mySmoothCriterion->SetEstimation(E1, E2, E3);
-
- Standard_Real WQuadratic, WQuality;
-
- if(!myWithMinMax && myTolerance != 0.)
- WQuality = myTolerance;
- else if (myTolerance == 0.)
- WQuality = 1.;
- else
- WQuality = Max(myTolerance, Eps2 * Length);
-
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
- WQuadratic = Sqrt((Standard_Real)(myNbPoints - NbConstr)) * WQuality;
- if(WQuadratic > Eps3) WQuadratic = 1./ WQuadratic;
-
- if(WQuadratic == 0.) WQuadratic = Max(Sqrt(E1), 1.);
-
-
- mySmoothCriterion->SetWeight(WQuadratic, WQuality,
- myPercent[0], myPercent[1], myPercent[2]);
-
-
- Handle(PLib_Base) TheBase = new PLib_HermitJacobi(myMaxDegree, myContinuity);
- Handle(FEmTool_Curve) TheCurve;
- Standard_Integer NbElem;
- Standard_Real CurvTol = Eps2 * Length / myNbPoints;
-
- // Decoupe de l'intervalle en fonction des contraintes
- if(myWithCutting == Standard_True && NbConstr != 0) {
-
- InitCutting(TheBase, CurvTol, TheCurve);
-
- }
- else {
-
- NbElem = 1;
- TheCurve = new FEmTool_Curve(myDimension, NbElem, TheBase, CurvTol);
- TheCurve->Knots().SetValue(TheCurve->Knots().Lower(),
- myParameters->Value(myFirstPoint));
- TheCurve->Knots().SetValue(TheCurve->Knots().Upper(),
- myParameters->Value(myLastPoint));
-
- }
-
- mySmoothCriterion->SetCurve(TheCurve);
-
- return;
-
-}
-
-//
-//=======================================================================
-//function : InitParameters
-//purpose : Calculation of initial estimation of the multicurve's length
-// and parameters for multipoints.
-//=======================================================================
-//
-void AppParCurves_Variational::InitParameters(Standard_Real& Length)
-{
-
- const Standard_Real Eps1 = Precision::Confusion() * .01;
-
- Standard_Real aux, dist;
- Standard_Integer i, i0, i1 = 0, ipoint;
-
-
- Length = 0.;
- myParameters->SetValue(myFirstPoint, Length);
-
- for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint; ipoint++) {
- i0 = i1; i1 += myDimension;
- dist = 0;
- for(i = 1; i <= myDimension; i++) {
- aux = myTabPoints->Value(i1 + i) - myTabPoints->Value(i0 + i);
- dist += aux * aux;
- }
- Length += Sqrt(dist);
- myParameters->SetValue(ipoint, Length);
- }
-
-
- if(Length <= Eps1)
- Standard_ConstructionError::Raise("AppParCurves_Variational::InitParameters");
-
-
- for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint - 1; ipoint++)
- myParameters->SetValue(ipoint, myParameters->Value(ipoint) / Length);
-
- myParameters->SetValue(myLastPoint, 1.);
-
- // Avec peu de point il y a sans doute sous estimation ...
- if(myNbPoints < 10) Length *= (1. + 0.1 / (myNbPoints - 1));
-}
-
-//
-//=======================================================================
-//function : InitCriterionEstimations
-//purpose : Calculation of initial estimation of the linear criteria
-//
-//=======================================================================
-//
-void AppParCurves_Variational::InitCriterionEstimations(const Standard_Real Length,
- Standard_Real& E1,
- Standard_Real& E2,
- Standard_Real& E3) const
-{
- E1 = Length * Length;
-
- const Standard_Real Eps1 = Precision::Confusion() * .01;
-
- math_Vector VTang1(1, myDimension), VTang2(1, myDimension), VTang3(1, myDimension),
- VScnd1(1, myDimension), VScnd2(1, myDimension), VScnd3(1, myDimension);
-
- // ========== Treatment of first point =================
-
- Standard_Integer ipnt = myFirstPoint;
-
- EstTangent(ipnt, VTang1);
- ipnt++;
- EstTangent(ipnt, VTang2);
- ipnt++;
- EstTangent(ipnt, VTang3);
-
- ipnt = myFirstPoint;
- EstSecnd(ipnt, VTang1, VTang2, Length, VScnd1);
- ipnt++;
- EstSecnd(ipnt, VTang1, VTang3, Length, VScnd2);
-
-// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 Begin
-// Standard_Real Delta = .5 * (myParameters->Value(ipnt) - myParameters->Value(--ipnt));
- Standard_Integer anInd = ipnt;
- Standard_Real Delta = .5 * (myParameters->Value(anInd) - myParameters->Value(--ipnt));
-// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 End
-
- if(Delta <= Eps1) Delta = 1.;
-
- E2 = VScnd1.Norm2() * Delta;
-
- E3 = (Delta > Eps1) ? VScnd2.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
- // ========== Treatment of internal points =================
-
- Standard_Integer CurrPoint = 2;
-
- for(ipnt = myFirstPoint + 1; ipnt < myLastPoint; ipnt++) {
-
- Delta = .5 * (myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1));
-
- if(CurrPoint == 1) {
- if(ipnt + 1 != myLastPoint) {
- EstTangent(ipnt + 2, VTang3);
- EstSecnd(ipnt + 1, VTang1, VTang3, Length, VScnd2);
- }
- else
- EstSecnd(ipnt + 1, VTang1, VTang2, Length, VScnd2);
-
- E2 += VScnd1.Norm2() * Delta;
- E3 += (Delta > Eps1) ? VScnd2.Subtracted(VScnd3).Norm2() / (4. * Delta) : 0.;
-
- }
- else if(CurrPoint == 2) {
- if(ipnt + 1 != myLastPoint) {
- EstTangent(ipnt + 2, VTang1);
- EstSecnd(ipnt + 1, VTang2, VTang1, Length, VScnd3);
- }
- else
- EstSecnd(ipnt + 1, VTang2, VTang3, Length, VScnd3);
-
- E2 += VScnd2.Norm2() * Delta;
- E3 += (Delta > Eps1) ? VScnd3.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
-
- }
- else {
- if(ipnt + 1 != myLastPoint) {
- EstTangent(ipnt + 2, VTang2);
- EstSecnd(ipnt + 1, VTang3, VTang2, Length, VScnd1);
- }
- else
- EstSecnd(ipnt + 1, VTang3, VTang1, Length, VScnd1);
-
- E2 += VScnd3.Norm2() * Delta;
- E3 += (Delta > Eps1) ? VScnd1.Subtracted(VScnd2).Norm2() / (4. * Delta) : 0.;
-
- }
-
- CurrPoint++; if(CurrPoint == 4) CurrPoint = 1;
- }
-
- // ========== Treatment of last point =================
-
- Delta = .5 * (myParameters->Value(myLastPoint) - myParameters->Value(myLastPoint - 1));
- if(Delta <= Eps1) Delta = 1.;
-
- Standard_Real aux;
-
- if(CurrPoint == 1) {
-
- E2 += VScnd1.Norm2() * Delta;
- aux = VScnd1.Subtracted(VScnd3).Norm2();
- E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
-
- }
- else if(CurrPoint == 2) {
-
- E2 += VScnd2.Norm2() * Delta;
- aux = VScnd2.Subtracted(VScnd1).Norm2();
- E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
-
- }
- else {
-
- E2 += VScnd3.Norm2() * Delta;
- aux = VScnd3.Subtracted(VScnd2).Norm2();
- E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
-
- }
-
- aux = Length * Length;
-
- E2 *= aux; E3 *= aux;
-
-
-}
-
-//
-//=======================================================================
-//function : EstTangent
-//purpose : Calculation of estimation of the Tangent
-// (see fortran routine MMLIPRI)
-//=======================================================================
-//
-
-void AppParCurves_Variational::EstTangent(const Standard_Integer ipnt,
- math_Vector& VTang) const
-
-{
- Standard_Integer i ;
- const Standard_Real Eps1 = Precision::Confusion() * .01;
- const Standard_Real EpsNorm = 1.e-9;
-
- Standard_Real Wpnt = 1.;
-
-
- if(ipnt == myFirstPoint) {
- // Estimation at first point
- if(myNbPoints < 3)
- Wpnt = 0.;
- else {
-
- Standard_Integer adr1 = 1, adr2 = adr1 + myDimension,
- adr3 = adr2 + myDimension;
-
- math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
- math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
- math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
-
- // Parabolic interpolation
- // if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
- // first derivative for t=0 is A1 = ((d2-1)*P1 + P2 - d2*P3)/(d*(1-d))
- // d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*d
- Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
- Standard_Real V2 = 0.;
- if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
- if(V2 > Eps1) {
- Standard_Real d = V1 / (V1 + V2), d1;
- d1 = 1. / (d * (1 - d)); d *= d;
- VTang = ((d - 1.) * Pnt1 + Pnt2 - d * Pnt3) * d1;
- }
- else {
- // Simple 2-point estimation
-
- VTang = Pnt2 - Pnt1;
- }
- }
- }
- else if (ipnt == myLastPoint) {
- // Estimation at last point
- if(myNbPoints < 3)
- Wpnt = 0.;
- else {
-
- Standard_Integer adr1 = (myLastPoint - 3) * myDimension + 1,
- adr2 = adr1 + myDimension,
- adr3 = adr2 + myDimension;
-
- math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
- math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
- math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
-
- // Parabolic interpolation
- // if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
- // first derivative for t=1 is 2*A2 + A1 = ((d2+1)*P1 - P2 - d2*P3)/(d*(1-d))
- // d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*(d-2)
- Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
- Standard_Real V2 = 0.;
- if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
- if(V2 > Eps1) {
- Standard_Real d = V1 / (V1 + V2), d1;
- d1 = 1. / (d * (1 - d)); d *= d - 2;
- VTang = ((d + 1.) * Pnt1 - Pnt2 - d * Pnt3) * d1;
- }
- else {
- // Simple 2-point estimation
-
- VTang = Pnt3 - Pnt2;
- }
- }
- }
- else {
-
- Standard_Integer adr1 = (ipnt - myFirstPoint - 1) * myDimension + 1,
- adr2 = adr1 + 2 * myDimension;
-
- math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
- math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
-
- VTang = Pnt2 - Pnt1;
-
- }
-
- Standard_Real Vnorm = VTang.Norm();
-
- if(Vnorm <= EpsNorm)
- VTang.Init(0.);
- else
- VTang /= Vnorm;
-
- // Estimation with constraints
-
- Standard_Real Wcnt = 0.;
- Standard_Integer IdCnt = 1;
-
-// Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
-
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
- math_Vector VCnt(1, myDimension, 0.);
-
- if(NbConstr > 0) {
-
- while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
- IdCnt <= NbConstr) IdCnt++;
- if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
- (myTypConstraints->Value(2 * IdCnt) >= 1)) {
- Wcnt = 1.;
- Standard_Integer i0 = 2 * myDimension * (IdCnt - 1), k = 0;
- for( i = 1; i <= myNbP3d; i++) {
- for(Standard_Integer j = 1; j <= 3; j++)
- VCnt(++k) = myTabConstraints->Value(++i0);
- i0 += 3;
- }
- for(i = 1; i <= myNbP2d; i++) {
- for(Standard_Integer j = 1; j <= 2; j++)
- VCnt(++k) = myTabConstraints->Value(++i0);
- i0 += 2;
- }
- }
- }
-
- // Averaging of estimation
-
- Standard_Real Denom = Wpnt + Wcnt;
- if(Denom == 0.) Denom = 1.;
- else Denom = 1. / Denom;
-
- VTang = (Wpnt * VTang + Wcnt * VCnt) * Denom;
-
- Vnorm = VTang.Norm();
-
- if(Vnorm <= EpsNorm)
- VTang.Init(0.);
- else
- VTang /= Vnorm;
-
-
-}
-
-//
-//=======================================================================
-//function : EstSecnd
-//purpose : Calculation of estimation of the second derivative
-// (see fortran routine MLIMSCN)
-//=======================================================================
-//
-void AppParCurves_Variational::EstSecnd(const Standard_Integer ipnt,
- const math_Vector& VTang1,
- const math_Vector& VTang2,
- const Standard_Real Length,
- math_Vector& VScnd) const
-{
- Standard_Integer i ;
-
- const Standard_Real Eps = 1.e-9;
-
- Standard_Real Wpnt = 1.;
-
- Standard_Real aux;
-
- if(ipnt == myFirstPoint)
- aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt);
- else if(ipnt == myLastPoint)
- aux = myParameters->Value(ipnt) - myParameters->Value(ipnt - 1);
- else
- aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1);
-
- if(aux <= Eps)
- aux = 1.;
- else
- aux = 1. / aux;
-
- VScnd = (VTang2 - VTang1) * aux;
-
- // Estimation with constraints
-
- Standard_Real Wcnt = 0.;
- Standard_Integer IdCnt = 1;
-
-// Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
-
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
- math_Vector VCnt(1, myDimension, 0.);
-
- if(NbConstr > 0) {
-
- while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
- IdCnt <= NbConstr) IdCnt++;
-
- if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
- (myTypConstraints->Value(2 * IdCnt) >= 2)) {
- Wcnt = 1.;
- Standard_Integer i0 = 2 * myDimension * (IdCnt - 1) + 3, k = 0;
- for( i = 1; i <= myNbP3d; i++) {
- for(Standard_Integer j = 1; j <= 3; j++)
- VCnt(++k) = myTabConstraints->Value(++i0);
- i0 += 3;
- }
- i0--;
- for(i = 1; i <= myNbP2d; i++) {
- for(Standard_Integer j = 1; j <= 2; j++)
- VCnt(++k) = myTabConstraints->Value(++i0);
- i0 += 2;
- }
- }
- }
-
- // Averaging of estimation
-
- Standard_Real Denom = Wpnt + Wcnt;
- if(Denom == 0.) Denom = 1.;
- else Denom = 1. / Denom;
-
- VScnd = (Wpnt * VScnd + (Wcnt * Length) * VCnt) * Denom;
-
-}
-
-
-//
-//=======================================================================
-//function : InitCutting
-//purpose : Realisation of curve's cutting a priory accordingly to
-// constraints (see fortran routine MLICUT)
-//=======================================================================
-//
-void AppParCurves_Variational::InitCutting(const Handle(PLib_Base)& aBase,
- const Standard_Real CurvTol,
- Handle(FEmTool_Curve)& aCurve) const
-{
-
- // Definition of number of elements
- Standard_Integer ORCMx = -1, NCont = 0, i, kk, NbElem;
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
-
- for(i = 1; i <= NbConstr; i++) {
- kk = Abs(myTypConstraints->Value(2 * i)) + 1;
- ORCMx = Max(ORCMx, kk);
- NCont += kk;
- }
-
- if(ORCMx > myMaxDegree - myNivCont)
- Standard_ConstructionError::Raise("AppParCurves_Variational::InitCutting");
-
- Standard_Integer NLibre = Max(myMaxDegree - myNivCont - (myMaxDegree + 1) / 4,
- myNivCont + 1);
-
- NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
-
- while((NbElem > myMaxSegment) && (NLibre < myMaxDegree - myNivCont)) {
-
- NLibre++;
- NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
-
- }
-
-
- if(NbElem > myMaxSegment)
- Standard_ConstructionError::Raise("AppParCurves_Variational::InitCutting");
-
-
- aCurve = new FEmTool_Curve(myDimension, NbElem, aBase, CurvTol);
-
- Standard_Integer NCnt = (NCont - 1) / NbElem + 1;
- Standard_Integer NPlus = NbElem - (NCnt * NbElem - NCont);
-
- TColStd_Array1OfReal& Knot = aCurve->Knots();
-
- Standard_Integer IDeb = 0, IFin = NbConstr + 1,
- NDeb = 0, NFin = 0,
- IndEl = Knot.Lower(), IUpper = Knot.Upper(),
- NbEl = 0;
-
-
- Knot(IndEl) = myParameters->Value(myFirstPoint);
- Knot(IUpper) = myParameters->Value(myLastPoint);
-
- while(NbElem - NbEl > 1) {
-
- IndEl++; NbEl++;
- if(NPlus == 0) NCnt--;
-
- while(NDeb < NCnt && IDeb < IFin) {
- IDeb++;
- NDeb += Abs(myTypConstraints->Value(2 * IDeb)) + 1;
- }
-
- if(NDeb == NCnt) {
- NDeb = 0;
- if(NPlus == 1 &&
- myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) > Knot(IndEl - 1))
-
- Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
- else
- Knot(IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) +
- myParameters->Value(myTypConstraints->Value(2 * IDeb + 1))) / 2;
-
- }
- else {
- NDeb -= NCnt;
- Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
- }
-
- NPlus--;
- if(NPlus == 0) NCnt--;
-
- if(NbElem - NbEl == 1) break;
-
- NbEl++;
-
- while(NFin < NCnt && IDeb < IFin) {
- IFin--;
- NFin += Abs(myTypConstraints->Value(2 * IFin)) + 1;
- }
-
- if(NFin == NCnt) {
- NFin = 0;
- Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
- myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
- }
- else {
- NFin -= NCnt;
- if(myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) < Knot(IUpper - IndEl + 1))
- Knot(IUpper + 1 - IndEl) = myParameters->Value(myTypConstraints->Value(2 * IFin - 1));
- else
- Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
- myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
- }
-
- }
-
-
-}
+++ /dev/null
-// Created on: 1997-09-17
-// Created by: Philippe MANGIN
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//====================== Private Methodes =============================//
-//=======================================================================
-//function : Adjusting
-//purpose : Smoothing's adjusting like STRIM routine "MAJLIS"
-//=======================================================================
-void AppParCurves_Variational::Adjusting(
- Handle(AppParCurves_SmoothCriterion)& J,
- Standard_Real& WQuadratic,
- Standard_Real& WQuality,
- Handle(FEmTool_Curve)& TheCurve,
- TColStd_Array1OfReal& Ecarts)
-{
-
-// cout << "=========== Adjusting =============" << endl;
-
- /* Initialized data */
-
- const Standard_Integer mxiter = 2;
- const Standard_Real eps1 = 1e-6;
- Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
- Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
- Standard_Real CurvTol = eps1 * J->EstLength() / NbrPnt;
-
-
- /* Local variables */
- Standard_Integer iter, ipnt;
- Standard_Real ecart, emold, erold, tpara;
- Standard_Real vocri[4], j1cibl, vtest, vseuil;
- Standard_Integer i, numint, flag;
- TColStd_Array1OfReal tbpoid(myFirstPoint, myLastPoint);
- Standard_Boolean loptim, lrejet;
- Handle(AppParCurves_SmoothCriterion) JNew;
- Handle(FEmTool_Curve) CNew;
- Standard_Real E1, E2, E3;
-
-
-/* (0.b) Initialisations */
-
- loptim = Standard_True;
- iter = 0;
- tbpoid.Init(1.);
-
-
-/* ============ boucle sur le moteur de lissage ============== */
-
- vtest = WQuality * .9;
- j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
-
- while(loptim) {
-
- ++iter;
-
-/* (1) Sauvegarde de l'etat precedents */
-
- vocri[0] = myCriterium[0];
- vocri[1] = myCriterium[1];
- vocri[2] = myCriterium[2];
- vocri[3] = myCriterium[3];
- erold = myMaxError;
- emold = myAverageError;
-
-/* (2) Augmentation du poids des moindre carre */
-
- if (j1cibl > vtest) {
- WQuadratic = j1cibl / vtest * WQuadratic;
- }
-
-/* (3) Augmentation du poid associe aux points a problemes */
-
- vseuil = WQuality * .88;
-
- for (ipnt = myFirstPoint; ipnt <= myLastPoint; ++ipnt) {
- if (Ecarts(ipnt) > vtest) {
- ecart = (Ecarts(ipnt) - vseuil) / WQuality;
- tbpoid(ipnt) = (ecart * 3 + 1.) * tbpoid(ipnt);
- }
- }
-
-/* (4) Decoupe force */
-
- if (TheCurve->NbElements() < myMaxSegment && myWithCutting) {
-
- numint = NearIndex(myParameters->Value(myMaxErrorIndex), TheCurve->Knots(), 0, flag);
-
- tpara = (TheCurve->Knots()(numint) + TheCurve->Knots()(numint + 1) +
- myParameters->Value(myMaxErrorIndex) * 2) / 4;
-
- CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements() + 1,
- TheCurve->Base(), CurvTol);
-
- for(i = 1; i <= numint; i++) CNew->Knots()(i) = TheCurve->Knots()(i);
- for(i = numint + 1; i <= TheCurve->Knots().Length(); i++)
- CNew->Knots()(i + 1) = TheCurve->Knots()(i);
-
- CNew->Knots()(numint + 1) = tpara;
-
- } else {
-
- CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements(), TheCurve->Base(), CurvTol);
-
- CNew->Knots() = TheCurve->Knots();
- }
-
-
- JNew = new AppParCurves_MyCriterion(mySSP, myFirstPoint, myLastPoint);
-
- JNew->EstLength() = J->EstLength();
-
- J->GetEstimation(E1, E2, E3);
-
- JNew->SetEstimation(E1, E2, E3);
-
- JNew->SetParameters(myParameters);
-
- JNew->SetWeight(WQuadratic, WQuality, myPercent[0], myPercent[1], myPercent[2]);
-
- JNew->SetWeight(tbpoid);
-
- JNew->SetCurve(CNew);
-
-/* (5) Relissage */
-
- TheMotor(JNew, WQuadratic, WQuality, CNew, Ecarts);
-
-/* (6) Tests de rejet */
-
- j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
- vseuil = Sqrt(vocri[1]) + (erold - myMaxError) * 4;
-
- lrejet = ((myMaxError > WQuality) && (myMaxError > erold * 1.01)) || (Sqrt(myCriterium[1]) > vseuil * 1.05);
-
- if (lrejet) {
- myCriterium[0] = vocri[0];
- myCriterium[1] = vocri[1];
- myCriterium[2] = vocri[2];
- myCriterium[3] = vocri[3];
- myMaxError = erold;
- myAverageError = emold;
-
- loptim = Standard_False;
- }
- else {
- J = JNew;
- TheCurve = CNew;
- J->SetCurve(TheCurve);
- }
-
-/* (7) Test de convergence */
-
- if (((iter >= mxiter) && (myMaxSegment == CNew->NbElements())) || myMaxError < WQuality) {
- loptim = Standard_False;
- }
-
- }
-
-
-}
-
-
-
-
-
+++ /dev/null
-// Created on: 1999-02-15
-// Created by: Igor FEOKTISTOV
-// Copyright (c) 1999-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <PLib_Base.hxx>
-#include <PLib_JacobiPolynomial.hxx>
-#include <PLib_HermitJacobi.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <math_Vector.hxx>
-
-void AppParCurves_Variational::AssemblingConstraints(const Handle(FEmTool_Curve)& Curve,
- const TColStd_Array1OfReal& Parameters,
- const Standard_Real CBLONG,
- FEmTool_Assembly& A ) const
-{
-
- Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
- NbElm = Curve->NbElements(),
- NbDim = Curve->Dimension();
-
- TColStd_Array1OfReal G0(0, MxDeg), G1(0, MxDeg), G2(0, MxDeg);
- math_Vector V0((Standard_Real*)&G0(0), 0, MxDeg),
- V1((Standard_Real*)&G1(0), 0, MxDeg),
- V2((Standard_Real*)&G2(0), 0, MxDeg);
-
- Standard_Integer IndexOfConstraint, Ng3d, Ng2d, NBeg2d, NPass, NgPC1,
- NTang3d, NTang2d,
- Point, TypOfConstr,
- p0 = Parameters.Lower() - myFirstPoint,
- curel = 1, el, i, ipnt, ityp, j, k, pnt, curdim,
- jt, Ntheta = 6 * myNbP3d + 2 * myNbP2d;
- Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
-
-// Ng3d = 3 * NbConstr + 2 * myNbTangPoints + 5 * myNbCurvPoints;
-// Ng2d = 2 * NbConstr + 1 * myNbTangPoints + 3 * myNbCurvPoints;
- Ng3d = 3 * NbConstr + 3 * myNbTangPoints + 5 * myNbCurvPoints;
- Ng2d = 2 * NbConstr + 2 * myNbTangPoints + 3 * myNbCurvPoints;
- NBeg2d = Ng3d * myNbP3d;
-// NgPC1 = NbConstr + myNbCurvPoints;
- NgPC1 = NbConstr + myNbTangPoints + myNbCurvPoints;
- NPass = 0;
- NTang3d = 3 * NgPC1;
- NTang2d = 2 * NgPC1;
-
- TColStd_Array1OfReal& Intervals = Curve->Knots();
-
- Standard_Real t, R1, R2;
-
- Handle(PLib_Base) myBase = Curve->Base();
- Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
- Standard_Integer Order = myHermitJacobi->NivConstr() + 1;
-
- Standard_Real UFirst, ULast, coeff, c0, mfact, mfact1;
-
- A.NullifyConstraint();
-
- ipnt = -1;
- ityp = 0;
- for(i = 1; i <= NbConstr; i++) {
-
- ipnt += 2; ityp += 2;
-
- Point = myTypConstraints->Value(ipnt);
- TypOfConstr = myTypConstraints->Value(ityp);
-
- t = Parameters(p0 + Point);
-
- for(el = curel; el <= NbElm; ) {
- if( t <= Intervals(++el) ) {
- curel = el - 1;
- break;
- }
- }
-
-
- UFirst = Intervals(curel); ULast = Intervals(curel + 1);
- coeff = (ULast - UFirst)/2.; c0 = (ULast + UFirst)/2.;
-
- t = (t - c0) / coeff;
-
- if(TypOfConstr == 0) {
- myBase->D0(t, G0);
- for(k = 1; k < Order; k++) {
- mfact = Pow(coeff, k);
- G0(k) *= mfact;
- G0(k + Order) *= mfact;
- }
- }
- else if(TypOfConstr == 1) {
- myBase->D1(t, G0, G1);
- for(k = 1; k < Order; k++) {
- mfact = Pow(coeff, k);
- G0(k) *= mfact;
- G0(k + Order) *= mfact;
- G1(k) *= mfact;
- G1(k + Order) *= mfact;
- }
- mfact = 1./coeff;
- for(k = 0; k <= MxDeg; k++) {
- G1(k) *= mfact;
- }
- }
- else {
- myBase->D2(t, G0, G1, G2);
- for(k = 1; k < Order; k++) {
- mfact = Pow(coeff, k);
- G0(k) *= mfact;
- G0(k + Order) *= mfact;
- G1(k) *= mfact;
- G1(k + Order) *= mfact;
- G2(k) *= mfact;
- G2(k + Order) *= mfact;
- }
- mfact = 1. / coeff;
- mfact1 = mfact / coeff;
- for(k = 0; k <= MxDeg; k++) {
- G1(k) *= mfact;
- G2(k) *= mfact1;
- }
- }
-
- NPass++;
-
- j = NbDim * (Point - myFirstPoint);
- Standard_Integer n0 = NPass;
- curdim = 0;
- for(pnt = 1; pnt <= myNbP3d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 3; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- j +=3;
- n0 += Ng3d;
- }
-
- n0 = NPass + NBeg2d;
- for(pnt = 1; pnt <= myNbP2d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 2; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- j +=2;
- n0 += Ng2d;
- }
-
-/* if(TypOfConstr == 1) {
-
- IndexOfConstraint = NTang3d + 1;
- jt = Ntheta * (i - 1);
- for(pnt = 1; pnt <= myNbP3d; pnt++) {
- for(k = 1; k <= 3; k++) {
- A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
- A.AddConstraint(IndexOfConstraint + 1, curel, k, myTtheta->Value(jt + 3 + k) * V1, 0.);
- }
- IndexOfConstraint += Ng3d;
- jt += 6;
- }
-
- IndexOfConstraint = NBeg2d + NTang2d + 1;
- for(pnt = 1; pnt <= myNbP2d; pnt++) {
- for(k = 1; k <= 2; k++) {
- A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
- }
- IndexOfConstraint += Ng2d;
- jt += 2;
- }
-
- NTang3d += 2;
- NTang2d += 1;
- } */
- if(TypOfConstr == 1) {
-
- NPass++;
- n0 = NPass;
- j = 2 * NbDim * (i - 1);
- curdim = 0;
- for(pnt = 1; pnt <= myNbP3d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 3; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- n0 += Ng3d;
- j += 6;
- }
-
- n0 = NPass + NBeg2d;
- for(pnt = 1; pnt <= myNbP2d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 2; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- n0 += Ng2d;
- j += 4;
- }
- }
- if(TypOfConstr == 2) {
-
- NPass++;
- n0 = NPass;
- j = 2 * NbDim * (i - 1);
- curdim = 0;
- for(pnt = 1; pnt <= myNbP3d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 3; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- n0 += Ng3d;
- j += 6;
- }
-
- n0 = NPass + NBeg2d;
- for(pnt = 1; pnt <= myNbP2d; pnt++) {
- IndexOfConstraint = n0;
- for(k = 1; k <= 2; k++) {
- curdim++;
- A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
- IndexOfConstraint += NgPC1;
- }
- n0 += Ng2d;
- j += 4;
- }
-
- j = 2 * NbDim * (i - 1) + 3;
- jt = Ntheta * (i - 1);
- IndexOfConstraint = NTang3d + 1;
- curdim = 0;
- for(pnt = 1; pnt <= myNbP3d; pnt++) {
- R1 = 0.; R2 = 0.;
- for(k = 1; k <= 3; k++) {
- R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
- R2 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + 3 + k);
- }
- R1 *= CBLONG * CBLONG;
- R2 *= CBLONG * CBLONG;
- for(k = 1; k <= 3; k++) {
- curdim++;
- if(k > 1) R1 = R2 = 0.;
- A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
- A.AddConstraint(IndexOfConstraint + 1, curel, curdim, myTfthet->Value(jt + 3 + k) * V2, R2);
- }
- IndexOfConstraint += Ng3d;
- j += 6;
- jt += 6;
- }
-
- j--;
- IndexOfConstraint = NBeg2d + NTang2d + 1;
- for(pnt = 1; pnt <= myNbP2d; pnt++) {
- R1 = 0.;
- for(k = 1; k <= 2; k++) {
- R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
- }
- R1 *= CBLONG * CBLONG;
- for(k = 1; k <= 2; k++) {
- curdim++;
- if(k > 1) R1 = 0.;
- A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
- }
- IndexOfConstraint += Ng2d;
- j += 4;
- jt += 2;
- }
-
- NTang3d += 2;
- NTang2d += 1;
- }
-
- }
-
-}
+++ /dev/null
-// Created on: 1999-02-19
-// Created by: Sergey KHROMOV
-// Copyright (c) 1999-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-static Standard_Boolean NotParallel(gp_Vec& T, gp_Vec& V)
-{
- V = T;
- V.SetX(V.X() + 1.);
- if (V.CrossMagnitude(T) > 1.e-12)
- return Standard_True;
- V.SetY(V.Y() + 1.);
- if (V.CrossMagnitude(T) > 1.e-12)
- return Standard_True;
- V.SetZ(V.Z() + 1.);
- if (V.CrossMagnitude(T) > 1.e-12)
- return Standard_True;
- return Standard_False;
-}
-
- Standard_Boolean AppParCurves_Variational::InitTthetaF(const Standard_Integer ndimen,
- const AppParCurves_Constraint typcon,
- const Standard_Integer begin,
- const Standard_Integer jndex)
-{
- if ((ndimen < 2)||(ndimen >3))
- return Standard_False;
- gp_Vec T, V;
- gp_Vec theta1, theta2;
- gp_Vec F;
- Standard_Real XX, XY, YY, XZ, YZ, ZZ;
-
- if ((typcon == AppParCurves_TangencyPoint)||(typcon == AppParCurves_CurvaturePoint))
- {
- T.SetX(myTabConstraints->Value(jndex));
- T.SetY(myTabConstraints->Value(jndex + 1));
- if (ndimen == 3)
- T.SetZ(myTabConstraints->Value(jndex + 2));
- else
- T.SetZ(0.);
- if (ndimen == 2)
- {
- V.SetX(0.);
- V.SetY(0.);
- V.SetZ(1.);
- }
- if (ndimen == 3)
- if (!NotParallel(T, V))
- return Standard_False;
- theta1 = V ^ T;
- theta1.Normalize();
- myTtheta->SetValue(begin, theta1.X());
- myTtheta->SetValue(begin + 1, theta1.Y());
- if (ndimen == 3)
- {
- theta2 = T ^ theta1;
- theta2.Normalize();
- myTtheta->SetValue(begin + 2, theta1.Z());
- myTtheta->SetValue(begin + 3, theta2.X());
- myTtheta->SetValue(begin + 4, theta2.Y());
- myTtheta->SetValue(begin + 5, theta2.Z());
- }
-
- // Calculation of myTfthet
- if (typcon == AppParCurves_CurvaturePoint)
- {
- XX = Pow(T.X(), 2);
- XY = T.X() * T.Y();
- YY = Pow(T.Y(), 2);
- if (ndimen == 2)
- {
- F.SetX(YY * theta1.X() - XY * theta1.Y());
- F.SetY(XX * theta1.Y() - XY * theta1.X());
- myTfthet->SetValue(begin, F.X());
- myTfthet->SetValue(begin + 1, F.Y());
- }
- if (ndimen == 3)
- {
- XZ = T.X() * T.Z();
- YZ = T.Y() * T.Z();
- ZZ = Pow(T.Z(), 2);
-
- F.SetX((ZZ + YY) * theta1.X() - XY * theta1.Y() - XZ * theta1.Z());
- F.SetY((XX + ZZ) * theta1.Y() - XY * theta1.X() - YZ * theta1.Z());
- F.SetZ((XX + YY) * theta1.Z() - XZ * theta1.X() - YZ * theta1.Y());
- myTfthet->SetValue(begin, F.X());
- myTfthet->SetValue(begin + 1, F.Y());
- myTfthet->SetValue(begin + 2, F.Z());
- F.SetX((ZZ + YY) * theta2.X() - XY * theta2.Y() - XZ * theta2.Z());
- F.SetY((XX + ZZ) * theta2.Y() - XY * theta2.X() - YZ * theta2.Z());
- F.SetZ((XX + YY) * theta2.Z() - XZ * theta2.X() - YZ * theta2.Y());
- myTfthet->SetValue(begin + 3, F.X());
- myTfthet->SetValue(begin + 4, F.Y());
- myTfthet->SetValue(begin + 5, F.Z());
- }
- }
- }
- return Standard_True;
-}
+++ /dev/null
-AppParCurves_Variational_1.gxx
-AppParCurves_Variational_2.gxx
-AppParCurves_Variational_3.gxx
-AppParCurves_Variational_4.gxx
-AppParCurves_Variational_5.gxx
-AppParCurves_Variational_6.gxx
-AppParCurves_Variational_7.gxx
-AppParCurves_Variational_8.gxx
-AppParCurves_Variational_9.gxx
#include <math_Vector.hxx>
#include <AppDef_MultiPointConstraint.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
-#include <AppDef_TheVariational.hxx>
+#include <AppDef_Variational.hxx>
//=======================================================================
}
- AppDef_TheVariational Variation(multL, 1, NbPoint, TABofCC);
+ AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
//===================================
Standard_Integer theMaxSegments = 1000;
#include <AppDef_MultiPointConstraint.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
#include <AppParCurves_Constraint.hxx>
-#include <AppDef_TheVariational.hxx>
+#include <AppDef_Variational.hxx>
//=======================================================================
}
- AppDef_TheVariational Variation(multL, 1, NbPoint, TABofCC);
+ AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
//===================================
Standard_Integer theMaxSegments = 1000;
#include <math_Vector.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
#include <AppParCurves_ConstraintCouple.hxx>
-#include <AppDef_TheVariational.hxx>
+#include <AppDef_Variational.hxx>
//=======================================================================
}
- AppDef_TheVariational Variation(Line, 1, NbPointJ, TABofCC);
+ AppDef_Variational Variation(Line, 1, NbPointJ, TABofCC);
//===================================
Standard_Integer theMaxSegments = 1000;
}
- AppDef_TheVariational Variation2(Line2, 1, NbPointI, TABofCC2);
+ AppDef_Variational Variation2(Line2, 1, NbPointI, TABofCC2);
Variation2.SetMaxDegree(DegMax);
Variation2.SetContinuity(Continuity);
#include <TColStd_HArray1OfBoolean.hxx>
#include <AppParCurves_MultiBSpCurve.hxx>
#include <AppDef_MultiLine.hxx>
-#include <AppDef_TheVariational.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
#include <AppParCurves_ConstraintCouple.hxx>
#include <GC_MakeSegment.hxx>
static Standard_Integer solutions(Draw_Interpretor& di,
- Geom2dGcc_Circ2d2TanRad& ct3, const char* name)
+ Geom2dGcc_Circ2d2TanRad& ct3, const char* name)
{
char solname[200];
}
static Standard_Integer solutions(Draw_Interpretor& di,
- Geom2dGcc_Circ2d3Tan& ct3, const char* name)
+ Geom2dGcc_Circ2d3Tan& ct3, const char* name)
{
char solname[200];
Standard_Boolean ip1 = DrawTrSurf::GetPoint2d(a[2],P1);
Standard_Boolean ip2 = DrawTrSurf::GetPoint2d(a[3],P2);
Standard_Boolean ip3 = DrawTrSurf::GetPoint2d(a[4],P3);
-
+
Standard_Real tol = Precision::Confusion();
if (n > 5) tol = Draw::Atof(a[5]);
if (!C2.IsNull()) {
// C-C-...
if (!C3.IsNull()) {
- // C-C-C
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C2),
- Geom2dGcc::Unqualified(C3),
- tol,0,0,0);
- return solutions(di,ct3,a[1]);
+ // C-C-C
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
+ Geom2dGcc::Unqualified(C2),
+ Geom2dGcc::Unqualified(C3),
+ tol,0,0,0);
+ return solutions(di,ct3,a[1]);
}
else if (ip3) {
- // C-C-P
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C2),
- new Geom2d_CartesianPoint(P3),
- tol,0,0);
- return solutions(di,ct3,a[1]);
+ // C-C-P
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
+ Geom2dGcc::Unqualified(C2),
+ new Geom2d_CartesianPoint(P3),
+ tol,0,0);
+ return solutions(di,ct3,a[1]);
}
else {
- // C-C-R
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C2),
- Draw::Atof(a[4]),tol);
- return solutions(di,ct3,a[1]);
+ // C-C-R
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
+ Geom2dGcc::Unqualified(C2),
+ Draw::Atof(a[4]),tol);
+ return solutions(di,ct3,a[1]);
}
}
else if (ip2) {
// C-P-..
if (!C3.IsNull()) {
- // C-P-C
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C3),
- new Geom2d_CartesianPoint(P2),
- tol,0,0);
- return solutions(di,ct3,a[1]);
- }
-
+ // C-P-C
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
+ Geom2dGcc::Unqualified(C3),
+ new Geom2d_CartesianPoint(P2),
+ tol,0,0);
+ return solutions(di,ct3,a[1]);
+ }
+
else if (ip3) {
- // C-P-P
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
- new Geom2d_CartesianPoint(P2),
- new Geom2d_CartesianPoint(P3),
- tol,0);
- return solutions(di,ct3,a[1]);
- }
-
+ // C-P-P
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C1),
+ new Geom2d_CartesianPoint(P2),
+ new Geom2d_CartesianPoint(P3),
+ tol,0);
+ return solutions(di,ct3,a[1]);
+ }
+
else {
- // C-P-R
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
- new Geom2d_CartesianPoint(P2),
- Draw::Atof(a[4]),tol);
- return solutions(di,ct3,a[1]);
+ // C-P-R
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
+ new Geom2d_CartesianPoint(P2),
+ Draw::Atof(a[4]),tol);
+ return solutions(di,ct3,a[1]);
}
}
else {
// C-R-..
if (!C3.IsNull()) {
- // C-R-C
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C3),
- Draw::Atof(a[3]),
- tol);
- return solutions(di,ct3,a[1]);
- }
-
+ // C-R-C
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
+ Geom2dGcc::Unqualified(C3),
+ Draw::Atof(a[3]),
+ tol);
+ return solutions(di,ct3,a[1]);
+ }
+
else if (ip3) {
- // C-R-P
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
- new Geom2d_CartesianPoint(P3),
- Draw::Atof(a[3]),
- tol);
- return solutions(di,ct3,a[1]);
- }
-
+ // C-R-P
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C1),
+ new Geom2d_CartesianPoint(P3),
+ Draw::Atof(a[3]),
+ tol);
+ return solutions(di,ct3,a[1]);
+ }
+
else {
- // C-R-R
- di << "Curve, radius, radius ???"<<"\n";
- return 1;
+ // C-R-R
+ di << "Curve, radius, radius ???"<<"\n";
+ return 1;
}
}
}
if (!C2.IsNull()) {
// P-C-...
if (!C3.IsNull()) {
- // P-C-C
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C2),
- Geom2dGcc::Unqualified(C3),
- new Geom2d_CartesianPoint(P1),
- tol,0,0);
- return solutions(di,ct3,a[1]);
+ // P-C-C
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C2),
+ Geom2dGcc::Unqualified(C3),
+ new Geom2d_CartesianPoint(P1),
+ tol,0,0);
+ return solutions(di,ct3,a[1]);
}
else if (ip3) {
- // P-C-P
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C2),
- new Geom2d_CartesianPoint(P1),
- new Geom2d_CartesianPoint(P3),
- tol,0);
- return solutions(di,ct3,a[1]);
+ // P-C-P
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C2),
+ new Geom2d_CartesianPoint(P1),
+ new Geom2d_CartesianPoint(P3),
+ tol,0);
+ return solutions(di,ct3,a[1]);
}
else {
- // P-C-R
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
- new Geom2d_CartesianPoint(P1),
- Draw::Atof(a[4]),tol);
- return solutions(di,ct3,a[1]);
+ // P-C-R
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
+ new Geom2d_CartesianPoint(P1),
+ Draw::Atof(a[4]),tol);
+ return solutions(di,ct3,a[1]);
}
}
else if (ip2) {
// P-P-..
if (!C3.IsNull()) {
- // P-P-C
- Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C3),
- new Geom2d_CartesianPoint(P1),
- new Geom2d_CartesianPoint(P2),
- tol,0);
- return solutions(di,ct3,a[1]);
- }
-
+ // P-P-C
+ Geom2dGcc_Circ2d3Tan ct3(Geom2dGcc::Unqualified(C3),
+ new Geom2d_CartesianPoint(P1),
+ new Geom2d_CartesianPoint(P2),
+ tol,0);
+ return solutions(di,ct3,a[1]);
+ }
+
else if (ip3) {
- // P-P-P
- Geom2dGcc_Circ2d3Tan ct3(new Geom2d_CartesianPoint(P1),
- new Geom2d_CartesianPoint(P2),
- new Geom2d_CartesianPoint(P3),
- tol);
- return solutions(di,ct3,a[1]);
- }
-
+ // P-P-P
+ Geom2dGcc_Circ2d3Tan ct3(new Geom2d_CartesianPoint(P1),
+ new Geom2d_CartesianPoint(P2),
+ new Geom2d_CartesianPoint(P3),
+ tol);
+ return solutions(di,ct3,a[1]);
+ }
+
else {
- // P-P-R
- Geom2dGcc_Circ2d2TanRad ct3(new Geom2d_CartesianPoint(P1),
- new Geom2d_CartesianPoint(P2),
- Draw::Atof(a[4]),tol);
- return solutions(di,ct3,a[1]);
+ // P-P-R
+ Geom2dGcc_Circ2d2TanRad ct3(new Geom2d_CartesianPoint(P1),
+ new Geom2d_CartesianPoint(P2),
+ Draw::Atof(a[4]),tol);
+ return solutions(di,ct3,a[1]);
}
}
else {
// P-R-..
if (!C3.IsNull()) {
- // P-R-C
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C3),
- new Geom2d_CartesianPoint(P1),
- Draw::Atof(a[3]),
- tol);
- return solutions(di,ct3,a[1]);
- }
-
+ // P-R-C
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C3),
+ new Geom2d_CartesianPoint(P1),
+ Draw::Atof(a[3]),
+ tol);
+ return solutions(di,ct3,a[1]);
+ }
+
else if (ip3) {
- // P-R-P
- Geom2dGcc_Circ2d2TanRad ct3(new Geom2d_CartesianPoint(P1),
- new Geom2d_CartesianPoint(P3),
- Draw::Atof(a[3]),
- tol);
- return solutions(di,ct3,a[1]);
- }
-
+ // P-R-P
+ Geom2dGcc_Circ2d2TanRad ct3(new Geom2d_CartesianPoint(P1),
+ new Geom2d_CartesianPoint(P3),
+ Draw::Atof(a[3]),
+ tol);
+ return solutions(di,ct3,a[1]);
+ }
+
else {
- // P-R-R
- di << "Point, radius, radius ???"<<"\n";
- return 1;
+ // P-R-R
+ di << "Point, radius, radius ???"<<"\n";
+ return 1;
}
}
}
if (!C2.IsNull()) {
// R-C-...
if (!C3.IsNull()) {
- // R-C-C
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
- Geom2dGcc::Unqualified(C3),
- Draw::Atof(a[2]),
- tol);
- return solutions(di,ct3,a[1]);
+ // R-C-C
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
+ Geom2dGcc::Unqualified(C3),
+ Draw::Atof(a[2]),
+ tol);
+ return solutions(di,ct3,a[1]);
}
else if (ip3) {
- // R-C-P
- Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
- new Geom2d_CartesianPoint(P3),
- Draw::Atof(a[2]),
- tol);
- return solutions(di,ct3,a[1]);
+ // R-C-P
+ Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C2),
+ new Geom2d_CartesianPoint(P3),
+ Draw::Atof(a[2]),
+ tol);
+ return solutions(di,ct3,a[1]);
}
else {
if (!C3.IsNull()) {
// R-P-C
Geom2dGcc_Circ2d2TanRad ct3(Geom2dGcc::Unqualified(C3),
- new Geom2d_CartesianPoint(P2),
- Draw::Atof(a[2]),
- tol);
+ new Geom2d_CartesianPoint(P2),
+ Draw::Atof(a[2]),
+ tol);
return solutions(di,ct3,a[1]);
}
-
+
else if (ip3)
{
// R-P-P
Geom2dGcc_Circ2d2TanRad ct3(new Geom2d_CartesianPoint(P2),
- new Geom2d_CartesianPoint(P3),
- Draw::Atof(a[2]),
- tol);
+ new Geom2d_CartesianPoint(P3),
+ Draw::Atof(a[2]),
+ tol);
return solutions(di,ct3,a[1]);
}
else {
}
Standard_Real ang = Draw::Atof(a[4]) * (M_PI / 180.0);
Geom2dGcc_Lin2dTanObl ct3(Geom2dGcc::Unqualified(C1),
- L->Lin2d(),
- Precision::Angular(),
- (C1->FirstParameter()+C1->LastParameter())/2.,
- ang);
+ L->Lin2d(),
+ Precision::Angular(),
+ (C1->FirstParameter()+C1->LastParameter())/2.,
+ ang);
if (ct3.IsDone()) {
for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
- Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
- Sprintf(solname,"%s_%d",a[1],i);
- char* temp = solname; // pour portage WNT
- DrawTrSurf::Set(temp,LS);
- di << solname << " ";
+ Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
+ Sprintf(solname,"%s_%d",a[1],i);
+ char* temp = solname; // pour portage WNT
+ DrawTrSurf::Set(temp,LS);
+ di << solname << " ";
}
}
else
}
else {
Geom2dGcc_Lin2d2Tan ct3(Geom2dGcc::Unqualified(C1),
- Geom2dGcc::Unqualified(C2),
- Precision::Angular(),
- (C1->FirstParameter()+C1->LastParameter())/2.,
- (C2->FirstParameter()+C2->LastParameter())/2.);
+ Geom2dGcc::Unqualified(C2),
+ Precision::Angular(),
+ (C1->FirstParameter()+C1->LastParameter())/2.,
+ (C2->FirstParameter()+C2->LastParameter())/2.);
if (ct3.IsDone()) {
for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
- Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
- Sprintf(solname,"%s_%d",a[1],i);
- char* temp = solname; // pour portage WNT
- DrawTrSurf::Set(temp,LS);
- di << solname << " ";
+ Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
+ Sprintf(solname,"%s_%d",a[1],i);
+ char* temp = solname; // pour portage WNT
+ DrawTrSurf::Set(temp,LS);
+ di << solname << " ";
}
}
else
gp_Pnt P;
gp_Pnt2d P2d;
Standard_Boolean newcurve;
-
+
if (dout.Is3D(id)) {
Handle(Draw_Marker3D) mark;
Handle(TColgp_HArray1OfPnt) Points = new TColgp_HArray1OfPnt(1, 1);
dout.Flush();
Handle(Geom_BSplineCurve) C;
i = 1;
-
+
while (b != 3) {
- dout.Select(id,XX,YY,b, Standard_False);
- P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
- ThePoints->SetValue(i+1, P);
- newcurve = Standard_False;
- if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
- if (b == 1) {
- i++;
- mark = new Draw_Marker3D(ThePoints->Value(i), Draw_X, Draw_vert);
- dout << mark;
- dout.Flush();
- Points =
- new TColgp_HArray1OfPnt(ThePoints->Lower(),ThePoints->Upper());
- Points->ChangeArray1() = ThePoints->Array1();
- newcurve = Standard_True;
- }
- GeomAPI_Interpolate anInterpolator(ThePoints,
- Standard_False,
- 1.0e-5);
- anInterpolator.Perform() ;
- if (anInterpolator.IsDone()) {
- C = anInterpolator.Curve() ;
- Handle(DrawTrSurf_BSplineCurve)
- DC = new DrawTrSurf_BSplineCurve(C);
- DC->ClearPoles();
- DC->ClearKnots();
- Draw::Set(a[1], DC);
- dout.RepaintView(id);
- }
- if (newcurve) {
- ThePoints = new TColgp_HArray1OfPnt(1, i+1);
- for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
- }
- }
+ dout.Select(id,XX,YY,b, Standard_False);
+ P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
+ ThePoints->SetValue(i+1, P);
+ newcurve = Standard_False;
+ if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
+ if (b == 1) {
+ i++;
+ mark = new Draw_Marker3D(ThePoints->Value(i), Draw_X, Draw_vert);
+ dout << mark;
+ dout.Flush();
+ Points =
+ new TColgp_HArray1OfPnt(ThePoints->Lower(),ThePoints->Upper());
+ Points->ChangeArray1() = ThePoints->Array1();
+ newcurve = Standard_True;
+ }
+ GeomAPI_Interpolate anInterpolator(ThePoints,
+ Standard_False,
+ 1.0e-5);
+ anInterpolator.Perform() ;
+ if (anInterpolator.IsDone()) {
+ C = anInterpolator.Curve() ;
+ Handle(DrawTrSurf_BSplineCurve)
+ DC = new DrawTrSurf_BSplineCurve(C);
+ DC->ClearPoles();
+ DC->ClearKnots();
+ Draw::Set(a[1], DC);
+ dout.RepaintView(id);
+ }
+ if (newcurve) {
+ ThePoints = new TColgp_HArray1OfPnt(1, i+1);
+ for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
+ }
+ }
}
GeomAPI_Interpolate anInterpolator(ThePoints,
- Standard_False,
- 1.0e-5);
+ Standard_False,
+ 1.0e-5);
anInterpolator.Perform() ;
if (anInterpolator.IsDone()) {
- C = anInterpolator.Curve() ;
- DrawTrSurf::Set(a[1], C);
- dout.RepaintView(id);
+ C = anInterpolator.Curve() ;
+ DrawTrSurf::Set(a[1], C);
+ dout.RepaintView(id);
}
}
else {
dout.Flush();
Handle(Geom2d_BSplineCurve) C;
i = 1;
-
+
while (b != 3) {
- dout.Select(id,XX,YY,b, Standard_False);
- P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
- ThePoints->SetValue(i+1, P2d);
- newcurve = Standard_False;
- if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
- if (b == 1) {
- i++;
- mark = new Draw_Marker2D(P2d, Draw_X, Draw_vert);
- dout << mark;
- dout.Flush();
- Points =
- new TColgp_HArray1OfPnt2d(ThePoints->Lower(),ThePoints->Upper());
- Points->ChangeArray1() = ThePoints->Array1();
- newcurve = Standard_True;
- }
+ dout.Select(id,XX,YY,b, Standard_False);
+ P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
+ ThePoints->SetValue(i+1, P2d);
+ newcurve = Standard_False;
+ if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
+ if (b == 1) {
+ i++;
+ mark = new Draw_Marker2D(P2d, Draw_X, Draw_vert);
+ dout << mark;
+ dout.Flush();
+ Points =
+ new TColgp_HArray1OfPnt2d(ThePoints->Lower(),ThePoints->Upper());
+ Points->ChangeArray1() = ThePoints->Array1();
+ newcurve = Standard_True;
+ }
Geom2dAPI_Interpolate a2dInterpolator(ThePoints,
- Standard_False,
- 1.0e-5) ;
+ Standard_False,
+ 1.0e-5) ;
a2dInterpolator.Perform() ;
if (a2dInterpolator.IsDone()) {
- C = a2dInterpolator.Curve() ;
-
- Handle(DrawTrSurf_BSplineCurve2d)
- DC = new DrawTrSurf_BSplineCurve2d(C);
- DC->ClearPoles();
- DC->ClearKnots();
- Draw::Set(a[1], DC);
- dout.RepaintView(id);
- }
-
- if (newcurve) {
- ThePoints = new TColgp_HArray1OfPnt2d(1, i+1);
- for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
- }
- }
+ C = a2dInterpolator.Curve() ;
+
+ Handle(DrawTrSurf_BSplineCurve2d)
+ DC = new DrawTrSurf_BSplineCurve2d(C);
+ DC->ClearPoles();
+ DC->ClearKnots();
+ Draw::Set(a[1], DC);
+ dout.RepaintView(id);
+ }
+
+ if (newcurve) {
+ ThePoints = new TColgp_HArray1OfPnt2d(1, i+1);
+ for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
+ }
+ }
}
Geom2dAPI_Interpolate a2dInterpolator(Points,
- Standard_False,
- 1.0e-5) ;
+ Standard_False,
+ 1.0e-5) ;
a2dInterpolator.Perform() ;
if (a2dInterpolator.IsDone()) {
- C = a2dInterpolator.Curve() ;
-
- DrawTrSurf::Set(a[1], C);
- dout.RepaintView(id);
+ C = a2dInterpolator.Curve() ;
+
+ DrawTrSurf::Set(a[1], C);
+ dout.RepaintView(id);
}
}
iFile >> dimen;
if (!strcmp(dimen,"3d")) {
Handle_TColgp_HArray1OfPnt Point =
- new TColgp_HArray1OfPnt(1, nbp);
+ new TColgp_HArray1OfPnt(1, nbp);
for (i = 1; i <= nbp; i++) {
- iFile >> x >> y >> z;
- Point->SetValue(i, gp_Pnt(x, y, z));
+ iFile >> x >> y >> z;
+ Point->SetValue(i, gp_Pnt(x, y, z));
}
GeomAPI_Interpolate anInterpolator(Point,
- Standard_False,
- 1.0e-5) ;
+ Standard_False,
+ 1.0e-5) ;
anInterpolator.Perform() ;
if (anInterpolator.IsDone()) {
- Handle(Geom_BSplineCurve) C =
- anInterpolator.Curve();
- DrawTrSurf::Set(a[1], C);
+ Handle(Geom_BSplineCurve) C =
+ anInterpolator.Curve();
+ DrawTrSurf::Set(a[1], C);
}
}
else if (!strcmp(dimen,"2d")) {
Handle(TColgp_HArray1OfPnt2d) PointPtr =
- new TColgp_HArray1OfPnt2d(1, nbp);
+ new TColgp_HArray1OfPnt2d(1, nbp);
for (i = 1; i <= nbp; i++) {
- iFile >> x >> y;
- PointPtr->SetValue(i, gp_Pnt2d(x, y));
+ iFile >> x >> y;
+ PointPtr->SetValue(i, gp_Pnt2d(x, y));
}
Geom2dAPI_Interpolate a2dInterpolator(PointPtr,
- Standard_False,
- 1.0e-5);
+ Standard_False,
+ 1.0e-5);
a2dInterpolator.Perform() ;
if (a2dInterpolator.IsDone()) {
- Handle(Geom2d_BSplineCurve) C = a2dInterpolator.Curve() ;
- DrawTrSurf::Set(a[1], C);
+ Handle(Geom2d_BSplineCurve) C = a2dInterpolator.Curve() ;
+ DrawTrSurf::Set(a[1], C);
}
}
}
}
static Standard_Integer tanginterpol (Draw_Interpretor& di,
- Standard_Integer n,
- const char** a)
+ Standard_Integer n,
+ const char** a)
{
Standard_Integer
ii,
jj,
-// num_knots,
-// degree,
+ // num_knots,
+ // degree,
num_tangents,
num_read,
num_start,
num_parameters ;
-
+
Standard_Real
-// delta,
+ // delta,
tolerance;
-// parameter ;
+ // parameter ;
- Standard_Boolean periodic_flag = Standard_False ;
- gp_Pnt a_point ;
- gp_Vec a_vector ;
- tolerance = 1.0e-5 ;
+ Standard_Boolean periodic_flag = Standard_False ;
+ gp_Pnt a_point ;
+ gp_Vec a_vector ;
+ tolerance = 1.0e-5 ;
}
Handle_TColgp_HArray1OfPnt PointsArrayPtr=
new TColgp_HArray1OfPnt(1,num_parameters) ;
-
+
num_tangents = ((n - num_read) / 3) - num_parameters ;
num_tangents = Max (0,num_tangents) ;
num_tangents = Min (num_parameters, num_tangents) ;
ii += 1 ;
}
GeomAPI_Interpolate anInterpolator(PointsArrayPtr,
- periodic_flag,
- tolerance) ;
+ periodic_flag,
+ tolerance) ;
if (num_tangents > 0) {
TColgp_Array1OfVec TangentsArray(1,num_parameters) ;
Handle_TColStd_HArray1OfBoolean
TangentFlagsPtr =
- new TColStd_HArray1OfBoolean(1,num_parameters) ;
-
+ new TColStd_HArray1OfBoolean(1,num_parameters) ;
+
for (ii = 1 ; ii <= num_tangents ; ii++) {
TangentFlagsPtr->SetValue(ii,Standard_True) ;
}
ii = 1 ;
while (ii <= num_tangents) {
for (jj = 1 ; jj <= 3 ; jj++) {
- a_vector.SetCoord(jj,Draw::Atof(a[num_read])) ;
- num_read += 1 ;
+ a_vector.SetCoord(jj,Draw::Atof(a[num_read])) ;
+ num_read += 1 ;
}
TangentsArray.SetValue(ii,a_vector) ;
ii += 1 ;
}
-
-
+
+
anInterpolator.Load(TangentsArray,
- TangentFlagsPtr) ;
+ TangentFlagsPtr) ;
}
anInterpolator.Perform() ;
if (anInterpolator.IsDone()) {
anInterpolator.Curve() ;
DrawTrSurf::Set(a[1],
- NewCurvePtr) ;
+ NewCurvePtr) ;
di << a[2] << " " ;
}
gp_Pnt P1,P2,P3,P4;
if (!strcmp(a[2], "seg")) {
if (DrawTrSurf::GetPoint(a[3], P1)) {
- if (DrawTrSurf::GetPoint(a[4], P2)) {
- Handle(Geom_Curve) theline = GC_MakeSegment(P1,P2).Value();
- DrawTrSurf::Set(a[1], theline);
- return 1;
- }
+ if (DrawTrSurf::GetPoint(a[4], P2)) {
+ Handle(Geom_Curve) theline = GC_MakeSegment(P1,P2).Value();
+ DrawTrSurf::Set(a[1], theline);
+ return 1;
+ }
}
}
else if (!strcmp(a[2], "cir")) {
if (DrawTrSurf::GetPoint(a[3], P1)) {
- if (DrawTrSurf::GetPoint(a[4], P2)) {
- if (DrawTrSurf::GetPoint(a[5], P3)) {
-// if (DrawTrSurf::GetPoint(a[6], P4)) {
- if (n>6) {
- DrawTrSurf::GetPoint(a[6], P4);
- gp_Vec V1 = gp_Vec(P2,P3);
- Handle(Geom_Curve)thearc = GC_MakeArcOfCircle(P1,V1,P4).Value();
- DrawTrSurf::Set(a[1], thearc);
- return 1;
- }
- else {
- Handle(Geom_Curve)thearc = GC_MakeArcOfCircle(P1,P2,P3).Value();
- DrawTrSurf::Set(a[1], thearc);
- return 1;
- }
- }
- }
+ if (DrawTrSurf::GetPoint(a[4], P2)) {
+ if (DrawTrSurf::GetPoint(a[5], P3)) {
+ // if (DrawTrSurf::GetPoint(a[6], P4)) {
+ if (n>6) {
+ DrawTrSurf::GetPoint(a[6], P4);
+ gp_Vec V1 = gp_Vec(P2,P3);
+ Handle(Geom_Curve)thearc = GC_MakeArcOfCircle(P1,V1,P4).Value();
+ DrawTrSurf::Set(a[1], thearc);
+ return 1;
+ }
+ else {
+ Handle(Geom_Curve)thearc = GC_MakeArcOfCircle(P1,P2,P3).Value();
+ DrawTrSurf::Set(a[1], thearc);
+ return 1;
+ }
+ }
+ }
}
}
}
// constrained constructs
g = "GEOMETRY Constraints";
- theCommands.Add("cirtang",
- "cirtang cname curve/point/radius curve/point/radius curve/point/radius",
- __FILE__,
- cirtang,g);
-
- theCommands.Add("lintan",
- "lintan lname curve1 curve2 [angle]",
- __FILE__,
- lintang,g);
-
-
- theCommands.Add("interpol",
- "interpol cname [fic]",
- __FILE__,
- interpol, g);
- theCommands.Add("tanginterpol",
- "tanginterpol curve [p] num_points points [tangents] modifier p = periodic",
- __FILE__,
- tanginterpol,g);
-
- theCommands.Add("gcarc",
- "gcarc name seg/cir p1 p2 p3 p4",
- __FILE__,
- gcarc,g);
+ theCommands.Add("cirtang",
+ "cirtang cname curve/point/radius curve/point/radius curve/point/radius",
+ __FILE__,
+ cirtang,g);
+
+ theCommands.Add("lintan",
+ "lintan lname curve1 curve2 [angle]",
+ __FILE__,
+ lintang,g);
+
+
+ theCommands.Add("interpol",
+ "interpol cname [fic]",
+ __FILE__,
+ interpol, g);
+ theCommands.Add("tanginterpol",
+ "tanginterpol curve [p] num_points points [tangents] modifier p = periodic",
+ __FILE__,
+ tanginterpol,g);
+
+ theCommands.Add("gcarc",
+ "gcarc name seg/cir p1 p2 p3 p4",
+ __FILE__,
+ gcarc,g);
}
#include <AppParCurves_MultiBSpCurve.hxx>
#include <AppParCurves_MultiCurve.hxx>
#include <AppDef_MultiLine.hxx>
-#include <AppDef_TheVariational.hxx>
+#include <AppDef_Variational.hxx>
#include <AppDef_Compute.hxx>
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
#include <AppParCurves_ConstraintCouple.hxx>
}
}
- AppDef_TheVariational Variation(AML,
+ AppDef_Variational Variation(AML,
1, NbPoints,
TABofCC);
}
}
- AppDef_TheVariational Variation(AML,
+ AppDef_Variational Variation(AML,
1, NbPoints,
TABofCC);
di <<" Error2D is : " << err2d << "\n";
}
else {
- AppDef_TheVariational Varia(AML,
+ AppDef_Variational Varia(AML,
1, NbPoints,
TABofCC,
Degree, 1);
di <<" Error3D is : " << err << "\n";
}
else {
- AppDef_TheVariational Varia(AML,
+ AppDef_Variational Varia(AML,
1, NbPoints,
TABofCC,
Degree, 1);
+++ /dev/null
-IntCurveSurface_SurfaceTool.gxx
-
--------------------------------------------------
generic class HCurveTool;
--------------------------------------------------
- generic class SurfaceTool;
- --------------------------------------------------
generic class Polygon;
--------------------------------------------------
generic class Polyhedron;
+++ /dev/null
--- Created on: 1993-07-02
--- Created by: Laurent BUCHARD
--- Copyright (c) 1993-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-generic class SurfaceTool from IntCurveSurface
- ( TheSurface as any)
-
-
-uses
-
- Shape from GeomAbs,
- SurfaceType from GeomAbs,
- Pln from gp,
- Cone from gp,
- Cylinder from gp,
- Sphere from gp,
- Torus from gp,
- Pnt from gp,
- Vec from gp,
- Array1OfReal from TColStd,
- BezierSurface from Geom,
- BSplineSurface from Geom,
- HSurface from Adaptor3d,
- HCurve from Adaptor3d,
- Ax1 from gp,
- Dir from gp
-
-raises
- NoSuchObject from Standard,
- OutOfRange from Standard
-
-
-is
-
- FirstUParameter(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
- FirstVParameter(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
- LastUParameter(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
- LastVParameter(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
-
-
- NbUIntervals(myclass; S: TheSurface;
- Sh : Shape from GeomAbs)
- ---C++: inline
- returns Integer from Standard;
-
- NbVIntervals(myclass; S: TheSurface;
- Sh : Shape from GeomAbs)
- ---C++: inline
- returns Integer from Standard;
-
-
-
- UIntervals(myclass; S : TheSurface;
- T : in out Array1OfReal from TColStd;
- Sh : Shape from GeomAbs);
- ---C++: inline
-
- VIntervals(myclass; S : TheSurface;
- T : in out Array1OfReal from TColStd;
- Sh : Shape from GeomAbs) ;
- ---C++: inline
-
-
- UTrim(myclass; S : TheSurface;
- First, Last, Tol : Real)
- ---C++: inline
- returns HSurface from Adaptor3d
- raises
- OutOfRange from Standard;
- ---Purpose: If <First> >= <Last>
-
- VTrim(myclass; S : TheSurface;
- First, Last, Tol : Real)
- ---C++: inline
- returns HSurface from Adaptor3d
- raises
- OutOfRange from Standard;
- ---Purpose: If <First> >= <Last>
-
-
- IsUClosed(myclass; S: TheSurface)
- ---C++: inline
- returns Boolean from Standard;
-
- IsVClosed(myclass; S: TheSurface)
- ---C++: inline
- returns Boolean from Standard;
-
-
- IsUPeriodic(myclass; S: TheSurface)
- ---C++: inline
- returns Boolean from Standard;
-
- UPeriod(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
- IsVPeriodic(myclass; S: TheSurface)
- ---C++: inline
- returns Boolean from Standard;
-
- VPeriod(myclass; S: TheSurface)
- ---C++: inline
- returns Real from Standard;
-
-
-
- Value(myclass; S : TheSurface;
- u,v : Real from Standard)
- ---C++: inline
- returns Pnt from gp;
-
- D0(myclass; S : TheSurface;
- u,v : Real from Standard;
- P : out Pnt from gp);
- ---C++: inline
-
- D1(myclass; S : TheSurface;
- u,v : Real from Standard;
- P : out Pnt from gp;
- D1u,D1v: out Vec from gp);
- ---C++: inline
-
- D2(myclass; S : TheSurface;
- u,v : Real from Standard;
- P : out Pnt from gp;
- D1U,D1V,D2U,D2V,D2UV: out Vec from gp);
- ---C++: inline
-
- D3(myclass; S : TheSurface;
- u,v : Real from Standard;
- P : out Pnt from gp;
- D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV: out Vec from gp);
- ---C++: inline
-
- DN(myclass; S : TheSurface;
- u,v : Real from Standard;
- Nu,Nv : Integer from Standard)
- ---C++: inline
- returns Vec from gp;
-
-
-
- UResolution(myclass; S:TheSurface; R3d: Real from Standard)
- ---C++: inline
- returns Real from Standard;
-
- VResolution(myclass; S:TheSurface; R3d: Real from Standard)
- ---C++: inline
- returns Real from Standard;
-
- GetType(myclass; S: TheSurface)
- ---C++: inline
- returns SurfaceType from GeomAbs;
-
-
- Plane(myclass; S: TheSurface)
- ---C++: inline
- returns Pln from gp;
-
- Cylinder(myclass; S : TheSurface) returns Cylinder from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
-
- Cone(myclass; S : TheSurface) returns Cone from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
- Torus(myclass; S : TheSurface) returns Torus from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
-
- Sphere(myclass; S : TheSurface) returns Sphere from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
- Bezier(myclass; S : TheSurface) returns BezierSurface from Geom
- raises NoSuchObject from Standard;
- ---C++: inline
-
- BSpline(myclass; S : TheSurface) returns BSplineSurface from Geom
- raises NoSuchObject from Standard;
- ---C++: inline
-
- AxeOfRevolution(myclass; S: TheSurface) returns Ax1 from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
- Direction(myclass; S: TheSurface) returns Dir from gp
- raises NoSuchObject from Standard;
- ---C++: inline
-
- BasisCurve(myclass; S:TheSurface) returns HCurve from Adaptor3d
- raises NoSuchObject from Standard;
- ---C++: inline
-
-
---------------------------------------------------------------------------------
-
-
- NbSamplesU(myclass; S : TheSurface) returns Integer from Standard;
-
-
- NbSamplesV(myclass; S : TheSurface) returns Integer from Standard;
-
-
- NbSamplesU(myclass; S : TheSurface; u1,u2: Real from Standard) returns Integer from Standard;
-
-
- NbSamplesV(myclass; S : TheSurface; v1,v2: Real from Standard) returns Integer from Standard;
-
-
-
-end SurfaceTool;
+++ /dev/null
-// Created by: Laurent BUCHARD
-// Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//-- <lbr@nonox>
-
-#include TheSurface_hxx
-
-
-Standard_Integer IntCurveSurface_SurfaceTool::NbSamplesU(const TheSurface& S) {
- Standard_Integer nbs;
- GeomAbs_SurfaceType typS = S.GetType();
- switch(typS) {
- case GeomAbs_Plane:
- {
- nbs = 2;
- }
- break;
- case GeomAbs_BezierSurface:
- {
- nbs = 3 + S.NbUPoles();
- }
- break;
- case GeomAbs_BSplineSurface:
- {
- nbs = S.NbUKnots();
- nbs*= S.UDegree();
- if(nbs < 2) nbs=2;
-
- }
- break;
- case GeomAbs_Torus:
- {
- nbs = 20;
- }
- break;
- case GeomAbs_Cylinder:
- case GeomAbs_Cone:
- case GeomAbs_Sphere:
- case GeomAbs_SurfaceOfRevolution:
- case GeomAbs_SurfaceOfExtrusion:
- {
- nbs = 10;
- }
- break;
-
- default:
- {
- nbs = 10;
- }
- break;
- }
- return(nbs);
-}
-
-Standard_Integer IntCurveSurface_SurfaceTool::NbSamplesV(const TheSurface& S) {
- Standard_Integer nbs;
- GeomAbs_SurfaceType typS = S.GetType();
- switch(typS) {
- case GeomAbs_Plane:
- {
- nbs = 2;
- }
- break;
- case GeomAbs_BezierSurface:
- {
- nbs = 3 + S.NbVPoles();
- }
- break;
- case GeomAbs_BSplineSurface:
- {
- nbs = S.NbVKnots();
- nbs*= S.VDegree();
- if(nbs < 2) nbs=2;
-
- }
- break;
- case GeomAbs_Cylinder:
- case GeomAbs_Cone:
- case GeomAbs_Sphere:
- case GeomAbs_Torus:
- case GeomAbs_SurfaceOfRevolution:
- case GeomAbs_SurfaceOfExtrusion:
- {
- nbs = 15;
- }
- break;
-
- default:
- {
- nbs = 10;
- }
- break;
- }
- return(nbs);
-}
-
-Standard_Integer IntCurveSurface_SurfaceTool::NbSamplesU(const TheSurface& S,
- const Standard_Real u1,
- const Standard_Real u2) {
- Standard_Integer nbs = NbSamplesU(S);
- Standard_Integer n = nbs;
- if(nbs>10) {
- Standard_Real uf = FirstUParameter(S);
- Standard_Real ul = LastUParameter(S);
- n*= (Standard_Integer)((u2-u1)/(uf-ul));
- if(n>nbs) n = nbs;
- if(n<5) n = 5;
- }
- return(n);
-}
-
-Standard_Integer IntCurveSurface_SurfaceTool::NbSamplesV(const TheSurface& S,
- const Standard_Real v1,
- const Standard_Real v2) {
- Standard_Integer nbs = NbSamplesV(S);
- Standard_Integer n = nbs;
- if(nbs>10) {
- Standard_Real vf = FirstVParameter(S);
- Standard_Real vl = LastVParameter(S);
- n*= (Standard_Integer)((v2-v1)/(vf-vl));
- if(n>nbs) n = nbs;
- if(n<5) n = 5;
- }
- return(n);
-}
-
-
+++ /dev/null
-// Created by: Laurent BUCHARD
-// Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//-- <lbr@nonox>
-
-
-
-#include TheSurface_hxx
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Cylinder.hxx>
-#include <gp_Cone.hxx>
-#include <gp_Torus.hxx>
-#include <gp_Sphere.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Dir.hxx>
-#include <Geom_BezierSurface.hxx>
-#include <Geom_BSplineSurface.hxx>
-#include <Adaptor3d_HSurface.hxx>
-#include <Adaptor3d_HCurve.hxx>
-
-
-
-inline Standard_Real IntCurveSurface_SurfaceTool::FirstUParameter(const TheSurface& Surf){ return Surf.FirstUParameter(); }
-inline Standard_Real IntCurveSurface_SurfaceTool::FirstVParameter(const TheSurface& Surf){ return Surf.FirstVParameter();}
-inline Standard_Real IntCurveSurface_SurfaceTool::LastUParameter(const TheSurface& Surf){ return Surf.LastUParameter();}
-inline Standard_Real IntCurveSurface_SurfaceTool::LastVParameter(const TheSurface& Surf){ return Surf.LastVParameter();}
-
-inline Standard_Integer IntCurveSurface_SurfaceTool::NbUIntervals(const TheSurface& Surf,
- const GeomAbs_Shape S){
- return Surf.NbUIntervals(S);
-}
-
-inline Standard_Integer IntCurveSurface_SurfaceTool::NbVIntervals(const TheSurface& Surf,
- const GeomAbs_Shape S){
- return Surf.NbVIntervals(S);
-}
-
-inline void IntCurveSurface_SurfaceTool::UIntervals(const TheSurface& Surf,
- TColStd_Array1OfReal& Tab,
- const GeomAbs_Shape S){
- Surf.UIntervals(Tab,S);
-}
-
-inline void IntCurveSurface_SurfaceTool::VIntervals(const TheSurface& Surf,
- TColStd_Array1OfReal& Tab,
- const GeomAbs_Shape S){
- Surf.VIntervals(Tab,S);
-}
-
-
-inline Handle_Adaptor3d_HSurface IntCurveSurface_SurfaceTool::UTrim(const TheSurface& Surf,
- const Standard_Real F,
- const Standard_Real L,
- const Standard_Real Tol) {
- return Surf.UTrim(F,L,Tol);
-}
-
-inline Handle_Adaptor3d_HSurface IntCurveSurface_SurfaceTool::VTrim(const TheSurface& Surf,
- const Standard_Real F,
- const Standard_Real L,
- const Standard_Real Tol) {
- return Surf.VTrim(F,L,Tol);
-}
-
-
-
-
-inline Standard_Boolean IntCurveSurface_SurfaceTool::IsUClosed(const TheSurface& S)
-{
- return S.IsUClosed();
-}
-
-inline Standard_Boolean IntCurveSurface_SurfaceTool::IsVClosed(const TheSurface& S)
-{
- return S.IsVClosed();
-}
-
-inline Standard_Boolean IntCurveSurface_SurfaceTool::IsUPeriodic(const TheSurface& S)
-{
- return S.IsUPeriodic();
-}
-
-inline Standard_Real IntCurveSurface_SurfaceTool::UPeriod(const TheSurface& S)
-{
- return S.UPeriod();
-}
-
-inline Standard_Boolean IntCurveSurface_SurfaceTool::IsVPeriodic(const TheSurface& S)
-{
- return S.IsVPeriodic();
-}
-
-inline Standard_Real IntCurveSurface_SurfaceTool::VPeriod(const TheSurface& S)
-{
- return S.VPeriod();
-}
-
-inline gp_Pnt IntCurveSurface_SurfaceTool::Value(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V )
-{
- return S.Value(U,V);
-}
-
-inline void IntCurveSurface_SurfaceTool::D0(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P)
-{
- S.D0(U,V,P);
-}
-
-inline void IntCurveSurface_SurfaceTool::D1(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V)
-{
- S.D1(U,V,P,D1U,D1V);
-}
-
-inline void IntCurveSurface_SurfaceTool::D2(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V,
- gp_Vec& D2U,
- gp_Vec& D2V,
- gp_Vec& D2UV)
-{
- S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
-}
-
-inline void IntCurveSurface_SurfaceTool::D3(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V,
- gp_Vec& D2U,
- gp_Vec& D2V,
- gp_Vec& D2UV,
- gp_Vec& D3U,
- gp_Vec& D3V,
- gp_Vec& D3UUV,
- gp_Vec& D3UVV)
-{
- S.D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
-}
-
-inline gp_Vec IntCurveSurface_SurfaceTool::DN(const TheSurface& S,
- const Standard_Real U,
- const Standard_Real V,
- const Standard_Integer Nu,
- const Standard_Integer Nv)
-{
- return S.DN(U,V,Nu,Nv);
-}
-
-inline Standard_Real IntCurveSurface_SurfaceTool::UResolution(const TheSurface& S,
- const Standard_Real R3d)
-{
- return S.UResolution(R3d);
-}
-
-inline Standard_Real IntCurveSurface_SurfaceTool::VResolution(const TheSurface& S,
- const Standard_Real R3d)
-{
- return S.VResolution(R3d);
-}
-
-inline GeomAbs_SurfaceType IntCurveSurface_SurfaceTool::GetType(const TheSurface& S )
-{
- return S.GetType();
-}
-
-inline gp_Pln IntCurveSurface_SurfaceTool::Plane(const TheSurface& S)
-{
- return S.Plane();
-}
-
-inline gp_Cylinder IntCurveSurface_SurfaceTool::Cylinder(const TheSurface& S)
-{
- return S.Cylinder();
-}
-
-inline gp_Cone IntCurveSurface_SurfaceTool::Cone(const TheSurface& S)
-{
- return S.Cone();
-}
-
-inline gp_Sphere IntCurveSurface_SurfaceTool::Sphere(const TheSurface& S)
-{
- return S.Sphere();
-}
-
-inline gp_Torus IntCurveSurface_SurfaceTool::Torus(const TheSurface& S)
-{
- return S.Torus();
-}
-
-
-inline Handle(Geom_BezierSurface) IntCurveSurface_SurfaceTool::Bezier(const TheSurface& S) {
- return(S.Bezier());
-}
-
-inline Handle(Geom_BSplineSurface) IntCurveSurface_SurfaceTool::BSpline(const TheSurface& S) {
- return(S.BSpline());
-}
-
-
-inline gp_Ax1 IntCurveSurface_SurfaceTool::AxeOfRevolution(const TheSurface& S) {
- return(S.AxeOfRevolution());
-}
-
-inline gp_Dir IntCurveSurface_SurfaceTool::Direction(const TheSurface& S) {
- return(S.Direction());
-}
-
-inline Handle(Adaptor3d_HCurve) IntCurveSurface_SurfaceTool::BasisCurve(const TheSurface& S) {
- return(S.BasisCurve());
-}
-
generic class ZerCSParFunc; -- inherits FunctionSetWithDerivatives
- generic class ZerCOnSSParFunc; -- inherits FunctionSetWithDerivatives
-
generic class Int2S,TheFunction;
generic class IntCS;
+++ /dev/null
--- Created on: 1994-02-14
--- Created by: Jacques GOUSSARD
--- Copyright (c) 1994-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-generic class ZerCOnSSParFunc from IntImp
- (ThePSurface as any;
- ThePSurfaceTool as any;
- TheCurveOnSurf as any;
- TheCurveTool as any
- )
-
-inherits FunctionSetWithDerivatives from math
-
- ---Purpose: this function is associated to the intersection between
- -- a curve on surface and a surface .
-
-
-uses Vector from math,
- Matrix from math,
- Pnt from gp
-
-is
- Create( S1 : ThePSurface;
- C : TheCurveOnSurf;
- S2 : ThePSurface )
-
- ---Purpose: S1 is the surface on which the intersection is searched.
- -- C is a curve on the surface S2.
-
- returns ZerCOnSSParFunc from IntImp;
-
-
- NbVariables(me) returns Integer from Standard
- is static;
-
- NbEquations(me) returns Integer from Standard
- is static;
-
- Value(me : in out; X : in Vector from math;
- F : out Vector from math)
- returns Boolean from Standard
- is static;
-
- Derivatives(me : in out;X : in Vector from math;
- D : out Matrix from math)
- returns Boolean from Standard
- is static;
-
- Values(me : in out;
- X : in Vector from math;
- F : out Vector from math; D: out Matrix from math)
- returns Boolean from Standard
- is static;
-
- Point(me)
- ---C++: return const&
- returns Pnt from gp
- is static;
-
- Root(me) returns Real from Standard
- is static;
-
- AuxillarSurface(me)
- ---C++: return const&
- returns ThePSurface
- is static;
-
- AuxillarCurve(me)
- ---C++: return const&
- returns TheCurveOnSurf
- is static;
-
-fields
- curve : Address from Standard; --- TheCurveOnSurf;
- surface1 : Address from Standard; --- ThePSurface;
- surface2 : Address from Standard; --- ThePSurface;
- p : Pnt from gp;
- f : Real from Standard;
-
-end ZerCOnSSParFunc;
+++ /dev/null
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec2d.hxx>
-
-#ifndef DEB
-#define No_Standard_RangeError
-#define No_Standard_OutOfRange
-#endif
-
-
-#define SURFACE1 (*((ThePSurface *)(surface1)))
-#define SURFACE2 (*((ThePSurface *)(surface2)))
-#define CURVE (*((TheCurveOnSurf *)(curve)))
-
-IntImp_ZerCOnSSParFunc::IntImp_ZerCOnSSParFunc(const ThePSurface& S1,
- const TheCurveOnSurf& C,
- const ThePSurface& S2)
-{
- surface1 = (Standard_Address)(&S1);
- surface2 = (Standard_Address)(&S2);
- curve = (Standard_Address)(&C);
-}
-
-Standard_Integer IntImp_ZerCOnSSParFunc::NbVariables()const { return 3;}
-
-Standard_Integer IntImp_ZerCOnSSParFunc::NbEquations()const { return 3;}
-
-Standard_Boolean IntImp_ZerCOnSSParFunc::Value(const math_Vector& X,
- math_Vector& F){
-
- gp_Pnt Psurf(ThePSurfaceTool::Value(SURFACE1,X(1),X(2)));
- gp_Pnt2d p2d(TheCurveTool::Value(CURVE,X(3)));
- gp_Pnt Pcurv(ThePSurfaceTool::Value(SURFACE2,p2d.X(),p2d.Y()));
-
- F(1) = Psurf.X()-Pcurv.X();
- F(2) = Psurf.Y()-Pcurv.Y();
- F(3) = Psurf.Z()-Pcurv.Z();
- f = F(1)*F(1)+ F(2)*F(2)+ F(3)*F(3);
- p = gp_Pnt((Psurf.XYZ()+Pcurv.XYZ())/2.);
- return Standard_True;
-}
-
-Standard_Boolean IntImp_ZerCOnSSParFunc::Derivatives ( const math_Vector& X,
- math_Matrix& D) {
- gp_Pnt Psurf,Pcurv;
- gp_Vec D1u,D1v,D1w;
- gp_Pnt2d p2d;
- gp_Vec2d d2d;
- gp_Vec d1u,d1v;
-
- ThePSurfaceTool::D1(SURFACE1,X(1),X(2),Psurf,D1u,D1v);
- TheCurveTool::D1(CURVE,X(3),p2d,d2d);
- ThePSurfaceTool::D1(SURFACE2,p2d.X(),p2d.Y(),Pcurv,d1u,d1v);
- D1w.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
- D(1,1) = D1u.X();
- D(1,2) = D1v.X();
- D(1,3) = -D1w.X();
- D(2,1) = D1u.Y();
- D(2,2) = D1v.Y();
- D(2,3) = -D1w.Y();
- D(3,1) = D1u.Z();
- D(3,2) = D1v.Z();
- D(3,3) = -D1w.Z();
- return Standard_True;
-}
-
-Standard_Boolean IntImp_ZerCOnSSParFunc::Values( const math_Vector& X,
- math_Vector& F,
- math_Matrix& D) {
- gp_Pnt Psurf,Pcurv;
- gp_Vec D1u,D1v,D1w;
-
- gp_Pnt2d p2d;
- gp_Vec2d d2d;
- gp_Vec d1u,d1v;
-
- ThePSurfaceTool::D1(SURFACE1,X(1),X(2),Psurf,D1u,D1v);
- TheCurveTool::D1(CURVE,X(3),p2d,d2d);
- ThePSurfaceTool::D1(SURFACE2,p2d.X(),p2d.Y(),Pcurv,d1u,d1v);
- D1w.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
- D(1,1) = D1u.X();
- D(1,2) = D1v.X();
- D(1,3) = -D1w.X();
- D(2,1) = D1u.Y();
- D(2,2) = D1v.Y();
- D(2,3) = -D1w.Y();
- D(3,1) = D1u.Z();
- D(3,2) = D1v.Z();
- D(3,3) = -D1w.Z();
- F(1) = Psurf.X()-Pcurv.X();
- F(2) = Psurf.Y()-Pcurv.Y();
- F(3) = Psurf.Z()-Pcurv.Z();
- f = F(1)*F(1)+ F(2)*F(2)+ F(3)*F(3);
- p = gp_Pnt((Psurf.XYZ()+Pcurv.XYZ())/2.);
- return Standard_True;
-}
-
-const gp_Pnt& IntImp_ZerCOnSSParFunc::Point() const { return p;}
-
-Standard_Real IntImp_ZerCOnSSParFunc::Root() const { return f;}
-
-const ThePSurface& IntImp_ZerCOnSSParFunc::AuxillarSurface() const {
- return SURFACE1;}
-
-const TheCurveOnSurf& IntImp_ZerCOnSSParFunc::AuxillarCurve() const {
- return CURVE;}
-
-#undef SURFACE1
-#undef SURFACE2
-#undef CURVE
-- implicite/implicite
class ImpImpIntersection;
+
+ class CSFunction; -- inherits FunctionSetWithDerivatives
-- commun implicite/parametree et parametree/parametree
alias SearchPnt is InterferencePolygon2d from Intf;
- class CSFunction instantiates ZerCOnSSParFunc from IntImp
- (HSurface from Adaptor3d,
- HSurfaceTool from Adaptor3d,
- HCurve2d from Adaptor2d,
- HCurve2dTool from IntPatch);
class CurvIntSurf instantiates IntCS from IntImp
(HSurface from Adaptor3d,
--- /dev/null
+-- Created on: 1994-02-14
+-- Created by: Jacques GOUSSARD
+-- Copyright (c) 1994-1999 Matra Datavision
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- This library is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU Lesser General Public License version 2.1 as published
+-- by the Free Software Foundation, with special exception defined in the file
+-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+-- distribution for complete text of the license and disclaimer of any warranty.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+class CSFunction from IntPatch inherits FunctionSetWithDerivatives from math
+
+ ---Purpose: this function is associated to the intersection between
+ -- a curve on surface and a surface .
+
+
+uses Vector from math,
+ Matrix from math,
+ Pnt from gp,
+ HSurface from Adaptor3d,
+ HSurfaceTool from Adaptor3d,
+ HCurve2d from Adaptor2d,
+ HCurve2dTool from IntPatch
+
+is
+ Create( S1 : HSurface from Adaptor3d;
+ C : HCurve2d from Adaptor2d;
+ S2 : HSurface from Adaptor3d )
+
+ ---Purpose: S1 is the surface on which the intersection is searched.
+ -- C is a curve on the surface S2.
+
+ returns CSFunction from IntPatch;
+
+
+ NbVariables(me) returns Integer from Standard
+ is static;
+
+ NbEquations(me) returns Integer from Standard
+ is static;
+
+ Value(me : in out; X : in Vector from math;
+ F : out Vector from math)
+ returns Boolean from Standard
+ is static;
+
+ Derivatives(me : in out;X : in Vector from math;
+ D : out Matrix from math)
+ returns Boolean from Standard
+ is static;
+
+ Values(me : in out;
+ X : in Vector from math;
+ F : out Vector from math; D: out Matrix from math)
+ returns Boolean from Standard
+ is static;
+
+ Point(me)
+ ---C++: return const&
+ returns Pnt from gp
+ is static;
+
+ Root(me) returns Real from Standard
+ is static;
+
+ AuxillarSurface(me)
+ ---C++: return const&
+ returns HSurface from Adaptor3d
+ is static;
+
+ AuxillarCurve(me)
+ ---C++: return const&
+ returns HCurve2d from Adaptor2d
+ is static;
+
+fields
+ curve : Address from Standard; --- HCurve2d from Adaptor2d;
+ surface1 : Address from Standard; --- HSurface from Adaptor3d;
+ surface2 : Address from Standard; --- HSurface from Adaptor3d;
+ p : Pnt from gp;
+ f : Real from Standard;
+
+end CSFunction;
--- /dev/null
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <IntPatch_CSFunction.ixx>
+
+#include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_HSurfaceTool.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
+#include <IntPatch_HCurve2dTool.hxx>
+
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2d.hxx>
+
+#ifndef DEB
+#define No_Standard_RangeError
+#define No_Standard_OutOfRange
+#endif
+
+
+#define SURFACE1 (*((Handle(Adaptor3d_HSurface) *)(surface1)))
+#define SURFACE2 (*((Handle(Adaptor3d_HSurface) *)(surface2)))
+#define CURVE (*((Handle(Adaptor2d_HCurve2d) *)(curve)))
+
+IntPatch_CSFunction::IntPatch_CSFunction(const Handle(Adaptor3d_HSurface)& S1,
+ const Handle(Adaptor2d_HCurve2d)& C,
+ const Handle(Adaptor3d_HSurface)& S2)
+{
+ surface1 = (Standard_Address)(&S1);
+ surface2 = (Standard_Address)(&S2);
+ curve = (Standard_Address)(&C);
+}
+
+Standard_Integer IntPatch_CSFunction::NbVariables()const { return 3;}
+
+Standard_Integer IntPatch_CSFunction::NbEquations()const { return 3;}
+
+Standard_Boolean IntPatch_CSFunction::Value(const math_Vector& X,
+ math_Vector& F){
+
+ gp_Pnt Psurf(Adaptor3d_HSurfaceTool::Value(SURFACE1,X(1),X(2)));
+ gp_Pnt2d p2d(IntPatch_HCurve2dTool::Value(CURVE,X(3)));
+ gp_Pnt Pcurv(Adaptor3d_HSurfaceTool::Value(SURFACE2,p2d.X(),p2d.Y()));
+
+ F(1) = Psurf.X()-Pcurv.X();
+ F(2) = Psurf.Y()-Pcurv.Y();
+ F(3) = Psurf.Z()-Pcurv.Z();
+ f = F(1)*F(1)+ F(2)*F(2)+ F(3)*F(3);
+ p = gp_Pnt((Psurf.XYZ()+Pcurv.XYZ())/2.);
+ return Standard_True;
+}
+
+Standard_Boolean IntPatch_CSFunction::Derivatives ( const math_Vector& X,
+ math_Matrix& D) {
+ gp_Pnt Psurf,Pcurv;
+ gp_Vec D1u,D1v,D1w;
+ gp_Pnt2d p2d;
+ gp_Vec2d d2d;
+ gp_Vec d1u,d1v;
+
+ Adaptor3d_HSurfaceTool::D1(SURFACE1,X(1),X(2),Psurf,D1u,D1v);
+ IntPatch_HCurve2dTool::D1(CURVE,X(3),p2d,d2d);
+ Adaptor3d_HSurfaceTool::D1(SURFACE2,p2d.X(),p2d.Y(),Pcurv,d1u,d1v);
+ D1w.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+
+ D(1,1) = D1u.X();
+ D(1,2) = D1v.X();
+ D(1,3) = -D1w.X();
+ D(2,1) = D1u.Y();
+ D(2,2) = D1v.Y();
+ D(2,3) = -D1w.Y();
+ D(3,1) = D1u.Z();
+ D(3,2) = D1v.Z();
+ D(3,3) = -D1w.Z();
+ return Standard_True;
+}
+
+Standard_Boolean IntPatch_CSFunction::Values( const math_Vector& X,
+ math_Vector& F,
+ math_Matrix& D) {
+ gp_Pnt Psurf,Pcurv;
+ gp_Vec D1u,D1v,D1w;
+
+ gp_Pnt2d p2d;
+ gp_Vec2d d2d;
+ gp_Vec d1u,d1v;
+
+ Adaptor3d_HSurfaceTool::D1(SURFACE1,X(1),X(2),Psurf,D1u,D1v);
+ IntPatch_HCurve2dTool::D1(CURVE,X(3),p2d,d2d);
+ Adaptor3d_HSurfaceTool::D1(SURFACE2,p2d.X(),p2d.Y(),Pcurv,d1u,d1v);
+ D1w.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+
+ D(1,1) = D1u.X();
+ D(1,2) = D1v.X();
+ D(1,3) = -D1w.X();
+ D(2,1) = D1u.Y();
+ D(2,2) = D1v.Y();
+ D(2,3) = -D1w.Y();
+ D(3,1) = D1u.Z();
+ D(3,2) = D1v.Z();
+ D(3,3) = -D1w.Z();
+ F(1) = Psurf.X()-Pcurv.X();
+ F(2) = Psurf.Y()-Pcurv.Y();
+ F(3) = Psurf.Z()-Pcurv.Z();
+ f = F(1)*F(1)+ F(2)*F(2)+ F(3)*F(3);
+ p = gp_Pnt((Psurf.XYZ()+Pcurv.XYZ())/2.);
+ return Standard_True;
+}
+
+const gp_Pnt& IntPatch_CSFunction::Point() const { return p;}
+
+Standard_Real IntPatch_CSFunction::Root() const { return f;}
+
+const Handle_Adaptor3d_HSurface& IntPatch_CSFunction::AuxillarSurface() const {
+ return SURFACE1;}
+
+const Handle_Adaptor2d_HCurve2d& IntPatch_CSFunction::AuxillarCurve() const {
+ return CURVE;}
+
+#undef SURFACE1
+#undef SURFACE2
+#undef CURVE
---Purpose: Computes the interference between two polygons in 2d.
-- Result : points of intersections and zones of tangence.
- generic class InterferencePolygon3d;
- ---Purpose: Computes the interference between two polygon in 3d.
- -- Section points, common perpendicular and projections.
-
generic class InterferencePolygonPolyhedron;
---Purpose: Computes the interference between a polygon or a straight
-- line and a polyhedron. Points of intersection and zones
+++ /dev/null
--- Created on: 1992-09-29
--- Created by: Didier PIFFAULT
--- Copyright (c) 1992-1999 Matra Datavision
--- Copyright (c) 1999-2014 OPEN CASCADE SAS
---
--- This file is part of Open CASCADE Technology software library.
---
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
--- by the Free Software Foundation, with special exception defined in the file
--- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
--- distribution for complete text of the license and disclaimer of any warranty.
---
--- Alternatively, this file may be used under the terms of Open CASCADE
--- commercial license or contractual agreement.
-
-generic class InterferencePolygon3d from Intf
- (Polygon3d1 as any;
- ToolPolygon3d1 as any; -- as ToolPolygon(Pnt,Polygon3d1,Box)
- Polygon3d2 as any;
- ToolPolygon3d2 as any) -- as ToolPolygon(Pnt,Polygon3d2,Box)
- inherits Interference from Intf
-
- ---Purpose: Computes the interference between two polygons or the
- -- self interference of a polygon in 3 dimensions . In 3
- -- dimensions the result can be a common perpendicular ,
- -- an orthogonal projection or a real intersections.
- -- There are two different instantiation arguments to
- -- authorize an interference between two polygons from
- -- differents origin. Ex : to intersect a curve polygon
- -- with an algorithmic curve from numerical walking
- -- between two surfaces.
-
-uses Pnt from gp,
- SectionPoint from Intf,
- SeqOfSectionPoint from Intf,
- SectionLine from Intf,
- SeqOfSectionLine from Intf
-
-raises OutOfRange from Standard
-
-
-is
--- Interface :
-
- Create returns InterferencePolygon3d from Intf;
- ---Purpose: Constructs an empty interference of 3d Polygon.
-
-
- Create (Obje1 : in Polygon3d1 ;Obje2 : in Polygon3d2)
- returns InterferencePolygon3d from Intf;
- ---Purpose: Constructs and computes an interference between two Polygons.
-
-
- Create (Obje : in Polygon3d1)
- returns InterferencePolygon3d from Intf;
- ---Purpose: Constructs and computes the self interference of a Polygon.
-
-
- Perform (me : in out;
- Obje1 : in Polygon3d1 ;Obje2 : in Polygon3d2);
- ---Purpose: Computes an interference between two Polygons.
-
-
- Perform (me : in out;
- Obje : in Polygon3d1);
- ---Purpose: Computes the auto interference of a Polygon.
-
-
- NbResults (me)
- returns Integer is static;
- ---Purpose: Gives the number of common Perpendiculars or orthogonal
- -- projections between the two polygons.
-
- ResultLine (me;
- Index : in Integer)
- returns SectionLine from Intf
- raises OutOfRange from Standard
- is static;
- ---Purpose: Gives the segment of address <Index> in the interference
- -- representing the perpendicular or the orthogonal
- -- projection .
- --
- ---C++: return const &
-
-
- ResultValue (me;
- Index : in Integer)
- returns Real from Standard
- raises OutOfRange from Standard
- is static;
- ---Purpose: Gives the distance between the two polygons
-
-
- MinimalDistance(me)
- returns Real from Standard
- is static;
- ---Purpose: Gives the distance between the two polygon3d at the
- -- perpendicular or projection of minimal length.
-
-
- MinimalResult (me)
- returns Integer from Standard
- is static;
- ---Purpose: Give the perpendicular or projection of minimal length.
- -- WARNING : if there are points of intersection the minimal
- -- result is one of them and this function is unusuable.
-
-
--- Implementation :
-
- Interference (me : in out;
- Obje1 : in Polygon3d1;
- Obje2 : in Polygon3d2)
- is private;
-
- Interference (me : in out;
- Obje : in Polygon3d1)
- is private;
-
- CommonPerpen (me : in out;
- BegO : in Pnt from gp;
- EndO : in Pnt from gp;
- BegT : in Pnt from gp;
- EndT : in Pnt from gp)
- is private;
- ---Purpose: Computes the common perpendicular between the two
- -- segments <BegO><EndO> and <BegT><EndT>.
-
- Projections (me : in out;
- BegO : in Pnt from gp;
- EndO : in Pnt from gp;
- BegT : in Pnt from gp;
- EndT : in Pnt from gp)
- is private;
- ---Purpose: Computes the different orthogonal projections between
- -- segment <BegO><EndO> and points <BegT>,<EndT> and segment
- -- <BegT><EndT> and points <BegO>,<EndO>.
-
-
-fields IndexMin : Integer from Standard;
- MinimalDist : Real from Standard;
- iObje1, iObje2 : Integer from Standard;
- beginOfNotClosedFirst: Boolean from Standard;
- beginOfNotClosedSecon: Boolean from Standard;
-
-
-end InterferencePolygon3d;
+++ /dev/null
-// Created on: 1992-10-09
-// Created by: Didier PIFFAULT
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <Intf_SectionPoint.hxx>
-#include <Intf_SeqOfSectionPoint.hxx>
-#include <Intf_SectionLine.hxx>
-#include <Intf_SeqOfSectionLine.hxx>
-#include <Intf_SeqOfTangentZone.hxx>
-#include <Intf_TangentZone.hxx>
-
-//=======================================================================
-//function : Intf_InterferencePolygon3d
-//purpose : Empty constructor.
-//=======================================================================
-
-Intf_InterferencePolygon3d::Intf_InterferencePolygon3d()
-: Intf_Interference (Standard_False),
- IndexMin (0),
- iObje1 (0),
- iObje2 (0),
- beginOfNotClosedFirst (Standard_True),
- beginOfNotClosedSecon (Standard_True)
-{}
-
-//=======================================================================
-//function : Intf_InterferencePolygon3d
-//purpose : Constructor of the interference beetween two Polygon.
-//=======================================================================
-
-Intf_InterferencePolygon3d::Intf_InterferencePolygon3d
- (const Polygon3d1& Obje1, const Polygon3d2& Obje2)
-: Intf_Interference (Standard_False),
- IndexMin (0),
- iObje1 (0),
- iObje2 (0),
- beginOfNotClosedFirst (Standard_True),
- beginOfNotClosedSecon (Standard_True)
-{
- Tolerance=ToolPolygon3d1::DeflectionOverEstimation(Obje1)+
- ToolPolygon3d2::DeflectionOverEstimation(Obje2);
- if (Tolerance<=0.) Tolerance=Epsilon(1000.);
- Interference(Obje1, Obje2);
-}
-
-
-//=======================================================================
-//function : Intf_InterferencePolygon3d
-//purpose : Constructor of the auto interference of a Polygon.
-//=======================================================================
-
-Intf_InterferencePolygon3d::Intf_InterferencePolygon3d
- (const Polygon3d1& Obje)
-: Intf_Interference (Standard_True),
- IndexMin(0),
- iObje1 (0),
- iObje2 (0),
- beginOfNotClosedFirst (Standard_True),
- beginOfNotClosedSecon (Standard_True)
-{
- Tolerance=ToolPolygon3d1::DeflectionOverEstimation(Obje)*2;
- Interference(Obje);
-}
-
-
-//=======================================================================
-//function : Perform
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::Perform
- (const Polygon3d1& Obje1, const Polygon3d2& Obje2)
-{
- SelfInterference(Standard_False);
- IndexMin=0;
- Tolerance=ToolPolygon3d1::DeflectionOverEstimation(Obje1)+
- ToolPolygon3d2::DeflectionOverEstimation(Obje2);
- if (Tolerance<=0.) Tolerance=Epsilon(1000.);
- Interference(Obje1, Obje2);
-}
-
-
-//=======================================================================
-//function : Perform
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::Perform
- (const Polygon3d1& Obje)
-{
- SelfInterference(Standard_True);
- IndexMin=0;
- Tolerance=ToolPolygon3d1::DeflectionOverEstimation(Obje)*2;
- Interference(Obje);
-}
-
-//--------------------------------------------------------
-// Return the number of singularity in the interference.
-//--------------------------------------------------------
-Standard_Integer Intf_InterferencePolygon3d::NbResults () const
-{
- return mySLines.Length();
-}
-
-//----------------------------------------------------------
-// Give the result of range Index in the interference.
-//----------------------------------------------------------
-const Intf_SectionLine& Intf_InterferencePolygon3d::ResultLine
- (const Standard_Integer Index) const
-{
- return mySLines(Index);
-}
-
-//=======================================================================
-//function : ResultValue
-//purpose : give the distance beetween the two polygons for this result.
-//=======================================================================
-
-Standard_Real Intf_InterferencePolygon3d::ResultValue
- (const Standard_Integer Index) const
-{
- return mySLines(Index).GetPoint(1).Pnt().Distance
- (mySLines(Index).GetPoint(2).Pnt());
-}
-
-//=======================================================================
-//function : MinimalDistance
-//purpose :
-//=======================================================================
-
-Standard_Real Intf_InterferencePolygon3d::MinimalDistance () const
-{
- return MinimalDist;
-}
-
-
-//=======================================================================
-//function : MinimalResult
-//purpose : give the result of minimal distance.
-//=======================================================================
-
-Standard_Integer Intf_InterferencePolygon3d::MinimalResult () const
-{
- return IndexMin;
-}
-
-//=======================================================================
-//function : Interference
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::Interference
- (const Polygon3d1& Obje1,
- const Polygon3d2& Obje2)
-{
- beginOfNotClosedFirst=!ToolPolygon3d1::Closed(Obje1);
- for (iObje1=1; iObje1<=ToolPolygon3d1::NbSegments(Obje1); iObje1++) {
- beginOfNotClosedSecon=!ToolPolygon3d2::Closed(Obje2);
- for (iObje2=1; iObje2<=ToolPolygon3d2::NbSegments(Obje2); iObje2++) {
-
- CommonPerpen(ToolPolygon3d1::BeginOfSeg(Obje1, iObje1),
- ToolPolygon3d1::EndOfSeg(Obje1, iObje1),
- ToolPolygon3d2::BeginOfSeg(Obje2, iObje2),
- ToolPolygon3d2::EndOfSeg(Obje2, iObje2));
-
- Projections(ToolPolygon3d1::BeginOfSeg(Obje1, iObje1),
- ToolPolygon3d1::EndOfSeg(Obje1, iObje1),
- ToolPolygon3d2::BeginOfSeg(Obje2, iObje2),
- ToolPolygon3d2::EndOfSeg(Obje2, iObje2));
-
- beginOfNotClosedSecon=Standard_False;
- }
- beginOfNotClosedFirst=Standard_False;
- }
-}
-
-//=======================================================================
-//function : Interference
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::Interference
- (const Polygon3d1& Obje)
-{
- beginOfNotClosedFirst=!ToolPolygon3d1::Closed(Obje);
- beginOfNotClosedSecon=Standard_False;
- for (iObje1=1; iObje1<=ToolPolygon3d1::NbSegments(Obje); iObje1++) {
- for (iObje2=iObje1+1; iObje2<=ToolPolygon3d1::NbSegments(Obje); iObje2++) {
-
- CommonPerpen(ToolPolygon3d1::BeginOfSeg(Obje, iObje1),
- ToolPolygon3d1::EndOfSeg(Obje, iObje1),
- ToolPolygon3d1::BeginOfSeg(Obje, iObje2),
- ToolPolygon3d1::EndOfSeg(Obje, iObje2));
-
- Projections(ToolPolygon3d1::BeginOfSeg(Obje, iObje1),
- ToolPolygon3d1::EndOfSeg(Obje, iObje1),
- ToolPolygon3d1::BeginOfSeg(Obje, iObje2),
- ToolPolygon3d1::EndOfSeg(Obje, iObje2));
-
- }
- beginOfNotClosedFirst=Standard_False;
- }
-}
-
-
-
-//=======================================================================
-//function : CommonPerpen
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::CommonPerpen
- (const gp_Pnt& BegO, const gp_Pnt& EndO,
- const gp_Pnt& BegT, const gp_Pnt& EndT)
-{
- gp_XYZ segT=EndT.XYZ()-BegT.XYZ();
- gp_XYZ segO=EndO.XYZ()-BegO.XYZ();
- gp_XYZ refPlane=segT^segO;
- Standard_Real lgsO=Sqrt(segT*segT);
- Standard_Real lgsT=Sqrt(segO*segO);
-
- if (lgsO<=Tolerance || lgsT<=Tolerance) {
- // Un des segments n a pas une longueur significative
- }
- else if (refPlane.Modulus()<Tolerance) {
- // Les deux segments sont paralleles
- }
- else {
- // Les deux segments ne sont pas parralleles
- Standard_Real distOP=(BegT.XYZ()*refPlane)/refPlane.Modulus();
- Standard_Real distTP=(BegO.XYZ()*refPlane)/refPlane.Modulus();
- Standard_Real lgPC=distOP-distTP;
-
- if (Abs(lgPC)< Tolerance) {
- // Les deux segments sont dans le meme plan
- }
- else {
- // Les deux segments ne sont pas dans le meme plan
-
- gp_XYZ pO=refPlane^segO; // Plan contenant segO normal a refPlane
- pO.Normalize();
- Standard_Real dpO=pO*BegO.XYZ();
-
- Standard_Real distBegTpO=(pO*BegT.XYZ())-dpO;
- Standard_Real distEndTpO=(pO*EndT.XYZ())-dpO;
- Standard_Real parT=-1.;
-
- if (distBegTpO*distEndTpO<0.)
- parT=distBegTpO/(distBegTpO-distEndTpO);
- else if (Abs(distBegTpO)<=Tolerance)
- parT=0.;
- else if (Abs(distEndTpO)<=Tolerance)
- parT=1.;
-
- if (parT>=0.) {
- gp_XYZ pT=refPlane^segT; // Plan contenant segT normal a refPlane
- pT.Normalize();
- Standard_Real dpT=pT*BegT.XYZ();
-
- Standard_Real distBegOpT=(pT*BegO.XYZ())-dpT;
- Standard_Real distEndOpT=(pT*EndO.XYZ())-dpT;
- Standard_Real parO=-1.;
-
- if (distBegOpT*distEndOpT<0.)
- parO=distBegOpT/(distBegOpT-distEndOpT);
- else if (Abs(distBegOpT)<=Tolerance)
- parO=0.;
- else if (Abs(distEndOpT)<=Tolerance)
- parO=1.;
-
- if (parO>=0.) {
- // Il y a une perpendiculaire commune interessante
- Intf_SectionLine PC;
- PC.Append(Intf_SectionPoint
- (BegO.Translated(gp_Vec(segO*parO)),
- Intf_EDGE, iObje1, 0, parO,
- Intf_EXTERNAL, 0, 0, 0., 0));
- PC.Append(Intf_SectionPoint
- (BegT.Translated(gp_Vec(segT*parT)),
- Intf_EXTERNAL, 0, 0, 0.,
- Intf_EDGE, iObje2, 0, parT, 0.));
- mySLines.Append(PC);
- Standard_Real dist=PC.GetPoint(1).Pnt().Distance
- (PC.GetPoint(2).Pnt());
- if (dist< MinimalDist) {
- MinimalDist=dist;
- IndexMin=mySLines.Length();
- }
- }
- }
- }
- }
-}
-
-//=======================================================================
-//function : Projections
-//purpose :
-//=======================================================================
-
-void Intf_InterferencePolygon3d::Projections
- (const gp_Pnt& BegO, const gp_Pnt& EndO,
- const gp_Pnt& BegT, const gp_Pnt& EndT)
-{
-}
-
-// EOF File: Intf_InterferencePolygon3d.gxx