]> 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, 5 May 2017 14:22:49 +0000 (17:22 +0300)
committerazv <azv@opencascade.com>
Fri, 5 May 2017 14:22:49 +0000 (17:22 +0300)
Complete new movement functionality

src/SketchPlugin/Test/TestConstraintFixed.py
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Defs.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/SketchSolver_ConstraintFixed.cpp
src/SketchSolver/SketchSolver_ConstraintFixed.h
src/SketchSolver/SketchSolver_ConstraintMovement.cpp
src/SketchSolver/SketchSolver_ConstraintMovement.h
src/SketchSolver/SketchSolver_Group.cpp

index d3b631530a6de163af9f37a91654eaebfe227f4a..c0fb8b3fef9d888b3a45ffb5ca06f0c78928bf7c 100644 (file)
@@ -149,6 +149,141 @@ assert ((aLineAStartPoint.x(), aLineAStartPoint.y()) == (aLineCEndPoint.x(), aLi
 assert ((aLineBStartPoint.x(), aLineBStartPoint.y()) == (aLineAEndPoint.x(), aLineAEndPoint.y()))
 assert ((aLineCStartPoint.x(), aLineCStartPoint.y()) == (aLineBEndPoint.x(), aLineBEndPoint.y()))
 assert (model.dof(aSketchFeature) == 6)
+
+#=========================================================================
+# Create circle, fix it and check the circle is not moved
+#=========================================================================
+aCenter = [10., 10.]
+aRadius = 5.
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchCircle")
+aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
+aCircleRadius = aCircle.real("circle_radius")
+aCircleCenter.setValue(aCenter[0], aCenter[1])
+aCircleRadius.setValue(aRadius)
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 9)
+# fixed constraints
+aSession.startOperation()
+aRigidConstraint = aSketchFeature.addFeature("SketchConstraintRigid")
+aRigidConstraint.refattr("ConstraintEntityA").setObject(aCircle.lastResult())
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 6)
+# move center of circle
+aSession.startOperation()
+aCircleCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.)
+aSession.finishOperation()
+assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1])
+assert (aCircleRadius.value() == aRadius)
+assert (model.dof(aSketchFeature) == 6)
+# change radius of circle
+aSession.startOperation()
+aCircleRadius.setValue(aRadius + 3.)
+aSession.finishOperation()
+assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1])
+assert (aCircleRadius.value() == aRadius)
+assert (model.dof(aSketchFeature) == 6)
+
+#=========================================================================
+# Remove Fixed constraint and check the circle can be moved
+#=========================================================================
+aSession.startOperation()
+aDocument.removeFeature(aRigidConstraint)
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 9)
+# move center of circle
+aCenter = [aCenter[0] + 1., aCenter[1] - 1.]
+aSession.startOperation()
+aCircleCenter.setValue(aCenter[0], aCenter[1])
+aSession.finishOperation()
+assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1])
+assert (aCircleRadius.value() == aRadius)
+assert (model.dof(aSketchFeature) == 9)
+# change radius of circle
+aRadius = aRadius + 3.
+aSession.startOperation()
+aCircleRadius.setValue(aRadius)
+aSession.finishOperation()
+assert (aCircleCenter.x() == aCenter[0] and aCircleCenter.y() == aCenter[1])
+assert (aCircleRadius.value() == aRadius)
+assert (model.dof(aSketchFeature) == 9)
+
+#=========================================================================
+# Create arc, fix it and check it is not moved
+#=========================================================================
+aCenter = [10., 10.]
+aStart = [5., 10.]
+aEnd = [10., 15.]
+aSession.startOperation()
+anArc = aSketchFeature.addFeature("SketchArc")
+anArcCenter = geomDataAPI_Point2D(anArc.attribute("center_point"))
+anArcStart = geomDataAPI_Point2D(anArc.attribute("start_point"))
+anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point"))
+anArcCenter.setValue(aCenter[0], aCenter[1])
+anArcStart.setValue(aStart[0], aStart[1])
+anArcEnd.setValue(aEnd[0], aEnd[1])
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 14)
+# fixed constraints
+aSession.startOperation()
+aRigidConstraint = aSketchFeature.addFeature("SketchConstraintRigid")
+aRigidConstraint.refattr("ConstraintEntityA").setObject(anArc.lastResult())
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 9)
+# move center of arc
+aSession.startOperation()
+anArcCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.)
+aSession.finishOperation()
+assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1])
+assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1])
+assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1])
+assert (model.dof(aSketchFeature) == 9)
+# move start point of arc
+aSession.startOperation()
+anArcStart.setValue(aStart[0] + 1., aStart[1] - 1.)
+aSession.finishOperation()
+assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1])
+assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1])
+assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1])
+assert (model.dof(aSketchFeature) == 9)
+# move end point of arc
+aSession.startOperation()
+anArcEnd.setValue(aEnd[0] + 1., aEnd[1] - 1.)
+aSession.finishOperation()
+assert (anArcCenter.x() == aCenter[0] and anArcCenter.y() == aCenter[1])
+assert (anArcStart.x() == aStart[0] and anArcStart.y() == aStart[1])
+assert (anArcEnd.x() == aEnd[0] and anArcEnd.y() == aEnd[1])
+assert (model.dof(aSketchFeature) == 9)
+
+#=========================================================================
+# Remove Fixed constraint and check the arc can be moved
+#=========================================================================
+aSession.startOperation()
+aDocument.removeFeature(aRigidConstraint)
+aSession.finishOperation()
+assert (model.dof(aSketchFeature) == 14)
+# move center of arc
+aCenter = [anArcCenter.x(), anArcCenter.y()]
+aSession.startOperation()
+anArcCenter.setValue(aCenter[0] + 1., aCenter[1] - 1.)
+aSession.finishOperation()
+assert (anArcCenter.x() != aCenter[0] or anArcCenter.y() != aCenter[1])
+assert (model.dof(aSketchFeature) == 14)
+# move start point of arc
+aStart = [anArcStart.x(), anArcStart.y()]
+aSession.startOperation()
+anArcStart.setValue(aStart[0] + 1., aStart[1] - 1.)
+aSession.finishOperation()
+assert (anArcStart.x() != aStart[0] or anArcStart.y() != aStart[1])
+assert (model.dof(aSketchFeature) == 14)
+# move end point of arc
+aEnd = [anArcEnd.x(), anArcEnd.y()]
+aSession.startOperation()
+anArcEnd.setValue(aEnd[0] + 1., aEnd[1] - 1.)
+aSession.finishOperation()
+assert (anArcEnd.x() != aEnd[0] or anArcEnd.y() != aEnd[1])
+assert (model.dof(aSketchFeature) == 14)
+
 #=========================================================================
 # End of test
 #=========================================================================
