X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Validators.cpp;h=9235d933e78d40e886dc4902e2f84649f016f7e3;hb=47ee8cc9aac0bef34d6d2ef58816334c32781827;hp=30993f225bd44544afc1544cedc0f00bb8a5a095;hpb=b04366b7cb8e262e53383f50b3bc536c2d525816;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 30993f225..9235d933e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2020 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 @@ -23,6 +23,7 @@ #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" @@ -30,7 +31,7 @@ #include #include -#include > +#include #include #include #include @@ -54,14 +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, @@ -271,9 +279,8 @@ 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::VERTEX - && aSubShape->shapeType() != GeomAPI_Shape::EDGE - && aSubShape->shapeType() != GeomAPI_Shape::FACE) { + if (aSubShape->shapeType() > GeomAPI_Shape::VERTEX || + aSubShape->shapeType() < GeomAPI_Shape::FACE) { theError = "Error: Compound should contain only faces, edges or vertices."; return false; } @@ -299,7 +306,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; } @@ -394,9 +401,32 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast(theAttribute); + + const std::string& 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; } } @@ -429,28 +459,32 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute aConstruction = std::dynamic_pointer_cast(aContext); if(aConstruction.get()) { // Construction selected. Check that it is not infinite. - if(aConstruction->isInfinite()) { + 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."; @@ -461,7 +495,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) { @@ -547,8 +581,7 @@ bool FeaturesPlugin_ValidatorExtrusionDir::isValid( // 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; @@ -913,8 +946,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."; @@ -928,8 +962,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; } @@ -938,6 +972,79 @@ 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 + } + + // 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, @@ -1135,7 +1242,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()) { @@ -1561,16 +1667,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; @@ -1686,7 +1792,7 @@ bool FeaturesPlugin_ValidatorBooleanFuseArguments::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; @@ -1737,14 +1843,9 @@ 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; @@ -1843,9 +1944,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); @@ -1880,3 +1980,42 @@ bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory( 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; + } + } + + return true; +}