Salome HOME
Issues #2850, #2860: Change type of angle while Python Dump, because the configuratio...
authorazv <azv@opencascade.com>
Wed, 13 Feb 2019 12:14:57 +0000 (15:14 +0300)
committerazv <azv@opencascade.com>
Thu, 14 Feb 2019 05:46:00 +0000 (08:46 +0300)
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
src/SketchAPI/CMakeLists.txt
src/SketchAPI/SketchAPI.i
src/SketchAPI/SketchAPI_Constraint.cpp
src/SketchAPI/SketchAPI_Constraint.h
src/SketchAPI/SketchAPI_ConstraintAngle.cpp [new file with mode: 0644]
src/SketchAPI/SketchAPI_ConstraintAngle.h [new file with mode: 0644]
src/SketchAPI/SketchAPI_swig.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/Test/Test2860.py [new file with mode: 0644]

index b1feda56784e6b549eb84609f6f5a5c316689d5d..db86c56cb83a32be113d85be12d61f6ef3e21eb5 100644 (file)
@@ -188,12 +188,23 @@ 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") {
+      return "";
+    }
     if (anAttr->text().empty())
       aResult<<anAttr->value();
     else
       aResult<<anAttr->text();
   } else if (aType == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
+    if (anAttr->id() == "ConstraintValue") {
+      // do not dump a value of constraint if it is ConstraintAngle,
+      // because this value depends on the angle type
+      FeaturePtr anOwner = ModelAPI_Feature::feature(anAttr->owner());
+      if (anOwner && anOwner->getKind() == "SketchConstraintAngle")
+        return "";
+    }
     int aPrecision = PRECISION;
     // Special case - precision for the arc angle. It is calculated with tolerance 1e-4,
     // so the value has only 4 correct digits
@@ -206,6 +217,10 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
       aResult<<anAttr->text();
   } else if (aType == ModelAPI_AttributeBoolean::typeId()) {
     AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
+    // do not dump internal flags of ConstraintAngle
+    if (anAttr->id() == "AngleReversedLine1" || anAttr->id() == "AngleReversedLine2") {
+      return "";
+    }
     aResult<<anAttr->value();
   } else if (aType == ModelAPI_AttributeString::typeId()) {
     AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
index 389d004e71fd90e3be202f73362cfd83f71cfbc4..ac3b1364c16199d5a61ef16f09abbc20ed454d76 100644 (file)
@@ -25,6 +25,7 @@ SET(PROJECT_HEADERS
   SketchAPI_Arc.h
   SketchAPI_Circle.h
   SketchAPI_Constraint.h
+  SketchAPI_ConstraintAngle.h
   SketchAPI_IntersectionPoint.h
   SketchAPI_Line.h
   SketchAPI_MacroArc.h
@@ -43,6 +44,7 @@ SET(PROJECT_SOURCES
   SketchAPI_Arc.cpp
   SketchAPI_Circle.cpp
   SketchAPI_Constraint.cpp
+  SketchAPI_ConstraintAngle.cpp
   SketchAPI_IntersectionPoint.cpp
   SketchAPI_Line.cpp
   SketchAPI_MacroArc.cpp
index 0f76546eba007d67f21ebaf3117007e94fa32180..23a3506fb13dce248e5d32dd73e29183137b9342 100644 (file)
@@ -50,6 +50,7 @@
 %shared_ptr(SketchAPI_Circle)
 %shared_ptr(SketchAPI_MacroCircle)
 %shared_ptr(SketchAPI_Constraint)
+%shared_ptr(SketchAPI_ConstraintAngle)
 %shared_ptr(SketchAPI_IntersectionPoint)
 %shared_ptr(SketchAPI_Line)
 %shared_ptr(SketchAPI_Mirror)
 %include "SketchAPI_Rotation.h"
 %include "SketchAPI_Sketch.h"
 %include "SketchAPI_Constraint.h"
+%include "SketchAPI_ConstraintAngle.h"
index d9edb13de83dc5627dfa1da7dd8d2a830ddccd48..dd15059eca92bd2d6ba0f673874f3abb00dcfcff 100644 (file)
@@ -24,7 +24,6 @@
 #include <ModelHighAPI_Tools.h>
 
 #include <SketchPlugin_Constraint.h>
-#include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintCollinear.h>
 #include <SketchPlugin_ConstraintDistance.h>
@@ -97,10 +96,6 @@ static const std::string& constraintTypeToSetter(const std::string& theType)
     static const std::string COINCIDENCE_SETTER("setCoincident");
     return COINCIDENCE_SETTER;
   }
-  if (theType == SketchPlugin_ConstraintAngle::ID()) {
-    static const std::string ANGLE_SETTER("setAngle");
-    return ANGLE_SETTER;
-  }
   if (theType == SketchPlugin_ConstraintCollinear::ID()) {
     static const std::string COLLINEAR_SETTER("setCollinear");
     return COLLINEAR_SETTER;
@@ -175,6 +170,20 @@ static std::string angleTypeToString(int theAngleType)
   return std::string();
 }
 
+bool SketchAPI_Constraint::areAllAttributesDumped(ModelHighAPI_Dumper& theDumper) const
+{
+  bool areAttributesDumped = true;
+  FeaturePtr aBase = feature();
+  for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
+    AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+    if (aRefAttr && aRefAttr->isInitialized())
+      areAttributesDumped = theDumper.isDumped(aRefAttr);
+  }
+  if (!areAttributesDumped)
+    theDumper.postpone(aBase);
+  return areAttributesDumped;
+}
+
 void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
 {
   FeaturePtr aBase = feature();
@@ -194,26 +203,12 @@ void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
       return;
   }
 
-  // Check all attributes are already dumped. If not, store the constraint as postponed.
-  bool areAttributesDumped = true;
-  for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
-    AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
-    if (aRefAttr && aRefAttr->isInitialized())
-      areAttributesDumped = theDumper.isDumped(aRefAttr);
-  }
-  if (!areAttributesDumped) {
-    theDumper.postpone(aBase);
+  // postpone constraint until all its attributes be dumped
+  if (!areAllAttributesDumped(theDumper))
     return;
-  }
-
-  bool isAngle = aBase->getKind() == SketchPlugin_ConstraintAngle::ID();
-  std::string aSetterSuffix;
-  if (isAngle)
-    aSetterSuffix = angleTypeToString(aBase->integer(
-                    SketchPlugin_ConstraintAngle::TYPE_ID())->value());
 
   const std::string& aSketchName = theDumper.parentName(aBase);
