Salome HOME
bos #29482 Export of colors and names to STEP.
[modules/shaper.git] / src / ModelHighAPI / ModelHighAPI_FeatureStore.cpp
index fc73000c04b2fb1753ed3a6e2dc68ef128244d02..83653fece020cec6571aaa43da5d7ba6c885a237 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022  CEA/DEN, EDF R&D
 //
 // 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 <TopoDS_Shape.hxx>
-#include <TopExp_Explorer.hxx>
+#include <Locale_Convert.h>
 
 #include <ios>
 #include <cmath>
+#include <sstream>
+#include <iomanip>
 
 #define PRECISION 6
 #define TOLERANCE (1.e-7)
@@ -75,7 +77,8 @@ ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(ObjectPtr theObject) {
 std::string ModelHighAPI_FeatureStore::compare(ObjectPtr theObject) {
   std::string anError = compareData(theObject->data(), myAttrs);
   if (!anError.empty()) {
-    return "Features '" + theObject->data()->name() + "' differ:" + anError;
+    return "Features '" + Locale::Convert::toString(theObject->data()->name()) +
+      "' differ:" + anError;
   }
 
   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
@@ -87,11 +90,13 @@ std::string ModelHighAPI_FeatureStore::compare(ObjectPtr theObject) {
     for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
       anError = compareData((*aRes)->data(), *aResIter);
       if (!anError.empty())
-        return "Results of feature '" + aFeature->name() + "' '" + (*aRes)->data()->name() +
+        return "Results of feature '" + Locale::Convert::toString(aFeature->name()) +
+        "' '" + Locale::Convert::toString((*aRes)->data()->name()) +
         "' differ:" + anError;
     }
     if (aRes != allResults.end()) {
-      return "Current model has more results '" + (*aRes)->data()->name() + "'";
+      return "Current model has more results '" +
+        Locale::Convert::toString((*aRes)->data()->name()) + "'";
     }
     if (aResIter != myRes.end()) {
       return "Original model had more results '" + (*aResIter)["__name__"] + "'";
@@ -104,7 +109,7 @@ void ModelHighAPI_FeatureStore::storeData(std::shared_ptr<ModelAPI_Data> theData
   std::map<std::string, std::string>& theAttrs)
 {
   // store name to keep also this information and output if needed
-  theAttrs["__name__"] = theData->name();
+  theAttrs["__name__"] = Locale::Convert::toString(theData->name());
   std::list<std::shared_ptr<ModelAPI_Attribute> > allAttrs = theData->attributes("");
   std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = allAttrs.begin();
   for(; anAttr != allAttrs.end(); anAttr++) {
@@ -148,7 +153,7 @@ static void dumpArray(std::ostringstream& theOutput, const double theArray[],
   for (int i = 0; i < theSize; ++i) {
     if (i > 0)
       theOutput << " ";
-    theOutput << std::fixed << setprecision(thePrecision)
+    theOutput << std::fixed << std::setprecision(thePrecision)
               << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]);
   }
 }
@@ -189,7 +194,8 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     if (anAttr->value() != aDoc) {
       ResultPtr aRes = ModelAPI_Tools::findPartResult(aDoc, anAttr->value());
       if (aRes.get()) {
-        aResult<<aRes->data()->name(); // Part result name (the same as saved file name)
+        // Part result name (the same as saved file name)
+        aResult<< Locale::Convert::toString(aRes->data()->name());
       }
     } else {
       aResult<<aDoc->kind(); // PartSet
@@ -197,7 +203,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
   } else if (aType == ModelAPI_AttributeInteger::typeId()) {
     AttributeIntegerPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttr);
     // do not dump a type of ConstraintAngle, because it can be changed due dumping
-    if (anAttr->id() == "AngleType") {
+    if (anAttr->id() == "AngleType" || anAttr->id() == "AngleTypePrevious") {
       return "";
     } else if (anAttr->id() == "LocationType") {
       return "__notinitialized__";
@@ -205,7 +211,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") {
@@ -224,7 +230,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
@@ -235,7 +241,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();
@@ -243,7 +254,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     AttributeReferencePtr anAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttr);
     if (anAttr->value().get()) {
-      aResult<<anAttr->value()->data()->name();
+      aResult<< Locale::Convert::toString(anAttr->value()->data()->name());
     } else {
       aResult<<"__empty__";
     }
@@ -251,7 +262,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     AttributeSelectionPtr anAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttr);
     if (anAttr->context().get())
-      aResult<<anAttr->namingName();
+      aResult<< Locale::Convert::toString(anAttr->namingName());
     else
       aResult<<"__notinitialized__";
   } else if (aType == ModelAPI_AttributeSelectionList::typeId()) {
@@ -260,14 +271,14 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     for(int a = 0; a < anAttr->size(); a++) {
       if (a != 0)
         aResult<<" ";
-      aResult<<anAttr->value(a)->namingName();
+      aResult<< Locale::Convert::toString(anAttr->value(a)->namingName());
     }
   } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
     AttributeRefAttrPtr anAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttr);
     ObjectPtr anObj = anAttr->isObject() ? anAttr->object() : anAttr->attr()->owner();
     if (anObj.get()) {
-      aResult<<anObj->data()->name();
+      aResult<< Locale::Convert::toString(anObj->data()->name());
       if (!anAttr->isObject()) {
         aResult<<" "<<anAttr->attr()->id();
       }
@@ -287,10 +298,13 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
         if (isSketchFeatures) {
           // do not control construction features of an ellipse and other
           FeaturePtr aFeature = ModelAPI_Feature::feature(*aL);
-          if (aFeature->getKind() == "SketchConstraintCoincidenceInternal")
-            continue; // skip internal constraints
+          //if (aFeature->getKind() == "SketchConstraintCoincidenceInternal")
+          //  continue; // skip internal constraints
+          std::string aStr = aFeature->getKind().substr(0, 16);
+          if (aStr == "SketchConstraint")
+            continue; // no need to dump and check constraints
         }
-        aResList.push_back((*aL)->data()->name());
+        aResList.push_back(Locale::Convert::toString((*aL)->data()->name()));
       } else if (!isSketchFeatures) {
         aResList.push_back("__empty__");
       }
@@ -310,7 +324,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
         aResult<<" ";
       ObjectPtr anObj = aL->second.get() ? aL->second->owner() : aL->first;
       if (anObj.get()) {
-        aResult<<anObj->data()->name();
+        aResult<< Locale::Convert::toString(anObj->data()->name());
         if (aL->second.get()) {
           aResult<<" "<<aL->second->id();
         }
@@ -368,12 +382,16 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
     dumpArray(aResult, aValues, 3);
   } else if (aType == GeomDataAPI_Dir::typeId()) {
+    if (theAttr->id() == "DistanceDirection")
+      return "__notcase__";
     AttributeDirPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
     double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
     dumpArray(aResult, aValues, 3);
   } else if (aType == GeomDataAPI_Point2D::typeId()) {
-    // do not dump flyout point for constraints as it may be changed unexpectedly
-    if (theAttr->id() == "ConstraintFlyoutValuePnt")
+    // do not dump flyout point for constraints as it may be changed unexpectedly,
+    // also do not dump selection points controlled by GUI
+    if (theAttr->id() == "ConstraintFlyoutValuePnt" ||
+        theAttr->id() == "SelectedPointA" || theAttr->id() == "SelectedPointB")
       return "__notinitialized__";
     AttributePoint2DPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
     double aValues[2] = {anAttr->x(), anAttr->y()};
@@ -385,19 +403,17 @@ 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);
+  GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPOUND;
+  for (; aType <= GeomAPI_Shape::VERTEX; aType = GeomAPI_Shape::ShapeType((int)aType + 1)) {
+    GeomAPI_ShapeExplorer anExp(theShape, aType);
     int aCount = 0;
-    for(; anExp.More(); anExp.Next()) aCount++;
-    TopAbs::Print(aType, aResult);
-    aResult<<": "<<aCount<<std::endl;
+    for (; anExp.more(); anExp.next()) aCount++;
+    aResult << anExp.current()->shapeTypeStr().c_str() <<  ": " << aCount << std::endl;
   }
   // output the main characteristics
   double aVolume = GeomAlgoAPI_ShapeTools::volume(theShape);
@@ -405,11 +421,21 @@ std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>&
     aResult<<"Volume: ";
     // volumes of too huge shapes write in the scientific format
     if (aVolume >= 1.e5)
-      aResult<<std::scientific<<setprecision(7);
+      aResult<<std::scientific<<std::setprecision(7);
     else
-      aResult<<std::fixed<<setprecision(3);
+      aResult<<std::fixed<<std::setprecision(3);
     aResult<<aVolume<<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
+    if (anArea >= 1.e5)
+      aResult << std::scientific << std::setprecision(7);
+    else
+      aResult << std::fixed << std::setprecision(3);
+    aResult << anArea << std::endl;
+  }
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
   aResult<<"Center of mass: ";
   double aCenterVals[3] = {aCenter->x(), aCenter->y(), aCenter->z()};