]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Movement of arc in ward of sketch solver (improvement #730, issue #1172)
authorazv <azv@opencascade.com>
Fri, 22 Jan 2016 11:41:42 +0000 (14:41 +0300)
committerazv <azv@opencascade.com>
Fri, 22 Jan 2016 11:42:45 +0000 (14:42 +0300)
12 files changed:
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchSolver/CMakeLists.txt
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/SketchSolver_Builder.cpp
src/SketchSolver/SketchSolver_Builder.h
src/SketchSolver/SketchSolver_ConstraintFixed.cpp
src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.cpp [new file with mode: 0644]
src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.h [new file with mode: 0644]
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h

index 261e70b9526613c849954c5af876529c1c585dfb..9ec13a3205a7edc0473ef56d2d3b553743768c5c 100644 (file)
@@ -94,13 +94,11 @@ void SketchPlugin_Arc::execute()
     // compute and change the arc end point
     std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
         GeomDataAPI_Point2D>(data()->attribute(END_ID()));
-    /* must be automatically done in attributeChanged
     std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
         new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
     std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
     if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
       anEndAttr->setValue(aProjection);
-    */
     std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
     AttributeBooleanPtr isInversed =
         std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(attribute(INVERSED_ID()));
@@ -249,64 +247,11 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
     }
     return;
   }
-  if (!aCenterAttr->isInitialized())
-    return;
-  if (!aStartAttr->isInitialized())
-    return;
-  if (!anEndAttr->isInitialized())
+  if (!isFeatureValid())
     return;
 
   // update the points in accordance to the changed point changes
