+ } else {
+ // 1. check whether the references object is a linear
+ ObjectPtr anObject = aRefAttr->object();
+
+ const ModelAPI_AttributeValidator* aShapeValidator =
+ dynamic_cast<const ModelAPI_AttributeValidator*>(aFactory->validator("GeomValidators_ShapeType"));
+ std::list<std::string> anArguments;
+ anArguments.push_back("circle");
+ Events_InfoMessage aCircleError;
+ bool aShapeValid = aShapeValidator->isValid(aRefAttr, anArguments, aCircleError);
+ // the circle line is not a valid case
+ if (aShapeValid) {
+ theError = "Circle can not be used in distance constraint";
+ return false;
+ }
+
+ anArguments.clear();
+ anArguments.push_back("line");
+ Events_InfoMessage aLineError;
+ aShapeValid = aShapeValidator->isValid(aRefAttr, anArguments, aLineError);
+ // if the attribute value is not a line, that means it is a vertex. A vertex is always valid
+ if (aShapeValid) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ // If it is a line then we have to check that first attribute id not a line
+ std::shared_ptr<SketchPlugin_Feature> aSFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
+ SketchPlugin_Sketch* aSketch = aSFeature->sketch();
+ std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(aSketch);
+ std::shared_ptr<GeomDataAPI_Point2D> aPoint = SketcherPrs_Tools::getFeaturePoint(
+ aFeature->data(), aParamA, aPlane);
+ if (!aPoint.get()) {
+ theError = "One of parameters of distance constraint should be a point";
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+static bool hasCoincidentPoint(FeaturePtr theFeature1, FeaturePtr theFeature2)
+{
+ FeaturePtr aConstrFeature;
+ std::list<AttributePtr> anAttrList;
+ if (theFeature1->getKind() == SketchPlugin_Circle::ID() ||
+ theFeature2->getKind() == SketchPlugin_Circle::ID())
+ return false;
+ if (theFeature2->getKind() == SketchPlugin_Line::ID()) {
+ anAttrList.push_back(theFeature2->attribute(SketchPlugin_Line::START_ID()));
+ anAttrList.push_back(theFeature2->attribute(SketchPlugin_Line::END_ID()));
+ } else if (theFeature2->getKind() == SketchPlugin_Arc::ID()) {
+ anAttrList.push_back(theFeature2->attribute(SketchPlugin_Arc::START_ID()));
+ anAttrList.push_back(theFeature2->attribute(SketchPlugin_Arc::END_ID()));
+ }
+
+ const std::set<AttributePtr>& aRefsList = theFeature1->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRefIt = aRefsList.begin();
+ for (; aRefIt != aRefsList.end(); ++aRefIt) {
+ aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIt)->owner());
+ if (aConstrFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+ continue;
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ AttributePtr anAttr = aRefAttr->attr();
+ if (anAttr->id() == SketchPlugin_Arc::CENTER_ID())
+ continue;
+
+ anAttr = aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
+ if (anAttr == *aRefIt)
+ anAttr = aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
+
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
+ if (!aRefAttr)
+ continue;
+ anAttr = aRefAttr->attr();
+ for (std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
+ anIt != anAttrList.end(); ++anIt)
+ if (*anIt == anAttr)
+ return true;
+ }
+ return false;
+}
+
+bool SketchPlugin_TangentAttrValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) {
+ theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
+ return false;
+ }
+
+ // there is a check whether the feature contains a point and a linear edge or two point values
+ std::string aParamA = theArguments.front();
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+
+ FeaturePtr anAttributeFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+
+ bool isObject = aRefAttr->isObject();
+ ObjectPtr anObject = aRefAttr->object();
+ if (isObject && anObject.get()) {
+ FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
+
+ AttributeRefAttrPtr aOtherAttr = anAttributeFeature->data()->refattr(aParamA);
+ ObjectPtr aOtherObject = aOtherAttr->object();
+ FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
+ if (!aOtherFea)
+ return true;
+
+ if ((aRefFea->getKind() == SketchPlugin_Arc::ID() ||
+ aOtherFea->getKind() == SketchPlugin_Arc::ID()) &&
+ !hasCoincidentPoint(aRefFea, aOtherFea))
+ return false;
+
+ if (aRefFea->getKind() == SketchPlugin_Line::ID()) {
+ if (aOtherFea->getKind() != SketchPlugin_Arc::ID() &&
+ aOtherFea->getKind() != SketchPlugin_Circle::ID()) {
+ theError = "It refers to a " + SketchPlugin_Line::ID() + ", but " + aParamA + " is neither an "
+ + SketchPlugin_Arc::ID() + " nor " + SketchPlugin_Circle::ID();
+ return false;
+ }
+ }
+ else if (aRefFea->getKind() == SketchPlugin_Arc::ID()) {
+ if (aOtherFea->getKind() != SketchPlugin_Line::ID() &&
+ aOtherFea->getKind() != SketchPlugin_Arc::ID()) {
+ theError = "It refers to an " + SketchPlugin_Arc::ID() + ", but " + aParamA + " is not a "
+ + SketchPlugin_Line::ID() + " or an " + SketchPlugin_Arc::ID();
+ return false;
+ }
+ }
+ else if (aRefFea->getKind() == SketchPlugin_Circle::ID()) {
+ if (aOtherFea->getKind() != SketchPlugin_Line::ID()) {
+ theError = "It refers to an " + SketchPlugin_Circle::ID() + ", but " + aParamA + " is not a "
+ + SketchPlugin_Line::ID();
+ return false;
+ }
+ }
+ else {
+ theError = "It refers to " + aRefFea->getKind() + ", but should refer to " + SketchPlugin_Line::ID()
+ + " or " + SketchPlugin_Arc::ID() + " or " + SketchPlugin_Circle::ID();
+ return false;
+ }
+ return true;
+ }
+ else {
+ theError = "It uses an empty object";
+ return false;
+ }
+
+ return true;
+}
+
+bool SketchPlugin_NotFixedValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) {
+ theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
+ return false;
+ }