Salome HOME
Values of constraint (length, distance, radius) now initialized on reference definition
authormpv <mikhail.ponikarov@opencascade.com>
Thu, 27 Nov 2014 12:12:36 +0000 (15:12 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Thu, 27 Nov 2014 12:12:36 +0000 (15:12 +0300)
16 files changed:
src/Model/Model_Data.cpp
src/ModelAPI/ModelAPI_Attribute.h
src/ModelAPI/ModelAPI_Object.h
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_Circle.h
src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistance.h
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.h
src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp
src/SketchPlugin/SketchPlugin_ConstraintRadius.h
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Line.h
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Sketch.h
src/XGUI/XGUI_PropertyPanel.cpp

index 5dcc138deeecbf1d46821c83b5e93fe7173cd6ce..0ae7a75aa3f3caf3e507ac2a8b57d2e725593744 100644 (file)
@@ -100,6 +100,7 @@ void Model_Data::addAttribute(const std::string& theID, const std::string theAtt
   if (anAttr) {
     myAttrs[theID] = std::shared_ptr<ModelAPI_Attribute>(anAttr);
     anAttr->setObject(myObject);
+    anAttr->setID(theID);
   } else {
     Events_Error::send("Can not create unknown type of attribute " + theAttrType);
   }
@@ -195,7 +196,7 @@ void Model_Data::sendAttributeUpdated(ModelAPI_Attribute* theAttr)
     static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
     ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
     if (myObject) {
-      myObject->attributeChanged();
+      myObject->attributeChanged(theAttr->id());
     }
   }
 }
index 27d65eb9b69eb8bc96b6ac5da4b680a5fb55acad..041e27b7cf5d7632493843cf917acb1f4c3230e2 100644 (file)
@@ -19,11 +19,12 @@ class ModelAPI_Attribute
 {
   ///< needed here to emit signal that feature changed on change of the attribute
   std::shared_ptr<ModelAPI_Object> myObject;
+  std::string myID; ///< identifier of this attribute in Data class
  protected:
   // accessible from the attributes
-  bool myIsInitialized;
-  bool myIsArgument;
-  bool myIsImmutable;
+  bool myIsInitialized; ///< is some value assigned to this attribute
+  bool myIsArgument;    ///< is this attribute used as an argument for execution
+  bool myIsImmutable;   ///< is this attribute can be changed programmatically (e.g. by constraint)
 
  public:
 
@@ -88,6 +89,12 @@ class ModelAPI_Attribute
     return myIsImmutable;
   }
 
+  /// ID of the attribute in Data
+  MODELAPI_EXPORT const std::string& id() const
+  {
+    return myID;
+  }
+
  protected:
   /// Objects are created for features automatically
   ModelAPI_Attribute()
@@ -97,6 +104,13 @@ class ModelAPI_Attribute
     myIsImmutable = false;
   }
 
+  /// Sets the ID of the attribute in Data (called from Data)
+  MODELAPI_EXPORT void setID(const std::string theID)
+  {
+    myID = theID;
+  }
+
+  friend class Model_Data;
 };
 
 //! Pointer on attribute object
index be488054077184cc2dc006ff80bd358387f635ce..3c8e6a6e8dfba3a5c6d450068895184dea638ec5 100644 (file)
@@ -55,7 +55,8 @@ class ModelAPI_Object
   virtual std::string groupName() = 0;
 
   /// Called on change of any argument-attribute of this object
-  MODELAPI_EXPORT virtual void attributeChanged() 
+  /// \param theID identifier of changed attribute
+  MODELAPI_EXPORT virtual void attributeChanged(const std::string& theID) 
   {}
 
   /// To use virtuality for destructors
index 209f9744a7310e9483a080a96033975dd4f91599..eeb77874dd974b2a4b70e63c7502f264edd26f75 100644 (file)
@@ -100,18 +100,17 @@ bool SketchPlugin_Circle::isFixed() {
   return data()->selection(EXTERNAL_ID())->context();
 }
 
