Salome HOME
Correct processing arcs in SketchSolver with SolveSpace (issue #1144)
authorazv <azv@opencascade.com>
Fri, 18 Dec 2015 08:56:05 +0000 (11:56 +0300)
committerazv <azv@opencascade.com>
Fri, 18 Dec 2015 08:56:05 +0000 (11:56 +0300)
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_Constraint.h
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_EntityWrapper.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_EntityWrapper.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h

index 96051c3d01128d11ef79f375f255acb67cfaaabd..1de16cfe79a18b71be201aab9d80cd577067c996 100644 (file)
@@ -217,9 +217,3 @@ bool SketchSolver_Constraint::isUsed(AttributePtr theAttribute) const
       return true;
   return false;
 }
-
-void SketchSolver_Constraint::makeTemporary() const
-{
-  myStorage->setTemporary(myBaseConstraint);
-}
-
index 6f8a6fd7942f1f6a34753f1f0bbf05ac6c650dae..817afa58db9fd35af2aa59165f586e9bb930d9a0 100644 (file)
@@ -57,9 +57,6 @@ public:
   virtual SketchSolver_ConstraintType getType() const
   { return myType; }
 
-  /// \brief The constraint is made temporary
-  void makeTemporary() const;
-
   /// \brief Verify the feature or any its attribute is used by constraint
   bool isUsed(FeaturePtr theFeature) const;
   /// \brief Verify the attribute is used by constraint
index ee4c2da05af6786761270d0ca593a3c23daec76e..0959722eeb56e68471b3524971f9b638d3517752 100644 (file)
@@ -133,6 +133,7 @@ bool SketchSolver_Group::changeConstraint(
     return false;
 
   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+  myStorage->blockEvents(true);
 
   bool isNewConstraint = myConstraints.find(theConstraint) == myConstraints.end();
   if (isNewConstraint) {
@@ -200,6 +201,7 @@ bool SketchSolver_Group::updateFeature(FeaturePtr theFeature)
   if (!checkFeatureValidity(theFeature))
     return false;
 
+  myStorage->blockEvents(true);
   myStorage->refresh(true);
   return myStorage->update(theFeature);
 }
@@ -209,6 +211,7 @@ void SketchSolver_Group::moveFeature(FeaturePtr theFeature)
   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
 
   // Firstly, revert changes in the fixed entities
+  myStorage->blockEvents(true);
   myStorage->refresh(true);
 
   // Secondly, search attributes of the feature in the list of the Multi constraints and update them
@@ -295,19 +298,17 @@ bool SketchSolver_Group::resolveConstraints()
         // To avoid overconstraint situation, we will remove temporary constraints one-by-one
         // and try to find the case without overconstraint
         bool isLastChance = false;
-        size_t aNbTemp = myStorage->nbTemporary();
         while (true) {
           aResult = mySketchSolver->solve();
           if (aResult == STATUS_OK || aResult == STATUS_EMPTYSET || isLastChance)
             break;
-          if (aNbTemp == 0) {
-            // try to update parameters and resolve once again
-            ConstraintConstraintMap::iterator aConstrIt = myConstraints.begin();
-            for (; aConstrIt != myConstraints.end(); ++aConstrIt)
-              aConstrIt->second->update();
-            isLastChance = true;
-          } else
-            aNbTemp = myStorage->removeTemporary();
+          // try to update parameters and resolve once again
+          ConstraintConstraintMap::iterator aConstrIt = myConstraints.begin();
+          for (; aConstrIt != myConstraints.end(); ++aConstrIt)
+            aConstrIt->second->update();
+          isLastChance = true;
+
+          removeTemporaryConstraints();
           mySketchSolver->calculateFailedConstraints(true); // something failed => need to find it
           myStorage->initializeSolver(mySketchSolver);
         }
@@ -353,6 +354,7 @@ bool SketchSolver_Group::resolveConstraints()
       myStorage->refresh();
   }
   removeTemporaryConstraints();
+  myStorage->blockEvents(false);
   myStorage->setNeedToResolve(false);
   return aResolved;
 }
@@ -497,10 +499,6 @@ void SketchSolver_Group::removeTemporaryConstraints()
   for (; aTmpIt != myTempConstraints.end(); ++aTmpIt)
     (*aTmpIt)->remove();
 
-  size_t aNbTemp = myStorage->nbTemporary();
-  if (aNbTemp > 0)
-    myStorage->removeTemporary(aNbTemp);
-
   if (!myTempConstraints.empty())
     myStorage->verifyFixed();
   myStorage->setNeedToResolve(false);
@@ -569,7 +567,6 @@ bool SketchSolver_Group::isComplexConstraint(FeaturePtr theConstraint)
 // ============================================================================
 void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint)
 {
-  theConstraint->makeTemporary();
   myTempConstraints.insert(theConstraint);
 }
 
index 8db3eaa5c2c31be9afb6c7bae645d7563f94a1b0..feae88f9c7bca42846caed0112e80f3b59492a93 100644 (file)
@@ -44,6 +44,9 @@ void SketchSolver_Storage::addConstraint(
       update(*aCIt);
   }
   myConstraintMap[theConstraint] = theSolverConstraints;
