]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix unit tests for ParametersPlugin
authorazv <azv@opencascade.com>
Thu, 18 Aug 2016 12:32:28 +0000 (15:32 +0300)
committerazv <azv@opencascade.com>
Thu, 18 Aug 2016 12:32:50 +0000 (15:32 +0300)
src/ModelHighAPI/ModelHighAPI_Dumper.cpp
src/ModelHighAPI/ModelHighAPI_Dumper.h
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
src/ParametersAPI/ParametersAPI_Parameter.cpp
src/ParametersPlugin/Test/TestParameterChangeValue.py
src/ParametersPlugin/Test/TestParameterCreation.py
src/ParametersPlugin/Test/TestParameterRename.py
src/PythonAPI/model/dump/DumpAssistant.py

index dfc6c389bc5146cd3f3087baec294ea9abe7e5cf..28961598fd5ecfc827f2fb82c77e7624d4616aca 100644 (file)
@@ -59,15 +59,20 @@ ModelHighAPI_Dumper* ModelHighAPI_Dumper::getInstance()
   return mySelf;
 }
 
+#define CLEAR_STREAM(theStream) { \
+    std::ostringstream anOther;   \
+    swap(theStream, anOther);     \
+  }
+
 void ModelHighAPI_Dumper::clear(bool bufferOnly)
 {
-  myDumpBuffer = std::ostringstream();
+  CLEAR_STREAM(myDumpBuffer);
   myDumpBuffer << std::setprecision(16);
 
   clearNotDumped();
 
   if (!bufferOnly) {
-    myFullDump = std::ostringstream();
+    CLEAR_STREAM(myFullDump);
     myFullDump << std::setprecision(16);
 
     myNames.clear();
@@ -82,7 +87,7 @@ void ModelHighAPI_Dumper::clearNotDumped()
   myNotDumpedEntities.clear();
 }
 
-const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity)
+const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, bool theSaveNotDumped)
 {
   EntityNameMap::const_iterator aFound = myNames.find(theEntity);
   if (aFound != myNames.end())
@@ -116,7 +121,8 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity)
   }
 
   myNames[theEntity] = std::pair<std::string, bool>(aName, isUserDefined);
-  myNotDumpedEntities.insert(theEntity);
+  if (theSaveNotDumped)
+    myNotDumpedEntities.insert(theEntity);
   return myNames[theEntity].first;
 }
 
@@ -150,10 +156,13 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theD
 bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc)
 {
   bool isOk = true;
-  // dump all features
   std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
   std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
-  for (; aFeatIt != aFeatures.end(); ++aFeatIt) {
+  // firstly, dump all parameters
+  for (; aFeatIt != aFeatures.end(); ++ aFeatIt)
+    dumpParameter(*aFeatIt);
+  // dump all other features
+  for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) {
     CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
     if (aCompFeat) // iteratively process composite features
       isOk = process(aCompFeat) && isOk;
@@ -206,6 +215,9 @@ bool ModelHighAPI_Dumper::processSubs(const std::shared_ptr<ModelAPI_CompositeFe
   bool isOk = true;
   // dump all sub-features;
   int aNbSubs = theComposite->numberOfSubs();
+//////////////////////////////////////
+  std::list<ObjectPtr> aList = theComposite->reflist("Features")->list();
+//////////////////////////////////////
   for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
     FeaturePtr aFeature = theComposite->subFeature(anIndex);
     if (isDumped(aFeature))
@@ -533,11 +545,11 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
     myDumpBuffer << "]";
   } else {
     // clear buffer and store list "as is"
-    myDumpBuffer = std::ostringstream();
+    CLEAR_STREAM(myDumpBuffer);
     *this << theRefList;
     // save buffer and clear it again
     std::string aDumpedList = myDumpBuffer.str();
-    myDumpBuffer = std::ostringstream();
+    CLEAR_STREAM(myDumpBuffer);
     // obtain name of list
     FeaturePtr anOwner = ModelAPI_Feature::feature(theRefList->owner());
     std::string aListName = name(anOwner) + "_objects";
index f7f0dcc3e5c192126f9aaee79dc6d29ca7e02c47..61ed607039eb1be2ae67335b6d68f2c5e7e594ae 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "ModelHighAPI.h"
 
+#include <list>
 #include <map>
 #include <memory>
 #include <set>
@@ -80,13 +81,18 @@ public:
                     const std::string& theObject = std::string());
 
   /// Returns name of specified entity
+  /// \param theEntity        [in] named entity
+  /// \param theSaveNotDumped [in] if \c true, the entity should be stored as not dumped (will be dumped automatically)
+  /// \return name of the entity
   MODELHIGHAPI_EXPORT
-  const std::string& name(const EntityPtr& theEntity);
+  const std::string& name(const EntityPtr& theEntity, bool theSaveNotDumped = true);
 
   /// Returns name of parent composite feature for specified entity
   MODELHIGHAPI_EXPORT
   const std::string& parentName(const FeaturePtr& theFeature);
 
+  /// Dump parameter feature only
+  virtual void dumpParameter(const FeaturePtr& theFeature) = 0;
   /// Dump given feature
   virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
 
index 326f4a16ba960b2347e040961c4fc15090d280da..ac702d9689d881026d432b8d1d4a452534bb3e47 100644 (file)
 #include <TopExp_Explorer.hxx>
 
 #include <ios>
+#include <cmath>
+
+#define PRECISION 7
+#define TOLERANCE (1.e-7)
 
 ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) {
   storeData(theFeature->data(), myAttrs);
@@ -112,6 +116,16 @@ std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data
   return "";
 }
 
+static void dumpArray(std::ostringstream& theOutput, const double theArray[], int theSize)
+{
+  for (int i = 0; i < theSize; ++i) {
+    if (i > 0)
+      theOutput << " ";
+    theOutput << std::fixed << setprecision(PRECISION)
+              << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]);
+  }
+}
+
 std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
   static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
   FeaturePtr aFeatOwner = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttr->owner());