-void SketchPlugin_Circle::attributeChanged() {
-  static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
-  std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-  // update arguments due to the selection value
-  if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
-    myIsUpdated = true;
-    std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
-    std::shared_ptr<GeomAPI_Circ> aCirc = anEdge->circle();
-    std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = 
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
-    aCenterAttr->setValue(sketch()->to2D(aCirc->center()));
-    real(RADIUS_ID())->setValue(aCirc->radius());
-    myIsUpdated = false;
+void SketchPlugin_Circle::attributeChanged(const std::string& theID) {
+  if (theID == EXTERNAL_ID()) {
+    std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+    // update arguments due to the selection value
+    if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
+      std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
+      std::shared_ptr<GeomAPI_Circ> aCirc = anEdge->circle();
+      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
+      aCenterAttr->setValue(sketch()->to2D(aCirc->center()));
+      real(RADIUS_ID())->setValue(aCirc->radius());
+    }
   }
 }
index 8ceef34ebce1a521f54428ffa9a8a9e1b0c68965..08263db8c587c23797ff5866843a562d8e2bc4cc 100644 (file)
@@ -77,7 +77,7 @@ class SketchPlugin_Circle : public SketchPlugin_Feature  //, public GeomAPI_IPre
   virtual double distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
 
   /// Called on change of any argument-attribute of this object
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged();
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
 
   /// Use plugin manager for features creation
   SketchPlugin_Circle();
index 97d41154c71e4fca2fdf1736c200605a28ed4b11..092d3c74cfedc4cfdcc5714e9eac186edc6cfd0c 100644 (file)
@@ -101,18 +101,12 @@ AISObjectPtr SketchPlugin_ConstraintDistance::getAISObject(AISObjectPtr thePrevi
   // value calculation
   std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeDouble>(aData->attribute(SketchPlugin_Constraint::VALUE()));
-  // TODO: has to be calculated on definition of reference object
-  double aValue;
+  double aValue = 0;
   // Issue #196: checking the positivity of the distance constraint
   // there is a validator for a distance constraint, that the value should be positive
   // in case if an invalid value is set, the current distance value is shown
   if (aValueAttr->isInitialized())
     aValue = aValueAttr->value();
-  else {
-    aValue = calculateCurrentDistance();
-    aValueAttr->setValue(aValue);
-  }
-  // End TODO
 
   AISObjectPtr anAIS = thePrevious;
   if (!anAIS)
@@ -168,6 +162,20 @@ double SketchPlugin_ConstraintDistance::calculateCurrentDistance() const
   return aDistance;
 }
 
+void SketchPlugin_ConstraintDistance::attributeChanged(const std::string& theID) {
+  if (theID == SketchPlugin_Constraint::ENTITY_A() || 
+      theID == SketchPlugin_Constraint::ENTITY_B()) 
+  {
+    std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
+        ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
+    if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
+      double aDistance = calculateCurrentDistance();
+      if (aDistance > 0) { // set as value the length of updated references
+        aValueAttr->setValue(aDistance);
+      }
+    }
+  }
+}
 
 //*************************************************************************************
 std::shared_ptr<GeomDataAPI_Point2D> getFeaturePoint(DataPtr theData,
index 8ac80c3139df4e41830ff70033cc6095d987cb24..ef58b245317231c9075156e2550f2d52a66353a6 100644 (file)
@@ -56,6 +56,10 @@ class SketchPlugin_ConstraintDistance : public SketchPlugin_ConstraintBase
   /// \param theDeltaY the delta for Y coordinate is moved
   SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
 
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
   /// Returns the current distance between the feature attributes
   double calculateCurrentDistance() const;
 
index 5799a3a1284fd0c0cf7d12b6cd2e37341ccb0436..b5431fddf72378575778a29e232622d69b17ac2f 100644 (file)
@@ -51,32 +51,41 @@ void SketchPlugin_ConstraintLength::execute()
   }
 }
 
-AISObjectPtr SketchPlugin_ConstraintLength::getAISObject(AISObjectPtr thePrevious)
+bool SketchPlugin_ConstraintLength::getPoints(
+  std::shared_ptr<GeomAPI_Pnt>& thePoint1, std::shared_ptr<GeomAPI_Pnt>& thePoint2,
+  std::shared_ptr<GeomDataAPI_Point2D>& theStartPoint,
+  std::shared_ptr<GeomDataAPI_Point2D>& theEndPoint)
 {
   if (!sketch())
-    return thePrevious;
-
+    return false;
   std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
-
   std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
   if (!anAttr)
-    return thePrevious;
+    return false;
   FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->object());
   if (!aFeature || aFeature->getKind() != SketchPlugin_Line::ID())