index 9274c2878907627ce2f9c77fa3551b8126960db7..3fa64daa86238c460ee6613324decccdff610b1a 100644 (file)
@@ -26,6 +26,7 @@ typedef int ConstraintID;
 // Predefined values for identifiers
 const ConstraintID CID_UNKNOWN  =  0;
 const ConstraintID CID_MOVEMENT = -1;
+const ConstraintID CID_FICTIVE = 1024;
 
 /// Types of entities
 enum SketchSolver_EntityType {
index eb8868409fbcf49e072b8d6d122525737f3beeed..0c1584873293aa8b5ffe609da08dca24f87d31f0 100644 (file)
@@ -13,7 +13,8 @@ PlaneGCSSolver_Solver::PlaneGCSSolver_Solver()
     myDiagnoseBeforeSolve(false),
     myInitilized(false),
     myConfCollected(false),
-    myDOF(0)
+    myDOF(0),
+    myFictiveConstraint(0)
 {
 }
 
@@ -29,6 +30,8 @@ void PlaneGCSSolver_Solver::clear()
   myConstraints.clear();
   myConflictingIDs.clear();
   myDOF = 0;
+
+  removeFictiveConstraint();
 }
 
 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
@@ -73,6 +76,7 @@ void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
 void PlaneGCSSolver_Solver::initialize()
 {
   Events_LongOp::start(this);
+  addFictiveConstraintIfNecessary();
   if (myDiagnoseBeforeSolve)
     diagnose();
   myEquationSystem->declareUnknowns(myParameters);
@@ -98,6 +102,8 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
   if (myInitilized) {
     aResult = (GCS::SolveStatus)myEquationSystem->solve();
   } else {
+    addFictiveConstraintIfNecessary();
+
     if (myDiagnoseBeforeSolve)
       diagnose();
     aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
@@ -121,6 +127,7 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
     aStatus = STATUS_OK;
   }
 
+  removeFictiveConstraint();
   myInitilized = false;
   return aStatus;
 }
@@ -162,3 +169,34 @@ void PlaneGCSSolver_Solver::diagnose()
   myDOF = myEquationSystem->diagnose();
   myDiagnoseBeforeSolve = false;
 }
