From 3d4920e4e7b481bb0f09a44f26e28688468f2216 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sun, 4 Jun 2017 07:55:41 +0200 Subject: [PATCH] Sketcher: Extension to report redundancy, Standardisation of return codes for solve, documentation, initialisation of solver information ======================================================================================================================================== Motivation: - Improve notifications of redundancy in the solver (Bonus effect, now the sketcher refuses to add a redundant datum constraint) - Initialize all solver information, so that it is accurate also in corner cases. - Provide different return codes for the different solver status/conflicting/redundant/overconstraint (also looking forward for a future refactoring) Impact: - Python users that are currently using the return code of solve() for detecting overconstraint/conflicting/solver error, if any, might have to adapt their scripts. Those who are just checking for zero/non-zero will have to do nothing. --- src/Mod/Sketcher/App/SketchObject.cpp | 29 ++++++++++++++++++--------- src/Mod/Sketcher/App/SketchObject.h | 3 ++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index c714a4d8a9..165fc4999b 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -232,20 +232,33 @@ int SketchObject::solve(bool updateGeoAfterSolving/*=true*/) // set up a sketch (including dofs counting and diagnosing of conflicts) lastDoF = solvedSketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), getExternalGeometryCount()); - + // At this point we have the solver information about conflicting/redundant/over-constrained, but the sketch is NOT solved. // Some examples: // Redundant: a vertical line, a horizontal line and an angle constraint of 90 degrees between the two lines // Conflicting: a 80 degrees angle between a vertical line and another line, then adding a horizontal constraint to that other line // OverConstrained: a conflicting constraint when all other DoF are already constraint (it has more constrains than parameters and the extra constraints are not redundant) - + solverNeedsUpdate=false; - + lastHasConflict = solvedSketch.hasConflicts(); - + lastHasRedundancies = solvedSketch.hasRedundancies(); + lastConflicting=solvedSketch.getConflicting(); + lastRedundant=solvedSketch.getRedundant(); + lastSolveTime=0.0; + + lastSolverStatus=GCS::Failed; // Failure is default for notifying the user unless otherwise proven + int err=0; + + // redundancy is a lower priority problem than conflict/over-constraint/solver error + // we set it here because we are indeed going to solve, as we can. However, we still want to + // provide the right error code. + if (lastHasRedundancies) // redundant constraints + err = -2; + if (lastDoF < 0) { // over-constrained sketch - err = -3; + err = -4; // if lastDoF<0, then an over-constrained situation has ensued. // The solver has the updated geometry of the SketchObject (see setUpSketch above). // However we are not trying to solve for a geometry that cannot fulfil the constraints. @@ -261,17 +274,13 @@ int SketchObject::solve(bool updateGeoAfterSolving/*=true*/) else { lastSolverStatus=solvedSketch.solve(); if (lastSolverStatus != 0){ // solving - err = -2; + err = -1; // if solver failed, invalid constraints were likely added before solving // (see solve in addConstraint), so solver information is definitely invalid. this->Constraints.touch(); } } - lastHasRedundancies = solvedSketch.hasRedundancies(); - - lastConflicting=solvedSketch.getConflicting(); - lastRedundant=solvedSketch.getRedundant(); lastSolveTime=solvedSketch.SolveTime; if (err == 0 && updateGeoAfterSolving) { diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 3413e71336..a061a7437c 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -153,7 +153,8 @@ public: When a recompute is necessary, recompute triggers execute() which solves the sketch and updates all dependent features When a solve only is necessary (e.g. DoF changed), solve() solves the sketch and updates the geometry (if updateGeoAfterSolving==true), but does not trigger any recompute. - @return 0 + @return 0 if no error, if error, the following codes in this order of priority: -4 if overconstrained, + -3 if conflicting, -1 if solver error, -2 if redundant constraints */ int solve(bool updateGeoAfterSolving=true); /// set the datum of a Distance or Angle constraint and solve