Salome HOME
using a better solution to do compare doubles for shape physical properties master mbs/checkPythonDump V9_13_0a1 V9_13_0a2 65/head
authormbs <martin.bernhard@opencascade.com>
Wed, 5 Jun 2024 18:14:38 +0000 (19:14 +0100)
committermbs <martin.bernhard@opencascade.com>
Wed, 5 Jun 2024 18:14:38 +0000 (19:14 +0100)
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
src/ModelHighAPI/ModelHighAPI_FeatureStore.h
src/SketcherPrs/SketcherPrs_Coincident.cpp
src/SketcherPrs/SketcherPrs_SymbolPrs.cpp
src/SketcherPrs/SketcherPrs_Tools.cpp
src/SketcherPrs/SketcherPrs_Tools.h
test.hdfs/BearingSeparator.py

index e6b73dcdc5fd9c4ad596f67be66abbe6cda71bf4..b404f9e4138a1b106f99b2bb1d105148ac10f89c 100644 (file)
@@ -54,6 +54,7 @@
 #include <sstream>
 #include <iomanip>
 
+#define MAX_PRECISION 12
 #define PRECISION 5
 #define TOLERANCE (1.e-6)
 
@@ -132,7 +133,13 @@ std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data
     if (theAttrs.find(aThisIter->first) == theAttrs.end()) {
       return "original model had no attribute '" + aThisIter->first + "'";
     }
-    if (theAttrs[aThisIter->first] != aThisIter->second) {
+    if (aThisIter->first == "__shape__") {
+      // Compare the shape dump
+      if (theAttrs[aThisIter->first] != aThisIter->second) {
+        return compareShape(theAttrs[aThisIter->first], aThisIter->second);
+      }
+    }
+    else if (theAttrs[aThisIter->first] != aThisIter->second) {
       return "attribute '" + aThisIter->first + "' is different (original != current) '" +
         theAttrs[aThisIter->first] + "' != '" + aThisIter->second + "'";
     }
@@ -147,6 +154,35 @@ std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data
   return "";
 }
 
+std::string ModelHighAPI_FeatureStore::compareShape(const std::string &theOrig, const std::string &theCurrent)
+{
+  std::istringstream issOrig(theOrig), issCurr(theCurrent);
+  std::string strOrig, strCurr;
+
+  // Compare the topological information (as a single string)
+  bool bDifferent = (!std::getline(issOrig, strOrig) || !std::getline(issCurr, strCurr) || strOrig != strCurr);
+
+  if (!bDifferent) {
+    auto cmpDouble = [](double aOrig, double aCurr, double tol=1.e-5) {
+      return (fabs(aOrig) < tol ? fabs(aCurr) < tol : ((fabs(aOrig-aCurr) / fabs(aOrig)) < tol));
+    };
+    auto cmpPoint = [](double pOrig[], double pCurr[], double tol=1.e-4) {
+      return (sqrt((pOrig[0]-pCurr[0])*(pOrig[0]-pCurr[0]) + (pOrig[1]-pCurr[1])*(pOrig[1]-pCurr[1]) + (pOrig[2]-pCurr[2])*(pOrig[2]-pCurr[2])) < tol);
+    };
+
+    // Compare the physical properties (Volume, Area, Center of Mass as doubles with tolerance)
+    double volOrig{}, areaOrig{}, pntOrig[3]={0.,0.,0.};
+    double volCurr{}, areaCurr{}, pntCurr[3]={0.,0.,0.};
+    issOrig >> volOrig >> areaOrig >> pntOrig[0] >> pntOrig[1] >> pntOrig[2];
+    issCurr >> volCurr >> areaCurr >> pntCurr[0] >> pntCurr[1] >> pntCurr[2];
+    bDifferent = (!cmpDouble(volOrig, volCurr) || !cmpDouble(areaOrig, areaCurr) || !cmpPoint(pntOrig, pntCurr));
+  }
+  if (bDifferent)
+    return "attribute '__shape__' is different (original != current) '" + theOrig + "' != '" + theCurrent + "'";
+
+  return "";
+}
+
 static void dumpArray(std::ostringstream& theOutput, const double theArray[],
                       int theSize, int thePrecision = PRECISION)
 {
@@ -415,34 +451,27 @@ std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>&
       std::string aTypeStr = anExp.current()->shapeTypeStr();
       int aCount = 0;
       for (; anExp.more(); anExp.next()) aCount++;
-      aResult << aTypeStr.c_str() <<  ": " << aCount << std::endl;
+      aResult << aCount << " ";
+    }
+    else
+    {
+      aResult << "0 ";
     }
   }
+  aResult << "\n";
   // output the main characteristics
   double aVolume = GeomAlgoAPI_ShapeTools::volume(theShape);
   if (aVolume > 1.e-5) {
-    aResult<<"Volume: ";
-    // volumes of too huge shapes write in the scientific format
-    if (aVolume >= 1.e5)
-      aResult<<std::scientific<<std::setprecision(7);
-    else
-      aResult<<std::fixed<<std::setprecision(3);
-    aResult<<aVolume<<std::endl;
+    aResult << std::fixed << std::setprecision(MAX_PRECISION) << aVolume << " ";
   }
+  else
+    aResult << "0.0 ";
   double anArea = GeomAlgoAPI_ShapeTools::area(theShape);
