mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-24 13:50:49 +03:00
0029734: Modeling Algorithms - Compute global properties of tessellated shape
New algorithms calculating global properties on mesh data have been added: - BRepGProp_MeshCinert computes the global properties of polylines represented by a set of points; - BRepGProp_MeshProps computes the global properties of a surface mesh. Existing tool BRepGProp now automatically uses new algorithm for triangulation-only faces. By default, algorithm will use exact geometry objects (surfaces), when it is available (as before the patch); this behavior can be switched by a new flag UseTriangulation, forcing usage of triangulation instead of exact geometry when both defined.
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
#include <BRepGProp_Cinert.hxx>
|
||||
#include <BRepGProp_Sinert.hxx>
|
||||
#include <BRepGProp_Vinert.hxx>
|
||||
#include <BRepGProp_MeshProps.hxx>
|
||||
#include <BRepGProp_MeshCinert.hxx>
|
||||
#include <BRepGProp_VinertGK.hxx>
|
||||
#include <GProp_PGProps.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
@@ -29,6 +31,7 @@
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <BRepCheck_Shell.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
static Standard_Integer AffichEps = 0;
|
||||
#endif
|
||||
@@ -38,18 +41,45 @@ static gp_Pnt roughBaryCenter(const TopoDS_Shape& S){
|
||||
gp_XYZ xyz(0,0,0);
|
||||
for (ex.Init(S,TopAbs_VERTEX), i = 0; ex.More(); ex.Next(), i++)
|
||||
xyz += BRep_Tool::Pnt(TopoDS::Vertex(ex.Current())).XYZ();
|
||||
if ( i > 0 ) xyz /= i;
|
||||
if (i > 0)
|
||||
{
|
||||
xyz /= i;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Try using triangulation
|
||||
ex.Init(S, TopAbs_FACE);
|
||||
for (; ex.More(); ex.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = ex.Current();
|
||||
TopLoc_Location aLocDummy;
|
||||
const Handle(Poly_Triangulation)& aTri =
|
||||
BRep_Tool::Triangulation(TopoDS::Face(aF), aLocDummy);
|
||||
if (!aTri.IsNull())
|
||||
{
|
||||
xyz = aTri->Node(1).XYZ();
|
||||
if (!aLocDummy.IsIdentity())
|
||||
{
|
||||
aLocDummy.Transformation().Transforms(xyz);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return gp_Pnt(xyz);
|
||||
}
|
||||
|
||||
void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared){
|
||||
|
||||
|
||||
void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared,
|
||||
const Standard_Boolean UseTriangulation)
|
||||
{
|
||||
// find the origin
|
||||
gp_Pnt P(0,0,0);
|
||||
P.Transform(S.Location());
|
||||
SProps = GProp_GProps(P);
|
||||
|
||||
BRepAdaptor_Curve BAC;
|
||||
Standard_Real eps = Epsilon(1.);
|
||||
TopTools_MapOfShape anEMap;
|
||||
TopExp_Explorer ex;
|
||||
for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
|
||||
@@ -58,27 +88,35 @@ void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, c
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(!BRep_Tool::IsGeometric(aE))
|
||||
|
||||
Handle(TColgp_HArray1OfPnt) theNodes;
|
||||
Standard_Boolean IsGeom = BRep_Tool::IsGeometric(aE);
|
||||
if (UseTriangulation || !IsGeom)
|
||||
{
|
||||
GProp_PGProps aPProps;
|
||||
TopoDS_Iterator anIter(aE);
|
||||
for(; anIter.More(); anIter.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aV = TopoDS::Vertex(anIter.Value());
|
||||
aPProps.AddPoint(BRep_Tool::Pnt(aV), eps);
|
||||
}
|
||||
SProps.Add(aPProps);
|
||||
BRepGProp_MeshCinert::PreparePolygon(aE, theNodes);
|
||||
}
|
||||
if(!theNodes.IsNull())
|
||||
{
|
||||
BRepGProp_MeshCinert MG;
|
||||
MG.SetLocation(P);
|
||||
MG.Perform(theNodes->Array1());
|
||||
SProps.Add(MG);
|
||||
}
|
||||
else
|
||||
{
|
||||
BAC.Initialize(aE);
|
||||
BRepGProp_Cinert CG(BAC,P);
|
||||
SProps.Add(CG);
|
||||
if (IsGeom)
|
||||
{
|
||||
BAC.Initialize(aE);
|
||||
BRepGProp_Cinert CG(BAC, P);
|
||||
SProps.Add(CG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
|
||||
static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared,
|
||||
const Standard_Boolean UseTriangulation)
|
||||
{
|
||||
Standard_Integer i;
|
||||
#ifdef OCCT_DEBUG
|
||||
Standard_Integer iErrorMax = 0;
|
||||
@@ -87,66 +125,90 @@ static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Prop
|
||||
TopExp_Explorer ex;
|
||||
gp_Pnt P(roughBaryCenter(S));
|
||||
BRepGProp_Sinert G; G.SetLocation(P);
|
||||
BRepGProp_MeshProps MG(BRepGProp_MeshProps::Sinert);
|
||||
MG.SetLocation(P);
|
||||
|
||||
BRepGProp_Face BF;
|
||||
BRepGProp_Domain BD;
|
||||
TopTools_MapOfShape aFMap;
|
||||
TopLoc_Location aLocDummy;
|
||||
|
||||
for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) {
|
||||
for (ex.Init(S, TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) {
|
||||
const TopoDS_Face& F = TopoDS::Face(ex.Current());
|
||||
if(SkipShared && !aFMap.Add(F))
|
||||
if (SkipShared && !aFMap.Add(F))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False;
|
||||
{
|
||||
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (F, aLocDummy);
|
||||
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, aLocDummy);
|
||||
if (aSurf.IsNull())
|
||||
{
|
||||
// skip faces without geometry
|
||||
NoSurf = Standard_True;
|
||||
}
|
||||
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
|
||||
if (aTri.IsNull())
|
||||
{
|
||||
NoTri = Standard_True;
|
||||
}
|
||||
if (NoTri && NoSurf)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
BF.Load(F);
|
||||
Standard_Boolean IsNatRestr = (F.NbChildren() == 0);
|
||||
if(!IsNatRestr) BD.Init(F);
|
||||
if(Eps < 1.0) {
|
||||
G.Perform(BF, BD, Eps);
|
||||
Error = G.GetEpsilon();
|
||||
if(ErrorMax < Error) {
|
||||
ErrorMax = Error;
|
||||
#ifdef OCCT_DEBUG
|
||||
iErrorMax = i;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if(IsNatRestr) G.Perform(BF);
|
||||
else G.Perform(BF, BD);
|
||||
if ((UseTriangulation && !NoTri) || (NoSurf && !NoTri))
|
||||
{
|
||||
TopAbs_Orientation anOri = F.Orientation();
|
||||
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
|
||||
MG.Perform(aTri, aLocDummy, anOri);
|
||||
Props.Add(MG);
|
||||
}
|
||||
Props.Add(G);
|
||||
else
|
||||
{
|
||||
BF.Load(F);
|
||||
Standard_Boolean IsNatRestr = (F.NbChildren() == 0);
|
||||
if (!IsNatRestr) BD.Init(F);
|
||||
if (Eps < 1.0) {
|
||||
G.Perform(BF, BD, Eps);
|
||||
Error = G.GetEpsilon();
|
||||
if (ErrorMax < Error) {
|
||||
ErrorMax = Error;
|
||||
#ifdef OCCT_DEBUG
|
||||
if(AffichEps) cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon();
|
||||
iErrorMax = i;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (IsNatRestr) G.Perform(BF);
|
||||
else G.Perform(BF, BD);
|
||||
}
|
||||
Props.Add(G);
|
||||
#ifdef OCCT_DEBUG
|
||||
if(AffichEps) cout<<"\n"<<i<<":\tEpsArea = "<< G.GetEpsilon();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
if(AffichEps) cout<<"\n-----------------\n"<<iErrorMax<<":\tMaxError = "<<ErrorMax<<"\n";
|
||||
#endif
|
||||
return ErrorMax;
|
||||
}
|
||||
void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean SkipShared){
|
||||
void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean SkipShared,
|
||||
const Standard_Boolean UseTriangulation)
|
||||
{
|
||||
// find the origin
|
||||
gp_Pnt P(0,0,0);
|
||||
P.Transform(S.Location());
|
||||
Props = GProp_GProps(P);
|
||||
surfaceProperties(S,Props,1.0, SkipShared);
|
||||
surfaceProperties(S,Props,1.0, SkipShared, UseTriangulation);
|
||||
}
|
||||
Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
|
||||
// find the origin
|
||||
gp_Pnt P(0,0,0); P.Transform(S.Location());
|
||||
Props = GProp_GProps(P);
|
||||
Standard_Real ErrorMax = surfaceProperties(S,Props,Eps,SkipShared);
|
||||
Standard_Real ErrorMax = surfaceProperties(S,Props,Eps,SkipShared, Standard_False);
|
||||
return ErrorMax;
|
||||
}
|
||||
|
||||
@@ -155,7 +217,9 @@ Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps&
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
|
||||
static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared,
|
||||
const Standard_Boolean UseTriangulation)
|
||||
{
|
||||
Standard_Integer i;
|
||||
#ifdef OCCT_DEBUG
|
||||
Standard_Integer iErrorMax = 0;
|
||||
@@ -164,6 +228,8 @@ static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props
|
||||
TopExp_Explorer ex;
|
||||
gp_Pnt P(roughBaryCenter(S));
|
||||
BRepGProp_Vinert G; G.SetLocation(P);
|
||||
BRepGProp_MeshProps MG(BRepGProp_MeshProps::Vinert);
|
||||
MG.SetLocation(P);
|
||||
|
||||
BRepGProp_Face BF;
|
||||
BRepGProp_Domain BD;
|
||||
@@ -187,37 +253,56 @@ static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Standard_Boolean NoSurf = Standard_False, NoTri = Standard_False;
|
||||
{
|
||||
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (F, aLocDummy);
|
||||
if (aSurf.IsNull())
|
||||
{
|
||||
// skip faces without geometry
|
||||
NoSurf = Standard_True;
|
||||
}
|
||||
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
|
||||
if (aTri.IsNull())
|
||||
{
|
||||
NoTri = Standard_True;
|
||||
}
|
||||
if (NoTri && NoSurf)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFwd || isRvs){
|
||||
BF.Load(F);
|
||||
Standard_Boolean IsNatRestr = (F.NbChildren () == 0);
|
||||
if(!IsNatRestr) BD.Init(F);
|
||||
if(Eps < 1.0) {
|
||||
G.Perform(BF, BD, Eps);
|
||||
Error = G.GetEpsilon();
|
||||
if(ErrorMax < Error) {
|
||||
ErrorMax = Error;
|
||||
if (isFwd || isRvs)
|
||||
{
|
||||
if ((UseTriangulation && !NoTri) || (NoSurf && !NoTri))
|
||||
{
|
||||
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
|
||||
MG.Perform(aTri, aLocDummy, anOri);
|
||||
Props.Add(MG);
|
||||
}
|
||||
else
|
||||
{
|
||||
BF.Load(F);
|
||||
Standard_Boolean IsNatRestr = (F.NbChildren () == 0);
|
||||
if (!IsNatRestr) BD.Init(F);
|
||||
if (Eps < 1.0) {
|
||||
G.Perform(BF, BD, Eps);
|
||||
Error = G.GetEpsilon();
|
||||
if (ErrorMax < Error) {
|
||||
ErrorMax = Error;
|
||||
#ifdef OCCT_DEBUG
|
||||
iErrorMax = i;
|
||||
iErrorMax = i;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(IsNatRestr) G.Perform(BF);
|
||||
else G.Perform(BF, BD);
|
||||
}
|
||||
Props.Add(G);
|
||||
else {
|
||||
if (IsNatRestr) G.Perform(BF);
|
||||
else G.Perform(BF, BD);
|
||||
}
|
||||
Props.Add(G);
|
||||
#ifdef OCCT_DEBUG
|
||||
if(AffichEps) cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon();
|
||||
if(AffichEps) cout<<"\n"<<i<<":\tEpsVolume = "<< G.GetEpsilon();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
@@ -225,7 +310,9 @@ static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props
|
||||
#endif
|
||||
return ErrorMax;
|
||||
}
|
||||
void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared){
|
||||
void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared,
|
||||
const Standard_Boolean UseTriangulation)
|
||||
{
|
||||
// find the origin
|
||||
gp_Pnt P(0,0,0); P.Transform(S.Location());
|
||||
Props = GProp_GProps(P);
|
||||
@@ -238,9 +325,9 @@ void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, co
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0,SkipShared);
|
||||
if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0,SkipShared, UseTriangulation);
|
||||
}
|
||||
} else volumeProperties(S,Props,1.0,SkipShared);
|
||||
} else volumeProperties(S,Props,1.0,SkipShared, UseTriangulation);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -269,7 +356,7 @@ Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& P
|
||||
continue;
|
||||
}
|
||||
if(BRep_Tool::IsClosed(Sh)) {
|
||||
Error = volumeProperties(Sh,Props,Eps,SkipShared);
|
||||
Error = volumeProperties(Sh,Props,Eps,SkipShared, Standard_False);
|
||||
if(ErrorMax < Error) {
|
||||
ErrorMax = Error;
|
||||
#ifdef OCCT_DEBUG
|
||||
@@ -278,7 +365,7 @@ Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& P
|
||||
}
|
||||
}
|
||||
}
|
||||
} else ErrorMax = volumeProperties(S,Props,Eps,SkipShared);
|
||||
} else ErrorMax = volumeProperties(S,Props,Eps,SkipShared, Standard_False);
|
||||
#ifdef OCCT_DEBUG
|
||||
if(AffichEps) cout<<"\n\n==================="<<iErrorMax<<":\tMaxEpsVolume = "<<ErrorMax<<"\n";
|
||||
#endif
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <TColgp_Array1OfXYZ.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class GProp_GProps;
|
||||
class gp_Pln;
|
||||
@@ -35,6 +37,7 @@ class BRepGProp_Vinert;
|
||||
class BRepGProp_VinertGK;
|
||||
class BRepGProp_UFunction;
|
||||
class BRepGProp_TFunction;
|
||||
class gp_XYZ;
|
||||
|
||||
|
||||
//! Provides global functions to compute a shape's global
|
||||
@@ -85,10 +88,19 @@ public:
|
||||
//! No check is performed to verify that the shape S
|
||||
//! retains truly linear properties. If S is simply a vertex, it
|
||||
//! is not considered to present any additional global properties.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, edges, shared by two or more faces, are taken into calculation only once.
|
||||
//! If we have cube with sizes 1, 1, 1, its linear properties = 12 for SkipEdges = true and 24 for SkipEdges = false.
|
||||
Standard_EXPORT static void LinearProperties (const TopoDS_Shape& S, GProp_GProps& LProps, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared is a special flag, which allows taking in calculation
|
||||
//! shared topological entities or not.
|
||||
//! For ex., if SkipShared = True, edges, shared by two or more faces,
|
||||
//! are taken into calculation only once.
|
||||
//! If we have cube with sizes 1, 1, 1, its linear properties = 12
|
||||
//! for SkipEdges = true and 24 for SkipEdges = false.
|
||||
//! UseTriangulation is a special flag, which defines preferable
|
||||
//! source of geometry data. If UseTriangulation = Standard_False,
|
||||
//! exact geometry objects (curves) are used, otherwise polygons of
|
||||
//! triangulation are used first.
|
||||
Standard_EXPORT static void LinearProperties(const TopoDS_Shape& S, GProp_GProps& LProps,
|
||||
const Standard_Boolean SkipShared = Standard_False,
|
||||
const Standard_Boolean UseTriangulation = Standard_False);
|
||||
|
||||
//! Computes the surface global properties of the
|
||||
//! shape S, i.e. the global properties induced by each
|
||||
@@ -122,9 +134,17 @@ public:
|
||||
//! retains truly surface properties. If S is simply a
|
||||
//! vertex, an edge or a wire, it is not considered to
|
||||
//! present any additional global properties.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, faces, shared by two or more shells, are taken into calculation only once.
|
||||
Standard_EXPORT static void SurfaceProperties (const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared is a special flag, which allows taking in calculation
|
||||
//! shared topological entities or not.
|
||||
//! For ex., if SkipShared = True, faces, shared by two or more shells,
|
||||
//! are taken into calculation only once.
|
||||
//! UseTriangulation is a special flag, which defines preferable
|
||||
//! source of geometry data. If UseTriangulation = Standard_False,
|
||||
//! exact geometry objects (surfaces) are used,
|
||||
//! otherwise face triangulations are used first.
|
||||
Standard_EXPORT static void SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& SProps,
|
||||
const Standard_Boolean SkipShared = Standard_False,
|
||||
const Standard_Boolean UseTriangulation = Standard_False);
|
||||
|
||||
//! Updates <SProps> with the shape <S>, that contains its pricipal properties.
|
||||
//! The surface properties of all the faces in <S> are computed.
|
||||
@@ -134,9 +154,12 @@ public:
|
||||
//! for two successive steps of adaptive integration.
|
||||
//! Method returns estimation of relative error reached for whole shape.
|
||||
//! WARNING: if Eps > 0.001 algorithm performs non-adaptive integration.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, faces, shared by two or more shells, are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real SurfaceProperties (const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Real Eps, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared is a special flag, which allows taking in calculation
|
||||
//! shared topological entities or not
|
||||
//! For ex., if SkipShared = True, faces, shared by two or more shells,
|
||||
//! are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real SurfaceProperties (const TopoDS_Shape& S, GProp_GProps& SProps,
|
||||
const Standard_Real Eps, const Standard_Boolean SkipShared = Standard_False);
|
||||
//!
|
||||
//! Computes the global volume properties of the solid
|
||||
//! S, and brings them together with the global
|
||||
@@ -170,9 +193,19 @@ public:
|
||||
//! exempt of any free boundary. Note that these
|
||||
//! conditions of coherence are not checked by this
|
||||
//! algorithm, and results will be false if they are not respected.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal (the same TShape, location and orientation) faces are taken into calculation only once.
|
||||
Standard_EXPORT static void VolumeProperties (const TopoDS_Shape& S, GProp_GProps& VProps, const Standard_Boolean OnlyClosed = Standard_False, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared a is special flag, which allows taking in calculation
|
||||
//! shared topological entities or not.
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal
|
||||
//! (the same TShape, location and orientation) faces are taken
|
||||
//! into calculation only once.
|
||||
//! UseTriangulation is a special flag, which defines preferable
|
||||
//! source of geometry data. If UseTriangulation = Standard_False,
|
||||
//! exact geometry objects (surfaces) are used,
|
||||
//! otherwise face triangulations are used first.
|
||||
Standard_EXPORT static void VolumeProperties(const TopoDS_Shape& S, GProp_GProps& VProps,
|
||||
const Standard_Boolean OnlyClosed = Standard_False,
|
||||
const Standard_Boolean SkipShared = Standard_False,
|
||||
const Standard_Boolean UseTriangulation = Standard_False);
|
||||
|
||||
//! Updates <VProps> with the shape <S>, that contains its pricipal properties.
|
||||
//! The volume properties of all the FORWARD and REVERSED faces in <S> are computed.
|
||||
@@ -183,9 +216,14 @@ public:
|
||||
//! for two successive steps of adaptive integration.
|
||||
//! Method returns estimation of relative error reached for whole shape.
|
||||
//! WARNING: if Eps > 0.001 algorithm performs non-adaptive integration.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal (the same TShape, location and orientation) faces are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real VolumeProperties (const TopoDS_Shape& S, GProp_GProps& VProps, const Standard_Real Eps, const Standard_Boolean OnlyClosed = Standard_False, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared is a special flag, which allows taking in calculation shared
|
||||
//! topological entities or not.
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal
|
||||
//! (the same TShape, location and orientation)
|
||||
//! faces are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real VolumeProperties (const TopoDS_Shape& S, GProp_GProps& VProps,
|
||||
const Standard_Real Eps, const Standard_Boolean OnlyClosed = Standard_False,
|
||||
const Standard_Boolean SkipShared = Standard_False);
|
||||
|
||||
//! Updates <VProps> with the shape <S>, that contains its pricipal properties.
|
||||
//! The volume properties of all the FORWARD and REVERSED faces in <S> are computed.
|
||||
@@ -198,13 +236,27 @@ public:
|
||||
//! that is used for properties computation.
|
||||
//! Method returns estimation of relative error reached for whole shape.
|
||||
//! Returns negative value if the computation is failed.
|
||||
//! SkipShared is special flag, which allows to take in calculation shared topological entities or not
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal (the same TShape, location and orientation) faces are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real VolumePropertiesGK (const TopoDS_Shape& S, GProp_GProps& VProps, const Standard_Real Eps = 0.001, const Standard_Boolean OnlyClosed = Standard_False, const Standard_Boolean IsUseSpan = Standard_False, const Standard_Boolean CGFlag = Standard_False, const Standard_Boolean IFlag = Standard_False, const Standard_Boolean SkipShared = Standard_False);
|
||||
//! SkipShared is a special flag, which allows taking in calculation
|
||||
//! shared topological entities or not.
|
||||
//! For ex., if SkipShared = True, the volumes formed by the equal
|
||||
//! (the same TShape, location and orientation) faces are taken into calculation only once.
|
||||
Standard_EXPORT static Standard_Real VolumePropertiesGK (const TopoDS_Shape& S,
|
||||
GProp_GProps& VProps,
|
||||
const Standard_Real Eps = 0.001,
|
||||
const Standard_Boolean OnlyClosed = Standard_False,
|
||||
const Standard_Boolean IsUseSpan = Standard_False,
|
||||
const Standard_Boolean CGFlag = Standard_False,
|
||||
const Standard_Boolean IFlag = Standard_False,
|
||||
const Standard_Boolean SkipShared = Standard_False);
|
||||
|
||||
Standard_EXPORT static Standard_Real VolumePropertiesGK (const TopoDS_Shape& S, GProp_GProps& VProps, const gp_Pln& thePln, const Standard_Real Eps = 0.001, const Standard_Boolean OnlyClosed = Standard_False, const Standard_Boolean IsUseSpan = Standard_False, const Standard_Boolean CGFlag = Standard_False, const Standard_Boolean IFlag = Standard_False, const Standard_Boolean SkipShared = Standard_False);
|
||||
|
||||
|
||||
Standard_EXPORT static Standard_Real VolumePropertiesGK (const TopoDS_Shape& S,
|
||||
GProp_GProps& VProps,
|
||||
const gp_Pln& thePln, const Standard_Real Eps = 0.001,
|
||||
const Standard_Boolean OnlyClosed = Standard_False,
|
||||
const Standard_Boolean IsUseSpan = Standard_False,
|
||||
const Standard_Boolean CGFlag = Standard_False,
|
||||
const Standard_Boolean IFlag = Standard_False,
|
||||
const Standard_Boolean SkipShared = Standard_False);
|
||||
|
||||
|
||||
protected:
|
||||
|
236
src/BRepGProp/BRepGProp_MeshCinert.cxx
Normal file
236
src/BRepGProp/BRepGProp_MeshCinert.cxx
Normal file
@@ -0,0 +1,236 @@
|
||||
// Copyright (c) 2018 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_MeshCinert.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <math.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : BRepGProp_MeshCinert
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
BRepGProp_MeshCinert::BRepGProp_MeshCinert()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetLocation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshCinert::SetLocation(const gp_Pnt& CLocation)
|
||||
{
|
||||
loc = CLocation;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshCinert::Perform(const TColgp_Array1OfPnt& theNodes)
|
||||
{
|
||||
|
||||
Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
|
||||
dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0;
|
||||
|
||||
Standard_Integer Order = 2;
|
||||
|
||||
Standard_Real ds;
|
||||
Standard_Real ur, um, u;
|
||||
Standard_Real x, y, z;
|
||||
Standard_Real xloc, yloc, zloc;
|
||||
Standard_Real Upper;
|
||||
gp_XYZ P, D;
|
||||
|
||||
math_Vector GaussP (1, Order);
|
||||
math_Vector GaussW (1, Order);
|
||||
|
||||
math::GaussPoints (Order,GaussP);
|
||||
math::GaussWeights (Order,GaussW);
|
||||
|
||||
Standard_Integer nIndex = 0;
|
||||
|
||||
for(nIndex = 1; nIndex < theNodes.Length(); nIndex++)
|
||||
{
|
||||
const gp_XYZ& aP1 = theNodes(nIndex).XYZ();
|
||||
const gp_XYZ& aP2 = theNodes(nIndex + 1).XYZ();
|
||||
Standard_Real dimLocal, IxLocal, IyLocal, IzLocal, IxxLocal, IyyLocal, IzzLocal, IxyLocal, IxzLocal, IyzLocal;
|
||||
dimLocal = IxLocal = IyLocal = IzLocal = IxxLocal = IyyLocal = IzzLocal = IxyLocal = IxzLocal = IyzLocal = 0.0;
|
||||
|
||||
loc.Coord (xloc, yloc, zloc);
|
||||
|
||||
Standard_Integer i;
|
||||
|
||||
Upper = (aP2 - aP1).Modulus();
|
||||
if (Upper < gp::Resolution())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
um = 0.5 * Upper;
|
||||
ur =um;
|
||||
D = (aP2 - aP1) / Upper;
|
||||
|
||||
for (i = 1; i <= Order; i++) {
|
||||
u = um + ur * GaussP (i);
|
||||
P = aP1 + u * D;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PreparePolygon
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshCinert::PreparePolygon(const TopoDS_Edge& theE,
|
||||
Handle(TColgp_HArray1OfPnt)& thePolyg)
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
const Handle(Poly_Polygon3D)& aPolyg = BRep_Tool::Polygon3D(theE, aLoc);
|
||||
if (!aPolyg.IsNull())
|
||||
{
|
||||
const TColgp_Array1OfPnt& aNodes = aPolyg->Nodes();
|
||||
thePolyg = new TColgp_HArray1OfPnt(1, aNodes.Length());
|
||||
Standard_Integer i;
|
||||
if (aLoc.IsIdentity())
|
||||
{
|
||||
for (i = 1; i <= aNodes.Length(); ++i)
|
||||
{
|
||||
thePolyg->SetValue(i, aNodes(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const gp_Trsf& aTr = aLoc.Transformation();
|
||||
for (i = 1; i <= aNodes.Length(); ++i)
|
||||
{
|
||||
thePolyg->SetValue(i, aNodes.Value(i).Transformed(aTr));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Try to get PolygonOnTriangulation
|
||||
Handle(Poly_Triangulation) aTri;
|
||||
Handle(Poly_PolygonOnTriangulation) aPOnTri;
|
||||
BRep_Tool::PolygonOnTriangulation(theE, aPOnTri, aTri, aLoc);
|
||||
if (!aPOnTri.IsNull())
|
||||
{
|
||||
Standard_Integer aNbNodes = aPOnTri->NbNodes();
|
||||
thePolyg = new TColgp_HArray1OfPnt(1, aNbNodes);
|
||||
const TColStd_Array1OfInteger& aNodeInds = aPOnTri->Nodes();
|
||||
const TColgp_Array1OfPnt& aNodes = aTri->Nodes();
|
||||
Standard_Integer i;
|
||||
if (aLoc.IsIdentity())
|
||||
{
|
||||
for (i = 1; i <= aNbNodes; ++i)
|
||||
{
|
||||
thePolyg->SetValue(i, aNodes(aNodeInds(i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const gp_Trsf& aTr = aLoc.Transformation();
|
||||
for (i = 1; i <= aNbNodes; ++i)
|
||||
{
|
||||
thePolyg->SetValue(i, aNodes.Value(aNodeInds(i)).Transformed(aTr));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//
|
||||
//Try to get Polygon2D on Surface
|
||||
Handle(Poly_Polygon2D) aPolyg2D;
|
||||
Handle(Geom_Surface) aS;
|
||||
BRep_Tool::PolygonOnSurface(theE, aPolyg2D, aS, aLoc);
|
||||
if (!aPolyg2D.IsNull())
|
||||
{
|
||||
Standard_Integer aNbNodes = aPolyg2D->NbNodes();
|
||||
thePolyg = new TColgp_HArray1OfPnt(1, aNbNodes);
|
||||
const TColgp_Array1OfPnt2d& aNodes2D = aPolyg2D->Nodes();
|
||||
Standard_Integer i;
|
||||
if (aLoc.IsIdentity())
|
||||
{
|
||||
for (i = 1; i <= aNbNodes; ++i)
|
||||
{
|
||||
const gp_Pnt2d& aP2d = aNodes2D(i);
|
||||
gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y());
|
||||
thePolyg->SetValue(i, aP);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const gp_Trsf& aTr = aLoc.Transformation();
|
||||
for (i = 1; i <= aNbNodes; ++i)
|
||||
{
|
||||
const gp_Pnt2d& aP2d = aNodes2D(i);
|
||||
gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y());
|
||||
aP.Transform(aTr);
|
||||
thePolyg->SetValue(i, aP);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
67
src/BRepGProp/BRepGProp_MeshCinert.hxx
Normal file
67
src/BRepGProp/BRepGProp_MeshCinert.hxx
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2018 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.
|
||||
|
||||
#ifndef _BRepGProp_MeshCinert_HeaderFile
|
||||
#define _BRepGProp_MeshCinert_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
class gp_Pnt;
|
||||
class TopoDS_Edge;
|
||||
|
||||
|
||||
|
||||
//! Computes the global properties of
|
||||
//! of polylines represented by set of points.
|
||||
//! This class is used for computation of global
|
||||
//! properties of edge, which has no exact geometry
|
||||
//! (3d or 2d curve), but has any of allowed
|
||||
//! polygons.
|
||||
//!
|
||||
class BRepGProp_MeshCinert : public GProp_GProps
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
Standard_EXPORT BRepGProp_MeshCinert();
|
||||
|
||||
Standard_EXPORT void SetLocation (const gp_Pnt& CLocation);
|
||||
|
||||
//! Computes the global properties of
|
||||
//! of polylines represented by set of points.
|
||||
Standard_EXPORT void Perform(const TColgp_Array1OfPnt& theNodes);
|
||||
|
||||
//! Prepare set of 3d points on base of any available edge polygons:
|
||||
//! 3D polygon, polygon on triangulation, 2d polygon on surface
|
||||
//! If edge has no polygons, array thePolyg is left unchanged
|
||||
Standard_EXPORT static void PreparePolygon(const TopoDS_Edge& theE, Handle(TColgp_HArray1OfPnt)& thePolyg);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _BRepGProp_MeshCinert_HeaderFile
|
291
src/BRepGProp/BRepGProp_MeshProps.cxx
Normal file
291
src/BRepGProp/BRepGProp_MeshProps.cxx
Normal file
@@ -0,0 +1,291 @@
|
||||
// Copyright (c) 2018 OPEN CASCADE SAS
|
||||
// This file is part of commercial software by OPEN CASCADE SAS,
|
||||
// furnished in accordance with the terms and conditions of the contract
|
||||
// and with the inclusion of this copyright notice.
|
||||
// This file or any part thereof may not be provided or otherwise
|
||||
// made available to any third party.
|
||||
//
|
||||
// No ownership title to the software is transferred hereby.
|
||||
//
|
||||
// OPEN CASCADE SAS makes no representation or warranties with respect to the
|
||||
// performance of this software, and specifically disclaims any responsibility
|
||||
// for any damages, special or consequential, connected with its use.
|
||||
|
||||
#include <BRepGProp_MeshProps.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_Triangle.hxx>
|
||||
#include<ElSLib.hxx>
|
||||
#include<gp_Ax3.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <GProp.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : CalculateElSProps
|
||||
//purpose : Calculate one Gauss point for surface properties
|
||||
// of triangle p1, p2, p3
|
||||
// relatively point Apex
|
||||
//=======================================================================
|
||||
static void CalculateElSProps(const Standard_Real x,
|
||||
const Standard_Real y,
|
||||
const Standard_Real z, const Standard_Real ds, Standard_Real* GProps)
|
||||
{
|
||||
//GProps[0] = Volume
|
||||
// Static moments of inertia.
|
||||
//GProps[1] = Ix, GProps[2] = Iy, GProps[3] = Iz
|
||||
//Matrix of moments of inertia.
|
||||
//GProps[4] = Ixx, GProps[5] = Iyy, GProps[6] = Izz,
|
||||
//GProps[7] = Ixy, aGProps[8] = Ixz, GProps[9] = Iyz,
|
||||
//
|
||||
Standard_Real x2, y2, z2;
|
||||
x2 = x * x;
|
||||
y2 = y * y;
|
||||
z2 = z * z;
|
||||
|
||||
GProps[0] += ds; //Area
|
||||
GProps[1] += x * ds; //Ix
|
||||
GProps[2] += y * ds; //Iy
|
||||
GProps[3] += z * ds; //Iz
|
||||
//
|
||||
GProps[7] += x * y * ds; //Ixy
|
||||
GProps[8] += x * z * ds; //Ixz
|
||||
GProps[9] += y * z * ds; //Iyz
|
||||
GProps[4] += (y2 + z2) * ds; //Ixx
|
||||
GProps[5] += (x2 + z2) * ds; //Iyy
|
||||
GProps[6] += (x2 + y2) * ds; //Izz
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CalculateElVProps
|
||||
//purpose : Calculate one Gauss point for volume properties of pyramid,
|
||||
// based on triangle p1, p2, p3 with apex Apex
|
||||
//=======================================================================
|
||||
static void CalculateElVProps(const Standard_Real x,
|
||||
const Standard_Real y,
|
||||
const Standard_Real z, const Standard_Real dv, Standard_Real* GProps)
|
||||
{
|
||||
Standard_Real x2, y2, z2;
|
||||
x2 = x * x;
|
||||
y2 = y * y;
|
||||
z2 = z * z;
|
||||
GProps[0] += dv / 3.0; //Volume
|
||||
GProps[1] += 0.25 * x * dv; //Ix
|
||||
GProps[2] += 0.25 * y * dv; //Iy
|
||||
GProps[3] += 0.25 * z * dv; //Iz
|
||||
Standard_Real dv1 = 0.2 * dv;
|
||||
GProps[7] += x * y * dv1; //Ixy
|
||||
GProps[8] += x * z * dv1; //Ixz
|
||||
GProps[9] += y * z * dv1; //Iyz
|
||||
GProps[4] += (y2 + z2) * dv1; //Ixx
|
||||
GProps[5] += (x2 + z2) * dv1; //Iyy
|
||||
GProps[6] += (x2 + y2) * dv1; //Izz
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CalculateProps
|
||||
//purpose : Calculate global surface properties of triangle
|
||||
// or volume properties of pyramid, based on triangle
|
||||
// p1, p2, p3 with apex Apex by Gauss integration over triangle area.
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshProps::CalculateProps(const gp_Pnt& p1, const gp_Pnt& p2,
|
||||
const gp_Pnt& p3,
|
||||
const gp_Pnt& Apex,
|
||||
const Standard_Boolean isVolume,
|
||||
Standard_Real GProps[10],
|
||||
const Standard_Integer NbGaussPoints,
|
||||
const Standard_Real* GaussPnts)
|
||||
{
|
||||
//GProps[0] = Volume
|
||||
// Static moments of inertia.
|
||||
//GProps[1] = Ix, GProps[2] = Iy, GProps[3] = Iz
|
||||
//Matrix of moments of inertia.
|
||||
//GProps[4] = Ixx, GProps[5] = Iyy, GProps[6] = Izz,
|
||||
//GProps[7] = Ixy, aGProps[8] = Ixz, GProps[9] = Iyz,
|
||||
//
|
||||
|
||||
//Define plane and coordinates of triangle nodes on plane
|
||||
gp_Vec aV12(p2, p1);
|
||||
gp_Vec aV23(p3, p2);
|
||||
gp_Vec aNorm = aV12 ^ aV23;
|
||||
Standard_Real aDet = aNorm.Magnitude();
|
||||
if (aDet <= gp::Resolution())
|
||||
{
|
||||
return;
|
||||
}
|
||||
gp_XYZ aCenter = (p1.XYZ() + p2.XYZ() + p3.XYZ()) / 3.;
|
||||
gp_Pnt aPC(aCenter);
|
||||
gp_Dir aDN(aNorm);
|
||||
gp_Ax3 aPosPln(aPC, aDN);
|
||||
//Coordinates of nodes on plane
|
||||
Standard_Real x1, y1, x2, y2, x3, y3;
|
||||
ElSLib::PlaneParameters(aPosPln, p1, x1, y1);
|
||||
ElSLib::PlaneParameters(aPosPln, p2, x2, y2);
|
||||
ElSLib::PlaneParameters(aPosPln, p3, x3, y3);
|
||||
//
|
||||
Standard_Real l1, l2; //barycentriche coordinates
|
||||
Standard_Real x, y, z;
|
||||
Standard_Real w; //weight
|
||||
Standard_Integer i;
|
||||
for (i = 0; i < NbGaussPoints; ++i)
|
||||
{
|
||||
Standard_Integer ind = 3 * i;
|
||||
l1 = GaussPnts[ind];
|
||||
l2 = GaussPnts[ind + 1];
|
||||
w = GaussPnts[ind + 2];
|
||||
w *= aDet;
|
||||
x = l1*(x1 - x3) + l2*(x2 - x3) + x3;
|
||||
y = l1*(y1 - y3) + l2*(y2 - y3) + y3;
|
||||
gp_Pnt aP = ElSLib::PlaneValue(x, y, aPosPln);
|
||||
x = aP.X() - Apex.X();
|
||||
y = aP.Y() - Apex.Y();
|
||||
z = aP.Z() - Apex.Z();
|
||||
//
|
||||
if (isVolume)
|
||||
{
|
||||
Standard_Real xn = aDN.X() * w;
|
||||
Standard_Real yn = aDN.Y() * w;
|
||||
Standard_Real zn = aDN.Z() * w;
|
||||
Standard_Real dv = x * xn + y * yn + z * zn;
|
||||
CalculateElVProps(x, y, z, dv, GProps);
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real ds = w;
|
||||
CalculateElSProps(x, y, z, ds, GProps);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshProps::Perform(const Handle(Poly_Triangulation)& theMesh,
|
||||
const TopLoc_Location& theLoc,
|
||||
const TopAbs_Orientation theOri)
|
||||
{
|
||||
if (theLoc.IsIdentity())
|
||||
{
|
||||
Perform(theMesh->Nodes(), theMesh->Triangles(), theOri);
|
||||
}
|
||||
else
|
||||
{
|
||||
const gp_Trsf& aTr = theLoc.Transformation();
|
||||
//
|
||||
Standard_Boolean isToCopy = aTr.ScaleFactor()*aTr.HVectorialPart().Determinant() < 0. ||
|
||||
Abs(Abs(aTr.ScaleFactor()) - 1.) > gp::Resolution();
|
||||
if (isToCopy)
|
||||
{
|
||||
TColgp_Array1OfPnt aNodes(1, theMesh->NbNodes());
|
||||
const TColgp_Array1OfPnt& aMeshNodes = theMesh->Nodes();
|
||||
Standard_Integer i;
|
||||
for (i = 1; i <= aMeshNodes.Length(); ++i)
|
||||
{
|
||||
aNodes(i) = aMeshNodes.Value(i).Transformed(aTr);
|
||||
}
|
||||
Perform(aNodes, theMesh->Triangles(), theOri);
|
||||
return;
|
||||
}
|
||||
//
|
||||
gp_Trsf aTrInv = aTr.Inverted();
|
||||
gp_Pnt loc_save = loc;
|
||||
loc.Transform(aTrInv);
|
||||
Perform(theMesh->Nodes(), theMesh->Triangles(), theOri);
|
||||
//Computes the inertia tensor at mesh gravity center
|
||||
gp_Mat HMat, inertia0;
|
||||
gp_Pnt g0 = g;
|
||||
g.SetXYZ(g.XYZ() + loc.XYZ());
|
||||
if (g0.XYZ().Modulus() > gp::Resolution())
|
||||
{
|
||||
GProp::HOperator(g, loc, dim, HMat);
|
||||
inertia0 = inertia - HMat;
|
||||
}
|
||||
else
|
||||
{
|
||||
inertia0 = inertia;
|
||||
}
|
||||
//Transform inertia tensor for rotation
|
||||
gp_Mat HVec = aTrInv.HVectorialPart();
|
||||
gp_Mat HVecT = HVec.Transposed();
|
||||
HVecT.Multiply(inertia0);
|
||||
inertia0 = HVecT.Multiplied(HVec);
|
||||
//Put gravity center in true position of mesh
|
||||
g.Transform(aTr);
|
||||
g0 = g;
|
||||
g.SetXYZ(g.XYZ() - loc_save.XYZ());
|
||||
loc = loc_save;
|
||||
//
|
||||
//Computes the inertia tensor for loc
|
||||
GProp::HOperator(g0, loc, dim, HMat);
|
||||
inertia = inertia0 + HMat;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepGProp_MeshProps::Perform(const TColgp_Array1OfPnt& theNodes,
|
||||
const Poly_Array1OfTriangle& theTriangles,
|
||||
const TopAbs_Orientation theOri)
|
||||
{
|
||||
//
|
||||
// Gauss points for barycentriche coordinates
|
||||
static const Standard_Real GPtsWg[] =
|
||||
{ 1. / 6., 1. / 6., 1. / 6., /*3 points*/
|
||||
2. / 3., 1. / 6., 1. / 6.,
|
||||
1. / 6., 2. / 3., 1. / 6. };
|
||||
//
|
||||
Standard_Integer aNbGaussPoints = 3;
|
||||
|
||||
// Array to store global properties
|
||||
Standard_Real aGProps[10] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0 };
|
||||
//aGProps[0] = Volume
|
||||
// Static moments of inertia.
|
||||
//aGProps[1] = Ix, aGProps[2] = Iy, aGProps[3] = Iz
|
||||
//Matrix of moments of inertia.
|
||||
//aGProps[4] = Ixx, aGProps[5] = Iyy, aGProps[6] = Izz,
|
||||
//aGProps[7] = Ixy, aGProps[8] = Ixz, aGProps[9] = Iyz,
|
||||
|
||||
Standard_Boolean isVolume = myType == Vinert;
|
||||
Standard_Integer i;
|
||||
Standard_Integer n1, n2, n3; //node indeces
|
||||
for (i = theTriangles.Lower(); i <= theTriangles.Upper(); ++i)
|
||||
{
|
||||
const Poly_Triangle& aTri = theTriangles(i);
|
||||
aTri.Get(n1, n2, n3);
|
||||
if (theOri == TopAbs_REVERSED)
|
||||
{
|
||||
Standard_Integer nn = n2;
|
||||
n2 = n3;
|
||||
n3 = nn;
|
||||
}
|
||||
// Calculate properties of a pyramid built on face and apex
|
||||
const gp_Pnt& p1 = theNodes(n1);
|
||||
const gp_Pnt& p2 = theNodes(n2);
|
||||
const gp_Pnt& p3 = theNodes(n3);
|
||||
CalculateProps(p1, p2, p3, loc, isVolume, aGProps, aNbGaussPoints, GPtsWg);
|
||||
}
|
||||
|
||||
dim = aGProps[0];
|
||||
if (Abs(dim) >= 1.e-20) //To be consistent with GProp_GProps
|
||||
{
|
||||
g.SetX(aGProps[1] / dim);
|
||||
g.SetY(aGProps[2] / dim);
|
||||
g.SetZ(aGProps[3] / dim);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.SetX(aGProps[1]);
|
||||
g.SetY(aGProps[2]);
|
||||
g.SetZ(aGProps[3]);
|
||||
}
|
||||
inertia(1, 1) = aGProps[4];
|
||||
inertia(1, 2) = -aGProps[7];
|
||||
inertia(1, 3) = -aGProps[8];
|
||||
inertia(2, 1) = -aGProps[7];
|
||||
inertia(2, 2) = aGProps[5];
|
||||
inertia(2, 3) = -aGProps[9];
|
||||
inertia(3, 1) = -aGProps[8];
|
||||
inertia(3, 2) = -aGProps[9];
|
||||
inertia(3, 3) = aGProps[6];
|
||||
}
|
90
src/BRepGProp/BRepGProp_MeshProps.hxx
Normal file
90
src/BRepGProp/BRepGProp_MeshProps.hxx
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2018 OPEN CASCADE SAS
|
||||
// This file is part of commercial software by OPEN CASCADE SAS,
|
||||
// furnished in accordance with the terms and conditions of the contract
|
||||
// and with the inclusion of this copyright notice.
|
||||
// This file or any part thereof may not be provided or otherwise
|
||||
// made available to any third party.
|
||||
//
|
||||
// No ownership title to the software is transferred hereby.
|
||||
//
|
||||
// OPEN CASCADE SAS makes no representation or warranties with respect to the
|
||||
// performance of this software, and specifically disclaims any responsibility
|
||||
// for any damages, special or consequential, connected with its use.
|
||||
|
||||
#ifndef _BRepGProp_MeshProps_HeaderFile
|
||||
#define _BRepGProp_MeshProps_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <TopAbs_Orientation.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
|
||||
class Poly_Triangulation;
|
||||
class TopLoc_Location;
|
||||
class gp_Pnt;
|
||||
|
||||
|
||||
//! Computes the global properties of a surface mesh. The mesh can be
|
||||
//! interpreted as just a surface or as a piece of volume limited by this surface.
|
||||
class BRepGProp_MeshProps : public GProp_GProps
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Describes types of geometric objects.
|
||||
//! - Vinert is 3D closed region of space delimited with
|
||||
//! Point and surface mesh;
|
||||
//! - Sinert is surface mesh in 3D space.
|
||||
typedef enum { Vinert = 0, Sinert } BRepGProp_MeshObjType;
|
||||
|
||||
//! Constructor takes the type of object.
|
||||
BRepGProp_MeshProps(const BRepGProp_MeshObjType theType) :
|
||||
myType(theType)
|
||||
{}
|
||||
|
||||
//! Sets the point relative which the calculation is to be done
|
||||
void SetLocation(const gp_Pnt& theLocation) { loc = theLocation; }
|
||||
|
||||
//! Computes the global properties of a surface mesh of 3D space.
|
||||
//! Calculation of surface properties is performed by numerical integration
|
||||
//! over triangle surfaces using Gauss cubature formulas.
|
||||
//! Depending on the mesh object type used in constructor this method can
|
||||
//! calculate the surface or volume properties of the mesh.
|
||||
Standard_EXPORT void Perform(const Handle(Poly_Triangulation)& theMesh,
|
||||
const TopLoc_Location& theLoc,
|
||||
const TopAbs_Orientation theOri);
|
||||
|
||||
Standard_EXPORT void Perform(const TColgp_Array1OfPnt& theNodes,
|
||||
const Poly_Array1OfTriangle& theTriangles,
|
||||
const TopAbs_Orientation theOri);
|
||||
|
||||
//! Computes the global properties of triangle {p1, p2, p3} relatively
|
||||
//! point Apex
|
||||
//! If isVolume = true, volume properties are calculated
|
||||
//! otherwise - surface ones
|
||||
Standard_EXPORT static void CalculateProps(const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3,
|
||||
const gp_Pnt& Apex,
|
||||
const Standard_Boolean isVolume,
|
||||
Standard_Real GProps[10],
|
||||
const Standard_Integer NbGaussPoints,
|
||||
const Standard_Real* GaussPnts);
|
||||
|
||||
//! Get type of mesh object
|
||||
BRepGProp_MeshObjType GetMeshObjType() const
|
||||
{
|
||||
return myType;
|
||||
}
|
||||
|
||||
private: //! @name private fields
|
||||
|
||||
|
||||
BRepGProp_MeshObjType myType; //!< Type of geometric object
|
||||
|
||||
};
|
||||
|
||||
#endif // _BRepGProp_MeshProps_HeaderFile
|
@@ -24,3 +24,7 @@ BRepGProp_Vinert.cxx
|
||||
BRepGProp_Vinert.hxx
|
||||
BRepGProp_VinertGK.cxx
|
||||
BRepGProp_VinertGK.hxx
|
||||
BRepGProp_MeshCinert.hxx
|
||||
BRepGProp_MeshCinert.cxx
|
||||
BRepGProp_MeshProps.hxx
|
||||
BRepGProp_MeshProps.cxx
|
||||
|
@@ -41,16 +41,25 @@ Standard_IMPORT Draw_Viewer dout;
|
||||
Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n < 2) {
|
||||
di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z] [-skip] [-full]\n";
|
||||
di << "Compute properties of the shape\n";
|
||||
di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z] [-skip] [-full] [-tri]\n";
|
||||
di << "Compute properties of the shape, exact geometry (curves, surfaces) or\n";
|
||||
di << "some discrete data (polygons, triangulations) can be used for calculations\n";
|
||||
di << "The epsilon, if given, defines relative precision of computation\n";
|
||||
di << "The \"closed\" flag, if present, do computation only closed shells of the shape\n";
|
||||
di << "The centroid coordinates will be put to DRAW variables x y z (if given)\n";
|
||||
di << "Shared entities will be take in account only one time in the skip mode\n";
|
||||
di << "All values are outputted with the full precision in the full mode.\n\n";
|
||||
di << "All values are outputted with the full precision in the full mode.\n";
|
||||
di << "Preferable source of geometry data are triangulations in case if it exists, if the -tri key is used.\n";
|
||||
di << "If epsilon is given, exact geometry (curves, surfaces) are used for calculations independently of using key -tri\n\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Standard_Boolean UseTriangulation = Standard_False;
|
||||
if (n >= 2 && strcmp(a[n - 1], "-tri") == 0)
|
||||
{
|
||||
UseTriangulation = Standard_True;
|
||||
--n;
|
||||
}
|
||||
Standard_Boolean isFullMode = Standard_False;
|
||||
if (n >= 2 && strcmp(a[n-1], "-full") == 0)
|
||||
{
|
||||
@@ -86,11 +95,11 @@ Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
||||
}
|
||||
else {
|
||||
if (*a[0] == 'l')
|
||||
BRepGProp::LinearProperties(S,G,SkipShared);
|
||||
BRepGProp::LinearProperties(S, G, SkipShared, UseTriangulation);
|
||||
else if (*a[0] == 's')
|
||||
BRepGProp::SurfaceProperties(S,G,SkipShared);
|
||||
BRepGProp::SurfaceProperties(S, G, SkipShared, UseTriangulation);
|
||||
else
|
||||
BRepGProp::VolumeProperties(S,G,onlyClosed,SkipShared);
|
||||
BRepGProp::VolumeProperties(S,G,onlyClosed,SkipShared, UseTriangulation);
|
||||
}
|
||||
|
||||
gp_Pnt P = G.CentreOfMass();
|
||||
@@ -313,6 +322,7 @@ Standard_Integer vpropsgk(Draw_Interpretor& di, Standard_Integer n, const char**
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GPropCommands
|
||||
//purpose :
|
||||
@@ -328,11 +338,11 @@ void BRepTest::GPropCommands(Draw_Interpretor& theCommands)
|
||||
|
||||
const char* g = "Global properties";
|
||||
theCommands.Add("lprops",
|
||||
"lprops name [x y z] [-skip] [-full] : compute linear properties",
|
||||
"lprops name [x y z] [-skip] [-full] [-tri]: compute linear properties",
|
||||
__FILE__, props, g);
|
||||
theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-skip] [-full] :\n"
|
||||
theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-skip] [-full] [-tri]:\n"
|
||||
" compute surfacic properties", __FILE__, props, g);
|
||||
theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-skip] [-full] :\n"
|
||||
theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-skip] [-full] [-tri]:\n"
|
||||
" compute volumic properties", __FILE__, props, g);
|
||||
|
||||
theCommands.Add("vpropsgk",
|
||||
|
@@ -826,6 +826,43 @@ void BRepTools::Clean(const TopoDS_Shape& theShape)
|
||||
aBuilder.UpdateEdge (aEdge, aNullPoly3d);
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CleanGeometry
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void BRepTools::CleanGeometry(const TopoDS_Shape& theShape)
|
||||
{
|
||||
if (theShape.IsNull())
|
||||
return;
|
||||
|
||||
BRep_Builder aBuilder;
|
||||
|
||||
for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
TopLoc_Location aLocation;
|
||||
const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
|
||||
const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation);
|
||||
|
||||
for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current());
|
||||
aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface,
|
||||
aLocation, BRep_Tool::Tolerance(anEdge));
|
||||
}
|
||||
|
||||
aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace));
|
||||
}
|
||||
|
||||
for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current());
|
||||
|
||||
aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(),
|
||||
TopLoc_Location(), BRep_Tool::Tolerance(anEdge));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveUnusedPCurves
|
||||
|
@@ -155,6 +155,9 @@ public:
|
||||
//! edges.
|
||||
Standard_EXPORT static void Clean (const TopoDS_Shape& S);
|
||||
|
||||
//! Removes geometry (curves and surfaces) from all edges and faces of the shape
|
||||
Standard_EXPORT static void CleanGeometry(const TopoDS_Shape& theShape);
|
||||
|
||||
//! Removes all the pcurves of the edges of <S> that
|
||||
//! refer to surfaces not belonging to any face of <S>
|
||||
Standard_EXPORT static void RemoveUnusedPCurves (const TopoDS_Shape& S);
|
||||
|
@@ -370,11 +370,22 @@ static Standard_Integer triangles(Draw_Interpretor& ,
|
||||
static Standard_Integer tclean(Draw_Interpretor& ,
|
||||
Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n < 1) return 1;
|
||||
|
||||
for (Standard_Integer i = 1; i < n; i++) {
|
||||
if (n == 1) return 1;
|
||||
|
||||
Standard_Integer aStart = 1;
|
||||
Standard_Boolean toRemoveGeometry = Standard_False;
|
||||
if (strcmp(a[1], "-geom") == 0)
|
||||
{
|
||||
aStart++;
|
||||
toRemoveGeometry = Standard_True;
|
||||
}
|
||||
|
||||
for (Standard_Integer i = aStart; i < n; i++) {
|
||||
TopoDS_Shape S = DBRep::Get(a[i]);
|
||||
BRepTools::Clean(S);
|
||||
if (toRemoveGeometry)
|
||||
BRepTools::CleanGeometry(S);
|
||||
else
|
||||
BRepTools::Clean(S);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1412,7 +1423,10 @@ void DBRep::BasicCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("hlr" ,"[no]hlr, rg1, rgn, hid, ang",__FILE__,hlr ,g);
|
||||
theCommands.Add("vori","vori [name1 ...], edges are colored by orientation (see vconn)",__FILE__,dispor,g);
|
||||
theCommands.Add("triangles", "triangles [name1]..., display triangles of shapes if exists",__FILE__, triangles, g);
|
||||
theCommands.Add("tclean", "tclean [name1]..., erase triangulations and polygons on triangulations from shapes",__FILE__, tclean, g);
|
||||
theCommands.Add("tclean", "tclean [-geom] [name1]..., depending on using or not key -geom, \n"
|
||||
"\t erase geometry objects from shapes - key is used or \n"
|
||||
"\t erase triangulations and polygons on triangulations from shapes - key is omitted \n",
|
||||
__FILE__, tclean, g);
|
||||
theCommands.Add("polygons", "polygons [name1]..., display polygons of shapes if exists",__FILE__, polygons, g);
|
||||
theCommands.Add("vconn","vconn [name1 ...] , edges are colored by number of faces (see vori)",__FILE__,dispor,g);
|
||||
theCommands.Add("discretisation","discretisation [nbpoints]",__FILE__,discretisation,g);
|
||||
|
Reference in New Issue
Block a user