+
+void PlaneGCSSolver_Solver::addFictiveConstraintIfNecessary()
+{
+  if (!myConstraints.empty() &&
+      myConstraints.find(CID_MOVEMENT) == myConstraints.end())
+    return;
+
+  if (myFictiveConstraint)
+    return; // no need several fictive constraints
+
+  double* aParam = createParameter();
+  double* aFictiveParameter = new double(0.0);
+
+  myFictiveConstraint = new GCS::ConstraintEqual(aFictiveParameter, aParam);
+  myFictiveConstraint->setTag(CID_FICTIVE);
+  myEquationSystem->addConstraint(myFictiveConstraint);
+}
+
+void PlaneGCSSolver_Solver::removeFictiveConstraint()
+{
+  if (myFictiveConstraint) {
+    myEquationSystem->removeConstraint(myFictiveConstraint);
+    myParameters.pop_back();
+
+    GCS::VEC_pD aParams = myFictiveConstraint->params();
+    for (GCS::VEC_pD::iterator anIt = aParams.begin(); anIt != aParams.end(); ++ anIt)
+      delete *anIt;
+    delete myFictiveConstraint;
+    myFictiveConstraint = 0;
+  }
+}
index cb195ada3b7ba2b7e1dd79e4d22c881fc3a2d8f5..8d8322714c26b1916c12ebd95eb5a57b9d0b6368 100644 (file)
@@ -65,6 +65,11 @@ public:
 private:
   void collectConflicting();
 
+  /// \brief Add fictive constraint if the sketch contains temporary constraints only
+  void addFictiveConstraintIfNecessary();
+  /// \brief Remove previously added fictive constraint
+  void removeFictiveConstraint();
+
 private:
   typedef std::map<ConstraintID, std::set<GCSConstraintPtr> > ConstraintMap;
 
@@ -80,6 +85,8 @@ private:
   bool                         myConfCollected;
 
   int                          myDOF;            ///< degrees of freedom
+
+  GCS::Constraint*             myFictiveConstraint;
 };
 
 typedef std::shared_ptr<PlaneGCSSolver_Solver> SolverPtr;
index 88020df90d3c0f8635db3df16b1a217dadb74c6d..c7e6f276f4083312b6ddcaa846ba2a214f0f4011 100644 (file)
@@ -54,9 +54,6 @@ void PlaneGCSSolver_Storage::addConstraint(
 void PlaneGCSSolver_Storage::addMovementConstraint(
     const ConstraintWrapperPtr& theSolverConstraint)
 {
-  if (myConstraintMap.empty())
-    return; // no need to process temporary constraints if there is no active constraint
-
   // before adding movement constraint to solver, re-check its DOF
   if (mySketchSolver->dof() == 0)
     mySketchSolver->diagnose();
index ab58762a4612d41a2031c57c2cf768d1c8e08e2a..3d316d0ff53c34f7250990197c24c04e17acff05 100644 (file)
 #include <GeomDataAPI_Point2D.h>
 #include <SketchPlugin_Feature.h>
 
-#include <cmath>
-
-// Verify the entities are equal
-static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
+/// \brief Get list of parameters of current entity
+static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
 
 
 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
@@ -79,7 +77,11 @@ EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
   return EntityWrapperPtr();
 }
 
-GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity)
+
+
+
+// ==================     Auxiliary functions     ==================
+GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
 {
   GCS::VEC_pD aParameters;
   if (!theEntity)
@@ -110,12 +112,16 @@ GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& t
         std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
     aParameters.push_back(aCircle->center.x);
     aParameters.push_back(aCircle->center.y);
+    aParameters.push_back(aCircle->rad);
     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);
+    aParameters.push_back(anArc->rad);
+    aParameters.push_back(anArc->startAngle);
+    aParameters.push_back(anArc->endAngle);
     break;
     }
   default:
index 7d20a432058cdaba748bea0e3d12f3c9d8867e27..41805b4a086f34912d9f8f57cbaf686fb5d4bb5f 100644 (file)
@@ -33,15 +33,12 @@ protected:
   {}
 
   /// \brief Obtain entity to be fixed
-  virtual EntityWrapperPtr entityToFix();
+  EntityWrapperPtr entityToFix();
 
   /// \brief Create Fixed constraint for the feature basing on its type
   /// \param theFeature [in]  feature, converted to solver specific format
   /// \return Fixed constraint
-  virtual ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature);
-
-  /// \brief Get list of parameters of current entity
-  static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
+  ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature);
 
 protected:
   std::vector<double> myFixedValues;
index 44efdafe9ce1aa3a78a4748ba2bca0b22e6762b9..bec111b871975cab56dc2e8f0aac9890400d1117 100644 (file)
@@ -4,6 +4,9 @@
 #include <SketchSolver_Error.h>
 #include <SketchSolver_Manager.h>
 
