Salome HOME
"Conflicting constraints" should appear when a center of fillet is coincident with...
authorazv <azv@opencascade.com>
Tue, 22 Dec 2015 13:10:48 +0000 (16:10 +0300)
committerazv <azv@opencascade.com>
Tue, 22 Dec 2015 13:22:54 +0000 (16:22 +0300)
src/Model/Model_Data.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_ISolver.h
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp

index 47f27eaad514f8e309cc1894addc4d5f9eea34e6..1072d921bc4ee4a125ced38c5f6775c708ab0181 100644 (file)
@@ -565,7 +565,9 @@ void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
   std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator aMyIter = myAttrs.begin();
   for(; aMyIter != myAttrs.end(); aMyIter++) {
     if (aMyIter->second->isInitialized()) {
-      theTarget->attribute(aMyIter->first)->setInitialized();
+      AttributePtr aTargetAttr = theTarget->attribute(aMyIter->first);
+      if (aTargetAttr)
+        aTargetAttr->setInitialized();
     }
   }
 }
index b4856ba88bed9617998f8d9460240c926884897d..d62f995e15c507145b5363f6d26dd8f503028df6 100644 (file)
@@ -297,6 +297,7 @@ bool SketchSolver_Group::resolveConstraints()
     mySketchSolver->setGroup(myID);
     mySketchSolver->calculateFailedConstraints(false);
     myStorage->initializeSolver(mySketchSolver);
+    mySketchSolver->prepare();
 
     SketchSolver_SolveStatus aResult = STATUS_OK;
     try {
@@ -329,6 +330,7 @@ bool SketchSolver_Group::resolveConstraints()
         sendMessage(EVENT_SOLVER_FAILED);
         myPrevSolved = false;
       }
+      mySketchSolver->undo();
       return false;
     }
     if (aResult == STATUS_OK || aResult == STATUS_EMPTYSET) {  // solution succeeded, store results into correspondent attributes
@@ -339,13 +341,16 @@ bool SketchSolver_Group::resolveConstraints()
         sendMessage(EVENT_SOLVER_REPAIRED);
         myPrevSolved = true;
       }
-    } else if (!myConstraints.empty()) {
+    } else {
+      mySketchSolver->undo();
+      if (!myConstraints.empty()) {
 //      Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this);
-      getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS());
-      if (myPrevSolved) {
-        // the error message should be changed before sending the message
-        sendMessage(EVENT_SOLVER_FAILED);
-        myPrevSolved = false;
+        getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS());
+        if (myPrevSolved) {
+          // the error message should be changed before sending the message
+          sendMessage(EVENT_SOLVER_FAILED);
+          myPrevSolved = false;
+        }
       }
     }
 
index 75ddbfdf4d66a05d94b5f71f42b53f43437e3d91..19c2c5e22565d2f6cb72cfa928f966e1e7c17523 100644 (file)
@@ -36,10 +36,16 @@ public:
   void calculateFailedConstraints(bool theSic)
   { myFindFaileds = theSic; }
 
+  /// \brief Prepare for solving. Store initial values of parameters for undo
+  virtual void prepare() = 0;
+
   /// \brief Solve the set of equations
   /// \return identifier whether solution succeeded
   virtual SketchSolver_SolveStatus solve() = 0;
 
+  /// \brief Revert solution to initial values
+  virtual void undo() = 0;
+
 protected:
   GroupID myGroup;       ///< ID of the group to be solved
   bool    myFindFaileds; ///< flag to find conflicting or inappropriate constraints
index 742ef54bdda3aff1ce1650389a118d8a13b23ab4..f5617bbea6d11168816e2f8e720bf191c313121d 100644 (file)
@@ -85,6 +85,15 @@ void SketchSolver_Storage::addEntity(FeaturePtr       theFeature,
      (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
     setNeedToResolve(true); // the entity is new or modified
 
+  if (!theSolverEntity) {
+    // feature links to the empty entity, add its attributes
+    std::list<AttributePtr> aPntAttrs =
+        theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+    std::list<AttributePtr>::const_iterator anAttrIt = aPntAttrs.begin();
+    for (; anAttrIt != aPntAttrs.end(); ++anAttrIt)
+        addEntity(*anAttrIt, EntityWrapperPtr());
+  }
+
   myFeatureMap[theFeature] = theSolverEntity;
   // block events if necessary
   if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid())
index a46a7c0b37cbef86b0731cf3151bed645c044516..a7a83a13d91a1be1a282572b8fc63fa3d9615862 100644 (file)
@@ -27,6 +27,8 @@ SolveSpaceSolver_Solver::SolveSpaceSolver_Solver()
   // If the set of constraints is inconsistent,
   // the failed field will contain wrong constraints
   myEquationsSystem.calculateFaileds = 0;
+
+  myParamsCopy = 0;
 }
 
 SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver()
@@ -37,6 +39,9 @@ SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver()
   if (myEquationsSystem.failed)
     delete[] myEquationsSystem.failed;
   myEquationsSystem.failed = 0;
+  if (myParamsCopy)
+    delete [] myParamsCopy;
+  myParamsCopy = 0;
 }
 
 void SolveSpaceSolver_Solver::setParameters(Slvs_Param* theParameters, int theSize)
