]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Task 2.4. Ability to modify the radius of circles and arcs of circle with the mouse
authorazv <azv@opencascade.com>
Fri, 28 Apr 2017 14:58:33 +0000 (17:58 +0300)
committerazv <azv@opencascade.com>
Fri, 28 Apr 2017 14:59:01 +0000 (17:59 +0300)
Redesign of the movement processing in the PlaneGCSSolver plugin.

17 files changed:
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h
src/SketchSolver/CMakeLists.txt
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h
src/SketchSolver/SketchSolver_ConstraintFixed.cpp
src/SketchSolver/SketchSolver_ConstraintFixed.h
src/SketchSolver/SketchSolver_ConstraintMovement.cpp [new file with mode: 0644]
src/SketchSolver/SketchSolver_ConstraintMovement.h [new file with mode: 0644]
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Group.h
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Manager.h
src/SketchSolver/SketchSolver_Storage.h

index fea8bb975fb63c4dab94419929f8d086683c4ca9..f6eb37c9ea38a3f46382c307c8e6c0c5f51a564c 100644 (file)
@@ -94,6 +94,7 @@ SET(PROJECT_SOURCES
 
 SET(PROJECT_LIBRARIES
     Config
+    GeomAPI
 )
 SET(CMAKE_SWIG_FLAGS -threads -Wall)
 ADD_DEFINITIONS(-DMODELAPI_EXPORTS)
index 00c74c8df695aa05d9cb04e7f66b4b5712134135..2a4665d4b3cb3cf28a614fb92a5e6fd1254d4594 100644 (file)
@@ -10,6 +10,8 @@
 #include <ModelAPI.h>
 #include <ModelAPI_Events.h>
 
+#include <GeomAPI_Pnt2d.h>
+
 ModelAPI_ObjectUpdatedMessage::ModelAPI_ObjectUpdatedMessage(const Events_ID theID,
                                                              const void* theSender)
     : Events_MessageGroup(theID, theSender)
@@ -328,3 +330,41 @@ const std::set<ObjectPtr>& ModelAPI_SolverFailedMessage::objects() const
   return myObjects;
 }
 
+
+// =====   ModelAPI_ObjectMovedMessage   =====
+ModelAPI_ObjectMovedMessage::ModelAPI_ObjectMovedMessage(const void* theSender)
+  : Events_Message(Events_Loop::eventByName(EVENT_OBJECT_MOVED), theSender)
+{
+}
+
+void ModelAPI_ObjectMovedMessage::setMovedObject(const ObjectPtr& theMovedObject)
+{
+  myMovedObject = theMovedObject;
+  myMovedAttribute = AttributePtr();
+}
+
+void ModelAPI_ObjectMovedMessage::setMovedAttribute(const AttributePtr& theMovedAttribute)
+{
+  myMovedAttribute = theMovedAttribute;
+  myMovedObject = ObjectPtr();
+}
+
+void ModelAPI_ObjectMovedMessage::setOriginalPosition(double theX, double theY)
+{
+  myOriginalPosition = std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY));
+}
+
+void ModelAPI_ObjectMovedMessage::setOriginalPosition(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  myOriginalPosition = thePoint;
+}
+
+void ModelAPI_ObjectMovedMessage::setCurrentPosition(double theX, double theY)
+{
+  myCurrentPosition = std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY));
+}
+
+void ModelAPI_ObjectMovedMessage::setCurrentPosition(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  myCurrentPosition = thePoint;
+}
index bbe18f7b6dc92152045a4e247529dad41ae1df13..f0c3b7761b41778f35c4e021fdf14d7415dfb176 100644 (file)
@@ -22,6 +22,7 @@
 
 class ModelAPI_Document;
 class ModelAPI_ResultParameter;
+class GeomAPI_Pnt2d;
 
 /// Event ID that feature is created (comes with ModelAPI_ObjectUpdatedMessage)
 static const char * EVENT_OBJECT_CREATED = "ObjectCreated";
@@ -453,4 +454,46 @@ private:
   int myDOF;
 };
 