+#include <PlaneGCSSolver_EdgeWrapper.h>
+#include <PlaneGCSSolver_PointWrapper.h>
+
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_Line.h>
 
 SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature)
   : SketchSolver_ConstraintFixed(ConstraintPtr()),
-    myMovedFeature(theFeature)
+    myMovedFeature(theFeature),
+    mySimpleMove(true)
 {
 }
 
 SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr thePoint)
   : SketchSolver_ConstraintFixed(ConstraintPtr()),
-    myDraggedPoint(thePoint)
+    myDraggedPoint(thePoint),
+    mySimpleMove(true)
 {
   myMovedFeature = ModelAPI_Feature::feature(thePoint->owner());
 }
@@ -41,57 +46,156 @@ void SketchSolver_ConstraintMovement::process()
     return;
   }
 
-  EntityWrapperPtr aMovedEntity = entityToFix();
-  if (!myErrorMsg.empty() || !aMovedEntity) {
+  mySolverConstraint = initMovement();
+  if (!myErrorMsg.empty() || !mySolverConstraint) {
     // Nothing to move, clear the feature to avoid changing its group
     // after removing the Movement constraint.
     myMovedFeature = FeaturePtr();
     return;
   }
-
-  mySolverConstraint = fixFeature(aMovedEntity);
   myStorage->addMovementConstraint(mySolverConstraint);
 }
 
 
-EntityWrapperPtr SketchSolver_ConstraintMovement::entityToFix()
+static bool isSimpleMove(FeaturePtr theMovedFeature, AttributePtr theDraggedPoint)
+{
+  bool isSimple = true;
+  if (theMovedFeature->getKind() == SketchPlugin_Circle::ID())
+    isSimple = (theDraggedPoint.get() != 0);
+  else if (theMovedFeature->getKind() == SketchPlugin_Arc::ID()) {
+    isSimple = (theDraggedPoint.get() != 0 &&
+                theDraggedPoint->id() == SketchPlugin_Arc::CENTER_ID());
+  }
+  return isSimple;
+}
+
+ConstraintWrapperPtr SketchSolver_ConstraintMovement::initMovement()
 {
+  ConstraintWrapperPtr aConstraint;
+
   // 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 aConstraint;
   }
 
   EntityWrapperPtr anEntity =
       myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature);
   if (!anEntity) {
     myStorage->update(myMovedFeature, true);
-    anEntity = myStorage->entity(myMovedFeature);
+    anEntity =
+        myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature);
+    if (!anEntity)
+      return aConstraint;
+  }
+
+  mySimpleMove = isSimpleMove(myMovedFeature, myDraggedPoint);
+
+  if (mySimpleMove)
+    aConstraint = fixFeature(anEntity);
+  else {
+    if (myDraggedPoint) // start or end point of arc has been moved
+      aConstraint = fixArcExtremity(anEntity);
+    else // arc or circle has been moved
+      aConstraint = fixPointOnCircle(anEntity);
+  }
+
+  return aConstraint;
+}
+
+ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixArcExtremity(
+    const EntityWrapperPtr& theArcExtremity)
+{
+  static const int nbParams = 4;
+  myFixedValues.reserve(nbParams); // moved point and center of arc
+
+  EdgeWrapperPtr aCircularEntity = std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(
+      myStorage->entity(myMovedFeature));
+  std::shared_ptr<GCS::Arc> anArc =
+      std::dynamic_pointer_cast<GCS::Arc>(aCircularEntity->entity());
+
+  PointWrapperPtr aPoint =
+      std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theArcExtremity);
+
+  double* aParams[nbParams] = { aPoint->point()->x, aPoint->point()->y,
+                                anArc->center.x, anArc->center.y };
+
+  std::list<GCSConstraintPtr> aConstraints;
+  for (int i = 0; i < nbParams; ++i) {
+    myFixedValues.push_back(*aParams[i]);
+    GCSConstraintPtr aNewConstraint(new GCS::ConstraintEqual(&myFixedValues[i], aParams[i]));
+    aNewConstraint->rescale(0.01);
+    aConstraints.push_back(aNewConstraint);
+  }
+
+  return ConstraintWrapperPtr(
+      new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
+}
+
+ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixPointOnCircle(
+    const EntityWrapperPtr& theCircular)
+{
+  static const double scale = 0.01;
+  static const int nbParams = 4;
+  myFixedValues.reserve(nbParams); // moved point and center of arc/circle
+
+  EdgeWrapperPtr aCircularEntity =
+      std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theCircular);
+  std::shared_ptr<GCS::Circle> aCircular =
+      std::dynamic_pointer_cast<GCS::Circle>(aCircularEntity->entity());
+
+  // initialize fixed values
+  myFixedValues.push_back(*aCircular->center.x + *aCircular->rad);
+  myFixedValues.push_back(*aCircular->center.y);
+  myFixedValues.push_back(*aCircular->center.x);
+  myFixedValues.push_back(*aCircular->center.y);
+
+  // create a moved point
+  GCS::Point aPointOnCircle;
+  aPointOnCircle.x = &myFixedValues[0];
+  aPointOnCircle.y = &myFixedValues[1];
+
+  std::list<GCSConstraintPtr> aConstraints;
+  // point-on-circle
+  GCSConstraintPtr aNewConstraint(
+      new GCS::ConstraintP2PDistance(aPointOnCircle, aCircular->center, aCircular->rad));
+  aNewConstraint->rescale(scale);
+  aConstraints.push_back(aNewConstraint);
+  // fixed center (x)
+  aNewConstraint = GCSConstraintPtr(
+      new GCS::ConstraintEqual(&myFixedValues[2], aCircular->center.x));
+  aNewConstraint->rescale(scale);
+  aConstraints.push_back(aNewConstraint);
+  // fixed center (y)
+  aNewConstraint = GCSConstraintPtr(
+      new GCS::ConstraintEqual(&myFixedValues[3], aCircular->center.y));
+  aNewConstraint->rescale(scale);
+  aConstraints.push_back(aNewConstraint);
+
+  return ConstraintWrapperPtr(
+      new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
+}
+
+
+void SketchSolver_ConstraintMovement::startPoint(
+    const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint)
+{
+  myStartPoint = theStartPoint;
+  if (!mySimpleMove) {
+    myFixedValues[0] = myStartPoint->x();
+    myFixedValues[1] = myStartPoint->y();
   }
-  return anEntity;
 }
 
 void SketchSolver_ConstraintMovement::moveTo(
     const std::shared_ptr<GeomAPI_Pnt2d>& theDestinationPoint)
 {
-  EntityWrapperPtr aMovedEntity =
-      myDraggedPoint ? myStorage->entity(myDraggedPoint) : 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];
-
-  // no persistent constraints in the storage, thus store values directly to the feature
-  if (myStorage->isEmpty()) {
-    for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
-      *(aFixedParams[i]) = myFixedValues[i];
-    myStorage->setNeedToResolve(true);
-  }
+  int aMaxSize = mySimpleMove ? (int)myFixedValues.size() : 2;
+  for (int i = 0; i < aMaxSize; ++i)
+    myFixedValues[i] += aDelta[i % 2];
 }