-  theDumper << aBase << " = " << aSketchName << "." << aSetter << aSetterSuffix << "(";
+  theDumper << aBase << " = " << aSketchName << "." << aSetter << "(";
 
   bool isFirstAttr = true;
   for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
@@ -225,10 +220,8 @@ void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
   }
 
   AttributeDoublePtr aValueAttr;
-  if (isAngle)
-    aValueAttr = aBase->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
-  else if (aBase->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
-           aBase->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
+  if (aBase->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
+      aBase->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
     aValueAttr = aBase->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID());
   else
     aValueAttr = aBase->real(SketchPlugin_Constraint::VALUE());
index 958bbdae31c810b98bd36a9e4bfdc95ac3d11669..892deec760d40cfe7dfcfd77b97283764fc5a335 100644 (file)
@@ -66,6 +66,11 @@ public:
   /// Dump wrapped feature
   SKETCHAPI_EXPORT
   virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+protected:
+  // Check all attributes of constraint are already dumped.
+  // If not, store the constraint as postponed.
+  bool areAllAttributesDumped(ModelHighAPI_Dumper& theDumper) const;
 };
 
 #endif
diff --git a/src/SketchAPI/SketchAPI_ConstraintAngle.cpp b/src/SketchAPI/SketchAPI_ConstraintAngle.cpp
new file mode 100644 (file)
index 0000000..cdfa37b
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright (C) 2019-20xx  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "SketchAPI_ConstraintAngle.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <GeomAPI_Angle2d.h>
+#include <GeomAPI_Lin2d.h>
+
+#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_Line.h>
+
+#include <cmath>
+
+SketchAPI_ConstraintAngle::SketchAPI_ConstraintAngle(
+    const std::shared_ptr<ModelAPI_Feature> & theFeature)
+: SketchAPI_Constraint(theFeature)
+{
+  ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
+  if (aConstraint)
+    initialize();
+}
+
+static FeaturePtr getFeatureLine(DataPtr theData, const std::string& theAttribute)
+{
+  FeaturePtr aLine;
+  if (!theData.get() || !theData->isValid()) /// essential check as it is called in openGl thread)
+    return aLine;
+
+  std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+    std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theData->attribute(theAttribute));
+  if (anAttr) {
+    FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->object());
+    if (aFeature && aFeature->getKind() == SketchPlugin_Line::ID()) {
+      return aFeature;
+    }
+  }
+  return aLine;
+}
+
+static void calculatePossibleValuesOfAngle(FeaturePtr theFeature,
+    double& theAngleDirect, double& theAngleComplementary, double& theAngleBackward)
+{
+  std::shared_ptr<ModelAPI_Data> aData = theFeature->data();
+  FeaturePtr aLineA = getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+  FeaturePtr aLineB = getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+
+  std::shared_ptr<GeomDataAPI_Point2D> aStartA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    aLineA->attribute(SketchPlugin_Line::START_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aEndA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    aLineA->attribute(SketchPlugin_Line::END_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aStartB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    aLineB->attribute(SketchPlugin_Line::START_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aEndB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    aLineB->attribute(SketchPlugin_Line::END_ID()));
+
+  std::shared_ptr<GeomAPI_Angle2d> anAng(new GeomAPI_Angle2d(
+      aStartA->pnt(), aEndA->pnt(), aStartB->pnt(), aEndB->pnt()));
+  theAngleDirect = anAng->angleDegree();
+  theAngleBackward = 360.0 - theAngleDirect;
+
+  if (theAngleDirect > 180.0)
+    theAngleComplementary = theAngleDirect - 180.0;
+  else
+    theAngleComplementary = 180.0 - theAngleDirect;
+}
+
+static std::string angleTypeToString(FeaturePtr theFeature)
+{
+  static const double TOLERANCE = 1.e-7;
+  double anAngleDirect, anAngleComplmentary, anAngleBackward;
+  calculatePossibleValuesOfAngle(theFeature, anAngleDirect, anAngleComplmentary, anAngleBackward);
+
+  AttributeDoublePtr aValueAttr = theFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+
+  std::string aType;
+  if (fabs(aValueAttr->value() - anAngleDirect) < TOLERANCE) {
+    // Nothing to do.
+    // This case is empty and going the first to check the direct angle before the others.
+  }
+  else if (fabs(aValueAttr->value() - anAngleComplmentary) < TOLERANCE)
+    aType = "Complementary";
+  else if (fabs(aValueAttr->value() - anAngleBackward) < TOLERANCE)
+    aType = "Backward";
+  return aType;
+}
+
+void SketchAPI_ConstraintAngle::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  // postpone constraint until all its attributes be dumped
+  if (!areAllAttributesDumped(theDumper))
+    return;
+
+  // calculate angle value as it was just applied to the attributes
+  FeaturePtr aBase = feature();
+  std::string aSetterSuffix = angleTypeToString(aBase);
+
+  const std::string& aSketchName = theDumper.parentName(aBase);
+  theDumper << aBase << " = " << aSketchName << "." << "setAngle" << aSetterSuffix << "(";
+
+  bool isFirstAttr = true;
+  for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+    AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+    if (aRefAttr && aRefAttr->isInitialized()) {
+      theDumper << (isFirstAttr ? "" : ", ") << aRefAttr;
+      isFirstAttr = false;
+    }
+  }
+
+  AttributeDoublePtr aValueAttr = aBase->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+  if (aValueAttr && aValueAttr->isInitialized())
+    theDumper << ", " << aValueAttr;
+
+  theDumper << ")" << std::endl;
+}
diff --git a/src/SketchAPI/SketchAPI_ConstraintAngle.h b/src/SketchAPI/SketchAPI_ConstraintAngle.h
new file mode 100644 (file)
index 0000000..573d201
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2019-20xx  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef SRC_SKETCHAPI_SKETCHAPI_CONSTRAINTANGLE_H_
+#define SRC_SKETCHAPI_SKETCHAPI_CONSTRAINTANGLE_H_
+
+#include "SketchAPI_Constraint.h"
+
+class ModelHighAPI_Double;
+
+/**\class SketchAPI_ConstraintAngle
+ * \ingroup CPPHighAPI
+ * \brief Interface for ConstraintAngle feature
+ */
+class SketchAPI_ConstraintAngle : public SketchAPI_Constraint
+{
+public:
+  /// Constructor without values
+  SKETCHAPI_EXPORT
+  explicit SketchAPI_ConstraintAngle(const std::shared_ptr<ModelAPI_Feature> & theFeature);
+
+  static std::string ID()
+  {
+    static const std::string MY_SKETCH_CONSTRAINT_ID = "SketchConstraintAngle";
+    return MY_SKETCH_CONSTRAINT_ID;
+  }
+  virtual std::string getID() { return ID(); }
+
+  /// Dump wrapped feature
+  SKETCHAPI_EXPORT
+  virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+#endif
index 440eb2aec66e0d0600d0ce92c8f0f6f3c464f2ea..1b6e81f3cfe7048ea7fbcd4eb5e10bcb60b8cc5a 100644 (file)
@@ -29,6 +29,7 @@
   #include "SketchAPI_Circle.h"
   #include "SketchAPI_MacroCircle.h"
   #include "SketchAPI_Constraint.h"
+  #include "SketchAPI_ConstraintAngle.h"
   #include "SketchAPI_IntersectionPoint.h"
   #include "SketchAPI_Line.h"
   #include "SketchAPI_Mirror.h"
index dad15e6d74b932e9b8f9530f56e2395f63e40718..7c49a07fccae998f7de32c1cd661d037bc62e677 100644 (file)
@@ -193,6 +193,7 @@ ADD_UNIT_TESTS(
   Test2741.py
   Test2810.py
   Test2824.py
+  Test2860.py
   TestArcBehavior.py
   TestConstraintAngle.py
   TestConstraintCoincidence.py
diff --git a/src/SketchPlugin/Test/Test2860.py b/src/SketchPlugin/Test/Test2860.py
new file mode 100644 (file)
index 0000000..d497c8d
--- /dev/null
@@ -0,0 +1,42 @@
+## Copyright (C) 2018-20xx  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
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+    Test2860.py
+    Test case for issue #2650 "setAngleComplementary becomes setAngle in BARCOM"
+    Test case for issue #2860 "Error in python dump reload because of setAngleComplementary"
+"""
+
+from salome.shaper import model
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-9.326798599059195, -0.7578903795715272, 33.09960827213365, 41.66851649162133)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 60)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_2.result(), 45)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_1.endPoint(), 5)
+model.do()
+model.end()
+
+assert(model.checkPythonDump())