From: azv Date: Tue, 19 Apr 2016 07:45:27 +0000 (+0300) Subject: Degrees of freedom for a sketch (issue #796) X-Git-Tag: V_2.3.0~197 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=28bb5c301466d4581d9a1b4aa920e0e101b8ac47;p=modules%2Fshaper.git Degrees of freedom for a sketch (issue #796) --- diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index 7aac578b8..45f321509 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -230,7 +230,8 @@ void ModelAPI_ReplaceParameterMessage::setObject(ObjectPtr theObject) // ===== ModelAPI_SolverFailedMessage ===== ModelAPI_SolverFailedMessage::ModelAPI_SolverFailedMessage(const Events_ID theID, const void* theSender) - : Events_Message(theID, theSender) + : Events_Message(theID, theSender), + myDOF(-1) { } diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index ff549a6f8..656ec109a 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -320,8 +320,14 @@ public: /// Returns list of conflicting constraints MODELAPI_EXPORT const std::set& objects() const; + /// Sets degrees of freedom + void dof(const int theDOF) { myDOF = theDOF; } + /// Returns degrees of freedom + const int& dof() const { return myDOF; } + private: std::set myObjects; + int myDOF; }; #endif diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index 3e18488eb..be98e05d9 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -97,3 +97,7 @@ void PlaneGCSSolver_Solver::collectConflicting() myConfCollected = true; } +int PlaneGCSSolver_Solver::dof() const +{ + return const_cast(this)->myEquationSystem.dofsNumber(); +} diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h index c2c463c5d..35920bca0 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h @@ -49,6 +49,9 @@ public: /// \brief Check the constraint is conflicted with others virtual bool isConflicting(const ConstraintID& theConstraint) const; + /// \brief Degrees of freedom + virtual int dof() const; + private: void collectConflicting(); diff --git a/src/SketchSolver/SketchSolver_ISolver.h b/src/SketchSolver/SketchSolver_ISolver.h index fd992971a..cd5254057 100644 --- a/src/SketchSolver/SketchSolver_ISolver.h +++ b/src/SketchSolver/SketchSolver_ISolver.h @@ -50,6 +50,9 @@ public: /// \brief Check the constraint is conflicted with others virtual bool isConflicting(const ConstraintID& theConstraint) const = 0; + /// \brief Degrees of freedom + virtual int dof() const = 0; + protected: GroupID myGroup; ///< ID of the group to be solved bool myFindFaileds; ///< flag to find conflicting or inappropriate constraints diff --git a/src/SketchSolver/SketchSolver_Manager.cpp b/src/SketchSolver/SketchSolver_Manager.cpp index 453fbf5fc..2422426e3 100644 --- a/src/SketchSolver/SketchSolver_Manager.cpp +++ b/src/SketchSolver/SketchSolver_Manager.cpp @@ -15,9 +15,27 @@ #include #include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -26,6 +44,7 @@ #include #include +#include #include #include #include @@ -184,6 +203,7 @@ void SketchSolver_Manager::processEvent( resolveConstraints(aGroupsToResolve); } } + degreesOfFreedom(); myIsComputed = false; } @@ -425,6 +445,136 @@ bool SketchSolver_Manager::resolveConstraints(const std::list aDoFDelta; // indicates how many DoF adds or decreases a feature + static bool isNeedInit = true; + if (isNeedInit) { + aDoFDelta[SketchPlugin_Point::ID()] = 2; + aDoFDelta[SketchPlugin_Line::ID()] = 4; + aDoFDelta[SketchPlugin_Circle::ID()] = 3; + aDoFDelta[SketchPlugin_Arc::ID()] = 5; + + aDoFDelta[SketchPlugin_ConstraintAngle::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintCollinear::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintDistance::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintEqual::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintHorizontal::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintLength::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintMiddle::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintParallel::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintPerpendicular::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintRadius::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintTangent::ID()] = -1; + aDoFDelta[SketchPlugin_ConstraintVertical::ID()] = -1; + + isNeedInit = false; + } + + std::map aSketchDoF; + + std::list::const_iterator aGroupIt = myGroups.begin(); + for (; aGroupIt != myGroups.end(); ++aGroupIt) { + CompositeFeaturePtr aSketch = (*aGroupIt)->getWorkplane(); + + // check conflicting constraints in the group + if ((*aGroupIt)->isFailed()) + aSketchDoF[aSketch] = -1; + // check the sketch is already processed + if (aSketchDoF.find(aSketch) != aSketchDoF.end() || aSketchDoF[aSketch] < 0) + continue; + + int aDoF = 0; + int aNbSubs = aSketch->numberOfSubs(); + for (int i = 0; i < aNbSubs; ++i) { + FeaturePtr aFeature = aSketch->subFeature(i); + // check DoF delta for invariant types + std::map::const_iterator aFound = aDoFDelta.find(aFeature->getKind()); + if (aFound != aDoFDelta.end()) { + aDoF += aFound->second; + continue; + } + + // DoF delta in specific cases + if (aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + for (int j = 0; j < 2; ++j) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j))); + if (!aRefAttr) + continue; + bool isPoint = !aRefAttr->isObject(); + if (!isPoint) { + FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object()); + isPoint = anAttr && anAttr->getKind() == SketchPlugin_Point::ID(); + } + if (isPoint) + aDoF -= 1; + } + } + else if (aFeature->getKind() == SketchPlugin_ConstraintRigid::ID()) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Constraint::ENTITY_A())); + assert(aRefAttr); + if (!aRefAttr->isObject()) + aDoF -= 2; // attribute is a point + else { + FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object()); + assert(anAttr); + aDoF -= aDoFDelta[anAttr->getKind()]; + } + } + else if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID() || + aFeature->getKind() == SketchPlugin_MultiRotation::ID() || + aFeature->getKind() == SketchPlugin_MultiTranslation::ID()) { + int aNbCopies = 1; + std::string anAttrName; + if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID()) + anAttrName = SketchPlugin_Constraint::ENTITY_B(); + else { + if (aFeature->getKind() == SketchPlugin_MultiRotation::ID()) + aNbCopies = aFeature->integer(SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID())->value() - 1; + else if (aFeature->getKind() == SketchPlugin_MultiTranslation::ID()) + aNbCopies = aFeature->integer(SketchPlugin_MultiTranslation::NUMBER_OF_OBJECTS_ID())->value() - 1; + anAttrName = SketchPlugin_Constraint::ENTITY_A(); + } + + AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast( + aFeature->attribute(anAttrName)); + std::list anObjList = aRefListOfShapes->list(); + std::list::const_iterator anObjIt = anObjList.begin(); + for (; anObjIt != anObjList.end(); ++anObjIt) { + FeaturePtr aSub = ModelAPI_Feature::feature(*anObjIt); + aDoF -= aDoFDelta[aSub->getKind()] * aNbCopies; + } + } + } + + aSketchDoF[aSketch] = aDoF; + } + + // Check the degrees of freedom are changed + std::map::const_iterator aDoFIt = aSketchDoF.begin(); + std::map::iterator aFound; + for (; aDoFIt != aSketchDoF.end(); ++aDoFIt) { + if (aDoFIt->second < 0) + continue; // conflicting constraints on the current sketch + aFound = myDoF.find(aDoFIt->first); + if (aFound != myDoF.end() && aFound->second == aDoFIt->second) + continue; // nothing is changed + myDoF[aDoFIt->first] = aDoFIt->second; + // send a message + std::shared_ptr aMessage = + std::shared_ptr( + new ModelAPI_SolverFailedMessage(Events_Loop::eventByName(EVENT_SOLVER_REPAIRED))); + aMessage->dof(aDoFIt->second); + Events_Loop::loop()->send(aMessage); + } +} + bool SketchSolver_Manager::stopSendUpdate() const { // to avoid redisplay of each segment on update by solver one by one in the viewer diff --git a/src/SketchSolver/SketchSolver_Manager.h b/src/SketchSolver/SketchSolver_Manager.h index 42ec9df67..0781129c0 100644 --- a/src/SketchSolver/SketchSolver_Manager.h +++ b/src/SketchSolver/SketchSolver_Manager.h @@ -113,6 +113,9 @@ private: /// find other groups on the same sketch, which have conflicts. void checkConflictingConstraints(const std::shared_ptr& theMessage); + /// \brief Calculate DoF for each sketch and send messages if changed + void degreesOfFreedom(); + private: static SketchSolver_Manager* mySelf; ///< Self pointer to implement singleton functionality std::list myGroups; ///< Groups of constraints @@ -120,6 +123,8 @@ private: /// true if computation is performed and all "updates" are generated by this algo /// and needs no recomputation bool myIsComputed; + + std::map myDoF; ///< Degree of freedom for corresponding sketch }; #endif diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp index f1d72c8ba..2adb7dcd6 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp @@ -205,3 +205,8 @@ bool SolveSpaceSolver_Solver::isConflicting(const ConstraintID& theConstraint) c return true; return false; } + +int SolveSpaceSolver_Solver::dof() const +{ + return myEquationsSystem.dof; +} diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h index cc78b95a6..b80421707 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h @@ -83,6 +83,9 @@ public: /// \brief Check the constraint is conflicted with others virtual bool isConflicting(const ConstraintID& theConstraint) const; + /// \brief Degrees of freedom + virtual int dof() const; + private: /// \brief Check whether degenerated arcs exist bool hasDegeneratedArcs() const;