+  // block events if necessary
+  if (myEventsBlocked && theConstraint->data() && theConstraint->data()->isValid())
+    theConstraint->data()->blockSendAttributeUpdated(myEventsBlocked);
 }
 
 void SketchSolver_Storage::addEntity(FeaturePtr       theFeature,
@@ -54,6 +57,9 @@ void SketchSolver_Storage::addEntity(FeaturePtr       theFeature,
     setNeedToResolve(true); // the entity is new or modified
 
   myFeatureMap[theFeature] = theSolverEntity;
+  // block events if necessary
+  if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid())
+    theFeature->data()->blockSendAttributeUpdated(myEventsBlocked);
 }
 
 void SketchSolver_Storage::addEntity(AttributePtr     theAttribute,
@@ -64,6 +70,10 @@ void SketchSolver_Storage::addEntity(AttributePtr     theAttribute,
     setNeedToResolve(true); // the entity is new or modified
 
   myAttributeMap[theAttribute] = theSolverEntity;
+  // block events if necessary
+  if (myEventsBlocked && theAttribute->owner() &&
+      theAttribute->owner()->data() && theAttribute->owner()->data()->isValid())
+    theAttribute->owner()->data()->blockSendAttributeUpdated(myEventsBlocked);
 }
 
 
@@ -73,6 +83,8 @@ bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup
   EntityWrapperPtr aRelated = entity(theFeature);
   if (!aRelated) { // Feature is not exist, create it
     std::list<EntityWrapperPtr> aSubs;
+    // Reserve the feature in the map of features (do not want to add several copies of it)
+    myFeatureMap[theFeature] = aRelated;
     // Firstly, create/update its attributes
     std::list<AttributePtr> anAttrs =
         theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
@@ -95,7 +107,8 @@ bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup
     }
     // Secondly, convert feature
     BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
-    aRelated = aBuilder->createFeature(theFeature, aSubs, theGroup);
+    GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
+    aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup);
     if (!aRelated)
       return false;
     addEntity(theFeature, aRelated);
