1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0027273: The computation of linear properties on shared shapes is not correct

New flag is inserted in parameters of static methods LinearProperties(...), surfaceProperties(...), volumeProperties(...). This flag defines to skip or not to skip second and next appearance shared topology entities (edges, faces, shells) in properties calculation.
Corresponding Draw commands is modified to take in account new parameter.

Test case for issue CR27273

Add option -skip into checkprops command
This commit is contained in:
ifv 2016-03-22 14:41:43 +03:00 committed by bugmaster
parent 1fbf69bb21
commit fe3e01db81
5 changed files with 198 additions and 54 deletions

View File

@ -26,6 +26,7 @@
#include <TopTools.hxx>
#include <BRep_Tool.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BRepCheck_Shell.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#ifdef OCCT_DEBUG
@ -41,7 +42,7 @@ static gp_Pnt roughBaryCenter(const TopoDS_Shape& S){
return gp_Pnt(xyz);
}
void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps){
void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Boolean SkipShared){
// find the origin
gp_Pnt P(0,0,0);
P.Transform(S.Location());
@ -49,9 +50,14 @@ void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps){
BRepAdaptor_Curve BAC;
Standard_Real eps = Epsilon(1.);
TopTools_MapOfShape anEMap;
TopExp_Explorer ex;
for (ex.Init(S,TopAbs_EDGE); ex.More(); ex.Next()) {
const TopoDS_Edge& aE = TopoDS::Edge(ex.Current());
if(SkipShared && !anEMap.Add(aE))
{
continue;
}
if(!BRep_Tool::IsGeometric(aE))
{
GProp_PGProps aPProps;
@ -72,7 +78,7 @@ void BRepGProp::LinearProperties(const TopoDS_Shape& S, GProp_GProps& SProps){
}
}
static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps){
static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
Standard_Integer i;
#ifdef OCCT_DEBUG
Standard_Integer iErrorMax = 0;
@ -84,9 +90,14 @@ static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Prop
BRepGProp_Face BF;
BRepGProp_Domain BD;
TopTools_MapOfShape aFMap;
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))
{
continue;
}
BF.Load(F);
TopoDS_Iterator aWIter(F);
Standard_Boolean IsNatRestr = !aWIter.More();
@ -114,18 +125,18 @@ static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Prop
#endif
return ErrorMax;
}
void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props){
void BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean SkipShared){
// find the origin
gp_Pnt P(0,0,0);
P.Transform(S.Location());
Props = GProp_GProps(P);
surfaceProperties(S,Props,1.0);
surfaceProperties(S,Props,1.0, SkipShared);
}
Standard_Real BRepGProp::SurfaceProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps){
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);
Standard_Real ErrorMax = surfaceProperties(S,Props,Eps,SkipShared);
return ErrorMax;
}
@ -134,7 +145,7 @@ 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){
static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Real Eps, const Standard_Boolean SkipShared){
Standard_Integer i;
#ifdef OCCT_DEBUG
Standard_Integer iErrorMax = 0;
@ -146,10 +157,26 @@ static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props
BRepGProp_Face BF;
BRepGProp_Domain BD;
TopTools_MapOfShape aFwdFMap;
TopTools_MapOfShape aRvsFMap;
for (ex.Init(S,TopAbs_FACE), i = 1; ex.More(); ex.Next(), i++) {
const TopoDS_Face& F = TopoDS::Face(ex.Current());
if ((F.Orientation() == TopAbs_FORWARD) || (F.Orientation() == TopAbs_REVERSED)){
TopAbs_Orientation anOri = F.Orientation();
Standard_Boolean isFwd = anOri == TopAbs_FORWARD;
Standard_Boolean isRvs = Standard_False;
if(!isFwd)
{
isRvs = anOri == TopAbs_REVERSED;
}
if(SkipShared)
{
if((isFwd && !aFwdFMap.Add(F)) || (isRvs && !aRvsFMap.Add(F)))
{
continue;
}
}
if (isFwd || isRvs){
BF.Load(F);
TopoDS_Iterator aWIter(F);
Standard_Boolean IsNatRestr = !aWIter.More();
@ -179,17 +206,22 @@ 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){
void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared){
// find the origin
gp_Pnt P(0,0,0); P.Transform(S.Location());
Props = GProp_GProps(P);
if(OnlyClosed){
TopTools_MapOfShape aShMap;
TopExp_Explorer ex(S,TopAbs_SHELL);
for (; ex.More(); ex.Next()) {
const TopoDS_Shape& Sh = ex.Current();
if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0);
if(SkipShared && !aShMap.Add(Sh))
{
continue;
}
if(BRep_Tool::IsClosed(Sh)) volumeProperties(Sh,Props,1.0,SkipShared);
}
} else volumeProperties(S,Props,1.0);
} else volumeProperties(S,Props,1.0,SkipShared);
}
//=======================================================================
@ -198,7 +230,7 @@ void BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props, co
//=======================================================================
Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& Props,
const Standard_Real Eps, const Standard_Boolean OnlyClosed)
const Standard_Real Eps, const Standard_Boolean OnlyClosed, const Standard_Boolean SkipShared)
{
// find the origin
gp_Pnt P(0,0,0); P.Transform(S.Location());
@ -209,11 +241,16 @@ Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& P
#endif
Standard_Real ErrorMax = 0.0, Error = 0.0;
if(OnlyClosed){
TopTools_MapOfShape aShMap;
TopExp_Explorer ex(S,TopAbs_SHELL);
for (i = 1; ex.More(); ex.Next(), i++) {
const TopoDS_Shape& Sh = ex.Current();
if(SkipShared && !aShMap.Add(Sh))
{
continue;
}
if(BRep_Tool::IsClosed(Sh)) {
Error = volumeProperties(Sh,Props,Eps);
Error = volumeProperties(Sh,Props,Eps,SkipShared);
if(ErrorMax < Error) {
ErrorMax = Error;
#ifdef OCCT_DEBUG
@ -222,7 +259,7 @@ Standard_Real BRepGProp::VolumeProperties(const TopoDS_Shape& S, GProp_GProps& P
}
}
}
} else ErrorMax = volumeProperties(S,Props,Eps);
} else ErrorMax = volumeProperties(S,Props,Eps,SkipShared);
#ifdef OCCT_DEBUG
if(AffichEps) cout<<"\n\n==================="<<iErrorMax<<":\tMaxEpsVolume = "<<ErrorMax<<"\n";
#endif
@ -242,7 +279,7 @@ static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
const Standard_Real theTol,
const Standard_Boolean IsUseSpan,
const Standard_Boolean CGFlag,
const Standard_Boolean IFlag)
const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
{
TopExp_Explorer anExp;
anExp.Init(theShape, TopAbs_FACE);
@ -256,14 +293,28 @@ static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
BRepGProp_Domain aPropDomain;
Standard_Real aLocalError;
Standard_Real anError = 0.;
TopTools_MapOfShape aFwdFMap;
TopTools_MapOfShape aRvsFMap;
aVProps.SetLocation(aLoc);
for (; anExp.More(); anExp.Next()) {
TopoDS_Face aFace = TopoDS::Face(anExp.Current());
if (aFace.Orientation() == TopAbs_FORWARD ||
aFace.Orientation() == TopAbs_REVERSED) {
TopAbs_Orientation anOri = aFace.Orientation();
Standard_Boolean isFwd = anOri == TopAbs_FORWARD;
Standard_Boolean isRvs = Standard_False;
if(!isFwd)
{
isRvs = anOri == TopAbs_REVERSED;
}
if(SkipShared)
{
if((isFwd && !aFwdFMap.Add(aFace)) || (isRvs && !aRvsFMap.Add(aFace)))
{
continue;
}
}
if (isFwd || isRvs){
aPropFace.Load(aFace);
TopoDS_Iterator aWIter(aFace);
@ -297,7 +348,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
const Standard_Boolean OnlyClosed,
const Standard_Boolean IsUseSpan,
const Standard_Boolean CGFlag,
const Standard_Boolean IFlag)
const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
{
gp_Pnt P(0,0,0);
Standard_Real anError = 0.;
@ -309,11 +360,16 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
// To select closed shells.
TopExp_Explorer anExp;
TopTools_ListOfShape aClosedShells;
TopTools_MapOfShape aShMap;
anExp.Init(S, TopAbs_SHELL);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aShell = anExp.Current();
if(SkipShared && !aShMap.Add(aShell))
{
continue;
}
BRepCheck_Shell aChecker(TopoDS::Shell(aShell));
BRepCheck_Status aStatus = aChecker.Closed(Standard_False);
@ -334,7 +390,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
for (; anIter.More(); anIter.Next()) {
const TopoDS_Shape &aShell = anIter.Value();
aLocalError = volumePropertiesGK(aShell, Props, aTol, IsUseSpan, CGFlag, IFlag);
aLocalError = volumePropertiesGK(aShell, Props, aTol, IsUseSpan, CGFlag, IFlag,SkipShared);
if (aLocalError < 0)
return aLocalError;
@ -343,7 +399,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
}
} else
anError = volumePropertiesGK(S, Props, Eps, IsUseSpan, CGFlag, IFlag);
anError = volumePropertiesGK(S, Props, Eps, IsUseSpan, CGFlag, IFlag,SkipShared);
Standard_Real vol = Props.Mass();
if(vol > Epsilon(1.)) anError /= vol;
@ -361,7 +417,7 @@ static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
const Standard_Real theTol,
const Standard_Boolean IsUseSpan,
const Standard_Boolean CGFlag,
const Standard_Boolean IFlag)
const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
{
TopExp_Explorer anExp;
anExp.Init(theShape, TopAbs_FACE);
@ -375,14 +431,28 @@ static Standard_Real volumePropertiesGK(const TopoDS_Shape &theShape,
BRepGProp_Domain aPropDomain;
Standard_Real aLocalError;
Standard_Real anError = 0.;
TopTools_MapOfShape aFwdFMap;
TopTools_MapOfShape aRvsFMap;
aVProps.SetLocation(aLoc);
for (; anExp.More(); anExp.Next()) {
TopoDS_Face aFace = TopoDS::Face(anExp.Current());
if (aFace.Orientation() == TopAbs_FORWARD ||
aFace.Orientation() == TopAbs_REVERSED) {
TopAbs_Orientation anOri = aFace.Orientation();
Standard_Boolean isFwd = anOri == TopAbs_FORWARD;
Standard_Boolean isRvs = Standard_False;
if(!isFwd)
{
isRvs = anOri == TopAbs_REVERSED;
}
if(SkipShared)
{
if((isFwd && !aFwdFMap.Add(aFace)) || (isRvs && !aRvsFMap.Add(aFace)))
{
continue;
}
}
if (isFwd || isRvs){
aPropFace.Load(aFace);
TopoDS_Iterator aWIter(aFace);
@ -417,7 +487,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
const Standard_Boolean OnlyClosed,
const Standard_Boolean IsUseSpan,
const Standard_Boolean CGFlag,
const Standard_Boolean IFlag)
const Standard_Boolean IFlag, const Standard_Boolean SkipShared)
{
gp_Pnt P(0,0,0);
Standard_Real anError = 0.;
@ -429,11 +499,16 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
// To select closed shells.
TopExp_Explorer anExp;
TopTools_ListOfShape aClosedShells;
TopTools_MapOfShape aShMap;
anExp.Init(S, TopAbs_SHELL);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aShell = anExp.Current();
if(SkipShared && !aShMap.Add(aShell))
{
continue;
}
BRepCheck_Shell aChecker(TopoDS::Shell(aShell));
BRepCheck_Status aStatus = aChecker.Closed(Standard_False);
@ -454,7 +529,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
for (; anIter.More(); anIter.Next()) {
const TopoDS_Shape &aShell = anIter.Value();
aLocalError = volumePropertiesGK(aShell, Props, thePln, aTol, IsUseSpan, CGFlag, IFlag);
aLocalError = volumePropertiesGK(aShell, Props, thePln, aTol, IsUseSpan, CGFlag, IFlag,SkipShared);
if (aLocalError < 0)
return aLocalError;
@ -462,7 +537,7 @@ Standard_Real BRepGProp::VolumePropertiesGK(const TopoDS_Shape &S,
anError += aLocalError;
}
} else
anError = volumePropertiesGK(S, Props, thePln, Eps, IsUseSpan, CGFlag, IFlag);
anError = volumePropertiesGK(S, Props, thePln, Eps, IsUseSpan, CGFlag, IFlag,SkipShared);
Standard_Real vol = Props.Mass();
if(vol > Epsilon(1.)) anError /= vol;

View File

@ -85,7 +85,10 @@ 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.
Standard_EXPORT static void LinearProperties (const TopoDS_Shape& S, GProp_GProps& LProps);
//! 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);
//! Computes the surface global properties of the
//! shape S, i.e. the global properties induced by each
@ -119,7 +122,9 @@ 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.
Standard_EXPORT static void SurfaceProperties (const TopoDS_Shape& S, GProp_GProps& SProps);
//! 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);
//! Updates <SProps> with the shape <S>, that contains its pricipal properties.
//! The surface properties of all the faces in <S> are computed.
@ -129,6 +134,9 @@ 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);
//!
//! Computes the global volume properties of the solid
//! S, and brings them together with the global
@ -161,10 +169,10 @@ public:
//! oriented in a coherent way. Nonetheless, S must be
//! 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.
Standard_EXPORT static Standard_Real SurfaceProperties (const TopoDS_Shape& S, GProp_GProps& SProps, const Standard_Real Eps);
Standard_EXPORT static void VolumeProperties (const TopoDS_Shape& S, GProp_GProps& VProps, const Standard_Boolean OnlyClosed = Standard_False);
//! 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);
//! 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.
@ -175,7 +183,9 @@ 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.
Standard_EXPORT static Standard_Real VolumeProperties (const TopoDS_Shape& S, GProp_GProps& VProps, const Standard_Real Eps, const Standard_Boolean OnlyClosed = Standard_False);
//! 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);
//! 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.
@ -188,9 +198,11 @@ 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.
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);
//! 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);
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);
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);

View File

@ -41,11 +41,12 @@ 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] [-full]\n";
di << "Use: " << a[0] << " shape [epsilon] [c[losed]] [x y z] [-skip] [-full]\n";
di << "Compute properties of the shape\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";
return 1;
}
@ -56,6 +57,12 @@ Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
isFullMode = Standard_True;
--n;
}
Standard_Boolean SkipShared = Standard_False;
if (n >= 2 && strcmp(a[n-1], "-skip") == 0)
{
SkipShared = Standard_True;
--n;
}
TopoDS_Shape S = DBRep::Get(a[1]);
if (S.IsNull()) return 0;
@ -71,19 +78,19 @@ Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
if (witheps){
if (Abs(eps) < Precision::Angular()) return 2;
if (*a[0] == 'l')
BRepGProp::LinearProperties(S,G);
BRepGProp::LinearProperties(S,G,SkipShared);
else if (*a[0] == 's')
eps = BRepGProp::SurfaceProperties(S,G,eps);
eps = BRepGProp::SurfaceProperties(S,G,eps,SkipShared);
else
eps = BRepGProp::VolumeProperties(S,G,eps,onlyClosed);
eps = BRepGProp::VolumeProperties(S,G,eps,onlyClosed,SkipShared);
}
else {
if (*a[0] == 'l')
BRepGProp::LinearProperties(S,G);
BRepGProp::LinearProperties(S,G,SkipShared);
else if (*a[0] == 's')
BRepGProp::SurfaceProperties(S,G);
BRepGProp::SurfaceProperties(S,G,SkipShared);
else
BRepGProp::VolumeProperties(S,G,onlyClosed);
BRepGProp::VolumeProperties(S,G,onlyClosed,SkipShared);
}
gp_Pnt P = G.CentreOfMass();
@ -174,7 +181,7 @@ Standard_Integer props(Draw_Interpretor& di, Standard_Integer n, const char** a)
Standard_Integer vpropsgk(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
if (n < 2) {
di << "Use: " << a[0] << " shape epsilon closed span mode [x y z]\n";
di << "Use: " << a[0] << " shape epsilon closed span mode [x y z] [-skip]\n";
di << "Compute properties of the shape\n";
di << "The epsilon defines relative precision of computation\n";
di << "The \"closed\" flag, if equal 1, causes computation only closed shells of the shape\n";
@ -196,6 +203,12 @@ Standard_Integer vpropsgk(Draw_Interpretor& di, Standard_Integer n, const char**
if (S.IsNull()) return 0;
GProp_GProps G;
Standard_Boolean SkipShared = Standard_False;
if (n >= 2 && strcmp(a[n-1], "-skip") == 0)
{
SkipShared = Standard_True;
--n;
}
Standard_Boolean onlyClosed = Standard_False;
Standard_Boolean isUseSpan = Standard_False;
@ -219,7 +232,7 @@ Standard_Integer vpropsgk(Draw_Interpretor& di, Standard_Integer n, const char**
//aChrono.Reset();
//aChrono.Start();
eps = BRepGProp::VolumePropertiesGK(S, G, eps, onlyClosed, isUseSpan, CGFlag, IFlag);
eps = BRepGProp::VolumePropertiesGK(S, G, eps, onlyClosed, isUseSpan, CGFlag, IFlag, SkipShared);
//aChrono.Stop();
Standard_SStream aSStream0;
@ -315,15 +328,15 @@ void BRepTest::GPropCommands(Draw_Interpretor& theCommands)
const char* g = "Global properties";
theCommands.Add("lprops",
"lprops name [x y z] [-full] : compute linear properties",
"lprops name [x y z] [-skip] [-full] : compute linear properties",
__FILE__, props, g);
theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-full] :\n"
theCommands.Add("sprops", "sprops name [epsilon] [x y z] [-skip] [-full] :\n"
" compute surfacic properties", __FILE__, props, g);
theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-full] :\n"
theCommands.Add("vprops", "vprops name [epsilon] [c[losed]] [x y z] [-skip] [-full] :\n"
" compute volumic properties", __FILE__, props, g);
theCommands.Add("vpropsgk",
"vpropsgk name epsilon closed span mode [x y z] : compute volumic properties",
"vpropsgk name epsilon closed span mode [x y z] [-skip] : compute volumic properties",
__FILE__,
vpropsgk,
g);

View File

@ -503,6 +503,7 @@ help checkprops {
-eps EPSILON: the epsilon defines relative precision of computation
-equal SHAPE: compare area\volume\length of input shapes. Puts error if its are not equal
-notequal SHAPE: compare area\volume\length of input shapes. Puts error if its are equal
-skip: count shared shapes only once, skipping repeatitions
Options -l, -s and -v are independent and can be used in any order. Tolerance epsilon is the same for all options.
}
@ -522,10 +523,12 @@ proc checkprops {shape args} {
set compared_equal_shape -1
set compared_notequal_shape -1
set equal_check 0
set skip 0
set options {{"-eps" epsilon 1}
{"-equal" compared_equal_shape 1}
{"-notequal" compared_notequal_shape 1}}
{"-notequal" compared_notequal_shape 1}
{"-skip" skip 0}}
if { [regexp {\-[not]*equal} $args] } {
lappend options {"-s" area 0}
@ -557,12 +560,18 @@ proc checkprops {shape args} {
set prop "volume"
set equal_check 0
}
set skip_option ""
if { $skip } {
set skip_option "-skip"
}
regexp {Mass +: +([-0-9.+eE]+)} [${CommandName} ${shape} ${epsilon}] full m
regexp {Mass +: +([-0-9.+eE]+)} [eval ${CommandName} ${shape} ${epsilon} $skip_option] full m
if { ${compared_equal_shape} != -1 } {
upvar ${compared_equal_shape} ${compared_equal_shape}
regexp {Mass +: +([-0-9.+eE]+)} [${CommandName} ${compared_equal_shape} ${epsilon}] full compared_m
regexp {Mass +: +([-0-9.+eE]+)} [eval ${CommandName} ${compared_equal_shape} ${epsilon} $skip_option] full compared_m
if { $compared_m != $m } {
puts "Error: Shape ${compared_equal_shape} is not equal to shape ${shape}"
}
@ -570,7 +579,7 @@ proc checkprops {shape args} {
if { ${compared_notequal_shape} != -1 } {
upvar ${compared_notequal_shape} ${compared_notequal_shape}
regexp {Mass +: +([-0-9.+eE]+)} [${CommandName} ${compared_notequal_shape} ${epsilon}] full compared_m
regexp {Mass +: +([-0-9.+eE]+)} [eval ${CommandName} ${compared_notequal_shape} ${epsilon} $skip_option] full compared_m
if { $compared_m == $m } {
puts "Error: Shape ${compared_notequal_shape} is equal shape to ${shape}"
}

View File

@ -0,0 +1,35 @@
puts "============"
puts "OCC27273"
puts "============"
puts ""
###########################################################################################################
# The computation of linear properties on shared shapes is not correct
###########################################################################################################
restore [locate_data_file bug27273_my_shape.brep] a
checkprops a -l 8
checkprops a -l 7 -skip
box b 1 1 1
checkprops b -l 24
checkprops b -l 12 -skip
#Create a compsolid with a face repeated in two solids
plane f 0 0 0 1 0 0
mkface f f 0 1 0 1
prism p1 f 1 0 0
prism p2 f -1 0 0
shape cs Cs
add p1 cs
add p2 cs
checkprops cs -s 12
checkprops cs -s 11 -skip
#Create a compound of two compounds sharing the same solid
box b1 2 0 0 1 1 1
box b2 -2 0 0 1 1 1
compound b1 b c1
compound b2 b c2
compound c1 c2 c3
checkprops c3 -v 4
checkprops c3 -v 3 -skip