+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
// File: SketchSolver_ConstraintGroup.cpp
// Created: 27 May 2014
// Author: Artem ZHIDKOV
/// Tolerance for value of parameters
const double tolerance = 1.e-10;
-/*
+/**
* Collects all sketch solver error' codes
* as inline static functions
- * TODO: Move this class into a separate file
*/
+ // TODO: Move this class into a separate file
class SketchSolver_Error
{
public:
static const std::string MY_ERROR_VALUE("Conflicting constraints");
return MY_ERROR_VALUE;
}
+ /// The entities need to have shared point, but they have not
+ inline static const std::string& NO_COINCIDENT_POINTS()
+ {
+ static const std::string MY_ERROR_VALUE("Objects should have coincident point");
+ return MY_ERROR_VALUE;
+ }
};
/// This value is used to give unique index to the groups
// For the length constraint the start and end points of the line should be added to the entities list instead of line
if (aConstrType == SLVS_C_PT_PT_DISTANCE
&& theConstraint->getKind().compare(SketchPlugin_ConstraintLength::ID()) == 0) {
- Slvs_hEntity aLineEnt = changeEntity(aFeature);
+ Slvs_hEntity aLineEnt = changeEntityFeature(aFeature);
int aEntPos = Search(aLineEnt, myEntities);
aConstrEnt[indAttr++] = myEntities[aEntPos].point[0];
aConstrEnt[indAttr++] = myEntities[aEntPos].point[1];
aConstrEnt[indAttr++] = 0;
break; // there should be no other entities
} else if (aConstrAttr->isObject())
- aConstrEnt[indAttr] = changeEntity(aFeature);
+ aConstrEnt[indAttr] = changeEntityFeature(aFeature);
else
aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
}
removeTemporaryConstraints(aTmpConstrToDelete);
}
}
+ // For the tangency constraints it is necessary to identify which points of entities are coincident
+ int aSlvsOtherFlag = 0;
+ int aSlvsOther2Flag = 0;
+ if (aConstrType == SLVS_C_ARC_LINE_TANGENT || aConstrType == SLVS_C_CURVE_CURVE_TANGENT) {
+ // Search entities used by constraint
+ int anEnt1Pos = Search(aConstrEnt[2], myEntities);
+ int anEnt2Pos = Search(aConstrEnt[3], myEntities);
+ // Obtain start and end points of entities
+ Slvs_hEntity aPointsToFind[4];
+ aPointsToFind[0] = myEntities[anEnt1Pos].point[1];
+ aPointsToFind[1]= myEntities[anEnt1Pos].point[2];
+ bool hasLine = (myEntities[anEnt2Pos].type == SLVS_E_LINE_SEGMENT);
+ aPointsToFind[2]= myEntities[anEnt2Pos].point[hasLine ? 0 : 1];
+ aPointsToFind[3]= myEntities[anEnt2Pos].point[hasLine ? 1 : 2];
+ // Search coincident points
+ bool isPointFound[4];
+ std::vector<std::set<Slvs_hEntity> >::const_iterator aCPIter = myCoincidentPoints.begin();
+ for ( ; aCPIter != myCoincidentPoints.end(); aCPIter++) {
+ for (int i = 0; i < 4; i++)
+ isPointFound[i] = (aCPIter->find(aPointsToFind[i]) != aCPIter->end());
+ if ((isPointFound[0] || isPointFound[1]) && (isPointFound[2] || isPointFound[3])) {
+ // the arc is tangent by end point
+ if (isPointFound[1]) aSlvsOtherFlag = 1;
+ // the second item is an arc and it is tangent by end point too
+ if (!hasLine && isPointFound[3]) aSlvsOther2Flag = 1;
+ break;
+ }
+ }
+ if (aCPIter == myCoincidentPoints.end()) {
+ // There is no coincident points between tangential objects. Generate error message
+ Events_Error::send(SketchSolver_Error::NO_COINCIDENT_POINTS(), this);
+ return false;
+ }
+ }
// Create SolveSpace constraint structure
- Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
+ Slvs_Constraint aSlvsConstr = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
myWorkplane.h, aDistance, aConstrEnt[0],
aConstrEnt[1], aConstrEnt[2], aConstrEnt[3]);
- myConstraints.push_back(aConstraint);
- myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>(1, aConstraint.h);
- int aConstrPos = Search(aConstraint.h, myConstraints);
+ if (aSlvsOtherFlag != 0) aSlvsConstr.other = aSlvsOtherFlag;
+ if (aSlvsOther2Flag != 0) aSlvsConstr.other2 = aSlvsOther2Flag;
+ myConstraints.push_back(aSlvsConstr);
+ myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>(1, aSlvsConstr.h);
+ int aConstrPos = Search(aSlvsConstr.h, myConstraints);
aConstrIter = myConstraints.begin() + aConstrPos;
myNeedToSolve = true;
} else { // Attributes of constraint may be changed => update constraint
aFeature = aDoc->feature(aRC);
}
- aConstrEnt = aConstrAttr->isObject() ? changeEntity(aFeature) : changeEntity(aConstrAttr->attr());
+ aConstrEnt = aConstrAttr->isObject() ? changeEntityFeature(aFeature) : changeEntity(aConstrAttr->attr());
if (aConstrMapIter == myConstraintMap.end()) { // Add new constraint
// Check the fixed entity is not a point.
// Class: SketchSolver_ConstraintGroup
// Purpose: create/update the element defined by the feature affected by any constraint
// ============================================================================
-Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(FeaturePtr theEntity)
+Slvs_hEntity SketchSolver_ConstraintGroup::changeEntityFeature(FeaturePtr theEntity)
{
if (!theEntity->data()->isValid())
return SLVS_E_UNKNOWN;
// We should go through the attributes map, because only attributes have valued parameters
std::map<std::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator anEntIter =
myEntityAttrMap.begin();
- for (; anEntIter != myEntityAttrMap.end(); anEntIter++)
+ for (; anEntIter != myEntityAttrMap.end(); anEntIter++) {
+ if (anEntIter->first->owner().get() && anEntIter->first->owner()->data().get())
+ anEntIter->first->owner()->data()->blockSendAttributeUpdated(true);
if (updateAttribute(anEntIter->first, anEntIter->second))
updateRelatedConstraints(anEntIter->first);
+ }
+ // unblock all features then
+ for (anEntIter = myEntityAttrMap.begin(); anEntIter != myEntityAttrMap.end(); anEntIter++) {
+ if (anEntIter->first->owner().get() && anEntIter->first->owner()->data().get())
+ anEntIter->first->owner()->data()->blockSendAttributeUpdated(false);
+ }
} else if (!myConstraints.empty())
Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this);
}
}
-void SketchSolver_ConstraintGroup::updateRelatedConstraints(
+void SketchSolver_ConstraintGroup::updateRelatedConstraintsFeature(
std::shared_ptr<ModelAPI_Feature> theFeature) const
{
ConstraintMap::const_iterator aConstrIter = myConstraintMap.begin();