+/// Message sent when feature or attrubute has been moved.
+/// Stores the moving object/attribute, original and new positions of mouse.
+class ModelAPI_ObjectMovedMessage : public Events_Message
+{
+  ObjectPtr myMovedObject;
+  AttributePtr myMovedAttribute;
+
+  std::shared_ptr<GeomAPI_Pnt2d> myOriginalPosition;
+  std::shared_ptr<GeomAPI_Pnt2d> myCurrentPosition;
+
+public:
+  MODELAPI_EXPORT ModelAPI_ObjectMovedMessage(const void* theSender = 0);
+
+  /// Set object which is being moved (if the message already contains attribute it will be cleared)
+  MODELAPI_EXPORT void setMovedObject(const ObjectPtr& theMovedObject);
+  /// Set attribute which is being moved (if the message already contains object it will be cleared)
+  MODELAPI_EXPORT void setMovedAttribute(const AttributePtr& theMovedAttribute);
+
+  /// Return moved object
+  ObjectPtr movedObject() const
+  { return myMovedObject; }
+  /// Return moved attribute
+  AttributePtr movedAttribute() const
+  { return myMovedAttribute; }
+
+  /// Set original mouse position
+  MODELAPI_EXPORT void setOriginalPosition(double theX, double theY);
+  /// Set original mouse position
+  MODELAPI_EXPORT void setOriginalPosition(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+  /// Return original mouse position
+  const std::shared_ptr<GeomAPI_Pnt2d>& originalPosition() const
+  { return myOriginalPosition; }
+
+  /// Set current mouse position
+  MODELAPI_EXPORT void setCurrentPosition(double theX, double theY);
+  /// Set current mouse position
+  MODELAPI_EXPORT void setCurrentPosition(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+  /// Return current mouse position
+  const std::shared_ptr<GeomAPI_Pnt2d>& currentPosition() const
+  { return myCurrentPosition; }
+};
+
 #endif
index 776221aa0419dcf7f876bb31b2c0d97dd745ffcf..737934c914568bd2e8380284ae6123eb85605cb6 100644 (file)
@@ -37,6 +37,7 @@ SET(SKETCHSOLVER_CONSTRAINT_HEADERS
     SketchSolver_ConstraintMulti.h
     SketchSolver_ConstraintMultiRotation.h
     SketchSolver_ConstraintMultiTranslation.h
+    SketchSolver_ConstraintMovement.h
 )
 
 SET(SKETCHSOLVER_SOURCES
@@ -60,6 +61,7 @@ SET(SKETCHSOLVER_CONSTRAINT_SOURCES
     SketchSolver_ConstraintMulti.cpp
     SketchSolver_ConstraintMultiRotation.cpp
     SketchSolver_ConstraintMultiTranslation.cpp
+    SketchSolver_ConstraintMovement.cpp
 )
 
 SET(SKETCHSOLVER_LIBRARIES
index 64d9c7fb5512754b5c7391c83411aa31ec72e23a..8640e513ae0add011fbc80298d6c625d5a6de129 100644 (file)
@@ -51,7 +51,7 @@ void PlaneGCSSolver_Storage::addConstraint(
   constraintsToSolver(theSolverConstraint, mySketchSolver);
 }
 
-void PlaneGCSSolver_Storage::addTemporaryConstraint(
+void PlaneGCSSolver_Storage::addMovementConstraint(
     const ConstraintWrapperPtr& theSolverConstraint)
 {
   if (myConstraintMap.empty())
index c7e1d1edaddfa79db572503617f31f45176036e1..6b6f034be55b769dcc6cc38f328a196790c8b550 100644 (file)
@@ -30,10 +30,10 @@ public:
   virtual void addConstraint(ConstraintPtr        theConstraint,
                              ConstraintWrapperPtr theSolverConstraint);
 
-  /// \brief Add list of temporary constraints which will be destroyed
+  /// \brief Add a movement constraint which will be destroyed
   ///        after the next solving of the set of constraints.
   /// \param theSolverConstraint [in]  solver's constraint
-  virtual void addTemporaryConstraint(const ConstraintWrapperPtr& theSolverConstraint);
+  virtual void addMovementConstraint(const ConstraintWrapperPtr& theSolverConstraint);
 
 
   /// \brief Convert feature to the form applicable for specific solver and map it
index 63813ba7555663d5512928142132a8b33008dead..0e609ceee196d8f318942656bc0fd34dec546c45 100644 (file)
@@ -123,12 +123,28 @@ SolverConstraintPtr PlaneGCSSolver_Tools::createConstraint(ConstraintPtr theCons
   return SolverConstraintPtr(new SketchSolver_Constraint(theConstraint));
 }
 
+#ifdef SUPPORT_NEW_MOVE
+std::shared_ptr<SketchSolver_ConstraintMovement> PlaneGCSSolver_Tools::createMovementConstraint(
+    FeaturePtr theMovedFeature)
+{
+  return std::shared_ptr<SketchSolver_ConstraintMovement>(
+      new SketchSolver_ConstraintMovement(theMovedFeature));
+}
+
+std::shared_ptr<SketchSolver_ConstraintMovement> PlaneGCSSolver_Tools::createMovementConstraint(
+    AttributePtr theMovedAttribute)
+{
+  return std::shared_ptr<SketchSolver_ConstraintMovement>(
+      new SketchSolver_ConstraintMovement(theMovedAttribute));
+}
+#else
 std::shared_ptr<SketchSolver_ConstraintFixed> PlaneGCSSolver_Tools::createMovementConstraint(
     FeaturePtr theMovedFeature)
 {
   return std::shared_ptr<SketchSolver_ConstraintFixed>(
       new SketchSolver_ConstraintFixed(theMovedFeature));
 }
+#endif
 
 
 
index 4e43206c177ce64032ca3680939eee913d8fe426..dc520695f36454de8f959dc5cf720d04766cd0fa 100644 (file)
@@ -8,7 +8,7 @@
 #define PlaneGCSSolver_Tools_H_
 
 #include <SketchSolver_Constraint.h>
-#include <SketchSolver_ConstraintFixed.h>
+#include <SketchSolver_ConstraintMovement.h>
 #include <SketchPlugin_Constraint.h>
 
 #include <GeomAPI_Lin2d.h>
@@ -24,9 +24,18 @@ namespace PlaneGCSSolver_Tools
   ///        or returns empty pointer if not all attributes are correct
   SolverConstraintPtr createConstraint(ConstraintPtr theConstraint);
 
+#ifdef SUPPORT_NEW_MOVE
+  /// \brief Creates temporary constraint to fix the feature after movement
+  std::shared_ptr<SketchSolver_ConstraintMovement>
+      createMovementConstraint(FeaturePtr theMovedFeature);
+  /// \brief Creates temporary constraint to fix the attribute after movement
+  std::shared_ptr<SketchSolver_ConstraintMovement>
+      createMovementConstraint(AttributePtr theMovedAttribute);
+#else
   /// \brief Creates temporary constraint to fix the feature after movement
   std::shared_ptr<SketchSolver_ConstraintFixed>
       createMovementConstraint(FeaturePtr theMovedFeature);
+#endif
 
   /// \brief Creates new constraint using given parameters
   /// \param theConstraint [in]  original constraint
index 9c4f2333006bdda7d600c3869722bdbfa8287970..5ea43291508d68ffae39f80936416b04b67c626d 100644 (file)
@@ -16,8 +16,6 @@
 
 // Verify the entities are equal
 static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
-// Convert entity to the list of parameters
-static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
 
 
 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
@@ -26,42 +24,65 @@ SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theCons
   myType = CONSTRAINT_FIXED;
 }
 
+#ifndef SUPPORT_NEW_MOVE
 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
   : SketchSolver_Constraint(),
     myBaseFeature(theFeature)
 {
   myType = CONSTRAINT_FIXED;
 }
+#endif
 
 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
 {
+#ifndef SUPPORT_NEW_MOVE
   if (myBaseFeature)
     myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
   if (myBaseConstraint)
-    SketchSolver_Constraint::blockEvents(isBlocked);
+#endif
+  SketchSolver_Constraint::blockEvents(isBlocked);
 }
 
 void SketchSolver_ConstraintFixed::process()
 {
   cleanErrorMsg();
+#ifdef SUPPORT_NEW_MOVE
+  if (!myBaseConstraint || !myStorage) {
+#else
   if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
+#endif
     // Not enough parameters are assigned
     return;
   }
 
+#ifdef SUPPORT_NEW_MOVE
+  EntityWrapperPtr aBaseEntity = entityToFix();
+  if (!aBaseEntity)
+    myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
+#else
   EntityWrapperPtr aBaseEntity;
   getAttributes(aBaseEntity, myFixedEntity);
   if (!aBaseEntity) {
     moveFeature(); // remove myFixed entity
     myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
   }
+#endif
   if (!myErrorMsg.empty())
     return;
 
-  fixFeature(aBaseEntity);
+#ifdef SUPPORT_NEW_MOVE
+  ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity);
+  myStorage->addConstraint(myBaseConstraint, aConstraint);
+#else
+  myConstraint = fixFeature(aBaseEntity);
+  if (myBaseConstraint)
+    myStorage->addConstraint(myBaseConstraint, myConstraint);
+  else
+    myStorage->addMovementConstraint(myConstraint);
+#endif
 }
 
-void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
+ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
 {
   GCS::VEC_pD aParameters = toParameters(theFeature);
 
@@ -75,15 +96,25 @@ void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
         GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
   }
 
-  myConstraint = ConstraintWrapperPtr(
+  return ConstraintWrapperPtr(
       new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
-
-  if (myBaseConstraint)
-    myStorage->addConstraint(myBaseConstraint, myConstraint);
-  else
-    myStorage->addTemporaryConstraint(myConstraint);
 }
 
+#ifdef SUPPORT_NEW_MOVE
+EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
+{
+  // Constraint Fixed is added by user.
+  // Get the attribute of constraint (it should be alone in the list of constraints).
+  EntityWrapperPtr aValue;
+  std::vector<EntityWrapperPtr> anAttributes;
+  SketchSolver_Constraint::getAttributes(aValue, anAttributes);
+  std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
+  for (; anIt != anAttributes.end(); ++anIt)
+    if (*anIt)
+      return *anIt;
+  return EntityWrapperPtr();
+}
+#else
 void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
                                                  EntityWrapperPtr& theFixedEntity)
 {
@@ -139,12 +170,9 @@ void SketchSolver_ConstraintFixed::moveFeature()
 
   myFixedEntity = EntityWrapperPtr();
 }
+#endif
 
-
-
-
-// ====================   Auxiliary functions   ===============================
-GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
+GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity)
 {
   GCS::VEC_pD aParameters;
   if (!theEntity)
@@ -175,16 +203,20 @@ GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
         std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
     aParameters.push_back(aCircle->center.x);
     aParameters.push_back(aCircle->center.y);
+#ifndef SUPPORT_NEW_MOVE
     aParameters.push_back(aCircle->rad);
+#endif
     break;
     }
   case ENTITY_ARC: {
     std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
     aParameters.push_back(anArc->center.x);
     aParameters.push_back(anArc->center.y);
+#ifndef SUPPORT_NEW_MOVE
     aParameters.push_back(anArc->rad);
     aParameters.push_back(anArc->startAngle);
     aParameters.push_back(anArc->endAngle);
+#endif
     break;
     }
   default:
@@ -194,10 +226,12 @@ GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
   return aParameters;
 }
 
+#ifndef SUPPORT_NEW_MOVE
+// ====================   Auxiliary functions   ===============================
 bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
 {
-  GCS::VEC_pD aParamList1 = toParameters(theEntity1);
-  GCS::VEC_pD aParamList2 = toParameters(theEntity2);
+  GCS::VEC_pD aParamList1 = SketchSolver_ConstraintFixed::toParameters(theEntity1);
+  GCS::VEC_pD aParamList2 = SketchSolver_ConstraintFixed::toParameters(theEntity2);
 
   GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
   GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
@@ -207,3 +241,4 @@ bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEnti
 
   return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();
 }
+#endif
index 7fc02b203f7af254aa297485c47048604b87b9e3..13ec1d160c4d1dd5c1639c0a7b2ebede8f6e1c04 100644 (file)
 /** \class   SketchSolver_ConstraintFixed
  *  \ingroup Plugins
  *  \brief   Stores data of the Fixed constraint
- *
- *  Fixed constraint may have NULL basic SketchPlugin constraint,
- *  because the Fixed constraint may be temporary for correct moving of objects.
  */
 class SketchSolver_ConstraintFixed : public SketchSolver_Constraint
 {
 public:
   /// Creates constraint to manage the given constraint from plugin
   SketchSolver_ConstraintFixed(ConstraintPtr theConstraint);
+#ifndef SUPPORT_NEW_MOVE
   /// Creates temporary constraint based on feature (useful while the feature is being moved)
   SketchSolver_ConstraintFixed(FeaturePtr theFeature);
+#endif
 
   /// \brief Block or unblock events from this constraint
   virtual void blockEvents(bool isBlocked);
 
+#ifndef SUPPORT_NEW_MOVE
   /// \brief Set coordinates of fixed feature to the values where it has been dragged.
   ///        Useful when the feature is being moved.
   void moveFeature();
+#endif
 
 protected:
   /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
   virtual void process();
 
+  /// \brief Generate list of attributes of constraint in order useful for constraints
+  /// \param[out] theValue      numerical characteristic of constraint (e.g. distance)
+  /// \param[out] theAttributes list of attributes to be filled
+  virtual void getAttributes(EntityWrapperPtr& , std::vector<EntityWrapperPtr>& )
+  {}
+
+#ifdef SUPPORT_NEW_MOVE
+  /// \brief Obtain entity to be fixed
+  virtual EntityWrapperPtr entityToFix();
+#else
   /// \brief Generate list of attributes of constraint in order useful for constraints
   /// \param[out] theBaseEntity  the entity which coordinates should be fixed
   /// \param[out] theFixedEntity the entity containing fixed values
   virtual void getAttributes(EntityWrapperPtr& theBaseEntity,
                              EntityWrapperPtr& theFixedEntity);
+#endif
 
-  /// \brief Fixed feature basing on its type
+  /// \brief Create Fixed constraint for the feature basing on its type
   /// \param theFeature [in]  feature, converted to solver specific format
-  virtual void fixFeature(EntityWrapperPtr theFeature);
+  /// \return Fixed constraint
+  virtual ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature);
+
+#ifndef SUPPORT_NEW_MOVE
+public:
+#endif
+  /// \brief Get list of parameters of current entity
+  static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
 
+#ifdef SUPPORT_NEW_MOVE
+protected:
+#else
 private:
   FeaturePtr myBaseFeature; ///< fixed feature (when it is set, myBaseConstraint should be NULL)
 
   ConstraintWrapperPtr myConstraint;
-  std::vector<double> myFixedValues;
   EntityWrapperPtr    myFixedEntity;
+#endif
+  std::vector<double> myFixedValues;
 };
 
 #endif
diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp
new file mode 100644 (file)
index 0000000..59dcac1
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+#include <SketchSolver_ConstraintMovement.h>
+#include <SketchSolver_Error.h>
+#include <SketchSolver_Manager.h>
+
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Circle.h>
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
+
+#include <GeomDataAPI_Point2D.h>
+
+#include <GeomAPI_Pnt2d.h>
+
+
+SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature)
+  : SketchSolver_ConstraintFixed(ConstraintPtr()),
+    myMovedFeature(theFeature)
+{
+}
+
+SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr thePoint)
+  : SketchSolver_ConstraintFixed(ConstraintPtr()),
+    myDraggedPoint(thePoint)
+{
+  myMovedFeature = ModelAPI_Feature::feature(thePoint->owner());
+}
+
+void SketchSolver_ConstraintMovement::blockEvents(bool isBlocked)
+{
+  if (myMovedFeature)
+    myMovedFeature->data()->blockSendAttributeUpdated(isBlocked);
+}
+
+void SketchSolver_ConstraintMovement::process()
+{
+  cleanErrorMsg();
+  if (!myMovedFeature || !myStorage) {
+    // Not enough parameters are initialized
+    return;
+  }
+
+  EntityWrapperPtr aMovedEntity = entityToFix();
+  if (!myErrorMsg.empty() || !aMovedEntity) {
+    // Nothing to move, clear the feature to avoid changing its group
+    // after removing the Movement constraint.
+    myMovedFeature = FeaturePtr();
+    return;
+  }
+
+  ConstraintWrapperPtr aConstraint = fixFeature(aMovedEntity);
+  myStorage->addMovementConstraint(aConstraint);
+}
+
+
+EntityWrapperPtr SketchSolver_ConstraintMovement::entityToFix()
+{
+  // if the feature is copy, do not move it
+  std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(myMovedFeature);
+  if (!aSketchFeature || aSketchFeature->isCopy()) {
+    myStorage->setNeedToResolve(true);
+    return EntityWrapperPtr();
+  }
+
+  return myStorage->entity(myMovedFeature);
+}
+
+void SketchSolver_ConstraintMovement::moveTo(const std::shared_ptr<GeomAPI_Pnt2d>& theDestinationPoint)
+{
+#ifdef SUPPORT_NEW_MOVE
+  EntityWrapperPtr aMovedEntity = myStorage->entity(myMovedFeature);
+  if (!aMovedEntity)
+    return;
+
+  double aDelta[2] = { theDestinationPoint->x() - myStartPoint->x(),
+                       theDestinationPoint->y() - myStartPoint->y() };
+
+  GCS::VEC_pD aFixedParams = toParameters(aMovedEntity);
+  for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
+    myFixedValues[i] = *(aFixedParams[i]) + aDelta[i % 2];
+
+#endif
+}
diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.h b/src/SketchSolver/SketchSolver_ConstraintMovement.h
new file mode 100644 (file)
index 0000000..42d3f39
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (C) 2015-20xx CEA/DEN, EDF R&D
+
+// File:    SketchSolver_ConstraintMovement.h
+// Created: 15 Jun 2015
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchSolver_ConstraintMovement_H_
+#define SketchSolver_ConstraintMovement_H_
+
+#include <SketchSolver_ConstraintFixed.h>
+
+class GeomAPI_Pnt2d;
+
+/** \class   SketchSolver_ConstraintMovement
+ *  \ingroup Plugins
+ *  \brief   Stores data to the Fixed constraint for the moved feature only
+ */
+class SketchSolver_ConstraintMovement : public SketchSolver_ConstraintFixed
+{
+public:
+  /// Creates movement constraint based on feature
+  SketchSolver_ConstraintMovement(FeaturePtr theFeature);
+
+  /// Creates movement constraint based on point
+  SketchSolver_ConstraintMovement(AttributePtr thePoint);
+
+  /// \brief Set coordinates of the start point of the movement
+  void startPoint(const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint)
+  { myStartPoint = theStartPoint; }
+
+  /// \brief Set coordinates of fixed feature to the values where it has been dragged.
+  ///        Useful when the feature is being moved.
+  void moveTo(const std::shared_ptr<GeomAPI_Pnt2d>& theDestinationPoint);
+
+  /// \brief Block or unblock events from this constraint
+  virtual void blockEvents(bool isBlocked);
+
+  /// \brief Returns moved feature
+  FeaturePtr movedFeature() const
+  { return myMovedFeature; }
+
+protected:
+  /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
+  virtual void process();
+
+  /// \brief Obtain entity to be fixed
+  virtual EntityWrapperPtr entityToFix();
+
+private:
+  FeaturePtr       myMovedFeature; ///< fixed feature (when it is set, myBaseConstraint should be NULL)
+  AttributePtr     myDraggedPoint; ///< one of the feature points which has been moved
+  std::shared_ptr<GeomAPI_Pnt2d> myStartPoint; ///< start point of the movement
+};
+
+#endif
index a0a7d362408d8fa2d5b6df058fcbc7d3b1511d0a..6f855c97601e4f104516520f3764b4545c063de0 100644 (file)
@@ -56,7 +56,7 @@ static void sendMessage(const char* theMessageName,
 
 
 // ========================================================
-// =========  SketchSolver_Group  ===============
+// =========       SketchSolver_Group       ===============
 // ========================================================
 
 SketchSolver_Group::SketchSolver_Group(const CompositeFeaturePtr& theWorkplane)
@@ -115,6 +115,62 @@ bool SketchSolver_Group::updateFeature(FeaturePtr theFeature)
   return myStorage->update(theFeature);
 }
 