-  if (theID == END_ID() && !myEndUpdate) {
-    myEndUpdate = true;
-    // compute and change the arc end point
-    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
-        new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
-    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
-    if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) {
-      if (!isStable()) { // issue #855: trying to update only not-updated coordinate if it is possible
-        if (fabs(myXEndBefore - anEndAttr->x()) < 1.e-10) { // keep Y unchanged
-          double aVy = aCenterAttr->y() - anEndAttr->y();
-          double aVy2 = aVy * aVy;
-          double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
-          if (aVy2 <= aR2) {
-            double aDX = sqrt(aR2 - aVy * aVy);
-            if (anEndAttr->x() > aCenterAttr->x())
-              aProjection->setX(aCenterAttr->x() + aDX);
-            else 
-              aProjection->setX(aCenterAttr->x() - aDX);
-            aProjection->setY(anEndAttr->y());
-          }
-        } else if (fabs(myYEndBefore - anEndAttr->y()) < 1.e-10) { // keep X unchanged
-          double aVx = aCenterAttr->x() - anEndAttr->x();
-          double aVx2 = aVx * aVx;
-          double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
-          if (aVx2 <= aR2) {
-            double aDY = sqrt(aR2 - aVx * aVx);
-            if (anEndAttr->y() > aCenterAttr->y())
-              aProjection->setY(aCenterAttr->y() + aDY);
-            else 
-              aProjection->setY(aCenterAttr->y() - aDY);
-            aProjection->setX(anEndAttr->x());
-          }
-        }
-      }
-
-      anEndAttr->setValue(aProjection);
-    }
-    myXEndBefore = anEndAttr->x();
-    myYEndBefore = anEndAttr->y();
-    myEndUpdate = false;
-  } else if (theID == START_ID() && !myStartUpdate) {
-    myStartUpdate = true;
-    // compute and change the arc start point
-    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
-        new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt()));
-    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aStartAttr->pnt());
-    if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance)
-      aStartAttr->setValue(aProjection);
-    myStartUpdate = false;
-  } else if (theID == CENTER_ID() && !myEndUpdate) {
+  if (theID == CENTER_ID() && !myEndUpdate) {
     myEndUpdate = true;
     // compute and change the arc end point
     std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
index 91cfe6c82b8b73b866556b995730e6d09c810784..8e18f16da387b9314ba5bce708b62bf11d92e2e3 100644 (file)
@@ -13,6 +13,7 @@ SET(PROJECT_HEADERS
     SketchSolver_ConstraintLength.h
     SketchSolver_ConstraintMirror.h
     SketchSolver_ConstraintFixed.h
+    SketchSolver_ConstraintFixedArcRadius.h
     SketchSolver_ConstraintTangent.h
     SketchSolver_ConstraintMulti.h
     SketchSolver_ConstraintMultiRotation.h
@@ -37,6 +38,7 @@ SET(PROJECT_SOURCES
     SketchSolver_ConstraintLength.cpp
     SketchSolver_ConstraintMirror.cpp
     SketchSolver_ConstraintFixed.cpp
+    SketchSolver_ConstraintFixedArcRadius.cpp
     SketchSolver_ConstraintTangent.cpp
     SketchSolver_ConstraintMulti.cpp
     SketchSolver_ConstraintMultiRotation.cpp
index 33a04b7f3800cdcca8d767897fced30d55e99153..5d0578c06af45302b5c3b5e61449a93e7ec74761 100644 (file)
@@ -178,7 +178,7 @@ bool PlaneGCSSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
 
   if (aConstraint->valueParameter())
     isFullyRemoved = remove(aConstraint->valueParameter()) && isFullyRemoved;
-  if (!isFullyRemoved &&
+  if (!isFullyRemoved && aConstraint->baseConstraint() &&
      (!aConstraint->baseConstraint()->data() || !aConstraint->baseConstraint()->data()->isValid()))
     isFullyRemoved = true;
   setNeedToResolve(true);
index ff34136493468ad554df9d61b17ed0fba4badf95..dece279ca8e054703f825bcdef9aec4440168637 100644 (file)
@@ -11,6 +11,7 @@
 #include <SketchSolver_ConstraintDistance.h>
 #include <SketchSolver_ConstraintEqual.h>
 #include <SketchSolver_ConstraintFixed.h>
+#include <SketchSolver_ConstraintFixedArcRadius.h>
 #include <SketchSolver_ConstraintLength.h>
 #include <SketchSolver_ConstraintMirror.h>
 #include <SketchSolver_ConstraintTangent.h>
@@ -107,6 +108,14 @@ SolverConstraintPtr SketchSolver_Builder::createFixedConstraint(FeaturePtr theFi
   return SolverConstraintPtr(new SketchSolver_ConstraintFixed(theFixedFeature));
 }
 
+SolverConstraintPtr SketchSolver_Builder::createFixedArcRadiusConstraint(FeaturePtr theArc) const
+{
+  DataPtr aData = theArc->data();
+  if (!aData || !aData->isValid())
+    return SolverConstraintPtr();
+  return SolverConstraintPtr(new SketchSolver_ConstraintFixedArcRadius(theArc));
+}
+
 SolverConstraintPtr SketchSolver_Builder::createMovementConstraint(FeaturePtr theFixedFeature) const
 {
   DataPtr aData = theFixedFeature->data();
index e7e6f5cf04b89eed2763a54350213349a2402a2e..86a395bc29a4925e818a4254747fcb622f389926 100644 (file)
@@ -32,6 +32,9 @@ public:
   /// \brief Creates temporary constraint to fix the placement of the feature
   SolverConstraintPtr createFixedConstraint(FeaturePtr theFixedFeature) const;
 
+  /// \brief Creates temporary constraint to fix radius of the arc
+  SolverConstraintPtr createFixedArcRadiusConstraint(FeaturePtr theArc) const;
+
   /// \brief Creates temporary constraint to fix the feature after movement
   SolverConstraintPtr createMovementConstraint(FeaturePtr theFixedFeature) const;
 
index ee1700d22a40a42b59910e532ffd0f2ea264dc6b..13c2fa50dc47e3dc377e92f84dc4b78bb969c926 100644 (file)
@@ -69,7 +69,7 @@ void SketchSolver_ConstraintFixed::getAttributes(
   EntityWrapperPtr aSolverEntity;
   if (myBaseFeature) {
     // The feature is fixed.
-    myStorage->update(myBaseFeature, myGroupID);
+    myStorage->update(myBaseFeature/*, myGroupID*/);
     aSolverEntity = myStorage->entity(myBaseFeature);
   } else if (myBaseConstraint) {
     // Constraint Fixed is added by user.
diff --git a/src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.cpp b/src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.cpp
new file mode 100644 (file)
index 0000000..e451371
--- /dev/null
@@ -0,0 +1,61 @@
+#include <SketchSolver_ConstraintFixedArcRadius.h>
+#include <SketchSolver_Error.h>
+#include <SketchSolver_Manager.h>
+
+#include <SketchPlugin_Arc.h>
+#include <GeomAPI_Pnt2d.h>
+
+SketchSolver_ConstraintFixedArcRadius::SketchSolver_ConstraintFixedArcRadius(FeaturePtr theFeature)
+  : SketchSolver_ConstraintFixed(theFeature)
+{
+  myType = CONSTRAINT_RADIUS;
+  process();
+}
+
+void SketchSolver_ConstraintFixedArcRadius::process()
+{
+  cleanErrorMsg();
+  if (!myBaseFeature || !myStorage || myGroupID == GID_UNKNOWN) {
+    // Not enough parameters are assigned
+    return;
+  }
+
+  if (myBaseFeature->getKind() != SketchPlugin_Arc::ID()) {
+    myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
+    return;
+  }
+
+  ParameterWrapperPtr aValue;
+  std::vector<EntityWrapperPtr> anEntities;
+  getAttributes(aValue, anEntities);
+  if (!myErrorMsg.empty() || anEntities.empty())
+    return;
+  fixFeature(anEntities.front());
+}
+
+void SketchSolver_ConstraintFixedArcRadius::fixFeature(EntityWrapperPtr theFeature)
+{
+  BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+
+  // Calculate radius of the arc
+  std::list<EntityWrapperPtr> aSubs = theFeature->subEntities();
+  std::list<EntityWrapperPtr>::const_iterator aSubIt = aSubs.begin();
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter = aBuilder->point(*aSubIt++);
+  std::shared_ptr<GeomAPI_Pnt2d> aStart  = aBuilder->point(*aSubIt++);
+  double aRadius = aCenter->distance(aStart);
+
+  // Create constraint
+  std::list<ConstraintWrapperPtr> aConstrList = aBuilder->createConstraint(ConstraintPtr(),
+      myGroupID, mySketchID, myType, aRadius, EntityWrapperPtr(), EntityWrapperPtr(), theFeature);
+  myRadiusConstraint = aConstrList.front();
+  myStorage->addConstraint(ConstraintPtr(), myRadiusConstraint);
+}
+
+bool SketchSolver_ConstraintFixedArcRadius::remove()
+{
+  bool isFullyRemoved = SketchSolver_ConstraintFixed::remove();
+  if (myRadiusConstraint)
+    isFullyRemoved = myStorage->removeConstraint(ConstraintPtr()) &&
+                     myStorage->remove(myRadiusConstraint) && isFullyRemoved;
+  return isFullyRemoved;
+}
diff --git a/src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.h b/src/SketchSolver/SketchSolver_ConstraintFixedArcRadius.h
new file mode 100644 (file)
index 0000000..f4fc805
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:    SketchSolver_ConstraintFixedArcRadiusArcRadius.h
+// Created: 22 Jan 2016
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchSolver_ConstraintFixedArcRadius_H_
+#define SketchSolver_ConstraintFixedArcRadius_H_
+
+#include "SketchSolver.h"
+#include <SketchSolver_ConstraintFixed.h>
+
+/** \class   SketchSolver_ConstraintFixedArcRadius
+ *  \ingroup Plugins
+ *  \brief   Fix radius of the arc. Temporary constraint. Based on an arc, sharp!
+ */
+class SketchSolver_ConstraintFixedArcRadius : public SketchSolver_ConstraintFixed
+{
+public:
+  /// Creates temporary constraint based on feature
+  SketchSolver_ConstraintFixedArcRadius(FeaturePtr theFeature);
+
+  /// \brief Tries to remove constraint
+  /// \return \c false, if current constraint contains another SketchPlugin constraints (like for multiple coincidence)
+  virtual bool remove();
+
+protected:
+  /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
+  virtual void process();
+
+  /// \brief Fix radius of arc
+  /// \param theFeature [in]  feature, converted to solver specific format
+  virtual void fixFeature(EntityWrapperPtr theFeature);
+
+private:
+  ConstraintWrapperPtr myRadiusConstraint;
+};
+
+#endif
index 34fb4d17b525179faf294141fff76a7bb9c23f5e..950004104df5b14ffcbb08983f976bf11dcd9f02 100644 (file)
@@ -19,6 +19,7 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 
+#include <SketchPlugin_Arc.h>
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintDistance.h>
@@ -222,6 +223,17 @@ void SketchSolver_Group::moveFeature(FeaturePtr theFeature)
 
   // Secondly, search attributes of the feature in the list of the Multi constraints and update them
   updateMultiConstraints(myConstraints, theFeature);
+
+  // Workaround to process arcs.
+  // When move unconstrained arc, add temporary constraint to fix radius.
+  if (theFeature->getKind() == SketchPlugin_Arc::ID()) {
+    SolverConstraintPtr aFixedRadius = aBuilder->createFixedArcRadiusConstraint(theFeature);
+    if (aFixedRadius) {
+      aFixedRadius->process(myStorage, getId(), getWorkplaneId());
+      if (aFixedRadius->error().empty())
+        setTemporary(aFixedRadius);
+    }
+  }
 }
 
 // ============================================================================
@@ -270,7 +282,7 @@ bool SketchSolver_Group::updateWorkplane()
 bool SketchSolver_Group::resolveConstraints()
 {
   bool aResolved = false;
-  bool isGroupEmpty = isEmpty();
+  bool isGroupEmpty = isEmpty() && myStorage->isEmpty();
   if (myStorage->isNeedToResolve() && !isGroupEmpty) {
     if (!mySketchSolver)
       mySketchSolver = SketchSolver_Manager::instance()->builder()->createSolver();
index ba8b2ea17a80a839991b123ebc9dcb71655e65bb..546186bb53133738fd53f02a2eb2fb3243b831e3 100644 (file)
@@ -287,10 +287,21 @@ bool SketchSolver_Manager::changeFeature(std::shared_ptr<SketchPlugin_Feature> t
 // ============================================================================
 void SketchSolver_Manager::moveEntity(std::shared_ptr<SketchPlugin_Feature> theFeature)
 {
+  bool isMoved = false;
   std::vector<SketchSolver_Group*>::iterator aGroupIt = myGroups.begin();
   for (; aGroupIt != myGroups.end(); aGroupIt++)
-    if (!(*aGroupIt)->isEmpty() && (*aGroupIt)->isInteract(theFeature))
+    if (!(*aGroupIt)->isEmpty() && (*aGroupIt)->isInteract(theFeature)) {
       (*aGroupIt)->moveFeature(theFeature);
+      isMoved = true;
+    }
+
+  if (!isMoved && theFeature->getKind() == SketchPlugin_Arc::ID()) {
+    // Workaround to move arc.
+    // If the arc has not been constrained, we will push it into empty group and apply movement.
+    for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); aGroupIt++)
+      if ((*aGroupIt)->isEmpty())
+        (*aGroupIt)->moveFeature(theFeature);
+  }
 }
 
 // ============================================================================
index e606f44c132d84324274139e8eaac3bcc90e9c0d..e75992823848cbb6d47635c685004f1d7a6706a3 100644 (file)
@@ -76,7 +76,7 @@ void SketchSolver_Storage::addConstraint(
   if (!theSolverConstraints.empty() || aFound == myConstraintMap.end())
     myConstraintMap[theConstraint] = theSolverConstraints;
   // block events if necessary
-  if (myEventsBlocked && theConstraint->data() && theConstraint->data()->isValid())
+  if (myEventsBlocked && theConstraint && theConstraint->data() && theConstraint->data()->isValid())
     theConstraint->data()->blockSendAttributeUpdated(myEventsBlocked);
 }
 
index 7cd073f70f13dc59bf47eff3d805c976dcfb0d08..2be30dec3cd89f4b5999b04ccbdfd2a727e50036 100644 (file)
@@ -19,6 +19,7 @@
 #include <SketchPlugin_Constraint.h>
 
 class SketchSolver_ConstraintDistance;
+class SketchSolver_ConstraintFixedArcRadius;
 typedef std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> > CoincidentPointsMap;
 
 
@@ -113,6 +114,10 @@ public:
   /// \brief Check the features is not removed
   bool isConsistent() const;
 
+  /// \brief Check the storage has constraints
+  bool isEmpty() const
+  { return myConstraintMap.empty(); }
+
   /// \brief Check the entity is fixed.
   ///        If the point is under verification, all coincident points are checked too.
   SKETCHSOLVER_EXPORT bool isFixed(EntityWrapperPtr theEntity) const;
@@ -216,6 +221,7 @@ protected:
 
   // to be able to update entities from constraints
   friend class SketchSolver_ConstraintDistance;
+  friend class SketchSolver_ConstraintFixedArcRadius;
 };
 
 typedef std::shared_ptr<SketchSolver_Storage> StoragePtr;