@@ -119,7 +132,8 @@ bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theG
   EntityWrapperPtr aRelated = entity(anAttribute);
   if (!aRelated) { // Attribute is not exist, create it
     BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
-    aRelated = aBuilder->createAttribute(anAttribute, theGroup);
+    GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
+    aRelated = aBuilder->createAttribute(anAttribute, aGroup);
     if (!aRelated)
       return false;
     addEntity(anAttribute, aRelated);
@@ -173,6 +187,171 @@ const EntityWrapperPtr& SketchSolver_Storage::entity(const AttributePtr& theAttr
   return aDummy;
 }
 
+bool SketchSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
+{
+  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
+      aFound = myConstraintMap.find(theConstraint);
+  if (aFound == myConstraintMap.end())
+    return true; // no constraint, already deleted
+
+  // Remove constraint
+  std::list<ConstraintWrapperPtr> aConstrList = aFound->second;
+  myConstraintMap.erase(aFound);
+  // Remove SolveSpace constraints
+  bool isFullyRemoved = true;
+  std::list<ConstraintWrapperPtr>::iterator anIt = aConstrList.begin();
+  while (anIt != aConstrList.end()) {
+    if (remove(*anIt)) {
+      std::list<ConstraintWrapperPtr>::iterator aRemoveIt = anIt++;
+      aConstrList.erase(aRemoveIt);
+    } else {
+      isFullyRemoved = false;
+      ++anIt;
+    }
+  }
+  if (!isFullyRemoved)
+    myConstraintMap[theConstraint] = aConstrList;
+  return isFullyRemoved;
+}
+
+template <class ENT_TYPE>
+static bool isUsed(ConstraintWrapperPtr theConstraint, ENT_TYPE theEntity)
+{
+  std::list<EntityWrapperPtr>::const_iterator anEntIt = theConstraint->entities().begin();
+  for (; anEntIt != theConstraint->entities().end(); ++anEntIt)
+    if ((*anEntIt)->isBase(theEntity))
+      return true;
+  return false;
+}
+
+static bool isUsed(EntityWrapperPtr theFeature, AttributePtr theSubEntity)
+{
+  std::list<EntityWrapperPtr>::const_iterator aSubIt = theFeature->subEntities().begin();
+  for (; aSubIt != theFeature->subEntities().end(); ++aSubIt)
+    if ((*aSubIt)->isBase(theSubEntity))
+      return true;
+  return false;
+}
+
+bool SketchSolver_Storage::isUsed(FeaturePtr theFeature) const
+{
+  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
+      aCIt = myConstraintMap.begin();
+  std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
+  for (; aCIt != myConstraintMap.end(); ++aCIt)
+    for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
+      if (::isUsed(*aCWIt, theFeature))
+        return true;
+  // check attributes
+  std::list<AttributePtr> anAttrList = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+  std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
+  for (; anIt != anAttrList.end(); ++anIt)
+    if (isUsed(*anIt))
+      return true;
+  return false;
+}
+
+bool SketchSolver_Storage::isUsed(AttributePtr theAttribute) const
+{
+  AttributePtr anAttribute = theAttribute;
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
+  if (aRefAttr) {
+    if (aRefAttr->isObject())
+      return isUsed(ModelAPI_Feature::feature(aRefAttr->object()));
+    else
+      anAttribute = aRefAttr->attr();
+  }
+
+  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
+      aCIt = myConstraintMap.begin();
+  std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
+  for (; aCIt != myConstraintMap.end(); ++aCIt)
+    for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
+      if (::isUsed(*aCWIt, anAttribute))
+        return true;
+  return false;
+}
+
+
+bool SketchSolver_Storage::removeEntity(FeaturePtr theFeature)
+{
+  std::map<FeaturePtr, EntityWrapperPtr>::iterator aFound = myFeatureMap.find(theFeature);
+  if (aFound == myFeatureMap.end())
+    return false; // feature not found, nothing to delete
+
+  // Check the feature is not used by constraints
+  if (isUsed(theFeature))
+    return false; // the feature is used, don't remove it
+
+  // Remove feature
+  EntityWrapperPtr anEntity = aFound->second;
+  myFeatureMap.erase(aFound);
+  if (remove(anEntity))
+    return true;
+  // feature is not removed, revert operation
+  myFeatureMap[theFeature] = anEntity;
+  return false;
+}
+
+bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute)
+{
+  std::map<AttributePtr, EntityWrapperPtr>::iterator aFound = myAttributeMap.find(theAttribute);
+  if (aFound == myAttributeMap.end())
+    return false; // attribute not found, nothing to delete
+
+  // Check the attribute is not used by constraints
+  if (isUsed(theAttribute))
+    return false; // the attribute is used, don't remove it
+  // Check the attribute is not used by other features
+  std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
+  for (; aFIt != myFeatureMap.end(); ++aFIt)
+    if (::isUsed(aFIt->second, theAttribute)) // the attribute is used, don't remove it
+      return false;
+
+  // Remove attribute
+  EntityWrapperPtr anEntity = aFound->second;
+  myAttributeMap.erase(aFound);
+  if (remove(anEntity))
+    return true;
+  // attribute is not removed, revert operation
+  myAttributeMap[theAttribute] = anEntity;
+  return false;
+}
+
+
+bool SketchSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
+{
+  bool isFullyRemoved = true;
+  std::list<EntityWrapperPtr>::const_iterator anIt = theConstraint->entities().begin();
+  for (; anIt != theConstraint->entities().end(); ++anIt) {
+    FeaturePtr aBaseFeature = (*anIt)->baseFeature();
+    if (aBaseFeature)
+      isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
+    else
+      isFullyRemoved = SketchSolver_Storage::removeEntity((*anIt)->baseAttribute()) && isFullyRemoved;
+  }
+  return isFullyRemoved;
+}
+
+bool SketchSolver_Storage::remove(EntityWrapperPtr theEntity)
+{
+  bool isFullyRemoved = true;
+  std::list<EntityWrapperPtr>::const_iterator anEntIt = theEntity->subEntities().begin();
+  for (; anEntIt != theEntity->subEntities().end(); ++anEntIt) {
+    FeaturePtr aBaseFeature = (*anEntIt)->baseFeature();
+    if (aBaseFeature)
+      isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
+    else
+      isFullyRemoved = SketchSolver_Storage::removeEntity((*anEntIt)->baseAttribute()) && isFullyRemoved;
+  }
+
+  std::list<ParameterWrapperPtr>::const_iterator aParIt = theEntity->parameters().begin();
+  for (; aParIt != theEntity->parameters().end(); ++aParIt)
+    isFullyRemoved = remove(*aParIt) && isFullyRemoved;
+  return isFullyRemoved;
+}
+
+
 bool SketchSolver_Storage::isInteract(const FeaturePtr& theFeature) const
 {
   if (!theFeature)
@@ -293,7 +472,7 @@ const EntityWrapperPtr& SketchSolver_Storage::sketch() const
 
   std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
   for (; aFIt != myFeatureMap.end(); ++aFIt)
-    if (aFIt->second->type() == ENTITY_SKETCH)
+    if (aFIt->second && aFIt->second->type() == ENTITY_SKETCH)
       break;
   if (aFIt == myFeatureMap.end())
     return aDummySketch;
@@ -307,8 +486,11 @@ void SketchSolver_Storage::setSketch(const EntityWrapperPtr& theSketch)
   addEntity(FeaturePtr(), theSketch);
 }
 
-void SketchSolver_Storage::blockEvents(bool isBlocked) const
+void SketchSolver_Storage::blockEvents(bool isBlocked)
 {
+  if (isBlocked == myEventsBlocked)
+    return;
+
   std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
       aCIter = myConstraintMap.begin();
   for (; aCIter != myConstraintMap.end(); aCIter++)
@@ -325,6 +507,7 @@ void SketchSolver_Storage::blockEvents(bool isBlocked) const
     if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
         anAtIter->first->owner()->data()->isValid())
       anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);
+  myEventsBlocked = isBlocked;
 }
 
 
index ee27e9d14b91b80bf4900a73941e33b92f036d01..26ccd019af5e04a05a78d5f7c93192d5bfca3adf 100644 (file)
 #include <ModelAPI_Feature.h>
 #include <SketchPlugin_Constraint.h>
 
+
 typedef std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> > CoincidentPointsMap;
 