@@ -153,9 +167,10 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
       aResult<<anAttr->text();
   } else if (aType == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
-    if (anAttr->text().empty())
-      aResult<<std::fixed<<setprecision(7)<<anAttr->value();
-    else
+    if (anAttr->text().empty()) {
+      double aVal = anAttr->value();
+      dumpArray(aResult, &aVal, 1);
+    } else
       aResult<<anAttr->text();
   } else if (aType == ModelAPI_AttributeBoolean::typeId()) {
     AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
@@ -245,13 +260,16 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
       aResult<<anAttr->value(a)<<" ";
   } else if (aType == GeomDataAPI_Point::typeId()) {
     AttributePointPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttr);
-    aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
+    double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+    dumpArray(aResult, aValues, 3);
   } else if (aType == GeomDataAPI_Dir::typeId()) {
     AttributeDirPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
-    aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
+    double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+    dumpArray(aResult, aValues, 3);
   } else if (aType == GeomDataAPI_Point2D::typeId()) {
     AttributePoint2DPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
-    aResult<<anAttr->x()<<" "<<anAttr->y()<<" ";
+    double aValues[2] = {anAttr->x(), anAttr->y()};
+    dumpArray(aResult, aValues, 2);
   } else {
     aResult<<"__unknownattribute__";
   }
@@ -276,7 +294,7 @@ std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>&
   // output the main characteristics
   aResult<<"Volume: "<<setprecision(2)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
   std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
-  aResult<<"Center of mass: "<<std::fixed<<setprecision(7)
+  aResult<<"Center of mass: "<<std::fixed<<setprecision(PRECISION)
     <<aCenter->x()<<" "<<aCenter->y()<<" "<<aCenter->z()<<std::endl;
   return aResult.str();
 }