-    return thePrevious;
-
-  std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
-      GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
-
+    return false;
   DataPtr aData = aFeature->data();
-  std::shared_ptr<GeomDataAPI_Point2D> aStartPoint = std::dynamic_pointer_cast<
+  theStartPoint = std::dynamic_pointer_cast<
       GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::START_ID()));
-  std::shared_ptr<GeomDataAPI_Point2D> anEndPoint = std::dynamic_pointer_cast<
+  theEndPoint = std::dynamic_pointer_cast<
       GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::END_ID()));
+  thePoint1 = sketch()->to3D(theStartPoint->x(), theStartPoint->y());
+  thePoint2 = sketch()->to3D(theEndPoint->x(), theEndPoint->y());
+  return true;
+}
 
-  std::shared_ptr<GeomAPI_Pnt> aPoint1 = sketch()->to3D(aStartPoint->x(), aStartPoint->y());
-  std::shared_ptr<GeomAPI_Pnt> aPoint2 = sketch()->to3D(anEndPoint->x(), anEndPoint->y());
+AISObjectPtr SketchPlugin_ConstraintLength::getAISObject(AISObjectPtr thePrevious)
+{
+  std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
+  std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, anEndPoint;
+  if (!getPoints(aPoint1, aPoint2, aStartPoint, anEndPoint))
+    return thePrevious; // not possible to show length because points are not defined
+
+  std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
+  std::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = std::dynamic_pointer_cast<
+      GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
   std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = std::shared_ptr<GeomAPI_Pnt>();
   if (aFlyOutAttr->isInitialized()) {
     aFlyoutPnt = sketch()->to3D(aFlyOutAttr->x(), aFlyOutAttr->y());
@@ -106,7 +115,8 @@ AISObjectPtr SketchPlugin_ConstraintLength::getAISObject(AISObjectPtr thePreviou
   anAIS->createDistance(aPoint1, aPoint2, aFlyoutPnt, aPlane, aValue);
 
   // Set color from preferences
-  std::vector<int> aRGB = Config_PropManager::color("Visualization", "length_color", LENGTH_COLOR);
+  std::vector<int> aRGB = 
+    Config_PropManager::color("Visualization", "length_color", LENGTH_COLOR);
   anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]);
   return anAIS;
 }
@@ -122,3 +132,18 @@ void SketchPlugin_ConstraintLength::move(double theDeltaX, double theDeltaY)
   aPoint->move(theDeltaX, theDeltaY);
 }
 
+void SketchPlugin_ConstraintLength::attributeChanged(const std::string& theID) {
+  if (theID == SketchPlugin_Constraint::ENTITY_A()) 
+  {
+    std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
+      ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
+    if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
+      std::shared_ptr<GeomAPI_Pnt> aPoint1, aPoint2;
+      std::shared_ptr<GeomDataAPI_Point2D> aStartPoint, anEndPoint;
+      if (getPoints(aPoint1, aPoint2, aStartPoint, anEndPoint)) {
+        double aLength = aPoint1->distance(aPoint2);
+        aValueAttr->setValue(aLength);
+      }
+    }
+  }
+}
index 5f3ae9aae121173e9897dbf8268c5bd2f178c845..9cdd7e153fce2a676989ee9239862733e75583d5 100644 (file)
@@ -10,6 +10,8 @@
 #include <SketchPlugin_Sketch.h>
 #include <list>
 
