+ theError = "Error: Attribute \"%1\" does not supported by this validator.";
+ theError.arg(anAttributeType);
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
+ theError = "Error: The attribute with the %1 type is not processed";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ if (theArguments.size() != 2) {
+ theError = "Error: Wrong parameters in XML definition for %1 type";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ // first argument is for the base attribute, second - for skipping feature kind
+ std::list<std::string>::const_iterator anIt = theArguments.begin();
+ std::string aBaseAttributeId = *anIt;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+ AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
+ if (!aBaseAttribute.get()) {
+ theError = "Wrong parameters in XML definition for %1 type";
+ theError.arg(theAttribute->attributeType());
+ return false;
+ }
+ if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
+ // this validator is not necessary anymore
+ return true;
+
+ anIt++;
+ std::string aFeatureAttributeKind = *anIt;
+ GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
+ // check whether the selection is on the sketch
+ std::list<std::string> anArguments;
+ anArguments.push_back(aFeatureAttributeKind);
+
+ bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
+ bool aPlanarFace = false;
+ // check if selection has Face selected
+ GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
+ anArguments.clear();
+ anArguments.push_back("face");
+ aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
+
+ bool aValid = !aFeatureKind && aPlanarFace;
+ return aValid;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if(theArguments.size() != 2) {
+ theError = "Error: Validator should be used with 2 parameters for extrusion.";
+ return false;
+ }
+
+ std::list<std::string>::const_iterator
+ anArgsIt = theArguments.begin(), aLast = theArguments.end();
+
+ AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
+ ++anArgsIt;
+
+ GeomShapePtr aDirShape;
+ AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
+ if(aSelAttr.get()) {
+ aDirShape = aSelAttr->value();
+ if(!aDirShape.get()) {
+ ResultPtr aContext = aSelAttr->context();
+ if(aContext.get()) {
+ aDirShape = aContext->shape();
+ }
+ }
+ }
+
+ if(!aDirShape.get()) {
+ // Check that dir can be empty.
+ if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
+ theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
+ "can not be used with default value. Select direction for extrusion.";
+ theError.arg(*anArgsIt);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
+
+ // If faces selected check that direction not parallel with them.
+ AttributeSelectionListPtr aListAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
+ GeomShapePtr aShapeInList = anAttr->value();
+ if(!aShapeInList.get()) {
+ aShapeInList = anAttr->context()->shape();
+ }
+ bool isParallel = true;
+ if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
+ aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
+ for(GeomAPI_ShapeExplorer
+ anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
+ isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
+ if(isParallel) {
+ break;
+ }
+ }
+ } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
+ std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
+ std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
+ if(aPlanarEdges.get()) {
+ std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
+ if(aDirEdge->isLine()) {
+ std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
+ isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
+ } else {
+ isParallel = false;
+ }
+ } else {
+ isParallel = false;
+ }
+ } else {
+ isParallel = false;
+ }
+ if(isParallel) {
+ theError =
+ "Error: Direction is parallel to one of the selected face or face on selected shell.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
+ std::string theAttribute)
+{
+ return false;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
+ Events_InfoMessage& theError) const
+{
+ if(!theAttribute.get()) {
+ return true;
+ }
+
+ std::string anAttributeType = theAttribute->attributeType();
+ if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aListAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
+ // If at least one attribute is invalid, the result is false.
+ if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
+ return false;
+ }
+ }
+ } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
+ // Getting context.
+ AttributeSelectionPtr anAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ ResultPtr aContext = anAttr->context();
+ if(!aContext.get()) {
+ return false;
+ }
+
+ GeomShapePtr aShape = anAttr->value();
+ GeomShapePtr aContextShape = aContext->shape();
+ if(!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if(!aShape.get()) {
+ return false;
+ }
+
+ if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
+ aShape->shapeType() == GeomAPI_Shape::EDGE ||
+ !aShape->isPlanar()) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!anAttrSelectionList.get()) {
+ theError =
+ "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
+ return false;
+ }
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ int anOperationType = aFeature->integer("bool_type")->value();
+
+ for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+ if(!anAttrSelection.get()) {
+ theError = "Error: Empty attribute selection.";
+ return false;
+ }
+ ResultPtr aContext = anAttrSelection->context();
+ if(!aContext.get()) {
+ theError = "Error: Empty selection context.";
+ return false;
+ }
+ ResultConstructionPtr aResultConstruction =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if(aResultConstruction.get()) {
+ theError = "Error: Result construction not allowed for selection.";
+ return false;
+ }
+ std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+ GeomShapePtr aContextShape = aContext->shape();
+ if(!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if(!aShape.get()) {
+ theError = "Error: Empty shape.";
+ return false;
+ }
+ if(!aShape->isEqual(aContextShape)) {
+ theError = "Error: Local selection not allowed.";
+ return false;
+ }
+
+ int aShapeType = aShape->shapeType();
+ if(anOperationType == 1) {
+ // Fuse operation. Allow to select edges, faces and solids.
+ if(aShapeType != GeomAPI_Shape::EDGE &&
+ aShapeType != GeomAPI_Shape::FACE &&
+ aShapeType != GeomAPI_Shape::SOLID &&
+ aShapeType != GeomAPI_Shape::COMPSOLID &&
+ aShapeType != GeomAPI_Shape::COMPOUND) {
+ theError = "Error: Selected shape has the wrong type.";
+ return false;
+ }
+ } else {
+ if(aShapeType != GeomAPI_Shape::SOLID &&
+ aShapeType != GeomAPI_Shape::COMPSOLID &&
+ aShapeType != GeomAPI_Shape::COMPOUND) {
+ theError = "Error: Selected shape has the wrong type.";
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if(!anAttrSelectionList.get()) {
+ theError = "Error: This validator can only work with selection list in \"Partition\" feature.";