X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Validators.cpp;h=c77f516b64c14c8b09fe732d2efa850e360139ec;hb=919584a7e5ee83c384873c2627b9865e8ba02272;hp=1aee44fa68788d46be42a28fcb2167656b53af4f;hpb=78205c43afb89dee242a940236c22000df5af987;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 1aee44fa6..c77f516b6 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -6,46 +6,82 @@ #include "FeaturesPlugin_Validators.h" +#include "FeaturesPlugin_Union.h" + +#include + #include #include #include #include #include #include +#include #include -#include - #include #include #include #include +#include #include #include #include +#include #include #include #include +#define _USE_MATH_DEFINES +#include + +//================================================================================================== +bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast(theAttribute); + if(!aPathAttrSelection.get()) { + theError = "Error: This validator can only work with path selector in \"Pipe\" feature."; + return false; + } + + GeomShapePtr aPathShape = aPathAttrSelection->value(); + ResultPtr aContext = aPathAttrSelection->context(); + if(!aContext.get()) { + theError = "Error: Empty context."; + return false; + } + GeomShapePtr aContextShape = aContext->shape(); + if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE && !aPathShape->isEqual(aContextShape)) { + theError = "Error: Local selection of wires not allowed."; + return false; + } + + return true; +} + //================================================================================================== bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { static const std::string aCreationMethodID = "creation_method"; static const std::string aBaseObjectsID = "base_objects"; static const std::string aLocationsID = "locations_objects"; if(theFeature->getKind() != "Pipe") { - theError = "Error: Feature \"" + theFeature->getKind() + "\" does not supported by this validator."; + theError = "Error: Feature \"%1\" does not supported by this validator."; + theError.arg(theFeature->getKind()); return false; } AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID); if(!aCreationMethodAttr.get()) { - theError = "Error: Could not get \"" + aCreationMethodID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aCreationMethodID); return false; } @@ -55,13 +91,15 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptrselectionList(aBaseObjectsID); if(!aBaseObjectsSelectionList.get()) { - theError = "Error: Could not get \"" + aBaseObjectsID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aBaseObjectsID); return false; } AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID); if(!aLocationsSelectionList.get()) { - theError = "Error: Could not get \"" + aBaseObjectsID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aBaseObjectsID); return false; } @@ -82,7 +120,7 @@ bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeatu //================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { if(theArguments.empty()) { theError = "Error: Validator parameters is empty."; @@ -105,25 +143,47 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex); - ResultConstructionPtr aContext = std::dynamic_pointer_cast(aSelectionAttr->context()); + ResultPtr aContext = aSelectionAttr->context(); if(!aContext.get()) { - // It is not a result construction, continue. + theError = "Error: Empty context."; + return false; + } + + ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast(aContext); + if(!aResultConstruction.get()) { + // It is not a result construction. If shape is compound check that it contains only faces and edges. + GeomShapePtr aShape = aSelectionAttr->value(); + if(!aShape.get()) { + aShape = aContext->shape(); + } + + if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) { + for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) { + GeomShapePtr aSubShape = anIt.current(); + if(aSubShape->shapeType() != GeomAPI_Shape::EDGE + && aSubShape->shapeType() != GeomAPI_Shape::FACE) { + theError = "Error: Compound should contain only faces and edges."; + return false; + } + } + } + continue; } GeomShapePtr aShape = aSelectionAttr->value(); - GeomShapePtr aContextShape = aContext->shape(); + GeomShapePtr aContextShape = aResultConstruction->shape(); if(!aShape.get()) { // Whole sketch selected. - if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) { + if(aSelectedSketchesFromObjects.find(aResultConstruction) != aSelectedSketchesFromObjects.cend()) { theError = "Error: Object from this sketch is already selected. Sketch is not allowed for selection."; return false; } - aSelectedSketches.insert(aContext); + aSelectedSketches.insert(aResultConstruction); } else { // Object from sketch selected. - if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) { + if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) { theError = "Error: Whole sketch with this object is already selected. Don't allow to select this object."; return false; } @@ -141,7 +201,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA } aSelectedWiresFromObjects.bind(aWire, aWire); - aSelectedSketchesFromObjects.insert(aContext); + aSelectedSketchesFromObjects.insert(aResultConstruction); } } } @@ -153,7 +213,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA //================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { if(!theAttribute.get()) { theError = "Error: Empty attribute."; @@ -220,18 +280,20 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute // Check that object is a shape with allowed type. GeomValidators_ShapeType aShapeTypeValidator; if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) { - theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, " - "whole sketch(if it has at least one face), and whole objects with shape types: "; - std::list::const_iterator anIt = theArguments.cbegin(); - theError += *anIt; - for(++anIt; anIt != theArguments.cend(); ++anIt) { - theError += ", " + *anIt; + theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, whole sketch(if it has at least one face), and whole objects with shape types: %1"; + std::string anArgumentString; + for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) { + if (!anArgumentString.empty()) + anArgumentString += ", "; + anArgumentString += *anIt; } + theError.arg(anArgumentString); return false; } } else { - theError = "Error: Attribute \"" + anAttributeType + "\" does not supported by this validator."; + theError = "Error: Attribute \"%1\" does not supported by this validator."; + theError.arg(anAttributeType); return false; } @@ -241,14 +303,16 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute //================================================================================================== bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) { - theError = "Error: The attribute with the " + theAttribute->attributeType() + " type is not processed"; + 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 " + theAttribute->attributeType() + " type"; + 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 @@ -257,7 +321,8 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId); if (!aBaseAttribute.get()) { - theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type"; + 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, @@ -284,9 +349,9 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA } //================================================================================================== -bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr& theFeature, +bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { if(theArguments.size() != 2) { theError = "Error: Validator should be used with 2 parameters for extrusion."; @@ -298,46 +363,82 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptrattribute(*anArgsIt); ++anArgsIt; - if(isShapesCanBeEmpty(aCheckAttribute, theError)) { - return true; - } - + GeomShapePtr aDirShape; AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt); - if(!aSelAttr.get()) { - theError = "Error: Could not get selection attribute \"" + *anArgsIt + "\"."; - return false; + if(aSelAttr.get()) { + aDirShape = aSelAttr->value(); + if(!aDirShape.get()) { + ResultPtr aContext = aSelAttr->context(); + if(aContext.get()) { + aDirShape = aContext->shape(); + } + } } - GeomShapePtr aShape = aSelAttr->value(); - if(!aShape.get()) { - ResultPtr aContext = aSelAttr->context(); - if(!aContext.get()) { - theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt - + "\" can not be used with default value. Select direction for extrusion."; + 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; } - - aShape = aContext->shape(); } - if(!aShape.get()) { - theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt - + "\" can not be used with default value. Select direction for extrusion."; - return false; + std::shared_ptr aDirEdge(new GeomAPI_Edge(aDirShape)); + + // If faces selected check that direction not parallel with them. + AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(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 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 aPlanarEdges = std::dynamic_pointer_cast(aShapeInList); + if(aPlanarEdges.get()) { + std::shared_ptr aSketchDir = aPlanarEdges->norm(); + if(aDirEdge->isLine()) { + std::shared_ptr aDir = aDirEdge->line()->direction(); + isParallel = abs(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_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute) +bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature, std::string theAttribute) { return false; } //================================================================================================== -bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute, - std::string& theError) const +bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute, + Events_InfoMessage& theError) const { if(!theAttribute.get()) { return true; @@ -384,7 +485,7 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& //================================================================================================== bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { @@ -412,13 +513,19 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt return false; } std::shared_ptr aShape = anAttrSelection->value(); + GeomShapePtr aContextShape = aContext->shape(); if(!aShape.get()) { - aShape = aContext->shape(); + 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. @@ -446,7 +553,7 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt //================================================================================================== bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { @@ -470,20 +577,27 @@ bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& the ResultPtr aContext = aSelectAttr->context(); ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast(aContext); if(aResultConstruction.get()) { + theError = "Error: Only body shapes and construction planes are allowed for selection."; + return false; + } + ResultCompSolidPtr aResultCompsolid = std::dynamic_pointer_cast(aContext); + if(aResultCompsolid.get()) { + continue; } theError = "Error: Only body shapes and construction planes are allowed for selection."; return false; } + theError = ""; return true; } //================================================================================================== bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast(theAttribute); if(!aSubShapesAttrList.get()) { @@ -496,7 +610,8 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePt AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID); if(!aShapeAttrSelection.get()) { - theError = "Error: Could not get \"" + aBaseShapeID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aBaseShapeID); return false; } @@ -536,31 +651,35 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePt //================================================================================================== bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, - std::string& theError) const + Events_InfoMessage& theError) const { static const std::string aBaseShapeID = "base_shape"; static const std::string aSubShapesID = "subshapes"; if(theFeature->getKind() != "Remove_SubShapes") { - theError = "Error: Feature \"" + theFeature->getKind() + "\" does not supported by this validator."; + theError = "Error: Feature \"%1\" does not supported by this validator."; + theError.arg(theFeature->getKind()); return false; } AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID); if(!aShapeAttrSelection.get()) { - theError = "Error: Could not get \"" + aBaseShapeID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aBaseShapeID); return false; } AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID); if(!aSubShapesAttrList.get()) { - theError = "Error: Could not get \"" + aSubShapesID + "\" attribute."; + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aSubShapesID); return false; } // Copy base shape. GeomShapePtr aBaseShape = aShapeAttrSelection->value(); if(!aBaseShape.get()) { + theError = "Error: Base shape is empty."; return false; } GeomShapePtr aResultShape = aBaseShape->emptyCopied(); @@ -587,3 +706,79 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string { return false; } + +//================================================================================================== +bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr aBaseObjectsAttrList = std::dynamic_pointer_cast(theAttribute); + if(!aBaseObjectsAttrList.get()) { + theError = "Error: This validator can only work with selection list in \"%1\" feature."; + theError.arg(FeaturesPlugin_Union::ID()); + return false; + } + + for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) { + bool isSameFound = false; + AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex); + ResultCompSolidPtr aResult = std::dynamic_pointer_cast(anAttrSelectionInList->context()); + if(!aResult.get()) { + continue; + } + if(aResult->numberOfSubs() > 0) { + theError = "Error: Whole compsolids not allowed for selection."; + return false; + } + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorUnionArguments::isValid(const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + // Check feature kind. + if(theFeature->getKind() != FeaturesPlugin_Union::ID()) { + theError = "Error: This validator supports only \"%1\" feature."; + theError.arg(FeaturesPlugin_Union::ID()); + return false; + } + + // Get base objects attribute list. + AttributeSelectionListPtr aBaseObejctsAttrList = theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID()); + if(!aBaseObejctsAttrList.get()) { + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID()); + return false; + } + + // Get all shapes. + ListOfShape aBaseShapesList; + for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) { + AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex); + GeomShapePtr aShape = anAttrSelectionInList->value(); + aBaseShapesList.push_back(aShape); + } + + // Make componud and find connected. + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList); + ListOfShape aCombined, aFree; + GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree); + + if(aFree.size() > 0 || aCombined.size() > 1) { + theError = "Error: Not all shapes have shared topology."; + return false; + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature, + std::string theAttribute) +{ + return false; +}