From: dln Date: Fri, 28 Mar 2014 05:55:22 +0000 (+0400) Subject: 0024774: Convertation of the generic classes to the non-generic. Part 8 X-Git-Tag: V6_8_0_beta~438 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=424cd6bb6436d4c685f077ffa41bc4c5b41a0960;p=occt-copy.git 0024774: Convertation of the generic classes to the non-generic. Part 8 Generic classes: "GProp_CGProps", "GProp_SGProps", "GProp_VGProps", "GProp_VGPropsGK", "GProp_TFunction" (internal), "GProp_UFunction" (internal) from "GProp" package converted to the non-generic classes and moved to the "BRepGProp" package. Names of several classes were changed to: "BRepGProp_Cinert", "BRepGProp_Sinert", "BRepGProp_Vinert", "BRepGProp_VinertGK". Also all instantiations of the "internal" classes of this classes were moved to the "Geom2dHatch.cdl". For new "BRepGProp_TFunction" and "BRepGProp_UFunction" internal classes two new "*.cdl" files were created. --- diff --git a/src/BRepGProp/BRepGProp.cdl b/src/BRepGProp/BRepGProp.cdl index 1f715631f6..d69d6ad188 100644 --- a/src/BRepGProp/BRepGProp.cdl +++ b/src/BRepGProp/BRepGProp.cdl @@ -45,26 +45,23 @@ is class EdgeTool; class Face; - + class Domain; + + class Cinert; - class Cinert instantiates CGProps from GProp( Curve from BRepAdaptor, - EdgeTool from BRepGProp); - - class Sinert instantiates SGProps from GProp( Edge from TopoDS, - Face from BRepGProp , - Domain from BRepGProp); + class Sinert; + + class Vinert; + + class VinertGK; + + class UFunction; + class TFunction; - class Vinert instantiates VGProps from GProp( Edge from TopoDS, - Face from BRepGProp, - Domain from BRepGProp); - - class VinertGK instantiates VGPropsGK from GProp( Edge from TopoDS, - Face from BRepGProp, - Domain from BRepGProp); -- -- Package methods to compute global properties. - -- + -- LinearProperties(S : Shape from TopoDS; LProps : in out GProps from GProp); ---Purpose: Computes the linear global properties of the shape S, @@ -233,7 +230,3 @@ is end BRepGProp; - - - - diff --git a/src/BRepGProp/BRepGProp_Cinert.cdl b/src/BRepGProp/BRepGProp_Cinert.cdl new file mode 100644 index 0000000000..6c4a032629 --- /dev/null +++ b/src/BRepGProp/BRepGProp_Cinert.cdl @@ -0,0 +1,46 @@ +-- Created on: 1991-04-11 +-- Created by: Michel CHAUVAT +-- Copyright (c) 1991-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. + +-- Jean-Claude Vauthier January 1992, September 1992 + + +class Cinert from BRepGProp inherits GProps from GProp + + --- Purpose : + -- Computes the global properties of bounded curves + -- in 3D space. The curve must have at least a continuity C1. + -- It can be a curve as defined in the template CurveTool from + -- package GProp. This template gives the minimum of methods + -- required to evaluate the global properties of a curve 3D with + -- the algorithmes of GProp. + +uses Pnt from gp, + Curve from BRepAdaptor, + EdgeTool from BRepGProp + +is + + Create returns Cinert; + + Create (C : Curve from BRepAdaptor; CLocation : Pnt) returns Cinert; + + SetLocation(me : in out;CLocation : Pnt) ; + + Perform(me : in out; C : Curve from BRepAdaptor); + +end Cinert; + + diff --git a/src/BRepGProp/BRepGProp_Cinert.cxx b/src/BRepGProp/BRepGProp_Cinert.cxx new file mode 100644 index 0000000000..cd1ae71348 --- /dev/null +++ b/src/BRepGProp/BRepGProp_Cinert.cxx @@ -0,0 +1,154 @@ +// 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 + +#include +#include +#include + +BRepGProp_Cinert::BRepGProp_Cinert(){} + +void BRepGProp_Cinert::SetLocation(const gp_Pnt& CLocation) +{ + loc = CLocation; +} + +void BRepGProp_Cinert::Perform (const BRepAdaptor_Curve& C) +{ + + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + + Standard_Real Lower = BRepGProp_EdgeTool::FirstParameter (C); + Standard_Real Upper = BRepGProp_EdgeTool::LastParameter (C); + Standard_Integer Order = Min(BRepGProp_EdgeTool::IntegrationOrder (C), + math::GaussPointsMax()); + + gp_Pnt P; //value on the curve + gp_Vec V1; //first derivative on the curve + Standard_Real ds; //curvilign abscissae + Standard_Real ur, um, u; + Standard_Real x, y, z; + Standard_Real xloc, yloc, zloc; + + math_Vector GaussP (1, Order); + math_Vector GaussW (1, Order); + + //Recuperation des points de Gauss dans le fichier GaussPoints. + math::GaussPoints (Order,GaussP); + math::GaussWeights (Order,GaussW); + + // modified by NIZHNY-MKK Thu Jun 9 12:13:21 2005.BEGIN + Standard_Integer nbIntervals = BRepGProp_EdgeTool::NbIntervals(C, GeomAbs_CN); + Standard_Boolean bHasIntervals = (nbIntervals > 1); + TColStd_Array1OfReal TI(1, nbIntervals + 1); + + if(bHasIntervals) { + BRepGProp_EdgeTool::Intervals(C, TI, GeomAbs_CN); + } + else { + nbIntervals = 1; + } + Standard_Integer nIndex = 0; + Standard_Real UU1 = Min(Lower, Upper); + Standard_Real UU2 = Max(Lower, Upper); + + for(nIndex = 1; nIndex <= nbIntervals; nIndex++) { + if(bHasIntervals) { + Lower = Max(TI(nIndex), UU1); + Upper = Min(TI(nIndex+1), UU2); + } + else { + Lower = UU1; + Upper = UU2; + } + + Standard_Real dimLocal, IxLocal, IyLocal, IzLocal, IxxLocal, IyyLocal, IzzLocal, IxyLocal, IxzLocal, IyzLocal; + dimLocal = IxLocal = IyLocal = IzLocal = IxxLocal = IyyLocal = IzzLocal = IxyLocal = IxzLocal = IyzLocal = 0.0; + // modified by NIZHNY-MKK Thu Jun 9 12:13:32 2005.END + + loc.Coord (xloc, yloc, zloc); + + Standard_Integer i; + + // Calcul des integrales aux points de gauss : + um = 0.5 * (Upper + Lower); + ur = 0.5 * (Upper - Lower); + + for (i = 1; i <= Order; i++) { + u = um + ur * GaussP (i); + BRepGProp_EdgeTool::D1 (C,u, P, V1); + ds = V1.Magnitude(); + P.Coord (x, y, z); + x -= xloc; + y -= yloc; + z -= zloc; + ds *= GaussW (i); + dimLocal += ds; + IxLocal += x * ds; + IyLocal += y * ds; + IzLocal += z * ds; + IxyLocal += x * y * ds; + IyzLocal += y * z * ds; + IxzLocal += x * z * ds; + x *= x; + y *= y; + z *= z; + IxxLocal += (y + z) * ds; + IyyLocal += (x + z) * ds; + IzzLocal += (x + y) * ds; + } + // modified by NIZHNY-MKK Thu Jun 9 12:13:47 2005.BEGIN + dimLocal *= ur; + IxLocal *= ur; + IyLocal *= ur; + IzLocal *= ur; + IxxLocal *= ur; + IyyLocal *= ur; + IzzLocal *= ur; + IxyLocal *= ur; + IxzLocal *= ur; + IyzLocal *= ur; + + dim += dimLocal; + Ix += IxLocal; + Iy += IyLocal; + Iz += IzLocal; + Ixx += IxxLocal; + Iyy += IyyLocal; + Izz += IzzLocal; + Ixy += IxyLocal; + Ixz += IxzLocal; + Iyz += IyzLocal; + } + // modified by NIZHNY-MKK Thu Jun 9 12:13:55 2005.END + + inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), + gp_XYZ (-Ixy, Iyy, -Iyz), + gp_XYZ (-Ixz, -Iyz, Izz)); + + if (Abs(dim) < gp::Resolution()) + g = P; + else + g.SetCoord (Ix/dim, Iy/dim, Iz/dim); +} + + +BRepGProp_Cinert::BRepGProp_Cinert (const BRepAdaptor_Curve& C, + const gp_Pnt& CLocation) +{ + SetLocation(CLocation); + Perform(C); +} diff --git a/src/BRepGProp/BRepGProp_Face.cxx b/src/BRepGProp/BRepGProp_Face.cxx index 61052a4c1c..d694054391 100644 --- a/src/BRepGProp/BRepGProp_Face.cxx +++ b/src/BRepGProp/BRepGProp_Face.cxx @@ -13,23 +13,24 @@ // commercial license or contractual agreement. #include -#include + #include -#include -#include -#include -#include + +#include #include #include +#include +#include +#include +#include + #include + #include #include #include -#include + #include -#include -#include -#include //======================================================================= //function : UIntegrationOrder @@ -37,32 +38,33 @@ //======================================================================= Standard_Integer BRepGProp_Face::UIntegrationOrder() const { - - Standard_Integer Nu; - switch (mySurface.GetType()) { - case GeomAbs_Plane : - Nu =4; - break; + Standard_Integer Nu; + switch (mySurface.GetType()) + { - case GeomAbs_BezierSurface : - { - Nu = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; - Nu = Max(4,Nu); - } - break; - case GeomAbs_BSplineSurface : - { - Standard_Integer a = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; - Standard_Integer b = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbUKnots()-1; - Nu = Max(4,a*b); - } - break; + case GeomAbs_Plane : + Nu =4; + break; - default : - Nu = 9; - break; - } + case GeomAbs_BezierSurface : + { + Nu = (*((Handle(Geom_BezierSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; + Nu = Max(4,Nu); + } + break; + case GeomAbs_BSplineSurface : + { + Standard_Integer a = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->UDegree()+1; + Standard_Integer b = (*((Handle(Geom_BSplineSurface)*)&((mySurface.Surface()).Surface())))->NbUKnots()-1; + Nu = Max(4,a*b); + } + break; + + default : + Nu = 9; + break; + } return Max(8,2*Nu); } diff --git a/src/BRepGProp/BRepGProp_Sinert.cdl b/src/BRepGProp/BRepGProp_Sinert.cdl new file mode 100644 index 0000000000..31dd2c3e11 --- /dev/null +++ b/src/BRepGProp/BRepGProp_Sinert.cdl @@ -0,0 +1,62 @@ +-- Created on: 1991-04-12 +-- Created by: Michel CHAUVAT +-- Copyright (c) 1991-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. + +-- Jean-Claude VAUTHIER January 1992 + + +class Sinert from BRepGProp inherits GProps + + --- Purpose : + -- Computes the global properties of a face in 3D space. + -- The face 's requirements to evaluate the global properties + -- are defined in the template FaceTool from package GProp. + +uses Pnt from gp, + Edge from TopoDS, + Face from BRepGProp, + Domain from BRepGProp +is + + Create returns Sinert; + + Create (S: Face; SLocation: Pnt) returns Sinert; + Create (S : in out Face; D : in out Domain; SLocation : Pnt) returns Sinert; + --- Purpose : + -- Builds a Sinert to evaluate the global properties of + -- the face . If isNaturalRestriction is true the domain of S is defined + -- with the natural bounds, else it defined with an iterator + -- of Edge from TopoDS (see DomainTool from GProp) + Create (S: in out Face; SLocation: Pnt; Eps: Real) returns Sinert; + Create (S: in out Face; D : in out Domain; SLocation: Pnt; Eps: Real) returns Sinert; + -- --"-- + -- Parameter Eps sets maximal relative error of computed area. + + SetLocation(me: in out; SLocation: Pnt); + + Perform(me: in out; S: Face); + Perform(me : in out; S : in out Face ; D : in out Domain); + Perform(me: in out; S: in out Face; Eps: Real) returns Real; + Perform(me: in out; S: in out Face; D : in out Domain; Eps: Real) returns Real; + + GetEpsilon(me: out) returns Real; + --- Purpose : + -- If previously used method contained Eps parameter + -- get actual relative error of the computation, else return 1.0. +fields + + myEpsilon: Real from Standard; + +end Sinert; diff --git a/src/BRepGProp/BRepGProp_Sinert.cxx b/src/BRepGProp/BRepGProp_Sinert.cxx new file mode 100644 index 0000000000..fcd267435a --- /dev/null +++ b/src/BRepGProp/BRepGProp_Sinert.cxx @@ -0,0 +1,1021 @@ +// 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 + +#include +#include +#include + +class HMath_Vector{ + math_Vector *pvec; + void operator=(const math_Vector&){} + public: + HMath_Vector(){ pvec = 0;} + HMath_Vector(math_Vector* pv){ pvec = pv;} + ~HMath_Vector(){ if(pvec != 0) delete pvec;} + void operator=(math_Vector* pv){ if(pvec != pv && pvec != 0) delete pvec; pvec = pv;} + Standard_Real& operator()(Standard_Integer i){ return (*pvec).operator()(i);} + const Standard_Real& operator()(Standard_Integer i) const{ return (*pvec).operator()(i);} + const math_Vector* operator->() const{ return pvec;} + math_Vector* operator->(){ return pvec;} + math_Vector* Vector(){ return pvec;} + math_Vector* Init(Standard_Real v, Standard_Integer i = 0, Standard_Integer iEnd = 0){ + if(pvec == 0) return pvec; + if(iEnd - i == 0) pvec->Init(v); + else { Standard_Integer End = (iEnd <= pvec->Upper()) ? iEnd : pvec->Upper(); + for(; i <= End; i++) pvec->operator()(i) = v; } + return pvec; + } +}; + +static Standard_Real EPS_PARAM = 1.e-12; +static Standard_Real EPS_DIM = 1.e-20; +static Standard_Real ERROR_ALGEBR_RATIO = 2.0/3.0; + +static Standard_Integer GPM = 61; +static Standard_Integer SUBS_POWER = 32; +static Standard_Integer SM = 1953; + +static math_Vector LGaussP0(1,GPM); +static math_Vector LGaussW0(1,GPM); +static math_Vector LGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); +static math_Vector LGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); + +static math_Vector* LGaussP[] = {&LGaussP0,&LGaussP1}; +static math_Vector* LGaussW[] = {&LGaussW0,&LGaussW1}; + +static HMath_Vector L1 = new math_Vector(1,SM,0.0); +static HMath_Vector L2 = new math_Vector(1,SM,0.0); +static HMath_Vector DimL = new math_Vector(1,SM,0.0); +static HMath_Vector ErrL = new math_Vector(1,SM,0.0); +static HMath_Vector ErrUL = new math_Vector(1,SM,0.0); +static HMath_Vector IxL = new math_Vector(1,SM,0.0); +static HMath_Vector IyL = new math_Vector(1,SM,0.0); +static HMath_Vector IzL = new math_Vector(1,SM,0.0); +static HMath_Vector IxxL = new math_Vector(1,SM,0.0); +static HMath_Vector IyyL = new math_Vector(1,SM,0.0); +static HMath_Vector IzzL = new math_Vector(1,SM,0.0); +static HMath_Vector IxyL = new math_Vector(1,SM,0.0); +static HMath_Vector IxzL = new math_Vector(1,SM,0.0); +static HMath_Vector IyzL = new math_Vector(1,SM,0.0); + +static math_Vector UGaussP0(1,GPM); +static math_Vector UGaussW0(1,GPM); +static math_Vector UGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); +static math_Vector UGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); + +static math_Vector* UGaussP[] = {&UGaussP0,&UGaussP1}; +static math_Vector* UGaussW[] = {&UGaussW0,&UGaussW1}; + +static HMath_Vector U1 = new math_Vector(1,SM,0.0); +static HMath_Vector U2 = new math_Vector(1,SM,0.0); +static HMath_Vector DimU = new math_Vector(1,SM,0.0); +static HMath_Vector ErrU = new math_Vector(1,SM,0.0); +static HMath_Vector IxU = new math_Vector(1,SM,0.0); +static HMath_Vector IyU = new math_Vector(1,SM,0.0); +static HMath_Vector IzU = new math_Vector(1,SM,0.0); +static HMath_Vector IxxU = new math_Vector(1,SM,0.0); +static HMath_Vector IyyU = new math_Vector(1,SM,0.0); +static HMath_Vector IzzU = new math_Vector(1,SM,0.0); +static HMath_Vector IxyU = new math_Vector(1,SM,0.0); +static HMath_Vector IxzU = new math_Vector(1,SM,0.0); +static HMath_Vector IyzU = new math_Vector(1,SM,0.0); + +static inline Standard_Real MultiplicationInf(Standard_Real theMA, Standard_Real theMB) +{ + if((theMA == 0.0) || (theMB == 0.0)) //strictly zerro (without any tolerances) + return 0.0; + + if(Precision::IsPositiveInfinite(theMA)) + { + if(theMB < 0.0) + return -Precision::Infinite(); + else + return Precision::Infinite(); + } + + if(Precision::IsPositiveInfinite(theMB)) + { + if(theMA < 0.0) + return -Precision::Infinite(); + else + return Precision::Infinite(); + } + + if(Precision::IsNegativeInfinite(theMA)) + { + if(theMB < 0.0) + return +Precision::Infinite(); + else + return -Precision::Infinite(); + } + + if(Precision::IsNegativeInfinite(theMB)) + { + if(theMA < 0.0) + return +Precision::Infinite(); + else + return -Precision::Infinite(); + } + + return (theMA * theMB); +} + +static inline Standard_Real AdditionInf(Standard_Real theMA, Standard_Real theMB) +{ + if(Precision::IsPositiveInfinite(theMA)) + { + if(Precision::IsNegativeInfinite(theMB)) + return 0.0; + else + return Precision::Infinite(); + } + + if(Precision::IsPositiveInfinite(theMB)) + { + if(Precision::IsNegativeInfinite(theMA)) + return 0.0; + else + return Precision::Infinite(); + } + + if(Precision::IsNegativeInfinite(theMA)) + { + if(Precision::IsPositiveInfinite(theMB)) + return 0.0; + else + return -Precision::Infinite(); + } + + if(Precision::IsNegativeInfinite(theMB)) + { + if(Precision::IsPositiveInfinite(theMA)) + return 0.0; + else + return -Precision::Infinite(); + } + + return (theMA + theMB); +} + +static inline Standard_Real Multiplication(Standard_Real theMA, Standard_Real theMB) +{ + return (theMA * theMB); +} + +static inline Standard_Real Addition(Standard_Real theMA, Standard_Real theMB) +{ + return (theMA + theMB); +} + +static Standard_Integer FillIntervalBounds(Standard_Real A, + Standard_Real B, + const TColStd_Array1OfReal& Knots, + HMath_Vector& VA, + HMath_Vector& VB) +{ + Standard_Integer i = 1, iEnd = Knots.Upper(), j = 1, k = 1; + VA(j++) = A; + for(; i <= iEnd; i++){ + Standard_Real kn = Knots(i); + if(A < kn) + { + if(kn < B) + { + VA(j++) = VB(k++) = kn; + } + else + { + break; + } + } + } + VB(k) = B; + return k; +} + +static inline Standard_Integer MaxSubs(Standard_Integer n, Standard_Integer coeff = SUBS_POWER){ + // return n = IntegerLast()/coeff < n? IntegerLast(): n*coeff + 1; + return Min((n * coeff + 1),SM); +} + +static Standard_Integer LFillIntervalBounds(Standard_Real A, + Standard_Real B, + const TColStd_Array1OfReal& Knots, + const Standard_Integer NumSubs) +{ + Standard_Integer iEnd = Knots.Upper(), jEnd = L1->Upper(); + if(iEnd - 1 > jEnd){ + iEnd = MaxSubs(iEnd-1,NumSubs); + L1 = new math_Vector(1,iEnd); + L2 = new math_Vector(1,iEnd); + DimL = new math_Vector(1,iEnd); + ErrL = new math_Vector(1,iEnd,0.0); + ErrUL = new math_Vector(1,iEnd,0.0); + IxL = new math_Vector(1,iEnd); + IyL = new math_Vector(1,iEnd); + IzL = new math_Vector(1,iEnd); + IxxL = new math_Vector(1,iEnd); + IyyL = new math_Vector(1,iEnd); + IzzL = new math_Vector(1,iEnd); + IxyL = new math_Vector(1,iEnd); + IxzL = new math_Vector(1,iEnd); + IyzL = new math_Vector(1,iEnd); + } + return FillIntervalBounds(A, B, Knots, L1, L2); +} + +static Standard_Integer UFillIntervalBounds(Standard_Real A, + Standard_Real B, + const TColStd_Array1OfReal& Knots, + const Standard_Integer NumSubs) +{ + Standard_Integer iEnd = Knots.Upper(), jEnd = U1->Upper(); + if(iEnd - 1 > jEnd){ + iEnd = MaxSubs(iEnd-1,NumSubs); + U1 = new math_Vector(1,iEnd); + U2 = new math_Vector(1,iEnd); + DimU = new math_Vector(1,iEnd); + ErrU = new math_Vector(1,iEnd,0.0); + IxU = new math_Vector(1,iEnd); + IyU = new math_Vector(1,iEnd); + IzU = new math_Vector(1,iEnd); + IxxU = new math_Vector(1,iEnd); + IyyU = new math_Vector(1,iEnd); + IzzU = new math_Vector(1,iEnd); + IxyU = new math_Vector(1,iEnd); + IxzU = new math_Vector(1,iEnd); + IyzU = new math_Vector(1,iEnd); + } + return FillIntervalBounds(A, B, Knots, U1, U2); +} + +static Standard_Real CCompute(BRepGProp_Face& S, + BRepGProp_Domain& D, + const gp_Pnt& loc, + Standard_Real& Dim, + gp_Pnt& g, + gp_Mat& inertia, + const Standard_Real EpsDim, + const Standard_Boolean isErrorCalculation, + const Standard_Boolean isVerifyComputation) +{ + Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); + Standard_Real (*FuncMul)(Standard_Real, Standard_Real); + + FuncAdd = Addition; + FuncMul = Multiplication; + + Standard_Boolean isNaturalRestriction = S.NaturalRestriction(); + + Standard_Integer NumSubs = SUBS_POWER; + + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + Dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + Standard_Real x, y, z; + //boundary curve parametrization + Standard_Real l1, l2, lm, lr, l; + //BRepGProp_Face parametrization in U and V direction + Standard_Real BV1, BV2, v; + Standard_Real BU1, BU2, u1, u2, um, ur, u; + S.Bounds (BU1, BU2, BV1, BV2); + u1 = BU1; + + if(Precision::IsInfinite(BU1) || Precision::IsInfinite(BU2) || + Precision::IsInfinite(BV1) || Precision::IsInfinite(BV2)) + { + FuncAdd = AdditionInf; + FuncMul = MultiplicationInf; + } + + + //location point used to compute the inertia + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); // use member of parent class + //Jacobien (x, y, z) -> (u, v) = ||n|| + Standard_Real ds; + //On the BRepGProp_Face + gp_Pnt Ps; + gp_Vec VNor; + //On the boundary curve u-v + gp_Pnt2d Puv; + gp_Vec2d Vuv; + Standard_Real Dul; // Dul = Du / Dl + Standard_Real CDim[2], CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz; + Standard_Real LocDim[2], LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, LocIxz, LocIyz; + + Standard_Real ErrorU, ErrorL, ErrorLMax = 0.0, Eps=0.0, EpsL=0.0, EpsU=0.0; + + Standard_Integer iD = 0, NbLSubs, iLS, iLSubEnd, iGL, iGLEnd, NbLGaussP[2], LRange[2], iL, kL, kLEnd, IL, JL; + Standard_Integer i, NbUSubs, iUS, iUSubEnd, iGU, iGUEnd, NbUGaussP[2], URange[2], iU, kU, kUEnd, IU, JU; + Standard_Integer UMaxSubs, LMaxSubs; + iGLEnd = isErrorCalculation? 2: 1; + for(i = 0; i < 2; i++) { + LocDim[i] = 0.0; + CDim[i] = 0.0; + } + + NbUGaussP[0] = S.SIntOrder(EpsDim); + NbUGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbUGaussP[0])); + math::GaussPoints(NbUGaussP[0],UGaussP0); math::GaussWeights(NbUGaussP[0],UGaussW0); + math::GaussPoints(NbUGaussP[1],UGaussP1); math::GaussWeights(NbUGaussP[1],UGaussW1); + + NbUSubs = S.SUIntSubs(); + TColStd_Array1OfReal UKnots(1,NbUSubs+1); + S.UKnots(UKnots); + + while (isNaturalRestriction || D.More()) + { + if(isNaturalRestriction) + { + NbLGaussP[0] = Min(2*NbUGaussP[0],math::GaussPointsMax()); + } + else + { + S.Load(D.Value()); ++iD; + NbLGaussP[0] = S.LIntOrder(EpsDim); + } + + NbLGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbLGaussP[0])); + math::GaussPoints(NbLGaussP[0],LGaussP0); math::GaussWeights(NbLGaussP[0],LGaussW0); + math::GaussPoints(NbLGaussP[1],LGaussP1); math::GaussWeights(NbLGaussP[1],LGaussW1); + + NbLSubs = isNaturalRestriction? S.SVIntSubs(): S.LIntSubs(); + + TColStd_Array1OfReal LKnots(1,NbLSubs+1); + if(isNaturalRestriction) + { + S.VKnots(LKnots); + l1 = BV1; l2 = BV2; + } + else + { + S.LKnots(LKnots); + l1 = S.FirstParameter(); l2 = S.LastParameter(); + } + + ErrorL = 0.0; + kLEnd = 1; JL = 0; + //OCC503(apo): if(Abs(l2-l1) < EPS_PARAM) continue; + if(Abs(l2-l1) > EPS_PARAM) + { + iLSubEnd = LFillIntervalBounds(l1, l2, LKnots, NumSubs); + LMaxSubs = MaxSubs(iLSubEnd); + if(LMaxSubs > DimL.Vector()->Upper()) + LMaxSubs = DimL.Vector()->Upper(); + + DimL.Init(0.0,1,LMaxSubs); ErrL.Init(0.0,1,LMaxSubs); ErrUL.Init(0.0,1,LMaxSubs); + + do{// while: L + if(++JL > iLSubEnd) + { + LRange[0] = IL = ErrL->Max(); + LRange[1] = JL; + L1(JL) = (L1(IL) + L2(IL))/2.0; + L2(JL) = L2(IL); + L2(IL) = L1(JL); + } + else + LRange[0] = IL = JL; + + if(JL == LMaxSubs || Abs(L2(JL) - L1(JL)) < EPS_PARAM) + if(kLEnd == 1) + { + DimL(JL) = ErrL(JL) = IxL(JL) = IyL(JL) = IzL(JL) = + IxxL(JL) = IyyL(JL) = IzzL(JL) = IxyL(JL) = IxzL(JL) = IyzL(JL) = 0.0; + }else{ + JL--; + EpsL = ErrorL; Eps = EpsL/0.9; + break; + } + else + for(kL=0; kL < kLEnd; kL++) + { + iLS = LRange[kL]; + lm = 0.5*(L2(iLS) + L1(iLS)); + lr = 0.5*(L2(iLS) - L1(iLS)); + CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; + + for(iGL=0; iGL < iGLEnd; iGL++) + { + CDim[iGL] = 0.0; + for(iL=1; iL<=NbLGaussP[iGL]; iL++) + { + l = lm + lr*(*LGaussP[iGL])(iL); + if(isNaturalRestriction) + { + v = l; u2 = BU2; Dul = (*LGaussW[iGL])(iL); + } + else + { + S.D12d (l, Puv, Vuv); + Dul = Vuv.Y()*(*LGaussW[iGL])(iL); // Dul = Du / Dl + if(Abs(Dul) < EPS_PARAM) + continue; + + v = Puv.Y(); + u2 = Puv.X(); + //Check on cause out off bounds of value current parameter + if(v < BV1) + v = BV1; + else if(v > BV2) + v = BV2; + + if(u2 < BU1) + u2 = BU1; + else if(u2 > BU2) + u2 = BU2; + } + + ErrUL(iLS) = 0.0; + kUEnd = 1; + JU = 0; + + if(Abs(u2-u1) < EPS_PARAM) + continue; + + iUSubEnd = UFillIntervalBounds(u1, u2, UKnots, NumSubs); + UMaxSubs = MaxSubs(iUSubEnd); + if(UMaxSubs > DimU.Vector()->Upper()) + UMaxSubs = DimU.Vector()->Upper(); + + DimU.Init(0.0,1,UMaxSubs); ErrU.Init(0.0,1,UMaxSubs); ErrorU = 0.0; + + do{//while: U + if(++JU > iUSubEnd) + { + URange[0] = IU = ErrU->Max(); + URange[1] = JU; + U1(JU) = (U1(IU)+U2(IU))/2.0; + U2(JU) = U2(IU); + U2(IU) = U1(JU); + } + else + URange[0] = IU = JU; + + if(JU == UMaxSubs || Abs(U2(JU) - U1(JU)) < EPS_PARAM) + if(kUEnd == 1) + { + DimU(JU) = ErrU(JU) = IxU(JU) = IyU(JU) = IzU(JU) = + IxxU(JU) = IyyU(JU) = IzzU(JU) = IxyU(JU) = IxzU(JU) = IyzU(JU) = 0.0; + }else + { + JU--; + EpsU = ErrorU; Eps = EpsU*Abs((u2-u1)*Dul)/0.1; EpsL = 0.9*Eps; + break; + } + else + for(kU=0; kU < kUEnd; kU++) + { + iUS = URange[kU]; + um = 0.5*(U2(iUS) + U1(iUS)); + ur = 0.5*(U2(iUS) - U1(iUS)); + LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = LocIxy = LocIxz = LocIyz = 0.0; + iGUEnd = iGLEnd - iGL; + for(iGU=0; iGU < iGUEnd; iGU++) + { + LocDim[iGU] = 0.0; + for(iU=1; iU <= NbUGaussP[iGU]; iU++) + { + u = um + ur*(*UGaussP[iGU])(iU); + S.Normal(u, v, Ps, VNor); + ds = VNor.Magnitude(); //Jacobien(x,y,z) -> (u,v)=||n|| + ds *= (*UGaussW[iGU])(iU); + LocDim[iGU] += ds; + + if(iGU > 0) + continue; + + Ps.Coord(x, y, z); + x = FuncAdd(x, -xloc); + y = FuncAdd(y, -yloc); + z = FuncAdd(z, -zloc); + + const Standard_Real XdS = FuncMul(x, ds); + const Standard_Real YdS = FuncMul(y, ds); + const Standard_Real ZdS = FuncMul(z, ds); + + LocIx = FuncAdd(LocIx, XdS); + LocIy = FuncAdd(LocIy, YdS); + LocIz = FuncAdd(LocIz, ZdS); + LocIxy = FuncAdd(LocIxy, FuncMul(x, YdS)); + LocIyz = FuncAdd(LocIyz, FuncMul(y, ZdS)); + LocIxz = FuncAdd(LocIxz, FuncMul(x, ZdS)); + + const Standard_Real XXdS = FuncMul(x, XdS); + const Standard_Real YYdS = FuncMul(y, YdS); + const Standard_Real ZZdS = FuncMul(z, ZdS); + + LocIxx = FuncAdd(LocIxx, FuncAdd(YYdS, ZZdS)); + LocIyy = FuncAdd(LocIyy, FuncAdd(XXdS, ZZdS)); + LocIzz = FuncAdd(LocIzz, FuncAdd(XXdS, YYdS)); + }//for: iU + }//for: iGU + + DimU(iUS) = FuncMul(LocDim[0],ur); + if(iGL > 0) + continue; + + ErrU(iUS) = FuncMul(Abs(LocDim[1]-LocDim[0]), ur); + IxU(iUS) = FuncMul(LocIx, ur); + IyU(iUS) = FuncMul(LocIy, ur); + IzU(iUS) = FuncMul(LocIz, ur); + IxxU(iUS) = FuncMul(LocIxx, ur); + IyyU(iUS) = FuncMul(LocIyy, ur); + IzzU(iUS) = FuncMul(LocIzz, ur); + IxyU(iUS) = FuncMul(LocIxy, ur); + IxzU(iUS) = FuncMul(LocIxz, ur); + IyzU(iUS) = FuncMul(LocIyz, ur); + }//for: kU (iUS) + + if(JU == iUSubEnd) + kUEnd = 2; + + if(kUEnd == 2) + ErrorU = ErrU(ErrU->Max()); + }while((ErrorU - EpsU > 0.0 && EpsU != 0.0) || kUEnd == 1); + + for(i=1; i<=JU; i++) + CDim[iGL] = FuncAdd(CDim[iGL], FuncMul(DimU(i), Dul)); + + if(iGL > 0) + continue; + + ErrUL(iLS) = ErrorU*Abs((u2-u1)*Dul); + for(i=1; i<=JU; i++) + { + CIx = FuncAdd(CIx, FuncMul(IxU(i), Dul)); + CIy = FuncAdd(CIy, FuncMul(IyU(i), Dul)); + CIz = FuncAdd(CIz, FuncMul(IzU(i), Dul)); + CIxx = FuncAdd(CIxx, FuncMul(IxxU(i), Dul)); + CIyy = FuncAdd(CIyy, FuncMul(IyyU(i), Dul)); + CIzz = FuncAdd(CIzz, FuncMul(IzzU(i), Dul)); + CIxy = FuncAdd(CIxy, FuncMul(IxyU(i), Dul)); + CIxz = FuncAdd(CIxz, FuncMul(IxzU(i), Dul)); + CIyz = FuncAdd(CIyz, FuncMul(IyzU(i), Dul)); + } + }//for: iL + }//for: iGL + + DimL(iLS) = FuncMul(CDim[0], lr); + if(iGLEnd == 2) + ErrL(iLS) = FuncAdd(FuncMul(Abs(CDim[1]-CDim[0]),lr), ErrUL(iLS)); + + IxL(iLS) = FuncMul(CIx, lr); + IyL(iLS) = FuncMul(CIy, lr); + IzL(iLS) = FuncMul(CIz, lr); + IxxL(iLS) = FuncMul(CIxx, lr); + IyyL(iLS) = FuncMul(CIyy, lr); + IzzL(iLS) = FuncMul(CIzz, lr); + IxyL(iLS) = FuncMul(CIxy, lr); + IxzL(iLS) = FuncMul(CIxz, lr); + IyzL(iLS) = FuncMul(CIyz, lr); + }//for: (kL)iLS + // Calculate/correct epsilon of computation by current value of Dim + //That is need for not spend time for + if(JL == iLSubEnd) + { + kLEnd = 2; + Standard_Real DDim = 0.0; + for(i=1; i<=JL; i++) + DDim += DimL(i); + + DDim = Abs(DDim*EpsDim); + if(DDim > Eps) + { + Eps = DDim; + EpsL = 0.9*Eps; + } + } + + if(kLEnd == 2) + ErrorL = ErrL(ErrL->Max()); + }while((ErrorL - EpsL > 0.0 && isVerifyComputation) || kLEnd == 1); + + for(i=1; i<=JL; i++) + { + Dim = FuncAdd(Dim, DimL(i)); + Ix = FuncAdd(Ix, IxL(i)); + Iy = FuncAdd(Iy, IyL(i)); + Iz = FuncAdd(Iz, IzL(i)); + Ixx = FuncAdd(Ixx, IxxL(i)); + Iyy = FuncAdd(Iyy, IyyL(i)); + Izz = FuncAdd(Izz, IzzL(i)); + Ixy = FuncAdd(Ixy, IxyL(i)); + Ixz = FuncAdd(Ixz, IxzL(i)); + Iyz = FuncAdd(Iyz, IyzL(i)); + } + + ErrorLMax = Max(ErrorLMax, ErrorL); + } + + if(isNaturalRestriction) + break; + + D.Next(); + } + + if(Abs(Dim) >= EPS_DIM) + { + Ix /= Dim; + Iy /= Dim; + Iz /= Dim; + g.SetCoord (Ix, Iy, Iz); + } + else + { + Dim =0.0; + g.SetCoord (0., 0.,0.); + } + + inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), + gp_XYZ (-Ixy, Iyy, -Iyz), + gp_XYZ (-Ixz, -Iyz, Izz)); + + if(iGLEnd == 2) + Eps = Dim != 0.0? ErrorLMax/Abs(Dim): 0.0; + else + Eps = EpsDim; + + return Eps; +} + +static Standard_Real Compute(BRepGProp_Face& S, const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, + Standard_Real EpsDim) +{ + Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; + Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; + EpsDim = Abs(EpsDim); + BRepGProp_Domain D; + return CCompute(S,D,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); +} + +static Standard_Real Compute(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, + Standard_Real EpsDim) +{ + Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; + Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; + EpsDim = Abs(EpsDim); + return CCompute(S,D,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); +} + +static void Compute(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& loc, Standard_Real& dim, gp_Pnt& g, gp_Mat& inertia) +{ + Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); + Standard_Real (*FuncMul)(Standard_Real, Standard_Real); + + FuncAdd = Addition; + FuncMul = Multiplication; + + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + + Standard_Real x, y, z; + Standard_Integer NbCGaussgp_Pnts = 0; + + Standard_Real l1, l2, lm, lr, l; //boundary curve parametrization + Standard_Real v1, v2, v; //BRepGProp_Face parametrization in v direction + Standard_Real u1, u2, um, ur, u; + Standard_Real ds; //Jacobien (x, y, z) -> (u, v) = ||n|| + + gp_Pnt P; //On the BRepGProp_Face + gp_Vec VNor; + + gp_Pnt2d Puv; //On the boundary curve u-v + gp_Vec2d Vuv; + Standard_Real Dul; // Dul = Du / Dl + Standard_Real CArea, CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz; + Standard_Real LocArea, LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, + LocIxz, LocIyz; + + + S.Bounds (u1, u2, v1, v2); + + if(Precision::IsInfinite(u1) || Precision::IsInfinite(u2) || + Precision::IsInfinite(v1) || Precision::IsInfinite(v2)) + { + FuncAdd = AdditionInf; + FuncMul = MultiplicationInf; + } + + + Standard_Integer NbUGaussgp_Pnts = Min(S.UIntegrationOrder (), + math::GaussPointsMax()); + Standard_Integer NbVGaussgp_Pnts = Min(S.VIntegrationOrder (), + math::GaussPointsMax()); + + Standard_Integer NbGaussgp_Pnts = Max(NbUGaussgp_Pnts, NbVGaussgp_Pnts); + + //Number of Gauss points for the integration + //on the BRepGProp_Face + math_Vector GaussSPV (1, NbGaussgp_Pnts); + math_Vector GaussSWV (1, NbGaussgp_Pnts); + math::GaussPoints (NbGaussgp_Pnts,GaussSPV); + math::GaussWeights (NbGaussgp_Pnts,GaussSWV); + + + //location point used to compute the inertia + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + + while (D.More()) { + + S.Load(D.Value()); + NbCGaussgp_Pnts = Min(S.IntegrationOrder (), math::GaussPointsMax()); + + math_Vector GaussCP (1, NbCGaussgp_Pnts); + math_Vector GaussCW (1, NbCGaussgp_Pnts); + math::GaussPoints (NbCGaussgp_Pnts,GaussCP); + math::GaussWeights (NbCGaussgp_Pnts,GaussCW); + + CArea = 0.0; + CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; + l1 = S.FirstParameter (); + l2 = S.LastParameter (); + lm = 0.5 * (l2 + l1); + lr = 0.5 * (l2 - l1); + + for (Standard_Integer i = 1; i <= NbCGaussgp_Pnts; i++) { + l = lm + lr * GaussCP (i); + S.D12d(l, Puv, Vuv); + v = Puv.Y(); + u2 = Puv.X(); + Dul = Vuv.Y(); + Dul *= GaussCW (i); + um = 0.5 * (u2 + u1); + ur = 0.5 * (u2 - u1); + LocArea = LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = + LocIxy = LocIxz = LocIyz = 0.0; + for (Standard_Integer j = 1; j <= NbGaussgp_Pnts; j++) { + u = FuncAdd(um, FuncMul(ur, GaussSPV (j))); + S.Normal (u, v, P, VNor); + ds = VNor.Magnitude(); //normal.Magnitude + ds = FuncMul(ds, Dul) * GaussSWV (j); + LocArea = FuncAdd(LocArea, ds); + P.Coord (x, y, z); + + x = FuncAdd(x, -xloc); + y = FuncAdd(y, -yloc); + z = FuncAdd(z, -zloc); + + const Standard_Real XdS = FuncMul(x, ds); + const Standard_Real YdS = FuncMul(y, ds); + const Standard_Real ZdS = FuncMul(z, ds); + + LocIx = FuncAdd(LocIx, XdS); + LocIy = FuncAdd(LocIy, YdS); + LocIz = FuncAdd(LocIz, ZdS); + LocIxy = FuncAdd(LocIxy, FuncMul(x, YdS)); + LocIyz = FuncAdd(LocIyz, FuncMul(y, ZdS)); + LocIxz = FuncAdd(LocIxz, FuncMul(x, ZdS)); + + const Standard_Real XXdS = FuncMul(x, XdS); + const Standard_Real YYdS = FuncMul(y, YdS); + const Standard_Real ZZdS = FuncMul(z, ZdS); + + LocIxx = FuncAdd(LocIxx, FuncAdd(YYdS, ZZdS)); + LocIyy = FuncAdd(LocIyy, FuncAdd(XXdS, ZZdS)); + LocIzz = FuncAdd(LocIzz, FuncAdd(XXdS, YYdS)); + } + + CArea = FuncAdd(CArea, FuncMul(LocArea, ur)); + CIx = FuncAdd(CIx, FuncMul(LocIx, ur)); + CIy = FuncAdd(CIy, FuncMul(LocIy, ur)); + CIz = FuncAdd(CIz, FuncMul(LocIz, ur)); + CIxx = FuncAdd(CIxx, FuncMul(LocIxx, ur)); + CIyy = FuncAdd(CIyy, FuncMul(LocIyy, ur)); + CIzz = FuncAdd(CIzz, FuncMul(LocIzz, ur)); + CIxy = FuncAdd(CIxy, FuncMul(LocIxy, ur)); + CIxz = FuncAdd(CIxz, FuncMul(LocIxz, ur)); + CIyz = FuncAdd(CIyz, FuncMul(LocIyz, ur)); + } + + dim = FuncAdd(dim, FuncMul(CArea, lr)); + Ix = FuncAdd(Ix, FuncMul(CIx, lr)); + Iy = FuncAdd(Iy, FuncMul(CIy, lr)); + Iz = FuncAdd(Iz, FuncMul(CIz, lr)); + Ixx = FuncAdd(Ixx, FuncMul(CIxx, lr)); + Iyy = FuncAdd(Iyy, FuncMul(CIyy, lr)); + Izz = FuncAdd(Izz, FuncMul(CIzz, lr)); + Ixy = FuncAdd(Ixy, FuncMul(CIxy, lr)); + Ixz = FuncAdd(Iyz, FuncMul(CIxz, lr)); + Iyz = FuncAdd(Ixz, FuncMul(CIyz, lr)); + D.Next(); + } + + if (Abs(dim) >= EPS_DIM) { + Ix /= dim; + Iy /= dim; + Iz /= dim; + g.SetCoord (Ix, Iy, Iz); + } + else { + dim =0.; + g.SetCoord (0., 0.,0.); + } + + inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), + gp_XYZ (-Ixy, Iyy, -Iyz), + gp_XYZ (-Ixz, -Iyz, Izz)); +} + +static void Compute(const BRepGProp_Face& S, + const gp_Pnt& loc, + Standard_Real& dim, + gp_Pnt& g, + gp_Mat& inertia) +{ + Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); + Standard_Real (*FuncMul)(Standard_Real, Standard_Real); + + FuncAdd = Addition; + FuncMul = Multiplication; + + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + + Standard_Real LowerU, UpperU, LowerV, UpperV; + S.Bounds (LowerU, UpperU, LowerV, UpperV); + + if(Precision::IsInfinite(LowerU) || Precision::IsInfinite(UpperU) || + Precision::IsInfinite(LowerV) || Precision::IsInfinite(UpperV)) + { + FuncAdd = AdditionInf; + FuncMul = MultiplicationInf; + } + + Standard_Integer UOrder = Min(S.UIntegrationOrder (), + math::GaussPointsMax()); + Standard_Integer VOrder = Min(S.VIntegrationOrder (), + math::GaussPointsMax()); + gp_Pnt P; + gp_Vec VNor; + Standard_Real dsi, ds; + Standard_Real ur, um, u, vr, vm, v; + Standard_Real x, y, z; + Standard_Real Ixi, Iyi, Izi, Ixxi, Iyyi, Izzi, Ixyi, Ixzi, Iyzi; + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + + Standard_Integer i, j; + math_Vector GaussPU (1, UOrder); //gauss points and weights + math_Vector GaussWU (1, UOrder); + math_Vector GaussPV (1, VOrder); + math_Vector GaussWV (1, VOrder); + + //Recuperation des points de Gauss dans le fichier GaussPoints. + math::GaussPoints (UOrder,GaussPU); + math::GaussWeights (UOrder,GaussWU); + math::GaussPoints (VOrder,GaussPV); + math::GaussWeights (VOrder,GaussWV); + + // Calcul des integrales aux points de gauss : + um = 0.5 * FuncAdd(UpperU, LowerU); + vm = 0.5 * FuncAdd(UpperV, LowerV); + ur = 0.5 * FuncAdd(UpperU, -LowerU); + vr = 0.5 * FuncAdd(UpperV, -LowerV); + + for (j = 1; j <= VOrder; j++) { + v = FuncAdd(vm, FuncMul(vr, GaussPV(j))); + dsi = Ixi = Iyi = Izi = Ixxi = Iyyi = Izzi = Ixyi = Ixzi = Iyzi = 0.0; + + for (i = 1; i <= UOrder; i++) { + u = FuncAdd(um, FuncMul(ur, GaussPU (i))); + S.Normal (u, v, P, VNor); + ds = FuncMul(VNor.Magnitude(), GaussWU (i)); + P.Coord (x, y, z); + + x = FuncAdd(x, -xloc); + y = FuncAdd(y, -yloc); + z = FuncAdd(z, -zloc); + + dsi = FuncAdd(dsi, ds); + + const Standard_Real XdS = FuncMul(x, ds); + const Standard_Real YdS = FuncMul(y, ds); + const Standard_Real ZdS = FuncMul(z, ds); + + Ixi = FuncAdd(Ixi, XdS); + Iyi = FuncAdd(Iyi, YdS); + Izi = FuncAdd(Izi, ZdS); + Ixyi = FuncAdd(Ixyi, FuncMul(x, YdS)); + Iyzi = FuncAdd(Iyzi, FuncMul(y, ZdS)); + Ixzi = FuncAdd(Ixzi, FuncMul(x, ZdS)); + + const Standard_Real XXdS = FuncMul(x, XdS); + const Standard_Real YYdS = FuncMul(y, YdS); + const Standard_Real ZZdS = FuncMul(z, ZdS); + + Ixxi = FuncAdd(Ixxi, FuncAdd(YYdS, ZZdS)); + Iyyi = FuncAdd(Iyyi, FuncAdd(XXdS, ZZdS)); + Izzi = FuncAdd(Izzi, FuncAdd(XXdS, YYdS)); + } + + dim = FuncAdd(dim, FuncMul(dsi, GaussWV (j))); + Ix = FuncAdd(Ix, FuncMul(Ixi, GaussWV (j))); + Iy = FuncAdd(Iy, FuncMul(Iyi, GaussWV (j))); + Iz = FuncAdd(Iz, FuncMul(Izi, GaussWV (j))); + Ixx = FuncAdd(Ixx, FuncMul(Ixxi, GaussWV (j))); + Iyy = FuncAdd(Iyy, FuncMul(Iyyi, GaussWV (j))); + Izz = FuncAdd(Izz, FuncMul(Izzi, GaussWV (j))); + Ixy = FuncAdd(Ixy, FuncMul(Ixyi, GaussWV (j))); + Iyz = FuncAdd(Iyz, FuncMul(Iyzi, GaussWV (j))); + Ixz = FuncAdd(Ixz, FuncMul(Ixzi, GaussWV (j))); + } + + vr = FuncMul(vr, ur); + Ixx = FuncMul(vr, Ixx); + Iyy = FuncMul(vr, Iyy); + Izz = FuncMul(vr, Izz); + Ixy = FuncMul(vr, Ixy); + Ixz = FuncMul(vr, Ixz); + Iyz = FuncMul(vr, Iyz); + + if (Abs(dim) >= EPS_DIM) + { + Ix /= dim; + Iy /= dim; + Iz /= dim; + dim *= vr; + g.SetCoord (Ix, Iy, Iz); + } + else + { + dim =0.; + g.SetCoord (0.,0.,0.); + } + + inertia = gp_Mat (gp_XYZ ( Ixx, -Ixy, -Ixz), + gp_XYZ (-Ixy, Iyy, -Iyz), + gp_XYZ (-Ixz, -Iyz, Izz)); +} + +BRepGProp_Sinert::BRepGProp_Sinert(){} + +BRepGProp_Sinert::BRepGProp_Sinert (const BRepGProp_Face& S, + const gp_Pnt& SLocation + ) +{ + SetLocation(SLocation); + Perform(S); +} + +BRepGProp_Sinert::BRepGProp_Sinert (BRepGProp_Face& S, + BRepGProp_Domain& D, + const gp_Pnt& SLocation + ) +{ + SetLocation(SLocation); + Perform(S,D); +} + +BRepGProp_Sinert::BRepGProp_Sinert(BRepGProp_Face& S, const gp_Pnt& SLocation, const Standard_Real Eps){ + SetLocation(SLocation); + Perform(S, Eps); +} + +BRepGProp_Sinert::BRepGProp_Sinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& SLocation, const Standard_Real Eps){ + SetLocation(SLocation); + Perform(S, D, Eps); +} + +void BRepGProp_Sinert::SetLocation(const gp_Pnt& SLocation){ + loc = SLocation; +} + +void BRepGProp_Sinert::Perform(const BRepGProp_Face& S){ + Compute(S,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +void BRepGProp_Sinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D){ + Compute(S,D,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +Standard_Real BRepGProp_Sinert::Perform(BRepGProp_Face& S, const Standard_Real Eps){ + return myEpsilon = Compute(S,loc,dim,g,inertia,Eps); +} + +Standard_Real BRepGProp_Sinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const Standard_Real Eps){ + return myEpsilon = Compute(S,D,loc,dim,g,inertia,Eps); +} + + +Standard_Real BRepGProp_Sinert::GetEpsilon(){ + return myEpsilon; +} diff --git a/src/BRepGProp/BRepGProp_TFunction.cdl b/src/BRepGProp/BRepGProp_TFunction.cdl new file mode 100644 index 0000000000..9ce55cc418 --- /dev/null +++ b/src/BRepGProp/BRepGProp_TFunction.cdl @@ -0,0 +1,126 @@ +-- Created on: 2005-12-21 +-- Created by: Sergey KHROMOV +-- Copyright (c) 2005-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 TFunction from BRepGProp inherits Function from math + + ---Purpose: This class represents the integrand function for the outer + -- integral computation. The returned value represents the + -- integral of UFunction. It depends on the value type and the + -- flag IsByPoint. + +uses + + Pnt from gp, + Address from Standard, + Boolean from Standard, + Integer from Standard, + Real from Standard, + ValueType from GProp, + UFunction from BRepGProp, + Face from BRepGProp + +is + + Create(theSurface : Face from BRepGProp; + theVertex : Pnt from gp; + IsByPoint : Boolean from Standard; + theCoeffs : Address from Standard; + theUMin : Real from Standard; + theTolerance: Real from Standard) + ---Purpose: Constructor. Initializes the function with the face, the + -- location point, the flag IsByPoint, the coefficients + -- theCoeff that have different meaning depending on the value + -- of IsByPoint. The last two parameters are theUMin - the + -- lower bound of the inner integral. This value is fixed for + -- any integral. And the value of tolerance of inner integral + -- computation. + -- If IsByPoint is equal to Standard_True, the number of the + -- coefficients is equal to 3 and they represent X, Y and Z + -- coordinates (theCoeff[0], theCoeff[1] and theCoeff[2] + -- correspondingly) of the shift if the inertia is computed + -- with respect to the point different then the location. + -- If IsByPoint is equal to Standard_False, the number of the + -- coefficients is 4 and they represent the compbination of + -- plane parameters and shift values. + returns TFunction from BRepGProp; + + Init(me: in out); + + SetNbKronrodPoints(me: in out; theNbPoints: Integer from Standard); + ---Purpose: Setting the expected number of Kronrod points for the outer + -- integral computation. This number is required for + -- computation of a value of tolerance for inner integral + -- computation. After GetStateNumber method call, this number + -- is recomputed by the same law as in + -- math_KronrodSingleIntegration, i.e. next number of points + -- is equal to the current number plus a square root of the + -- current number. If the law in math_KronrodSingleIntegration + -- is changed, the modification algo should be modified + -- accordingly. + ---C++: inline + + SetValueType(me: in out; aType: ValueType from GProp); + ---Purpose: Setting the type of the value to be returned. This + -- parameter is directly passed to the UFunction. + ---C++: inline + + SetTolerance(me: in out; aTol: Real from Standard); + ---Purpose: Setting the tolerance for inner integration + ---C++: inline + + ErrorReached(me) + ---Purpose: Returns the relative reached error of all values computation since + -- the last call of GetStateNumber method. + ---C++: inline + returns Real from Standard; + + AbsolutError(me) + ---Purpose: Returns the absolut reached error of all values computation since + -- the last call of GetStateNumber method. + ---C++: inline + returns Real from Standard; + + Value(me: in out; X: Real from Standard; + F: out Real from Standard) + ---Purpose: Returns a value of the function. The value represents an + -- integral of UFunction. It is computed with the predefined + -- tolerance using the adaptive Gauss-Kronrod method. + returns Boolean from Standard + is redefined; + + GetStateNumber(me: in out) + ---Purpose: Redefined method. Remembers the error reached during + -- computation of integral values since the object creation + -- or the last call of GetStateNumber. It is invoked in each + -- algorithm from the package math. Particularly in the + -- algorithm math_KronrodSingleIntegration that is used to + -- compute the integral of TFunction. + returns Integer + is redefined; + +fields + + mySurface : Face from BRepGProp; + myUFunction : UFunction from BRepGProp; + myUMin : Real from Standard; + myTolerance : Real from Standard; + myTolReached: Real from Standard; + myErrReached: Real from Standard; + myAbsError : Real from Standard; + myValueType : ValueType from GProp; + myIsByPoint : Boolean from Standard; + myNbPntOuter: Integer from Standard; + +end TFunction; diff --git a/src/BRepGProp/BRepGProp_TFunction.cxx b/src/BRepGProp/BRepGProp_TFunction.cxx new file mode 100644 index 0000000000..af020dc7ca --- /dev/null +++ b/src/BRepGProp/BRepGProp_TFunction.cxx @@ -0,0 +1,183 @@ +// Created on: 2005-12-09 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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 + +#include +#include +#include + +//======================================================================= +//function : Constructor. +//purpose : +//======================================================================= + +BRepGProp_TFunction::BRepGProp_TFunction(const BRepGProp_Face &theSurface, + const gp_Pnt &theVertex, + const Standard_Boolean IsByPoint, + const Standard_Address theCoeffs, + const Standard_Real theUMin, + const Standard_Real theTolerance): + mySurface(theSurface), + myUFunction(mySurface, theVertex, IsByPoint, theCoeffs), + myUMin(theUMin), + myTolerance(theTolerance), + myTolReached(0.), + myErrReached(0.), + myAbsError(0.), + myValueType(GProp_Unknown), + myIsByPoint(IsByPoint), + myNbPntOuter(3) +{ +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= + +void BRepGProp_TFunction::Init() +{ + myTolReached = 0.; + myErrReached = 0.; + myAbsError = 0.; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= + +Standard_Boolean BRepGProp_TFunction::Value(const Standard_Real X, + Standard_Real &F) +{ + const Standard_Real tolU = 1.e-9; + + gp_Pnt2d aP2d; + gp_Vec2d aV2d; + Standard_Real aUMax; + Handle(TColStd_HArray1OfReal) anUKnots; + + mySurface.D12d(X, aP2d, aV2d); + aUMax = aP2d.X(); + + if(aUMax - myUMin < tolU) + { + F = 0.; + return Standard_True; + } + + mySurface.GetUKnots(myUMin, aUMax, anUKnots); + myUFunction.SetVParam(aP2d.Y()); + + // Compute the integral from myUMin to aUMax of myUFunction. + Standard_Integer i; + Standard_Real aCoeff = aV2d.Y(); + //Standard_Integer aNbUIntervals = anUKnots->Length() - 1; + //Standard_Real aTol = myTolerance/aNbUIntervals; + Standard_Real aTol = myTolerance; + + //aTol /= myNbPntOuter; + + if (myValueType == GProp_Mass) { + if (myIsByPoint) + aCoeff /= 3.; + } else if (myValueType == GProp_CenterMassX || + myValueType == GProp_CenterMassY || + myValueType == GProp_CenterMassZ) { + if (myIsByPoint) + aCoeff *= 0.25; + } else if (myValueType == GProp_InertiaXX || + myValueType == GProp_InertiaYY || + myValueType == GProp_InertiaZZ || + myValueType == GProp_InertiaXY || + myValueType == GProp_InertiaXZ || + myValueType == GProp_InertiaYZ) { + if (myIsByPoint) + aCoeff *= 0.2; + } else + return Standard_False; + + Standard_Real aAbsCoeff = Abs(aCoeff); + + if (aAbsCoeff <= Precision::Angular()) { + // No need to compute the integral. The value will be equal to 0. + F = 0.; + return Standard_True; + } + //else if (aAbsCoeff > 10.*aTol) + // aTol /= aAbsCoeff; + //else + // aTol = 0.1; + + Standard_Integer iU = anUKnots->Upper(); + Standard_Integer aNbPntsStart; + Standard_Integer aNbMaxIter = 1000; + math_KronrodSingleIntegration anIntegral; + Standard_Real aLocalErr = 0.; + + i = anUKnots->Lower(); + F = 0.; + + // Epmirical criterion + aNbPntsStart = Min(15, mySurface.UIntegrationOrder()/(anUKnots->Length() - 1)+1); + aNbPntsStart = Max(5, aNbPntsStart); + + while (i < iU) { + Standard_Real aU1 = anUKnots->Value(i++); + Standard_Real aU2 = anUKnots->Value(i); + + if(aU2 - aU1 < tolU) continue; + + anIntegral.Perform(myUFunction, aU1, aU2, aNbPntsStart, aTol, aNbMaxIter); + + if (!anIntegral.IsDone()) + return Standard_False; + + F += anIntegral.Value(); + aLocalErr += anIntegral.AbsolutError(); + //cout << " TFunction : " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << endl; + } + + F *= aCoeff; + aLocalErr *= aAbsCoeff; + myAbsError = Max(myAbsError, aLocalErr); + + myTolReached += aLocalErr; + + if(Abs(F) > Epsilon(1.)) aLocalErr /= Abs(F); + + myErrReached = Max(myErrReached, aLocalErr); + + + return Standard_True; +} + +//======================================================================= +//function : GetStateNumber +//purpose : +//======================================================================= + +Standard_Integer BRepGProp_TFunction::GetStateNumber() +{ + //myErrReached = myTolReached; + //myTolReached = 0.; + //myNbPntOuter += RealToInt(0.5*myNbPntOuter); + + //if (myNbPntOuter%2 == 0) + //myNbPntOuter++; + + return 0; +} diff --git a/src/BRepGProp/BRepGProp_TFunction.lxx b/src/BRepGProp/BRepGProp_TFunction.lxx new file mode 100644 index 0000000000..d746a8c9c1 --- /dev/null +++ b/src/BRepGProp/BRepGProp_TFunction.lxx @@ -0,0 +1,66 @@ +// Created on: 2005-12-21 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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. + +//======================================================================= +//function : SetNbKronrodPoints +//purpose : +//======================================================================= + +inline void BRepGProp_TFunction::SetNbKronrodPoints + (const Standard_Integer theNbPoints) +{ + myNbPntOuter = (theNbPoints%2 == 0) ? theNbPoints + 1 : theNbPoints; +} + +//======================================================================= +//function : SetValueType +//purpose : +//======================================================================= + +inline void BRepGProp_TFunction::SetValueType(const GProp_ValueType theType) +{ + myValueType = theType; + myUFunction.SetValueType(myValueType); +} + +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= + +inline void BRepGProp_TFunction::SetTolerance(const Standard_Real theTolerance) +{ + myTolerance = theTolerance; +} + +//======================================================================= +//function : TolReached +//purpose : +//======================================================================= + +inline Standard_Real BRepGProp_TFunction::ErrorReached() const +{ + return myErrReached; +} + +//======================================================================= +//function : ErrorReached +//purpose : +//======================================================================= + +inline Standard_Real BRepGProp_TFunction::AbsolutError() const +{ + return myAbsError; +} diff --git a/src/BRepGProp/BRepGProp_UFunction.cdl b/src/BRepGProp/BRepGProp_UFunction.cdl new file mode 100644 index 0000000000..d64281fa5e --- /dev/null +++ b/src/BRepGProp/BRepGProp_UFunction.cdl @@ -0,0 +1,129 @@ +-- Created on: 2005-12-21 +-- Created by: Sergey KHROMOV +-- Copyright (c) 2005-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 UFunction from BRepGProp inherits Function from math + + ---Purpose: This class represents the integrand function for + -- computation of an inner integral. The returned value + -- depends on the value type and the flag IsByPoint. + -- + -- The type of returned value is the one of the following + -- values: + -- - GProp_Mass - volume computation. + -- - GProp_CenterMassX, GProp_CenterMassY, + -- GProp_CenterMassZ - X, Y and Z coordinates of center + -- of mass computation. + -- - GProp_InertiaXX, GProp_InertiaYY, GProp_InertiaZZ, + -- GProp_InertiaXY, GProp_InertiaXZ, GProp_InertiaYZ + -- - moments of inertia computation. + -- + -- If the flag IsByPoint is set to Standard_True, the value is + -- returned for the region of space that is delimited by a + -- surface and a point. Otherwise all computations are + -- performed for the region of space delimited by a surface + -- and a plane. + +uses + Pnt from gp, + XYZ from gp, + Address from Standard, + Boolean from Standard, + Real from Standard, + ValueType from GProp, + Face from BRepGProp + +is + + Create(theSurface: Face from BRepGProp; + theVertex : Pnt from gp; + IsByPoint : Boolean from Standard; + theCoeffs : Address from Standard) + ---Purpose: Constructor. Initializes the function with the face, the + -- location point, the flag IsByPoint and the coefficients + -- theCoeff that have different meaning depending on the value + -- of IsByPoint. + -- If IsByPoint is equal to Standard_True, the number of the + -- coefficients is equal to 3 and they represent X, Y and Z + -- coordinates (theCoeff[0], theCoeff[1] and theCoeff[2] + -- correspondingly) of the shift, if the inertia is computed + -- with respect to the point different then the location. + -- If IsByPoint is equal to Standard_False, the number of the + -- coefficients is 4 and they represent the combination of + -- plane parameters and shift values. + returns UFunction from BRepGProp; + + SetValueType(me: in out; theType: ValueType from GProp); + ---Purpose: Setting the type of the value to be returned. + ---C++: inline + + SetVParam(me: in out; theVParam: Real from Standard); + ---Purpose: Setting the V parameter that is constant during the + -- integral computation. + ---C++: inline + + Value(me: in out; X: Real from Standard; + F: out Real from Standard) + ---Purpose: Returns a value of the function. + returns Boolean from Standard + is redefined; + + ----------------------- + -- Private methods -- + ----------------------- + + VolumeValue(me: in out; X : Real from Standard; + thePMP0: out XYZ from gp; + theS : out Real from Standard; + theD1 : out Real from Standard) + ---Purpose: Private method. Returns the value for volume computation. + -- Other returned values are: + -- - thePMP0 - PSurf(X,Y) minus Location. + -- - theS and theD1 coeffitients that are computed and used + -- for computation of center of mass and inertia values + -- by plane. + returns Real from Standard + is private; + + CenterMassValue(me: in out; X: Real from Standard; + F: out Real from Standard) + ---Purpose: Private method. Returns a value for the center of mass + -- computation. If the value type other then GProp_CenterMassX, + -- GProp_CenterMassY or GProp_CenterMassZ this method returns + -- Standard_False. Returns Standard_True in case of successful + -- computation of a value. + returns Boolean from Standard + is private; + + InertiaValue(me: in out; X: Real from Standard; + F: out Real from Standard) + ---Purpose: Private method. Computes the value of intertia. The type of + -- a value returned is defined by the value type. If it is + -- other then GProp_InertiaXX, GProp_InertiaYY, + -- GProp_InertiaZZ, GProp_InertiaXY, GProp_InertiaXZ or + -- GProp_InertiaYZ, the method returns Standard_False. Returns + -- Standard_True in case of successful computation of a value + returns Boolean from Standard + is private; + +fields + + mySurface : Face from BRepGProp; + myVertex : Pnt from gp; + myCoeffs : Address from Standard; + myVParam : Real from Standard; + myValueType: ValueType from GProp; + myIsByPoint: Boolean from Standard; + +end UFunction; diff --git a/src/BRepGProp/BRepGProp_UFunction.cxx b/src/BRepGProp/BRepGProp_UFunction.cxx new file mode 100644 index 0000000000..2cebff943f --- /dev/null +++ b/src/BRepGProp/BRepGProp_UFunction.cxx @@ -0,0 +1,268 @@ +// Created on: 2005-12-09 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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 + +//======================================================================= +//function : Constructor. +//purpose : +//======================================================================= + +BRepGProp_UFunction::BRepGProp_UFunction(const BRepGProp_Face &theSurface, + const gp_Pnt &theVertex, + const Standard_Boolean IsByPoint, + const Standard_Address theCoeffs) + : mySurface(theSurface), + myVertex(theVertex), + myCoeffs(theCoeffs), + myVParam(0.), + myValueType(GProp_Unknown), + myIsByPoint(IsByPoint) +{ +} + +//======================================================================= +//function : Value +//purpose : Returns a value of the function. +//======================================================================= + +Standard_Boolean BRepGProp_UFunction::Value(const Standard_Real X, + Standard_Real &F) +{ + // Volume computation + if (myValueType == GProp_Mass) { + gp_XYZ aPMP0; + Standard_Real aTmpPar1; + Standard_Real aTmpPar2; + + F = VolumeValue(X, aPMP0, aTmpPar1, aTmpPar2); + + return Standard_True; + } + + // Center of mass computation + if (myValueType == GProp_CenterMassX || + myValueType == GProp_CenterMassY || + myValueType == GProp_CenterMassZ) + return CenterMassValue(X, F); + + // Inertia computation + if (myValueType == GProp_InertiaXX || + myValueType == GProp_InertiaYY || + myValueType == GProp_InertiaZZ || + myValueType == GProp_InertiaXY || + myValueType == GProp_InertiaXZ || + myValueType == GProp_InertiaYZ) + return InertiaValue(X, F); + + return Standard_False; +} + +//======================================================================= +//function : VolumeValue +//purpose : Returns the value for volume computation. +//======================================================================= + +Standard_Real BRepGProp_UFunction::VolumeValue(const Standard_Real X, + gp_XYZ &thePMP0, + Standard_Real &theS, + Standard_Real &theD1) +{ + gp_Pnt aPnt; + gp_Vec aNorm; + + mySurface.Normal(X, myVParam, aPnt, aNorm); + + thePMP0 = aPnt.XYZ().Subtracted(myVertex.XYZ()); + + // Volume computation for ByPoint mode. + if (myIsByPoint) + return thePMP0.Dot(aNorm.XYZ()); + + // Volume and additional coefficients computation for ByPlane mode. + Standard_Real *aCoeff = (Standard_Real *)myCoeffs; + + theS = aNorm.X()*aCoeff[0] + aNorm.Y()*aCoeff[1] + aNorm.Z()*aCoeff[2]; + theD1 = thePMP0.X()*aCoeff[0] + thePMP0.Y()*aCoeff[1] + + thePMP0.Z()*aCoeff[2] - aCoeff[3]; + + return theS*theD1; +} + +//======================================================================= +//function : CenterMassValue +//purpose : Returns a value for the center of mass computation. +//======================================================================= + +Standard_Boolean BRepGProp_UFunction::CenterMassValue(const Standard_Real X, + Standard_Real &F) +{ + gp_XYZ aPmP0; + Standard_Real aS; + Standard_Real aD1; + + F = VolumeValue(X, aPmP0, aS, aD1); + + // Center of mass computation for ByPoint mode. + if (myIsByPoint) { + switch (myValueType) { + case GProp_CenterMassX: F *= aPmP0.X(); break; + case GProp_CenterMassY: F *= aPmP0.Y(); break; + case GProp_CenterMassZ: F *= aPmP0.Z(); break; + default: + return Standard_False; + } + + return Standard_True; + } + + // Center of mass computation for ByPlane mode. + Standard_Real *aCoeff = (Standard_Real *)myCoeffs; + + switch (myValueType) { + case GProp_CenterMassX: F *= (aPmP0.X() - 0.5*aCoeff[0]*aD1); break; + case GProp_CenterMassY: F *= (aPmP0.Y() - 0.5*aCoeff[1]*aD1); break; + case GProp_CenterMassZ: F *= (aPmP0.Z() - 0.5*aCoeff[2]*aD1); break; + default: + return Standard_False; + } + + return Standard_True; +} + +//======================================================================= +//function : InertiaValue +//purpose : Compute the value of intertia. +//======================================================================= + +Standard_Boolean BRepGProp_UFunction::InertiaValue(const Standard_Real X, + Standard_Real &F) +{ + gp_XYZ aPmP0; + Standard_Real aS; + Standard_Real aD1; + Standard_Real aParam1; + Standard_Real aParam2; + Standard_Real *aCoeffs = (Standard_Real *)myCoeffs; + + F = VolumeValue(X, aPmP0, aS, aD1); + + // Inertia computation for ByPoint mode. + if (myIsByPoint) { + switch(myValueType) { + case GProp_InertiaXX: + case GProp_InertiaYZ: + aParam1 = aPmP0.Y() - aCoeffs[1]; + aParam2 = aPmP0.Z() - aCoeffs[2]; + break; + case GProp_InertiaYY: + case GProp_InertiaXZ: + aParam1 = aPmP0.X() - aCoeffs[0]; + aParam2 = aPmP0.Z() - aCoeffs[2]; + break; + case GProp_InertiaZZ: + case GProp_InertiaXY: + aParam1 = aPmP0.X() - aCoeffs[0]; + aParam2 = aPmP0.Y() - aCoeffs[1]; + break; + default: + return Standard_False; + } + + if (myValueType == GProp_InertiaXX || + myValueType == GProp_InertiaYY || + myValueType == GProp_InertiaZZ) + F *= aParam1*aParam1 + aParam2*aParam2; + else + F *= -aParam1*aParam2; + + return Standard_True; + } + + // Inertia computation for ByPlane mode. + Standard_Real aD2 = aD1*aD1; + Standard_Real aD3 = aD1*aD2/3.; + Standard_Real aPPar1; + Standard_Real aPPar2; + Standard_Real aCoeff1; + Standard_Real aCoeff2; + + // Inertia computation for XX, YY and ZZ. + if (myValueType == GProp_InertiaXX || + myValueType == GProp_InertiaYY || + myValueType == GProp_InertiaZZ) { + + if (myValueType == GProp_InertiaXX) { + aPPar1 = aPmP0.Y(); + aPPar2 = aPmP0.Z(); + aCoeff1 = aCoeffs[1]; + aCoeff2 = aCoeffs[2]; + } else if (myValueType == GProp_InertiaYY) { + aPPar1 = aPmP0.X(); + aPPar2 = aPmP0.Z(); + aCoeff1 = aCoeffs[0]; + aCoeff2 = aCoeffs[2]; + } else { // myValueType == GProp_InertiaZZ + aPPar1 = aPmP0.X(); + aPPar2 = aPmP0.Y(); + aCoeff1 = aCoeffs[0]; + aCoeff2 = aCoeffs[1]; + } + + aPPar1 -= aCoeff1*aD1; + aPPar2 -= aCoeff2*aD1; + aParam1 = aPPar1*aPPar1*aD1 + aPPar1*aCoeff1*aD2 + aCoeff1*aCoeff1*aD3; + aParam2 = aPPar2*aPPar2*aD1 + aPPar2*aCoeff2*aD2 + aCoeff2*aCoeff2*aD3; + + F = (aParam1 + aParam2)*aS; + + return Standard_True; + } + + // Inertia computation for XY, YZ and XZ. + if (myValueType == GProp_InertiaXY || + myValueType == GProp_InertiaYZ || + myValueType == GProp_InertiaXZ) { + + if (myValueType == GProp_InertiaXY) { + aPPar1 = aPmP0.X(); + aPPar2 = aPmP0.Y(); + aCoeff1 = aCoeffs[0]; + aCoeff2 = aCoeffs[1]; + } else if (myValueType == GProp_InertiaYZ) { + aPPar1 = aPmP0.Y(); + aPPar2 = aPmP0.Z(); + aCoeff1 = aCoeffs[1]; + aCoeff2 = aCoeffs[2]; + } else { // myValueType == GProp_InertiaXZ + aPPar1 = aPmP0.X(); + aPPar2 = aPmP0.Z(); + aCoeff1 = aCoeffs[0]; + aCoeff2 = aCoeffs[2]; + } + + aD2 *= 0.5; + aPPar1 -= aCoeff1*aD1; + aPPar2 -= aCoeff2*aD1; + aParam1 = aPPar1*aPPar2*aD1 + + (aPPar1*aCoeff2 + aPPar2*aCoeff1)*aD2 + aCoeff1*aCoeff2*aD3; + + F = -aParam1*aS; + + return Standard_True; + } + + return Standard_False; +} diff --git a/src/BRepGProp/BRepGProp_UFunction.lxx b/src/BRepGProp/BRepGProp_UFunction.lxx new file mode 100644 index 0000000000..e74afe9f8a --- /dev/null +++ b/src/BRepGProp/BRepGProp_UFunction.lxx @@ -0,0 +1,35 @@ +// Created on: 2005-12-21 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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. + +//======================================================================= +//function : SetValueType +//purpose : Setting the type of the value to be returned. +//======================================================================= + +inline void BRepGProp_UFunction::SetValueType(const GProp_ValueType theType) +{ + myValueType = theType; +} + +//======================================================================= +//function : SetVParam +//purpose : Setting the V parameter that is constant during the +// integral computation. +//======================================================================= + +inline void BRepGProp_UFunction::SetVParam(const Standard_Real theVParam) +{ + myVParam = theVParam; +} diff --git a/src/BRepGProp/BRepGProp_Vinert.cdl b/src/BRepGProp/BRepGProp_Vinert.cdl new file mode 100644 index 0000000000..0773b24718 --- /dev/null +++ b/src/BRepGProp/BRepGProp_Vinert.cdl @@ -0,0 +1,195 @@ +-- Created on: 1991-04-12 +-- Created by: Michel CHAUVAT +-- Copyright (c) 1991-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. + +-- Jean-Claude VAUTHIER January 1992 + + +class Vinert from BRepGProp inherits GProps from GProp + + --- Purpose : + -- Computes the global properties of a geometric solid + -- (3D closed region of space) delimited with : + -- . a surface + -- . a point and a surface + -- . a plane and a surface + -- + -- The surface can be : + -- . a surface limited with its parametric values U-V, + -- . a surface limited in U-V space with its curves of restriction, + -- + -- The surface 's requirements to evaluate the global properties + -- are defined in the template SurfaceTool from package GProp. + +uses Pnt from gp, + Pln from gp, + Edge from TopoDS, + Face from BRepGProp, + Domain from BRepGProp +is + + Create returns Vinert; + + Create (S: Face from BRepGProp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of a region of 3D space + -- delimited with the surface and the point VLocation. S can be closed + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Errror of the computation is not calculated. + + Create (S: in out Face from BRepGProp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of a region of 3D space + -- delimited with the surface and the point VLocation. S can be closed + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + + Create (S: Face from BRepGProp; O: Pnt from gp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the point VLocation. + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Error of the computation is not calculated. + + Create (S: in out Face from BRepGProp; O: Pnt from gp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the point VLocation. + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. + + Create (S: Face from BRepGProp; Pl: Pln from gp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the plane Pln. + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Error of the computation is not calculated. + + Create (S: in out Face from BRepGProp; Pl: Pln from gp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the plane Pln. + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. + + -- With Domain from BRepGProp -- + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of a region of 3D space + -- delimited with the surface and the point VLocation. S can be closed + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Errror of the computation is not calculated. + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of a region of 3D space + -- delimited with the surface and the point VLocation. S can be closed + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; O: Pnt from gp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the point VLocation. + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Error of the computation is not calculated. + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; O: Pnt from gp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the point VLocation. + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; Pl: Pln from gp; VLocation: Pnt from gp) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the plane Pln. + -- The method is quick and its precision is enough for many cases of analytical + -- surfaces. + -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points + -- is used. Numbers of points depend on types of surfaces and curves. + -- Error of the computation is not calculated. + + Create (S: in out Face from BRepGProp; D : in out Domain from BRepGProp; Pl: Pln from gp; VLocation: Pnt from gp; Eps: Real) returns Vinert; + --- Purpose : + -- Computes the global properties of the region of 3D space + -- delimited with the surface and the plane Pln. + -- Adaptive 2D Gauss integration is used. + -- Parameter Eps sets maximal relative error of computed mass (volume) for face. + -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values + -- for two successive steps of adaptive integration. + -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. + + SetLocation(me: in out; VLocation: Pnt from gp); + + Perform(me: in out; S: Face from BRepGProp); + Perform(me: in out; S: in out Face from BRepGProp; Eps: Real) returns Real; + + Perform(me: in out; S: Face from BRepGProp; O : Pnt from gp); + Perform(me: in out; S: in out Face from BRepGProp; O : Pnt from gp; Eps: Real) returns Real; + + Perform(me: in out; S: Face from BRepGProp; Pl : Pln from gp); + Perform(me: in out; S: in out Face from BRepGProp; Pl : Pln from gp; Eps: Real) returns Real; + + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp); + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp; Eps: Real) returns Real; + + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp; O : Pnt from gp); + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp; O : Pnt from gp; Eps: Real) returns Real; + + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp; Pl : Pln from gp); + Perform(me: in out; S: in out Face from BRepGProp; D : in out Domain from BRepGProp; Pl : Pln from gp; Eps: Real) returns Real; + + GetEpsilon(me: out) returns Real; + --- Purpose : + -- If previously used methods containe Eps parameter + -- gets actual relative error of the computation, else returns 1.0. +fields + + myEpsilon: Real from Standard; + +end Vinert; + + diff --git a/src/BRepGProp/BRepGProp_Vinert.cxx b/src/BRepGProp/BRepGProp_Vinert.cxx new file mode 100644 index 0000000000..843f83f070 --- /dev/null +++ b/src/BRepGProp/BRepGProp_Vinert.cxx @@ -0,0 +1,965 @@ +// 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 + +#include +#include + +class HMath_Vector{ + math_Vector *pvec; + void operator=(const math_Vector&){} +public: + HMath_Vector(){ pvec = 0;} + HMath_Vector(math_Vector* pv){ pvec = pv;} + ~HMath_Vector(){ if(pvec != 0) delete pvec;} + void operator=(math_Vector* pv){ if(pvec != pv && pvec != 0) delete pvec; pvec = pv;} + Standard_Real& operator()(Standard_Integer i){ return (*pvec).operator()(i);} + const Standard_Real& operator()(Standard_Integer i) const{ return (*pvec).operator()(i);} + const math_Vector* operator->() const{ return pvec;} + math_Vector* operator->(){ return pvec;} + math_Vector* Init(Standard_Real v, Standard_Integer i = 0, Standard_Integer iEnd = 0){ + if(pvec == 0) return pvec; + if(iEnd - i == 0) pvec->Init(v); + else for(; i <= iEnd; i++) pvec->operator()(i) = v; + return pvec; + } +}; + +//Minimal value of interval's range for computation | minimal value of "dim" | ... +static Standard_Real EPS_PARAM = Precision::Angular(), EPS_DIM = 1.E-30, ERROR_ALGEBR_RATIO = 2.0/3.0; +//Maximum of GaussPoints on a subinterval and maximum of subintervals +static Standard_Integer GPM = math::GaussPointsMax(), SUBS_POWER = 32, SM = SUBS_POWER*GPM + 1; +static Standard_Boolean IS_MIN_DIM = 1; // if the value equal 0 error of algorithm calculted by static moments + +static math_Vector LGaussP0(1,GPM), LGaussW0(1,GPM), +LGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))), LGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); +static HMath_Vector L1 = new math_Vector(1,SM), L2 = new math_Vector(1,SM), +DimL = new math_Vector(1,SM), ErrL = new math_Vector(1,SM), ErrUL = new math_Vector(1,SM,0.0), +IxL = new math_Vector(1,SM), IyL = new math_Vector(1,SM), IzL = new math_Vector(1,SM), +IxxL = new math_Vector(1,SM), IyyL = new math_Vector(1,SM), IzzL = new math_Vector(1,SM), +IxyL = new math_Vector(1,SM), IxzL = new math_Vector(1,SM), IyzL = new math_Vector(1,SM); + +static math_Vector* LGaussP[] = {&LGaussP0,&LGaussP1}; +static math_Vector* LGaussW[] = {&LGaussW0,&LGaussW1}; + +static math_Vector UGaussP0(1,GPM), UGaussW0(1,GPM), +UGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))), UGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); +static HMath_Vector U1 = new math_Vector(1,SM), U2 = new math_Vector(1,SM), +DimU = new math_Vector(1,SM), ErrU = new math_Vector(1,SM,0.0), +IxU = new math_Vector(1,SM), IyU = new math_Vector(1,SM), IzU = new math_Vector(1,SM), +IxxU = new math_Vector(1,SM), IyyU = new math_Vector(1,SM), IzzU = new math_Vector(1,SM), +IxyU = new math_Vector(1,SM), IxzU = new math_Vector(1,SM), IyzU = new math_Vector(1,SM); + +static math_Vector* UGaussP[] = {&UGaussP0,&UGaussP1}; +static math_Vector* UGaussW[] = {&UGaussW0,&UGaussW1}; + +static Standard_Integer FillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, + HMath_Vector& VA, HMath_Vector& VB) +{ + Standard_Integer i = 1, iEnd = Knots.Upper(), j = 1, k = 1; + VA(j++) = A; + for(; i <= iEnd; i++){ + Standard_Real kn = Knots(i); + if(A < kn) + { + if(kn < B) + { + VA(j++) = VB(k++) = kn; + } + else + { + break; + } + } + } + VB(k) = B; + return k; +} + +static inline Standard_Integer MaxSubs(Standard_Integer n, Standard_Integer coeff = SUBS_POWER){ + return n = IntegerLast()/coeff < n? IntegerLast(): n*coeff + 1; +} + +static Standard_Integer LFillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, + const Standard_Integer NumSubs) +{ + Standard_Integer iEnd = Knots.Upper(), jEnd = L1->Upper(); + + // Modified by Sergey KHROMOV - Wed Mar 26 11:22:50 2003 + iEnd = Max(iEnd, MaxSubs(iEnd-1,NumSubs)); + if(iEnd - 1 > jEnd){ + // iEnd = MaxSubs(iEnd-1,NumSubs); + // Modified by Sergey KHROMOV - Wed Mar 26 11:22:51 2003 + L1 = new math_Vector(1,iEnd); L2 = new math_Vector(1,iEnd); + DimL = new math_Vector(1,iEnd); ErrL = new math_Vector(1,iEnd,0.0); ErrUL = new math_Vector(1,iEnd,0.0); + IxL = new math_Vector(1,iEnd); IyL = new math_Vector(1,iEnd); IzL = new math_Vector(1,iEnd); + IxxL = new math_Vector(1,iEnd); IyyL = new math_Vector(1,iEnd); IzzL = new math_Vector(1,iEnd); + IxyL = new math_Vector(1,iEnd); IxzL = new math_Vector(1,iEnd); IyzL = new math_Vector(1,iEnd); + } + return FillIntervalBounds(A, B, Knots, L1, L2); +} + +static Standard_Integer UFillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, + const Standard_Integer NumSubs) +{ + Standard_Integer iEnd = Knots.Upper(), jEnd = U1->Upper(); + + // Modified by Sergey KHROMOV - Wed Mar 26 11:22:50 2003 + iEnd = Max(iEnd, MaxSubs(iEnd-1,NumSubs)); + if(iEnd - 1 > jEnd){ + // iEnd = MaxSubs(iEnd-1,NumSubs); + // Modified by Sergey KHROMOV - Wed Mar 26 11:22:51 2003 + U1 = new math_Vector(1,iEnd); U2 = new math_Vector(1,iEnd); + DimU = new math_Vector(1,iEnd); ErrU = new math_Vector(1,iEnd,0.0); + IxU = new math_Vector(1,iEnd); IyU = new math_Vector(1,iEnd); IzU = new math_Vector(1,iEnd); + IxxU = new math_Vector(1,iEnd); IyyU = new math_Vector(1,iEnd); IzzU = new math_Vector(1,iEnd); + IxyU = new math_Vector(1,iEnd); IxzU = new math_Vector(1,iEnd); IyzU = new math_Vector(1,iEnd); + } + return FillIntervalBounds(A, B, Knots, U1, U2); +} + +static Standard_Real CCompute(BRepGProp_Face& S, BRepGProp_Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], + const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, + const Standard_Real EpsDim, + const Standard_Boolean isErrorCalculation, const Standard_Boolean isVerifyComputation) +{ + Standard_Boolean isNaturalRestriction = S.NaturalRestriction(); + + Standard_Integer NumSubs = SUBS_POWER; + Standard_Boolean isMinDim = IS_MIN_DIM; + + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + Dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + //boundary curve parametrization + Standard_Real l1, l2, lm, lr, l; + //BRepGProp_Face parametrization in U and V direction + Standard_Real BV1, BV2, v; + Standard_Real BU1, BU2, u1, u2, um, ur, u; + S.Bounds (BU1, BU2, BV1, BV2); u1 = BU1; + //location point used to compute the inertia + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + //location point used to compute the inertiard (xloc, yloc, zloc); + //Jacobien (x, y, z) -> (u, v) = ||n|| + Standard_Real xn, yn, zn, s, ds, dDim; + Standard_Real x, y, z, xi, px, py, pz, yi, zi, d1, d2, d3; + //On the BRepGProp_Face + gp_Pnt Ps; + gp_Vec VNor; + //On the boundary curve u-v + gp_Pnt2d Puv; + gp_Vec2d Vuv; + Standard_Real Dul; // Dul = Du / Dl + Standard_Real CDim[2], CIx, CIy, CIz, CIxx[2], CIyy[2], CIzz[2], CIxy, CIxz, CIyz; + Standard_Real LocDim[2], LocIx[2], LocIy[2], LocIz[2], LocIxx[2], LocIyy[2], LocIzz[2], LocIxy[2], LocIxz[2], LocIyz[2]; + + Standard_Integer iD = 0, NbLSubs, iLS, iLSubEnd, iGL, iGLEnd, NbLGaussP[2], LRange[2], iL, kL, kLEnd, IL, JL; + Standard_Integer i, NbUSubs, iUS, iUSubEnd, iGU, iGUEnd, NbUGaussP[2], URange[2], iU, kU, kUEnd, IU, JU; + Standard_Integer UMaxSubs, LMaxSubs; + + Standard_Real ErrorU, ErrorL, ErrorLMax = 0.0, Eps=0.0, EpsL=0.0, EpsU=0.0; + iGLEnd = isErrorCalculation? 2: 1; + + for(i = 0; i < 2; i++) { + LocDim[i] = 0.0; + LocIx[i] = 0.0; + LocIy[i] = 0.0; + LocIz[i] = 0.0; + LocIxx[i] = 0.0; + LocIyy[i] = 0.0; + LocIzz[i] = 0.0; + LocIxy[i] = 0.0; + LocIyz[i] = 0.0; + LocIxz[i] = 0.0; + } + + NbUGaussP[0] = S.SIntOrder(EpsDim); + NbUGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbUGaussP[0])); + math::GaussPoints(NbUGaussP[0],UGaussP0); math::GaussWeights(NbUGaussP[0],UGaussW0); + math::GaussPoints(NbUGaussP[1],UGaussP1); math::GaussWeights(NbUGaussP[1],UGaussW1); + + NbUSubs = S.SUIntSubs(); + TColStd_Array1OfReal UKnots(1,NbUSubs+1); + S.UKnots(UKnots); + + while (isNaturalRestriction || D.More()) { + if(isNaturalRestriction){ + NbLGaussP[0] = Min(2*NbUGaussP[0],math::GaussPointsMax()); + }else{ + S.Load(D.Value()); ++iD; + NbLGaussP[0] = S.LIntOrder(EpsDim); + } + NbLGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbLGaussP[0])); + math::GaussPoints(NbLGaussP[0],LGaussP0); math::GaussWeights(NbLGaussP[0],LGaussW0); + math::GaussPoints(NbLGaussP[1],LGaussP1); math::GaussWeights(NbLGaussP[1],LGaussW1); + + NbLSubs = isNaturalRestriction? S.SVIntSubs(): S.LIntSubs(); + TColStd_Array1OfReal LKnots(1,NbLSubs+1); + if(isNaturalRestriction){ + S.VKnots(LKnots); + l1 = BV1; l2 = BV2; + }else{ + S.LKnots(LKnots); + l1 = S.FirstParameter(); l2 = S.LastParameter(); + } + ErrorL = 0.0; + kLEnd = 1; JL = 0; + //OCC503(apo): if(Abs(l2-l1) < EPS_PARAM) continue; + if(Abs(l2-l1) > EPS_PARAM) { + iLSubEnd = LFillIntervalBounds(l1, l2, LKnots, NumSubs); + LMaxSubs = MaxSubs(iLSubEnd); + //-- exception avoiding + if(LMaxSubs > SM) LMaxSubs = SM; + DimL.Init(0.0,1,LMaxSubs); ErrL.Init(0.0,1,LMaxSubs); ErrUL.Init(0.0,1,LMaxSubs); + do{// while: L + if(++JL > iLSubEnd){ + LRange[0] = IL = ErrL->Max(); LRange[1] = JL; + L1(JL) = (L1(IL) + L2(IL))/2.0; L2(JL) = L2(IL); L2(IL) = L1(JL); + }else LRange[0] = IL = JL; + if(JL == LMaxSubs || Abs(L2(JL) - L1(JL)) < EPS_PARAM) + if(kLEnd == 1){ + DimL(JL) = ErrL(JL) = IxL(JL) = IyL(JL) = IzL(JL) = + IxxL(JL) = IyyL(JL) = IzzL(JL) = IxyL(JL) = IxzL(JL) = IyzL(JL) = 0.0; + }else{ + JL--; + EpsL = ErrorL; Eps = EpsL/0.9; + break; + } + else + for(kL=0; kL < kLEnd; kL++){ + iLS = LRange[kL]; + lm = 0.5*(L2(iLS) + L1(iLS)); + lr = 0.5*(L2(iLS) - L1(iLS)); + CIx = CIy = CIz = CIxy = CIxz = CIyz = 0.0; + for(iGL=0; iGL < iGLEnd; iGL++){// + CDim[iGL] = CIxx[iGL] = CIyy[iGL] = CIzz[iGL] = 0.0; + for(iL=1; iL<=NbLGaussP[iGL]; iL++){ + l = lm + lr*(*LGaussP[iGL])(iL); + if(isNaturalRestriction){ + v = l; u2 = BU2; Dul = (*LGaussW[iGL])(iL); + }else{ + S.D12d (l, Puv, Vuv); + Dul = Vuv.Y()*(*LGaussW[iGL])(iL); // Dul = Du / Dl + if(Abs(Dul) < EPS_PARAM) continue; + v = Puv.Y(); u2 = Puv.X(); + //Check on cause out off bounds of value current parameter + if(v < BV1) v = BV1; else if(v > BV2) v = BV2; + if(u2 < BU1) u2 = BU1; else if(u2 > BU2) u2 = BU2; + } + ErrUL(iLS) = 0.0; + kUEnd = 1; JU = 0; + if(Abs(u2-u1) < EPS_PARAM) continue; + iUSubEnd = UFillIntervalBounds(u1, u2, UKnots, NumSubs); + UMaxSubs = MaxSubs(iUSubEnd); + //-- exception avoiding + if(UMaxSubs > SM) UMaxSubs = SM; + DimU.Init(0.0,1,UMaxSubs); ErrU.Init(0.0,1,UMaxSubs); ErrorU = 0.0; + do{//while: U + if(++JU > iUSubEnd){ + URange[0] = IU = ErrU->Max(); URange[1] = JU; + U1(JU) = (U1(IU)+U2(IU))/2.0; U2(JU) = U2(IU); U2(IU) = U1(JU); + }else URange[0] = IU = JU; + if(JU == UMaxSubs || Abs(U2(JU) - U1(JU)) < EPS_PARAM) + if(kUEnd == 1){ + DimU(JU) = ErrU(JU) = IxU(JU) = IyU(JU) = IzU(JU) = + IxxU(JU) = IyyU(JU) = IzzU(JU) = IxyU(JU) = IxzU(JU) = IyzU(JU) = 0.0; + }else{ + JU--; + EpsU = ErrorU; Eps = EpsU*Abs((u2-u1)*Dul)/0.1; EpsL = 0.9*Eps; + break; + } + else + for(kU=0; kU < kUEnd; kU++){ + iUS = URange[kU]; + um = 0.5*(U2(iUS) + U1(iUS)); + ur = 0.5*(U2(iUS) - U1(iUS)); + iGUEnd = iGLEnd - iGL; + for(iGU=0; iGU < iGUEnd; iGU++){// + LocDim[iGU] = + LocIxx[iGU] = LocIyy[iGU] = LocIzz[iGU] = + LocIx[iGU] = LocIy[iGU] = LocIz[iGU] = + LocIxy[iGU] = LocIxz[iGU] = LocIyz[iGU] = 0.0; + for(iU=1; iU<=NbUGaussP[iGU]; iU++){ + u = um + ur*(*UGaussP[iGU])(iU); + S.Normal(u, v, Ps, VNor); + VNor.Coord(xn, yn, zn); + Ps.Coord(x, y, z); + x -= xloc; y -= yloc; z -= zloc; + xn *= (*UGaussW[iGU])(iU); + yn *= (*UGaussW[iGU])(iU); + zn *= (*UGaussW[iGU])(iU); + if(ByPoint){ + //volume of elementary cone + dDim = (x*xn+y*yn+z*zn)/3.0; + //coordinates of cone's center mass + px = 0.75*x; py = 0.75*y; pz = 0.75*z; + LocDim[iGU] += dDim; + //if(iGU > 0) continue; + LocIx[iGU] += px*dDim; + LocIy[iGU] += py*dDim; + LocIz[iGU] += pz*dDim; + x -= Coeff[0]; y -= Coeff[1]; z -= Coeff[2]; + dDim *= 3.0/5.0; + LocIxy[iGU] -= x*y*dDim; + LocIyz[iGU] -= y*z*dDim; + LocIxz[iGU] -= x*z*dDim; + xi = x*x; yi = y*y; zi = z*z; + LocIxx[iGU] += (yi+zi)*dDim; + LocIyy[iGU] += (xi+zi)*dDim; + LocIzz[iGU] += (xi+yi)*dDim; + }else{ // by plane + s = xn*Coeff[0] + yn*Coeff[1] + zn*Coeff[2]; + d1 = Coeff[0]*x + Coeff[1]*y + Coeff[2]*z - Coeff[3]; + d2 = d1*d1; + d3 = d1*d2/3.0; + ds = s*d1; + LocDim[iGU] += ds; + //if(iGU > 0) continue; + LocIx[iGU] += (x - Coeff[0]*d1/2.0) * ds; + LocIy[iGU] += (y - Coeff[1]*d1/2.0) * ds; + LocIz[iGU] += (z - Coeff[2]*d1/2.0) * ds; + px = x-Coeff[0]*d1; py = y-Coeff[1]*d1; pz = z-Coeff[2]*d1; + xi = px*px*d1 + px*Coeff[0]*d2 + Coeff[0]*Coeff[0]*d3; + yi = py*py*d1 + py*Coeff[1]*d2 + Coeff[1]*Coeff[1]*d3; + zi = pz*pz*d1 + pz*Coeff[2]*d2 + Coeff[2]*Coeff[2]*d3; + LocIxx[iGU] += (yi+zi)*s; + LocIyy[iGU] += (xi+zi)*s; + LocIzz[iGU] += (xi+yi)*s; + d2 /= 2.0; + xi = py*pz*d1 + py*Coeff[2]*d2 + pz*Coeff[1]*d2 + Coeff[1]*Coeff[2]*d3; + yi = px*pz*d1 + pz*Coeff[0]*d2 + px*Coeff[2]*d2 + Coeff[0]*Coeff[2]*d3; + zi = px*py*d1 + px*Coeff[1]*d2 + py*Coeff[0]*d2 + Coeff[0]*Coeff[1]*d3; + LocIxy[iGU] -= zi*s; LocIyz[iGU] -= xi*s; LocIxz[iGU] -= yi*s; + } + }//for: iU + }//for: iGU + DimU(iUS) = LocDim[0]*ur; + IxxU(iUS) = LocIxx[0]*ur; IyyU(iUS) = LocIyy[0]*ur; IzzU(iUS) = LocIzz[0]*ur; + if(iGL > 0) continue; + LocDim[1] = Abs(LocDim[1]-LocDim[0]); + LocIxx[1] = Abs(LocIxx[1]-LocIxx[0]); + LocIyy[1] = Abs(LocIyy[1]-LocIyy[0]); + LocIzz[1] = Abs(LocIzz[1]-LocIzz[0]); + ErrU(iUS) = isMinDim? LocDim[1]*ur: (LocIxx[1] + LocIyy[1] + LocIzz[1])*ur; + IxU(iUS) = LocIx[0]*ur; IyU(iUS) = LocIy[0]*ur; IzU(iUS) = LocIz[0]*ur; + IxyU(iUS) = LocIxy[0]*ur; IxzU(iUS) = LocIxz[0]*ur; IyzU(iUS) = LocIyz[0]*ur; + }//for: kU (iUS) + if(JU == iUSubEnd) kUEnd = 2; + if(kUEnd == 2) { + Standard_Integer imax = ErrU->Max(); + if(imax > 0) ErrorU = ErrU(imax); + else ErrorU = 0.0; + } + }while((ErrorU - EpsU > 0.0 && EpsU != 0.0) || kUEnd == 1); + for(i=1; i<=JU; i++) { + CDim[iGL] += DimU(i)*Dul; + CIxx[iGL] += IxxU(i)*Dul; CIyy[iGL] += IyyU(i)*Dul; CIzz[iGL] += IzzU(i)*Dul; + } + if(iGL > 0) continue; + ErrUL(iLS) = ErrorU*Abs((u2-u1)*Dul); + for(i=1; i<=JU; i++){ + CIx += IxU(i)*Dul; CIy += IyU(i)*Dul; CIz += IzU(i)*Dul; + //CIxx += IxxU(i)*Dul; CIyy += IyyU(i)*Dul; CIzz += IzzU(i)*Dul; + CIxy += IxyU(i)*Dul; CIxz += IxzU(i)*Dul; CIyz += IyzU(i)*Dul; + } + }//for: iL + }//for: iGL + DimL(iLS) = CDim[0]*lr; + IxxL(iLS) = CIxx[0]*lr; IyyL(iLS) = CIyy[0]*lr; IzzL(iLS) = CIzz[0]*lr; + if(iGLEnd == 2) { + //ErrL(iLS) = Abs(CDim[1]-CDim[0])*lr + ErrUL(iLS); + CDim[1] = Abs(CDim[1]-CDim[0]); + CIxx[1] = Abs(CIxx[1]-CIxx[0]); CIyy[1] = Abs(CIyy[1]-CIyy[0]); CIzz[1] = Abs(CIzz[1]-CIzz[0]); + ErrorU = ErrUL(iLS); + ErrL(iLS) = (isMinDim? CDim[1]: (CIxx[1] + CIyy[1] + CIzz[1]))*lr + ErrorU; + } + IxL(iLS) = CIx*lr; IyL(iLS) = CIy*lr; IzL(iLS) = CIz*lr; + //IxxL(iLS) = CIxx*lr; IyyL(iLS) = CIyy*lr; IzzL(iLS) = CIzz*lr; + IxyL(iLS) = CIxy*lr; IxzL(iLS) = CIxz*lr; IyzL(iLS) = CIyz*lr; + }//for: (kL)iLS + // Calculate/correct epsilon of computation by current value of Dim + //That is need for not spend time for + if(JL == iLSubEnd){ + kLEnd = 2; + Standard_Real DDim = 0.0, DIxx = 0.0, DIyy = 0.0, DIzz = 0.0; + for(i=1; i<=JL; i++) { + DDim += DimL(i); + DIxx += IxxL(i); DIyy += IyyL(i); DIzz += IzzL(i); + } + DDim = isMinDim? Abs(DDim): Abs(DIxx) + Abs(DIyy) + Abs(DIzz); + DDim = Abs(DDim*EpsDim); + if(DDim > Eps) { + Eps = DDim; EpsL = 0.9*Eps; + } + } + if(kLEnd == 2) { + Standard_Integer imax = ErrL->Max(); + if(imax > 0) ErrorL = ErrL(imax); + else ErrorL = 0.0; + } + }while((ErrorL - EpsL > 0.0 && isVerifyComputation) || kLEnd == 1); + for(i=1; i<=JL; i++){ + Dim += DimL(i); + Ix += IxL(i); Iy += IyL(i); Iz += IzL(i); + Ixx += IxxL(i); Iyy += IyyL(i); Izz += IzzL(i); + Ixy += IxyL(i); Ixz += IxzL(i); Iyz += IyzL(i); + } + ErrorLMax = Max(ErrorLMax, ErrorL); + } + if(isNaturalRestriction) break; + D.Next(); + } + if(Abs(Dim) >= EPS_DIM){ + if(ByPoint){ + Ix = Coeff[0] + Ix/Dim; + Iy = Coeff[1] + Iy/Dim; + Iz = Coeff[2] + Iz/Dim; + }else{ + Ix /= Dim; + Iy /= Dim; + Iz /= Dim; + } + g.SetCoord (Ix, Iy, Iz); + }else{ + Dim =0.; + g.SetCoord(0.,0.,0.); + } + inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), + gp_XYZ (Ixy, Iyy, Iyz), + gp_XYZ (Ixz, Iyz, Izz)); + if(iGLEnd == 2) + Eps = Dim != 0.0? ErrorLMax/(isMinDim? Abs(Dim): (Abs(Ixx) + Abs(Iyy) + Abs(Izz))): 0.0; + else Eps = EpsDim; + return Eps; +} + +static Standard_Real Compute(BRepGProp_Face& S, const Standard_Boolean ByPoint, const Standard_Real Coeff[], + const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, Standard_Real EpsDim) +{ + Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; + Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; + EpsDim = Abs(EpsDim); + BRepGProp_Domain D; + return CCompute(S,D,ByPoint,Coeff,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); +} + +static Standard_Real Compute(BRepGProp_Face& S, BRepGProp_Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], + const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, Standard_Real EpsDim) +{ + Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; + Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; + EpsDim = Abs(EpsDim); + return CCompute(S,D,ByPoint,Coeff,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); +} + +static void Compute(const BRepGProp_Face& S, + const Standard_Boolean ByPoint, + const Standard_Real Coeff[], + const gp_Pnt& Loc, + Standard_Real& Volu, + gp_Pnt& G, + gp_Mat& Inertia) +{ + + gp_Pnt P; + gp_Vec VNor; + Standard_Real dvi, dv; + Standard_Real ur, um, u, vr, vm, v; + Standard_Real x, y, z, xn, yn, zn, xi, yi, zi; + // Standard_Real x, y, z, xn, yn, zn, xi, yi, zi, xyz; + Standard_Real px,py,pz,s,d1,d2,d3; + Standard_Real Ixi, Iyi, Izi, Ixxi, Iyyi, Izzi, Ixyi, Ixzi, Iyzi; + Standard_Real xloc, yloc, zloc; + Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + + Volu = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + Loc.Coord (xloc, yloc, zloc); + + Standard_Real LowerU, UpperU, LowerV, UpperV; + S.Bounds ( LowerU, UpperU, LowerV, UpperV); + Standard_Integer UOrder = Min(S.UIntegrationOrder (), + math::GaussPointsMax()); + Standard_Integer VOrder = Min(S.VIntegrationOrder (), + math::GaussPointsMax()); + + Standard_Integer i, j; + math_Vector GaussPU (1, UOrder); //gauss points and weights + math_Vector GaussWU (1, UOrder); + math_Vector GaussPV (1, VOrder); + math_Vector GaussWV (1, VOrder); + + math::GaussPoints (UOrder,GaussPU); + math::GaussWeights (UOrder,GaussWU); + math::GaussPoints (VOrder,GaussPV); + math::GaussWeights (VOrder,GaussWV); + + um = 0.5 * (UpperU + LowerU); + vm = 0.5 * (UpperV + LowerV); + ur = 0.5 * (UpperU - LowerU); + vr = 0.5 * (UpperV - LowerV); + + for (j = 1; j <= VOrder; j++) { + v = vm + vr * GaussPV (j); + dvi = Ixi = Iyi = Izi = Ixxi = Iyyi = Izzi = Ixyi = Ixzi = Iyzi = 0.0; + + for (i = 1; i <= UOrder; i++) { + u = um + ur * GaussPU (i); + S.Normal (u, v, P, VNor); + VNor.Coord (xn, yn, zn); + P.Coord (x, y, z); + x -= xloc; y -= yloc; z -= zloc; + xn *= GaussWU (i); yn *= GaussWU (i); zn *= GaussWU (i); + if (ByPoint) { + ///////////////////// /////////////////////// + // OFV code // // Initial code // + ///////////////////// /////////////////////// + // modified by APO + dv = (x*xn+y*yn+z*zn)/3.0; //xyz = x * y * z; + dvi += dv; //Ixyi += zn * xyz; + Ixi += 0.75*x*dv; //Iyzi += xn * xyz; + Iyi += 0.75*y*dv; //Ixzi += yn * xyz; + Izi += 0.75*z*dv; //xi = x * x * x * xn / 3.0; + x -= Coeff[0]; //yi = y * y * y * yn / 3.0; + y -= Coeff[1]; //zi = z * z * z * zn / 3.0; + z -= Coeff[2]; //Ixxi += (yi + zi); + dv *= 3.0/5.0; //Iyyi += (xi + zi); + Ixyi -= x*y*dv; //Izzi += (xi + yi); + Iyzi -= y*z*dv; //x -= Coeff[0]; + Ixzi -= x*z*dv; //y -= Coeff[1]; + xi = x*x; //z -= Coeff[2]; + yi = y*y; //dv = x * xn + y * yn + z * zn; + zi = z*z; //dvi += dv; + Ixxi += (yi + zi)*dv; //Ixi += x * dv; + Iyyi += (xi + zi)*dv; //Iyi += y * dv; + Izzi += (xi + yi)*dv; //Izi += z * dv; + } + else { // by plane + s = xn * Coeff[0] + yn * Coeff[1] + zn * Coeff[2]; + d1 = Coeff[0] * x + Coeff[1] * y + Coeff[2] * z - Coeff[3]; + d2 = d1 * d1; + d3 = d1 * d2 / 3.0; + dv = s * d1; + dvi += dv; + Ixi += (x - (Coeff[0] * d1 / 2.0)) * dv; + Iyi += (y - (Coeff[1] * d1 / 2.0)) * dv; + Izi += (z - (Coeff[2] * d1 / 2.0)) * dv; + px = x - Coeff[0] * d1; + py = y - Coeff[1] * d1; + pz = z - Coeff[2] * d1; + xi = px * px * d1 + px * Coeff[0]* d2 + Coeff[0] * Coeff[0] * d3; + yi = py * py * d1 + py * Coeff[1] * d2 + Coeff[1] * Coeff[1] * d3; + zi = pz * pz * d1 + pz * Coeff[2] * d2 + Coeff[2] * Coeff[2] * d3; + Ixxi += (yi + zi) * s; + Iyyi += (xi + zi) * s; + Izzi += (xi + yi) * s; + d2 /= 2.0; + xi = (py * pz * d1) + (py * Coeff[2] * d2) + (pz * Coeff[1] * d2) + (Coeff[1] * Coeff[2] * d3); + yi = (px * pz * d1) + (pz * Coeff[0] * d2) + (px * Coeff[2] * d2) + (Coeff[0] * Coeff[2] * d3); + zi = (px * py * d1) + (px * Coeff[1] * d2) + (py * Coeff[0] * d2) + (Coeff[0] * Coeff[1] * d3); + Ixyi -= zi * s; + Iyzi -= xi * s; + Ixzi -= yi * s; + } + } + Volu += dvi * GaussWV (j); + Ix += Ixi * GaussWV (j); + Iy += Iyi * GaussWV (j); + Iz += Izi * GaussWV (j); + Ixx += Ixxi * GaussWV (j); + Iyy += Iyyi * GaussWV (j); + Izz += Izzi * GaussWV (j); + Ixy += Ixyi * GaussWV (j); + Ixz += Ixzi * GaussWV (j); + Iyz += Iyzi * GaussWV (j); + } + vr *= ur; + Ixx *= vr; + Iyy *= vr; + Izz *= vr; + Ixy *= vr; + Ixz *= vr; + Iyz *= vr; + if (Abs(Volu) >= EPS_DIM ) { + if (ByPoint) { + Ix = Coeff[0] + Ix/Volu; + Iy = Coeff[1] + Iy/Volu; + Iz = Coeff[2] + Iz/Volu; + Volu *= vr; + } + else { //by plane + Ix /= Volu; + Iy /= Volu; + Iz /= Volu; + Volu *= vr; + } + G.SetCoord (Ix, Iy, Iz); + } + else { + G.SetCoord(0.,0.,0.); + Volu =0.; + } + Inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), + gp_XYZ (Ixy, Iyy, Iyz), + gp_XYZ (Ixz, Iyz, Izz)); + +} + +// Last modified by OFV 5.2001: +// 1). surface and edge integration order is equal now +// 2). "by point" works now rathre correctly (it looks so...) +static void Compute(BRepGProp_Face& S, BRepGProp_Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], + const gp_Pnt& Loc, Standard_Real& Volu, gp_Pnt& G, gp_Mat& Inertia) + +{ + Standard_Real x, y, z, xi, yi, zi, l1, l2, lm, lr, l, v1, v2, v, u1, u2, um, ur, u, ds, Dul, xloc, yloc, zloc; + Standard_Real LocVolu, LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, LocIxz, LocIyz; + Standard_Real CVolu, CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz, Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; + Standard_Real xn, yn, zn, px, py, pz, s, d1, d2, d3, dSigma; + Standard_Integer i, j, vio, sio, max, NbGaussgp_Pnts; + + gp_Pnt Ps; + gp_Vec VNor; + gp_Pnt2d Puv; + gp_Vec2d Vuv; + + Loc.Coord (xloc, yloc, zloc); + Volu = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; + S.Bounds (u1, u2, v1, v2); + Standard_Real _u2 = u2; //OCC104 + vio = S.VIntegrationOrder (); + + while (D.More()) + { + S.Load(D.Value()); + sio = S.IntegrationOrder (); + max = Max(vio,sio); + NbGaussgp_Pnts = Min(max,math::GaussPointsMax()); + + math_Vector GaussP (1, NbGaussgp_Pnts); + math_Vector GaussW (1, NbGaussgp_Pnts); + math::GaussPoints (NbGaussgp_Pnts,GaussP); + math::GaussWeights (NbGaussgp_Pnts,GaussW); + + CVolu = CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; + l1 = S.FirstParameter(); + l2 = S.LastParameter(); + lm = 0.5 * (l2 + l1); + lr = 0.5 * (l2 - l1); + + for (i=1; i<=NbGaussgp_Pnts; i++) + { + l = lm + lr * GaussP(i); + S.D12d (l, Puv, Vuv); + v = Puv.Y(); + u2 = Puv.X(); + + //OCC104 + v = v < v1? v1: v; + v = v > v2? v2: v; + u2 = u2 < u1? u1: u2; + u2 = u2 > _u2? _u2: u2; + + Dul = Vuv.Y() * GaussW(i); + um = 0.5 * (u2 + u1); + ur = 0.5 * (u2 - u1); + LocVolu = LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = LocIxy = LocIxz = LocIyz = 0.0; + + for (j=1; j<=NbGaussgp_Pnts; j++) + { + u = um + ur * GaussP(j); + S.Normal (u, v, Ps, VNor); + VNor.Coord (xn, yn, zn); + Ps.Coord (x, y, z); + x -= xloc; + y -= yloc; + z -= zloc; + xn = xn * Dul * GaussW(j); + yn = yn * Dul * GaussW(j); + zn = zn * Dul * GaussW(j); + if(ByPoint) + { + dSigma = (x*xn+y*yn+z*zn)/3.0; + LocVolu += dSigma; + LocIx += 0.75*x*dSigma; + LocIy += 0.75*y*dSigma; + LocIz += 0.75*z*dSigma; + x -= Coeff[0]; + y -= Coeff[1]; + z -= Coeff[2]; + dSigma *= 3.0/5.0; + LocIxy -= x*y*dSigma; + LocIyz -= y*z*dSigma; + LocIxz -= x*z*dSigma; + xi = x*x; + yi = y*y; + zi = z*z; + LocIxx += (yi + zi)*dSigma; + LocIyy += (xi + zi)*dSigma; + LocIzz += (xi + yi)*dSigma; + } + else + { + s = xn * Coeff[0] + yn * Coeff[1] + zn * Coeff[2]; + d1 = Coeff[0] * x + Coeff[1] * y + Coeff[2] * z; + d2 = d1 * d1; + d3 = d1 * d2 / 3.0; + ds = s * d1; + LocVolu += ds; + LocIx += (x - Coeff[0] * d1 / 2.0) * ds; + LocIy += (y - Coeff[1] * d1 / 2.0) * ds; + LocIz += (z - Coeff[2] * d1 / 2.0) * ds; + px = x - Coeff[0] * d1; + py = y - Coeff[1] * d1; + pz = z - Coeff[2] * d1; + xi = (px * px * d1) + (px * Coeff[0]* d2) + (Coeff[0] * Coeff[0] * d3); + yi = (py * py * d1) + (py * Coeff[1] * d2) + (Coeff[1] * Coeff[1] * d3); + zi = pz * pz * d1 + pz * Coeff[2] * d2 + (Coeff[2] * Coeff[2] * d3); + LocIxx += (yi + zi) * s; + LocIyy += (xi + zi) * s; + LocIzz += (xi + yi) * s; + d2 /= 2.0; + xi = (py * pz * d1) + (py * Coeff[2] * d2) + (pz * Coeff[1] * d2) + (Coeff[1] * Coeff[2] * d3); + yi = (px * pz * d1) + (pz * Coeff[0] * d2) + (px * Coeff[2] * d2) + (Coeff[0] * Coeff[2] * d3); + zi = (px * py * d1) + (px * Coeff[1] * d2) + (py * Coeff[0] * d2) + (Coeff[0] * Coeff[1] * d3); + LocIxy -= zi * s; + LocIyz -= xi * s; + LocIxz -= yi * s; + } + } + CVolu += LocVolu * ur; + CIx += LocIx * ur; + CIy += LocIy * ur; + CIz += LocIz * ur; + CIxx += LocIxx * ur; + CIyy += LocIyy * ur; + CIzz += LocIzz * ur; + CIxy += LocIxy * ur; + CIxz += LocIxz * ur; + CIyz += LocIyz * ur; + } + Volu += CVolu * lr; + Ix += CIx * lr; + Iy += CIy * lr; + Iz += CIz * lr; + Ixx += CIxx * lr; + Iyy += CIyy * lr; + Izz += CIzz * lr; + Ixy += CIxy * lr; + Ixz += CIxz * lr; + Iyz += CIyz * lr; + D.Next(); + } + + if(Abs(Volu) >= EPS_DIM) + { + if(ByPoint) + { + Ix = Coeff[0] + Ix/Volu; + Iy = Coeff[1] + Iy/Volu; + Iz = Coeff[2] + Iz/Volu; + } + else + { + Ix /= Volu; + Iy /= Volu; + Iz /= Volu; + } + G.SetCoord (Ix, Iy, Iz); + } + else + { + Volu =0.; + G.SetCoord(0.,0.,0.); + } + + Inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), + gp_XYZ (Ixy, Iyy, Iyz), + gp_XYZ (Ixz, Iyz, Izz)); + +} + +BRepGProp_Vinert::BRepGProp_Vinert(){} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,D,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S,D); +} + +BRepGProp_Vinert::BRepGProp_Vinert(const BRepGProp_Face& S, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, const gp_Pnt& O, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,O,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& O, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,D,O,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(const BRepGProp_Face& S, const gp_Pnt& O, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S,O); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& O, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S,D,O); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, const gp_Pln& Pl, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,Pl,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pln& Pl, const gp_Pnt& VLocation, const Standard_Real Eps){ + SetLocation(VLocation); + Perform(S,D,Pl,Eps); +} + +BRepGProp_Vinert::BRepGProp_Vinert(const BRepGProp_Face& S, const gp_Pln& Pl, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S,Pl); +} + +BRepGProp_Vinert::BRepGProp_Vinert(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pln& Pl, const gp_Pnt& VLocation){ + SetLocation(VLocation); + Perform(S,D,Pl); +} + +void BRepGProp_Vinert::SetLocation(const gp_Pnt& VLocation){ + loc = VLocation; +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, const Standard_Real Eps){ + Standard_Real Coeff[] = {0., 0., 0.}; + return myEpsilon = Compute(S,Standard_True,Coeff,loc,dim,g,inertia,Eps); +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const Standard_Real Eps){ + Standard_Real Coeff[] = {0., 0., 0.}; + return myEpsilon = Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia,Eps); +} + +void BRepGProp_Vinert::Perform(const BRepGProp_Face& S){ + Standard_Real Coeff[] = {0., 0., 0.}; + Compute(S,Standard_True,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +void BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D){ + Standard_Real Coeff[] = {0., 0., 0.}; + Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, const gp_Pnt& O, const Standard_Real Eps){ + Standard_Real xloc, yloc, zloc; + loc.Coord(xloc, yloc, zloc); + Standard_Real Coeff[3]; + O.Coord (Coeff[0], Coeff[1], Coeff[2]); + Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; + return myEpsilon = Compute(S,Standard_True,Coeff,loc,dim,g,inertia,Eps); +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& O, const Standard_Real Eps){ + Standard_Real xloc, yloc, zloc; + loc.Coord(xloc, yloc, zloc); + Standard_Real Coeff[3]; + O.Coord (Coeff[0], Coeff[1], Coeff[2]); + Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; + return myEpsilon = Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia,Eps); +} + +void BRepGProp_Vinert::Perform(const BRepGProp_Face& S, const gp_Pnt& O){ + Standard_Real xloc, yloc, zloc; + loc.Coord(xloc, yloc, zloc); + Standard_Real Coeff[3]; + O.Coord (Coeff[0], Coeff[1], Coeff[2]); + Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; + Compute(S,Standard_True,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +void BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pnt& O){ + Standard_Real xloc, yloc, zloc; + loc.Coord(xloc, yloc, zloc); + Standard_Real Coeff[3]; + O.Coord (Coeff[0], Coeff[1], Coeff[2]); + Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; + Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, const gp_Pln& Pl, const Standard_Real Eps){ + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + Standard_Real Coeff[4]; + Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); + Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; + return myEpsilon = Compute(S,Standard_False,Coeff,loc,dim,g,inertia,Eps); +} + +Standard_Real BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pln& Pl, const Standard_Real Eps){ + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + Standard_Real Coeff[4]; + Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); + Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; + return myEpsilon = Compute(S,D,Standard_False,Coeff,loc,dim,g,inertia,Eps); +} + +void BRepGProp_Vinert::Perform(const BRepGProp_Face& S, const gp_Pln& Pl){ + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + Standard_Real Coeff[4]; + Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); + Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; + Compute(S,Standard_False,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +void BRepGProp_Vinert::Perform(BRepGProp_Face& S, BRepGProp_Domain& D, const gp_Pln& Pl){ + Standard_Real xloc, yloc, zloc; + loc.Coord (xloc, yloc, zloc); + Standard_Real Coeff[4]; + Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); + Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; + Compute(S,D,Standard_False,Coeff,loc,dim,g,inertia); + myEpsilon = 1.0; + return; +} + +Standard_Real BRepGProp_Vinert::GetEpsilon(){ + return myEpsilon; +} diff --git a/src/BRepGProp/BRepGProp_VinertGK.cdl b/src/BRepGProp/BRepGProp_VinertGK.cdl new file mode 100644 index 0000000000..0cc3f43377 --- /dev/null +++ b/src/BRepGProp/BRepGProp_VinertGK.cdl @@ -0,0 +1,244 @@ +-- Created on: 2005-12-21 +-- Created by: Sergey KHROMOV +-- Copyright (c) 2005-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 VinertGK from BRepGProp inherits GProps from GProp + + ---Purpose: Computes the global properties of a geometric solid + -- (3D closed region of space) delimited with : + -- - a point and a surface + -- - a plane and a surface + -- + -- The surface can be : + -- - a surface limited with its parametric values U-V, + -- (naturally restricted) + -- - a surface limited in U-V space with its boundary + -- curves. + -- + -- The surface's requirements to evaluate the global + -- properties are defined in the template FaceTool class from + -- the package GProp. + -- + -- The adaptive 2D algorithm of Gauss-Kronrod integration of + -- double integral is used. + -- + -- The inner integral is computed along U parameter of + -- surface. The integrand function is encapsulated in the + -- support class UFunction that is defined below. + -- + -- The outer integral is computed along T parameter of a + -- bounding curve. The integrand function is encapsulated in + -- the support class TFunction that is defined below. + +uses + + Pnt from gp, + XYZ from gp, + Pln from gp, + Address from Standard, + Boolean from Standard, + Real from Standard, + Edge from TopoDS, + Face from BRepGProp, + Domain from BRepGProp + + +-- Template class functions. Used for integration. Begin + +is + + Create + ---Purpose: Empty constructor. + ---C++: inline + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the naturally restricted surface + -- and the point VLocation. + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + thePoint : Pnt from gp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the naturally restricted surface + -- and the point VLocation. The inertia is computed with + -- respect to thePoint. + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the surface bounded by the domain + -- and the point VLocation. + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + thePoint : Pnt from gp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the surface bounded by the domain + -- and the point VLocation. The inertia is computed with + -- respect to thePoint. + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + thePlane : Pln from gp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the naturally restricted surface + -- and the plane. + returns VinertGK; + + Create(theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + thePlane : Pln from gp; + theLocation : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Constructor. Computes the global properties of a region of + -- 3D space delimited with the surface bounded by the domain + -- and the plane. + returns VinertGK; + + SetLocation(me: in out; theLocation: Pnt from gp); + ---Purpose: Sets the vertex that delimit 3D closed region of space. + ---C++: inline + + Perform(me: in out; theSurface : in out Face from BRepGProp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the naturally restricted surface and the + -- point VLocation. + returns Real from Standard; + + Perform(me: in out; theSurface : in out Face from BRepGProp; + thePoint : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the naturally restricted surface and the + -- point VLocation. The inertia is computed with respect to + -- thePoint. + returns Real from Standard; + + Perform(me: in out; theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the surface bounded by the domain and the + -- point VLocation. + returns Real from Standard; + + Perform(me: in out; theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + thePoint : Pnt from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the surface bounded by the domain and the + -- point VLocation. The inertia is computed with respect to + -- thePoint. + returns Real from Standard; + + Perform(me: in out; theSurface : in out Face from BRepGProp; + thePlane : Pln from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the naturally restricted surface and the + -- plane. + returns Real from Standard; + + Perform(me: in out; theSurface : in out Face from BRepGProp; + theDomain : in out Domain from BRepGProp; + thePlane : Pln from gp; + theTolerance: Real from Standard = 0.001; + theCGFlag: Boolean from Standard = Standard_False; + theIFlag: Boolean from Standard = Standard_False) + + ---Purpose: Computes the global properties of a region of 3D space + -- delimited with the surface bounded by the domain and the + -- plane. + returns Real from Standard; + + GetErrorReached(me) + ---Purpose: Returns the relative reached computation error. + ---C++: inline + returns Real from Standard; + + GetAbsolutError(me) + ---Purpose: Returns the absolut reached computation error. + ---C++: inline + returns Real from Standard; + +----------------------- +-- Private methods -- +----------------------- + + PrivatePerform(me: in out; + theSurface : in out Face from BRepGProp; + thePtrDomain: Address from Standard; -- pointer to Domain from BRepGProp. + IsByPoint : Boolean from Standard; + theCoeffs : Address from Standard; + theTolerance: Real from Standard; + theCGFlag : Boolean from Standard; + theIFlag : Boolean from Standard) + + ---Purpose: Main method for computation of the global properties that + -- is invoked by each Perform method. + returns Real from Standard + is private; + +fields + + myErrorReached: Real from Standard; + myAbsolutError: Real from Standard; + +end VinertGK; diff --git a/src/BRepGProp/BRepGProp_VinertGK.cxx b/src/BRepGProp/BRepGProp_VinertGK.cxx new file mode 100644 index 0000000000..4a1df6723e --- /dev/null +++ b/src/BRepGProp/BRepGProp_VinertGK.cxx @@ -0,0 +1,480 @@ +// Created on: 2005-12-09 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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 + +#include +#include +#include + +#include + +//========================================================================== +//function : Constructor +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face &theSurface, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Constructor +// +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK( BRepGProp_Face &theSurface, + const gp_Pnt &thePoint, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, thePoint, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Constructor +// +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, theDomain, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Constructor +// +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const gp_Pnt &thePoint, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, theDomain, thePoint, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Constructor +// +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face &theSurface, + const gp_Pln &thePlane, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, thePlane, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Constructor +// +//========================================================================== + +BRepGProp_VinertGK::BRepGProp_VinertGK(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const gp_Pln &thePlane, + const gp_Pnt &theLocation, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag): + myErrorReached(0.) +{ + SetLocation(theLocation); + Perform(theSurface, theDomain, thePlane, theTolerance, theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + Standard_Real aShift[] = { 0., 0., 0. }; + + return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + const gp_Pnt &thePoint, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + gp_XYZ aXYZ(thePoint.XYZ().Subtracted(loc.XYZ())); + Standard_Real aShift[3]; + + aXYZ.Coord(aShift[0], aShift[1], aShift[2]); + + return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + Standard_Real aShift[] = { 0., 0., 0. }; + + return PrivatePerform(theSurface, &theDomain, + Standard_True, &aShift, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const gp_Pnt &thePoint, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + gp_XYZ aXYZ(thePoint.XYZ().Subtracted(loc.XYZ())); + Standard_Real aShift[3]; + + aXYZ.Coord(aShift[0], aShift[1], aShift[2]); + + return PrivatePerform(theSurface, &theDomain, + Standard_True, &aShift, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + const gp_Pln &thePlane, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + Standard_Real aCoeff[4]; + Standard_Real aXLoc; + Standard_Real aYLoc; + Standard_Real aZLoc; + + loc.Coord(aXLoc, aYLoc, aZLoc); + thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]); + aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc; + + return PrivatePerform(theSurface, NULL, + Standard_False, &aCoeff, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : Perform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::Perform(BRepGProp_Face &theSurface, + BRepGProp_Domain &theDomain, + const gp_Pln &thePlane, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + Standard_Real aCoeff[4]; + Standard_Real aXLoc; + Standard_Real aYLoc; + Standard_Real aZLoc; + + loc.Coord(aXLoc, aYLoc, aZLoc); + thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]); + aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc; + + return PrivatePerform(theSurface, &theDomain, + Standard_False, &aCoeff, theTolerance, + theCGFlag, theIFlag); +} + +//========================================================================== +//function : PrivatePerform +// Compute the properties. +//========================================================================== + +Standard_Real BRepGProp_VinertGK::PrivatePerform +(BRepGProp_Face &theSurface, + const Standard_Address thePtrDomain, + const Standard_Boolean IsByPoint, + const Standard_Address theCoeffs, + const Standard_Real theTolerance, + const Standard_Boolean theCGFlag, + const Standard_Boolean theIFlag) + +{ + + const Standard_Real aTTol = 1.e-9; + Standard_Real *aCoeffs = (Standard_Real *)theCoeffs; + + // Compute the number of 2d bounding curves of the face. + BRepGProp_Domain *aPDomain = NULL; + Standard_Integer aNbCurves = 0; + + // If the pointer to the domain is NULL, there is only one curve to treat: + // U isoline with the UMax parameter. + if (thePtrDomain == NULL) + aNbCurves = 1; + else { + aPDomain = (BRepGProp_Domain *)thePtrDomain; + + for (aPDomain->Init(); aPDomain->More(); aPDomain->Next()) + aNbCurves++; + } + + if (aNbCurves == 0) { + myErrorReached = -1.; + + return myErrorReached; + } + + //Standard_Real aCrvTol = 0.5*theTolerance/aNbCurves; + Standard_Real aCrvTol = 0.1*theTolerance; + Standard_Real aUMin; + Standard_Real aUMax; + Standard_Real aTMin; + Standard_Real aTMax; + Standard_Integer aNbPnts; + Standard_Integer aNbMaxIter = 1000; + Standard_Integer aNbVal = 10; + Standard_Integer k; + math_Vector aLocalValue(1, aNbVal); + math_Vector aLocalTolReached(1, aNbVal); + math_Vector aValue(1, aNbVal); + math_Vector aTolReached(1, aNbVal); + TColStd_Array1OfBoolean CFlags(1, aNbVal); + CFlags.Init(Standard_False); + Standard_Boolean isMore; + + //aNbVal = 1; + aValue.Init(0.); + aTolReached.Init(0.); + + CFlags.Init(Standard_False); + CFlags(1) = Standard_True; + + if(theCGFlag || theIFlag) { + Standard_Integer i; + for(i = 2; i <= 4; ++i) {CFlags(i) = Standard_True;} + } + + if(theIFlag) { + Standard_Integer i; + for(i = 5; i <= 10; ++i) {CFlags(i) = Standard_True;} + } + + theSurface.Bounds(aUMin, aUMax, aTMin, aTMax); + + if (thePtrDomain == NULL) + isMore = Standard_True; + else { + aPDomain->Init(); + isMore = aPDomain->More(); + } + + while(isMore) { + // If the pointer to the domain is NULL, there is only one curve to treat: + // U isoline with the UMax parameter. + + if (thePtrDomain == NULL) + theSurface.Load(Standard_False, GeomAbs_IsoU); + else + theSurface.Load(aPDomain->Value()); + + aTMin = theSurface.FirstParameter(); + aTMax = theSurface.LastParameter(); + + + // Get the spans on the curve. + Handle(TColStd_HArray1OfReal) aTKnots; + BRepGProp_TFunction aTFunc(theSurface, loc, IsByPoint, theCoeffs, + aUMin, aCrvTol); + + theSurface.GetTKnots(aTMin, aTMax, aTKnots); + + Standard_Integer iU = aTKnots->Upper(); + Standard_Integer aNbTIntervals = aTKnots->Length() - 1; + //Standard_Real aTolSpan = aCrvTol/aNbTIntervals; + Standard_Real aTolSpan = 0.9*theTolerance; //Relative error + math_KronrodSingleIntegration anIntegral; + GProp_ValueType aValueType; + + + // Empirical criterion. + aNbPnts = Min(15, theSurface.IntegrationOrder()/aNbTIntervals + 1); + aNbPnts = Max(5, aNbPnts); + // aNbPnts = theSurface.IntegrationOrder(); + + aLocalValue.Init(0.); + aLocalTolReached.Init(0.); + + for (k = 1; k <= aNbVal; k++) { + + if(!CFlags(k)) continue; + + Standard_Integer i = aTKnots->Lower(); + + switch (k) { + case 1: aValueType = GProp_Mass; break; + case 2: aValueType = GProp_CenterMassX; break; + case 3: aValueType = GProp_CenterMassY; break; + case 4: aValueType = GProp_CenterMassZ; break; + case 5: aValueType = GProp_InertiaXX; break; + case 6: aValueType = GProp_InertiaYY; break; + case 7: aValueType = GProp_InertiaZZ; break; + case 8: aValueType = GProp_InertiaXY; break; + case 9: aValueType = GProp_InertiaXZ; break; + case 10: aValueType = GProp_InertiaYZ; break; + + default: myErrorReached = -1.; return myErrorReached; + } + aTFunc.SetValueType(aValueType); + + Standard_Real err1 = 0.; + while (i < iU) { + + //cout << "-------------- Span " << i << " nbp: " << aNbPnts << endl; + Standard_Real aT1 = aTKnots->Value(i++); + Standard_Real aT2 = aTKnots->Value(i); + + if(aT2 - aT1 < aTTol) continue; + + aTFunc.SetNbKronrodPoints(aNbPnts); + aTFunc.Init(); + aTFunc.SetTolerance(aCrvTol/(aT2-aT1)); + anIntegral.Perform(aTFunc, aT1, aT2, aNbPnts, aTolSpan, aNbMaxIter); + + if (!anIntegral.IsDone()) { + myErrorReached = -1.; + + return myErrorReached; + } + + aLocalValue(k) += anIntegral.Value(); + err1 = aTFunc.AbsolutError()*(aT2 - aT1); + //cout << "Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl; + aLocalTolReached(k) += anIntegral.AbsolutError() + err1; + //cout << "--- Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl; + } + + aValue(k) += aLocalValue(k); + aTolReached(k) += aLocalTolReached(k); + } + + // If the pointer to the domain is NULL, there is only one curve to treat: + // U isoline with the UMax parameter. + if (thePtrDomain == NULL) + isMore = Standard_False; + else { + aPDomain->Next(); + isMore = aPDomain->More(); + } + } + + // Get volume value. + dim = aValue(1); + myErrorReached = aTolReached(1); + myAbsolutError = myErrorReached; + Standard_Real anAbsDim = Abs(dim); + Standard_Real aVolTol = Epsilon(myAbsolutError); + if(anAbsDim >= aVolTol) myErrorReached /= anAbsDim; + + if(theCGFlag || theIFlag) { + // Compute values of center of mass. + if(anAbsDim >= aVolTol) { + if (IsByPoint) { + aValue(2) = aCoeffs[0] + aValue(2)/dim; + aValue(3) = aCoeffs[1] + aValue(3)/dim; + aValue(4) = aCoeffs[2] + aValue(4)/dim; + } else { + aValue(2) /= dim; + aValue(3) /= dim; + aValue(4) /= dim; + } + } else { + aValue(2) = 0.; + aValue(3) = 0.; + aValue(4) = 0.; + dim = 0.; + } + g.SetCoord(aValue(2), aValue(3), aValue(4)); + } + + if(theIFlag) { + // Fill the matrix of inertia. + inertia.SetCols (gp_XYZ (aValue(5), aValue(8), aValue(9)), + gp_XYZ (aValue(8), aValue(6), aValue(10)), + gp_XYZ (aValue(9), aValue(10), aValue(7))); + } + //return myErrorReached; + return myAbsolutError; +} + diff --git a/src/BRepGProp/BRepGProp_VinertGK.lxx b/src/BRepGProp/BRepGProp_VinertGK.lxx new file mode 100644 index 0000000000..947b06b012 --- /dev/null +++ b/src/BRepGProp/BRepGProp_VinertGK.lxx @@ -0,0 +1,45 @@ +// Created on: 2005-12-21 +// Created by: Sergey KHROMOV +// Copyright (c) 2005-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. + +//========================================================================== +//function : Constructor +// Empty constructor. +//========================================================================== + +inline BRepGProp_VinertGK::BRepGProp_VinertGK() + : myErrorReached(0.), + myAbsolutError(0.) +{ +} + +//========================================================================== +//function : SetLocation +// Sets the vertex that delimit 3D closed region of space. +//========================================================================== + +inline void BRepGProp_VinertGK::SetLocation(const gp_Pnt &theVertex) +{ + loc = theVertex; +} + +//========================================================================== +//function : GetErrorReached +// Returns the reached Error. +//========================================================================== + +inline Standard_Real BRepGProp_VinertGK::GetErrorReached() const +{ + return myErrorReached; +} diff --git a/src/GProp/GProp.cdl b/src/GProp/GProp.cdl index ae0919143b..e108a9c888 100644 --- a/src/GProp/GProp.cdl +++ b/src/GProp/GProp.cdl @@ -82,40 +82,16 @@ enumeration ValueType --- Purpose : -- Computes the global properties of a set of points in 3d. -- This class inherits GProps. - - - generic class CGProps; - ---Purpose : - -- Computes the global properties of a bounded - -- curve in 3d. This class inherits GProps. class CelGProps; ---Purpose : -- Computes the global properties of a gp curve in 3d -- This class inherits GProps. - generic class SGProps; - ---Purpose : - -- Computes the global properties and the area of a bounded - -- surface in 3d. This class inherits GProps. - - class SelGProps; ---Purpose : -- Computes the global properties and the area of a bounded -- elementary surface in 3d. This class inherits GProps. - - generic class VGProps; - ---Purpose : - -- Computes the global properties and the volume of a region - -- of space. This class inherits GProps. - - generic class VGPropsGK, UFunction, TFunction; - ---Purpose : - -- Computes the global properties and the volume of a region - -- of space by adaptive Gauss-Kronrod integration. - -- This class inherits GProps. - class VelGProps; ---Purpose : diff --git a/src/GProp/GProp_CGProps.cdl b/src/GProp/GProp_CGProps.cdl deleted file mode 100644 index 524d65e7fa..0000000000 --- a/src/GProp/GProp_CGProps.cdl +++ /dev/null @@ -1,48 +0,0 @@ --- Created on: 1991-04-11 --- Created by: Michel CHAUVAT --- Copyright (c) 1991-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. - --- Jean-Claude Vauthier January 1992, September 1992 - - - -generic class CGProps from GProp (Curve as any; - Tool as any) - -inherits GProps from GProp - - --- Purpose : - -- Computes the global properties of bounded curves - -- in 3D space. The curve must have at least a continuity C1. - -- It can be a curve as defined in the template CurveTool from - -- package GProp. This template gives the minimum of methods - -- required to evaluate the global properties of a curve 3D with - -- the algorithmes of GProp. - -uses Pnt from gp - -is - - Create returns CGProps; - - Create (C : Curve; CLocation : Pnt) returns CGProps; - - SetLocation(me : in out;CLocation : Pnt) ; - - Perform(me : in out; C : Curve); - -end CGProps; - - diff --git a/src/GProp/GProp_CGProps.gxx b/src/GProp/GProp_CGProps.gxx deleted file mode 100644 index 43128e046c..0000000000 --- a/src/GProp/GProp_CGProps.gxx +++ /dev/null @@ -1,157 +0,0 @@ -// 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 -#include -#include -#include -#include - -#include - - -GProp_CGProps::GProp_CGProps(){} - -void GProp_CGProps::SetLocation(const gp_Pnt& CLocation) -{ - loc = CLocation; -} - -void GProp_CGProps::Perform (const Curve& C) -{ - - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - - Standard_Real Lower = Tool::FirstParameter (C); - Standard_Real Upper = Tool::LastParameter (C); - Standard_Integer Order = Min(Tool::IntegrationOrder (C), - math::GaussPointsMax()); - - gp_Pnt P; //value on the curve - gp_Vec V1; //first derivative on the curve - Standard_Real ds; //curvilign abscissae - Standard_Real ur, um, u; - Standard_Real x, y, z; - Standard_Real xloc, yloc, zloc; - - math_Vector GaussP (1, Order); - math_Vector GaussW (1, Order); - - //Recuperation des points de Gauss dans le fichier GaussPoints. - math::GaussPoints (Order,GaussP); - math::GaussWeights (Order,GaussW); - - // modified by NIZHNY-MKK Thu Jun 9 12:13:21 2005.BEGIN - Standard_Integer nbIntervals = Tool::NbIntervals(C, GeomAbs_CN); - Standard_Boolean bHasIntervals = (nbIntervals > 1); - TColStd_Array1OfReal TI(1, nbIntervals + 1); - - if(bHasIntervals) { - Tool::Intervals(C, TI, GeomAbs_CN); - } - else { - nbIntervals = 1; - } - Standard_Integer nIndex = 0; - Standard_Real UU1 = Min(Lower, Upper); - Standard_Real UU2 = Max(Lower, Upper); - - for(nIndex = 1; nIndex <= nbIntervals; nIndex++) { - if(bHasIntervals) { - Lower = Max(TI(nIndex), UU1); - Upper = Min(TI(nIndex+1), UU2); - } - else { - Lower = UU1; - Upper = UU2; - } - - Standard_Real dimLocal, IxLocal, IyLocal, IzLocal, IxxLocal, IyyLocal, IzzLocal, IxyLocal, IxzLocal, IyzLocal; - dimLocal = IxLocal = IyLocal = IzLocal = IxxLocal = IyyLocal = IzzLocal = IxyLocal = IxzLocal = IyzLocal = 0.0; - // modified by NIZHNY-MKK Thu Jun 9 12:13:32 2005.END - - loc.Coord (xloc, yloc, zloc); - - Standard_Integer i; - - // Calcul des integrales aux points de gauss : - um = 0.5 * (Upper + Lower); - ur = 0.5 * (Upper - Lower); - - for (i = 1; i <= Order; i++) { - u = um + ur * GaussP (i); - Tool::D1 (C,u, P, V1); - ds = V1.Magnitude(); - P.Coord (x, y, z); - x -= xloc; - y -= yloc; - z -= zloc; - ds *= GaussW (i); - dimLocal += ds; - IxLocal += x * ds; - IyLocal += y * ds; - IzLocal += z * ds; - IxyLocal += x * y * ds; - IyzLocal += y * z * ds; - IxzLocal += x * z * ds; - x *= x; - y *= y; - z *= z; - IxxLocal += (y + z) * ds; - IyyLocal += (x + z) * ds; - IzzLocal += (x + y) * ds; - } - // modified by NIZHNY-MKK Thu Jun 9 12:13:47 2005.BEGIN - dimLocal *= ur; - IxLocal *= ur; - IyLocal *= ur; - IzLocal *= ur; - IxxLocal *= ur; - IyyLocal *= ur; - IzzLocal *= ur; - IxyLocal *= ur; - IxzLocal *= ur; - IyzLocal *= ur; - - dim += dimLocal; - Ix += IxLocal; - Iy += IyLocal; - Iz += IzLocal; - Ixx += IxxLocal; - Iyy += IyyLocal; - Izz += IzzLocal; - Ixy += IxyLocal; - Ixz += IxzLocal; - Iyz += IyzLocal; - } - // modified by NIZHNY-MKK Thu Jun 9 12:13:55 2005.END - - inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), - gp_XYZ (-Ixy, Iyy, -Iyz), - gp_XYZ (-Ixz, -Iyz, Izz)); - - if (Abs(dim) < gp::Resolution()) - g = P; - else - g.SetCoord (Ix/dim, Iy/dim, Iz/dim); -} - - -GProp_CGProps::GProp_CGProps (const Curve& C, - const gp_Pnt& CLocation) -{ - SetLocation(CLocation); - Perform(C); -} diff --git a/src/GProp/GProp_SGProps.cdl b/src/GProp/GProp_SGProps.cdl deleted file mode 100644 index 6774a59423..0000000000 --- a/src/GProp/GProp_SGProps.cdl +++ /dev/null @@ -1,62 +0,0 @@ --- Created on: 1991-04-12 --- Created by: Michel CHAUVAT --- Copyright (c) 1991-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. - --- Jean-Claude VAUTHIER January 1992 - - -generic class SGProps from GProp ( Arc as any; - Face as any; - Domain as any) -inherits GProps - - --- Purpose : - -- Computes the global properties of a face in 3D space. - -- The face 's requirements to evaluate the global properties - -- are defined in the template FaceTool from package GProp. - -uses Pnt from gp -is - - Create returns SGProps; - - Create (S: Face; SLocation: Pnt) returns SGProps; - Create (S : in out Face; D : in out Domain; SLocation : Pnt) returns SGProps; - --- Purpose : - -- Builds a SGProps to evaluate the global properties of - -- the face . If isNaturalRestriction is true the domain of S is defined - -- with the natural bounds, else it defined with an iterator - -- of Arc (see DomainTool from GProp) - Create (S: in out Face; SLocation: Pnt; Eps: Real) returns SGProps; - Create (S: in out Face; D : in out Domain; SLocation: Pnt; Eps: Real) returns SGProps; - -- --"-- - -- Parameter Eps sets maximal relative error of computed area. - - SetLocation(me: in out; SLocation: Pnt); - - Perform(me: in out; S: Face); - Perform(me : in out; S : in out Face ; D : in out Domain); - Perform(me: in out; S: in out Face; Eps: Real) returns Real; - Perform(me: in out; S: in out Face; D : in out Domain; Eps: Real) returns Real; - - GetEpsilon(me: out) returns Real; - --- Purpose : - -- If previously used method contained Eps parameter - -- get actual relative error of the computation, else return 1.0. -fields - - myEpsilon: Real from Standard; - -end SGProps; diff --git a/src/GProp/GProp_SGProps.gxx b/src/GProp/GProp_SGProps.gxx deleted file mode 100644 index 62535d3f79..0000000000 --- a/src/GProp/GProp_SGProps.gxx +++ /dev/null @@ -1,1026 +0,0 @@ -// 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 -#include -#include -#include -#include -#include -#include - -#include -#include - -class HMath_Vector{ - math_Vector *pvec; - void operator=(const math_Vector&){} - public: - HMath_Vector(){ pvec = 0;} - HMath_Vector(math_Vector* pv){ pvec = pv;} - ~HMath_Vector(){ if(pvec != 0) delete pvec;} - void operator=(math_Vector* pv){ if(pvec != pv && pvec != 0) delete pvec; pvec = pv;} - Standard_Real& operator()(Standard_Integer i){ return (*pvec).operator()(i);} - const Standard_Real& operator()(Standard_Integer i) const{ return (*pvec).operator()(i);} - const math_Vector* operator->() const{ return pvec;} - math_Vector* operator->(){ return pvec;} - math_Vector* Vector(){ return pvec;} - math_Vector* Init(Standard_Real v, Standard_Integer i = 0, Standard_Integer iEnd = 0){ - if(pvec == 0) return pvec; - if(iEnd - i == 0) pvec->Init(v); - else { Standard_Integer End = (iEnd <= pvec->Upper()) ? iEnd : pvec->Upper(); - for(; i <= End; i++) pvec->operator()(i) = v; } - return pvec; - } -}; - -static Standard_Real EPS_PARAM = 1.e-12; -static Standard_Real EPS_DIM = 1.e-20; -static Standard_Real ERROR_ALGEBR_RATIO = 2.0/3.0; - -static Standard_Integer GPM = 61; -static Standard_Integer SUBS_POWER = 32; -static Standard_Integer SM = 1953; - -static math_Vector LGaussP0(1,GPM); -static math_Vector LGaussW0(1,GPM); -static math_Vector LGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); -static math_Vector LGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); - -static math_Vector* LGaussP[] = {&LGaussP0,&LGaussP1}; -static math_Vector* LGaussW[] = {&LGaussW0,&LGaussW1}; - -static HMath_Vector L1 = new math_Vector(1,SM,0.0); -static HMath_Vector L2 = new math_Vector(1,SM,0.0); -static HMath_Vector DimL = new math_Vector(1,SM,0.0); -static HMath_Vector ErrL = new math_Vector(1,SM,0.0); -static HMath_Vector ErrUL = new math_Vector(1,SM,0.0); -static HMath_Vector IxL = new math_Vector(1,SM,0.0); -static HMath_Vector IyL = new math_Vector(1,SM,0.0); -static HMath_Vector IzL = new math_Vector(1,SM,0.0); -static HMath_Vector IxxL = new math_Vector(1,SM,0.0); -static HMath_Vector IyyL = new math_Vector(1,SM,0.0); -static HMath_Vector IzzL = new math_Vector(1,SM,0.0); -static HMath_Vector IxyL = new math_Vector(1,SM,0.0); -static HMath_Vector IxzL = new math_Vector(1,SM,0.0); -static HMath_Vector IyzL = new math_Vector(1,SM,0.0); - -static math_Vector UGaussP0(1,GPM); -static math_Vector UGaussW0(1,GPM); -static math_Vector UGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); -static math_Vector UGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); - -static math_Vector* UGaussP[] = {&UGaussP0,&UGaussP1}; -static math_Vector* UGaussW[] = {&UGaussW0,&UGaussW1}; - -static HMath_Vector U1 = new math_Vector(1,SM,0.0); -static HMath_Vector U2 = new math_Vector(1,SM,0.0); -static HMath_Vector DimU = new math_Vector(1,SM,0.0); -static HMath_Vector ErrU = new math_Vector(1,SM,0.0); -static HMath_Vector IxU = new math_Vector(1,SM,0.0); -static HMath_Vector IyU = new math_Vector(1,SM,0.0); -static HMath_Vector IzU = new math_Vector(1,SM,0.0); -static HMath_Vector IxxU = new math_Vector(1,SM,0.0); -static HMath_Vector IyyU = new math_Vector(1,SM,0.0); -static HMath_Vector IzzU = new math_Vector(1,SM,0.0); -static HMath_Vector IxyU = new math_Vector(1,SM,0.0); -static HMath_Vector IxzU = new math_Vector(1,SM,0.0); -static HMath_Vector IyzU = new math_Vector(1,SM,0.0); - -static inline Standard_Real MultiplicationInf(Standard_Real theMA, Standard_Real theMB) -{ - if((theMA == 0.0) || (theMB == 0.0)) //strictly zerro (without any tolerances) - return 0.0; - - if(Precision::IsPositiveInfinite(theMA)) - { - if(theMB < 0.0) - return -Precision::Infinite(); - else - return Precision::Infinite(); - } - - if(Precision::IsPositiveInfinite(theMB)) - { - if(theMA < 0.0) - return -Precision::Infinite(); - else - return Precision::Infinite(); - } - - if(Precision::IsNegativeInfinite(theMA)) - { - if(theMB < 0.0) - return +Precision::Infinite(); - else - return -Precision::Infinite(); - } - - if(Precision::IsNegativeInfinite(theMB)) - { - if(theMA < 0.0) - return +Precision::Infinite(); - else - return -Precision::Infinite(); - } - - return (theMA * theMB); -} - -static inline Standard_Real AdditionInf(Standard_Real theMA, Standard_Real theMB) -{ - if(Precision::IsPositiveInfinite(theMA)) - { - if(Precision::IsNegativeInfinite(theMB)) - return 0.0; - else - return Precision::Infinite(); - } - - if(Precision::IsPositiveInfinite(theMB)) - { - if(Precision::IsNegativeInfinite(theMA)) - return 0.0; - else - return Precision::Infinite(); - } - - if(Precision::IsNegativeInfinite(theMA)) - { - if(Precision::IsPositiveInfinite(theMB)) - return 0.0; - else - return -Precision::Infinite(); - } - - if(Precision::IsNegativeInfinite(theMB)) - { - if(Precision::IsPositiveInfinite(theMA)) - return 0.0; - else - return -Precision::Infinite(); - } - - return (theMA + theMB); -} - -static inline Standard_Real Multiplication(Standard_Real theMA, Standard_Real theMB) -{ - return (theMA * theMB); -} - -static inline Standard_Real Addition(Standard_Real theMA, Standard_Real theMB) -{ - return (theMA + theMB); -} - -static Standard_Integer FillIntervalBounds(Standard_Real A, - Standard_Real B, - const TColStd_Array1OfReal& Knots, - HMath_Vector& VA, - HMath_Vector& VB) -{ - Standard_Integer i = 1, iEnd = Knots.Upper(), j = 1, k = 1; - VA(j++) = A; - for(; i <= iEnd; i++){ - Standard_Real kn = Knots(i); - if(A < kn) - { - if(kn < B) - { - VA(j++) = VB(k++) = kn; - } - else - { - break; - } - } - } - VB(k) = B; - return k; -} - -static inline Standard_Integer MaxSubs(Standard_Integer n, Standard_Integer coeff = SUBS_POWER){ - // return n = IntegerLast()/coeff < n? IntegerLast(): n*coeff + 1; - return Min((n * coeff + 1),SM); -} - -static Standard_Integer LFillIntervalBounds(Standard_Real A, - Standard_Real B, - const TColStd_Array1OfReal& Knots, - const Standard_Integer NumSubs) -{ - Standard_Integer iEnd = Knots.Upper(), jEnd = L1->Upper(); - if(iEnd - 1 > jEnd){ - iEnd = MaxSubs(iEnd-1,NumSubs); - L1 = new math_Vector(1,iEnd); - L2 = new math_Vector(1,iEnd); - DimL = new math_Vector(1,iEnd); - ErrL = new math_Vector(1,iEnd,0.0); - ErrUL = new math_Vector(1,iEnd,0.0); - IxL = new math_Vector(1,iEnd); - IyL = new math_Vector(1,iEnd); - IzL = new math_Vector(1,iEnd); - IxxL = new math_Vector(1,iEnd); - IyyL = new math_Vector(1,iEnd); - IzzL = new math_Vector(1,iEnd); - IxyL = new math_Vector(1,iEnd); - IxzL = new math_Vector(1,iEnd); - IyzL = new math_Vector(1,iEnd); - } - return FillIntervalBounds(A, B, Knots, L1, L2); -} - -static Standard_Integer UFillIntervalBounds(Standard_Real A, - Standard_Real B, - const TColStd_Array1OfReal& Knots, - const Standard_Integer NumSubs) -{ - Standard_Integer iEnd = Knots.Upper(), jEnd = U1->Upper(); - if(iEnd - 1 > jEnd){ - iEnd = MaxSubs(iEnd-1,NumSubs); - U1 = new math_Vector(1,iEnd); - U2 = new math_Vector(1,iEnd); - DimU = new math_Vector(1,iEnd); - ErrU = new math_Vector(1,iEnd,0.0); - IxU = new math_Vector(1,iEnd); - IyU = new math_Vector(1,iEnd); - IzU = new math_Vector(1,iEnd); - IxxU = new math_Vector(1,iEnd); - IyyU = new math_Vector(1,iEnd); - IzzU = new math_Vector(1,iEnd); - IxyU = new math_Vector(1,iEnd); - IxzU = new math_Vector(1,iEnd); - IyzU = new math_Vector(1,iEnd); - } - return FillIntervalBounds(A, B, Knots, U1, U2); -} - -static Standard_Real CCompute(Face& S, - Domain& D, - const gp_Pnt& loc, - Standard_Real& Dim, - gp_Pnt& g, - gp_Mat& inertia, - const Standard_Real EpsDim, - const Standard_Boolean isErrorCalculation, - const Standard_Boolean isVerifyComputation) -{ - Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); - Standard_Real (*FuncMul)(Standard_Real, Standard_Real); - - FuncAdd = Addition; - FuncMul = Multiplication; - - Standard_Boolean isNaturalRestriction = S.NaturalRestriction(); - - Standard_Integer NumSubs = SUBS_POWER; - - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - Dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - Standard_Real x, y, z; - //boundary curve parametrization - Standard_Real l1, l2, lm, lr, l; - //Face parametrization in U and V direction - Standard_Real BV1, BV2, v; - Standard_Real BU1, BU2, u1, u2, um, ur, u; - S.Bounds (BU1, BU2, BV1, BV2); - u1 = BU1; - - if(Precision::IsInfinite(BU1) || Precision::IsInfinite(BU2) || - Precision::IsInfinite(BV1) || Precision::IsInfinite(BV2)) - { - FuncAdd = AdditionInf; - FuncMul = MultiplicationInf; - } - - - //location point used to compute the inertia - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); // use member of parent class - //Jacobien (x, y, z) -> (u, v) = ||n|| - Standard_Real ds; - //On the Face - gp_Pnt Ps; - gp_Vec VNor; - //On the boundary curve u-v - gp_Pnt2d Puv; - gp_Vec2d Vuv; - Standard_Real Dul; // Dul = Du / Dl - Standard_Real CDim[2], CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz; - Standard_Real LocDim[2], LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, LocIxz, LocIyz; - - Standard_Real ErrorU, ErrorL, ErrorLMax = 0.0, Eps=0.0, EpsL=0.0, EpsU=0.0; - - Standard_Integer iD = 0, NbLSubs, iLS, iLSubEnd, iGL, iGLEnd, NbLGaussP[2], LRange[2], iL, kL, kLEnd, IL, JL; - Standard_Integer i, NbUSubs, iUS, iUSubEnd, iGU, iGUEnd, NbUGaussP[2], URange[2], iU, kU, kUEnd, IU, JU; - Standard_Integer UMaxSubs, LMaxSubs; - iGLEnd = isErrorCalculation? 2: 1; - for(i = 0; i < 2; i++) { - LocDim[i] = 0.0; - CDim[i] = 0.0; - } - - NbUGaussP[0] = S.SIntOrder(EpsDim); - NbUGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbUGaussP[0])); - math::GaussPoints(NbUGaussP[0],UGaussP0); math::GaussWeights(NbUGaussP[0],UGaussW0); - math::GaussPoints(NbUGaussP[1],UGaussP1); math::GaussWeights(NbUGaussP[1],UGaussW1); - - NbUSubs = S.SUIntSubs(); - TColStd_Array1OfReal UKnots(1,NbUSubs+1); - S.UKnots(UKnots); - - while (isNaturalRestriction || D.More()) - { - if(isNaturalRestriction) - { - NbLGaussP[0] = Min(2*NbUGaussP[0],math::GaussPointsMax()); - } - else - { - S.Load(D.Value()); ++iD; - NbLGaussP[0] = S.LIntOrder(EpsDim); - } - - NbLGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbLGaussP[0])); - math::GaussPoints(NbLGaussP[0],LGaussP0); math::GaussWeights(NbLGaussP[0],LGaussW0); - math::GaussPoints(NbLGaussP[1],LGaussP1); math::GaussWeights(NbLGaussP[1],LGaussW1); - - NbLSubs = isNaturalRestriction? S.SVIntSubs(): S.LIntSubs(); - - TColStd_Array1OfReal LKnots(1,NbLSubs+1); - if(isNaturalRestriction) - { - S.VKnots(LKnots); - l1 = BV1; l2 = BV2; - } - else - { - S.LKnots(LKnots); - l1 = S.FirstParameter(); l2 = S.LastParameter(); - } - - ErrorL = 0.0; - kLEnd = 1; JL = 0; - //OCC503(apo): if(Abs(l2-l1) < EPS_PARAM) continue; - if(Abs(l2-l1) > EPS_PARAM) - { - iLSubEnd = LFillIntervalBounds(l1, l2, LKnots, NumSubs); - LMaxSubs = MaxSubs(iLSubEnd); - if(LMaxSubs > DimL.Vector()->Upper()) - LMaxSubs = DimL.Vector()->Upper(); - - DimL.Init(0.0,1,LMaxSubs); ErrL.Init(0.0,1,LMaxSubs); ErrUL.Init(0.0,1,LMaxSubs); - - do{// while: L - if(++JL > iLSubEnd) - { - LRange[0] = IL = ErrL->Max(); - LRange[1] = JL; - L1(JL) = (L1(IL) + L2(IL))/2.0; - L2(JL) = L2(IL); - L2(IL) = L1(JL); - } - else - LRange[0] = IL = JL; - - if(JL == LMaxSubs || Abs(L2(JL) - L1(JL)) < EPS_PARAM) - if(kLEnd == 1) - { - DimL(JL) = ErrL(JL) = IxL(JL) = IyL(JL) = IzL(JL) = - IxxL(JL) = IyyL(JL) = IzzL(JL) = IxyL(JL) = IxzL(JL) = IyzL(JL) = 0.0; - }else{ - JL--; - EpsL = ErrorL; Eps = EpsL/0.9; - break; - } - else - for(kL=0; kL < kLEnd; kL++) - { - iLS = LRange[kL]; - lm = 0.5*(L2(iLS) + L1(iLS)); - lr = 0.5*(L2(iLS) - L1(iLS)); - CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; - - for(iGL=0; iGL < iGLEnd; iGL++) - { - CDim[iGL] = 0.0; - for(iL=1; iL<=NbLGaussP[iGL]; iL++) - { - l = lm + lr*(*LGaussP[iGL])(iL); - if(isNaturalRestriction) - { - v = l; u2 = BU2; Dul = (*LGaussW[iGL])(iL); - } - else - { - S.D12d (l, Puv, Vuv); - Dul = Vuv.Y()*(*LGaussW[iGL])(iL); // Dul = Du / Dl - if(Abs(Dul) < EPS_PARAM) - continue; - - v = Puv.Y(); - u2 = Puv.X(); - //Check on cause out off bounds of value current parameter - if(v < BV1) - v = BV1; - else if(v > BV2) - v = BV2; - - if(u2 < BU1) - u2 = BU1; - else if(u2 > BU2) - u2 = BU2; - } - - ErrUL(iLS) = 0.0; - kUEnd = 1; - JU = 0; - - if(Abs(u2-u1) < EPS_PARAM) - continue; - - iUSubEnd = UFillIntervalBounds(u1, u2, UKnots, NumSubs); - UMaxSubs = MaxSubs(iUSubEnd); - if(UMaxSubs > DimU.Vector()->Upper()) - UMaxSubs = DimU.Vector()->Upper(); - - DimU.Init(0.0,1,UMaxSubs); ErrU.Init(0.0,1,UMaxSubs); ErrorU = 0.0; - - do{//while: U - if(++JU > iUSubEnd) - { - URange[0] = IU = ErrU->Max(); - URange[1] = JU; - U1(JU) = (U1(IU)+U2(IU))/2.0; - U2(JU) = U2(IU); - U2(IU) = U1(JU); - } - else - URange[0] = IU = JU; - - if(JU == UMaxSubs || Abs(U2(JU) - U1(JU)) < EPS_PARAM) - if(kUEnd == 1) - { - DimU(JU) = ErrU(JU) = IxU(JU) = IyU(JU) = IzU(JU) = - IxxU(JU) = IyyU(JU) = IzzU(JU) = IxyU(JU) = IxzU(JU) = IyzU(JU) = 0.0; - }else - { - JU--; - EpsU = ErrorU; Eps = EpsU*Abs((u2-u1)*Dul)/0.1; EpsL = 0.9*Eps; - break; - } - else - for(kU=0; kU < kUEnd; kU++) - { - iUS = URange[kU]; - um = 0.5*(U2(iUS) + U1(iUS)); - ur = 0.5*(U2(iUS) - U1(iUS)); - LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = LocIxy = LocIxz = LocIyz = 0.0; - iGUEnd = iGLEnd - iGL; - for(iGU=0; iGU < iGUEnd; iGU++) - { - LocDim[iGU] = 0.0; - for(iU=1; iU <= NbUGaussP[iGU]; iU++) - { - u = um + ur*(*UGaussP[iGU])(iU); - S.Normal(u, v, Ps, VNor); - ds = VNor.Magnitude(); //Jacobien(x,y,z) -> (u,v)=||n|| - ds *= (*UGaussW[iGU])(iU); - LocDim[iGU] += ds; - - if(iGU > 0) - continue; - - Ps.Coord(x, y, z); - x = FuncAdd(x, -xloc); - y = FuncAdd(y, -yloc); - z = FuncAdd(z, -zloc); - - const Standard_Real XdS = FuncMul(x, ds); - const Standard_Real YdS = FuncMul(y, ds); - const Standard_Real ZdS = FuncMul(z, ds); - - LocIx = FuncAdd(LocIx, XdS); - LocIy = FuncAdd(LocIy, YdS); - LocIz = FuncAdd(LocIz, ZdS); - LocIxy = FuncAdd(LocIxy, FuncMul(x, YdS)); - LocIyz = FuncAdd(LocIyz, FuncMul(y, ZdS)); - LocIxz = FuncAdd(LocIxz, FuncMul(x, ZdS)); - - const Standard_Real XXdS = FuncMul(x, XdS); - const Standard_Real YYdS = FuncMul(y, YdS); - const Standard_Real ZZdS = FuncMul(z, ZdS); - - LocIxx = FuncAdd(LocIxx, FuncAdd(YYdS, ZZdS)); - LocIyy = FuncAdd(LocIyy, FuncAdd(XXdS, ZZdS)); - LocIzz = FuncAdd(LocIzz, FuncAdd(XXdS, YYdS)); - }//for: iU - }//for: iGU - - DimU(iUS) = FuncMul(LocDim[0],ur); - if(iGL > 0) - continue; - - ErrU(iUS) = FuncMul(Abs(LocDim[1]-LocDim[0]), ur); - IxU(iUS) = FuncMul(LocIx, ur); - IyU(iUS) = FuncMul(LocIy, ur); - IzU(iUS) = FuncMul(LocIz, ur); - IxxU(iUS) = FuncMul(LocIxx, ur); - IyyU(iUS) = FuncMul(LocIyy, ur); - IzzU(iUS) = FuncMul(LocIzz, ur); - IxyU(iUS) = FuncMul(LocIxy, ur); - IxzU(iUS) = FuncMul(LocIxz, ur); - IyzU(iUS) = FuncMul(LocIyz, ur); - }//for: kU (iUS) - - if(JU == iUSubEnd) - kUEnd = 2; - - if(kUEnd == 2) - ErrorU = ErrU(ErrU->Max()); - }while((ErrorU - EpsU > 0.0 && EpsU != 0.0) || kUEnd == 1); - - for(i=1; i<=JU; i++) - CDim[iGL] = FuncAdd(CDim[iGL], FuncMul(DimU(i), Dul)); - - if(iGL > 0) - continue; - - ErrUL(iLS) = ErrorU*Abs((u2-u1)*Dul); - for(i=1; i<=JU; i++) - { - CIx = FuncAdd(CIx, FuncMul(IxU(i), Dul)); - CIy = FuncAdd(CIy, FuncMul(IyU(i), Dul)); - CIz = FuncAdd(CIz, FuncMul(IzU(i), Dul)); - CIxx = FuncAdd(CIxx, FuncMul(IxxU(i), Dul)); - CIyy = FuncAdd(CIyy, FuncMul(IyyU(i), Dul)); - CIzz = FuncAdd(CIzz, FuncMul(IzzU(i), Dul)); - CIxy = FuncAdd(CIxy, FuncMul(IxyU(i), Dul)); - CIxz = FuncAdd(CIxz, FuncMul(IxzU(i), Dul)); - CIyz = FuncAdd(CIyz, FuncMul(IyzU(i), Dul)); - } - }//for: iL - }//for: iGL - - DimL(iLS) = FuncMul(CDim[0], lr); - if(iGLEnd == 2) - ErrL(iLS) = FuncAdd(FuncMul(Abs(CDim[1]-CDim[0]),lr), ErrUL(iLS)); - - IxL(iLS) = FuncMul(CIx, lr); - IyL(iLS) = FuncMul(CIy, lr); - IzL(iLS) = FuncMul(CIz, lr); - IxxL(iLS) = FuncMul(CIxx, lr); - IyyL(iLS) = FuncMul(CIyy, lr); - IzzL(iLS) = FuncMul(CIzz, lr); - IxyL(iLS) = FuncMul(CIxy, lr); - IxzL(iLS) = FuncMul(CIxz, lr); - IyzL(iLS) = FuncMul(CIyz, lr); - }//for: (kL)iLS - // Calculate/correct epsilon of computation by current value of Dim - //That is need for not spend time for - if(JL == iLSubEnd) - { - kLEnd = 2; - Standard_Real DDim = 0.0; - for(i=1; i<=JL; i++) - DDim += DimL(i); - - DDim = Abs(DDim*EpsDim); - if(DDim > Eps) - { - Eps = DDim; - EpsL = 0.9*Eps; - } - } - - if(kLEnd == 2) - ErrorL = ErrL(ErrL->Max()); - }while((ErrorL - EpsL > 0.0 && isVerifyComputation) || kLEnd == 1); - - for(i=1; i<=JL; i++) - { - Dim = FuncAdd(Dim, DimL(i)); - Ix = FuncAdd(Ix, IxL(i)); - Iy = FuncAdd(Iy, IyL(i)); - Iz = FuncAdd(Iz, IzL(i)); - Ixx = FuncAdd(Ixx, IxxL(i)); - Iyy = FuncAdd(Iyy, IyyL(i)); - Izz = FuncAdd(Izz, IzzL(i)); - Ixy = FuncAdd(Ixy, IxyL(i)); - Ixz = FuncAdd(Ixz, IxzL(i)); - Iyz = FuncAdd(Iyz, IyzL(i)); - } - - ErrorLMax = Max(ErrorLMax, ErrorL); - } - - if(isNaturalRestriction) - break; - - D.Next(); - } - - if(Abs(Dim) >= EPS_DIM) - { - Ix /= Dim; - Iy /= Dim; - Iz /= Dim; - g.SetCoord (Ix, Iy, Iz); - } - else - { - Dim =0.0; - g.SetCoord (0., 0.,0.); - } - - inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), - gp_XYZ (-Ixy, Iyy, -Iyz), - gp_XYZ (-Ixz, -Iyz, Izz)); - - if(iGLEnd == 2) - Eps = Dim != 0.0? ErrorLMax/Abs(Dim): 0.0; - else - Eps = EpsDim; - - return Eps; -} - -static Standard_Real Compute(Face& S, const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, - Standard_Real EpsDim) -{ - Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; - Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; - EpsDim = Abs(EpsDim); - Domain D; - return CCompute(S,D,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); -} - -static Standard_Real Compute(Face& S, Domain& D, const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, - Standard_Real EpsDim) -{ - Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; - Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; - EpsDim = Abs(EpsDim); - return CCompute(S,D,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); -} - -static void Compute(Face& S, Domain& D, const gp_Pnt& loc, Standard_Real& dim, gp_Pnt& g, gp_Mat& inertia) -{ - Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); - Standard_Real (*FuncMul)(Standard_Real, Standard_Real); - - FuncAdd = Addition; - FuncMul = Multiplication; - - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - - Standard_Real x, y, z; - Standard_Integer NbCGaussgp_Pnts = 0; - - Standard_Real l1, l2, lm, lr, l; //boundary curve parametrization - Standard_Real v1, v2, v; //Face parametrization in v direction - Standard_Real u1, u2, um, ur, u; - Standard_Real ds; //Jacobien (x, y, z) -> (u, v) = ||n|| - - gp_Pnt P; //On the Face - gp_Vec VNor; - - gp_Pnt2d Puv; //On the boundary curve u-v - gp_Vec2d Vuv; - Standard_Real Dul; // Dul = Du / Dl - Standard_Real CArea, CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz; - Standard_Real LocArea, LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, - LocIxz, LocIyz; - - - S.Bounds (u1, u2, v1, v2); - - if(Precision::IsInfinite(u1) || Precision::IsInfinite(u2) || - Precision::IsInfinite(v1) || Precision::IsInfinite(v2)) - { - FuncAdd = AdditionInf; - FuncMul = MultiplicationInf; - } - - - Standard_Integer NbUGaussgp_Pnts = Min(S.UIntegrationOrder (), - math::GaussPointsMax()); - Standard_Integer NbVGaussgp_Pnts = Min(S.VIntegrationOrder (), - math::GaussPointsMax()); - - Standard_Integer NbGaussgp_Pnts = Max(NbUGaussgp_Pnts, NbVGaussgp_Pnts); - - //Number of Gauss points for the integration - //on the Face - math_Vector GaussSPV (1, NbGaussgp_Pnts); - math_Vector GaussSWV (1, NbGaussgp_Pnts); - math::GaussPoints (NbGaussgp_Pnts,GaussSPV); - math::GaussWeights (NbGaussgp_Pnts,GaussSWV); - - - //location point used to compute the inertia - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - - while (D.More()) { - - S.Load(D.Value()); - NbCGaussgp_Pnts = Min(S.IntegrationOrder (), math::GaussPointsMax()); - - math_Vector GaussCP (1, NbCGaussgp_Pnts); - math_Vector GaussCW (1, NbCGaussgp_Pnts); - math::GaussPoints (NbCGaussgp_Pnts,GaussCP); - math::GaussWeights (NbCGaussgp_Pnts,GaussCW); - - CArea = 0.0; - CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; - l1 = S.FirstParameter (); - l2 = S.LastParameter (); - lm = 0.5 * (l2 + l1); - lr = 0.5 * (l2 - l1); - - for (Standard_Integer i = 1; i <= NbCGaussgp_Pnts; i++) { - l = lm + lr * GaussCP (i); - S.D12d(l, Puv, Vuv); - v = Puv.Y(); - u2 = Puv.X(); - Dul = Vuv.Y(); - Dul *= GaussCW (i); - um = 0.5 * (u2 + u1); - ur = 0.5 * (u2 - u1); - LocArea = LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = - LocIxy = LocIxz = LocIyz = 0.0; - for (Standard_Integer j = 1; j <= NbGaussgp_Pnts; j++) { - u = FuncAdd(um, FuncMul(ur, GaussSPV (j))); - S.Normal (u, v, P, VNor); - ds = VNor.Magnitude(); //normal.Magnitude - ds = FuncMul(ds, Dul) * GaussSWV (j); - LocArea = FuncAdd(LocArea, ds); - P.Coord (x, y, z); - - x = FuncAdd(x, -xloc); - y = FuncAdd(y, -yloc); - z = FuncAdd(z, -zloc); - - const Standard_Real XdS = FuncMul(x, ds); - const Standard_Real YdS = FuncMul(y, ds); - const Standard_Real ZdS = FuncMul(z, ds); - - LocIx = FuncAdd(LocIx, XdS); - LocIy = FuncAdd(LocIy, YdS); - LocIz = FuncAdd(LocIz, ZdS); - LocIxy = FuncAdd(LocIxy, FuncMul(x, YdS)); - LocIyz = FuncAdd(LocIyz, FuncMul(y, ZdS)); - LocIxz = FuncAdd(LocIxz, FuncMul(x, ZdS)); - - const Standard_Real XXdS = FuncMul(x, XdS); - const Standard_Real YYdS = FuncMul(y, YdS); - const Standard_Real ZZdS = FuncMul(z, ZdS); - - LocIxx = FuncAdd(LocIxx, FuncAdd(YYdS, ZZdS)); - LocIyy = FuncAdd(LocIyy, FuncAdd(XXdS, ZZdS)); - LocIzz = FuncAdd(LocIzz, FuncAdd(XXdS, YYdS)); - } - - CArea = FuncAdd(CArea, FuncMul(LocArea, ur)); - CIx = FuncAdd(CIx, FuncMul(LocIx, ur)); - CIy = FuncAdd(CIy, FuncMul(LocIy, ur)); - CIz = FuncAdd(CIz, FuncMul(LocIz, ur)); - CIxx = FuncAdd(CIxx, FuncMul(LocIxx, ur)); - CIyy = FuncAdd(CIyy, FuncMul(LocIyy, ur)); - CIzz = FuncAdd(CIzz, FuncMul(LocIzz, ur)); - CIxy = FuncAdd(CIxy, FuncMul(LocIxy, ur)); - CIxz = FuncAdd(CIxz, FuncMul(LocIxz, ur)); - CIyz = FuncAdd(CIyz, FuncMul(LocIyz, ur)); - } - - dim = FuncAdd(dim, FuncMul(CArea, lr)); - Ix = FuncAdd(Ix, FuncMul(CIx, lr)); - Iy = FuncAdd(Iy, FuncMul(CIy, lr)); - Iz = FuncAdd(Iz, FuncMul(CIz, lr)); - Ixx = FuncAdd(Ixx, FuncMul(CIxx, lr)); - Iyy = FuncAdd(Iyy, FuncMul(CIyy, lr)); - Izz = FuncAdd(Izz, FuncMul(CIzz, lr)); - Ixy = FuncAdd(Ixy, FuncMul(CIxy, lr)); - Ixz = FuncAdd(Iyz, FuncMul(CIxz, lr)); - Iyz = FuncAdd(Ixz, FuncMul(CIyz, lr)); - D.Next(); - } - - if (Abs(dim) >= EPS_DIM) { - Ix /= dim; - Iy /= dim; - Iz /= dim; - g.SetCoord (Ix, Iy, Iz); - } - else { - dim =0.; - g.SetCoord (0., 0.,0.); - } - - inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz), - gp_XYZ (-Ixy, Iyy, -Iyz), - gp_XYZ (-Ixz, -Iyz, Izz)); -} - -static void Compute(const Face& S, - const gp_Pnt& loc, - Standard_Real& dim, - gp_Pnt& g, - gp_Mat& inertia) -{ - Standard_Real (*FuncAdd)(Standard_Real, Standard_Real); - Standard_Real (*FuncMul)(Standard_Real, Standard_Real); - - FuncAdd = Addition; - FuncMul = Multiplication; - - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - - Standard_Real LowerU, UpperU, LowerV, UpperV; - S.Bounds (LowerU, UpperU, LowerV, UpperV); - - if(Precision::IsInfinite(LowerU) || Precision::IsInfinite(UpperU) || - Precision::IsInfinite(LowerV) || Precision::IsInfinite(UpperV)) - { - FuncAdd = AdditionInf; - FuncMul = MultiplicationInf; - } - - Standard_Integer UOrder = Min(S.UIntegrationOrder (), - math::GaussPointsMax()); - Standard_Integer VOrder = Min(S.VIntegrationOrder (), - math::GaussPointsMax()); - gp_Pnt P; - gp_Vec VNor; - Standard_Real dsi, ds; - Standard_Real ur, um, u, vr, vm, v; - Standard_Real x, y, z; - Standard_Real Ixi, Iyi, Izi, Ixxi, Iyyi, Izzi, Ixyi, Ixzi, Iyzi; - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - - Standard_Integer i, j; - math_Vector GaussPU (1, UOrder); //gauss points and weights - math_Vector GaussWU (1, UOrder); - math_Vector GaussPV (1, VOrder); - math_Vector GaussWV (1, VOrder); - - //Recuperation des points de Gauss dans le fichier GaussPoints. - math::GaussPoints (UOrder,GaussPU); - math::GaussWeights (UOrder,GaussWU); - math::GaussPoints (VOrder,GaussPV); - math::GaussWeights (VOrder,GaussWV); - - // Calcul des integrales aux points de gauss : - um = 0.5 * FuncAdd(UpperU, LowerU); - vm = 0.5 * FuncAdd(UpperV, LowerV); - ur = 0.5 * FuncAdd(UpperU, -LowerU); - vr = 0.5 * FuncAdd(UpperV, -LowerV); - - for (j = 1; j <= VOrder; j++) { - v = FuncAdd(vm, FuncMul(vr, GaussPV(j))); - dsi = Ixi = Iyi = Izi = Ixxi = Iyyi = Izzi = Ixyi = Ixzi = Iyzi = 0.0; - - for (i = 1; i <= UOrder; i++) { - u = FuncAdd(um, FuncMul(ur, GaussPU (i))); - S.Normal (u, v, P, VNor); - ds = FuncMul(VNor.Magnitude(), GaussWU (i)); - P.Coord (x, y, z); - - x = FuncAdd(x, -xloc); - y = FuncAdd(y, -yloc); - z = FuncAdd(z, -zloc); - - dsi = FuncAdd(dsi, ds); - - const Standard_Real XdS = FuncMul(x, ds); - const Standard_Real YdS = FuncMul(y, ds); - const Standard_Real ZdS = FuncMul(z, ds); - - Ixi = FuncAdd(Ixi, XdS); - Iyi = FuncAdd(Iyi, YdS); - Izi = FuncAdd(Izi, ZdS); - Ixyi = FuncAdd(Ixyi, FuncMul(x, YdS)); - Iyzi = FuncAdd(Iyzi, FuncMul(y, ZdS)); - Ixzi = FuncAdd(Ixzi, FuncMul(x, ZdS)); - - const Standard_Real XXdS = FuncMul(x, XdS); - const Standard_Real YYdS = FuncMul(y, YdS); - const Standard_Real ZZdS = FuncMul(z, ZdS); - - Ixxi = FuncAdd(Ixxi, FuncAdd(YYdS, ZZdS)); - Iyyi = FuncAdd(Iyyi, FuncAdd(XXdS, ZZdS)); - Izzi = FuncAdd(Izzi, FuncAdd(XXdS, YYdS)); - } - - dim = FuncAdd(dim, FuncMul(dsi, GaussWV (j))); - Ix = FuncAdd(Ix, FuncMul(Ixi, GaussWV (j))); - Iy = FuncAdd(Iy, FuncMul(Iyi, GaussWV (j))); - Iz = FuncAdd(Iz, FuncMul(Izi, GaussWV (j))); - Ixx = FuncAdd(Ixx, FuncMul(Ixxi, GaussWV (j))); - Iyy = FuncAdd(Iyy, FuncMul(Iyyi, GaussWV (j))); - Izz = FuncAdd(Izz, FuncMul(Izzi, GaussWV (j))); - Ixy = FuncAdd(Ixy, FuncMul(Ixyi, GaussWV (j))); - Iyz = FuncAdd(Iyz, FuncMul(Iyzi, GaussWV (j))); - Ixz = FuncAdd(Ixz, FuncMul(Ixzi, GaussWV (j))); - } - - vr = FuncMul(vr, ur); - Ixx = FuncMul(vr, Ixx); - Iyy = FuncMul(vr, Iyy); - Izz = FuncMul(vr, Izz); - Ixy = FuncMul(vr, Ixy); - Ixz = FuncMul(vr, Ixz); - Iyz = FuncMul(vr, Iyz); - - if (Abs(dim) >= EPS_DIM) - { - Ix /= dim; - Iy /= dim; - Iz /= dim; - dim *= vr; - g.SetCoord (Ix, Iy, Iz); - } - else - { - dim =0.; - g.SetCoord (0.,0.,0.); - } - - inertia = gp_Mat (gp_XYZ ( Ixx, -Ixy, -Ixz), - gp_XYZ (-Ixy, Iyy, -Iyz), - gp_XYZ (-Ixz, -Iyz, Izz)); -} - -GProp_SGProps::GProp_SGProps(){} - -GProp_SGProps::GProp_SGProps (const Face& S, - const gp_Pnt& SLocation - ) -{ - SetLocation(SLocation); - Perform(S); -} - -GProp_SGProps::GProp_SGProps (Face& S, - Domain& D, - const gp_Pnt& SLocation - ) -{ - SetLocation(SLocation); - Perform(S,D); -} - -GProp_SGProps::GProp_SGProps(Face& S, const gp_Pnt& SLocation, const Standard_Real Eps){ - SetLocation(SLocation); - Perform(S, Eps); -} - -GProp_SGProps::GProp_SGProps(Face& S, Domain& D, const gp_Pnt& SLocation, const Standard_Real Eps){ - SetLocation(SLocation); - Perform(S, D, Eps); -} - -void GProp_SGProps::SetLocation(const gp_Pnt& SLocation){ - loc = SLocation; -} - -void GProp_SGProps::Perform(const Face& S){ - Compute(S,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -void GProp_SGProps::Perform(Face& S, Domain& D){ - Compute(S,D,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -Standard_Real GProp_SGProps::Perform(Face& S, const Standard_Real Eps){ - return myEpsilon = Compute(S,loc,dim,g,inertia,Eps); -} - -Standard_Real GProp_SGProps::Perform(Face& S, Domain& D, const Standard_Real Eps){ - return myEpsilon = Compute(S,D,loc,dim,g,inertia,Eps); -} - - -Standard_Real GProp_SGProps::GetEpsilon(){ - return myEpsilon; -} diff --git a/src/GProp/GProp_TFunction.gxx b/src/GProp/GProp_TFunction.gxx deleted file mode 100644 index 8da52526e0..0000000000 --- a/src/GProp/GProp_TFunction.gxx +++ /dev/null @@ -1,182 +0,0 @@ -// Created on: 2005-12-09 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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 -#include -#include -#include - -//======================================================================= -//function : Constructor. -//purpose : -//======================================================================= - -GProp_TFunction::GProp_TFunction(const Face &theSurface, - const gp_Pnt &theVertex, - const Standard_Boolean IsByPoint, - const Standard_Address theCoeffs, - const Standard_Real theUMin, - const Standard_Real theTolerance) - : mySurface(theSurface), - myUFunction(mySurface, theVertex, IsByPoint, theCoeffs), - myUMin(theUMin), - myTolerance(theTolerance), - myTolReached(0.), - myErrReached(0.), - myAbsError(0.), - myValueType(GProp_Unknown), - myIsByPoint(IsByPoint), - myNbPntOuter(3) -{ -} - -//======================================================================= -//function : Init -//purpose : -//======================================================================= - -void GProp_TFunction::Init() -{ - myTolReached = 0.; - myErrReached = 0.; - myAbsError = 0.; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= - -Standard_Boolean GProp_TFunction::Value(const Standard_Real X, - Standard_Real &F) -{ - - const Standard_Real tolU = 1.e-9; - - gp_Pnt2d aP2d; - gp_Vec2d aV2d; - Standard_Real aUMax; - Handle(TColStd_HArray1OfReal) anUKnots; - - mySurface.D12d(X, aP2d, aV2d); - aUMax = aP2d.X(); - - if(aUMax - myUMin < tolU) { - F = 0.; - return Standard_True; - } - - mySurface.GetUKnots(myUMin, aUMax, anUKnots); - myUFunction.SetVParam(aP2d.Y()); - - // Compute the integral from myUMin to aUMax of myUFunction. - Standard_Integer i; - Standard_Real aCoeff = aV2d.Y(); - //Standard_Integer aNbUIntervals = anUKnots->Length() - 1; - //Standard_Real aTol = myTolerance/aNbUIntervals; - Standard_Real aTol = myTolerance; - - //aTol /= myNbPntOuter; - - if (myValueType == GProp_Mass) { - if (myIsByPoint) - aCoeff /= 3.; - } else if (myValueType == GProp_CenterMassX || - myValueType == GProp_CenterMassY || - myValueType == GProp_CenterMassZ) { - if (myIsByPoint) - aCoeff *= 0.25; - } else if (myValueType == GProp_InertiaXX || - myValueType == GProp_InertiaYY || - myValueType == GProp_InertiaZZ || - myValueType == GProp_InertiaXY || - myValueType == GProp_InertiaXZ || - myValueType == GProp_InertiaYZ) { - if (myIsByPoint) - aCoeff *= 0.2; - } else - return Standard_False; - - Standard_Real aAbsCoeff = Abs(aCoeff); - - if (aAbsCoeff <= Precision::Angular()) { - // No need to compute the integral. The value will be equal to 0. - F = 0.; - return Standard_True; - } - //else if (aAbsCoeff > 10.*aTol) - // aTol /= aAbsCoeff; - //else - // aTol = 0.1; - - Standard_Integer iU = anUKnots->Upper(); - Standard_Integer aNbPntsStart; - Standard_Integer aNbMaxIter = 1000; - math_KronrodSingleIntegration anIntegral; - Standard_Real aLocalErr = 0.; - - i = anUKnots->Lower(); - F = 0.; - - // Epmirical criterion - aNbPntsStart = Min(15, mySurface.UIntegrationOrder()/(anUKnots->Length() - 1)+1); - aNbPntsStart = Max(5, aNbPntsStart); - - while (i < iU) { - Standard_Real aU1 = anUKnots->Value(i++); - Standard_Real aU2 = anUKnots->Value(i); - - if(aU2 - aU1 < tolU) continue; - - anIntegral.Perform(myUFunction, aU1, aU2, aNbPntsStart, aTol, aNbMaxIter); - - if (!anIntegral.IsDone()) - return Standard_False; - - F += anIntegral.Value(); - aLocalErr += anIntegral.AbsolutError(); - //cout << " TFunction : " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << endl; - } - - F *= aCoeff; - aLocalErr *= aAbsCoeff; - myAbsError = Max(myAbsError, aLocalErr); - - myTolReached += aLocalErr; - - if(Abs(F) > Epsilon(1.)) aLocalErr /= Abs(F); - - myErrReached = Max(myErrReached, aLocalErr); - - - return Standard_True; -} - -//======================================================================= -//function : GetStateNumber -//purpose : -//======================================================================= - -Standard_Integer GProp_TFunction::GetStateNumber() -{ - //myErrReached = myTolReached; - //myTolReached = 0.; - //myNbPntOuter += RealToInt(0.5*myNbPntOuter); - - //if (myNbPntOuter%2 == 0) - //myNbPntOuter++; - - return 0; -} diff --git a/src/GProp/GProp_TFunction.lxx b/src/GProp/GProp_TFunction.lxx deleted file mode 100644 index 9fd557eee6..0000000000 --- a/src/GProp/GProp_TFunction.lxx +++ /dev/null @@ -1,66 +0,0 @@ -// Created on: 2005-12-21 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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. - -//======================================================================= -//function : SetNbKronrodPoints -//purpose : -//======================================================================= - -inline void GProp_TFunction::SetNbKronrodPoints - (const Standard_Integer theNbPoints) -{ - myNbPntOuter = (theNbPoints%2 == 0) ? theNbPoints + 1 : theNbPoints; -} - -//======================================================================= -//function : SetValueType -//purpose : -//======================================================================= - -inline void GProp_TFunction::SetValueType(const GProp_ValueType theType) -{ - myValueType = theType; - myUFunction.SetValueType(myValueType); -} - -//======================================================================= -//function : SetTolerance -//purpose : -//======================================================================= - -inline void GProp_TFunction::SetTolerance(const Standard_Real theTolerance) -{ - myTolerance = theTolerance; -} - -//======================================================================= -//function : TolReached -//purpose : -//======================================================================= - -inline Standard_Real GProp_TFunction::ErrorReached() const -{ - return myErrReached; -} - -//======================================================================= -//function : ErrorReached -//purpose : -//======================================================================= - -inline Standard_Real GProp_TFunction::AbsolutError() const -{ - return myAbsError; -} diff --git a/src/GProp/GProp_UFunction.gxx b/src/GProp/GProp_UFunction.gxx deleted file mode 100644 index fc5ac30ae5..0000000000 --- a/src/GProp/GProp_UFunction.gxx +++ /dev/null @@ -1,266 +0,0 @@ -// Created on: 2005-12-09 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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. - -//======================================================================= -//function : Constructor. -//purpose : -//======================================================================= - -GProp_UFunction::GProp_UFunction(const Face &theSurface, - const gp_Pnt &theVertex, - const Standard_Boolean IsByPoint, - const Standard_Address theCoeffs) - : mySurface(theSurface), - myVertex(theVertex), - myCoeffs(theCoeffs), - myVParam(0.), - myValueType(GProp_Unknown), - myIsByPoint(IsByPoint) -{ -} - -//======================================================================= -//function : Value -//purpose : Returns a value of the function. -//======================================================================= - -Standard_Boolean GProp_UFunction::Value(const Standard_Real X, - Standard_Real &F) -{ - // Volume computation - if (myValueType == GProp_Mass) { - gp_XYZ aPMP0; - Standard_Real aTmpPar1; - Standard_Real aTmpPar2; - - F = VolumeValue(X, aPMP0, aTmpPar1, aTmpPar2); - - return Standard_True; - } - - // Center of mass computation - if (myValueType == GProp_CenterMassX || - myValueType == GProp_CenterMassY || - myValueType == GProp_CenterMassZ) - return CenterMassValue(X, F); - - // Inertia computation - if (myValueType == GProp_InertiaXX || - myValueType == GProp_InertiaYY || - myValueType == GProp_InertiaZZ || - myValueType == GProp_InertiaXY || - myValueType == GProp_InertiaXZ || - myValueType == GProp_InertiaYZ) - return InertiaValue(X, F); - - return Standard_False; -} - -//======================================================================= -//function : VolumeValue -//purpose : Returns the value for volume computation. -//======================================================================= - -Standard_Real GProp_UFunction::VolumeValue(const Standard_Real X, - gp_XYZ &thePMP0, - Standard_Real &theS, - Standard_Real &theD1) -{ - gp_Pnt aPnt; - gp_Vec aNorm; - - mySurface.Normal(X, myVParam, aPnt, aNorm); - - thePMP0 = aPnt.XYZ().Subtracted(myVertex.XYZ()); - - // Volume computation for ByPoint mode. - if (myIsByPoint) - return thePMP0.Dot(aNorm.XYZ()); - - // Volume and additional coefficients computation for ByPlane mode. - Standard_Real *aCoeff = (Standard_Real *)myCoeffs; - - theS = aNorm.X()*aCoeff[0] + aNorm.Y()*aCoeff[1] + aNorm.Z()*aCoeff[2]; - theD1 = thePMP0.X()*aCoeff[0] + thePMP0.Y()*aCoeff[1] - + thePMP0.Z()*aCoeff[2] - aCoeff[3]; - - return theS*theD1; -} - -//======================================================================= -//function : CenterMassValue -//purpose : Returns a value for the center of mass computation. -//======================================================================= - -Standard_Boolean GProp_UFunction::CenterMassValue(const Standard_Real X, - Standard_Real &F) -{ - gp_XYZ aPmP0; - Standard_Real aS; - Standard_Real aD1; - - F = VolumeValue(X, aPmP0, aS, aD1); - - // Center of mass computation for ByPoint mode. - if (myIsByPoint) { - switch (myValueType) { - case GProp_CenterMassX: F *= aPmP0.X(); break; - case GProp_CenterMassY: F *= aPmP0.Y(); break; - case GProp_CenterMassZ: F *= aPmP0.Z(); break; - default: - return Standard_False; - } - - return Standard_True; - } - - // Center of mass computation for ByPlane mode. - Standard_Real *aCoeff = (Standard_Real *)myCoeffs; - - switch (myValueType) { - case GProp_CenterMassX: F *= (aPmP0.X() - 0.5*aCoeff[0]*aD1); break; - case GProp_CenterMassY: F *= (aPmP0.Y() - 0.5*aCoeff[1]*aD1); break; - case GProp_CenterMassZ: F *= (aPmP0.Z() - 0.5*aCoeff[2]*aD1); break; - default: - return Standard_False; - } - - return Standard_True; -} - -//======================================================================= -//function : InertiaValue -//purpose : Compute the value of intertia. -//======================================================================= - -Standard_Boolean GProp_UFunction::InertiaValue(const Standard_Real X, - Standard_Real &F) -{ - gp_XYZ aPmP0; - Standard_Real aS; - Standard_Real aD1; - Standard_Real aParam1; - Standard_Real aParam2; - Standard_Real *aCoeffs = (Standard_Real *)myCoeffs; - - F = VolumeValue(X, aPmP0, aS, aD1); - - // Inertia computation for ByPoint mode. - if (myIsByPoint) { - switch(myValueType) { - case GProp_InertiaXX: - case GProp_InertiaYZ: - aParam1 = aPmP0.Y() - aCoeffs[1]; - aParam2 = aPmP0.Z() - aCoeffs[2]; - break; - case GProp_InertiaYY: - case GProp_InertiaXZ: - aParam1 = aPmP0.X() - aCoeffs[0]; - aParam2 = aPmP0.Z() - aCoeffs[2]; - break; - case GProp_InertiaZZ: - case GProp_InertiaXY: - aParam1 = aPmP0.X() - aCoeffs[0]; - aParam2 = aPmP0.Y() - aCoeffs[1]; - break; - default: - return Standard_False; - } - - if (myValueType == GProp_InertiaXX || - myValueType == GProp_InertiaYY || - myValueType == GProp_InertiaZZ) - F *= aParam1*aParam1 + aParam2*aParam2; - else - F *= -aParam1*aParam2; - - return Standard_True; - } - - // Inertia computation for ByPlane mode. - Standard_Real aD2 = aD1*aD1; - Standard_Real aD3 = aD1*aD2/3.; - Standard_Real aPPar1; - Standard_Real aPPar2; - Standard_Real aCoeff1; - Standard_Real aCoeff2; - - // Inertia computation for XX, YY and ZZ. - if (myValueType == GProp_InertiaXX || - myValueType == GProp_InertiaYY || - myValueType == GProp_InertiaZZ) { - - if (myValueType == GProp_InertiaXX) { - aPPar1 = aPmP0.Y(); - aPPar2 = aPmP0.Z(); - aCoeff1 = aCoeffs[1]; - aCoeff2 = aCoeffs[2]; - } else if (myValueType == GProp_InertiaYY) { - aPPar1 = aPmP0.X(); - aPPar2 = aPmP0.Z(); - aCoeff1 = aCoeffs[0]; - aCoeff2 = aCoeffs[2]; - } else { // myValueType == GProp_InertiaZZ - aPPar1 = aPmP0.X(); - aPPar2 = aPmP0.Y(); - aCoeff1 = aCoeffs[0]; - aCoeff2 = aCoeffs[1]; - } - - aPPar1 -= aCoeff1*aD1; - aPPar2 -= aCoeff2*aD1; - aParam1 = aPPar1*aPPar1*aD1 + aPPar1*aCoeff1*aD2 + aCoeff1*aCoeff1*aD3; - aParam2 = aPPar2*aPPar2*aD1 + aPPar2*aCoeff2*aD2 + aCoeff2*aCoeff2*aD3; - - F = (aParam1 + aParam2)*aS; - - return Standard_True; - } - - // Inertia computation for XY, YZ and XZ. - if (myValueType == GProp_InertiaXY || - myValueType == GProp_InertiaYZ || - myValueType == GProp_InertiaXZ) { - - if (myValueType == GProp_InertiaXY) { - aPPar1 = aPmP0.X(); - aPPar2 = aPmP0.Y(); - aCoeff1 = aCoeffs[0]; - aCoeff2 = aCoeffs[1]; - } else if (myValueType == GProp_InertiaYZ) { - aPPar1 = aPmP0.Y(); - aPPar2 = aPmP0.Z(); - aCoeff1 = aCoeffs[1]; - aCoeff2 = aCoeffs[2]; - } else { // myValueType == GProp_InertiaXZ - aPPar1 = aPmP0.X(); - aPPar2 = aPmP0.Z(); - aCoeff1 = aCoeffs[0]; - aCoeff2 = aCoeffs[2]; - } - - aD2 *= 0.5; - aPPar1 -= aCoeff1*aD1; - aPPar2 -= aCoeff2*aD1; - aParam1 = aPPar1*aPPar2*aD1 - + (aPPar1*aCoeff2 + aPPar2*aCoeff1)*aD2 + aCoeff1*aCoeff2*aD3; - - F = -aParam1*aS; - - return Standard_True; - } - - return Standard_False; -} diff --git a/src/GProp/GProp_UFunction.lxx b/src/GProp/GProp_UFunction.lxx deleted file mode 100644 index 10540e1d65..0000000000 --- a/src/GProp/GProp_UFunction.lxx +++ /dev/null @@ -1,35 +0,0 @@ -// Created on: 2005-12-21 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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. - -//======================================================================= -//function : SetValueType -//purpose : Setting the type of the value to be returned. -//======================================================================= - -inline void GProp_UFunction::SetValueType(const GProp_ValueType theType) -{ - myValueType = theType; -} - -//======================================================================= -//function : SetVParam -//purpose : Setting the V parameter that is constant during the -// integral computation. -//======================================================================= - -inline void GProp_UFunction::SetVParam(const Standard_Real theVParam) -{ - myVParam = theVParam; -} diff --git a/src/GProp/GProp_VGProps.cdl b/src/GProp/GProp_VGProps.cdl deleted file mode 100644 index daaf396fd9..0000000000 --- a/src/GProp/GProp_VGProps.cdl +++ /dev/null @@ -1,195 +0,0 @@ --- Created on: 1991-04-12 --- Created by: Michel CHAUVAT --- Copyright (c) 1991-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. - --- Jean-Claude VAUTHIER January 1992 - - -generic class VGProps from GProp (Arc as any; - Face as any; - Domain as any) -inherits GProps - - --- Purpose : - -- Computes the global properties of a geometric solid - -- (3D closed region of space) delimited with : - -- . a surface - -- . a point and a surface - -- . a plane and a surface - -- - -- The surface can be : - -- . a surface limited with its parametric values U-V, - -- . a surface limited in U-V space with its curves of restriction, - -- - -- The surface 's requirements to evaluate the global properties - -- are defined in the template SurfaceTool from package GProp. - -uses Pnt from gp, - Pln from gp -is - - Create returns VGProps; - - Create (S: Face; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of a region of 3D space - -- delimited with the surface and the point VLocation. S can be closed - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Errror of the computation is not calculated. - - Create (S: in out Face; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of a region of 3D space - -- delimited with the surface and the point VLocation. S can be closed - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - - Create (S: Face; O: Pnt from gp; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the point VLocation. - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Error of the computation is not calculated. - - Create (S: in out Face; O: Pnt from gp; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the point VLocation. - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. - - Create (S: Face; Pl: Pln from gp; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the plane Pln. - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Error of the computation is not calculated. - - Create (S: in out Face; Pl: Pln from gp; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the plane Pln. - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. - - -- With Domain -- - - Create (S: in out Face; D : in out Domain; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of a region of 3D space - -- delimited with the surface and the point VLocation. S can be closed - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Errror of the computation is not calculated. - - Create (S: in out Face; D : in out Domain; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of a region of 3D space - -- delimited with the surface and the point VLocation. S can be closed - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - - Create (S: in out Face; D : in out Domain; O: Pnt from gp; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the point VLocation. - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Error of the computation is not calculated. - - Create (S: in out Face; D : in out Domain; O: Pnt from gp; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the point VLocation. - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. - - Create (S: in out Face; D : in out Domain; Pl: Pln from gp; VLocation: Pnt from gp) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the plane Pln. - -- The method is quick and its precision is enough for many cases of analytical - -- surfaces. - -- Non-adaptive 2D Gauss integration with predefined numbers of Gauss points - -- is used. Numbers of points depend on types of surfaces and curves. - -- Error of the computation is not calculated. - - Create (S: in out Face; D : in out Domain; Pl: Pln from gp; VLocation: Pnt from gp; Eps: Real) returns VGProps; - --- Purpose : - -- Computes the global properties of the region of 3D space - -- delimited with the surface and the plane Pln. - -- Adaptive 2D Gauss integration is used. - -- Parameter Eps sets maximal relative error of computed mass (volume) for face. - -- Error is calculated as Abs((M(i+1)-M(i))/M(i+1)), M(i+1) and M(i) are values - -- for two successive steps of adaptive integration. - -- WARNING: if Eps > 0.001 algorithm performs non-adaptive integration. - - SetLocation(me: in out; VLocation: Pnt from gp); - - Perform(me: in out; S: Face); - Perform(me: in out; S: in out Face; Eps: Real) returns Real; - - Perform(me: in out; S: Face; O : Pnt from gp); - Perform(me: in out; S: in out Face; O : Pnt from gp; Eps: Real) returns Real; - - Perform(me: in out; S: Face; Pl : Pln from gp); - Perform(me: in out; S: in out Face; Pl : Pln from gp; Eps: Real) returns Real; - - Perform(me: in out; S: in out Face; D : in out Domain); - Perform(me: in out; S: in out Face; D : in out Domain; Eps: Real) returns Real; - - Perform(me: in out; S: in out Face; D : in out Domain; O : Pnt from gp); - Perform(me: in out; S: in out Face; D : in out Domain; O : Pnt from gp; Eps: Real) returns Real; - - Perform(me: in out; S: in out Face; D : in out Domain; Pl : Pln from gp); - Perform(me: in out; S: in out Face; D : in out Domain; Pl : Pln from gp; Eps: Real) returns Real; - - GetEpsilon(me: out) returns Real; - --- Purpose : - -- If previously used methods containe Eps parameter - -- gets actual relative error of the computation, else returns 1.0. -fields - - myEpsilon: Real from Standard; - -end VGProps; - - diff --git a/src/GProp/GProp_VGProps.gxx b/src/GProp/GProp_VGProps.gxx deleted file mode 100644 index 1a14eec66e..0000000000 --- a/src/GProp/GProp_VGProps.gxx +++ /dev/null @@ -1,970 +0,0 @@ -// 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 -#include -#include -#include -#include -#include -#include - -#include -#include -class HMath_Vector{ - math_Vector *pvec; - void operator=(const math_Vector&){} - public: - HMath_Vector(){ pvec = 0;} - HMath_Vector(math_Vector* pv){ pvec = pv;} - ~HMath_Vector(){ if(pvec != 0) delete pvec;} - void operator=(math_Vector* pv){ if(pvec != pv && pvec != 0) delete pvec; pvec = pv;} - Standard_Real& operator()(Standard_Integer i){ return (*pvec).operator()(i);} - const Standard_Real& operator()(Standard_Integer i) const{ return (*pvec).operator()(i);} - const math_Vector* operator->() const{ return pvec;} - math_Vector* operator->(){ return pvec;} - math_Vector* Init(Standard_Real v, Standard_Integer i = 0, Standard_Integer iEnd = 0){ - if(pvec == 0) return pvec; - if(iEnd - i == 0) pvec->Init(v); - else for(; i <= iEnd; i++) pvec->operator()(i) = v; - return pvec; - } -}; - -//Minimal value of interval's range for computation | minimal value of "dim" | ... -static Standard_Real EPS_PARAM = Precision::Angular(), EPS_DIM = 1.E-30, ERROR_ALGEBR_RATIO = 2.0/3.0; -//Maximum of GaussPoints on a subinterval and maximum of subintervals -static Standard_Integer GPM = math::GaussPointsMax(), SUBS_POWER = 32, SM = SUBS_POWER*GPM + 1; -static Standard_Boolean IS_MIN_DIM = 1; // if the value equal 0 error of algorithm calculted by static moments - -static math_Vector LGaussP0(1,GPM), LGaussW0(1,GPM), - LGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))), LGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); -static HMath_Vector L1 = new math_Vector(1,SM), L2 = new math_Vector(1,SM), - DimL = new math_Vector(1,SM), ErrL = new math_Vector(1,SM), ErrUL = new math_Vector(1,SM,0.0), - IxL = new math_Vector(1,SM), IyL = new math_Vector(1,SM), IzL = new math_Vector(1,SM), - IxxL = new math_Vector(1,SM), IyyL = new math_Vector(1,SM), IzzL = new math_Vector(1,SM), - IxyL = new math_Vector(1,SM), IxzL = new math_Vector(1,SM), IyzL = new math_Vector(1,SM); - -static math_Vector* LGaussP[] = {&LGaussP0,&LGaussP1}; -static math_Vector* LGaussW[] = {&LGaussW0,&LGaussW1}; - -static math_Vector UGaussP0(1,GPM), UGaussW0(1,GPM), - UGaussP1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))), UGaussW1(1,RealToInt(Ceiling(ERROR_ALGEBR_RATIO*GPM))); -static HMath_Vector U1 = new math_Vector(1,SM), U2 = new math_Vector(1,SM), - DimU = new math_Vector(1,SM), ErrU = new math_Vector(1,SM,0.0), - IxU = new math_Vector(1,SM), IyU = new math_Vector(1,SM), IzU = new math_Vector(1,SM), - IxxU = new math_Vector(1,SM), IyyU = new math_Vector(1,SM), IzzU = new math_Vector(1,SM), - IxyU = new math_Vector(1,SM), IxzU = new math_Vector(1,SM), IyzU = new math_Vector(1,SM); - -static math_Vector* UGaussP[] = {&UGaussP0,&UGaussP1}; -static math_Vector* UGaussW[] = {&UGaussW0,&UGaussW1}; - -static Standard_Integer FillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, - HMath_Vector& VA, HMath_Vector& VB) -{ - Standard_Integer i = 1, iEnd = Knots.Upper(), j = 1, k = 1; - VA(j++) = A; - for(; i <= iEnd; i++){ - Standard_Real kn = Knots(i); - if(A < kn) - { - if(kn < B) - { - VA(j++) = VB(k++) = kn; - } - else - { - break; - } - } - } - VB(k) = B; - return k; -} - -static inline Standard_Integer MaxSubs(Standard_Integer n, Standard_Integer coeff = SUBS_POWER){ - return n = IntegerLast()/coeff < n? IntegerLast(): n*coeff + 1; -} - -static Standard_Integer LFillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, - const Standard_Integer NumSubs) -{ - Standard_Integer iEnd = Knots.Upper(), jEnd = L1->Upper(); - -// Modified by Sergey KHROMOV - Wed Mar 26 11:22:50 2003 - iEnd = Max(iEnd, MaxSubs(iEnd-1,NumSubs)); - if(iEnd - 1 > jEnd){ -// iEnd = MaxSubs(iEnd-1,NumSubs); -// Modified by Sergey KHROMOV - Wed Mar 26 11:22:51 2003 - L1 = new math_Vector(1,iEnd); L2 = new math_Vector(1,iEnd); - DimL = new math_Vector(1,iEnd); ErrL = new math_Vector(1,iEnd,0.0); ErrUL = new math_Vector(1,iEnd,0.0); - IxL = new math_Vector(1,iEnd); IyL = new math_Vector(1,iEnd); IzL = new math_Vector(1,iEnd); - IxxL = new math_Vector(1,iEnd); IyyL = new math_Vector(1,iEnd); IzzL = new math_Vector(1,iEnd); - IxyL = new math_Vector(1,iEnd); IxzL = new math_Vector(1,iEnd); IyzL = new math_Vector(1,iEnd); - } - return FillIntervalBounds(A, B, Knots, L1, L2); -} - -static Standard_Integer UFillIntervalBounds(Standard_Real A, Standard_Real B, const TColStd_Array1OfReal& Knots, - const Standard_Integer NumSubs) -{ - Standard_Integer iEnd = Knots.Upper(), jEnd = U1->Upper(); - -// Modified by Sergey KHROMOV - Wed Mar 26 11:22:50 2003 - iEnd = Max(iEnd, MaxSubs(iEnd-1,NumSubs)); - if(iEnd - 1 > jEnd){ -// iEnd = MaxSubs(iEnd-1,NumSubs); -// Modified by Sergey KHROMOV - Wed Mar 26 11:22:51 2003 - U1 = new math_Vector(1,iEnd); U2 = new math_Vector(1,iEnd); - DimU = new math_Vector(1,iEnd); ErrU = new math_Vector(1,iEnd,0.0); - IxU = new math_Vector(1,iEnd); IyU = new math_Vector(1,iEnd); IzU = new math_Vector(1,iEnd); - IxxU = new math_Vector(1,iEnd); IyyU = new math_Vector(1,iEnd); IzzU = new math_Vector(1,iEnd); - IxyU = new math_Vector(1,iEnd); IxzU = new math_Vector(1,iEnd); IyzU = new math_Vector(1,iEnd); - } - return FillIntervalBounds(A, B, Knots, U1, U2); -} - -static Standard_Real CCompute(Face& S, Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], - const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, - const Standard_Real EpsDim, - const Standard_Boolean isErrorCalculation, const Standard_Boolean isVerifyComputation) -{ - Standard_Boolean isNaturalRestriction = S.NaturalRestriction(); - - Standard_Integer NumSubs = SUBS_POWER; - Standard_Boolean isMinDim = IS_MIN_DIM; - - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - Dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - //boundary curve parametrization - Standard_Real l1, l2, lm, lr, l; - //Face parametrization in U and V direction - Standard_Real BV1, BV2, v; - Standard_Real BU1, BU2, u1, u2, um, ur, u; - S.Bounds (BU1, BU2, BV1, BV2); u1 = BU1; - //location point used to compute the inertia - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - //location point used to compute the inertiard (xloc, yloc, zloc); - //Jacobien (x, y, z) -> (u, v) = ||n|| - Standard_Real xn, yn, zn, s, ds, dDim; - Standard_Real x, y, z, xi, px, py, pz, yi, zi, d1, d2, d3; - //On the Face - gp_Pnt Ps; - gp_Vec VNor; - //On the boundary curve u-v - gp_Pnt2d Puv; - gp_Vec2d Vuv; - Standard_Real Dul; // Dul = Du / Dl - Standard_Real CDim[2], CIx, CIy, CIz, CIxx[2], CIyy[2], CIzz[2], CIxy, CIxz, CIyz; - Standard_Real LocDim[2], LocIx[2], LocIy[2], LocIz[2], LocIxx[2], LocIyy[2], LocIzz[2], LocIxy[2], LocIxz[2], LocIyz[2]; - - Standard_Integer iD = 0, NbLSubs, iLS, iLSubEnd, iGL, iGLEnd, NbLGaussP[2], LRange[2], iL, kL, kLEnd, IL, JL; - Standard_Integer i, NbUSubs, iUS, iUSubEnd, iGU, iGUEnd, NbUGaussP[2], URange[2], iU, kU, kUEnd, IU, JU; - Standard_Integer UMaxSubs, LMaxSubs; - - Standard_Real ErrorU, ErrorL, ErrorLMax = 0.0, Eps=0.0, EpsL=0.0, EpsU=0.0; - iGLEnd = isErrorCalculation? 2: 1; - - for(i = 0; i < 2; i++) { - LocDim[i] = 0.0; - LocIx[i] = 0.0; - LocIy[i] = 0.0; - LocIz[i] = 0.0; - LocIxx[i] = 0.0; - LocIyy[i] = 0.0; - LocIzz[i] = 0.0; - LocIxy[i] = 0.0; - LocIyz[i] = 0.0; - LocIxz[i] = 0.0; - } - - NbUGaussP[0] = S.SIntOrder(EpsDim); - NbUGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbUGaussP[0])); - math::GaussPoints(NbUGaussP[0],UGaussP0); math::GaussWeights(NbUGaussP[0],UGaussW0); - math::GaussPoints(NbUGaussP[1],UGaussP1); math::GaussWeights(NbUGaussP[1],UGaussW1); - - NbUSubs = S.SUIntSubs(); - TColStd_Array1OfReal UKnots(1,NbUSubs+1); - S.UKnots(UKnots); - - while (isNaturalRestriction || D.More()) { - if(isNaturalRestriction){ - NbLGaussP[0] = Min(2*NbUGaussP[0],math::GaussPointsMax()); - }else{ - S.Load(D.Value()); ++iD; - NbLGaussP[0] = S.LIntOrder(EpsDim); - } - NbLGaussP[1] = RealToInt(Ceiling(ERROR_ALGEBR_RATIO*NbLGaussP[0])); - math::GaussPoints(NbLGaussP[0],LGaussP0); math::GaussWeights(NbLGaussP[0],LGaussW0); - math::GaussPoints(NbLGaussP[1],LGaussP1); math::GaussWeights(NbLGaussP[1],LGaussW1); - - NbLSubs = isNaturalRestriction? S.SVIntSubs(): S.LIntSubs(); - TColStd_Array1OfReal LKnots(1,NbLSubs+1); - if(isNaturalRestriction){ - S.VKnots(LKnots); - l1 = BV1; l2 = BV2; - }else{ - S.LKnots(LKnots); - l1 = S.FirstParameter(); l2 = S.LastParameter(); - } - ErrorL = 0.0; - kLEnd = 1; JL = 0; - //OCC503(apo): if(Abs(l2-l1) < EPS_PARAM) continue; - if(Abs(l2-l1) > EPS_PARAM) { - iLSubEnd = LFillIntervalBounds(l1, l2, LKnots, NumSubs); - LMaxSubs = MaxSubs(iLSubEnd); - //-- exception avoiding - if(LMaxSubs > SM) LMaxSubs = SM; - DimL.Init(0.0,1,LMaxSubs); ErrL.Init(0.0,1,LMaxSubs); ErrUL.Init(0.0,1,LMaxSubs); - do{// while: L - if(++JL > iLSubEnd){ - LRange[0] = IL = ErrL->Max(); LRange[1] = JL; - L1(JL) = (L1(IL) + L2(IL))/2.0; L2(JL) = L2(IL); L2(IL) = L1(JL); - }else LRange[0] = IL = JL; - if(JL == LMaxSubs || Abs(L2(JL) - L1(JL)) < EPS_PARAM) - if(kLEnd == 1){ - DimL(JL) = ErrL(JL) = IxL(JL) = IyL(JL) = IzL(JL) = - IxxL(JL) = IyyL(JL) = IzzL(JL) = IxyL(JL) = IxzL(JL) = IyzL(JL) = 0.0; - }else{ - JL--; - EpsL = ErrorL; Eps = EpsL/0.9; - break; - } - else - for(kL=0; kL < kLEnd; kL++){ - iLS = LRange[kL]; - lm = 0.5*(L2(iLS) + L1(iLS)); - lr = 0.5*(L2(iLS) - L1(iLS)); - CIx = CIy = CIz = CIxy = CIxz = CIyz = 0.0; - for(iGL=0; iGL < iGLEnd; iGL++){// - CDim[iGL] = CIxx[iGL] = CIyy[iGL] = CIzz[iGL] = 0.0; - for(iL=1; iL<=NbLGaussP[iGL]; iL++){ - l = lm + lr*(*LGaussP[iGL])(iL); - if(isNaturalRestriction){ - v = l; u2 = BU2; Dul = (*LGaussW[iGL])(iL); - }else{ - S.D12d (l, Puv, Vuv); - Dul = Vuv.Y()*(*LGaussW[iGL])(iL); // Dul = Du / Dl - if(Abs(Dul) < EPS_PARAM) continue; - v = Puv.Y(); u2 = Puv.X(); - //Check on cause out off bounds of value current parameter - if(v < BV1) v = BV1; else if(v > BV2) v = BV2; - if(u2 < BU1) u2 = BU1; else if(u2 > BU2) u2 = BU2; - } - ErrUL(iLS) = 0.0; - kUEnd = 1; JU = 0; - if(Abs(u2-u1) < EPS_PARAM) continue; - iUSubEnd = UFillIntervalBounds(u1, u2, UKnots, NumSubs); - UMaxSubs = MaxSubs(iUSubEnd); - //-- exception avoiding - if(UMaxSubs > SM) UMaxSubs = SM; - DimU.Init(0.0,1,UMaxSubs); ErrU.Init(0.0,1,UMaxSubs); ErrorU = 0.0; - do{//while: U - if(++JU > iUSubEnd){ - URange[0] = IU = ErrU->Max(); URange[1] = JU; - U1(JU) = (U1(IU)+U2(IU))/2.0; U2(JU) = U2(IU); U2(IU) = U1(JU); - }else URange[0] = IU = JU; - if(JU == UMaxSubs || Abs(U2(JU) - U1(JU)) < EPS_PARAM) - if(kUEnd == 1){ - DimU(JU) = ErrU(JU) = IxU(JU) = IyU(JU) = IzU(JU) = - IxxU(JU) = IyyU(JU) = IzzU(JU) = IxyU(JU) = IxzU(JU) = IyzU(JU) = 0.0; - }else{ - JU--; - EpsU = ErrorU; Eps = EpsU*Abs((u2-u1)*Dul)/0.1; EpsL = 0.9*Eps; - break; - } - else - for(kU=0; kU < kUEnd; kU++){ - iUS = URange[kU]; - um = 0.5*(U2(iUS) + U1(iUS)); - ur = 0.5*(U2(iUS) - U1(iUS)); - iGUEnd = iGLEnd - iGL; - for(iGU=0; iGU < iGUEnd; iGU++){// - LocDim[iGU] = - LocIxx[iGU] = LocIyy[iGU] = LocIzz[iGU] = - LocIx[iGU] = LocIy[iGU] = LocIz[iGU] = - LocIxy[iGU] = LocIxz[iGU] = LocIyz[iGU] = 0.0; - for(iU=1; iU<=NbUGaussP[iGU]; iU++){ - u = um + ur*(*UGaussP[iGU])(iU); - S.Normal(u, v, Ps, VNor); - VNor.Coord(xn, yn, zn); - Ps.Coord(x, y, z); - x -= xloc; y -= yloc; z -= zloc; - xn *= (*UGaussW[iGU])(iU); - yn *= (*UGaussW[iGU])(iU); - zn *= (*UGaussW[iGU])(iU); - if(ByPoint){ - //volume of elementary cone - dDim = (x*xn+y*yn+z*zn)/3.0; - //coordinates of cone's center mass - px = 0.75*x; py = 0.75*y; pz = 0.75*z; - LocDim[iGU] += dDim; - //if(iGU > 0) continue; - LocIx[iGU] += px*dDim; - LocIy[iGU] += py*dDim; - LocIz[iGU] += pz*dDim; - x -= Coeff[0]; y -= Coeff[1]; z -= Coeff[2]; - dDim *= 3.0/5.0; - LocIxy[iGU] -= x*y*dDim; - LocIyz[iGU] -= y*z*dDim; - LocIxz[iGU] -= x*z*dDim; - xi = x*x; yi = y*y; zi = z*z; - LocIxx[iGU] += (yi+zi)*dDim; - LocIyy[iGU] += (xi+zi)*dDim; - LocIzz[iGU] += (xi+yi)*dDim; - }else{ // by plane - s = xn*Coeff[0] + yn*Coeff[1] + zn*Coeff[2]; - d1 = Coeff[0]*x + Coeff[1]*y + Coeff[2]*z - Coeff[3]; - d2 = d1*d1; - d3 = d1*d2/3.0; - ds = s*d1; - LocDim[iGU] += ds; - //if(iGU > 0) continue; - LocIx[iGU] += (x - Coeff[0]*d1/2.0) * ds; - LocIy[iGU] += (y - Coeff[1]*d1/2.0) * ds; - LocIz[iGU] += (z - Coeff[2]*d1/2.0) * ds; - px = x-Coeff[0]*d1; py = y-Coeff[1]*d1; pz = z-Coeff[2]*d1; - xi = px*px*d1 + px*Coeff[0]*d2 + Coeff[0]*Coeff[0]*d3; - yi = py*py*d1 + py*Coeff[1]*d2 + Coeff[1]*Coeff[1]*d3; - zi = pz*pz*d1 + pz*Coeff[2]*d2 + Coeff[2]*Coeff[2]*d3; - LocIxx[iGU] += (yi+zi)*s; - LocIyy[iGU] += (xi+zi)*s; - LocIzz[iGU] += (xi+yi)*s; - d2 /= 2.0; - xi = py*pz*d1 + py*Coeff[2]*d2 + pz*Coeff[1]*d2 + Coeff[1]*Coeff[2]*d3; - yi = px*pz*d1 + pz*Coeff[0]*d2 + px*Coeff[2]*d2 + Coeff[0]*Coeff[2]*d3; - zi = px*py*d1 + px*Coeff[1]*d2 + py*Coeff[0]*d2 + Coeff[0]*Coeff[1]*d3; - LocIxy[iGU] -= zi*s; LocIyz[iGU] -= xi*s; LocIxz[iGU] -= yi*s; - } - }//for: iU - }//for: iGU - DimU(iUS) = LocDim[0]*ur; - IxxU(iUS) = LocIxx[0]*ur; IyyU(iUS) = LocIyy[0]*ur; IzzU(iUS) = LocIzz[0]*ur; - if(iGL > 0) continue; - LocDim[1] = Abs(LocDim[1]-LocDim[0]); - LocIxx[1] = Abs(LocIxx[1]-LocIxx[0]); - LocIyy[1] = Abs(LocIyy[1]-LocIyy[0]); - LocIzz[1] = Abs(LocIzz[1]-LocIzz[0]); - ErrU(iUS) = isMinDim? LocDim[1]*ur: (LocIxx[1] + LocIyy[1] + LocIzz[1])*ur; - IxU(iUS) = LocIx[0]*ur; IyU(iUS) = LocIy[0]*ur; IzU(iUS) = LocIz[0]*ur; - IxyU(iUS) = LocIxy[0]*ur; IxzU(iUS) = LocIxz[0]*ur; IyzU(iUS) = LocIyz[0]*ur; - }//for: kU (iUS) - if(JU == iUSubEnd) kUEnd = 2; - if(kUEnd == 2) { - Standard_Integer imax = ErrU->Max(); - if(imax > 0) ErrorU = ErrU(imax); - else ErrorU = 0.0; - } - }while((ErrorU - EpsU > 0.0 && EpsU != 0.0) || kUEnd == 1); - for(i=1; i<=JU; i++) { - CDim[iGL] += DimU(i)*Dul; - CIxx[iGL] += IxxU(i)*Dul; CIyy[iGL] += IyyU(i)*Dul; CIzz[iGL] += IzzU(i)*Dul; - } - if(iGL > 0) continue; - ErrUL(iLS) = ErrorU*Abs((u2-u1)*Dul); - for(i=1; i<=JU; i++){ - CIx += IxU(i)*Dul; CIy += IyU(i)*Dul; CIz += IzU(i)*Dul; - //CIxx += IxxU(i)*Dul; CIyy += IyyU(i)*Dul; CIzz += IzzU(i)*Dul; - CIxy += IxyU(i)*Dul; CIxz += IxzU(i)*Dul; CIyz += IyzU(i)*Dul; - } - }//for: iL - }//for: iGL - DimL(iLS) = CDim[0]*lr; - IxxL(iLS) = CIxx[0]*lr; IyyL(iLS) = CIyy[0]*lr; IzzL(iLS) = CIzz[0]*lr; - if(iGLEnd == 2) { - //ErrL(iLS) = Abs(CDim[1]-CDim[0])*lr + ErrUL(iLS); - CDim[1] = Abs(CDim[1]-CDim[0]); - CIxx[1] = Abs(CIxx[1]-CIxx[0]); CIyy[1] = Abs(CIyy[1]-CIyy[0]); CIzz[1] = Abs(CIzz[1]-CIzz[0]); - ErrorU = ErrUL(iLS); - ErrL(iLS) = (isMinDim? CDim[1]: (CIxx[1] + CIyy[1] + CIzz[1]))*lr + ErrorU; - } - IxL(iLS) = CIx*lr; IyL(iLS) = CIy*lr; IzL(iLS) = CIz*lr; - //IxxL(iLS) = CIxx*lr; IyyL(iLS) = CIyy*lr; IzzL(iLS) = CIzz*lr; - IxyL(iLS) = CIxy*lr; IxzL(iLS) = CIxz*lr; IyzL(iLS) = CIyz*lr; - }//for: (kL)iLS - // Calculate/correct epsilon of computation by current value of Dim - //That is need for not spend time for - if(JL == iLSubEnd){ - kLEnd = 2; - Standard_Real DDim = 0.0, DIxx = 0.0, DIyy = 0.0, DIzz = 0.0; - for(i=1; i<=JL; i++) { - DDim += DimL(i); - DIxx += IxxL(i); DIyy += IyyL(i); DIzz += IzzL(i); - } - DDim = isMinDim? Abs(DDim): Abs(DIxx) + Abs(DIyy) + Abs(DIzz); - DDim = Abs(DDim*EpsDim); - if(DDim > Eps) { - Eps = DDim; EpsL = 0.9*Eps; - } - } - if(kLEnd == 2) { - Standard_Integer imax = ErrL->Max(); - if(imax > 0) ErrorL = ErrL(imax); - else ErrorL = 0.0; - } - }while((ErrorL - EpsL > 0.0 && isVerifyComputation) || kLEnd == 1); - for(i=1; i<=JL; i++){ - Dim += DimL(i); - Ix += IxL(i); Iy += IyL(i); Iz += IzL(i); - Ixx += IxxL(i); Iyy += IyyL(i); Izz += IzzL(i); - Ixy += IxyL(i); Ixz += IxzL(i); Iyz += IyzL(i); - } - ErrorLMax = Max(ErrorLMax, ErrorL); - } - if(isNaturalRestriction) break; - D.Next(); - } - if(Abs(Dim) >= EPS_DIM){ - if(ByPoint){ - Ix = Coeff[0] + Ix/Dim; - Iy = Coeff[1] + Iy/Dim; - Iz = Coeff[2] + Iz/Dim; - }else{ - Ix /= Dim; - Iy /= Dim; - Iz /= Dim; - } - g.SetCoord (Ix, Iy, Iz); - }else{ - Dim =0.; - g.SetCoord(0.,0.,0.); - } - inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), - gp_XYZ (Ixy, Iyy, Iyz), - gp_XYZ (Ixz, Iyz, Izz)); - if(iGLEnd == 2) - Eps = Dim != 0.0? ErrorLMax/(isMinDim? Abs(Dim): (Abs(Ixx) + Abs(Iyy) + Abs(Izz))): 0.0; - else Eps = EpsDim; - return Eps; -} - -static Standard_Real Compute(Face& S, const Standard_Boolean ByPoint, const Standard_Real Coeff[], - const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, Standard_Real EpsDim) -{ - Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; - Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; - EpsDim = Abs(EpsDim); - Domain D; - return CCompute(S,D,ByPoint,Coeff,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); -} - -static Standard_Real Compute(Face& S, Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], - const gp_Pnt& loc, Standard_Real& Dim, gp_Pnt& g, gp_Mat& inertia, Standard_Real EpsDim) -{ - Standard_Boolean isErrorCalculation = 0.0 > EpsDim || EpsDim < 0.001? 1: 0; - Standard_Boolean isVerifyComputation = 0.0 < EpsDim && EpsDim < 0.001? 1: 0; - EpsDim = Abs(EpsDim); - return CCompute(S,D,ByPoint,Coeff,loc,Dim,g,inertia,EpsDim,isErrorCalculation,isVerifyComputation); -} - -static void Compute(const Face& S, - const Standard_Boolean ByPoint, - const Standard_Real Coeff[], - const gp_Pnt& Loc, - Standard_Real& Volu, - gp_Pnt& G, - gp_Mat& Inertia) -{ - - gp_Pnt P; - gp_Vec VNor; - Standard_Real dvi, dv; - Standard_Real ur, um, u, vr, vm, v; - Standard_Real x, y, z, xn, yn, zn, xi, yi, zi; -// Standard_Real x, y, z, xn, yn, zn, xi, yi, zi, xyz; - Standard_Real px,py,pz,s,d1,d2,d3; - Standard_Real Ixi, Iyi, Izi, Ixxi, Iyyi, Izzi, Ixyi, Ixzi, Iyzi; - Standard_Real xloc, yloc, zloc; - Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - - Volu = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - Loc.Coord (xloc, yloc, zloc); - - Standard_Real LowerU, UpperU, LowerV, UpperV; - S.Bounds ( LowerU, UpperU, LowerV, UpperV); - Standard_Integer UOrder = Min(S.UIntegrationOrder (), - math::GaussPointsMax()); - Standard_Integer VOrder = Min(S.VIntegrationOrder (), - math::GaussPointsMax()); - - Standard_Integer i, j; - math_Vector GaussPU (1, UOrder); //gauss points and weights - math_Vector GaussWU (1, UOrder); - math_Vector GaussPV (1, VOrder); - math_Vector GaussWV (1, VOrder); - - math::GaussPoints (UOrder,GaussPU); - math::GaussWeights (UOrder,GaussWU); - math::GaussPoints (VOrder,GaussPV); - math::GaussWeights (VOrder,GaussWV); - - um = 0.5 * (UpperU + LowerU); - vm = 0.5 * (UpperV + LowerV); - ur = 0.5 * (UpperU - LowerU); - vr = 0.5 * (UpperV - LowerV); - - for (j = 1; j <= VOrder; j++) { - v = vm + vr * GaussPV (j); - dvi = Ixi = Iyi = Izi = Ixxi = Iyyi = Izzi = Ixyi = Ixzi = Iyzi = 0.0; - - for (i = 1; i <= UOrder; i++) { - u = um + ur * GaussPU (i); - S.Normal (u, v, P, VNor); - VNor.Coord (xn, yn, zn); - P.Coord (x, y, z); - x -= xloc; y -= yloc; z -= zloc; - xn *= GaussWU (i); yn *= GaussWU (i); zn *= GaussWU (i); - if (ByPoint) { - ///////////////////// /////////////////////// - // OFV code // // Initial code // - ///////////////////// /////////////////////// - // modified by APO - dv = (x*xn+y*yn+z*zn)/3.0; //xyz = x * y * z; - dvi += dv; //Ixyi += zn * xyz; - Ixi += 0.75*x*dv; //Iyzi += xn * xyz; - Iyi += 0.75*y*dv; //Ixzi += yn * xyz; - Izi += 0.75*z*dv; //xi = x * x * x * xn / 3.0; - x -= Coeff[0]; //yi = y * y * y * yn / 3.0; - y -= Coeff[1]; //zi = z * z * z * zn / 3.0; - z -= Coeff[2]; //Ixxi += (yi + zi); - dv *= 3.0/5.0; //Iyyi += (xi + zi); - Ixyi -= x*y*dv; //Izzi += (xi + yi); - Iyzi -= y*z*dv; //x -= Coeff[0]; - Ixzi -= x*z*dv; //y -= Coeff[1]; - xi = x*x; //z -= Coeff[2]; - yi = y*y; //dv = x * xn + y * yn + z * zn; - zi = z*z; //dvi += dv; - Ixxi += (yi + zi)*dv; //Ixi += x * dv; - Iyyi += (xi + zi)*dv; //Iyi += y * dv; - Izzi += (xi + yi)*dv; //Izi += z * dv; - } - else { // by plane - s = xn * Coeff[0] + yn * Coeff[1] + zn * Coeff[2]; - d1 = Coeff[0] * x + Coeff[1] * y + Coeff[2] * z - Coeff[3]; - d2 = d1 * d1; - d3 = d1 * d2 / 3.0; - dv = s * d1; - dvi += dv; - Ixi += (x - (Coeff[0] * d1 / 2.0)) * dv; - Iyi += (y - (Coeff[1] * d1 / 2.0)) * dv; - Izi += (z - (Coeff[2] * d1 / 2.0)) * dv; - px = x - Coeff[0] * d1; - py = y - Coeff[1] * d1; - pz = z - Coeff[2] * d1; - xi = px * px * d1 + px * Coeff[0]* d2 + Coeff[0] * Coeff[0] * d3; - yi = py * py * d1 + py * Coeff[1] * d2 + Coeff[1] * Coeff[1] * d3; - zi = pz * pz * d1 + pz * Coeff[2] * d2 + Coeff[2] * Coeff[2] * d3; - Ixxi += (yi + zi) * s; - Iyyi += (xi + zi) * s; - Izzi += (xi + yi) * s; - d2 /= 2.0; - xi = (py * pz * d1) + (py * Coeff[2] * d2) + (pz * Coeff[1] * d2) + (Coeff[1] * Coeff[2] * d3); - yi = (px * pz * d1) + (pz * Coeff[0] * d2) + (px * Coeff[2] * d2) + (Coeff[0] * Coeff[2] * d3); - zi = (px * py * d1) + (px * Coeff[1] * d2) + (py * Coeff[0] * d2) + (Coeff[0] * Coeff[1] * d3); - Ixyi -= zi * s; - Iyzi -= xi * s; - Ixzi -= yi * s; - } - } - Volu += dvi * GaussWV (j); - Ix += Ixi * GaussWV (j); - Iy += Iyi * GaussWV (j); - Iz += Izi * GaussWV (j); - Ixx += Ixxi * GaussWV (j); - Iyy += Iyyi * GaussWV (j); - Izz += Izzi * GaussWV (j); - Ixy += Ixyi * GaussWV (j); - Ixz += Ixzi * GaussWV (j); - Iyz += Iyzi * GaussWV (j); - } - vr *= ur; - Ixx *= vr; - Iyy *= vr; - Izz *= vr; - Ixy *= vr; - Ixz *= vr; - Iyz *= vr; - if (Abs(Volu) >= EPS_DIM ) { - if (ByPoint) { - Ix = Coeff[0] + Ix/Volu; - Iy = Coeff[1] + Iy/Volu; - Iz = Coeff[2] + Iz/Volu; - Volu *= vr; - } - else { //by plane - Ix /= Volu; - Iy /= Volu; - Iz /= Volu; - Volu *= vr; - } - G.SetCoord (Ix, Iy, Iz); - } - else { - G.SetCoord(0.,0.,0.); - Volu =0.; - } - Inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), - gp_XYZ (Ixy, Iyy, Iyz), - gp_XYZ (Ixz, Iyz, Izz)); - -} - -// Last modified by OFV 5.2001: -// 1). surface and edge integration order is equal now -// 2). "by point" works now rathre correctly (it looks so...) -static void Compute(Face& S, Domain& D, const Standard_Boolean ByPoint, const Standard_Real Coeff[], - const gp_Pnt& Loc, Standard_Real& Volu, gp_Pnt& G, gp_Mat& Inertia) - -{ - Standard_Real x, y, z, xi, yi, zi, l1, l2, lm, lr, l, v1, v2, v, u1, u2, um, ur, u, ds, Dul, xloc, yloc, zloc; - Standard_Real LocVolu, LocIx, LocIy, LocIz, LocIxx, LocIyy, LocIzz, LocIxy, LocIxz, LocIyz; - Standard_Real CVolu, CIx, CIy, CIz, CIxx, CIyy, CIzz, CIxy, CIxz, CIyz, Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - Standard_Real xn, yn, zn, px, py, pz, s, d1, d2, d3, dSigma; - Standard_Integer i, j, vio, sio, max, NbGaussgp_Pnts; - - gp_Pnt Ps; - gp_Vec VNor; - gp_Pnt2d Puv; - gp_Vec2d Vuv; - - Loc.Coord (xloc, yloc, zloc); - Volu = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0; - S.Bounds (u1, u2, v1, v2); - Standard_Real _u2 = u2; //OCC104 - vio = S.VIntegrationOrder (); - - while (D.More()) - { - S.Load(D.Value()); - sio = S.IntegrationOrder (); - max = Max(vio,sio); - NbGaussgp_Pnts = Min(max,math::GaussPointsMax()); - - math_Vector GaussP (1, NbGaussgp_Pnts); - math_Vector GaussW (1, NbGaussgp_Pnts); - math::GaussPoints (NbGaussgp_Pnts,GaussP); - math::GaussWeights (NbGaussgp_Pnts,GaussW); - - CVolu = CIx = CIy = CIz = CIxx = CIyy = CIzz = CIxy = CIxz = CIyz = 0.0; - l1 = S.FirstParameter(); - l2 = S.LastParameter(); - lm = 0.5 * (l2 + l1); - lr = 0.5 * (l2 - l1); - - for (i=1; i<=NbGaussgp_Pnts; i++) - { - l = lm + lr * GaussP(i); - S.D12d (l, Puv, Vuv); - v = Puv.Y(); - u2 = Puv.X(); - - //OCC104 - v = v < v1? v1: v; - v = v > v2? v2: v; - u2 = u2 < u1? u1: u2; - u2 = u2 > _u2? _u2: u2; - - Dul = Vuv.Y() * GaussW(i); - um = 0.5 * (u2 + u1); - ur = 0.5 * (u2 - u1); - LocVolu = LocIx = LocIy = LocIz = LocIxx = LocIyy = LocIzz = LocIxy = LocIxz = LocIyz = 0.0; - - for (j=1; j<=NbGaussgp_Pnts; j++) - { - u = um + ur * GaussP(j); - S.Normal (u, v, Ps, VNor); - VNor.Coord (xn, yn, zn); - Ps.Coord (x, y, z); - x -= xloc; - y -= yloc; - z -= zloc; - xn = xn * Dul * GaussW(j); - yn = yn * Dul * GaussW(j); - zn = zn * Dul * GaussW(j); - if(ByPoint) - { - dSigma = (x*xn+y*yn+z*zn)/3.0; - LocVolu += dSigma; - LocIx += 0.75*x*dSigma; - LocIy += 0.75*y*dSigma; - LocIz += 0.75*z*dSigma; - x -= Coeff[0]; - y -= Coeff[1]; - z -= Coeff[2]; - dSigma *= 3.0/5.0; - LocIxy -= x*y*dSigma; - LocIyz -= y*z*dSigma; - LocIxz -= x*z*dSigma; - xi = x*x; - yi = y*y; - zi = z*z; - LocIxx += (yi + zi)*dSigma; - LocIyy += (xi + zi)*dSigma; - LocIzz += (xi + yi)*dSigma; - } - else - { - s = xn * Coeff[0] + yn * Coeff[1] + zn * Coeff[2]; - d1 = Coeff[0] * x + Coeff[1] * y + Coeff[2] * z; - d2 = d1 * d1; - d3 = d1 * d2 / 3.0; - ds = s * d1; - LocVolu += ds; - LocIx += (x - Coeff[0] * d1 / 2.0) * ds; - LocIy += (y - Coeff[1] * d1 / 2.0) * ds; - LocIz += (z - Coeff[2] * d1 / 2.0) * ds; - px = x - Coeff[0] * d1; - py = y - Coeff[1] * d1; - pz = z - Coeff[2] * d1; - xi = (px * px * d1) + (px * Coeff[0]* d2) + (Coeff[0] * Coeff[0] * d3); - yi = (py * py * d1) + (py * Coeff[1] * d2) + (Coeff[1] * Coeff[1] * d3); - zi = pz * pz * d1 + pz * Coeff[2] * d2 + (Coeff[2] * Coeff[2] * d3); - LocIxx += (yi + zi) * s; - LocIyy += (xi + zi) * s; - LocIzz += (xi + yi) * s; - d2 /= 2.0; - xi = (py * pz * d1) + (py * Coeff[2] * d2) + (pz * Coeff[1] * d2) + (Coeff[1] * Coeff[2] * d3); - yi = (px * pz * d1) + (pz * Coeff[0] * d2) + (px * Coeff[2] * d2) + (Coeff[0] * Coeff[2] * d3); - zi = (px * py * d1) + (px * Coeff[1] * d2) + (py * Coeff[0] * d2) + (Coeff[0] * Coeff[1] * d3); - LocIxy -= zi * s; - LocIyz -= xi * s; - LocIxz -= yi * s; - } - } - CVolu += LocVolu * ur; - CIx += LocIx * ur; - CIy += LocIy * ur; - CIz += LocIz * ur; - CIxx += LocIxx * ur; - CIyy += LocIyy * ur; - CIzz += LocIzz * ur; - CIxy += LocIxy * ur; - CIxz += LocIxz * ur; - CIyz += LocIyz * ur; - } - Volu += CVolu * lr; - Ix += CIx * lr; - Iy += CIy * lr; - Iz += CIz * lr; - Ixx += CIxx * lr; - Iyy += CIyy * lr; - Izz += CIzz * lr; - Ixy += CIxy * lr; - Ixz += CIxz * lr; - Iyz += CIyz * lr; - D.Next(); - } - - if(Abs(Volu) >= EPS_DIM) - { - if(ByPoint) - { - Ix = Coeff[0] + Ix/Volu; - Iy = Coeff[1] + Iy/Volu; - Iz = Coeff[2] + Iz/Volu; - } - else - { - Ix /= Volu; - Iy /= Volu; - Iz /= Volu; - } - G.SetCoord (Ix, Iy, Iz); - } - else - { - Volu =0.; - G.SetCoord(0.,0.,0.); - } - - Inertia.SetCols (gp_XYZ (Ixx, Ixy, Ixz), - gp_XYZ (Ixy, Iyy, Iyz), - gp_XYZ (Ixz, Iyz, Izz)); - -} - -GProp_VGProps::GProp_VGProps(){} - -GProp_VGProps::GProp_VGProps(Face& S, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,Eps); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,D,Eps); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S,D); -} - -GProp_VGProps::GProp_VGProps(const Face& S, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S); -} - -GProp_VGProps::GProp_VGProps(Face& S, const gp_Pnt& O, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,O,Eps); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pnt& O, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,D,O,Eps); -} - -GProp_VGProps::GProp_VGProps(const Face& S, const gp_Pnt& O, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S,O); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pnt& O, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S,D,O); -} - -GProp_VGProps::GProp_VGProps(Face& S, const gp_Pln& Pl, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,Pl,Eps); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pln& Pl, const gp_Pnt& VLocation, const Standard_Real Eps){ - SetLocation(VLocation); - Perform(S,D,Pl,Eps); -} - -GProp_VGProps::GProp_VGProps(const Face& S, const gp_Pln& Pl, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S,Pl); -} - -GProp_VGProps::GProp_VGProps(Face& S, Domain& D, const gp_Pln& Pl, const gp_Pnt& VLocation){ - SetLocation(VLocation); - Perform(S,D,Pl); -} - -void GProp_VGProps::SetLocation(const gp_Pnt& VLocation){ - loc = VLocation; -} - -Standard_Real GProp_VGProps::Perform(Face& S, const Standard_Real Eps){ - Standard_Real Coeff[] = {0., 0., 0.}; - return myEpsilon = Compute(S,Standard_True,Coeff,loc,dim,g,inertia,Eps); -} - -Standard_Real GProp_VGProps::Perform(Face& S, Domain& D, const Standard_Real Eps){ - Standard_Real Coeff[] = {0., 0., 0.}; - return myEpsilon = Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia,Eps); -} - -void GProp_VGProps::Perform(const Face& S){ - Standard_Real Coeff[] = {0., 0., 0.}; - Compute(S,Standard_True,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -void GProp_VGProps::Perform(Face& S, Domain& D){ - Standard_Real Coeff[] = {0., 0., 0.}; - Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -Standard_Real GProp_VGProps::Perform(Face& S, const gp_Pnt& O, const Standard_Real Eps){ - Standard_Real xloc, yloc, zloc; - loc.Coord(xloc, yloc, zloc); - Standard_Real Coeff[3]; - O.Coord (Coeff[0], Coeff[1], Coeff[2]); - Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; - return myEpsilon = Compute(S,Standard_True,Coeff,loc,dim,g,inertia,Eps); -} - -Standard_Real GProp_VGProps::Perform(Face& S, Domain& D, const gp_Pnt& O, const Standard_Real Eps){ - Standard_Real xloc, yloc, zloc; - loc.Coord(xloc, yloc, zloc); - Standard_Real Coeff[3]; - O.Coord (Coeff[0], Coeff[1], Coeff[2]); - Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; - return myEpsilon = Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia,Eps); -} - -void GProp_VGProps::Perform(const Face& S, const gp_Pnt& O){ - Standard_Real xloc, yloc, zloc; - loc.Coord(xloc, yloc, zloc); - Standard_Real Coeff[3]; - O.Coord (Coeff[0], Coeff[1], Coeff[2]); - Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; - Compute(S,Standard_True,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -void GProp_VGProps::Perform(Face& S, Domain& D, const gp_Pnt& O){ - Standard_Real xloc, yloc, zloc; - loc.Coord(xloc, yloc, zloc); - Standard_Real Coeff[3]; - O.Coord (Coeff[0], Coeff[1], Coeff[2]); - Coeff[0] -= xloc; Coeff[1] -= yloc; Coeff[2] -= zloc; - Compute(S,D,Standard_True,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -Standard_Real GProp_VGProps::Perform(Face& S, const gp_Pln& Pl, const Standard_Real Eps){ - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - Standard_Real Coeff[4]; - Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); - Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; - return myEpsilon = Compute(S,Standard_False,Coeff,loc,dim,g,inertia,Eps); -} - -Standard_Real GProp_VGProps::Perform(Face& S, Domain& D, const gp_Pln& Pl, const Standard_Real Eps){ - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - Standard_Real Coeff[4]; - Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); - Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; - return myEpsilon = Compute(S,D,Standard_False,Coeff,loc,dim,g,inertia,Eps); -} - -void GProp_VGProps::Perform(const Face& S, const gp_Pln& Pl){ - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - Standard_Real Coeff[4]; - Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); - Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; - Compute(S,Standard_False,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -void GProp_VGProps::Perform(Face& S, Domain& D, const gp_Pln& Pl){ - Standard_Real xloc, yloc, zloc; - loc.Coord (xloc, yloc, zloc); - Standard_Real Coeff[4]; - Pl.Coefficients (Coeff[0], Coeff[1],Coeff[2],Coeff[3]); - Coeff[3] = Coeff[3] - Coeff[0]*xloc - Coeff[1]*yloc - Coeff[2]*zloc; - Compute(S,D,Standard_False,Coeff,loc,dim,g,inertia); - myEpsilon = 1.0; - return; -} - -Standard_Real GProp_VGProps::GetEpsilon(){ - return myEpsilon; -} diff --git a/src/GProp/GProp_VGPropsGK.cdl b/src/GProp/GProp_VGPropsGK.cdl deleted file mode 100644 index fbac889c17..0000000000 --- a/src/GProp/GProp_VGPropsGK.cdl +++ /dev/null @@ -1,472 +0,0 @@ --- Created on: 2005-12-21 --- Created by: Sergey KHROMOV --- Copyright (c) 2005-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 VGPropsGK from GProp (Arc as any; - Face as any; - Domain as any) -inherits GProps from GProp - - ---Purpose: Computes the global properties of a geometric solid - -- (3D closed region of space) delimited with : - -- - a point and a surface - -- - a plane and a surface - -- - -- The surface can be : - -- - a surface limited with its parametric values U-V, - -- (naturally restricted) - -- - a surface limited in U-V space with its boundary - -- curves. - -- - -- The surface's requirements to evaluate the global - -- properties are defined in the template FaceTool class from - -- the package GProp. - -- - -- The adaptive 2D algorithm of Gauss-Kronrod integration of - -- double integral is used. - -- - -- The inner integral is computed along U parameter of - -- surface. The integrand function is encapsulated in the - -- support class UFunction that is defined below. - -- - -- The outer integral is computed along T parameter of a - -- bounding curve. The integrand function is encapsulated in - -- the support class TFunction that is defined below. - -uses - - Pnt from gp, - XYZ from gp, - Pln from gp, - Address from Standard, - Boolean from Standard, - Real from Standard - - --- Template class functions. Used for integration. Begin - - class UFunction from GProp inherits Function from math - ---Purpose: This class represents the integrand function for - -- computation of an inner integral. The returned value - -- depends on the value type and the flag IsByPoint. - -- - -- The type of returned value is the one of the following - -- values: - -- - GProp_Mass - volume computation. - -- - GProp_CenterMassX, GProp_CenterMassY, - -- GProp_CenterMassZ - X, Y and Z coordinates of center - -- of mass computation. - -- - GProp_InertiaXX, GProp_InertiaYY, GProp_InertiaZZ, - -- GProp_InertiaXY, GProp_InertiaXZ, GProp_InertiaYZ - -- - moments of inertia computation. - -- - -- If the flag IsByPoint is set to Standard_True, the value is - -- returned for the region of space that is delimited by a - -- surface and a point. Otherwise all computations are - -- performed for the region of space delimited by a surface - -- and a plane. - - uses - - Pnt from gp, - XYZ from gp, - Address from Standard, - Boolean from Standard, - Real from Standard, - ValueType from GProp - - is - - Create(theSurface: Face; - theVertex : Pnt from gp; - IsByPoint : Boolean from Standard; - theCoeffs : Address from Standard) - ---Purpose: Constructor. Initializes the function with the face, the - -- location point, the flag IsByPoint and the coefficients - -- theCoeff that have different meaning depending on the value - -- of IsByPoint. - -- If IsByPoint is equal to Standard_True, the number of the - -- coefficients is equal to 3 and they represent X, Y and Z - -- coordinates (theCoeff[0], theCoeff[1] and theCoeff[2] - -- correspondingly) of the shift, if the inertia is computed - -- with respect to the point different then the location. - -- If IsByPoint is equal to Standard_False, the number of the - -- coefficients is 4 and they represent the combination of - -- plane parameters and shift values. - returns UFunction from GProp; - - SetValueType(me: in out; theType: ValueType from GProp); - ---Purpose: Setting the type of the value to be returned. - ---C++: inline - - SetVParam(me: in out; theVParam: Real from Standard); - ---Purpose: Setting the V parameter that is constant during the - -- integral computation. - ---C++: inline - - Value(me: in out; X: Real from Standard; - F: out Real from Standard) - ---Purpose: Returns a value of the function. - returns Boolean from Standard - is redefined; - - ----------------------- - -- Private methods -- - ----------------------- - - VolumeValue(me: in out; X : Real from Standard; - thePMP0: out XYZ from gp; - theS : out Real from Standard; - theD1 : out Real from Standard) - ---Purpose: Private method. Returns the value for volume computation. - -- Other returned values are: - -- - thePMP0 - PSurf(X,Y) minus Location. - -- - theS and theD1 coeffitients that are computed and used - -- for computation of center of mass and inertia values - -- by plane. - returns Real from Standard - is private; - - CenterMassValue(me: in out; X: Real from Standard; - F: out Real from Standard) - ---Purpose: Private method. Returns a value for the center of mass - -- computation. If the value type other then GProp_CenterMassX, - -- GProp_CenterMassY or GProp_CenterMassZ this method returns - -- Standard_False. Returns Standard_True in case of successful - -- computation of a value. - returns Boolean from Standard - is private; - - InertiaValue(me: in out; X: Real from Standard; - F: out Real from Standard) - ---Purpose: Private method. Computes the value of intertia. The type of - -- a value returned is defined by the value type. If it is - -- other then GProp_InertiaXX, GProp_InertiaYY, - -- GProp_InertiaZZ, GProp_InertiaXY, GProp_InertiaXZ or - -- GProp_InertiaYZ, the method returns Standard_False. Returns - -- Standard_True in case of successful computation of a value. - returns Boolean from Standard - is private; - - fields - - mySurface : Face; - myVertex : Pnt from gp; - myCoeffs : Address from Standard; - myVParam : Real from Standard; - myValueType: ValueType from GProp; - myIsByPoint: Boolean from Standard; - - end UFunction; - - - -- Class TFunction. - - class TFunction from GProp inherits Function from math - ---Purpose: This class represents the integrand function for the outer - -- integral computation. The returned value represents the - -- integral of UFunction. It depends on the value type and the - -- flag IsByPoint. - - uses - - Pnt from gp, - Address from Standard, - Boolean from Standard, - Integer from Standard, - Real from Standard, - ValueType from GProp - - is - - Create(theSurface : Face; - theVertex : Pnt from gp; - IsByPoint : Boolean from Standard; - theCoeffs : Address from Standard; - theUMin : Real from Standard; - theTolerance: Real from Standard) - ---Purpose: Constructor. Initializes the function with the face, the - -- location point, the flag IsByPoint, the coefficients - -- theCoeff that have different meaning depending on the value - -- of IsByPoint. The last two parameters are theUMin - the - -- lower bound of the inner integral. This value is fixed for - -- any integral. And the value of tolerance of inner integral - -- computation. - -- If IsByPoint is equal to Standard_True, the number of the - -- coefficients is equal to 3 and they represent X, Y and Z - -- coordinates (theCoeff[0], theCoeff[1] and theCoeff[2] - -- correspondingly) of the shift if the inertia is computed - -- with respect to the point different then the location. - -- If IsByPoint is equal to Standard_False, the number of the - -- coefficients is 4 and they represent the compbination of - -- plane parameters and shift values. - returns TFunction from GProp; - - Init(me: in out); - - SetNbKronrodPoints(me: in out; theNbPoints: Integer from Standard); - ---Purpose: Setting the expected number of Kronrod points for the outer - -- integral computation. This number is required for - -- computation of a value of tolerance for inner integral - -- computation. After GetStateNumber method call, this number - -- is recomputed by the same law as in - -- math_KronrodSingleIntegration, i.e. next number of points - -- is equal to the current number plus a square root of the - -- current number. If the law in math_KronrodSingleIntegration - -- is changed, the modification algo should be modified - -- accordingly. - ---C++: inline - - SetValueType(me: in out; aType: ValueType from GProp); - ---Purpose: Setting the type of the value to be returned. This - -- parameter is directly passed to the UFunction. - ---C++: inline - - SetTolerance(me: in out; aTol: Real from Standard); - ---Purpose: Setting the tolerance for inner integration - ---C++: inline - - ErrorReached(me) - ---Purpose: Returns the relative reached error of all values computation since - -- the last call of GetStateNumber method. - ---C++: inline - returns Real from Standard; - - AbsolutError(me) - ---Purpose: Returns the absolut reached error of all values computation since - -- the last call of GetStateNumber method. - ---C++: inline - returns Real from Standard; - - Value(me: in out; X: Real from Standard; - F: out Real from Standard) - ---Purpose: Returns a value of the function. The value represents an - -- integral of UFunction. It is computed with the predefined - -- tolerance using the adaptive Gauss-Kronrod method. - returns Boolean from Standard - is redefined; - - GetStateNumber(me: in out) - ---Purpose: Redefined method. Remembers the error reached during - -- computation of integral values since the object creation - -- or the last call of GetStateNumber. It is invoked in each - -- algorithm from the package math. Particularly in the - -- algorithm math_KronrodSingleIntegration that is used to - -- compute the integral of TFunction. - returns Integer - is redefined; - - fields - - mySurface : Face; - myUFunction : UFunction; - myUMin : Real from Standard; - myTolerance : Real from Standard; - myTolReached: Real from Standard; - myErrReached: Real from Standard; - myAbsError : Real from Standard; - myValueType : ValueType from GProp; - myIsByPoint : Boolean from Standard; - myNbPntOuter: Integer from Standard; - - end TFunction; - --- Template class functions. Used for integration. End - -is - - Create - ---Purpose: Empty constructor. - ---C++: inline - returns VGPropsGK; - - Create(theSurface : in out Face; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the naturally restricted surface - -- and the point VLocation. - returns VGPropsGK; - - Create(theSurface : in out Face; - thePoint : Pnt from gp; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the naturally restricted surface - -- and the point VLocation. The inertia is computed with - -- respect to thePoint. - returns VGPropsGK; - - Create(theSurface : in out Face; - theDomain : in out Domain; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the surface bounded by the domain - -- and the point VLocation. - returns VGPropsGK; - - Create(theSurface : in out Face; - theDomain : in out Domain; - thePoint : Pnt from gp; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the surface bounded by the domain - -- and the point VLocation. The inertia is computed with - -- respect to thePoint. - returns VGPropsGK; - - Create(theSurface : in out Face; - thePlane : Pln from gp; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the naturally restricted surface - -- and the plane. - returns VGPropsGK; - - Create(theSurface : in out Face; - theDomain : in out Domain; - thePlane : Pln from gp; - theLocation : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Constructor. Computes the global properties of a region of - -- 3D space delimited with the surface bounded by the domain - -- and the plane. - returns VGPropsGK; - - SetLocation(me: in out; theLocation: Pnt from gp); - ---Purpose: Sets the vertex that delimit 3D closed region of space. - ---C++: inline - - Perform(me: in out; theSurface : in out Face; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the naturally restricted surface and the - -- point VLocation. - returns Real from Standard; - - Perform(me: in out; theSurface : in out Face; - thePoint : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the naturally restricted surface and the - -- point VLocation. The inertia is computed with respect to - -- thePoint. - returns Real from Standard; - - Perform(me: in out; theSurface : in out Face; - theDomain : in out Domain; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the surface bounded by the domain and the - -- point VLocation. - returns Real from Standard; - - Perform(me: in out; theSurface : in out Face; - theDomain : in out Domain; - thePoint : Pnt from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the surface bounded by the domain and the - -- point VLocation. The inertia is computed with respect to - -- thePoint. - returns Real from Standard; - - Perform(me: in out; theSurface : in out Face; - thePlane : Pln from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the naturally restricted surface and the - -- plane. - returns Real from Standard; - - Perform(me: in out; theSurface : in out Face; - theDomain : in out Domain; - thePlane : Pln from gp; - theTolerance: Real from Standard = 0.001; - theCGFlag: Boolean from Standard = Standard_False; - theIFlag: Boolean from Standard = Standard_False) - - ---Purpose: Computes the global properties of a region of 3D space - -- delimited with the surface bounded by the domain and the - -- plane. - returns Real from Standard; - - GetErrorReached(me) - ---Purpose: Returns the relative reached computation error. - ---C++: inline - returns Real from Standard; - - GetAbsolutError(me) - ---Purpose: Returns the absolut reached computation error. - ---C++: inline - returns Real from Standard; - ------------------------ --- Private methods -- ------------------------ - - PrivatePerform(me: in out; - theSurface : in out Face; - thePtrDomain: Address from Standard; -- pointer to Domain. - IsByPoint : Boolean from Standard; - theCoeffs : Address from Standard; - theTolerance: Real from Standard; - theCGFlag : Boolean from Standard; - theIFlag : Boolean from Standard) - - ---Purpose: Main method for computation of the global properties that - -- is invoked by each Perform method. - returns Real from Standard - is private; - -fields - - myErrorReached: Real from Standard; - myAbsolutError: Real from Standard; - -end VGPropsGK; diff --git a/src/GProp/GProp_VGPropsGK.gxx b/src/GProp/GProp_VGPropsGK.gxx deleted file mode 100644 index a4c01536fc..0000000000 --- a/src/GProp/GProp_VGPropsGK.gxx +++ /dev/null @@ -1,483 +0,0 @@ -// Created on: 2005-12-09 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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 -#include -#include -#include -#include - -//========================================================================== -//function : Constructor -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Constructor -// -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - const gp_Pnt &thePoint, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, thePoint, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Constructor -// -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - Domain &theDomain, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, theDomain, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Constructor -// -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - Domain &theDomain, - const gp_Pnt &thePoint, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, theDomain, thePoint, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Constructor -// -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - const gp_Pln &thePlane, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, thePlane, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Constructor -// -//========================================================================== - -GProp_VGPropsGK::GProp_VGPropsGK( Face &theSurface, - Domain &theDomain, - const gp_Pln &thePlane, - const gp_Pnt &theLocation, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - - : myErrorReached(0.) -{ - SetLocation(theLocation); - Perform(theSurface, theDomain, thePlane, theTolerance, theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - Standard_Real aShift[] = { 0., 0., 0. }; - - return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - const gp_Pnt &thePoint, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - gp_XYZ aXYZ(thePoint.XYZ().Subtracted(loc.XYZ())); - Standard_Real aShift[3]; - - aXYZ.Coord(aShift[0], aShift[1], aShift[2]); - - return PrivatePerform(theSurface, NULL, Standard_True, &aShift, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - Domain &theDomain, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - Standard_Real aShift[] = { 0., 0., 0. }; - - return PrivatePerform(theSurface, &theDomain, - Standard_True, &aShift, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - Domain &theDomain, - const gp_Pnt &thePoint, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - gp_XYZ aXYZ(thePoint.XYZ().Subtracted(loc.XYZ())); - Standard_Real aShift[3]; - - aXYZ.Coord(aShift[0], aShift[1], aShift[2]); - - return PrivatePerform(theSurface, &theDomain, - Standard_True, &aShift, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - const gp_Pln &thePlane, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - Standard_Real aCoeff[4]; - Standard_Real aXLoc; - Standard_Real aYLoc; - Standard_Real aZLoc; - - loc.Coord(aXLoc, aYLoc, aZLoc); - thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]); - aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc; - - return PrivatePerform(theSurface, NULL, - Standard_False, &aCoeff, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : Perform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::Perform( Face &theSurface, - Domain &theDomain, - const gp_Pln &thePlane, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - Standard_Real aCoeff[4]; - Standard_Real aXLoc; - Standard_Real aYLoc; - Standard_Real aZLoc; - - loc.Coord(aXLoc, aYLoc, aZLoc); - thePlane.Coefficients (aCoeff[0], aCoeff[1], aCoeff[2], aCoeff[3]); - aCoeff[3] = aCoeff[3] - aCoeff[0]*aXLoc - aCoeff[1]*aYLoc - aCoeff[2]*aZLoc; - - return PrivatePerform(theSurface, &theDomain, - Standard_False, &aCoeff, theTolerance, - theCGFlag, theIFlag); -} - -//========================================================================== -//function : PrivatePerform -// Compute the properties. -//========================================================================== - -Standard_Real GProp_VGPropsGK::PrivatePerform - ( Face &theSurface, - const Standard_Address thePtrDomain, - const Standard_Boolean IsByPoint, - const Standard_Address theCoeffs, - const Standard_Real theTolerance, - const Standard_Boolean theCGFlag, - const Standard_Boolean theIFlag) - -{ - - const Standard_Real aTTol = 1.e-9; - Standard_Real *aCoeffs = (Standard_Real *)theCoeffs; - - // Compute the number of 2d bounding curves of the face. - Domain *aPDomain = NULL; - Standard_Integer aNbCurves = 0; - - // If the pointer to the domain is NULL, there is only one curve to treat: - // U isoline with the UMax parameter. - if (thePtrDomain == NULL) - aNbCurves = 1; - else { - aPDomain = (Domain *)thePtrDomain; - - for (aPDomain->Init(); aPDomain->More(); aPDomain->Next()) - aNbCurves++; - } - - if (aNbCurves == 0) { - myErrorReached = -1.; - - return myErrorReached; - } - - //Standard_Real aCrvTol = 0.5*theTolerance/aNbCurves; - Standard_Real aCrvTol = 0.1*theTolerance; - Standard_Real aUMin; - Standard_Real aUMax; - Standard_Real aTMin; - Standard_Real aTMax; - Standard_Integer aNbPnts; - Standard_Integer aNbMaxIter = 1000; - Standard_Integer aNbVal = 10; - Standard_Integer k; - math_Vector aLocalValue(1, aNbVal); - math_Vector aLocalTolReached(1, aNbVal); - math_Vector aValue(1, aNbVal); - math_Vector aTolReached(1, aNbVal); - TColStd_Array1OfBoolean CFlags(1, aNbVal); - CFlags.Init(Standard_False); - Standard_Boolean isMore; - - //aNbVal = 1; - aValue.Init(0.); - aTolReached.Init(0.); - - CFlags.Init(Standard_False); - CFlags(1) = Standard_True; - - if(theCGFlag || theIFlag) { - Standard_Integer i; - for(i = 2; i <= 4; ++i) {CFlags(i) = Standard_True;} - } - - if(theIFlag) { - Standard_Integer i; - for(i = 5; i <= 10; ++i) {CFlags(i) = Standard_True;} - } - - theSurface.Bounds(aUMin, aUMax, aTMin, aTMax); - - if (thePtrDomain == NULL) - isMore = Standard_True; - else { - aPDomain->Init(); - isMore = aPDomain->More(); - } - - while(isMore) { - // If the pointer to the domain is NULL, there is only one curve to treat: - // U isoline with the UMax parameter. - - if (thePtrDomain == NULL) - theSurface.Load(Standard_False, GeomAbs_IsoU); - else - theSurface.Load(aPDomain->Value()); - - aTMin = theSurface.FirstParameter(); - aTMax = theSurface.LastParameter(); - - - // Get the spans on the curve. - Handle(TColStd_HArray1OfReal) aTKnots; - GProp_TFunction aTFunc(theSurface, loc, IsByPoint, theCoeffs, - aUMin, aCrvTol); - - theSurface.GetTKnots(aTMin, aTMax, aTKnots); - - Standard_Integer iU = aTKnots->Upper(); - Standard_Integer aNbTIntervals = aTKnots->Length() - 1; - //Standard_Real aTolSpan = aCrvTol/aNbTIntervals; - Standard_Real aTolSpan = 0.9*theTolerance; //Relative error - math_KronrodSingleIntegration anIntegral; - GProp_ValueType aValueType; - - - // Empirical criterion. - aNbPnts = Min(15, theSurface.IntegrationOrder()/aNbTIntervals + 1); - aNbPnts = Max(5, aNbPnts); -// aNbPnts = theSurface.IntegrationOrder(); - - aLocalValue.Init(0.); - aLocalTolReached.Init(0.); - - for (k = 1; k <= aNbVal; k++) { - - if(!CFlags(k)) continue; - - Standard_Integer i = aTKnots->Lower(); - - switch (k) { - case 1: aValueType = GProp_Mass; break; - case 2: aValueType = GProp_CenterMassX; break; - case 3: aValueType = GProp_CenterMassY; break; - case 4: aValueType = GProp_CenterMassZ; break; - case 5: aValueType = GProp_InertiaXX; break; - case 6: aValueType = GProp_InertiaYY; break; - case 7: aValueType = GProp_InertiaZZ; break; - case 8: aValueType = GProp_InertiaXY; break; - case 9: aValueType = GProp_InertiaXZ; break; - case 10: aValueType = GProp_InertiaYZ; break; - - default: myErrorReached = -1.; return myErrorReached; - } - aTFunc.SetValueType(aValueType); - - Standard_Real err1 = 0.; - while (i < iU) { - - //cout << "-------------- Span " << i << " nbp: " << aNbPnts << endl; - Standard_Real aT1 = aTKnots->Value(i++); - Standard_Real aT2 = aTKnots->Value(i); - - if(aT2 - aT1 < aTTol) continue; - - aTFunc.SetNbKronrodPoints(aNbPnts); - aTFunc.Init(); - aTFunc.SetTolerance(aCrvTol/(aT2-aT1)); - anIntegral.Perform(aTFunc, aT1, aT2, aNbPnts, aTolSpan, aNbMaxIter); - - if (!anIntegral.IsDone()) { - myErrorReached = -1.; - - return myErrorReached; - } - - aLocalValue(k) += anIntegral.Value(); - err1 = aTFunc.AbsolutError()*(aT2 - aT1); - //cout << "Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl; - aLocalTolReached(k) += anIntegral.AbsolutError() + err1; - //cout << "--- Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << endl; - } - - aValue(k) += aLocalValue(k); - aTolReached(k) += aLocalTolReached(k); - } - - // If the pointer to the domain is NULL, there is only one curve to treat: - // U isoline with the UMax parameter. - if (thePtrDomain == NULL) - isMore = Standard_False; - else { - aPDomain->Next(); - isMore = aPDomain->More(); - } - } - - // Get volume value. - dim = aValue(1); - myErrorReached = aTolReached(1); - myAbsolutError = myErrorReached; - Standard_Real anAbsDim = Abs(dim); - Standard_Real aVolTol = Epsilon(myAbsolutError); - if(anAbsDim >= aVolTol) myErrorReached /= anAbsDim; - - if(theCGFlag || theIFlag) { - // Compute values of center of mass. - if(anAbsDim >= aVolTol) { - if (IsByPoint) { - aValue(2) = aCoeffs[0] + aValue(2)/dim; - aValue(3) = aCoeffs[1] + aValue(3)/dim; - aValue(4) = aCoeffs[2] + aValue(4)/dim; - } else { - aValue(2) /= dim; - aValue(3) /= dim; - aValue(4) /= dim; - } - } else { - aValue(2) = 0.; - aValue(3) = 0.; - aValue(4) = 0.; - dim = 0.; - } - g.SetCoord(aValue(2), aValue(3), aValue(4)); - } - - if(theIFlag) { - // Fill the matrix of inertia. - inertia.SetCols (gp_XYZ (aValue(5), aValue(8), aValue(9)), - gp_XYZ (aValue(8), aValue(6), aValue(10)), - gp_XYZ (aValue(9), aValue(10), aValue(7))); - } - //return myErrorReached; - return myAbsolutError; -} - diff --git a/src/GProp/GProp_VGPropsGK.lxx b/src/GProp/GProp_VGPropsGK.lxx deleted file mode 100644 index 0627c5a821..0000000000 --- a/src/GProp/GProp_VGPropsGK.lxx +++ /dev/null @@ -1,45 +0,0 @@ -// Created on: 2005-12-21 -// Created by: Sergey KHROMOV -// Copyright (c) 2005-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. - -//========================================================================== -//function : Constructor -// Empty constructor. -//========================================================================== - -inline GProp_VGPropsGK::GProp_VGPropsGK() - : myErrorReached(0.), - myAbsolutError(0.) -{ -} - -//========================================================================== -//function : SetLocation -// Sets the vertex that delimit 3D closed region of space. -//========================================================================== - -inline void GProp_VGPropsGK::SetLocation(const gp_Pnt &theVertex) -{ - loc = theVertex; -} - -//========================================================================== -//function : GetErrorReached -// Returns the reached Error. -//========================================================================== - -inline Standard_Real GProp_VGPropsGK::GetErrorReached() const -{ - return myErrorReached; -}