+#ifdef SUPPORT_NEW_MOVE
+template <class Type>
+static SolverConstraintPtr move(StoragePtr theStorage,
+                                SolverPtr theSketchSolver,
+                                int theSketchDOF,
+                                bool theEventsBlocked,
+                                Type theFeatureOrPoint,
+                                const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+                                const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+  bool isEntityExists = (theStorage->entity(theFeatureOrPoint).get() != 0);
+  if (theSketchDOF == 0 && isEntityExists) {
+    // avoid moving elements of fully constrained sketch
+    theStorage->refresh();
+    return SolverConstraintPtr();
+  }
+
+  // Create temporary Fixed constraint
+  std::shared_ptr<SketchSolver_ConstraintMovement> aConstraint =
+      PlaneGCSSolver_Tools::createMovementConstraint(theFeatureOrPoint);
+  if (aConstraint) {
+    SolverConstraintPtr(aConstraint)->process(theStorage, theEventsBlocked);
+    if (aConstraint->error().empty()) {
+      if (!theStorage->isEmpty())
+        theStorage->setNeedToResolve(true);
+
+      theSketchSolver->initialize();
+      aConstraint->startPoint(theFrom);
+      aConstraint->moveTo(theTo);
+    } else
+      theStorage->notify(aConstraint->movedFeature());
+  }
+
+  return aConstraint;
+}
+
+bool SketchSolver_Group::moveFeature(FeaturePtr theFeature,
+                                     const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+                                     const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+  SolverConstraintPtr aConstraint =
+      move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theFeature, theFrom, theTo);
+  setTemporary(aConstraint);
+  return true;
+}
+
+bool SketchSolver_Group::movePoint(AttributePtr theAttribute,
+                                   const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+                                   const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+  SolverConstraintPtr aConstraint =
+      move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theAttribute, theFrom, theTo);
+  setTemporary(aConstraint);
+  return true;
+}
+#else
 bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
 {
   bool isFeatureExists = (myStorage->entity(theFeature).get() != 0);
@@ -142,6 +198,7 @@ bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
 
   return true;
 }
