myEntityMaxID(SLVS_E_UNKNOWN),
myConstrMaxID(SLVS_C_UNKNOWN),
myFixed(SLVS_E_UNKNOWN),
- myNeedToResolve(false)
+ myNeedToResolve(false),
+ myDuplicatedConstraint(false)
{
}
return true;
}
}
- // 2. The line is used in Parallel/Perpendicular and Length constraints
+ // 2. The line is used in Parallel/Perpendicular/Vertical/Horizontal and Length constraints
aList = getConstraintsByType(SLVS_C_PARALLEL);
aList.splice(aList.end(), getConstraintsByType(SLVS_C_PERPENDICULAR));
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_VERTICAL));
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_HORIZONTAL));
for (anIt = aList.begin(); anIt != aList.end(); anIt++)
if (anIt->entityA == theEntityID || anIt->entityB == theEntityID) {
Slvs_hEntity anOther = anIt->entityA == theEntityID ? anIt->entityB : anIt->entityA;
Slvs_Constraint aConstraint = theConstraint;
- // Find a constraint with same type uses same arguments
+ // Find a constraint with same type uses same arguments to show user overconstraint situation
std::vector<Slvs_Constraint>::iterator aCIt = myConstraints.begin();
for (; aCIt != myConstraints.end(); aCIt++) {
if (aConstraint.type != aCIt->type)
continue;
if (aConstraint.ptA == aCIt->ptA && aConstraint.ptB == aCIt->ptB &&
aConstraint.entityA == aCIt->entityA && aConstraint.entityB == aCIt->entityB &&
- aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD) {
- aConstraint.h = aCIt->h;
- return updateConstraint(aConstraint);
- }
+ aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD)
+ myDuplicatedConstraint = true;
}
if (aConstraint.h > myConstrMaxID)
// remove temporary fixed point, if available
if (myFixed == theConstraintID)
myFixed = SLVS_E_UNKNOWN;
+ if (myDuplicatedConstraint) {
+ // Check the duplicated constraints are still available
+ myDuplicatedConstraint = false;
+ std::vector<Slvs_Constraint>::const_iterator anIt1 = myConstraints.begin();
+ std::vector<Slvs_Constraint>::const_iterator anIt2 = myConstraints.begin();
+ for (; anIt1 != myConstraints.end() && !myDuplicatedConstraint; anIt1++)
+ for (anIt2 = anIt1+1; anIt2 != myConstraints.end() && !myDuplicatedConstraint; anIt2++) {
+ if (anIt1->type != anIt2->type)
+ continue;
+ if (anIt1->ptA == anIt2->ptA && anIt1->ptB == anIt2->ptB &&
+ anIt1->entityA == anIt2->entityA && anIt1->entityB == anIt2->entityB &&
+ anIt1->entityC == anIt2->entityC && anIt1->entityD == anIt2->entityD)
+ myDuplicatedConstraint = true;
+ }
+ }
}
return aResult;
}
myTemporaryConstraints.clear();
}
+int SketchSolver_Storage::deleteTemporaryConstraint()
+{
+ if (myTemporaryConstraints.empty())
+ return 0;
+ // Search the point-on-line or a non-rigid constraint
+ std::set<Slvs_hConstraint>::iterator aCIt = myTemporaryConstraints.begin();
+ for (; aCIt != myTemporaryConstraints.end(); aCIt++) {
+ int aPos = Search(*aCIt, myConstraints);
+ if (aPos >= (int)myConstraints.size() || myConstraints[aPos].type != SLVS_C_WHERE_DRAGGED)
+ break;
+ std::vector<Slvs_Constraint>::iterator anIt = myConstraints.begin();
+ for (; anIt != myConstraints.end(); anIt++)
+ if (anIt->type == SLVS_C_PT_ON_LINE && anIt->ptA == myConstraints[aPos].ptA)
+ break;
+ if (anIt != myConstraints.end())
+ break;
+ }
+ if (aCIt == myTemporaryConstraints.end())
+ aCIt = myTemporaryConstraints.begin();
+ bool aNewFixed = (*aCIt == myFixed);
+ removeConstraint(*aCIt);
+ myTemporaryConstraints.erase(aCIt);
+ if (aNewFixed) {
+ for (aCIt = myTemporaryConstraints.begin(); aCIt != myTemporaryConstraints.end(); aCIt++) {
+ int aPos = Search(*aCIt, myConstraints);
+ if (myConstraints[aPos].type == SLVS_C_WHERE_DRAGGED) {
+ myFixed = *aCIt;
+ break;
+ }
+ }
+ }
+ return (int)myTemporaryConstraints.size();
+}
+
bool SketchSolver_Storage::isTemporary(const Slvs_hConstraint& theConstraintID) const
{
return myTemporaryConstraints.find(theConstraintID) != myTemporaryConstraints.end();
for (; aCIter != myCoincidentPoints.end(); aCIter++)
if (aCIter->find(thePoint1) != aCIter->end() && aCIter->find(thePoint2) != aCIter->end())
return true;
+ // precise checking of coincidence
+ int aEnt1Pos = Search(thePoint1, myEntities);
+ int aEnt2Pos = Search(thePoint2, myEntities);
+ if (aEnt1Pos >= 0 && aEnt1Pos < (int)myEntities.size() &&
+ aEnt2Pos >= 0 && aEnt2Pos < (int)myEntities.size()) {
+ double aDist[2];
+ int aParamPos;
+ for (int i = 0; i < 2; i++) {
+ aParamPos = Search(myEntities[aEnt1Pos].param[i], myParameters);
+ aDist[i] = myParameters[aParamPos].val;
+ aParamPos = Search(myEntities[aEnt2Pos].param[i], myParameters);
+ aDist[i] -= myParameters[aParamPos].val;
+ }
+ if (aDist[0] * aDist[0] + aDist[1] * aDist[1] < tolerance * tolerance)
+ return true;
+ }
return false;
}