@@ -104,5 +109,83 @@ SketchSolver_SolveStatus SolveSpaceSolver_Solver::solve()
   default:
     aStatus = STATUS_FAILED;
   }
+
+  if (aStatus == STATUS_OK) {
+    // additional verification of arcs to be non-degenerated
+    if (hasDegeneratedArcs()) {
+      undo();
+      aStatus = STATUS_INCONSISTENT;
+    }
+  }
+
   return aStatus;
 }
+
+void SolveSpaceSolver_Solver::prepare()
+{
+  // make a copy of parameters to be able to make undo
+  if (myParamsCopy)
+    delete [] myParamsCopy;
+  myParamsCopy = new Slvs_Param[myEquationsSystem.params];
+  memcpy(myParamsCopy, myEquationsSystem.param, myEquationsSystem.params * sizeof(Slvs_Param));
+}
+
+void SolveSpaceSolver_Solver::undo()
+{
+  if (myParamsCopy) {
+    memcpy(myEquationsSystem.param, myParamsCopy, myEquationsSystem.params * sizeof(Slvs_Param));
+    delete [] myParamsCopy;
+  }
+  myParamsCopy = 0;
+}
+
+
+bool SolveSpaceSolver_Solver::hasDegeneratedArcs() const
+{
+  const double aTol2 = tolerance * tolerance;
+  double anArcPoints[3][2];
+
+  for (int anEnt = 0; anEnt < myEquationsSystem.entities; ++anEnt) {
+    const Slvs_Entity& anEntity = myEquationsSystem.entity[anEnt];
+    if (anEntity.type != SLVS_E_ARC_OF_CIRCLE)
+      continue;
+
+    for (int aPnt = 0; aPnt < 3; ++aPnt) {
+      // search point of arc
+      const int aShift = anEntity.point[aPnt] - anEntity.h;
+      int aPntInd = anEnt + aShift;
+      int aStep = 1;
+      if (myEquationsSystem.entity[aPntInd].h > anEntity.point[aPnt])
+        aStep = -1;
+      for (; aPntInd >=0 && aPntInd < myEquationsSystem.entities; aPntInd += aStep)
+        if (myEquationsSystem.entity[aPntInd].h == anEntity.point[aPnt])
+          break;
+
+      // search coordinates of the point
+      int aParamInd = myEquationsSystem.entity[aPntInd].param[0];
+      if (aParamInd >= myEquationsSystem.params) {
+        aParamInd = myEquationsSystem.params - 1;
+        aStep = -1;
+      }
+      else if ((int)myEquationsSystem.param[aParamInd].h > aParamInd)
+        aStep = -1;
+      else aStep = 1;
+
+      for (; aParamInd >=0 && aParamInd < myEquationsSystem.params; aParamInd += aStep)
+        if (myEquationsSystem.param[aParamInd].h == myEquationsSystem.entity[aPntInd].param[0])
+          break;
+      anArcPoints[aPnt][0] = myEquationsSystem.param[aParamInd].val;
+      anArcPoints[aPnt][1] = myEquationsSystem.param[aParamInd+1].val;
+    }
+
+    // check radius of arc
+    anArcPoints[1][0] -= anArcPoints[0][0];
+    anArcPoints[1][1] -= anArcPoints[0][1];
+    anArcPoints[2][0] -= anArcPoints[0][0];
+    anArcPoints[2][1] -= anArcPoints[0][1];
+    if (anArcPoints[1][0] * anArcPoints[1][0] + anArcPoints[1][1] * anArcPoints[1][1] < aTol2 ||
+        anArcPoints[2][0] * anArcPoints[2][0] + anArcPoints[2][1] * anArcPoints[2][1] < aTol2)
+      return true;
+  }
+  return false;
+}
index aa7729551494dcbc77fd7bd4fea9e87d9667d2c5..3ddadc8e610b5def32dde316df67ba548de1bae4 100644 (file)
@@ -74,8 +74,19 @@ public:
    */
   virtual SketchSolver_SolveStatus solve();
 
- private:
+  /// \brief Prepare for solving. Store initial values of parameters for undo
+  virtual void prepare();
+
+  /// \brief Revert solution to initial values
+  virtual void undo();
+
+private:
+  /// \brief Check whether degenerated arcs exist
+  bool hasDegeneratedArcs() const;
+
+private:
   Slvs_System myEquationsSystem; ///< set of equations for solving in SolveSpace
+  Slvs_Param* myParamsCopy;      ///< copy of parameters
 };
 
 #endif
index 35b4cf0cc18db7c270ae1eda77cf2c0e33ca0889..169302581dc619d99413f2571bfeaba944802760 100644 (file)
@@ -161,6 +161,8 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr theEntity)
       aSlvsEnt.distance = anID;
     else if (aSlvsEnt.point[anInd] != anID) {
       aSlvsEnt.point[anInd] = anID;
+      if ((*aSIt)->baseAttribute())
+        SketchSolver_Storage::addEntity((*aSIt)->baseAttribute(), *aSIt);
       isUpdated = true;
     }
   }