+#endif
 
 // ============================================================================
 //  Function: resolveConstraints
@@ -357,7 +414,8 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint)
 // ============================================================================
 void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint)
 {
-  myTempConstraints.insert(theConstraint);
+  if (theConstraint)
+    myTempConstraints.insert(theConstraint);
 }
 
 // ============================================================================
index fa590266467fe289621e49dd605838b8ab64ae7d..ae10ff58b551ac02b17772e105a913add1604b35 100644 (file)
@@ -17,6 +17,8 @@
 #include <memory>
 #include <map>
 
+class GeomAPI_Pnt2d;
+
 typedef std::map<ConstraintPtr, SolverConstraintPtr> ConstraintConstraintMap;
 
 /** \class   SketchSolver_Group
@@ -57,12 +59,35 @@ class SketchSolver_Group
    */
   bool updateFeature(FeaturePtr theFeature);
 
+#ifdef SUPPORT_NEW_MOVE
+  /** \brief Updates the data corresponding the specified feature moved in GUI.
+   *         Special kind of Fixed constraints is created.
+   *  \param[in] theFeature the feature to be updated
+   *  \param[in] theFrom    start point of the movement
+   *  \param[in] theTo      final point of the movement
+   *  \return \c true, if the feature is really moved
+   */
+  bool moveFeature(FeaturePtr theFeature,
+                   const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+                   const std::shared_ptr<GeomAPI_Pnt2d>& theTo);
+  /** \brief Updates the data corresponding the specified point moved in GUI.
+   *         Special kind of Fixed constraints is created.
+   *  \param[in] thePoint the attribute to be updated
+   *  \param[in] theFrom  start point of the movement
+   *  \param[in] theTo    final point of the movement
+   *  \return \c true, if the attribute is really moved
+   */
+  bool movePoint(AttributePtr thePoint,
+                 const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+                 const std::shared_ptr<GeomAPI_Pnt2d>& theTo);
+#else
   /** \brief Updates the data corresponding the specified feature moved in GUI.
    *         Additional Fixed constraints are created.
    *  \param[in] theFeature the feature to be updated
    *  \return \c true, if the feature is moved
    */
   bool moveFeature(FeaturePtr theFeature);
