assert (aRefListC.size() == 1)
checkMirror(aRefListB, aRefListC, aMirrorLine)
assert (model.dof(aSketchFeature) == 12)
+
+#=========================================================================
+# Create distance between original and mirrored entities (check the error appears)
+#=========================================================================
+aSketchErrorAttr = aSketchFeature.string("SolverError")
+assert len(aSketchErrorAttr.value()) == 0, "Sketch failed with error: {}".format(aSketchErrorAttr.value())
+aMirroredArc = model.lastSubFeature(aSketchFeature, "SketchArc")
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintDistance")
+refAttrA = aConstraint.refattr("ConstraintEntityA")
+refAttrB = aConstraint.refattr("ConstraintEntityB")
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("start_point"))
+aMirroredArcStartPoint = geomDataAPI_Point2D(aMirroredArc.attribute("start_point"))
+refAttrA.setAttr(anArcStartPoint)
+refAttrB.setAttr(aMirroredArcStartPoint)
+aConstraint.real("ConstraintValue").setValue(200.)
+aSession.finishOperation()
+print "Sketch error : {}".format(aSketchErrorAttr.value())
+assert len(aSketchErrorAttr.value()) != 0, "ERROR: Sketch has not been failed as expected"
+aSession.startOperation()
+aDocument.removeFeature(aConstraint)
+aSession.finishOperation()
+
#=========================================================================
# End of test
#=========================================================================
}
// indicates attribute containing in the external feature
-bool isExternalAttribute(const AttributePtr& theAttribute)
+static bool isExternalAttribute(const AttributePtr& theAttribute)
{
if (!theAttribute)
return false;
return aSketchFeature.get() && aSketchFeature->isExternal();
}
+static void addOwnerToSet(const AttributePtr& theAttribute, std::set<FeaturePtr>& theFeatures)
+{
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
+ if (anOwner)
+ theFeatures.insert(anOwner);
+}
+
void PlaneGCSSolver_Storage::refresh() const
{
const double aTol = 1000. * tolerance; // tolerance to prevent frequent updates
+ std::set<FeaturePtr> anUpdatedFeatures;
+
std::map<AttributePtr, EntityWrapperPtr>::const_iterator anIt = myAttributeMap.begin();
for (; anIt != myAttributeMap.end(); ++anIt) {
// the external feature always should keep the up to date values, so,
std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
GCSPointPtr aGCSPoint = aPointWrapper->point();
if (fabs(aPoint2D->x() - (*aGCSPoint->x)) > aTol ||
- fabs(aPoint2D->y() - (*aGCSPoint->y)) > aTol)
+ fabs(aPoint2D->y() - (*aGCSPoint->y)) > aTol) {
aPoint2D->setValue(*aGCSPoint->x, *aGCSPoint->y);
+ addOwnerToSet(anIt->first, anUpdatedFeatures);
+ }
continue;
}
AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anIt->first);
if (aScalar) {
ScalarWrapperPtr aScalarWrapper =
std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
- if (fabs(aScalar->value() - aScalarWrapper->value()) > aTol)
+ if (fabs(aScalar->value() - aScalarWrapper->value()) > aTol) {
aScalar->setValue(aScalarWrapper->value());
+ addOwnerToSet(anIt->first, anUpdatedFeatures);
+ }
continue;
}
}
+
+ // notify listeners about features update
+ std::set<FeaturePtr>::const_iterator aFIt = anUpdatedFeatures.begin();
+ for (; aFIt != anUpdatedFeatures.end(); ++aFIt)
+ notify(*aFIt);
}
theAngle = aValueBuilder.createAttribute(anAngleAttr);
myStorage->addEntity(anAngleAttr, theAngle);
- AttributePtr aCenterAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID());
+ AttributeRefAttrPtr aCenterAttr = myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID());
if (!aCenterAttr || !aCenterAttr->isInitialized()) {
myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
return;
theFullValue = aMethodTypeAttr->value() != "SingleAngle";
getEntities(theEntities);
+
+ // add owner of central point of Multi-Rotation to the list of monitored features
+ FeaturePtr anOwner = ModelAPI_Feature::feature(aCenterAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
}
void SketchSolver_ConstraintMultiRotation::process()
bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
{
DataPtr aData = myBaseConstraint->data();
- AttributePtr aStartPointAttr = aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID());
- AttributePtr aEndPointAttr = aData->attribute(SketchPlugin_MultiTranslation::END_POINT_ID());
+ AttributeRefAttrPtr aStartPointAttr = aData->refattr(SketchPlugin_MultiTranslation::START_POINT_ID());
+ AttributeRefAttrPtr aEndPointAttr = aData->refattr(SketchPlugin_MultiTranslation::END_POINT_ID());
if (!aStartPointAttr || !aStartPointAttr->isInitialized() ||
!aEndPointAttr || !aEndPointAttr->isInitialized()) {
myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
theFullValue = aMethodTypeAttr->value() != "SingleValue";
getEntities(theEntities);
+
+ // add owner of start and end points of Multi-Translation to the list of monitored features
+ FeaturePtr anOwner = ModelAPI_Feature::feature(aStartPointAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
+ anOwner = ModelAPI_Feature::feature(aEndPointAttr->attr()->owner());
+ if (anOwner)
+ myFeatures.insert(anOwner);
}
void SketchSolver_ConstraintMultiTranslation::process()
// additional check that copied entities used in Mirror and other "Multi" constraints
// is not connected with their originals by constraints.
myMultiConstraintUpdateStack += 1;
- updateMultiConstraints();
aResolved = true;
if (myStorage->isNeedToResolve())
aResolved = resolveConstraints();
myIsEventsBlocked = isBlocked;
}
-// ============================================================================
-// Function: updateMultiConstraints
-// Class: SketchSolver_Group
-// Purpose: update multi constraints
-// ============================================================================
-void SketchSolver_Group::updateMultiConstraints()
-{
- ConstraintConstraintMap::iterator anIt = myConstraints.begin();
- for (; anIt != myConstraints.end(); ++anIt) {
- if (anIt->first->getKind() == SketchPlugin_ConstraintMirror::ID() ||
- anIt->first->getKind() == SketchPlugin_MultiRotation::ID() ||
- anIt->first->getKind() == SketchPlugin_MultiTranslation::ID())
- anIt->second->update();
- }
-}
-
bool SketchSolver_Group::areConstraintsValid() const
{
// Check the constraints are valid
/// \brief Append given constraint to the group of temporary constraints
void setTemporary(SolverConstraintPtr theConstraint);
- /// \brief Update dependent (copied) features created by Mirror and other "Multi" constraints
- void updateMultiConstraints();
-
/// \brief Compute DoF of the sketch and set corresponding field
void computeDoF();