1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-30 13:05:50 +03:00
occt/src/BRepGProp/BRepGProp_VinertGK.cxx
tiv 0423218095 0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
"endl" manipulator for Message_Messenger is renamed to "Message_EndLine".

The following entities from std namespace are now used
with std:: explicitly specified (from Standard_Stream.hxx):
std::istream,std::ostream,std::ofstream,std::ifstream,std::fstream,
std::filebuf,std::streambuf,std::streampos,std::ios,std::cout,std::cerr,
std::cin,std::endl,std::ends,std::flush,std::setw,std::setprecision,
std::hex,std::dec.
2019-08-16 12:16:38 +03:00

483 lines
17 KiB
C++

// 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 <BRepGProp_Domain.hxx>
#include <BRepGProp_Face.hxx>
#include <BRepGProp_TFunction.hxx>
#include <BRepGProp_VinertGK.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <math_KronrodSingleIntegration.hxx>
#include <TColStd_Array1OfBoolean.hxx>
#include <TColStd_HArray1OfReal.hxx>
//==========================================================================
//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) {
//std::cout << "-------------- Span " << i << " nbp: " << aNbPnts << std::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);
//std::cout << "Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << std::endl;
aLocalTolReached(k) += anIntegral.AbsolutError() + err1;
//std::cout << "--- Errors: " << anIntegral.NbIterReached() << " " << anIntegral.AbsolutError() << " " << err1 << std::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;
}