+#endif
 
   /// Returns the current workplane
   inline const CompositeFeaturePtr& getWorkplane() const
index 849c95b0c9eb6ac72de7010c53c2ec4abbb99b1a..f0d6eb21045fab8c72a8063df93e48500e594248 100644 (file)
@@ -8,10 +8,12 @@
 #include "SketchSolver_Error.h"
 
 #include <Events_Loop.h>
+#include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
+#include <SketchPlugin_Constraint.h>
 #include <SketchPlugin_Sketch.h>
 
 /// Global constraint manager object
@@ -52,8 +54,6 @@ SketchSolver_Manager::SketchSolver_Manager()
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_MOVED));
 
-  ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED));
-  ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED));
   Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_PREPARED));
 }
 
@@ -91,20 +91,27 @@ void SketchSolver_Manager::processEvent(
     return;
   myIsComputed = true;
 
+#ifdef SUPPORT_NEW_MOVE
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)
+      || theMessage->eventID() == anUpdateEvent) {
+#else
   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)
       || theMessage->eventID() == anUpdateEvent
       || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
+#endif
     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
     std::set<ObjectPtr> aFeatures = anUpdateMsg->objects();
 
     isUpdateFlushed = stopSendUpdate();
 
+#ifndef SUPPORT_NEW_MOVE
     isMovedEvt = theMessage->eventID()
           == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
 
     // Shows that the message has at least one feature applicable for solver
     bool hasProperFeature = false;
