aConstraint->changeConstraint() = getConstraint(aConstrID);
isUpdated = true;
// check duplicated constraints based on different attributes
- if (myDuplicatedConstraint && !hasDupConstraints && findSameConstraint(aConstraint))
+ if (myDuplicatedConstraint && findSameConstraint(aConstraint) && !hasDupConstraints)
myDuplicatedConstraint = false;
}
}
(*aCWIt)->type() == CONSTRAINT_MULTI_TRANSLATION)
continue;
if ((*aCWIt)->type() == theConstraint->type()) {
- const Slvs_Constraint& aCComp = std::dynamic_pointer_cast<
- SolveSpaceSolver_ConstraintWrapper>(*aCWIt)->constraint();
+ const Slvs_Constraint& aCComp = getConstraint((Slvs_hConstraint)(*aCWIt)->id());
+
if (aCBase.ptA == aCComp.ptA && aCBase.ptB == aCComp.ptB &&
aCBase.entityA == aCComp.entityA && aCBase.entityB == aCComp.entityB &&
aCBase.entityC == aCComp.entityC && aCBase.entityD == aCComp.entityD &&
// parameter already used, rewrite it
int aPos = Search(theParam.h, myParameters);
if (aPos >= 0 && aPos < (int)myParameters.size()) {
- if (IsNotEqual(myParameters[aPos], theParam)) {
- myUpdatedParameters.insert(theParam.h);
+ if (IsNotEqual(myParameters[aPos], theParam))
setNeedToResolve(true);
- }
myParameters[aPos] = theParam;
return theParam.h;
}
return aResult;
}
-void SolveSpaceSolver_Storage::removeUnusedEntities()
-{
- std::set<Slvs_hEntity> anUnusedEntities;
- std::vector<Slvs_Entity>::const_iterator aEIt = myEntities.begin();
- for (; aEIt != myEntities.end(); ++aEIt) {
- if (aEIt->h == aEIt->wrkpl) {
- // don't remove workplane
- anUnusedEntities.erase(aEIt->point[0]);
- anUnusedEntities.erase(aEIt->normal);
- continue;
- }
- anUnusedEntities.insert(aEIt->h);
- }
-
- std::vector<Slvs_Constraint>::const_iterator aCIt = myConstraints.begin();
- for (; aCIt != myConstraints.end(); ++aCIt) {
- Slvs_hEntity aSubs[6] = {
- aCIt->entityA, aCIt->entityB,
- aCIt->entityC, aCIt->entityD,
- aCIt->ptA, aCIt->ptB};
- for (int i = 0; i < 6; i++) {
- if (aSubs[i] != SLVS_E_UNKNOWN) {
- anUnusedEntities.erase(aSubs[i]);
- int aPos = Search(aSubs[i], myEntities);
- if (aPos >= 0 && aPos < (int)myEntities.size()) {
- for (int j = 0; j < 4; j++)
- if (myEntities[aPos].point[j] != SLVS_E_UNKNOWN)
- anUnusedEntities.erase(myEntities[aPos].point[j]);
- if (myEntities[aPos].distance != SLVS_E_UNKNOWN)
- anUnusedEntities.erase(myEntities[aPos].distance);
- }
- }
- }
- }
-
- std::set<Slvs_hEntity>::const_iterator anEntIt = anUnusedEntities.begin();
- while (anEntIt != anUnusedEntities.end()) {
- int aPos = Search(*anEntIt, myEntities);
- if (aPos < 0 && aPos >= (int)myEntities.size())
- continue;
- Slvs_Entity anEntity = myEntities[aPos];
- // Remove entity if and only if all its parameters unused
- bool isUsed = false;
- if (anEntity.distance != SLVS_E_UNKNOWN &&
- anUnusedEntities.find(anEntity.distance) == anUnusedEntities.end())
- isUsed = true;
- for (int i = 0; i < 4 && !isUsed; i++)
- if (anEntity.point[i] != SLVS_E_UNKNOWN &&
- anUnusedEntities.find(anEntity.point[i]) == anUnusedEntities.end())
- isUsed = true;
- if (isUsed) {
- anUnusedEntities.erase(anEntity.distance);
- for (int i = 0; i < 4; i++)
- if (anEntity.point[i] != SLVS_E_UNKNOWN)
- anUnusedEntities.erase(anEntity.point[i]);
- std::set<Slvs_hEntity>::iterator aRemoveIt = anEntIt++;
- anUnusedEntities.erase(aRemoveIt);
- continue;
- }
- ++anEntIt;
- }
-
- for (anEntIt = anUnusedEntities.begin(); anEntIt != anUnusedEntities.end(); ++anEntIt) {
- int aPos = Search(*anEntIt, myEntities);
- if (aPos >= 0 && aPos < (int)myEntities.size()) {
- // Remove entity and its parameters
- Slvs_Entity anEntity = myEntities[aPos];
- myEntities.erase(myEntities.begin() + aPos);
- myEntityMaxID = myEntities.empty() ? SLVS_E_UNKNOWN : myEntities.back().h;
- if (anEntity.distance != SLVS_E_UNKNOWN)
- removeParameter(anEntity.distance);
- for (int i = 0; i < 4; i++)
- if (anEntity.param[i] != SLVS_E_UNKNOWN)
- removeParameter(anEntity.param[i]);
- for (int i = 0; i < 4; i++)
- if (anEntity.point[i] != SLVS_E_UNKNOWN)
- removeEntity(anEntity.point[i]);
- }
- }
-
- if (!anUnusedEntities.empty())
- myNeedToResolve = true;
-}
-
-bool SolveSpaceSolver_Storage::isUsedByConstraints(const Slvs_hEntity& theEntityID) const
-{
- std::vector<Slvs_Constraint>::const_iterator aCIt = myConstraints.begin();
- for (; aCIt != myConstraints.end(); ++aCIt) {
- Slvs_hEntity aSubs[6] = {
- aCIt->entityA, aCIt->entityB,
- aCIt->entityC, aCIt->entityD,
- aCIt->ptA, aCIt->ptB};
- for (int i = 0; i < 6; i++)
- if (aSubs[i] != SLVS_E_UNKNOWN && aSubs[i] == theEntityID)
- return true;
- }
- return false;
-}
-
const Slvs_Entity& SolveSpaceSolver_Storage::getEntity(const Slvs_hEntity& theEntityID) const
{
int aPos = Search(theEntityID, myEntities);
return aDummy;
}
-Slvs_hEntity SolveSpaceSolver_Storage::copyEntity(const Slvs_hEntity& theCopied)
-{
- int aPos = Search(theCopied, myEntities);
- if (aPos < 0 || aPos >= (int)myEntities.size())
- return SLVS_E_UNKNOWN;
-
- Slvs_Entity aCopy = myEntities[aPos];
- aCopy.h = SLVS_E_UNKNOWN;
- int i = 0;
- while (aCopy.point[i] != SLVS_E_UNKNOWN) {
- aCopy.point[i] = copyEntity(aCopy.point[i]);
- i++;
- }
- if (aCopy.param[0] != SLVS_E_UNKNOWN) {
- aPos = Search(aCopy.param[0], myParameters);
- i = 0;
- while (aCopy.param[i] != SLVS_E_UNKNOWN) {
- Slvs_Param aNewParam = myParameters[aPos];
- aNewParam.h = SLVS_E_UNKNOWN;
- aCopy.param[i] = addParameter(aNewParam);
- i++;
- aPos++;
- }
- }
- return addEntity(aCopy);
-}
-
-void SolveSpaceSolver_Storage::copyEntity(const Slvs_hEntity& theFrom, const Slvs_hEntity& theTo)
-{
- int aPosFrom = Search(theFrom, myEntities);
- int aPosTo = Search(theTo, myEntities);
- if (aPosFrom < 0 || aPosFrom >= (int)myEntities.size() ||
- aPosTo < 0 || aPosTo >= (int)myEntities.size())
- return;
-
- Slvs_Entity aEntFrom = myEntities[aPosFrom];
- Slvs_Entity aEntTo = myEntities[aPosTo];
- int i = 0;
- while (aEntFrom.point[i] != SLVS_E_UNKNOWN) {
- copyEntity(aEntFrom.point[i], aEntTo.point[i]);
- i++;
- }
- if (aEntFrom.param[0] != SLVS_E_UNKNOWN) {
- aPosFrom = Search(aEntFrom.param[0], myParameters);
- aPosTo = Search(aEntTo.param[0], myParameters);
- i = 0;
- while (aEntFrom.param[i] != SLVS_E_UNKNOWN) {
- myParameters[aPosTo++].val = myParameters[aPosFrom++].val;
- i++;
- }
- }
-}
-
Slvs_hConstraint SolveSpaceSolver_Storage::addConstraint(const Slvs_Constraint& theConstraint)
{
aConstraint.entityA == aCIt->entityA && aConstraint.entityB == aCIt->entityB &&
aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD) {
myDuplicatedConstraint = true;
- return aCIt->h;
+ break;
}
}
// Constraint is not found, add new one
Slvs_Constraint aConstraint = theConstraint;
aConstraint.h = 0;
+
+ // Firstly, check middle-point constraint conflicts with point-on-line
+ if (aConstraint.type == SLVS_C_AT_MIDPOINT) {
+ std::vector<Slvs_Constraint>::const_iterator anIt = myConstraints.begin();
+ for (; anIt != myConstraints.end(); ++anIt)
+ if (anIt->type == SLVS_C_PT_ON_LINE &&
+ anIt->ptA == aConstraint.ptA &&
+ anIt->entityA == aConstraint.entityA)
+ break;
+ if (anIt != myConstraints.end()) {
+ // change the constraint to the lengths equality to avoid conflicts
+ Slvs_Entity aLine = getEntity(aConstraint.entityA);
+ Slvs_Entity aNewLine1 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroupID,
+ myWorkplaneID, aLine.point[0], aConstraint.ptA);
+ aNewLine1.h = addEntity(aNewLine1);
+ Slvs_Entity aNewLine2 = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroupID,
+ myWorkplaneID, aLine.point[1], aConstraint.ptA);
+ aNewLine2.h = addEntity(aNewLine2);
+ aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroupID, SLVS_C_EQUAL_LENGTH_LINES,
+ myWorkplaneID, 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aNewLine1.h, aNewLine2.h);
+ }
+ }
+
return addConstraint(aConstraint);
}
std::dynamic_pointer_cast<SolveSpaceSolver_ConstraintWrapper>(theConstraint);
// verify whether the constraint has duplicated
+ bool hasSameID = false;
SameConstraintMap::iterator anEqIt = myEqualConstraints.begin();
- for (; anEqIt != myEqualConstraints.end(); ++anEqIt)
- if (anEqIt->find(aConstraint) != anEqIt->end()) {
+ for (; anEqIt != myEqualConstraints.end(); ++anEqIt) {
+ std::set<ConstraintWrapperPtr>::const_iterator aFound = anEqIt->find(aConstraint);
+ if (aFound != anEqIt->end()) {
+ // verify there is a constraint with same ID
+ std::set<ConstraintWrapperPtr>::const_iterator anIt = anEqIt->begin();
+ ConstraintID anID = (*aFound)->id();
+ for (++anIt; anIt != anEqIt->end() && !hasSameID; ++anIt)
+ if ((*anIt)->id() == anID && aFound != anIt)
+ hasSameID = true;
+ // erase constraint
anEqIt->erase(aConstraint);
break;
}
- if (anEqIt != myEqualConstraints.end())
+ }
+ if (anEqIt != myEqualConstraints.end() && hasSameID)
return true;
bool isFullyRemoved = removeConstraint((Slvs_hConstraint)aConstraint->id());
- isFullyRemoved = SketchSolver_Storage::remove(theConstraint) && isFullyRemoved;
-
// remove point-point coincidence
if (aConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT)
isFullyRemoved = removeCoincidence(theConstraint) && isFullyRemoved;
- return isFullyRemoved;
+ return SketchSolver_Storage::remove(theConstraint) && isFullyRemoved;
}
bool SolveSpaceSolver_Storage::remove(EntityWrapperPtr theEntity)
std::shared_ptr<SolveSpaceSolver_EntityWrapper> anEntity =
std::dynamic_pointer_cast<SolveSpaceSolver_EntityWrapper>(theEntity);
bool isFullyRemoved = isCoincide ? true : removeEntity((Slvs_hEntity)anEntity->id());
- return SketchSolver_Storage::remove(theEntity) && isFullyRemoved;
+ return (SketchSolver_Storage::remove(theEntity) || isCoincide) && isFullyRemoved;
}
bool SolveSpaceSolver_Storage::remove(ParameterWrapperPtr theParameter)
for (; anAttrIt != myAttributeMap.end(); ++anAttrIt) {
if (!anAttrIt->second)
continue;
+ if (anAttrIt->second->group() == GID_OUTOFGROUP) {
+ Slvs_Entity anEnt = getEntity((Slvs_hEntity)anAttrIt->second->id());
+ if (anEnt.group != (Slvs_hEntity)GID_OUTOFGROUP)
+ anEnt.group = (Slvs_hEntity)GID_OUTOFGROUP;
+ updateEntity(anEnt);
+ }
+
const std::list<ParameterWrapperPtr>& aParameters = anAttrIt->second->parameters();
std::list<ParameterWrapperPtr>::const_iterator aParIt = aParameters.begin();
for (; aParIt != aParameters.end(); ++aParIt)
- if ((*aParIt)->group() == GID_OUTOFGROUP) {
+ if (anAttrIt->second->group() == GID_OUTOFGROUP || (*aParIt)->group() == GID_OUTOFGROUP) {
Slvs_Param aParam = getParameter((Slvs_hParam)(*aParIt)->id());
if (aParam.group != (Slvs_hParam)GID_OUTOFGROUP) {
aParam.group = (Slvs_hParam)GID_OUTOFGROUP;