+
 /** \class   SketchSolver_Storage
  *  \ingroup Plugins
  *  \brief   Interface to map SketchPlugin features to the entities of corresponding solver.
@@ -34,7 +36,8 @@ private:
 public:
   SketchSolver_Storage(const GroupID& theGroup)
     : myGroupID(theGroup),
-      myNeedToResolve(false)
+      myNeedToResolve(false),
+      myEventsBlocked(false)
   {}
 
   /// \brief Change mapping between constraint from SketchPlugin and
@@ -85,26 +88,26 @@ public:
 
   /// \brief Removes constraint from the storage
   /// \return \c true if the constraint and all its parameters are removed successfully
-  virtual bool removeConstraint(ConstraintPtr theConstraint) = 0;
+  SKETCHSOLVER_EXPORT bool removeConstraint(ConstraintPtr theConstraint);
   /// \brief Removes feature from the storage
   /// \return \c true if the feature and its attributes are removed successfully;
   ///         \c false if the feature or any it attribute is used by remaining constraints.
-  virtual bool removeEntity(FeaturePtr theFeature) = 0;
+  SKETCHSOLVER_EXPORT bool removeEntity(FeaturePtr theFeature);
   /// \brief Removes attribute from the storage
   /// \return \c true if the attribute is not used by remaining features and constraints
-  virtual bool removeEntity(AttributePtr theAttribute) = 0;
+  SKETCHSOLVER_EXPORT bool removeEntity(AttributePtr theAttribute);
 
   /// \brief Remove all features became invalid
   SKETCHSOLVER_EXPORT void removeInvalidEntities();
 
-  /// \brief Mark specified constraint as temporary
-  virtual void setTemporary(ConstraintPtr theConstraint) = 0;
-  /// \brief Returns number of temporary constraints
-  virtual size_t nbTemporary() const = 0;
-  /// \brief Remove temporary constraints
-  /// \param theNbConstraints [in]  number of temporary constraints to be deleted
-  /// \return number of remaining temporary constraints
-  virtual size_t removeTemporary(size_t theNbConstraints = 1) = 0;
+////  /// \brief Mark specified constraint as temporary
+////  virtual void setTemporary(ConstraintPtr theConstraint) = 0;
+////  /// \brief Returns number of temporary constraints
+////  virtual size_t nbTemporary() const = 0;
+////  /// \brief Remove temporary constraints
+////  /// \param theNbConstraints [in]  number of temporary constraints to be deleted
+////  /// \return number of remaining temporary constraints
+////  virtual size_t removeTemporary(size_t theNbConstraints = 1) = 0;
 
   /// \brief Check whether the feature or its attributes are used by this storage
   /// \param theFeature [in]  feature to be checked
@@ -145,6 +148,9 @@ public:
   virtual EntityWrapperPtr calculateMiddlePoint(EntityWrapperPtr theBase,
                                                 double theCoeff) = 0;
 
+  /// \brief Block or unblock events when refreshing features
+  SKETCHSOLVER_EXPORT void blockEvents(bool isBlocked);
+
 protected:
   /// \brief Change mapping feature from SketchPlugin and
   ///        the entity applicable for corresponding solver.
@@ -173,10 +179,10 @@ protected:
 
   /// \brief Remove constraint
   /// \return \c true if the constraint and all its parameters are removed successfully
-  virtual bool remove(ConstraintWrapperPtr theConstraint) = 0;
+  SKETCHSOLVER_EXPORT virtual bool remove(ConstraintWrapperPtr theConstraint);
   /// \brief Remove entity
   /// \return \c true if the entity and all its parameters are removed successfully
-  virtual bool remove(EntityWrapperPtr theEntity) = 0;
+  SKETCHSOLVER_EXPORT virtual bool remove(EntityWrapperPtr theEntity);
   /// \brief Remove parameter
   /// \return \c true if the parameter has been removed
   virtual bool remove(ParameterWrapperPtr theParameter) = 0;
@@ -186,16 +192,19 @@ protected:
   /// \brief Update the group for the given parameter
   virtual void changeGroup(ParameterWrapperPtr theParam, const GroupID& theGroup) = 0;
 
-  /// \brief Block or unblock events when refreshing features
-  SKETCHSOLVER_EXPORT void blockEvents(bool isBlocked) const;
-
 private:
   /// \brief Find the normal of the sketch
   EntityWrapperPtr getNormal() const;
 
+  /// \brief Verify the feature or any its attribute is used by constraint
+  bool isUsed(FeaturePtr theFeature) const;
+  /// \brief Verify the attribute is used by constraint
+  bool isUsed(AttributePtr theAttirubute) const;
+
 protected:
   GroupID myGroupID;       ///< identifier of the group, this storage belongs to
   bool    myNeedToResolve; ///< parameters are changed and group needs to be resolved
+  bool    myEventsBlocked; ///< indicates that features do not send events
 
   /// map SketchPlugin constraint to a list of solver's constraints
   std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> > myConstraintMap;
index eabf9f6ae0c25d86a33407b2ec22c2961282802f..46fc1b20f0d1ae6dd2da18782b05d260bb447285 100644 (file)
@@ -311,11 +311,12 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createFeature(
     if (!aSub)
       return aDummy;
 
+    std::shared_ptr<SketchPlugin_Point> aPointFeature = 
+        std::dynamic_pointer_cast<SketchPlugin_Point>(theFeature);
+
     const Slvs_Entity& aSubEnt =
         std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(aSub)->entity();
-    EntityWrapperPtr aNewEntity(new SolveSpaceSolver_EntityWrapper(theFeature, aSubEnt));
-    aNewEntity->setSubEntities(std::list<EntityWrapperPtr>(1, aSub));
-    return aNewEntity;
+    return EntityWrapperPtr(new SolveSpaceSolver_EntityWrapper(aPointFeature, aPoint, aSubEnt));
   }
 
   // wrong entity
index 1cb81157dbeade5022622d91d069fc6ad4b09655..bd6f616764c35dd0d3ed9bae0c6ee02380861783 100644 (file)
@@ -20,6 +20,17 @@ SolveSpaceSolver_EntityWrapper::SolveSpaceSolver_EntityWrapper(
   myBaseAttribute = theAttribute;
 }
 
+SolveSpaceSolver_EntityWrapper::SolveSpaceSolver_EntityWrapper(
+    const std::shared_ptr<SketchPlugin_Point> theFeature,
+    const AttributePtr theAttribute,
+    const Slvs_Entity& theEntity)
+  : myEntity(theEntity)
+{
+  myBaseFeature = FeaturePtr(theFeature);
+  myBaseAttribute = theAttribute;
+}
+
+
 EntityID SolveSpaceSolver_EntityWrapper::id() const
 {
   return (EntityID)myEntity.h;
index 566625f91510dada2687a86e92ecbaeabd50ea17..b006251ebb329a746c47164a4496673f4d7a1742 100644 (file)
@@ -10,6 +10,8 @@
 #include <SketchSolver_IEntityWrapper.h>
 #include <SolveSpaceSolver_Solver.h>
 
+#include <SketchPlugin_Point.h>
+
 /**
  *  Wrapper providing operations with SolveSpace entities.
  */
