-// 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
#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>
#define _USE_MATH_DEFINES
#include <math.h>
+#ifdef _MSC_VER
+#pragma warning(disable: 4100)
+#endif
+
//==================================================================================================
bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments,
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;
}
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) {
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.";
// LCOV_EXCL_STOP
}
- std::list<std::string>::const_iterator
- anArgsIt = theArguments.begin(), aLast = theArguments.end();
+ std::list<std::string>::const_iterator anArgsIt = theArguments.begin();
AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
++anArgsIt;
}
}
- 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.";
}
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;
}
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,
}
for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
- bool isSameFound = false;
AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
ResultPtr aContext = anAttrSelectionInList->context();
if (!aContext.get()) {
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;
int anObjectsNb = 0, aToolsNb = 0;
- std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+ std::list<std::string>::const_iterator anIt = theArguments.begin();
bool isAllInSameCompSolid = true;
ResultBodyPtr aCompSolid;
}
}
- anIt++;
-
if (anObjectsNb + aToolsNb < 2) {
theError = "Not enough arguments for Fuse operation.";
return false;
int anObjectsNb = 0, aToolsNb = 0;
- std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+ std::list<std::string>::const_iterator anIt = theArguments.begin();
- bool isAllInSameCompSolid = true;
ResultBodyPtr aCompSolid;
AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
return false;
}
// LCOV_EXCL_STOP
+
+//==================================================================================================
+bool FeaturesPlugin_ValidatorDefeaturingSelection::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.";
+ 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;
+}