+bool SketchPlugin_IntersectionValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeSelection::typeId()) {
+ theError = "The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ AttributeSelectionPtr aLineAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ std::shared_ptr<GeomAPI_Edge> anEdge;
+ if(aLineAttr && aLineAttr->value() && aLineAttr->value()->isEdge()) {
+ anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aLineAttr->value()));
+ } else if(aLineAttr->context() &&
+ aLineAttr->context()->shape() && aLineAttr->context()->shape()->isEdge()) {
+ anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aLineAttr->context()->shape()));
+ }
+
+ if (!anEdge || !anEdge->isLine()) {
+ theError = "The attribute %1 should be a line";
+ theError.arg(theAttribute->id());
+ return false;
+ }
+
+ std::shared_ptr<GeomAPI_Dir> aLineDir = anEdge->line()->direction();
+
+ // find a sketch
+ std::shared_ptr<SketchPlugin_Sketch> aSketch;
+ std::set<AttributePtr> aRefs = aLineAttr->owner()->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator anIt = aRefs.begin();
+ for (; anIt != aRefs.end(); ++anIt) {
+ CompositeFeaturePtr aComp =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
+ if (aComp && aComp->getKind() == SketchPlugin_Sketch::ID()) {
+ aSketch = std::dynamic_pointer_cast<SketchPlugin_Sketch>(aComp);
+ break;
+ }
+ }
+ if (!aSketch) {
+ theError = "There is no sketch referring to the current feature";
+ return false;
+ }
+
+ std::shared_ptr<GeomAPI_Pln> aPlane = aSketch->plane();
+ std::shared_ptr<GeomAPI_Dir> aNormal = aPlane->direction();
+ return fabs(aNormal->dot(aLineDir)) > tolerance * tolerance;
+}
+
+bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ bool aValid = false;
+
+ if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
+ theError = "The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return aValid;
+ }
+ AttributeReferencePtr aFeatureAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+
+ ObjectPtr anAttrObject = aFeatureAttr->value();
+ FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttrObject);
+ if (!anAttrFeature)
+ return aValid;
+
+ std::string aKind = anAttrFeature->getKind();
+ if (aKind == SketchPlugin_Line::ID() ||
+ aKind == SketchPlugin_Arc::ID() ||
+ aKind == SketchPlugin_Circle::ID()) {
+
+ std::set<ResultPtr> anEdgeShapes;
+ ModelAPI_Tools::shapesOfType(anAttrFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
+ if (anEdgeShapes.empty() || anEdgeShapes.size() > 1 /*there case has not existed yet*/)
+ return aValid;
+
+ // coincidences to the feature
+ std::set<std::shared_ptr<GeomDataAPI_Point2D> > aRefAttributes;
+ ModelGeomAlgo_Point2D::getPointsOfReference(anAttrFeature,
+ SketchPlugin_ConstraintCoincidence::ID(),
+ aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
+
+ GeomShapePtr anAttrShape = (*anEdgeShapes.begin())->shape();
+ std::shared_ptr<SketchPlugin_Feature> aSFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(anAttrFeature);
+ SketchPlugin_Sketch* aSketch = aSFeature->sketch();
+
+ std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
+ std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+ aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+ std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
+ std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ aData->attribute(SketchPlugin_Sketch::NORM_ID()));
+ std::shared_ptr<GeomAPI_Dir> aDirY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
+
+ typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
+ std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
+ std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
+ PointToRefsMap aPointsInfo;
+
+ ModelGeomAlgo_Point2D::getPointsInsideShape(anAttrShape, aRefAttributes, aC->pnt(),
+ aX->dir(), aDirY, aPointsInfo);
+ int aCoincidentToFeature = (int)aPointsInfo.size();
+ if (aKind == SketchPlugin_Circle::ID())
+ aValid = aCoincidentToFeature >= 2;
+ else
+ aValid = aCoincidentToFeature >= 1;
+ }
+
+ return aValid;
+}
+
+bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeSelection::typeId()) {
+ theError = "The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+
+ AttributeSelectionPtr aFeatureAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ std::shared_ptr<GeomAPI_Edge> anEdge;
+ if (aFeatureAttr.get()) {
+ GeomShapePtr aVal = aFeatureAttr->value();
+ ResultPtr aRes = aFeatureAttr->context();
+ if(aFeatureAttr->value() && aFeatureAttr->value()->isEdge()) {
+ anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aFeatureAttr->value()));
+ } else if(aFeatureAttr->context() && aFeatureAttr->context()->shape() &&
+ aFeatureAttr->context()->shape()->isEdge()) {
+ anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(aFeatureAttr->context()->shape()));
+ }
+ }
+ if (!anEdge) {
+ theError = "The attribute %1 should be an edge";
+ theError.arg(theAttribute->id());
+ return false;
+ }
+
+ // find a sketch
+ std::shared_ptr<SketchPlugin_Sketch> aSketch;
+ std::set<AttributePtr> aRefs = theAttribute->owner()->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator anIt = aRefs.begin();
+ for (; anIt != aRefs.end(); ++anIt) {
+ CompositeFeaturePtr aComp =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
+ if (aComp && aComp->getKind() == SketchPlugin_Sketch::ID()) {
+ aSketch = std::dynamic_pointer_cast<SketchPlugin_Sketch>(aComp);
+ break;
+ }
+ }
+ if (!aSketch) {
+ theError = "There is no sketch referring to the current feature";
+ return false;
+ }
+
+ std::shared_ptr<GeomAPI_Pln> aPlane = aSketch->plane();
+ std::shared_ptr<GeomAPI_Dir> aNormal = aPlane->direction();
+ std::shared_ptr<GeomAPI_Pnt> anOrigin = aPlane->location();
+
+ if (anEdge->isLine()) {
+ std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
+ std::shared_ptr<GeomAPI_Dir> aLineDir = aLine->direction();
+ std::shared_ptr<GeomAPI_Pnt> aLineLoc = aLine->location();
+ double aDot = aNormal->dot(aLineDir);
+ double aDist = aLineLoc->xyz()->decreased(anOrigin->xyz())->dot(aNormal->xyz());
+ bool aValid = (fabs(aDot) >= tolerance && fabs(aDot) < 1.0 - tolerance) ||
+ (fabs(aDot) < tolerance && fabs(aDist) > tolerance);
+ if (!aValid)
+ theError = "Error: Edge is already in the sketch plane.";
+ return aValid;
+ }
+ else if (anEdge->isCircle() || anEdge->isArc()) {
+ std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
+ std::shared_ptr<GeomAPI_Dir> aCircNormal = aCircle->normal();
+ std::shared_ptr<GeomAPI_Pnt> aCircCenter = aCircle->center();
+ double aDot = fabs(aNormal->dot(aCircNormal));
+ double aDist = aCircCenter->xyz()->decreased(anOrigin->xyz())->dot(aNormal->xyz());
+ bool aValid = fabs(aDot - 1.0) < tolerance * tolerance && fabs(aDist) > tolerance;
+ if (!aValid)
+ theError.arg(anEdge->isCircle() ? "Error: Cirlce is already in the sketch plane."
+ : "Error: Arc is already in the sketch plane.");
+ return aValid;
+ }
+
+ theError = "Error: Selected object is not line, circle or arc.";
+ return false;
+}