#include "SketchPlugin_Validators.h"
#include "SketchPlugin_Arc.h"
+#include "SketchPlugin_BSpline.h"
+#include "SketchPlugin_BSplinePeriodic.h"
#include "SketchPlugin_Circle.h"
#include "SketchPlugin_ConstraintCoincidence.h"
+#include "SketchPlugin_ConstraintCoincidenceInternal.h"
#include "SketchPlugin_ConstraintDistance.h"
#include "SketchPlugin_ConstraintRigid.h"
#include "SketchPlugin_ConstraintTangent.h"
#include "SketchPlugin_Ellipse.h"
#include "SketchPlugin_EllipticArc.h"
#include "SketchPlugin_Fillet.h"
+#include "SketchPlugin_CurveFitting.h"
#include "SketchPlugin_Line.h"
#include "SketchPlugin_MacroArc.h"
#include "SketchPlugin_MacroCircle.h"
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefAttrList.h>
#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeString.h>
const double tolerance = 1.e-7;
+static bool isSpline(FeaturePtr theFeature)
+{
+ return theFeature && (theFeature->getKind() == SketchPlugin_BSpline::ID() ||
+ theFeature->getKind() == SketchPlugin_BSplinePeriodic::ID());
+}
+
+
bool SketchPlugin_DistanceAttrValidator::isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
bool isObject = aRefAttr->isObject();
ObjectPtr anObject = aRefAttr->object();
- if (isObject && anObject.get()) {
- FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
+ if (!isObject || !anObject.get()) {
+ theError = "It uses an empty object";
+ return false;
+ }
- AttributeRefAttrPtr aOtherAttr = anAttributeFeature->data()->refattr(aParamA);
- ObjectPtr aOtherObject = aOtherAttr->object();
- FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
- if (!aOtherFea)
- return true;
+ FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
- if (aRefFea->getKind() == SketchPlugin_Line::ID() &&
- aOtherFea->getKind() == SketchPlugin_Line::ID()) {
- theError = "Two segments cannot be tangent";
- return false;
- }
+ AttributeRefAttrPtr aOtherAttr = anAttributeFeature->data()->refattr(aParamA);
+ ObjectPtr aOtherObject = aOtherAttr->object();
+ FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
+ if (!aOtherFea)
return true;
+
+ if (aRefFea->getKind() == SketchPlugin_Line::ID() &&
+ aOtherFea->getKind() == SketchPlugin_Line::ID()) {
+ theError = "Two segments cannot be tangent";
+ return false;
}
- else {
- theError = "It uses an empty object";
+ else if (isSpline(aRefFea) && isSpline(aOtherFea)) {
+ theError = "Two B-splines cannot be tangent";
return false;
}
- return true;
+ bool isValid = true;
+ bool hasSpline = isSpline(aRefFea);
+ if (!hasSpline && isSpline(aOtherFea)) {
+ hasSpline = true;
+ std::swap(aRefFea, aOtherFea);
+ }
+ if (hasSpline) {
+ auto isApplicableCoincidence = [](FeaturePtr theFeature, const std::string& theAttrName) {
+ AttributeRefAttrPtr aRefAttr = theFeature->refattr(theAttrName);
+ if (aRefAttr->isObject())
+ return false;
+ AttributePtr anAttr = aRefAttr->attr();
+ FeaturePtr anOwner = ModelAPI_Feature::feature(anAttr->owner());
+ AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
+ if (aPointAttr) {
+ return anOwner->getKind() == SketchPlugin_BSpline::ID() &&
+ (aPointAttr->id() == SketchPlugin_BSpline::START_ID() ||
+ aPointAttr->id() == SketchPlugin_BSpline::END_ID());
+ }
+
+ AttributePoint2DArrayPtr aPntArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(anAttr);
+ if (aPntArray && anOwner->getKind() == SketchPlugin_BSpline::ID()) {
+ // check index of the pole
+ AttributeIntegerPtr anIndex = theAttrName == SketchPlugin_Constraint::ENTITY_A() ?
+ theFeature->integer(SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_A()) :
+ theFeature->integer(SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_B());
+ return anIndex && (anIndex->value() == 0 || anIndex->value() == aPntArray->size() - 1);
+ }
+ return false;
+ };
+
+ isValid = false;
+ AttributePoint2DArrayPtr aBSplinePoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
+ aRefFea->attribute(SketchPlugin_BSplineBase::POLES_ID()));
+ // additional check the B-spline edge and the other edge have a coincident boundary point
+ std::set<FeaturePtr> aCoincidences = SketchPlugin_Tools::findCoincidentConstraints(aRefFea);
+ for (std::set<FeaturePtr>::iterator anIt = aCoincidences.begin();
+ anIt != aCoincidences.end() && !isValid; ++anIt) {
+ std::set<FeaturePtr> aCoinc;
+ if (isApplicableCoincidence(*anIt, SketchPlugin_Constraint::ENTITY_A()))
+ SketchPlugin_Tools::findCoincidences(*anIt, SketchPlugin_Constraint::ENTITY_B(),
+ aCoinc, true);
+ else if (isApplicableCoincidence(*anIt, SketchPlugin_Constraint::ENTITY_B()))
+ SketchPlugin_Tools::findCoincidences(*anIt, SketchPlugin_Constraint::ENTITY_A(),
+ aCoinc, true);
+
+ isValid = aCoinc.find(aOtherFea) != aCoinc.end();
+ }
+ }
+
+ return isValid;
}
bool SketchPlugin_PerpendicularAttrValidator::isValid(const AttributePtr& theAttribute,
AttributeRefAttrPtr aOtherAttr = anOwner->refattr(aParamA);
ObjectPtr aOtherObject = aOtherAttr->object();
FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
- if (!aOtherFea)
- return true;
// at least one feature should be a line
if (aRefFea->getKind() != SketchPlugin_Line::ID() &&
- aOtherFea->getKind() != SketchPlugin_Line::ID()) {
+ aOtherFea && aOtherFea->getKind() != SketchPlugin_Line::ID()) {
theError = "At least one feature should be a line";
return false;
}
+ else if (isSpline(aRefFea) || isSpline(aOtherFea)) {
+ theError = "B-spline is not supported";
+ return false;
+ }
}
else {
theError = "It uses an empty object";
std::string aType[2];
std::list<std::string> anArguments;
for (int i = 0; i < 2; i++) {
- ObjectPtr anObject = aRefAttr[i]->object();
- if (!anObject.get()) {
- theError = "An empty object is used.";
- return false;
- }
-
- aFeature = ModelAPI_Feature::feature(anObject);
- if (!aFeature.get()) {
- theError = "An empty feature is used.";
- return false;
- }
+ aFeature = ModelAPI_Feature::feature(aRefAttr[i]->object());
+ if (!aFeature.get())
+ return true;
aType[i] = aFeature->getKind();
if (aFeature->getKind() != SketchPlugin_Line::ID() &&
for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
ObjectPtr aSelObject = aSelAttr->object(anInd);
+
+ // B-splines are not supported in Mirror yet
+ FeaturePtr aSelFeature = ModelAPI_Feature::feature(aSelObject);
+ if (aSelFeature && (aSelFeature->getKind() == SketchPlugin_BSpline::ID() ||
+ aSelFeature->getKind() == SketchPlugin_BSplinePeriodic::ID())) {
+ theError = "Not supported";
+ return false;
+ }
+
std::string aName = aSelObject.get() ? aSelObject->data()->name() : "";
std::list<ObjectPtr>::iterator aMirIter = aMirroredObjects.begin();
for (; aMirIter != aMirroredObjects.end(); aMirIter++)
break;
if (anObjIter != anInitialObjects.end())
continue;
+
+ // B-splines are not supported in Copying features
+ FeaturePtr aSelFeature = ModelAPI_Feature::feature(aSelObject);
+ if (aSelFeature && (aSelFeature->getKind() == SketchPlugin_BSpline::ID() ||
+ aSelFeature->getKind() == SketchPlugin_BSplinePeriodic::ID())) {
+ theError = "Not supported";
+ return false;
+ }
+
anObjIter = aCopiedObjects.begin();
for (; anObjIter != aCopiedObjects.end(); anObjIter++)
if (aSelObject == *anObjIter) {
if (!anAttrFeature)
return aValid;
+ // B-splines are not supported by the Split yet
+ if (anAttrFeature->getKind() == SketchPlugin_BSpline::ID() ||
+ anAttrFeature->getKind() == SketchPlugin_BSplinePeriodic::ID()) {
+ theError = "Not supported";
+ return false;
+ }
+
std::set<ResultPtr> anEdgeShapes;
ModelGeomAlgo_Shape::shapesOfType(anAttrFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
if (anEdgeShapes.empty() || anEdgeShapes.size() > 1 /*there case has not existed yet*/)
GeomShapePtr anAttrShape = (*anEdgeShapes.begin())->shape();
std::shared_ptr<SketchPlugin_Feature> aSFeature =
std::dynamic_pointer_cast<SketchPlugin_Feature>(anAttrFeature);
- if (!aSFeature)
+ if (!aSFeature || aSFeature->isCopy())
return false;
SketchPlugin_Sketch* aSketch = aSFeature->sketch();
if (!aSketchFeature.get() || aSketchFeature->isCopy())
return aValid;
+ // B-splines are not supported by the Trim yet
+ if (aBaseFeature->getKind() == SketchPlugin_BSpline::ID() ||
+ aBaseFeature->getKind() == SketchPlugin_BSplinePeriodic::ID()) {
+ theError = "Not supported";
+ return false;
+ }
+
// point on feature
AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
aTrimFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
{
- if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) {
+ if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId() &&
+ theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
theError = "The attribute with the %1 type is not processed";
theError.arg(theAttribute->attributeType());
return false;
}
// check the attribute refers to a sketch feature
+ bool isSketchFeature = false;
AttributeRefAttrPtr aRefAttr =
std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
- bool isSketchFeature = aRefAttr->isObject();
- if (isSketchFeature) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
- isSketchFeature = aFeature.get() != NULL;
+ if (aRefAttr) {
+ isSketchFeature = aRefAttr->isObject();
if (isSketchFeature) {
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- isSketchFeature = aSketchFeature.get() != NULL;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ isSketchFeature = aFeature.get() != NULL;
+ if (isSketchFeature) {
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ isSketchFeature = aSketchFeature.get() != NULL;
+ }
+ }
+ }
+ else {
+ AttributeReferencePtr aReference =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+ if (aReference) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aReference->value());
+ isSketchFeature = aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID();
}
}
- if (isSketchFeature)
- return true;
-
- theError = "The object selected is not a sketch feature";
- return false;
+ if (!isSketchFeature)
+ theError = "The object selected is not a sketch feature";
+ return isSketchFeature;
}
bool SketchPlugin_MultiRotationAngleValidator::isValid(const AttributePtr& theAttribute,
return false;
if (aPolesArray->size() < 2) {
- theError = "Number of B-spline poles should be 2 and more";
+ theError = "Number of B-spline poles should be 2 or more";
return false;
}
return true;
}
+
+bool SketchPlugin_CurveFittingValidator::isValid(const FeaturePtr& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeRefAttrListPtr aRefAttrList =
+ theFeature->refattrlist(SketchPlugin_CurveFitting::POINTS_ID());
+ AttributeBooleanPtr aPeriodicAttr =
+ theFeature->boolean(SketchPlugin_CurveFitting::PERIODIC_ID());
+
+ // check number of selected entities
+ int aMinNbPoints = aPeriodicAttr->value() ? 3 : 2;
+ if (aRefAttrList->size() < aMinNbPoints) {
+ theError = "Not enough points selected. Need at least %1 points.";
+ theError.arg(aMinNbPoints);
+ return false;
+ }
+ return true;
+}