+class GeomDataAPI_Point2D;
+
 #define LENGTH_COLOR "#ff00ff"
 
 /** \class SketchPlugin_ConstraintLength
@@ -50,8 +52,19 @@ class SketchPlugin_ConstraintLength : public SketchPlugin_ConstraintBase
   /// \param theDeltaY the delta for Y coordinate is moved
   SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
 
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintLength();
+
+private:
+  // retrns the points-base of length, returns false if it is not possible
+  bool getPoints(
+    std::shared_ptr<GeomAPI_Pnt>& thePoint1, std::shared_ptr<GeomAPI_Pnt>& thePoint2,
+    std::shared_ptr<GeomDataAPI_Point2D>& theStartPoint,
+    std::shared_ptr<GeomDataAPI_Point2D>& theEndPoint);
 };
 
 #endif
index 3aa6cba13a73865220469dfff36bb10f765833af..77fff3184de9e2816ae8f43c29db4f331fcca33c 100644 (file)
@@ -61,39 +61,58 @@ void SketchPlugin_ConstraintRadius::execute()
   }
 }
 
-AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePrevious)
+double SketchPlugin_ConstraintRadius::circleRadius(std::shared_ptr<ModelAPI_Feature>& theCirc)
 {
+  static const double kErrorResult = -1.;
   if (!sketch())
-    return thePrevious;
+    return kErrorResult;
 
   std::shared_ptr<ModelAPI_Data> aData = data();
   std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
   if (!anAttr)
-    return thePrevious;
-  FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->object());
-  std::string aKind = aFeature ? aFeature->getKind() : "";
+    return kErrorResult;
+  theCirc = ModelAPI_Feature::feature(anAttr->object());
+  std::string aKind = theCirc ? theCirc->getKind() : "";
   if (aKind != SketchPlugin_Circle::ID() && aKind != SketchPlugin_Arc::ID())
-    return thePrevious;
+    return kErrorResult;
+
+  DataPtr aCircData = theCirc->data();
+  std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
+  if (aKind == SketchPlugin_Circle::ID()) {
+    AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+        aCircData->attribute(SketchPlugin_Circle::RADIUS_ID()));
+    return aCircRadius->value();
+  } else {
+    aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+        aCircData->attribute(SketchPlugin_Arc::CENTER_ID()));
+    std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
+        GeomDataAPI_Point2D>(aCircData->attribute(SketchPlugin_Arc::START_ID()));
+    return aCenterAttr->pnt()->distance(aStartAttr->pnt());
+  }
+  return kErrorResult;
+}
+
+AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePrevious)
+{
+  std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
+  double aRadius = circleRadius(aCyrcFeature);
+  if (aRadius < 0)
+    return thePrevious; // can not create a good presentation
 
   // Flyout point
   std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
-      GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+      GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
   std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt;
   if (aFlyoutAttr->isInitialized()) {
     aFlyoutPnt = sketch()->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
   } 
 
   // Prepare a circle
-  std::shared_ptr<ModelAPI_Data> aCyrcData = aFeature->data();
   std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
-  double aRadius;
-  if (aKind == SketchPlugin_Circle::ID()) {
+  if (aCyrcFeature->getKind() == SketchPlugin_Circle::ID()) { // circle
     aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-        aCyrcData->attribute(SketchPlugin_Circle::CENTER_ID()));
-    AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
-        aCyrcData->attribute(SketchPlugin_Circle::RADIUS_ID()));
-    aRadius = aCircRadius->value();
+        aCyrcFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID()));
     if (!aFlyoutPnt) {
       double aShift = aRadius * 1.1;
       std::shared_ptr<GeomAPI_Pnt2d> aPnt = aCenterAttr->pnt();
@@ -102,15 +121,12 @@ AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePreviou
       aFlyoutAttr->setValue(aFPnt);
       aFlyoutPnt = sketch()->to3D(aFPnt->x(), aFPnt->y());
     }
-  } else if (aKind == SketchPlugin_Arc::ID()) {
+  } else { // arc
     aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-        aCyrcData->attribute(SketchPlugin_Arc::CENTER_ID()));
-    std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(aCyrcData->attribute(SketchPlugin_Arc::START_ID()));
-    aRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt());
+        aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID()));
     if (!aFlyoutPnt) {
       std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(aCyrcData->attribute(SketchPlugin_Arc::START_ID()));      
+        GeomDataAPI_Point2D>(aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID()));      
       aFlyoutAttr->setValue(aStartAttr->pnt());
       aFlyoutPnt = sketch()->to3D(aStartAttr->pnt()->x(), aStartAttr->pnt()->y());
     }
@@ -123,20 +139,14 @@ AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePreviou
   std::shared_ptr<GeomAPI_Circ> aCircle(new GeomAPI_Circ(aCenter, aNormal, aRadius));
 
   // Value
-  // TODO: has to be calculated on definition of reference object
   std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
-      ModelAPI_AttributeDouble>(aData->attribute(SketchPlugin_Constraint::VALUE()));
-  double aValue = aRadius;
+      ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
   if (aValueAttr->isInitialized())
-    aValue = aValueAttr->value();
-  else {
-    aValueAttr->setValue(aValue);
-  }
-  // End TODO
+    aRadius = aValueAttr->value();
   AISObjectPtr anAIS = thePrevious;
   if (!anAIS)
     anAIS = AISObjectPtr(new GeomAPI_AISObject);
-  anAIS->createRadius(aCircle, aFlyoutPnt, aValue);
+  anAIS->createRadius(aCircle, aFlyoutPnt, aRadius);
 
   // Set color from preferences
   std::vector<int> aRGB = Config_PropManager::color("Visualization", "radius_color", RADIUS_COLOR);
@@ -181,3 +191,17 @@ void SketchPlugin_ConstraintRadius::move(double theDeltaX, double theDeltaY)
 
   aFlyoutAttr->setValue(aFlyout->x(), aFlyout->y());
 }
+
+void SketchPlugin_ConstraintRadius::attributeChanged(const std::string& theID) {
+  if (theID == SketchPlugin_Constraint::ENTITY_A()) {
+    std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
+        ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
+    if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
+      std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
+      double aRadius = circleRadius(aCyrcFeature);
+      if (aRadius > 0) { // set as value the radius of updated reference to another circle
+        aValueAttr->setValue(aRadius);
+      }
+    }
+  }
+}
index 96e295e1b50f0227b3e4764061ff29d8fc441d29..7aa5ec6fbe10e2637e3d3c3a31b098ff1db03cbf 100644 (file)
@@ -49,8 +49,17 @@ class SketchPlugin_ConstraintRadius : public SketchPlugin_ConstraintBase
   /// \param theDeltaY the delta for Y coordinate is moved
   SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
 
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintRadius();
+
+private:
+  /// Checks and gets the radius of referenced circle (or arc) otherwise returns -1.
+  /// \param theCircData the found referenced circle returned by this method
+  double circleRadius(std::shared_ptr<ModelAPI_Feature>& theCirc);
 };
 
 #endif
index 2cba979ce710164a078d324ea93bf8139ee9fe8f..83ee216593697877dd81eec97f23c76792bef900 100644 (file)
@@ -99,19 +99,18 @@ bool SketchPlugin_Line::isFixed() {
   return data()->selection(EXTERNAL_ID())->context();
 }
 
-void SketchPlugin_Line::attributeChanged() {
-  static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
-  std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-   // update arguments due to the selection value
-  if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
-    myIsUpdated = true;
-    std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
-    std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_ID()));
-    aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
-    std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = 
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_ID()));
-    anEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
-    myIsUpdated = false;
+void SketchPlugin_Line::attributeChanged(const std::string& theID) {
+  if (theID == EXTERNAL_ID()) {
+    std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+     // update arguments due to the selection value
+    if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
+      std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
+      std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_ID()));
+      aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
+      std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_ID()));
+      anEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
+    }
   }
 }
index a9e3e606cc6b931e6b9f097603dabaf873886d57..850d17e4a23e15b13ab3f7fd82cd1b9f69bf37c6 100644 (file)
@@ -68,7 +68,7 @@ class SketchPlugin_Line : public SketchPlugin_Feature
   virtual double distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
 
   /// Called on change of any argument-attribute of this object
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged();
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
 
   /// Use plugin manager for features creation
   SketchPlugin_Line();
index 213d38502c035f544756d33f6fddf48b0464019c..1793ff16a17b6bd8b248ff544ccfb401d16b0f91 100644 (file)
@@ -271,66 +271,46 @@ void SketchPlugin_Sketch::erase()
   ModelAPI_CompositeFeature::erase();
 }
 
-void SketchPlugin_Sketch::attributeChanged() {
-  static bool kIsUpdated = false; // to avoid infinitive cycle on attrubtes change
-  static bool kIsAttrChanged = false;
-  std::shared_ptr<GeomAPI_Shape> aSelection = 
-    data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value();
-  if (aSelection && !kIsUpdated) { // update arguments due to the selection value
-    kIsUpdated = true;
-    // update the sketch plane
-    std::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aSelection);
-    if (aPlane) {
-      double anA, aB, aC, aD;
-      aPlane->coefficients(anA, aB, aC, aD);
-
-      // calculate attributes of the sketch
-      std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
-      std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
-      std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
-      aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
-      std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
-      // X axis is preferable to be dirX on the sketch
-      static const double tol = 1.e-7;
-      bool isX = fabs(anA - 1.0) < tol && fabs(aB) < tol && fabs(aC) < tol;
-      std::shared_ptr<GeomAPI_Dir> aTempDir(
-        isX ? new GeomAPI_Dir(0, 1, 0) : new GeomAPI_Dir(1, 0, 0));
-      std::shared_ptr<GeomAPI_Dir> aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir)));
-      std::shared_ptr<GeomAPI_Dir> aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir)));
-
-      kIsAttrChanged = false; // track the attributes were really changed during the plane update
-      std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast
-        <GeomDataAPI_Point>(data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-      anOrigin->setValue(anOrigPnt);
-      std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-        data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-      aNormal->setValue(aNormDir);
-      std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-        data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-      aDirX->setValue(aXDir);
-      std::shared_ptr<GeomDataAPI_Dir> aDirY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-        data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
-      aDirY->setValue(aYDir);
-      std::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
-
-      if (kIsAttrChanged) {
-        /* now it is in updater
-        // the plane was changed, so reexecute sub-elements to update shapes (located in new plane)
-        ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
-        list<ObjectPtr> aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list();
-        for(list<ObjectPtr>::iterator aSubIt = aSubs.begin(); aSubIt != aSubs.end(); aSubIt++) {
-          std::shared_ptr<SketchPlugin_Feature> aFeature = 
-            std::dynamic_pointer_cast<SketchPlugin_Feature>(*aSubIt);
-          if (aFeature && aFactory->validate(aFeature)) {
-            aFeature->execute();
-          }
-        }
-        */
-        kIsAttrChanged = false;
+void SketchPlugin_Sketch::attributeChanged(const std::string& theID) {
+  if (theID == SketchPlugin_Feature::EXTERNAL_ID()) {
+    std::shared_ptr<GeomAPI_Shape> aSelection = 
+      data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value();
+    if (aSelection) { // update arguments due to the selection value
+      // update the sketch plane
+      std::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aSelection);
+      if (aPlane) {
+        double anA, aB, aC, aD;
+        aPlane->coefficients(anA, aB, aC, aD);
+
+        // calculate attributes of the sketch
+        std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
+        std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
+        std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
+        aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
+        std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
+        // X axis is preferable to be dirX on the sketch
+        static const double tol = 1.e-7;
+        bool isX = fabs(anA - 1.0) < tol && fabs(aB) < tol && fabs(aC) < tol;
+        std::shared_ptr<GeomAPI_Dir> aTempDir(
+          isX ? new GeomAPI_Dir(0, 1, 0) : new GeomAPI_Dir(1, 0, 0));
+        std::shared_ptr<GeomAPI_Dir> aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir)));
+        std::shared_ptr<GeomAPI_Dir> aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir)));
+
+        // update position of the sketch
+        std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast
+          <GeomDataAPI_Point>(data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+        anOrigin->setValue(anOrigPnt);
+        std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+          data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+        aNormal->setValue(aNormDir);
+        std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+          data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
+        aDirX->setValue(aXDir);
+        std::shared_ptr<GeomDataAPI_Dir> aDirY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+          data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
+        aDirY->setValue(aYDir);
+        std::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
       }
     }
