X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Validators.cpp;h=93bcd42aced8ccbcf9deac33ece9386e7db1cd88;hb=fc72d43b677baa05ae7fd317346fd8b723b799ed;hp=8d785e658827d2d621b0d78407242db548749450;hpb=c66ffb67c688d6a40a765957538b635a94a35ecf;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 8d785e658..93bcd42ac 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,10 +12,9 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "FeaturesPlugin_Validators.h" @@ -24,12 +23,15 @@ #include "FeaturesPlugin_BooleanFuse.h" #include "FeaturesPlugin_BooleanCommon.h" #include "FeaturesPlugin_BooleanSmash.h" +#include "FeaturesPlugin_CompositeBoolean.h" +#include "FeaturesPlugin_Extrusion.h" #include "FeaturesPlugin_Pipe.h" #include "FeaturesPlugin_Union.h" #include #include +#include #include #include #include @@ -53,13 +55,21 @@ #include #include +#include +#include #include #include #include +#include + #define _USE_MATH_DEFINES #include +#ifdef _MSC_VER +#pragma warning(disable: 4100) +#endif + //================================================================================================== bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -68,8 +78,10 @@ bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast(theAttribute); if(!aPathAttrSelection.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with path selector in \"Pipe\" feature."; return false; +// LCOV_EXCL_STOP } GeomShapePtr aPathShape = aPathAttrSelection->value(); @@ -96,17 +108,21 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttri AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with selection list attributes in \"Pipe\" feature."; return false; +// LCOV_EXCL_STOP } std::shared_ptr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID()); if (!aPathSelection.get()) { +// LCOV_EXCL_START theError = "Error: Path not selected."; return false; +// LCOV_EXCL_STOP } GeomShapePtr aPathShape = aPathSelection->value(); @@ -161,6 +177,7 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttri } //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid( const std::shared_ptr& theFeature, const std::list& theArguments, @@ -209,16 +226,70 @@ bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid( return true; } +// LCOV_EXCL_STOP + +//================================================================================================== +bool FeaturesPlugin_ValidatorLoftSameTypeShape::isValid( + const std::shared_ptr& theFeature, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + static const std::string aFirstObjetcID = "first_object"; + static const std::string aSecondObjetcID = "second_object"; + + if (theFeature->getKind() != "Loft") { + theError = "Error: Feature \"%1\" does not supported by this validator."; + theError.arg(theFeature->getKind()); + return false; + } + + AttributeSelectionPtr aFirstObjectsSelection = theFeature->selection(aFirstObjetcID); + if ( !aFirstObjectsSelection->isInitialized()) { + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aFirstObjetcID); + return false; + } + + AttributeSelectionPtr aSecondObjectsSelection = theFeature->selection(aSecondObjetcID); + if (!aSecondObjectsSelection->isInitialized()) { + theError = "Error: Could not get \"%1\" attribute."; + theError.arg(aSecondObjetcID); + return false; + } + + GeomShapePtr aFirstShape = aFirstObjectsSelection->value(); + if (!aFirstShape.get()) { + aFirstShape = aFirstObjectsSelection->context()->shape(); + } + GeomShapePtr aSecondShape = aSecondObjectsSelection->value(); + if (!aSecondShape.get()) { + aSecondShape = aSecondObjectsSelection->context()->shape(); + } + + if (aFirstShape->isEqual(aSecondShape)) { + theError = "Error: the shapes are equal"; + return false; + } + + if (aFirstShape->shapeType()!=aSecondShape->shapeType()) { + theError = "Error: the shapes have different type"; + return false; + } + + return true; +} //================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const { +// LCOV_EXCL_START if(theArguments.empty()) { theError = "Error: Validator parameters is empty."; return false; } +// LCOV_EXCL_STOP // Checking attribute. if(!isValidAttribute(theAttribute, theArguments, theError)) { @@ -245,7 +316,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA 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. + // If shape is compound check that it contains only faces, edges or vertices. GeomShapePtr aShape = aSelectionAttr->value(); if(!aShape.get()) { if (aContext.get()) { @@ -259,9 +330,9 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA 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."; + if (aSubShape->shapeType() > GeomAPI_Shape::VERTEX || + aSubShape->shapeType() < GeomAPI_Shape::FACE) { + theError = "Error: Compound should contain only faces, edges or vertices."; return false; } } @@ -286,7 +357,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA if(aSelectedWiresFromObjects.isBound(aWire)) { theError = - "Error: Objects with such wire already selected. Don't allow to select this object."; + "Error: Objects with this wire already selected. Don't allow to select this object."; return false; } @@ -309,9 +380,11 @@ bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid( AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID); if(!aListAttr.get()) { +// LCOV_EXCL_START theError = "Error: Could not get \"%1\" attribute."; theError.arg(aBaseObjectsID); return false; +// LCOV_EXCL_STOP } std::set aSelectedSketches; @@ -369,17 +442,46 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute Events_InfoMessage& theError) const { if(!theAttribute.get()) { +// LCOV_EXCL_START theError = "Error: Empty attribute."; return false; +// LCOV_EXCL_STOP } std::string anAttributeType = theAttribute->attributeType(); if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); + + const std::string& aVersion = theAttribute->owner()->data()->version(); + std::string aSelType; + if (!aVersion.empty()) + aSelType = aListAttr->selectionType(); + + std::list anApplicableTypes; + switch (GeomValidators_ShapeType::shapeType(aSelType)) { + case GeomValidators_ShapeType::Vertex: + anApplicableTypes.push_back("vertex"); + break; + case GeomValidators_ShapeType::Edge: + anApplicableTypes.push_back("edge"); + anApplicableTypes.push_back("wire"); + break; + case GeomValidators_ShapeType::Face: + anApplicableTypes.push_back("face"); + anApplicableTypes.push_back("shell"); + // wire should not be the first in this list to be able to check + // the type of selection when evaluating shape by shape + anApplicableTypes.push_back("wire"); + break; + default: + anApplicableTypes = theArguments; + break; + } + for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) { // If at least one attribute is invalid, the result is false. - if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) { + if(!isValidAttribute(aListAttr->value(anIndex), anApplicableTypes, theError)) { return false; } } @@ -411,30 +513,33 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute if (aContext.get()) aConstruction = std::dynamic_pointer_cast(aContext); if(aConstruction.get()) { - // Construciotn selected. Check that is is not infinite. - if(aConstruction->isInfinite()) { + // Construction selected. Check that it is not infinite. + if(aConstruction->isInfinite() && !aConstruction->shape()->isVertex()) { theError = "Error: Infinite constructions is not allowed as base."; return false; } - GeomShapePtr aContextShape = aContext->shape(); + aContextShape = aContext->shape(); if(aShape->isEqual(aContextShape)) { - // Whole construction selected. Check that it have faces. - if(aConstruction->facesNum() > 0) { + // Whole construction selected. Check that it has faces. + if((theArguments.front() == "face" && aConstruction->facesNum() > 0) || + theArguments.front() == "edge") { return true; } } else { - // Shape on construction selected. Check that it is a face or wire. - if(aShape->shapeType() == GeomAPI_Shape::WIRE || - aShape->shapeType() == GeomAPI_Shape::FACE) { - return true; + // CUT operation supports only FACE or WIRE as a tool base + std::shared_ptr aComposite = + std::dynamic_pointer_cast( + ModelAPI_Feature::feature(theAttribute->owner())); + if (aComposite && + aComposite->operationType() == FeaturesPlugin_CompositeBoolean::BOOL_CUT) { + return aShape->shapeType() == GeomAPI_Shape::WIRE || + aShape->shapeType() == GeomAPI_Shape::FACE; } } - - return false; } - if(aContextShape.get() && !aShape->isEqual(aContextShape)) { + if(!aConstruction && 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."; @@ -445,7 +550,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute 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), " + "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) { @@ -458,15 +563,18 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute } } else { +// LCOV_EXCL_START theError = "Error: Attribute \"%1\" does not supported by this validator."; theError.arg(anAttributeType); return false; +// LCOV_EXCL_STOP } return true; } //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const @@ -513,6 +621,7 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA bool aValid = !aFeatureKind && aPlanarFace; return aValid; } +// LCOV_EXCL_STOP //================================================================================================== bool FeaturesPlugin_ValidatorExtrusionDir::isValid( @@ -521,12 +630,13 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( Events_InfoMessage& theError) const { if(theArguments.size() != 2) { +// LCOV_EXCL_START theError = "Error: Validator should be used with 2 parameters for extrusion."; return false; +// LCOV_EXCL_STOP } - std::list::const_iterator - anArgsIt = theArguments.begin(), aLast = theArguments.end(); + std::list::const_iterator anArgsIt = theArguments.begin(); AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt); ++anArgsIt; @@ -547,10 +657,16 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( if(aContext.get()) { aDirShape = aContext->shape(); } + + if (aDirShape.get() && aDirShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aDirShape); + aDirShape = anIt.current(); + } } } - if(!aDirShape.get()) { + if(!aDirShape.get() || aDirShape->isNull() || + aDirShape->shapeType() != GeomAPI_Shape::EDGE) { // Check that dir can be empty. if(!isShapesCanBeEmpty(aCheckAttribute, theError)) { theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" " @@ -615,9 +731,11 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute, Events_InfoMessage& theError) const { +// LCOV_EXCL_START if(!theAttribute.get()) { return true; } +// LCOV_EXCL_STOP std::string anAttributeType = theAttribute->attributeType(); if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { @@ -659,6 +777,99 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr return true; } +//================================================================================================== +bool FeaturesPlugin_ValidatorExtrusionBoundaryFace::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + + // Collect all necessary attributes and try to build prism + + // base face + AttributeSelectionListPtr aBaseShapeAttr = + aFeature->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID()); + ListOfShape aBaseShapeList; + std::string anError; + if (!FeaturesPlugin_Tools::getShape(aBaseShapeAttr, true, aBaseShapeList, anError)) { + theError = anError; + return false; + } + + // direction + AttributeSelectionPtr aSelection = + aFeature->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID()); + GeomShapePtr aShape = aSelection->value(); + if (!aShape.get() && aSelection->context().get()) + aShape = aSelection->context()->shape(); + + GeomEdgePtr anEdge; + if (aShape.get()) { + if (aShape->isEdge()) + anEdge = aShape->edge(); + else if (aShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aShape); + anEdge = anIt.current()->edge(); + } + } + + std::shared_ptr aDir; + if (anEdge.get() && anEdge->isLine()) + aDir = anEdge->line()->direction(); + + // from/to shapes + GeomShapePtr aFromShape, aToShape; + aSelection = aFeature->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID()); + if (aSelection.get()) { + aToShape = aSelection->value(); + if (!aToShape.get() && aSelection->context().get()) + aToShape = aSelection->context()->shape(); + if (aToShape.get() && aToShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aToShape); + aToShape = anIt.current(); + } + if (aToShape.get() && !aToShape->isFace()) { + theError = "\"To\" shape is not a face"; + return false; + } + } + aSelection = aFeature->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID()); + if (aSelection.get()) { + aFromShape = aSelection->value(); + if (!aFromShape.get() && aSelection->context().get()) + aFromShape = aSelection->context()->shape(); + if (aFromShape.get() && aFromShape->isCompound()) { + GeomAPI_ShapeIterator anIt(aFromShape); + aFromShape = anIt.current(); + } + if (aFromShape.get() && !aFromShape->isFace()) { + theError = "\"From\" shape is not a face"; + return false; + } + } + + double aToSize = aFeature->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID())->value(); + double aFromSize = aFeature->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID())->value(); + + // check extrusion + for (ListOfShape::iterator anIt = aBaseShapeList.begin(); anIt != aBaseShapeList.end(); anIt++) { + std::shared_ptr aBaseShape = *anIt; + + std::shared_ptr aPrismAlgo( + new GeomAlgoAPI_Prism(aBaseShape, aDir, aToShape, aToSize, aFromShape, aFromSize)); + bool isFailed = GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPrismAlgo, + FeaturesPlugin_Extrusion::ID(), + anError); + if (isFailed) { + theError = anError; + return false; + } + } + + return true; +} + //================================================================================================== bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -667,9 +878,11 @@ bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAt AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with selection list attributes in \"Boolean\" feature."; return false; +// LCOV_EXCL_STOP } std::shared_ptr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); @@ -756,9 +969,11 @@ bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAtt AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with selection list attributes in \"Fillet\" feature."; return false; +// LCOV_EXCL_STOP } FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); @@ -786,8 +1001,9 @@ bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAtt } } - ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext); - GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape(); + ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true); + GeomShapePtr anOwner = aContext->shape(); + GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner; if (!anOwner) { theError = "Error: wrong feature is selected."; @@ -801,8 +1017,8 @@ bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAtt } if (!aBaseSolid) - aBaseSolid = anOwner; - else if (!aBaseSolid->isEqual(anOwner)) { + aBaseSolid = aTopLevelOwner; + else if (!aBaseSolid->isEqual(aTopLevelOwner)) { theError = "Error: Sub-shapes of different solids have been selected."; return false; } @@ -811,6 +1027,94 @@ bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAtt return true; } + +//================================================================================================== +bool FeaturesPlugin_ValidatorFillet1DSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if (!anAttrSelectionList.get()) { + // LCOV_EXCL_START + theError = + "Error: This validator can only work with selection list attributes in \"Fillet\" feature."; + return false; + // LCOV_EXCL_STOP + } + + // Validate wires selection + if (!theArguments.empty() && + theArguments.front() == "wire") { + for (int ind = 0; ind < anAttrSelectionList->size(); ++ind) { + AttributeSelectionPtr aCurSel = anAttrSelectionList->value(ind); + //GeomShapePtr aContext = aCurSel->context()->shape(); + GeomShapePtr aWire = aCurSel->value(); + if (aWire->shapeType() != GeomAPI_Shape::WIRE) { + theError = "Selected shape is not a wire"; + return false; + } + } + return true; + } + + // check each selected vertex is a sharp corner between adjacent edges, + // and these edges are in the same plane + std::map aWireSubshapes; + int aNbSel = anAttrSelectionList->size(); + for (int ind = 0; ind < aNbSel; ++ind) { + AttributeSelectionPtr aCurSel = anAttrSelectionList->value(ind); + GeomShapePtr aContext = aCurSel->context()->shape(); + GeomShapePtr aVertex = aCurSel->value(); + // check wire already processed, if not, store all vertices and edges, sharing them + std::map::iterator aProcessed = aWireSubshapes.find(aContext); + if (aProcessed == aWireSubshapes.end()) { + if (aContext->shapeType() != GeomAPI_Shape::WIRE) { + theError = "Selected vertex is not a wire corner"; + return false; + } + if (aVertex->shapeType() != GeomAPI_Shape::VERTEX) { + theError = "Selected shape is not a vertex"; + return false; + } + + GeomAlgoAPI_MapShapesAndAncestors aMapVE(aContext, GeomAPI_Shape::VERTEX, + GeomAPI_Shape::EDGE); + aWireSubshapes[aContext] = aMapVE.map(); + aProcessed = aWireSubshapes.find(aContext); + } + + // check the vertex + MapShapeToShapes::iterator aFound = aProcessed->second.find(aVertex); + if (aFound == aProcessed->second.end()) { + theError = "Selected vertex does not exist in the wire"; + return true; + } + else if (aFound->second.size() != 2) { + theError = "Vertex should be shared between 2 edges exactly"; + return false; + } + + ListOfShape anEdges; + anEdges.insert(anEdges.end(), aFound->second.begin(), aFound->second.end()); + GeomPlanePtr aPlane = GeomAlgoAPI_ShapeTools::findPlane(anEdges); + if (!aPlane) { + theError = "Error: Edges are not planar"; + return false; + } + + GeomEdgePtr anEdge1(new GeomAPI_Edge(anEdges.front())); + GeomEdgePtr anEdge2(new GeomAPI_Edge(anEdges.back())); + GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(aVertex)); + if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex)) { + theError = "Error: Edges are tangent"; + return false; + } + } + + return true; +} + //================================================================================================== bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, @@ -819,8 +1123,10 @@ bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& the AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); if(!anAttrSelectionList.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with selection list in \"Partition\" feature."; return false; +// LCOV_EXCL_STOP } for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { @@ -877,9 +1183,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePt AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast(theAttribute); if(!aSubShapesAttrList.get()) { +// LCOV_EXCL_START theError = "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature."; return false; +// LCOV_EXCL_STOP } static const std::string aBaseShapeID = "base_shape"; @@ -887,9 +1195,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePt AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID); if(!aShapeAttrSelection.get()) { +// LCOV_EXCL_START theError = "Error: Could not get \"%1\" attribute."; theError.arg(aBaseShapeID); return false; +// LCOV_EXCL_STOP } GeomShapePtr aBaseShape = aShapeAttrSelection->value(); @@ -936,6 +1246,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( static const std::string aBaseShapeID = "base_shape"; static const std::string aSubShapesID = "subshapes_to_keep"; +// LCOV_EXCL_START if(theFeature->getKind() != "Remove_SubShapes") { theError = "Error: Feature \"%1\" does not supported by this validator."; theError.arg(theFeature->getKind()); @@ -955,6 +1266,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( theError.arg(aSubShapesID); return false; } +// LCOV_EXCL_STOP // Copy base shape. GeomShapePtr aBaseShape = aShapeAttrSelection->value(); @@ -986,6 +1298,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( } //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const @@ -999,7 +1312,6 @@ bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttr } for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) { - bool isSameFound = false; AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex); ResultPtr aContext = anAttrSelectionInList->context(); if (!aContext.get()) { @@ -1035,6 +1347,7 @@ bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttr return true; } +// LCOV_EXCL_STOP //================================================================================================== bool FeaturesPlugin_ValidatorUnionArguments::isValid( @@ -1042,6 +1355,7 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid( const std::list& theArguments, Events_InfoMessage& theError) const { +// LCOV_EXCL_START // Check feature kind. if(theFeature->getKind() != FeaturesPlugin_Union::ID()) { theError = "Error: This validator supports only \"%1\" feature."; @@ -1057,6 +1371,7 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid( theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID()); return false; } +// LCOV_EXCL_STOP // Get all shapes. GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID; @@ -1074,14 +1389,10 @@ bool FeaturesPlugin_ValidatorUnionArguments::isValid( // Make compound and find connected. GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList); - ListOfShape aCombined, aFree; - GeomAlgoAPI_ShapeTools::combineShapes( - aCompound, - aType, - aCombined, - aFree); - - if(aFree.size() > 0 || aCombined.size() > 1) { + ListOfShape aResults; + GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults); + + if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) { theError = "Error: Not all shapes have shared topology."; return false; } @@ -1094,9 +1405,11 @@ bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAtt Events_InfoMessage& theError) const { if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) { +// LCOV_EXCL_START theError = "Error: The attribute with the %1 type is not processed"; theError.arg(theAttribute->attributeType()); return false; +// LCOV_EXCL_STOP } AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast @@ -1157,81 +1470,52 @@ bool FeaturesPlugin_ValidatorBooleanArguments::isValid( const std::list& 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 anObjectsNb = 0, aToolsNb = 0; - //int anOperationType = 0; + int anObjectsToolsNb[2] = { 0, 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* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) { + AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt); + if (anAttrSelList) { - 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()) + *anArgNbIt = anAttrSelList->size(); + if (isAllInSameCompSolid) { + for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex) { - if (aCompSolid.get()) + AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex); + ResultPtr aContext = anAttr->context(); + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); + if (aResCompSolidPtr.get()) { - isAllInSameCompSolid = aCompSolid == aResCompSolidPtr; + if (aCompSolid.get()) + { + isAllInSameCompSolid = aCompSolid == aResCompSolidPtr; + } + else + { + aCompSolid = aResCompSolidPtr; + } } else { - aCompSolid = aResCompSolidPtr; + isAllInSameCompSolid = false; + break; } } - else - { - isAllInSameCompSolid = false; - break; - } } } } - anIt++; std::shared_ptr aFeature = std::dynamic_pointer_cast(theFeature); @@ -1240,7 +1524,7 @@ bool FeaturesPlugin_ValidatorBooleanArguments::isValid( if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) { // Fuse operation - if (anObjectsNb + aToolsNb < 2) + if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2) { theError = "Not enough arguments for Fuse operation."; return false; @@ -1253,12 +1537,12 @@ bool FeaturesPlugin_ValidatorBooleanArguments::isValid( } else { - if (anObjectsNb < 1) + if (anObjectsToolsNb[0] < 1) // check number of objects { theError = "Objects not selected."; return false; } - if (aToolsNb < 1) + if (anObjectsToolsNb[1] < 1) // check number of tools { theError = "Tools not selected."; return false; @@ -1274,6 +1558,7 @@ bool FeaturesPlugin_ValidatorBooleanArguments::isValid( } //================================================================================================= +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature, std::string theAttribute) { @@ -1284,6 +1569,7 @@ bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFe return false; } +// LCOV_EXCL_STOP //================================================================================================== bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( @@ -1297,9 +1583,11 @@ bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(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; @@ -1325,9 +1613,12 @@ bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( ResultPtr aContext = anAttrSelection->context(); std::shared_ptr aShape = anAttrSelection->value(); - GeomShapePtr aContextShape = aContext->shape(); if (!aShape.get()) { - aShape = aContextShape; + if (!aContext.get()) { + theError = "Error: Empty selection."; + return false; + } + aShape = aContext->shape(); } if (aShape->isSolid() || aShape->isCompSolid()) { @@ -1407,15 +1698,6 @@ bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( 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(); @@ -1436,6 +1718,7 @@ bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid( } //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const @@ -1454,16 +1737,16 @@ bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttrib 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()) { + if (aContext.get()) { + aFeature = ModelAPI_Feature::feature(aContext); + } else { + aFeature = anAttrSelection->contextFeature(); + if (!aFeature.get() || !aFeature->results().size() || + aFeature->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; @@ -1504,8 +1787,10 @@ bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttrib return true; } +// LCOV_EXCL_STOP //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid( const AttributePtr& theAttribute, const std::list& theArguments, @@ -1557,6 +1842,7 @@ bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid( return true; } +// LCOV_EXCL_STOP //================================================================================================= bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid( @@ -1564,17 +1850,19 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid( const std::list& 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 aFeature = std::dynamic_pointer_cast(theFeature); int anObjectsNb = 0, aToolsNb = 0; - std::list::const_iterator anIt = theArguments.begin(), aLast = theArguments.end(); + std::list::const_iterator anIt = theArguments.begin(); bool isAllInSameCompSolid = true; ResultBodyPtr aCompSolid; @@ -1625,20 +1913,16 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid( } } - 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) @@ -1649,8 +1933,10 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory( return false; } +// LCOV_EXCL_STOP //================================================================================================== +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid( const AttributePtr& theAttribute, const std::list& theArguments, @@ -1685,8 +1971,10 @@ bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid( } std::shared_ptr aShape = anAttrSelection->value(); GeomShapePtr aContextShape; - if (!aShape.get() && aContext.get()) { + if (aContext.get()) { aContextShape = aContext->shape(); + } + if (!aShape.get()) { aShape = aContextShape; } if (!aShape.get()) { @@ -1706,6 +1994,7 @@ bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid( return true; } +// LCOV_EXCL_STOP //================================================================================================= bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid( @@ -1714,8 +2003,10 @@ bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid( 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 aFeature = @@ -1723,9 +2014,8 @@ bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid( int anObjectsNb = 0, aToolsNb = 0; - std::list::const_iterator anIt = theArguments.begin(), aLast = theArguments.end(); + std::list::const_iterator anIt = theArguments.begin(); - bool isAllInSameCompSolid = true; ResultBodyPtr aCompSolid; AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt); @@ -1745,16 +2035,169 @@ bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid( if ((isSimpleMode && anObjectsNb < 2) || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) { - theError = "Not enough arguments for Fuse operation."; + theError = "Not enough arguments for Common operation."; return false; } return true; } //================================================================================================= +// LCOV_EXCL_START bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory( std::string theFeature, std::string theAttribute) { return false; } +// LCOV_EXCL_STOP + +//================================================================================================== +bool FeaturesPlugin_ValidatorDefeaturingSelection::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if (!anAttrSelectionList.get()) { + // LCOV_EXCL_START + theError = "Error: This validator can only work with selection list attributes."; + return false; + // LCOV_EXCL_STOP + } + + // Check selected entities are sub-shapes of solid or compsolid + 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()) { + theError = "Error: Empty selection context."; + return false; + } + + GeomShapePtr aContextShape = aContext->shape(); + if (aContextShape->shapeType() != GeomAPI_Shape::SOLID) { + theError = "Error: Not all selected shapes are sub-shapes of solids."; + return false; + } + + ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true); + if (aResRootPtr.get() && aResRootPtr->shape().get()) { + if (!aResRootPtr->shape()->isCollectionOfSolids()) { + theError = "Error: The main shape should be a collection of solids"; + return false; + } + } + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorSewingSelection::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."; + return false; + } + + // Check selected entities are of valid types + 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; + } + if (aContext->groupName() != ModelAPI_ResultBody::group()) { + theError = "Error: Not a result body."; + return false; + } + + GeomShapePtr aContextShape = aContext->shape(); + if (!aContextShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + GeomAPI_Shape::ShapeType aShapeType = aContextShape->shapeType(); + std::set anAllowedTypes; + 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); + if (anAllowedTypes.find(aShapeType) == anAllowedTypes.end()) { + theError = "Error: Selected shape has the wrong type."; + return false; + } + + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorGlueFacesSelection::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."; + return false; + } + + // Check selected entities are of valid types + 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; + } + if (aContext->groupName() != ModelAPI_ResultBody::group()) { + theError = "Error: Not a result body."; + return false; + } + + GeomShapePtr aContextShape = aContext->shape(); + if (!aContextShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + GeomAPI_Shape::ShapeType aShapeType = aContextShape->shapeType(); + std::set anAllowedTypes; + 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); + if (anAllowedTypes.find(aShapeType) == anAllowedTypes.end()) { + theError = "Error: Selected shape has the wrong type."; + return false; + } + + } + + return true; +}