{
double* aResult = new double(0);
myParameters.push_back(aResult);
- if (myDOF >= 0)
- ++myDOF;
+ if (myConstraints.empty() && myDOF >= 0)
+ ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
return aResult;
}
solve();
return myDOF;
}
+
+void PlaneGCSSolver_Solver::diagnose()
+{
+ myEquationSystem->declareUnknowns(myParameters);
+ myDOF = myEquationSystem->diagnose();
+}
/// \brief Check the constraint is conflicted with others
bool isConflicting(const ConstraintID& theConstraint) const;
+ /// \brief Check conflicting/redundant constraints and DoF
+ void diagnose();
+
/// \brief Degrees of freedom
int dof();
if (myConstraintMap.empty())
return; // no need to process temporary constraints if there is no active constraint
+ // before adding movement constraint to solver, re-check its DOF
+ if (mySketchSolver->dof() == 0)
+ mySketchSolver->diagnose();
+
theSolverConstraint->setId(CID_MOVEMENT);
constraintsToSolver(theSolverConstraint, mySketchSolver);
}
for (; aPIt != aPoints.end(); ++aPIt) {
AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPIt);
EntityWrapperPtr anEnt = theStorage->entity(*aPIt);
- if (!anEnt)
- continue;
- PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
- if (!isSameCoordinates(aPnt, aPW))
- aChangedPoints.push_back(anEnt);
+ if (anEnt) {
+ PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
+ if (!isSameCoordinates(aPnt, aPW))
+ aChangedPoints.push_back(anEnt);
+ } else {
+ theStorage->update(*aPIt);
+ aChangedPoints.push_back(theStorage->entity(*aPIt));
+ }
}
EntityWrapperPtr aChanged;
bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
{
- if (myDOF == 0) {
+ bool isFeatureExists = (myStorage->entity(theFeature).get() != 0);
+ if (myDOF == 0 && isFeatureExists) {
// avoid moving elements of fully constrained sketch
myStorage->refresh();
return true;