-    kIsUpdated = false;
-  } else if (kIsUpdated) { // other attributes are updated during the selection comupation
-    kIsAttrChanged = true;
   }
 }
index 66795f7bc266365599daf807136d7174cd956f66..0b4abaa4480b662728be3c6f25b790cf8caa86ae 100644 (file)
@@ -135,7 +135,7 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature//, public GeomAPI_I
   /// Returns the point projected into the sketch plane
   std::shared_ptr<GeomAPI_Pnt2d> to2D(const std::shared_ptr<GeomAPI_Pnt>& thePnt);
 
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged();
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
 protected:
   /// Creates a plane and append it to the list
   /// \param theX the X normal value
index c5b1a50d7ad70b6e6133f8c7e1494166c43a296b..04655869a267485433239823aba809a68e8a63ac 100644 (file)
@@ -97,6 +97,7 @@ void XGUI_PropertyPanel::setModelWidgets(const QList<ModuleBase_ModelWidget*>& t
     //if (aPointWidget)
     //  connect(aPointWidget, SIGNAL(storedPoint2D(ObjectPtr, const std::string&)), this,
     //          SIGNAL(storedPoint2D(ObjectPtr, const std::string&)))
+    //}
 
     if (!isEnableStretch) continue;
     foreach(QWidget* eachWidget, (*anIt)->getControls()) {