0027273: The computation of linear properties on shared shapes is not correct
authorifv <ifv@opencascade.com>
Tue, 22 Mar 2016 11:41:43 +0000 (14:41 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 28 Mar 2016 14:31:20 +0000 (17:31 +0300)
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

src/BRepGProp/BRepGProp.cxx
src/BRepGProp/BRepGProp.hxx
src/BRepTest/BRepTest_GPropCommands.cxx
src/DrawResources/CheckCommands.tcl
tests/bugs/modalg_6/bug27273 [new file with mode: 0644]

index b6a7574..ecaed92 100644 (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;
index 620998f..29a33b0 100644 (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);
 
 
 
index 669227c..edf6e81 100644 (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);
index 430ff14..a8c51e5 100644 (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}"
         }
diff --git a/tests/bugs/modalg_6/bug27273 b/tests/bugs/modalg_6/bug27273
new file mode 100644 (file)
index 0000000..c326776
--- /dev/null
@@ -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