From dae58840b66bf4262ee617d7cff793cc048c2b93 Mon Sep 17 00:00:00 2001 From: dbv Date: Mon, 18 Apr 2016 11:00:31 +0300 Subject: [PATCH] Issue #1369: add contour functionality --- .../FeaturesPlugin_Validators.cpp | 2 +- src/FeaturesPlugin/FeaturesPlugin_Wire.cpp | 156 ++++++++++++++++++ src/FeaturesPlugin/FeaturesPlugin_Wire.h | 11 ++ src/FeaturesPlugin/wire_widget.xml | 5 +- 4 files changed, 172 insertions(+), 2 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index c8559d011..9afdafd18 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -352,7 +352,7 @@ bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribu theError = "Attribute have empty context."; return false; } - + GeomShapePtr aShape = aSelection->value(); GeomShapePtr aContextShape = aContext->shape(); if(!aShape.get()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp b/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp index 6764df639..b704d65e7 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp @@ -8,9 +8,19 @@ #include #include +#include +#include + +#include +#include +#include + +#include #include +#include + //================================================================================================= FeaturesPlugin_Wire::FeaturesPlugin_Wire() { @@ -67,3 +77,149 @@ void FeaturesPlugin_Wire::execute() setResult(aResultBody); } +//================================================================================================= +bool FeaturesPlugin_Wire::customAction(const std::string& theActionId) +{ + if(theActionId == "add_contour") { + return addContour(); + } else { + Events_Error::send("Error: Feature \"" + getKind() + "\" does not support action \"" + theActionId + "\"."); + } + + return false; +} + +//================================================================================================= +bool FeaturesPlugin_Wire::addContour() +{ + // Get base objects list. + AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); + if(aSelectionList->size() == 0) { + Events_Error::send("Error: Empty selection list."); + return false; + } + + // Collect attributes to check. + ListOfShape anAddedEdges; + std::list anAttributesToCheck; + for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr anEdgeInList = aSelection->value(); + if(!anEdgeInList.get()) { + continue; + } + + // Check that it is edge. + if(anEdgeInList->shapeType() != GeomAPI_Shape::EDGE) { + continue; + } + + // Check that it is edge on sketch. + ResultPtr aContext = aSelection->context(); + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aContext); + if(!aConstruction.get()) { + continue; + } + GeomShapePtr aContextShape = aConstruction->shape(); + std::shared_ptr aPlanarEdges = std::dynamic_pointer_cast(aContextShape); + if(!aPlanarEdges.get()) { + continue; + } + + // Check that sketch have faces. + if(aConstruction->facesNum() == 0) { + continue; + } + + anAddedEdges.push_back(anEdgeInList); + anAttributesToCheck.push_back(aSelection); + } + + // Check if edges have contours. + bool isAnyContourFound = false; + for(std::list::const_iterator aListIt = anAttributesToCheck.cbegin(); + aListIt != anAttributesToCheck.cend(); + ++aListIt) { + AttributeSelectionPtr aSelection = *aListIt; + std::shared_ptr anEdgeInList(new GeomAPI_Edge(aSelection->value())); + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSelection->context()); + std::shared_ptr aPlanarEdges = std::dynamic_pointer_cast(aConstruction->shape()); + + ListOfShape aClosedWires; + GeomAlgoAPI_ShapeTools::getClosedWires(aPlanarEdges->getEdges(), aClosedWires); + + //// Iterate on wires and add wire with this edge. + //std::shared_ptr aFoundWire; + //for(ListOfShape::const_iterator aWireIt = aClosedWires.cbegin(); + // aWireIt != aClosedWires.cend(); + // ++aWireIt) { + // GeomShapePtr aWire = *aWireIt; + // for(GeomAPI_ShapeExplorer anExp(aWire, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { + // GeomShapePtr anEdgeOnWire = anExp.current(); + // if(anEdgeInList->isSame(anEdgeOnWire)) { + // aFoundWire = aWire; + // break; + // } + // } + + // if(aFoundWire.get()) { + // break; + // } + //} + + //// If wire with the same edge found add all other edges to list. + //if(aFoundWire.get()) { + // isAnyContourFound = true; + // anAddedEdges.bind(anEdgeInList, anEdgeInList); + // for(GeomAPI_ShapeExplorer anExp(aFoundWire, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { + // GeomShapePtr anEdgeOnFace = anExp.current(); + // if(!anAddedEdges.isBound(anEdgeOnFace)) { + // anAddedEdges.bind(anEdgeOnFace, anEdgeOnFace); + // aSelectionList->append(aConstruction, anEdgeOnFace); + // } + // } + //} + + // Iterate on faces and add face with this edge. + std::shared_ptr aFoundFace; + for(int anIndex = 0; anIndex < aConstruction->facesNum(); ++anIndex) { + std::shared_ptr aFace = aConstruction->face(anIndex); + for(GeomAPI_ShapeExplorer anExp(aFace, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { + std::shared_ptr anEdgeOnFace(new GeomAPI_Edge(anExp.current())); + if(anEdgeInList->isEqual(anEdgeOnFace)) { + aFoundFace = aFace; + break; + } + } + + if(aFoundFace.get()) { + break; + } + } + + // If face with the same edge found. Add all other edges to list. + if(aFoundFace.get()) { + isAnyContourFound = true; + for(GeomAPI_ShapeExplorer anExp(aFoundFace, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { + std::shared_ptr anEdgeOnFace(new GeomAPI_Edge(anExp.current())); + ListOfShape::const_iterator anEdgesIt = anAddedEdges.cbegin(); + for(; anEdgesIt != anAddedEdges.cend(); ++anEdgesIt) { + if(anEdgeOnFace->isEqual(*anEdgesIt)) { + break; + } + } + if(anEdgesIt == anAddedEdges.cend()) { + anAddedEdges.push_back(anEdgeOnFace); + aSelectionList->append(aConstruction, anEdgeOnFace); + } + } + } + } + + if(!isAnyContourFound) { + Events_Error::send("Error: No contours found for selected edges."); + return false; + } + + return false; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Wire.h b/src/FeaturesPlugin/FeaturesPlugin_Wire.h index 6a265cd1b..c456d1d00 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Wire.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Wire.h @@ -46,6 +46,17 @@ public: /// Creates a new part document if needed. FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Performs some functionality by action id. + /// \param[in] theAttributeId action key id. + /// \return false in case if action not perfomed. + FEATURESPLUGIN_EXPORT virtual bool customAction(const std::string& theActionId); + +private: + /// Action: Adds to the list of segments other segments of the sketcher connected to + /// the already selected ones to create a closed contour. + /// \return false in case if no countours have been added. + bool addContour(); }; #endif diff --git a/src/FeaturesPlugin/wire_widget.xml b/src/FeaturesPlugin/wire_widget.xml index a2b8c35a3..2b49cb9d8 100644 --- a/src/FeaturesPlugin/wire_widget.xml +++ b/src/FeaturesPlugin/wire_widget.xml @@ -7,5 +7,8 @@ type_choice="edges objects"> - + -- 2.39.2