Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// 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_UFunction.hxx>
#include <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
//=================================================================================================
BRepGProp_UFunction::BRepGProp_UFunction(const BRepGProp_Face& theSurface,
const gp_Pnt& theVertex,
const bool IsByPoint,
const double* theCoeffs)
: mySurface(theSurface),
myVertex(theVertex),
myCoeffs(theCoeffs),
myVParam(0.),
myValueType(GProp_Unknown),
myIsByPoint(IsByPoint)
{
}
//=======================================================================
// function : Value
// purpose : Returns a value of the function.
//=======================================================================
bool BRepGProp_UFunction::Value(const double X, double& F)
{
// Volume computation
if (myValueType == GProp_Mass)
{
gp_XYZ aPMP0;
double aTmpPar1;
double aTmpPar2;
F = VolumeValue(X, aPMP0, aTmpPar1, aTmpPar2);
return 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 false;
}
//=======================================================================
// function : VolumeValue
// purpose : Returns the value for volume computation.
//=======================================================================
double BRepGProp_UFunction::VolumeValue(const double X,
gp_XYZ& thePMP0,
double& theS,
double& 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.
const double* aCoeff = 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.
//=======================================================================
bool BRepGProp_UFunction::CenterMassValue(const double X, double& F)
{
gp_XYZ aPmP0;
double aS;
double 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 false;
}
return true;
}
// Center of mass computation for ByPlane mode.
const double* aCoeff = 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 false;
}
return true;
}
//=================================================================================================
bool BRepGProp_UFunction::InertiaValue(const double X, double& F)
{
gp_XYZ aPmP0;
double aS;
double aD1;
double aParam1;
double aParam2;
const double* aCoeffs = 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 false;
}
if (myValueType == GProp_InertiaXX || myValueType == GProp_InertiaYY
|| myValueType == GProp_InertiaZZ)
{
F *= aParam1 * aParam1 + aParam2 * aParam2;
}
else
{
F *= -aParam1 * aParam2;
}
return true;
}
// Inertia computation for ByPlane mode.
double aD2 = aD1 * aD1;
double aD3 = aD1 * aD2 / 3.;
double aPPar1;
double aPPar2;
double aCoeff1;
double 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 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 true;
}
return false;
}