@@ -19,6 +21,11 @@ public:
   SolveSpaceSolver_EntityWrapper(const FeaturePtr theFeature, const Slvs_Entity& theEntity);
   SolveSpaceSolver_EntityWrapper(const AttributePtr theAttribute, const Slvs_Entity& theEntity);
 
+  /// \brief Constructor useful for SketchPlugin_Point only
+  SolveSpaceSolver_EntityWrapper(const std::shared_ptr<SketchPlugin_Point> theFeature,
+                                 const AttributePtr theAttribute,
+                                 const Slvs_Entity& theEntity);
+
   /// \brief Return SolveSpace entity
   const Slvs_Entity& entity() const
   { return myEntity; }
index 5fe40328e2a088165108d59452b6716dd38bd07c..d48730926de2283aa027aedee5272dbf776bf200 100644 (file)
@@ -162,6 +162,15 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity)
       isUpdated = true;
     }
   }
+  if (theEntity->type() == ENTITY_POINT && aSubEntities.size() == 1) {
+    // theEntity is based on SketchPlugin_Point => need to substitute its attribute instead
+    bool isNew = (aSlvsEnt.h == SLVS_E_UNKNOWN);
+    aSlvsEnt = getEntity(aSlvsEnt.point[0]);
+    if (isNew) {
+      anEntity->changeEntity() = aSlvsEnt;
+      isUpdated = true;
+    }
+  }
 
   // update entity itself
   if (aSlvsEnt.wrkpl == SLVS_E_UNKNOWN && myWorkplaneID != SLVS_E_UNKNOWN)
@@ -181,8 +190,13 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity)
       FeaturePtr aFeature = ModelAPI_Feature::feature(theEntity->baseAttribute()->owner());
       if (aFeature->getKind() == SketchPlugin_Arc::ID() &&
           myFeatureMap.find(aFeature) == myFeatureMap.end()) {
-        myFeatureMap[aFeature] = EntityWrapperPtr();
-        return SketchSolver_Storage::update(aFeature, myGroupID);
+        // Additional checking that all attributes are initialized
+        if (aFeature->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() && 
+            aFeature->attribute(SketchPlugin_Arc::START_ID())->isInitialized() && 
+            aFeature->attribute(SketchPlugin_Arc::END_ID())->isInitialized()) {
+          myFeatureMap[aFeature] = EntityWrapperPtr();
+          return SketchSolver_Storage::update(aFeature);
+        }
       }
     }
   }
