X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Validators.cpp;h=aa78551d6b665e30f0dcf7a03d678694efa7bb1a;hb=84ff9a5e90ebf75292b9ef97a05a4609e67c4022;hp=acc2b8becfa8d36a29a2f60c8d31a902f08b70c5;hpb=7074394f8f08413d885f63be01df6bd5007b868c;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index acc2b8bec..aa78551d6 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -20,6 +20,11 @@ #include "FeaturesPlugin_Validators.h" +#include "FeaturesPlugin_Boolean.h" +#include "FeaturesPlugin_BooleanFuse.h" +#include "FeaturesPlugin_BooleanCommon.h" +#include "FeaturesPlugin_BooleanSmash.h" +#include "FeaturesPlugin_Pipe.h" #include "FeaturesPlugin_Union.h" #include @@ -31,17 +36,19 @@ #include #include #include -#include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -82,7 +89,79 @@ bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, } //================================================================================================== -bool FeaturesPlugin_ValidatorPipeLocations::isValid( +bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if(!anAttrSelectionList.get()) { + theError = + "Error: This validator can only work with selection list attributes in \"Pipe\" feature."; + return false; + } + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theAttribute->owner()); + + AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID()); + if (!aPathSelection.get()) { + theError = "Error: Path not selected."; + return false; + } + + GeomShapePtr aPathShape = aPathSelection->value(); + if (!aPathShape.get()) { + ResultPtr aContext = aPathSelection->context(); + if (!aContext.get()) { + FeaturePtr aContFeat = aPathSelection->contextFeature(); + if (!aContFeat.get() || !aContFeat->results().size()) { + theError = "Error: Empty selection context."; + return false; + } + } + aPathShape = aContext->shape(); + } + + if (!aPathShape.get()) { + theError = "Error: Empty path shape."; + 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()) { + theError = "Error: Empty selection context."; + return false; + } + } + std::shared_ptr aShape = anAttrSelection->value(); + if (!aShape.get() && aContext.get()) { + GeomShapePtr aContextShape = aContext->shape(); + aShape = aContextShape; + } + if (!aShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + if (!aPathShape->isSubShape(aShape)) { + theError = "Error: Location should be a vertex subshape from path shape."; + return false; + } + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid( const std::shared_ptr& theFeature, const std::list& theArguments, Events_InfoMessage& theError) const @@ -131,13 +210,6 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid( return true; } -//================================================================================================== -bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, - std::string theAttribute) -{ - return false; -} - //================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -164,7 +236,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex); ResultPtr aContext = aSelectionAttr->context(); - if(!aContext.get()) { + if(!aContext.get() && !aSelectionAttr->contextFeature().get()) { theError = "Error: Empty context."; return false; } @@ -176,7 +248,12 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA // If shape is compound check that it contains only faces and edges. GeomShapePtr aShape = aSelectionAttr->value(); if(!aShape.get()) { - aShape = aContext->shape(); + if (aContext.get()) { + aShape = aContext->shape(); + } else { + theError = "Error: Empty context."; + return false; + } } if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) { @@ -244,8 +321,13 @@ bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid( AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex); ResultPtr aContext = aSelectionAttr->context(); if(!aContext.get()) { - theError = "Error: Empty context."; - return false; + FeaturePtr aFeature = aSelectionAttr->contextFeature(); + if (!aFeature.get() || aFeature->results().empty()) { + theError = "Error: Empty context."; + return false; + } else { + aContext = aFeature->firstResult(); + } } ResultConstructionPtr aResultConstruction = @@ -281,14 +363,6 @@ bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid( return true; } -//================================================================================================== -bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isNotObligatory( - std::string theFeature, - std::string theAttribute) -{ - return false; -} - //================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute, const std::list& theArguments, @@ -314,14 +388,15 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); ResultPtr aContext = anAttr->context(); - if(!aContext.get()) { + if(!aContext.get() && !anAttr->contextFeature().get()) { theError = "Error: Attribute have empty context."; return false; } GeomShapePtr aShape = anAttr->value(); - GeomShapePtr aContextShape = aContext->shape(); - if(!aShape.get()) { + GeomShapePtr aContextShape; + if(!aShape.get() && aContext.get()) { + aContextShape = aContext->shape(); aShape = aContextShape; } if(!aShape.get()) { @@ -329,8 +404,12 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute return false; } - ResultConstructionPtr aConstruction = - std::dynamic_pointer_cast(aContext); + ResultConstructionPtr aConstruction; + if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) { + aContext = anAttr->contextFeature()->firstResult(); + } + if (aContext.get()) + aConstruction = std::dynamic_pointer_cast(aContext); if(aConstruction.get()) { // Construciotn selected. Check that is is not infinite. if(aConstruction->isInfinite()) { @@ -338,6 +417,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute return false; } + GeomShapePtr aContextShape = aContext->shape(); if(aShape->isEqual(aContextShape)) { // Whole construction selected. Check that it have faces. if(aConstruction->facesNum() > 0) { @@ -354,7 +434,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute return false; } - if(!aShape->isEqual(aContextShape)) { + if(aContextShape.get() && !aShape->isEqual(aContextShape)) { // Local selection on body does not allowed. theError = "Error: Selected shape is in the local selection. Only global selection is allowed."; @@ -457,6 +537,13 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( aDirShape = aSelAttr->value(); if(!aDirShape.get()) { ResultPtr aContext = aSelAttr->context(); + if(!aContext.get()) { + FeaturePtr aFeature = aSelAttr->contextFeature(); + if (aFeature.get() && !aFeature->results().empty()) { + aContext = aFeature->firstResult(); + } + } + if(aContext.get()) { aDirShape = aContext->shape(); } @@ -524,13 +611,6 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( 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 @@ -554,13 +634,13 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); ResultPtr aContext = anAttr->context(); - if(!aContext.get()) { + if(!aContext.get() && !anAttr->contextFeature().get()) { return false; } GeomShapePtr aShape = anAttr->value(); - GeomShapePtr aContextShape = aContext->shape(); - if(!aShape.get()) { + if(!aShape.get() && aContext.get()) { + GeomShapePtr aContextShape = aContext->shape(); aShape = aContextShape; } if(!aShape.get()) { @@ -591,8 +671,9 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt "Error: This validator can only work with selection list attributes in \"Boolean\" feature."; return false; } - FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); - int anOperationType = aFeature->integer("bool_type")->value(); + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theAttribute->owner()); + FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType(); for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex); @@ -602,48 +683,129 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt } ResultPtr aContext = anAttrSelection->context(); if(!aContext.get()) { - theError = "Error: Empty selection context."; - return false; + FeaturePtr aContFeat = anAttrSelection->contextFeature(); + if (!aContFeat.get() || !aContFeat->results().size()) { + theError = "Error: Empty selection context."; + return false; + } } ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast(aContext); if(aResultConstruction.get()) { - theError = "Error: Result construction not allowed for selection."; - return false; + if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL + || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } } std::shared_ptr aShape = anAttrSelection->value(); - GeomShapePtr aContextShape = aContext->shape(); - if(!aShape.get()) { + if(!aShape.get() && aContext.get()) { + GeomShapePtr aContextShape = aContext->shape(); aShape = aContextShape; } if(!aShape.get()) { theError = "Error: Empty shape."; return false; } - if(!aShape->isEqual(aContextShape)) { + if (aContext.get() && !aShape->isEqual(aContext->shape())) { 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."; + GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType(); + std::set anAllowedTypes; + if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) { + anAllowedTypes.insert(GeomAPI_Shape::EDGE); + anAllowedTypes.insert(GeomAPI_Shape::FACE); + anAllowedTypes.insert(GeomAPI_Shape::SOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPOUND); + } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL + || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT) + { + anAllowedTypes.insert(GeomAPI_Shape::VERTEX); + anAllowedTypes.insert(GeomAPI_Shape::EDGE); + anAllowedTypes.insert(GeomAPI_Shape::WIRE); + anAllowedTypes.insert(GeomAPI_Shape::FACE); + anAllowedTypes.insert(GeomAPI_Shape::SHELL); + anAllowedTypes.insert(GeomAPI_Shape::SOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPOUND); + } else { + anAllowedTypes.insert(GeomAPI_Shape::SOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID); + anAllowedTypes.insert(GeomAPI_Shape::COMPOUND); + } + + if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end() + || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) { + theError = "Error: Selected shape has the wrong type."; + return false; + } + + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if(!anAttrSelectionList.get()) { + theError = + "Error: This validator can only work with selection list attributes in \"Fillet\" feature."; + return false; + } + + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + // Check all selected entities are sub-shapes of single solid + GeomShapePtr aBaseSolid; + 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; } - } else { - if(aShapeType != GeomAPI_Shape::SOLID && - aShapeType != GeomAPI_Shape::COMPSOLID && - aShapeType != GeomAPI_Shape::COMPOUND) { - theError = "Error: Selected shape has the wrong type."; + if (aContFeat->results().size() == 1) + aContext = aContFeat->firstResult(); + else { + theError = "Error: Too many shapes selected."; return false; } } + + ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext); + GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape(); + + if (!anOwner) { + theError = "Error: wrong feature is selected."; + return false; + } + + if (anOwner->shapeType() != GeomAPI_Shape::SOLID && + anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) { + theError = "Error: Not all selected shapes are sub-shapes of solids."; + return false; + } + + if (!aBaseSolid) + aBaseSolid = anOwner; + else if (!aBaseSolid->isEqual(anOwner)) { + theError = "Error: Sub-shapes of different solids have been selected."; + return false; + } } return true; @@ -682,11 +844,22 @@ bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& the return false; } - ResultCompSolidPtr aResultCompsolid = - std::dynamic_pointer_cast(aContext); - if(aResultCompsolid.get()) { + ResultBodyPtr aResultBody = std::dynamic_pointer_cast(aContext); + if(aResultBody.get()) { continue; } + FeaturePtr aResultFeature = aSelectAttr->contextFeature(); + if(aResultFeature.get()) { + bool aOkRes = false; + std::list::const_iterator aFRes = aResultFeature->results().cbegin(); + for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) { + ResultBodyPtr aBody = std::dynamic_pointer_cast(*aFRes); + if (aBody.get() && !aBody->isDisabled()) + aOkRes = true; + } + if (aOkRes) + continue; + } theError = "Error: Only body shapes and construction planes are allowed for selection."; return false; @@ -733,17 +906,19 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePt return false; } + std::list aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape); for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) { bool isSameFound = false; AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex); GeomShapePtr aShapeToAdd = anAttrSelectionInList->value(); - for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { - if(anIt.current()->isEqual(aShapeToAdd)) { + for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt) + { + if ((*anIt)->isEqual(aShapeToAdd)) { isSameFound = true; break; } } - if(!isSameFound) { + if (!isSameFound) { theError = "Error: Only sub-shapes of selected shape is allowed for selection."; return false; } @@ -759,7 +934,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( Events_InfoMessage& theError) const { static const std::string aBaseShapeID = "base_shape"; - static const std::string aSubShapesID = "subshapes"; + static const std::string aSubShapesID = "subshapes_to_keep"; if(theFeature->getKind() != "Remove_SubShapes") { theError = "Error: Feature \"%1\" does not supported by this validator."; @@ -789,6 +964,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( } GeomShapePtr aResultShape = aBaseShape->emptyCopied(); + if (aSubShapesAttrList->size() == 0) { + theError = "Error: Resulting shape is not valid."; + return false; + } + // Copy sub-shapes from list to new shape. for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) { AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex); @@ -805,13 +985,6 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( return true; } -//================================================================================================== -bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature, - std::string theAttribute) -{ - return false; -} - //================================================================================================== bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -828,11 +1001,32 @@ bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttr for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) { bool isSameFound = false; AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex); - ResultCompSolidPtr aResult = - std::dynamic_pointer_cast(anAttrSelectionInList->context()); + ResultPtr aContext = anAttrSelectionInList->context(); + if (!aContext.get()) { + theError = "Error: selection is invalid."; + return false; + } + + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aContext); + if(aConstruction.get()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } + + GeomShapePtr aShape = anAttrSelectionInList->value(); + GeomShapePtr aContextShape = aContext->shape(); + if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) { + theError = "Error: Local selection not allowed."; + return false; + } + + ResultBodyPtr aResult = + std::dynamic_pointer_cast(aContext); if(!aResult.get()) { continue; } + if(aResult->numberOfSubs() > 0) { theError = "Error: Whole compsolids not allowed for selection."; return false; @@ -865,17 +1059,27 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid( } // Get all shapes. + GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID; ListOfShape aBaseShapesList; for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) { AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex); GeomShapePtr aShape = anAttrSelectionInList->value(); + if (!aShape.get()) { + continue; + } aBaseShapesList.push_back(aShape); + aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL : + GeomAPI_Shape::COMPSOLID; } - // Make componud and find connected. + // Make compound and find connected. GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList); ListOfShape aCombined, aFree; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree); + GeomAlgoAPI_ShapeTools::combineShapes( + aCompound, + aType, + aCombined, + aFree); if(aFree.size() > 0 || aCombined.size() > 1) { theError = "Error: Not all shapes have shared topology."; @@ -885,13 +1089,6 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid( return true; } -//================================================================================================== -bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature, - std::string theAttribute) -{ - return false; -} - bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const @@ -936,3 +1133,630 @@ bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAtt return theError.empty(); } + +bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + static std::list aEdgeArg(1, "circle"); + static std::list aFaceArg(1, "cylinder"); + + Events_InfoMessage aError; + bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError); + if (!isValid) { + isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError); + if (!isValid) + theError = "The shape neither circle nor cylinder"; + } + return isValid; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanArguments::isValid( + const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (theArguments.size() != 2) + { + theError = "Wrong number of arguments (expected 2)."; + return false; + } + + int anObjectsNb = 0, aToolsNb = 0; + //int anOperationType = 0; + + std::list::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++; + + + 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++; + + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theFeature); + FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType(); + + if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) + { + // Fuse operation + 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; + } + } + else + { + if (anObjectsNb < 1) + { + theError = "Objects not selected."; + return false; + } + if (aToolsNb < 1) + { + theError = "Tools not selected."; + return false; + } + if (isAllInSameCompSolid) + { + theError = "Operations only between sub-shapes of the same shape not allowed."; + return false; + } + } + + return true; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature, + std::string theAttribute) +{ + if (theAttribute == "main_objects" || theAttribute == "tool_objects") + { + return true; + } + + return false; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theAttribute->owner()); + + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if (!aFeature.get() || !anAttrSelectionList.get()) { + theError = + "Error: Validator used in wrong feature or attribute"; + return false; + } + + 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 aShape = anAttrSelection->value(); + GeomShapePtr aContextShape = aContext->shape(); + if (!aShape.get()) { + aShape = aContextShape; + } + + 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(aContext); + if (aResultConstruction.get()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } + std::shared_ptr 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; + } + + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); + if (aResCompSolidPtr.get()) { + GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape(); + if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) { + theError = "Error: Solids from compsolid in other list not allowed."; + 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; +} + +//================================================================================================== +bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (!theAttribute.get()) { + theError = "Error: empty selection."; + return false; + } + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(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 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; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(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(aContext); + if (aResultConstruction.get()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } + std::shared_ptr 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; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid( + const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (theArguments.size() != 2) { + theError = "Wrong number of arguments (expected 2)."; + return false; + } + + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theFeature); + + int anObjectsNb = 0, aToolsNb = 0; + + std::list::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; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory( + std::string theFeature, + std::string theAttribute) +{ + if (theAttribute == "main_objects" || theAttribute == "tool_objects") { + return true; + } + + return false; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(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(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 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; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid( + const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (theArguments.size() != 2) { + theError = "Wrong number of arguments (expected 2)."; + return false; + } + + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theFeature); + + int anObjectsNb = 0, aToolsNb = 0; + + std::list::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; +} + +//================================================================================================= +bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory( + std::string theFeature, + std::string theAttribute) +{ + return false; +}