+#endif
 
     // update sketch features only
     std::set<ObjectPtr>::iterator aFeatIter;
@@ -114,12 +121,39 @@ void SketchSolver_Manager::processEvent(
       if (!aFeature || aFeature->isMacro())
         continue;
 
+#ifdef SUPPORT_NEW_MOVE
+      updateFeature(aFeature);
+#else
       hasProperFeature = updateFeature(aFeature, isMovedEvt) || hasProperFeature;
+#endif
     }
 
+#ifndef SUPPORT_NEW_MOVE
     if (isMovedEvt && hasProperFeature)
       needToResolve = true;
 
+#else
+  } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
+    std::shared_ptr<ModelAPI_ObjectMovedMessage> aMoveMsg =
+        std::dynamic_pointer_cast<ModelAPI_ObjectMovedMessage>(theMessage);
+
+    ObjectPtr aMovedObject = aMoveMsg->movedObject();
+    std::shared_ptr<GeomDataAPI_Point2D> aMovedPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMoveMsg->movedAttribute());
+
+    const std::shared_ptr<GeomAPI_Pnt2d>& aFrom = aMoveMsg->originalPosition();
+    const std::shared_ptr<GeomAPI_Pnt2d>& aTo = aMoveMsg->currentPosition();
+
+    if (aMovedObject) {
+      FeaturePtr aMovedFeature = ModelAPI_Feature::feature(aMovedObject);
+      std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+          std::dynamic_pointer_cast<SketchPlugin_Feature>(aMovedFeature);
+      if (aSketchFeature && !aSketchFeature->isMacro())
+        needToResolve = moveFeature(aSketchFeature, aFrom, aTo);
+    } else if (aMovedPoint)
+      needToResolve = moveAttribute(aMovedPoint, aFrom, aTo);
+
+#endif
   } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
     std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleteMsg =
       std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