index 59fa2a198d9e152da5a47b094c99661cb0970b5f..f25bbb0afff880325d2e95e1a5b29a7bc08fafa6 100644 (file)
@@ -25,8 +25,7 @@ public:
   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; }
+  void startPoint(const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint);
 
   /// \brief Set coordinates of fixed feature to the values where it has been dragged.
   ///        Useful when the feature is being moved.
@@ -43,13 +42,22 @@ protected:
   /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
   virtual void process();
 
-  /// \brief Obtain entity to be fixed
-  virtual EntityWrapperPtr entityToFix();
+  /// \brief Create Fixed constraint for the feature basing on its type and moved point
+  /// \return Fixed constraint
+  ConstraintWrapperPtr initMovement();
+
+  /// \brief Create constraint to fix moved arc extremity
+  ConstraintWrapperPtr fixArcExtremity(const EntityWrapperPtr& theArcExtremity);
+
+  /// \brief Creat constraint to fix moved point on circle/arc
+  ConstraintWrapperPtr fixPointOnCircle(const EntityWrapperPtr& theCircular);
 
 private:
   FeaturePtr       myMovedFeature; ///< fixed feature (if 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
+
+  bool mySimpleMove; ///< simple move, thus all parameters should be increased by movement delta
 };
 
 #endif
index 840c7b736ca94ed52c3b6d968d8e1f2d790043bc..222482386c74abad3a340084cc8583c20da3e648 100644 (file)
@@ -137,12 +137,10 @@ static SolverConstraintPtr move(StoragePtr theStorage,
   if (aConstraint) {
     SolverConstraintPtr(aConstraint)->process(theStorage, theEventsBlocked);
     if (aConstraint->error().empty()) {
-      if (!theStorage->isEmpty())
-        theStorage->setNeedToResolve(true);
-
-      theSketchSolver->initialize();
       aConstraint->startPoint(theFrom);
+      theSketchSolver->initialize();
       aConstraint->moveTo(theTo);
+      theStorage->setNeedToResolve(true);
     } else
       theStorage->notify(aConstraint->movedFeature());
   }