#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 <GeomAPI_ShapeIterator.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_MapShapesAndAncestors.h>
#include <GeomAlgoAPI_Prism.h>
#include <GeomAlgoAPI_ShapeBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
#include <GeomAlgoAPI_WireBuilder.h>
+#include <algorithm>
+
#define _USE_MATH_DEFINES
#include <math.h>
if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
AttributeSelectionListPtr aListAttr =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+
+ const std::string& aSelType = aListAttr->selectionType();
+ std::list<std::string> 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;
}
}
aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(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;
}
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<FeaturesPlugin_CompositeBoolean> aComposite =
+ std::dynamic_pointer_cast<FeaturesPlugin_CompositeBoolean>(
+ 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.";
return true;
}
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorFillet1DSelection::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ AttributeSelectionListPtr anAttrSelectionList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ if (!anAttrSelectionList.get()) {
+ // 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<GeomShapePtr, MapShapeToShapes> 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<GeomShapePtr, MapShapeToShapes>::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<std::string>& theArguments,