@@ -165,11 +199,15 @@ void SketchSolver_Manager::processEvent(
 }
 
 // ============================================================================
-//  Function: changeConstraintOrEntity
-//  Purpose:  create/update the constraint or the feature and place it into appropriate group
+//  Function: updateFeature
+//  Purpose:  create/update constraint or feature in appropriate group
 // ============================================================================
+#ifdef SUPPORT_NEW_MOVE
+bool SketchSolver_Manager::updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature)
+#else
 bool SketchSolver_Manager::updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature,
                                          bool theMoved)
+#endif
 {
   // Check feature validity and find a group to place it.
   // If the feature is not valid, the returned group will be empty.
@@ -185,13 +223,56 @@ bool SketchSolver_Manager::updateFeature(std::shared_ptr<SketchPlugin_Feature> t
   bool isOk = false;
   if (aConstraint)
     isOk = aGroup->changeConstraint(aConstraint);
+#ifndef SUPPORT_NEW_MOVE
   else if (theMoved)
     isOk = aGroup->moveFeature(theFeature);
+#endif
   else
     isOk = aGroup->updateFeature(theFeature);
   return isOk;
 }
 
+#ifdef SUPPORT_NEW_MOVE
+// ============================================================================
+//  Function: moveFeature
+//  Purpose:  move given feature in appropriate group
+// ============================================================================
+bool SketchSolver_Manager::moveFeature(
+    const std::shared_ptr<SketchPlugin_Feature>& theMovedFeature,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+  SketchGroupPtr aGroup = findGroup(theMovedFeature);
+  if (!aGroup)
+    return false;
+
+  aGroup->blockEvents(true);
+  return aGroup->moveFeature(theMovedFeature, theFrom, theTo);
+}
+
+// ============================================================================
+//  Function: moveAttribute
+//  Purpose:  move given attribute in appropriate group
+// ============================================================================
+bool SketchSolver_Manager::moveAttribute(
+    const std::shared_ptr<GeomDataAPI_Point2D>& theMovedAttribute,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+    const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
+{
+  FeaturePtr anOwner = ModelAPI_Feature::feature(theMovedAttribute->owner());
+  std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(anOwner);
+  SketchGroupPtr aGroup;
+  if (aSketchFeature)
+    aGroup = findGroup(aSketchFeature);
+  if (!aGroup)
+    return false;
+
+  aGroup->blockEvents(true);
+  return aGroup->movePoint(theMovedAttribute, theFrom, theTo);
+}
+#endif
+
 // ============================================================================
 //  Function: findGroup
 //  Purpose:  search groups of entities interacting with given feature
index fc1b4222956f80db2f05942fc36b34cc9afa9530..f88e92a3a832309735ae63dfa726ad0c8a98dabf 100644 (file)
 #include <SketchSolver_Group.h>
 
 #include <Events_Listener.h>
-#include <SketchPlugin_Constraint.h>
 
 #include <list>
 #include <set>
 
+class GeomAPI_Pnt2d;
+class GeomDataAPI_Point2D;
+class SketchPlugin_Constraint;
+
 /** \class   SketchSolver_Manager
  *  \ingroup Plugins
  *  \brief   Listens the changes of SketchPlugin features and transforms the Constraint
@@ -45,12 +48,40 @@ protected:
   SketchSolver_Manager();
   ~SketchSolver_Manager();
 
+#ifdef SUPPORT_NEW_MOVE
+  /** \brief Adds or updates a constraint or an entity in the suitable group
+   *  \param[in] theFeature sketch feature to be changed
+   *  \return \c true if the feature changed successfully
+   */
+  bool updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature);
+
+  /** \brief Move feature
+   *  \param[in] theMovedFeature dragged sketch feature
+   *  \param[in] theFromPoint    original position of the feature
+   *  \param[in] theToPoint      prefereble position of the feature (current position of the mouse)
+   *  \return \c true if the feature has been changed successfully
+   */
+  bool moveFeature(const std::shared_ptr<SketchPlugin_Feature>& theMovedFeature,
+                   const std::shared_ptr<GeomAPI_Pnt2d>& theFromPoint,
+                   const std::shared_ptr<GeomAPI_Pnt2d>& theToPoint);
+
+  /** \brief Move feature using its moved attribute
+   *  \param[in] theMovedAttribute dragged point attribute of sketch feature
+   *  \param[in] theFromPoint      original position of the moved point
+   *  \param[in] theToPoint        prefereble position (current position of the mouse)
+   *  \return \c true if the attribute owner has been changed successfully
+   */
+  bool moveAttribute(const std::shared_ptr<GeomDataAPI_Point2D>& theMovedAttribute,
+                     const std::shared_ptr<GeomAPI_Pnt2d>& theFromPoint,
+                     const std::shared_ptr<GeomAPI_Pnt2d>& theToPoint);
+#else
   /** \brief Adds or updates a constraint or an entity in the suitable group
    *  \param[in] theFeature sketch feature to be changed
    *  \param[in] theMoved   \c true if the feature has been moved in the viewer
    *  \return \c true if the feature changed successfully
    */
   bool updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature, bool theMoved = false);
+#endif
 
   /** \brief Removes a constraint from the manager
    *  \param[in] theConstraint constraint to be removed
index 6ef8d08b57ca9a464199bd836bc572b755be2258..99ddc60989f319071cbe2ffb8dfd0dc2bed288ba 100644 (file)
@@ -43,10 +43,10 @@ public:
   virtual void addConstraint(ConstraintPtr        theConstraint,
                              ConstraintWrapperPtr theSolverConstraint);
 
-  /// \brief Add list of temporary constraints which will be destroyed
+  /// \brief Add a movement constraint which will be destroyed
   ///        after the next solving of the set of constraints.
   /// \param theSolverConstraint [in]  solver's constraint
-  virtual void addTemporaryConstraint(const ConstraintWrapperPtr& theSolverConstraint) = 0;
+  virtual void addMovementConstraint(const ConstraintWrapperPtr& theSolverConstraint) = 0;
 
   /// \brief Change mapping feature from SketchPlugin and
   ///        the entity applicable for corresponding solver.