Salome HOME
Issue #3237: Allow usage of accented characters in ObjectBrowser
[modules/shaper.git] / src / ModelHighAPI / ModelHighAPI_FeatureStore.cpp
index 54631e07685032085321f616cc1175d7d4cf6711..58e32136f2cd9decca891e655dcaf325fbd8b13a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2020  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
@@ -20,6 +20,7 @@
 #include <ModelHighAPI_FeatureStore.h>
 
 #include <ModelAPI_Tools.h>
+#include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_AttributeBoolean.h>
@@ -45,6 +46,8 @@
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAPI_Pnt.h>
 
+#include <Locale_Convert.h>
+
 #include <TopoDS_Shape.hxx>
 #include <TopExp_Explorer.hxx>
 
@@ -74,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);
@@ -86,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__"] + "'";
@@ -103,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++) {
@@ -147,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]);
   }
 }
@@ -159,6 +165,14 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     return "__notcase__";
   }
   std::string aType = theAttr->attributeType();
+
+  // do not check selection of the filter,
+  // because there is neither parametric update nor dump support yet.
+  FiltersFeaturePtr aFilter = std::dynamic_pointer_cast<ModelAPI_FiltersFeature>(aFeatOwner);
+  if (aFilter && (aType == ModelAPI_AttributeSelection::typeId() ||
+                  aType == ModelAPI_AttributeSelectionList::typeId()))
+    return "__filter_selection__";
+
   std::ostringstream aResult;
   if (!theAttr->isInitialized()) {
     if (aType == ModelAPI_AttributeBoolean::typeId()) {
@@ -180,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
@@ -188,13 +203,15 @@ 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__";
     }
     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") {
@@ -213,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
@@ -232,7 +249,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__";
     }
@@ -240,7 +257,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()) {
@@ -249,14 +266,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();
       }
@@ -265,7 +282,7 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     }
   } else if (aType == ModelAPI_AttributeRefList::typeId()) {
     AttributeRefListPtr anAttr =
-      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttr);
+        std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttr);
     // for sketch sub-features the empty values may be skipped and order is not important
     bool isSketchFeatures = anAttr->id() == "Features" &&
       std::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->owner())->getKind() == "Sketch";
@@ -273,7 +290,16 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
     std::list<std::string> aResList; // list of resulting strings
     for(std::list<ObjectPtr>::iterator aL = aList.begin(); aL != aList.end(); aL++) {
       if (aL->get()) {
-        aResList.push_back((*aL)->data()->name());
+        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
+          std::string aStr = aFeature->getKind().substr(0, 16);
+          if (aStr == "SketchConstraint")
+            continue; // no need to dump and check constraints
+        }
+        aResList.push_back(Locale::Convert::toString((*aL)->data()->name()));
       } else if (!isSketchFeatures) {
         aResList.push_back("__empty__");
       }
@@ -293,7 +319,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();
         }
@@ -302,6 +328,12 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
       }
     }
   } else if (aType == ModelAPI_AttributeIntArray::typeId()) {
+    if (theAttr->id() == "Color") {
+      ResultConstructionPtr aResConstr =
+          std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theAttr->owner());
+      if (aResConstr.get())
+        return "__notinitialized__";
+    }
     AttributeIntArrayPtr anAttr =
       std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttr);
     for(int a = 0; a < anAttr->size(); a++)
@@ -345,12 +377,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()};
@@ -377,9 +413,15 @@ std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>&
     aResult<<": "<<aCount<<std::endl;
   }
   // output the main characteristics
-  if (GeomAlgoAPI_ShapeTools::volume(theShape) > 1.e-5) {
-    aResult<<"Volume: "<<
-      std::fixed<<setprecision(3)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
+  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;
   }
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
   aResult<<"Center of mass: ";