+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+// LCOV_EXCL_START
+ if (theArguments.size() != 2)
+ {
+ theError = "Wrong number of arguments (expected 2).";
+ return false;
+ }
+// LCOV_EXCL_STOP
+
+ int anObjectsToolsNb[2] = { 0, 0 };
+
+ std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+
+ bool isAllInSameCompSolid = true;
+ ResultBodyPtr aCompSolid;
+
+ for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
+ AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
+ if (anAttrSelList)
+ {
+ *anArgNbIt = anAttrSelList->size();
+ if (isAllInSameCompSolid) {
+ for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
+ {
+ AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+ ResultPtr aContext = anAttr->context();
+ ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
+ if (aResCompSolidPtr.get())
+ {
+ if (aCompSolid.get())
+ {
+ isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+ }
+ else
+ {
+ aCompSolid = aResCompSolidPtr;
+ }
+ }
+ else
+ {
+ isAllInSameCompSolid = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
+ std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
+ FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
+
+ if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
+ {
+ // Fuse operation
+ if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
+ {
+ theError = "Not enough arguments for Fuse operation.";
+ return false;
+ }
+ else if (isAllInSameCompSolid)
+ {
+ theError = "Operations only between sub-shapes of the same shape not allowed.";
+ return false;
+ }
+ }
+ else
+ {
+ if (anObjectsToolsNb[0] < 1) // check number of objects
+ {
+ theError = "Objects not selected.";
+ return false;
+ }
+ if (anObjectsToolsNb[1] < 1) // check number of tools
+ {
+ theError = "Tools not selected.";
+ return false;
+ }
+ if (isAllInSameCompSolid)
+ {
+ theError = "Operations only between sub-shapes of the same shape not allowed.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//=================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
+ std::string theAttribute)
+{
+ if (theAttribute == "main_objects" || theAttribute == "tool_objects")
+ {
+ return true;
+ }
+
+ return false;
+}
+// LCOV_EXCL_STOP
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
+ const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
+ std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
+
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if (!aFeature.get() || !anAttrSelectionList.get()) {
+// LCOV_EXCL_START
+ theError =
+ "Error: Validator used in wrong feature or attribute";
+ return false;
+// LCOV_EXCL_STOP
+ }
+
+ AttributeSelectionListPtr anOtherAttrSelectionList;
+ if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
+ anOtherAttrSelectionList =
+ aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
+ } else {
+ anOtherAttrSelectionList =
+ aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
+ }
+
+ GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
+ GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
+ GeomPlanePtr aFacesPln;
+
+ for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
+
+ if (anAttrSelection->contextFeature().get()) {
+ theError = "Error: Features not allowed for selection.";
+ return false;
+ }
+
+ ResultPtr aContext = anAttrSelection->context();
+ std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+ if (!aShape.get()) {
+ if (!aContext.get()) {
+ theError = "Error: Empty selection.";
+ return false;
+ }
+ aShape = aContext->shape();
+ }
+
+ if (aShape->isSolid() || aShape->isCompSolid()) {
+ aSelectedShapesType = GeomAPI_Shape::SOLID;
+ ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
+ if (aResCompSolidPtr.get()) {
+ GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
+ aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
+ }
+ } else {
+ aSelectedShapesType = GeomAPI_Shape::FACE;
+ GeomAPI_Face aFace(aShape);
+ aFacesPln = aFace.getPlane();
+ break;
+ }
+ }
+
+ for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
+ if (!anAttrSelection.get()) {
+ theError = "Error: Empty attribute selection.";
+ return false;
+ }
+
+ if (anAttrSelection->contextFeature().get()) {
+ theError = "Error: Features not allowed for selection.";
+ return false;
+ }
+
+ ResultPtr aContext = anAttrSelection->context();
+ if(!aContext.get()) {
+ FeaturePtr aContFeat = anAttrSelection->contextFeature();
+ if (!aContFeat.get() || !aContFeat->results().size() ||
+ aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
+ 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;
+ }
+
+ if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
+ // Other list is empty.
+ if (aShape->isSolid() || aShape->isCompSolid()) {
+ aSelectedShapesType = GeomAPI_Shape::SOLID;
+ } else {
+ aSelectedShapesType = GeomAPI_Shape::FACE;
+ GeomAPI_Face aFace(aShape);
+ aFacesPln = aFace.getPlane();
+
+ if (!aFacesPln.get()) {
+ theError = "Error: Only planar faces allowed.";
+ return false;
+ }
+ }
+
+ continue;
+ } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
+ if (!aShape->isSolid() && !aShape->isCompSolid()) {
+ theError = "Error: Selected shapes should have the same type.";
+ return false;
+ }
+ } else {
+ GeomAPI_Face aFace(aShape);
+ GeomPlanePtr aPln = aFace.getPlane();
+
+ if (!aPln.get()) {
+ theError = "Error: Only planar faces allowed.";
+ return false;
+ }
+
+ if (!aFacesPln->isCoincident(aPln)) {
+ theError = "Error: Only coincident faces allowed.";
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+//==================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (!theAttribute.get()) {
+ theError = "Error: empty selection.";
+ return false;
+ }
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ 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()) {
+ FeaturePtr aContFeat = anAttrSelection->contextFeature();
+ if (!aContFeat.get() || !aContFeat->results().size() ||
+ aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
+ theError = "Error: Empty selection context.";
+ return false;
+ }
+ }
+ FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
+ anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
+ if (!aFeature.get()) {
+ theError = "Error: empty feature.";
+ return false;
+ }
+ std::string aFeatureKind = aFeature->getKind();
+ if (aFeatureKind == "Sketch" ||
+ aFeatureKind == "Plane" ||
+ aFeatureKind == "Axis") {
+ theError = "Error: %1 shape is not allowed for selection.";
+ theError.arg(aFeatureKind);
+ return false;
+ }
+ std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+ if (!aShape.get()) {
+ GeomShapePtr aContextShape = aContext->shape();
+ aShape = aContextShape;
+ }
+ if (!aShape.get()) {
+ theError = "Error: empty shape.";
+ return false;
+ }
+ if (aContext.get() && !aShape->isEqual(aContext->shape())) {
+ theError = "Error: Local selection not allowed.";
+ return false;
+ }
+
+ int aShapeType = aShape->shapeType();
+ // 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;
+ }
+ }
+
+ return true;
+}
+// LCOV_EXCL_STOP
+
+//==================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_ValidatorBooleanFuseSelection::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;
+ }
+
+ 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()) {
+ FeaturePtr aContFeat = anAttrSelection->contextFeature();
+ if (!aContFeat.get() || !aContFeat->results().size() ||
+ aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
+ 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();
+ if (!aShape.get()) {
+ GeomShapePtr aContextShape = aContext->shape();
+ aShape = aContextShape;
+ }
+ if (!aShape.get()) {
+ theError = "Error: Empty shape.";
+ return false;
+ }
+ if (aContext.get() && !aShape->isEqual(aContext->shape())) {
+ theError = "Error: Local selection not allowed.";
+ return false;
+ }
+ }
+
+ return true;
+}
+// LCOV_EXCL_STOP
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+// LCOV_EXCL_START
+ if (theArguments.size() != 2) {
+ theError = "Wrong number of arguments (expected 2).";
+ return false;
+ }
+// LCOV_EXCL_STOP
+
+ std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
+ std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
+
+ int anObjectsNb = 0, aToolsNb = 0;
+
+ std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+
+ bool isAllInSameCompSolid = true;
+ ResultBodyPtr aCompSolid;
+
+ AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
+ if (anAttrSelList) {
+ anObjectsNb = anAttrSelList->size();
+ for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
+ AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+ ResultPtr aContext = anAttr->context();
+ ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
+ if (aResCompSolidPtr.get()) {
+ if (aCompSolid.get()) {
+ isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+ } else {
+ aCompSolid = aResCompSolidPtr;
+ }
+ } else {
+ isAllInSameCompSolid = false;
+ break;
+ }
+ }
+ }
+ anIt++;
+
+ if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
+ == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
+ anAttrSelList = theFeature->selectionList(*anIt);
+ if (anAttrSelList) {
+ aToolsNb = anAttrSelList->size();
+ if (isAllInSameCompSolid) {
+ for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
+ AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+ ResultPtr aContext = anAttr->context();
+ ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
+ if (aResCompSolidPtr.get()) {
+ if (aCompSolid.get()) {
+ isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+ } else {
+ aCompSolid = aResCompSolidPtr;
+ }
+ } else {
+ isAllInSameCompSolid = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ anIt++;
+
+ if (anObjectsNb + aToolsNb < 2) {
+ theError = "Not enough arguments for Fuse operation.";
+ return false;
+ } else if (isAllInSameCompSolid) {
+ theError = "Operations only between sub-shapes of the same shape not allowed.";
+ return false;
+ }
+
+ return true;
+}
+
+//=================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
+ std::string theFeature,
+ std::string theAttribute)
+{
+ if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
+ return true;
+ }
+
+ return false;
+}
+// LCOV_EXCL_STOP
+
+//==================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_ValidatorBooleanCommonSelection::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;
+ }
+
+ 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() && !anAttrSelection->contextFeature().get()) {
+ theError = "Error: Empty selection context.";
+ return false;
+ }
+ ResultConstructionPtr aResultConstruction =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
+ if (aResultConstruction.get()) {
+ if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
+ theError = "Error: Result construction not allowed for selection.";
+ return false;
+ }
+ }
+ std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
+ GeomShapePtr aContextShape;
+ if (aContext.get()) {
+ aContextShape = aContext->shape();
+ }
+ if (!aShape.get()) {
+ aShape = aContextShape;
+ }
+ if (!aShape.get()) {
+ theError = "Error: Empty shape.";
+ return false;
+ }
+ if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
+ theError = "Error: Local selection not allowed.";
+ return false;
+ }
+
+ if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
+ theError = "Error: Result construction should be plane.";
+ return false;
+ }
+ }
+
+ return true;
+}
+// LCOV_EXCL_STOP
+
+//=================================================================================================
+bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ if (theArguments.size() != 2) {
+// LCOV_EXCL_START
+ theError = "Wrong number of arguments (expected 2).";
+ return false;
+// LCOV_EXCL_STOP
+ }
+
+ std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
+ std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
+
+ int anObjectsNb = 0, aToolsNb = 0;
+
+ std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+
+ bool isAllInSameCompSolid = true;
+ ResultBodyPtr aCompSolid;
+
+ AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
+ if (anAttrSelList) {
+ anObjectsNb = anAttrSelList->size();
+ }
+
+ bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
+ == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
+
+ if (!isSimpleMode) {
+ anAttrSelList = theFeature->selectionList(*anIt);
+ if (anAttrSelList) {
+ aToolsNb = anAttrSelList->size();
+ }
+ }
+
+ if ((isSimpleMode && anObjectsNb < 2)
+ || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
+ theError = "Not enough arguments for Fuse operation.";
+ return false;
+ }
+ return true;
+}
+
+//=================================================================================================
+// LCOV_EXCL_START
+bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
+ std::string theFeature,
+ std::string theAttribute)
+{
+ return false;
+}
+// LCOV_EXCL_STOP