Salome HOME
* Use new method to dump the volume and area value in shape dump
[modules/shaper.git] / src / ModelHighAPI / ModelHighAPI_FeatureStore.cpp
index 38d839ed50ca34cd010432fde646df674219baa0..ff5ce54351c21cbf97446b1dc7436480df758a6d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2024  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_Pnt.h>
 
 #include <Locale_Convert.h>
 
-#include <TopoDS_Shape.hxx>
-#include <TopExp_Explorer.hxx>
-
 #include <ios>
 #include <cmath>
+#include <sstream>
+#include <iomanip>
 
-#define PRECISION 6
-#define TOLERANCE (1.e-7)
+#define PRECISION 5
+#define TOLERANCE (1.e-6)
 
 ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(ObjectPtr theObject) {
   storeData(theObject->data(), myAttrs);
@@ -147,6 +147,26 @@ std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data
   return "";
 }
 
+static void dumpFloat(std::ostringstream& theOutput, double x, int nDigits)
+{
+  static double pow10[] = {
+       1.0, 10., 100., 1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8, 1.e9, 
+    1.e10, 1.e11, 1.e12, 1.e13, 1.e14, 1.e16, 1.e17, 1.e18, 1.e19
+  };
+  int numdigits = log10(fabs(x)) + 1;
+  if (numdigits >= nDigits)
+  {
+    int idx = numdigits - nDigits;
+    theOutput << std::fixed << std::setprecision(0) << (0 < idx && idx < 20 ? std::round(x / pow10[idx]) * pow10[idx] : x);
+  }
+  else
+  {
+    int prec = (numdigits < 0 ? nDigits : nDigits - numdigits);
+     theOutput << std::fixed << std::setprecision(prec) << x;
+  }
+}
+
+
 static void dumpArray(std::ostringstream& theOutput, const double theArray[],
                       int theSize, int thePrecision = PRECISION)
 {
@@ -155,6 +175,7 @@ static void dumpArray(std::ostringstream& theOutput, const double theArray[],
       theOutput << " ";
     theOutput << std::fixed << std::setprecision(thePrecision)
               << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]);
+    //dumpFloat(theOutput, (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]), thePrecision);
   }
 }
 
@@ -211,7 +232,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     if (anAttr->text().empty())
       aResult<<anAttr->value();
     else
-      aResult<<anAttr->text();
+      aResult << Locale::Convert::toString(anAttr->text());
   } else if (aType == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
     if (anAttr->id() == "ConstraintValue") {
@@ -230,7 +251,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
       double aVal = anAttr->value();
       dumpArray(aResult, &aVal, 1, aPrecision);
     } else
-      aResult<<anAttr->text();
+      aResult << Locale::Convert::toString(anAttr->text());
   } else if (aType == ModelAPI_AttributeBoolean::typeId()) {
     AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
     // do not dump internal flags of ConstraintAngle
@@ -241,7 +262,12 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
   } else if (aType == ModelAPI_AttributeString::typeId()) {
     AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
     // do not dump solver DOF for sketch as it may be changed unexpectedly
-    if(anAttr->id() == "SolverDOF") {
+    if (anAttr->id() == "SolverDOF") {
+      return "";
+    }
+    // do not dump file path for Image as it is changed after DumpPython
+    if (aFeatOwner->getKind() == "ImportImage" &&
+        anAttr->id() == "file_path") {
       return "";
     }
     aResult<<anAttr->value();
@@ -398,30 +424,35 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
 }
 
 std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape) {
-  TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
-  if (aShape.IsNull()) {
+  if (theShape->isNull()) {
     return "null";
   }
   std::ostringstream aResult;
   // output the number of shapes of different types
-  TopAbs_ShapeEnum aType = TopAbs_COMPOUND;
-  for(; aType <= TopAbs_VERTEX; aType = TopAbs_ShapeEnum((int)aType + 1)) {
-    TopExp_Explorer anExp(aShape, aType);
-    int aCount = 0;
-    for(; anExp.More(); anExp.Next()) aCount++;
-    TopAbs::Print(aType, aResult);
-    aResult<<": "<<aCount<<std::endl;
+  GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPOUND;
+  for (; aType <= GeomAPI_Shape::VERTEX; aType = GeomAPI_Shape::ShapeType((int)aType + 1)) {
+    GeomAPI_ShapeExplorer anExp(theShape, aType);
+    if (anExp.more()) {
+      std::string aTypeStr = anExp.current()->shapeTypeStr();
+      int aCount = 0;
+      for (; anExp.more(); anExp.next()) aCount++;
+      aResult << aTypeStr.c_str() <<  ": " << aCount << std::endl;
+    }
   }
   // 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;
+    dumpFloat(aResult, aVolume, 6);
+    aResult<<std::endl;
+  }
+  double anArea = GeomAlgoAPI_ShapeTools::area(theShape);
+  if (anArea > 1.e-5) {
+    aResult << "Area: ";
+    // volumes of too huge shapes write in the scientific format
+    dumpFloat(aResult, anArea, 6);
+    aResult << std::endl;
   }
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
   aResult<<"Center of mass: ";