@@ -327,6 +341,8 @@ void SolveSpaceSolver_Storage::replaceInFeatures(
 {
   std::map<FeaturePtr, EntityWrapperPtr>::const_iterator anIt = myFeatureMap.begin();
   for (; anIt != myFeatureMap.end(); ++anIt) {
+    if (!anIt->second)
+      continue;
     bool isUpdated = false;
     std::list<EntityWrapperPtr> aSubs = anIt->second->subEntities();
     std::list<EntityWrapperPtr>::iterator aSubIt = aSubs.begin();
@@ -1124,67 +1140,6 @@ void SolveSpaceSolver_Storage::addConstraintWhereDragged(const Slvs_hConstraint&
     myFixed = theConstraintID;
 }
 
-void SolveSpaceSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
-{
-  myTemporaryConstraints.insert(theConstraintID);
-}
-
-void SolveSpaceSolver_Storage::removeAllTemporary()
-{
-  myTemporaryConstraints.clear();
-}
-
-size_t SolveSpaceSolver_Storage::removeTemporary(size_t theNbConstraints)
-{
-  if (myTemporaryConstraints.empty())
-    return 0;
-  // Search the point-on-line or a non-rigid constraint
-  std::set<Slvs_hConstraint>::iterator aCIt = myTemporaryConstraints.begin();
-  for (; aCIt != myTemporaryConstraints.end(); aCIt++) {
-    int aPos = Search(*aCIt, myConstraints);
-    if (aPos >= (int)myConstraints.size() || myConstraints[aPos].type != SLVS_C_WHERE_DRAGGED)
-      break;
-    std::vector<Slvs_Constraint>::iterator anIt = myConstraints.begin();
-    for (; anIt != myConstraints.end(); anIt++)
-      if (anIt->type == SLVS_C_PT_ON_LINE && anIt->ptA == myConstraints[aPos].ptA)
-        break;
-    if (anIt != myConstraints.end())
-      break;
-  }
-  if (aCIt == myTemporaryConstraints.end())
-    aCIt = myTemporaryConstraints.begin();
-  bool aNewFixed = false;
-
-  size_t aNbRemain = theNbConstraints;
-  while (aNbRemain > 0 && aCIt != myTemporaryConstraints.end()) {
-    aNewFixed = aNewFixed || (*aCIt == myFixed);
-    --aNbRemain;
-
-    std::set<Slvs_hConstraint>::iterator aRemoveIt = aCIt++;
-    removeConstraint(*aRemoveIt);
-    myTemporaryConstraints.erase(aRemoveIt);
-    if (aCIt == myTemporaryConstraints.end())
-      aCIt = myTemporaryConstraints.begin();
-  }
-
-  if (aNewFixed) {
-    for (aCIt = myTemporaryConstraints.begin(); aCIt != myTemporaryConstraints.end(); aCIt++) {
-      int aPos = Search(*aCIt, myConstraints);
-      if (myConstraints[aPos].type == SLVS_C_WHERE_DRAGGED) {
-        myFixed = *aCIt;
-        break;
-      }
-    }
-  }
-  return myTemporaryConstraints.size();
-}
-
-bool SolveSpaceSolver_Storage::isTemporary(const Slvs_hConstraint& theConstraintID) const
-{
-  return myTemporaryConstraints.find(theConstraintID) != myTemporaryConstraints.end();
-}
-
-
 
 void SolveSpaceSolver_Storage::initializeSolver(SolverPtr theSolver)
 {
@@ -1280,7 +1235,7 @@ void SolveSpaceSolver_Storage::fixPoint(const Slvs_Entity& thePoint,
   Slvs_Constraint aConstraint;
   Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN;
   bool isFixed = isPointFixed(thePoint.h, aConstrID, true);
-  bool isForceUpdate = (isFixed && isTemporary(aConstrID));
+  bool isForceUpdate = (isFixed /*&& isTemporary(aConstrID)*/);
   if (!isForceUpdate) { // create new constraint
     if (isFixed) return;
     aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, thePoint.group, SLVS_C_WHERE_DRAGGED, thePoint.wrkpl,
@@ -1519,142 +1474,6 @@ bool SolveSpaceSolver_Storage::isUsedInEqual(
   return false;
 }
 
-void SolveSpaceSolver_Storage::setTemporary(ConstraintPtr theConstraint)
-{
-  // TODO
-}
-
-bool SolveSpaceSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
-{
-  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
-      aFound = myConstraintMap.find(theConstraint);
-  if (aFound == myConstraintMap.end())
-    return true; // no constraint, already deleted
-
-  // Remove constraint
-  std::list<ConstraintWrapperPtr> aConstrList = aFound->second;
-  myConstraintMap.erase(aFound);
-  // Remove SolveSpace constraints
-  bool isFullyRemoved = true;
-  std::list<ConstraintWrapperPtr>::iterator anIt = aConstrList.begin();
-  while (anIt != aConstrList.end()) {
-    if (remove(*anIt)) {
-      std::list<ConstraintWrapperPtr>::iterator aRemoveIt = anIt++;
-      aConstrList.erase(aRemoveIt);
-    } else {
-      isFullyRemoved = false;
-      ++anIt;
-    }
-  }
-  if (!isFullyRemoved)
-    myConstraintMap[theConstraint] = aConstrList;
-  return isFullyRemoved;
-}
-
-template <class ENT_TYPE>
-static bool isUsed(ConstraintWrapperPtr theConstraint, ENT_TYPE theEntity)
-{
-  std::list<EntityWrapperPtr>::const_iterator anEntIt = theConstraint->entities().begin();
-  for (; anEntIt != theConstraint->entities().end(); ++anEntIt)
-    if (std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(*anEntIt)->isBase(theEntity))
-      return true;
-  return false;
-}
-
-static bool isUsed(EntityWrapperPtr theFeature, AttributePtr theSubEntity)
-{
-  std::list<EntityWrapperPtr>::const_iterator aSubIt = theFeature->subEntities().begin();
-  for (; aSubIt != theFeature->subEntities().end(); ++aSubIt)
-    if (std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(*aSubIt)->isBase(theSubEntity))
-      return true;
-  return false;
-}
-
-bool SolveSpaceSolver_Storage::isUsed(FeaturePtr theFeature) const
-{
-  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
-      aCIt = myConstraintMap.begin();
-  std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
-  for (; aCIt != myConstraintMap.end(); ++aCIt)
-    for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
-      if (::isUsed(*aCWIt, theFeature))
-        return true;
-  // check attributes
-  std::list<AttributePtr> anAttrList = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-  std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
-  for (; anIt != anAttrList.end(); ++anIt)
-    if (isUsed(*anIt))
-      return true;
-  return false;
-}
-
-bool SolveSpaceSolver_Storage::isUsed(AttributePtr theAttribute) const
-{
-  AttributePtr anAttribute = theAttribute;
-  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
-  if (aRefAttr) {
-    if (aRefAttr->isObject())
-      return isUsed(ModelAPI_Feature::feature(aRefAttr->object()));
-    else
-      anAttribute = aRefAttr->attr();
-  }
-
-  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
-      aCIt = myConstraintMap.begin();
-  std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
-  for (; aCIt != myConstraintMap.end(); ++aCIt)
-    for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
-      if (::isUsed(*aCWIt, anAttribute))
-        return true;
-  return false;
-}
-
-
-bool SolveSpaceSolver_Storage::removeEntity(FeaturePtr theFeature)
-{
-  std::map<FeaturePtr, EntityWrapperPtr>::iterator aFound = myFeatureMap.find(theFeature);
-  if (aFound == myFeatureMap.end())
-    return false; // feature not found, nothing to delete
-
-  // Check the feature is not used by constraints
-  if (isUsed(theFeature))
-    return false; // the feature is used, don't remove it
-
-  // Remove feature
-  EntityWrapperPtr anEntity = aFound->second;
-  myFeatureMap.erase(aFound);
-  if (remove(anEntity))
-    return true;
-  // feature is not removed, revert operation
-  myFeatureMap[theFeature] = anEntity;
-  return false;
-}
-
-bool SolveSpaceSolver_Storage::removeEntity(AttributePtr theAttribute)
-{
-  std::map<AttributePtr, EntityWrapperPtr>::iterator aFound = myAttributeMap.find(theAttribute);
-  if (aFound == myAttributeMap.end())
-    return false; // attribute not found, nothing to delete
-
-  // Check the attribute is not used by constraints
-  if (isUsed(theAttribute))
-    return false; // the attribute is used, don't remove it
-  // Check the attribute is not used by other features
-  std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
-  for (; aFIt != myFeatureMap.end(); ++aFIt)
-    if (::isUsed(aFIt->second, theAttribute)) // the attribute is used, don't remove it
-      return false;
-
-  // Remove attribute
-  EntityWrapperPtr anEntity = aFound->second;
-  myAttributeMap.erase(aFound);
-  if (remove(anEntity))
-    return true;
-  // attribute is not removed, revert operation
-  myAttributeMap[theAttribute] = anEntity;
-  return false;
-}
-
 
 bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
 {
@@ -1672,42 +1491,18 @@ bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
     return true;
 
   bool isFullyRemoved = removeConstraint((Slvs_hConstraint)aConstraint->id());
-
-  std::list<EntityWrapperPtr>::const_iterator anIt = aConstraint->entities().begin();
-  for (; anIt != aConstraint->entities().end(); ++anIt) {
-    std::shared_ptr<SolveSpaceSolver_EntityWrapper> anEntity = 
-        std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(*anIt);
-    FeaturePtr aBaseFeature = anEntity->baseFeature();
-    if (aBaseFeature)
-      isFullyRemoved = removeEntity(aBaseFeature) && isFullyRemoved;
-    else
-      isFullyRemoved = removeEntity(anEntity->baseAttribute()) && isFullyRemoved;
-  }
-
-  return isFullyRemoved;
+  return SketchSolver_Storage::remove(theConstraint) && isFullyRemoved;
 }
 
 bool SolveSpaceSolver_Storage::remove(EntityWrapperPtr theEntity)
 {
+  if (!theEntity)
+    return false;
+
   std::shared_ptr<SolveSpaceSolver_EntityWrapper> anEntity = 
         std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(theEntity);
   bool isFullyRemoved = removeEntity((Slvs_hEntity)anEntity->id());
-
-  std::list<EntityWrapperPtr>::const_iterator anEntIt = anEntity->subEntities().begin();
-  for (; anEntIt != anEntity->subEntities().end(); ++anEntIt) {
-    std::shared_ptr<SolveSpaceSolver_EntityWrapper> aSubEntity = 
-        std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(*anEntIt);
-    FeaturePtr aBaseFeature = aSubEntity->baseFeature();
-    if (aBaseFeature)
-      isFullyRemoved = removeEntity(aBaseFeature) && isFullyRemoved;
-    else
-      isFullyRemoved = removeEntity(aSubEntity->baseAttribute()) && isFullyRemoved;
-  }
-
-  std::list<ParameterWrapperPtr>::const_iterator aParIt = anEntity->parameters().begin();
-  for (; aParIt != anEntity->parameters().end(); ++aParIt)
-    isFullyRemoved = remove(*aParIt) && isFullyRemoved;
-  return isFullyRemoved;
+  return SketchSolver_Storage::remove(theEntity) && isFullyRemoved;
 }
 
 bool SolveSpaceSolver_Storage::remove(ParameterWrapperPtr theParameter)
@@ -1718,7 +1513,7 @@ bool SolveSpaceSolver_Storage::remove(ParameterWrapperPtr theParameter)
 
 void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const
 {
-  blockEvents(true);
+  //blockEvents(true);
 
   std::map<AttributePtr, EntityWrapperPtr>::const_iterator anIt = myAttributeMap.begin();
   std::list<ParameterWrapperPtr> aParams;
@@ -1789,7 +1584,7 @@ void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const
     }
   }
 
-  blockEvents(false);
+  //blockEvents(false);
 }
 
 void SolveSpaceSolver_Storage::verifyFixed()
index 04e6790aac391e15131fffe1bc2e170865d7e9c2..38efa4c132378e3d8d8af3226bef87ed2c73ff26 100644 (file)
@@ -38,16 +38,16 @@ public:
   /// \return \c true if the value of parameter is updated
   virtual bool update(ParameterWrapperPtr& theParameter);
 
-  /// \brief Removes constraint from the storage
-  /// \return \c true if the constraint and all its parameters are remove successfully
-  virtual bool removeConstraint(ConstraintPtr theConstraint);
-  /// \brief Removes feature from the storage
-  /// \return \c true if the feature and its attributes are removed successfully;
-  ///         \c false if the feature or any it attribute is used by remaining constraints.
-  virtual bool removeEntity(FeaturePtr theFeature);
-  /// \brief Removes attribute from the storage
-  /// \return \c true if the attribute is not used by remaining features and constraints
-  virtual bool removeEntity(AttributePtr theAttribute);
+////  /// \brief Removes constraint from the storage
+////  /// \return \c true if the constraint and all its parameters are remove successfully
+////  virtual bool removeConstraint(ConstraintPtr theConstraint);
+////  /// \brief Removes feature from the storage
+////  /// \return \c true if the feature and its attributes are removed successfully;
+////  ///         \c false if the feature or any it attribute is used by remaining constraints.
+////  virtual bool removeEntity(FeaturePtr theFeature);
+////  /// \brief Removes attribute from the storage
+////  /// \return \c true if the attribute is not used by remaining features and constraints
+////  virtual bool removeEntity(AttributePtr theAttribute);
 
   /// \brief Update SketchPlugin features after resolving constraints
   /// \param theFixedOnly [in]  if \c true the fixed points will be updated only
@@ -177,21 +177,21 @@ public:
   /// \brief Attach constraint SLVS_C_WHERE_DRAGGED to this storage. It need to make precise calculations
   void addConstraintWhereDragged(const Slvs_hConstraint& theConstraintID);
 
-  /// \brief Add transient constraint
-  void addTemporaryConstraint(const Slvs_hConstraint& theConstraintID);
-  /// \brief Mark specified constraint as temporary
-  virtual void setTemporary(ConstraintPtr theConstraint);
-  /// \brief Remove all transient constraints
-  void removeAllTemporary();
-  /// \brief Remove temporary constraint s. Preferable to remove the points under Point-on-Line constraint
-  /// \param theNbConstraints [in]  number of temporary constraints to be deleted
-  /// \return Number of remaining temporary constraints
-  virtual size_t removeTemporary(size_t theNbConstraints);
-  /// \brief Checks the constraint is temporary
-  bool isTemporary(const Slvs_hConstraint& theConstraintID) const;
-  /// \brief Number of temporary constraints
-  virtual size_t nbTemporary() const
-  { return myTemporaryConstraints.size(); }
+////  /// \brief Add transient constraint
+////  void addTemporaryConstraint(const Slvs_hConstraint& theConstraintID);
+////  /// \brief Mark specified constraint as temporary
+////  virtual void setTemporary(ConstraintPtr theConstraint);
+////  /// \brief Remove all transient constraints
+////  void removeAllTemporary();
+////  /// \brief Remove temporary constraint s. Preferable to remove the points under Point-on-Line constraint
+////  /// \param theNbConstraints [in]  number of temporary constraints to be deleted
+////  /// \return Number of remaining temporary constraints
+////  virtual size_t removeTemporary(size_t theNbConstraints);
+////  /// \brief Checks the constraint is temporary
+////  bool isTemporary(const Slvs_hConstraint& theConstraintID) const;
+////  /// \brief Number of temporary constraints
+////  virtual size_t nbTemporary() const
+////  { return myTemporaryConstraints.size(); }
 
   /// \brief Shows the storage has the same constraint twice
   virtual bool hasDuplicatedConstraint() const
@@ -239,11 +239,6 @@ private:
   /// \brief Update arc points to be on circle sharp.
   void adjustArc(const Slvs_Entity& theArc);
 
-  /// \brief Verify the feature or any its attribute is used by constraint
-  bool isUsed(FeaturePtr theFeature) const;
-  /// \brief Verify the attribute is used by constraint
-  bool isUsed(AttributePtr theAttirubute) const;
-
   /// \brief Replace sub-entity theSource in all features by theDest
   void replaceInFeatures(EntityWrapperPtr theSource, EntityWrapperPtr theDest);
   /// \brief Replace constrained entity theSource by theDest in all constraints;
@@ -269,7 +264,7 @@ private:
 
   bool myDuplicatedConstraint; ///< shows the storage has same constraint twice
 
-  std::set<Slvs_hConstraint> myTemporaryConstraints; ///< list of transient constraints
+////  std::set<Slvs_hConstraint> myTemporaryConstraints; ///< list of transient constraints
   std::set<Slvs_hParam> myUpdatedParameters; ///< list of just updated parameters (cleared when isNeedToResolve() called)
 
   SameConstraintMap myEqualConstraints; ///< list of groups of equal constraints