1
0
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:
ifv
2018-05-17 15:38:17 +03:00
committed by kgv
parent a820bd4f13
commit 4b114473ef
15 changed files with 1090 additions and 105 deletions

View File

@@ -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

View File

@@ -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:

View 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;
}
}

View 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

View 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];
}

View 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

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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);

View File

@@ -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);