-  if (anArea > 1.e-5) {
-    aResult << "Area: ";
-    // volumes of too huge shapes write in the scientific format
-    if (anArea >= 1.e5)
-      aResult << std::scientific << std::setprecision(7);
-    else
-      aResult << std::fixed << std::setprecision(3);
-    aResult << anArea << std::endl;
-  }
+  if (anArea > 1.e-5)
+    aResult << std::fixed << std::setprecision(MAX_PRECISION) << anArea << " ";
+  else
+    aResult << "0.0 ";
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
-  aResult<<"Center of mass: ";
-  double aCenterVals[3] = {aCenter->x(), aCenter->y(), aCenter->z()};
-  dumpArray(aResult, aCenterVals, 3, 5);
-  aResult<<std::endl;
+  aResult << std::fixed << std::setprecision(MAX_PRECISION) << aCenter->x() << " " << aCenter->y() << " " << aCenter->z() << std::endl;
   return aResult.str();
 }
index 2d09b68acb0b364b72a5bb783003a7f98f7017d6..c444462519e7890ac43ac5254509487f815a5bdc 100644 (file)
@@ -60,9 +60,13 @@ private:
   /// returns not empty string with error if something is different
   std::string compareData(std::shared_ptr<ModelAPI_Data> theData,
                  std::map<std::string, std::string>& theAttrs);
+  /// compares the main characteristics of a shape
+  /// returns not empty string with error if something is different
+  std::string compareShape(const std::string &theOrig,
+                           const std::string &theCurrent);
   /// dumps the attribute content to the string
   std::string dumpAttr(const AttributePtr& theAttr);
-  /// dumps the shape main charatceristics to string
+  /// dumps the shape main characteristics to string
   std::string dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape);
 };
 
index 65ca0fc0dc337fb9ce24386712c35e80b24d62eb..a4481383804979d8a4872474fdb20f897a60a652 100644 (file)
@@ -143,7 +143,7 @@ void SketcherPrs_Coincident::Compute(
   Quantity_Color aExternalColor = aIsEdge ? aMainColor : Quantity_NOC_YELLOW;
   Quantity_Color aInternalColor = aIsEdge ? Quantity_NOC_YELLOW : aMainColor;
 
-  int aRatio = SketcherPrs_Tools::pixelRatio();
+  const double aRatio = SketcherPrs_Tools::pixelRatio();
 
   // Create the presentation as a combination of standard point markers
   // The external yellow contour
index efc2cc546679cd75a3c0fe28fc1c0e63bb260914..de2569009fbabd56088368c8b54beac231768830 100644 (file)
@@ -178,7 +178,7 @@ Handle(Image_AlienPixMap) SketcherPrs_SymbolPrs::icon()
   aFile += iconName();
   Handle(Image_AlienPixMap) aPixMap = new Image_AlienPixMap();
   if (aPixMap->Load(aFile.c_str())) {
-    int aRatio = SketcherPrs_Tools::pixelRatio();
+    const double aRatio = SketcherPrs_Tools::pixelRatio();
     if (aRatio > 1) {
       Handle(Image_AlienPixMap) aSizedMap = new Image_AlienPixMap();
       Standard_Size aWidth = aPixMap->Width() * aRatio;
index 03fb0c44b416dd1407839cbe963ee8489adba446..841679cf066c2cb0cd6641b5c01c6f46d2126c86 100644 (file)
@@ -288,14 +288,14 @@ std::shared_ptr<GeomAPI_Pnt2d> getProjectionPoint(const FeaturePtr theLine,
   return aLin2d.project(thePoint);
 }
 
-static int MyPixelRatio = 1;
+static double MyPixelRatio = 1.0;
 
-void setPixelRatio(int theRatio)
+void setPixelRatio(const double theRatio)
 {
   MyPixelRatio = theRatio;
 }
 
-int pixelRatio()
+double pixelRatio()
 {
   return MyPixelRatio;
 }
index 254605ba202e67f8105b95c6fbc10d0e93c83da2..da6bac84fc35a3976c83cdf57b43633ebd7c8457 100644 (file)
@@ -180,9 +180,9 @@ namespace SketcherPrs_Tools {
   SKETCHERPRS_EXPORT void sendEmptyPresentationError(ModelAPI_Feature* theFeature,
                                                      const std::string theError);
 
-  SKETCHERPRS_EXPORT void setPixelRatio(int theRatio);
+  SKETCHERPRS_EXPORT void setPixelRatio(const double theRatio);
 
-  SKETCHERPRS_EXPORT int pixelRatio();
+  SKETCHERPRS_EXPORT double pixelRatio();
 };
 
 #endif
index f41b0a15c2677d2373be090c0e2c8a97578a66a0..761590e062bde35c9db3adca62b7b22b3431f587 100644 (file)
@@ -25,7 +25,8 @@ if __name__ == "__main__":
   model.testNbSubShapes(aPartFeature, GeomAPI_Shape.FACE, [115])
   model.testNbSubShapes(aPartFeature, GeomAPI_Shape.EDGE, [890])
   model.testNbSubShapes(aPartFeature, GeomAPI_Shape.VERTEX, [1780])
-  model.testResultsVolumes(aPartFeature, [1311.87963636394])
+  model.testResultsVolumes(aPartFeature, [1311.87963636394], 6)
   model.testResultsAreas(aPartFeature, [3765.24411189])
 
-  assert(model.checkPythonDump())
+from ModelHighAPI import CHECK_NAMING
+assert(model.checkPythonDump(CHECK_NAMING))