if (!theConstraint)
return false;
- if (myConstraints.find(theConstraint) == myConstraints.end()) {
+ bool isNewConstraint = myConstraints.find(theConstraint) == myConstraints.end();
+ if (isNewConstraint) {
// Add constraint to the current group
SolverConstraintPtr aConstraint =
SketchSolver_Builder::getInstance()->createConstraint(theConstraint);
myConstraints[theConstraint]->update();
// Fix base features for fillet
- if (theConstraint->getKind() == SketchPlugin_ConstraintFillet::ID()) {
+ if (isNewConstraint && theConstraint->getKind() == SketchPlugin_ConstraintFillet::ID()) {
std::list<AttributePtr> anAttrList =
theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
std::list<AttributePtr>::iterator anAttrIter = anAttrList.begin();
setTemporary(aConstraint);
}
}
- //// Fix base features for mirror
- //if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID()) {
- // AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
- // theConstraint->attribute(SketchPlugin_ConstraintMirror::ENTITY_B()));
- // fixFeaturesList(aRefList);
- //}
+ // Fix mirror line
+ if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID()) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ theConstraint->attribute(SketchPlugin_ConstraintMirror::ENTITY_A()));
+ if (aRefAttr && aRefAttr->isObject()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aFeature) {
+ SolverConstraintPtr aConstraint =
+ SketchSolver_Builder::getInstance()->createRigidConstraint(aFeature);
+ if (aConstraint) {
+ aConstraint->setGroup(this);
+ aConstraint->setStorage(myStorage);
+ setTemporary(aConstraint);
+ }
+ }
+ }
+ }
if (!myFeatureStorage)
myFeatureStorage = FeatureStoragePtr(new SketchSolver_FeatureStorage);
void SketchSolver_Group::moveFeature(std::shared_ptr<SketchPlugin_Feature> theFeature)
{
- updateFeature(theFeature);
- // Temporary rigid constraint
+ // Firstly, create temporary rigid constraint
SolverConstraintPtr aConstraint =
SketchSolver_Builder::getInstance()->createRigidConstraint(theFeature);
if (!aConstraint)
aConstraint->setStorage(myStorage);
if (aConstraint->error().empty())
setTemporary(aConstraint);
+ // Secondly, update the feature
+ updateFeature(theFeature);
}
// ============================================================================
try {
if (myStorage->hasDuplicatedConstraint())
aResult = SLVS_RESULT_INCONSISTENT;
- else
- aResult = myConstrSolver.solve();
+ else {
+ // To avoid overconstraint situation, we will remove temporary constraints one-by-one
+ // and try to find the case without overconstraint
+ int aNbTemp = myStorage->numberTemporary();
+ while (true) {
+ aResult = myConstrSolver.solve();
+ if (aResult == SLVS_RESULT_OKAY || aNbTemp <= 0)
+ break;
+ aNbTemp = myStorage->deleteTemporaryConstraint();
+ myStorage->initializeSolver(myConstrSolver);
+ }
+ }
} catch (...) {
Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this);
return false;
void SketchSolver_Group::removeTemporaryConstraints()
{
myTempConstraints.clear();
- myStorage->removeTemporaryConstraints();
+ while (myStorage->numberTemporary())
+ myStorage->deleteTemporaryConstraint();
// Clean lists of removed entities in the storage
std::set<Slvs_hParam> aRemPar;
std::set<Slvs_hEntity> aRemEnt;