index 8781004a0c711f49df97c355fab7c5c6359435a3..d47448bce8f814a322c016d44817def700ad9722 100644 (file)
@@ -27,7 +27,8 @@ ParametersAPI_Parameter::ParametersAPI_Parameter(
   if (initialize()) {
     fillAttribute(theName, name());
     fillAttribute(theExpression, expression());
-    fillAttribute(theComment, comment());
+    if (!theComment.empty())
+      fillAttribute(theComment, comment());
 
     execute();
   }
@@ -41,7 +42,7 @@ void ParametersAPI_Parameter::dump(ModelHighAPI_Dumper& theDumper) const
 {
   FeaturePtr aBase = feature();
   const std::string& aDocName = theDumper.name(aBase->document());
-  const std::string& aParamName = theDumper.name(aBase);
+  const std::string& aParamName = theDumper.name(aBase, false);
 
   AttributeStringPtr anExpr   = aBase->string(ParametersPlugin_Parameter::EXPRESSION_ID());
   AttributeStringPtr aComment = aBase->string(ParametersPlugin_Parameter::COMMENT_ID());
index 46b076db2180c67376b914cdd2968f673221997a..c78775aee17bbd28d8891e9e1cb051148c45f919 100644 (file)
@@ -81,13 +81,54 @@ class TestParameterRename(unittest.TestCase):
         aSketchCircle = aSketchFeature.addFeature("SketchCircle")
         anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
         aRadiusAttr = aSketchCircle.real("CircleRadius")
-        anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
-        aRadiusAttr.setText("x1")
+        anCircleCentr.setValue(10., 20.)
+        aRadiusAttr.setValue(10.)
         self.aSession.finishOperation()
 
         self.anCircleCentr = anCircleCentr
         self.aRadiusAttr = aRadiusAttr
 
+        # constraints to fix circle position and radius
+        self.aSession.startOperation()
+        # fix X coordinate
+        aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+        anOY = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.SetValue(0., 100.)
+        anOY.selection("External").selectSubShape("EDGE", "OY")
+        refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+        value = aDistanceConstraint1.real("ConstraintValue")
+        value.setText("x1 + 10.0")
+        aDistanceConstraint1.execute();
+        # fix Y coordinate
+        aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+        anOX = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.SetValue(100., 0.)
+        anOX.selection("External").selectSubShape("EDGE", "OX")
+        refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+        value = aDistanceConstraint2.real("ConstraintValue")
+        value.setText("x1 + 20.0")
+        aDistanceConstraint2.execute();
+        # fix radius
+        aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+        refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+        refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+        aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+        aRadiusConstrAttr.setText("x1")
+        aRadiusConstraint.execute()
+        self.aSession.finishOperation()
+
         self.assertEqual(self.anCircleCentr.x(), 160.)
         self.assertEqual(self.anCircleCentr.y(), 170.)
         self.assertEqual(aRadiusAttr.value(), 150.)
index a791a54e95c05751e2625a85690296c25138ee0e..e4ac3fee07f89eb09ef28aa5c07bfe1416029436 100644 (file)
@@ -114,7 +114,7 @@ assert (aTmValue == round(2 * math.pi, 6))
 #=========================================================================
 # Use parameters to set radius of a circle :
 # 1. Create a circle (250., 250), r = 25.
-# 2. Set a 'cr1' as text value of radius attribute
+# 2. Create a radius constraint and set 'cr1' as text value of constraint
 #=========================================================================
 aSession.startOperation()
 aSketchCircle = aSketchFeature.addFeature("SketchCircle")
@@ -125,7 +125,12 @@ aRadiusAttr.setValue(25.)
 aSession.finishOperation()
 # Apply parameter
 aSession.startOperation()
-aRadiusAttr.setText("cr1")
+aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+aRadiusConstrAttr.setText("cr1")
+aRadiusConstraint.execute()
 aSession.finishOperation()
 assert(aRadiusAttr.value() == 100.)
 #=========================================================================
index 0605fac1a98587defbfb1e3df780c244d5acd86e..795ce9fe78335f3f41d934600ad2ddd73fc9c665 100644 (file)
@@ -83,13 +83,58 @@ class TestParameterRename(unittest.TestCase):
         aSketchCircle = aSketchFeature.addFeature("SketchCircle")
         anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
         aRadiusAttr = aSketchCircle.real("CircleRadius")
-        anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
-        aRadiusAttr.setText("x1")
+        anCircleCentr.setValue(10., 20.)
+        aRadiusAttr.setValue(10.)
         self.aSession.finishOperation()
 
         self.anCircleCentr = anCircleCentr
         self.aRadiusAttr = aRadiusAttr
 
+        # constraints to fix circle position and radius
+        self.aSession.startOperation()
+        # fix X coordinate
+        aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+        anOY = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.SetValue(0., 100.)
+        anOY.selection("External").selectSubShape("EDGE", "OY")
+        refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+        valueX = aDistanceConstraint1.real("ConstraintValue")
+        valueX.setText("x1 + 10.0")
+        aDistanceConstraint1.execute();
+        # fix Y coordinate
+        aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+        refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+        refattrA.setAttr(anCircleCentr)
+        refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+        anOX = aSketchFeature.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+        aStartPoint.setValue(0., 0.)
+        anEndPoint.SetValue(100., 0.)
+        anOX.selection("External").selectSubShape("EDGE", "OX")
+        refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+        valueY = aDistanceConstraint2.real("ConstraintValue")
+        valueY.setText("x1 + 20.0")
+        aDistanceConstraint2.execute();
+        # fix radius
+        aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+        refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+        refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+        aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+        aRadiusConstrAttr.setText("x1")
+        aRadiusConstraint.execute()
+        self.aSession.finishOperation()
+
+        self.aCircleCenterX = valueX
+        self.aCircleCenterY = valueY
+        sel.aCircleRadius = aRadiusConstraintAttr
+
         self.assertEqual(self.anCircleCentr.x(), 160.)
         self.assertEqual(self.anCircleCentr.y(), 170.)
         self.assertEqual(aRadiusAttr.value(), 150.)
@@ -110,9 +155,13 @@ class TestParameterRename(unittest.TestCase):
         aParam = self.dtParams["x2"]
         self.assertEqual(aParam.string("expression").value(), "a1 + y1 + 100.0")
         # Check rename in the feature
-        self.assertEqual(self.anCircleCentr.textX(), "a1 + 10.0")
-        self.assertEqual(self.anCircleCentr.textY(), "a1 + 20.0")
-        self.assertEqual(self.aRadiusAttr.text(), "a1")
+        self.assertEqual(self.aCircleCenterX.text(), "a1 + 10.0")
+        self.assertEqual(self.aCircleCenterY.text(), "a1 + 20.0")
+        self.assertEqual(self.aCircleRadius.text(), "a1")
+        # Check values
+        self.assertEqual(self.anCircleCentr.x(), 160.)
+        self.assertEqual(self.anCircleCentr.y(), 170.)
+        self.assertEqual(self.aRadiusAttr.value(), 150.)
 
     def test_rename_not_unique(self):
         # Rename to not unique name
@@ -129,9 +178,13 @@ class TestParameterRename(unittest.TestCase):
         aParam = self.dtParams["x2"]
         self.assertEqual(aParam.string("expression").value(), "x1 + y1 + 100.0")
         # Check rename in the feature (Expected: not renamed)
-        self.assertEqual(self.anCircleCentr.textX(), "x1 + 10.0")
-        self.assertEqual(self.anCircleCentr.textY(), "x1 + 20.0")
-        self.assertEqual(self.aRadiusAttr.text(), "x1")
+        self.assertEqual(self.aCircleCenterX.text(), "x1 + 10.0")
+        self.assertEqual(self.aCircleCenterY.text(), "x1 + 20.0")
+        self.assertEqual(self.aCircleRadius.text(), "x1")
+        # Check values
+        self.assertEqual(self.anCircleCentr.x(), 160.)
+        self.assertEqual(self.anCircleCentr.y(), 170.)
+        self.assertEqual(self.aRadiusAttr.value(), 150.)
 
 if __name__ == '__main__':
     unittest.main()
index dc4c8738432a3726ed412fedd7ce0d7953a51c9a..b4a27add1a8050dc10a825b2f209a7497cd840de 100644 (file)
@@ -40,7 +40,7 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
         if aFeatureKind in self.myFeatures:
             # Dump only feature created by user (in history).
             # For all other features, just keep their name.
-            if theForce or aFeatureKind == "Parameter" or theFeature.isInHistory():
+            if theForce or theFeature.isInHistory():
                 self.myFeatures[aFeatureKind](theFeature).dump(self)
             else:
                 self.name(theFeature)
@@ -50,6 +50,12 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
             # In case of theFeature is not a constraint, it will not be dumped.
             self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self)
 
+    ## Dump all parameters
+    def dumpParameter(self, theFeature):
+        aFeatureKind = theFeature.getKind()
+        if aFeatureKind == "Parameter" and aFeatureKind in self.myFeatures:
+            self.myFeatures[aFeatureKind](theFeature).dump(self)
+
     ## Return getter for specified attribute
     def attributeGetter(self, theFeature, theAttrName):
         aFeatureKind = theFeature.getKind()