From c44cee9c2c5f83a58f172a47037a8d9035e29b94 Mon Sep 17 00:00:00 2001 From: dbv Date: Fri, 15 Apr 2016 12:08:04 +0300 Subject: [PATCH] Issue #1369: Wire feature draft implementation. --- src/FeaturesPlugin/CMakeLists.txt | 3 + src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 5 ++ .../FeaturesPlugin_Validators.cpp | 76 ++++++++++++++++++ .../FeaturesPlugin_Validators.h | 16 ++++ src/FeaturesPlugin/FeaturesPlugin_Wire.cpp | 69 ++++++++++++++++ src/FeaturesPlugin/FeaturesPlugin_Wire.h | 51 ++++++++++++ src/FeaturesPlugin/plugin-Features.xml | 11 ++- src/FeaturesPlugin/wire_widget.xml | 10 +++ src/GeomAlgoAPI/CMakeLists.txt | 2 + src/GeomAlgoAPI/GeomAlgoAPI.i | 1 + src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.cpp | 42 ++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.h | 27 +++++++ src/GeomAlgoAPI/GeomAlgoAPI_swig.h | 1 + src/PartSet/PartSet_IconFactory.cpp | 28 +++---- src/PartSet/PartSet_icons.qrc | 1 + src/PartSet/icons/feature_wire.png | Bin 0 -> 342 bytes 16 files changed, 321 insertions(+), 22 deletions(-) create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Wire.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Wire.h create mode 100644 src/FeaturesPlugin/wire_widget.xml create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.h create mode 100644 src/PartSet/icons/feature_wire.png diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 3f940c5c0..3e9bbfd27 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -26,6 +26,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_RevolutionFuse.h FeaturesPlugin_ValidatorTransform.h FeaturesPlugin_Validators.h + FeaturesPlugin_Wire.h ) SET(PROJECT_SOURCES @@ -50,6 +51,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_RevolutionFuse.cpp FeaturesPlugin_ValidatorTransform.cpp FeaturesPlugin_Validators.cpp + FeaturesPlugin_Wire.cpp ) SET(XML_RESOURCES @@ -68,6 +70,7 @@ SET(XML_RESOURCES placement_widget.xml intersection_widget.xml pipe_widget.xml + wire_widget.xml ) INCLUDE_DIRECTORIES( diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 1de58f332..b83fc3339 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -44,6 +45,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() new FeaturesPlugin_ValidatorPipeLocations); aFactory->registerValidator("FeaturesPlugin_ValidatorCanBeEmpty", new FeaturesPlugin_ValidatorCanBeEmpty); + aFactory->registerValidator("FeaturesPlugin_ValidatorBaseForWire", + new FeaturesPlugin_ValidatorBaseForWire); // register this plugin ModelAPI_Session::get()->registerPlugin(this); @@ -79,6 +82,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(string theFeatureID) return FeaturePtr(new FeaturesPlugin_RevolutionCut); } else if (theFeatureID == FeaturesPlugin_RevolutionFuse::ID()) { return FeaturePtr(new FeaturesPlugin_RevolutionFuse); + } else if (theFeatureID == FeaturesPlugin_Wire::ID()) { + return FeaturePtr(new FeaturesPlugin_Wire); } // feature of such kind is not found return FeaturePtr(); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 0de4d856a..ed019bb64 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -12,9 +12,14 @@ #include #include +#include + #include #include +#include +#include + //================================================================================================= bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, @@ -312,3 +317,74 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& return true; } + +//================================================================================================= +bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + // Get base objects list. + if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) { + Events_Error::send("Validator does not support attribute type \"" + theAttribute->attributeType() + + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId() + "\" supported."); + return false; + } + AttributeSelectionListPtr aSelectionList = std::dynamic_pointer_cast(theAttribute); + if(!aSelectionList.get()) { + theError = "Could not get selection list."; + return false; + } + if(aSelectionList->size() == 0) { + theError = "Empty selection list."; + return false; + } + + // Collect base shapes. + ListOfShape aListOfShapes; + for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + if(!aShape.get()) { + theError = "Empty shape selected."; + return false; + } + + // Check that shape has acceptable type. + if(aShape->shapeType() != GeomAPI_Shape::EDGE && aShape->shapeType() != GeomAPI_Shape::WIRE) { + theError = "Selected shape has wrong type. Only edges and wires acceptable."; + return false; + } + + // Check that it is edge on sketch. + ResultPtr aContext = aSelection->context(); + if(!aContext.get()) { + theError = "Attribute have empty context."; + return false; + } + GeomShapePtr aContextShape = aContext->shape(); + ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aContext); + if(aConstruction.get()) { + std::shared_ptr anEdges = std::dynamic_pointer_cast(aContextShape); + if(!anEdges.get()) { + // It is not an edge on the sketch. + // Check that it is not local selection. + if(!aShape->isEqual(aContextShape)) { + // Local selection on body does not allowed. + theError = "Selected shape is in the local selection. Only global selection is allowed."; + return false; + } + } + } + + aListOfShapes.push_back(aShape); + } + + // Create wire. + GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes); + if(!aWire.get()) { + theError = "Result wire empty. Probably it has disconnected edges or non-manifold."; + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index e02b2ee63..66006583f 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -88,4 +88,20 @@ private: std::string& theError) const; }; +/// \class FeaturesPlugin_ValidatorBaseForWire +/// \ingroup Validators +/// \brief A validator for selection base shapes for wire. Allows to select edges on sketch and +/// wires objects that are connected to already selected shapes. +class FeaturesPlugin_ValidatorBaseForWire: public ModelAPI_AttributeValidator +{ +public: + //! Returns true if attribute is ok. + //! \param[in] theAttribute the checked attribute. + //! \param[in] theArguments arguments of the attribute. + //! \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const; +}; + #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp b/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp new file mode 100644 index 000000000..6764df639 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Wire.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: FeaturesPlugin_Wire.cpp +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#include "FeaturesPlugin_Wire.h" + +#include +#include + +#include + +//================================================================================================= +FeaturesPlugin_Wire::FeaturesPlugin_Wire() +{ +} + +//================================================================================================= +void FeaturesPlugin_Wire::initAttributes() +{ + data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); +} + +//================================================================================================= +void FeaturesPlugin_Wire::execute() +{ + // Get base objects list. + AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); + if(!aSelectionList.get()) { + setError("Error: Could not get selection list."); + return; + } + if(aSelectionList->size() == 0) { + setError("Error: Empty selection list."); + return; + } + + // Collect base shapes. + ListOfShape aListOfShapes; + for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + if(!aShape.get()) { + setError("Error: Empty shape selected."); + return; + } + + if(aShape->shapeType() != GeomAPI_Shape::EDGE && aShape->shapeType() != GeomAPI_Shape::WIRE) { + setError("Error: Selected shape has wrong type. Only edges and wires acceptable."); + return; + } + + aListOfShapes.push_back(aShape); + } + + // Create wire. + GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes); + if(!aWire.get()) { + setError("Error: Result wire empty. Probably it has disconnected edges or non-manifold."); + return; + } + + // Store result. + ResultBodyPtr aResultBody = document()->createBody(data()); + aResultBody->store(aWire); + setResult(aResultBody); +} + diff --git a/src/FeaturesPlugin/FeaturesPlugin_Wire.h b/src/FeaturesPlugin/FeaturesPlugin_Wire.h new file mode 100644 index 000000000..6a265cd1b --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Wire.h @@ -0,0 +1,51 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: FeaturesPlugin_Wire.h +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#ifndef FeaturesPlugin_Wire_H_ +#define FeaturesPlugin_Wire_H_ + +#include "FeaturesPlugin.h" + +#include + +/// \class FeaturesPlugin_Wire +/// \ingroup Plugins +/// \brief Feature for creation of wire from sketch edges or existing wires. +class FeaturesPlugin_Wire: public ModelAPI_Feature +{ +public: + /// Use plugin manager for features creation + FeaturesPlugin_Wire(); + + /// Feature kind. + inline static const std::string& ID() + { + static const std::string MY_ID("Wire"); + return MY_ID; + } + + /// Attribute name of base objects. + inline static const std::string& BASE_OBJECTS_ID() + { + static const std::string MY_BASE_OBJECTS_ID("base_objects"); + return MY_BASE_OBJECTS_ID; + } + + /// \return the kind of a feature. + FEATURESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = FeaturesPlugin_Wire::ID(); + return MY_KIND; + } + + /// Request for initialization of data model of the feature: adding all attributes. + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Creates a new part document if needed. + FEATURESPLUGIN_EXPORT virtual void execute(); +}; + +#endif diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index 1c084821d..0ca6daa42 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -2,13 +2,15 @@ + + + + + - @@ -20,9 +22,6 @@ - diff --git a/src/FeaturesPlugin/wire_widget.xml b/src/FeaturesPlugin/wire_widget.xml new file mode 100644 index 000000000..6db25b19f --- /dev/null +++ b/src/FeaturesPlugin/wire_widget.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 74f73a9bb..84105385f 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -36,6 +36,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_PaveFiller.h GeomAlgoAPI_Intersection.h GeomAlgoAPI_Pipe.h + GeomAlgoAPI_WireBuilder.h ) SET(PROJECT_SOURCES @@ -68,6 +69,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_PaveFiller.cpp GeomAlgoAPI_Intersection.cpp GeomAlgoAPI_Pipe.cpp + GeomAlgoAPI_WireBuilder.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 95fddd512..8c9279226 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -42,6 +42,7 @@ %include "GeomAlgoAPI_PaveFiller.h" %include "GeomAlgoAPI_Intersection.h" %include "GeomAlgoAPI_Pipe.h" +%include "GeomAlgoAPI_WireBuilder.h" %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & { $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr(*$1)), $descriptor(std::shared_ptr *), SWIG_POINTER_OWN | 0 ); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.cpp new file mode 100644 index 000000000..b6b9dec26 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_WireBuilder.cpp +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#include "GeomAlgoAPI_WireBuilder.h" + +#include +#include +#include + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_WireBuilder::wire(const ListOfShape& theShapes) +{ + BRepBuilderAPI_MakeWire aWireBuilder; + + for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { + const TopoDS_Shape& aShape = (*anIt)->impl(); + switch(aShape.ShapeType()) { + case TopAbs_EDGE: { + aWireBuilder.Add(TopoDS::Edge(aShape)); + break; + } + case TopAbs_WIRE: { + aWireBuilder.Add(TopoDS::Wire(aShape)); + break; + } + default: { + return GeomShapePtr(); + } + } + } + + if(aWireBuilder.Error() != BRepBuilderAPI_WireDone) { + return GeomShapePtr(); + } + + GeomShapePtr aResultShape(new GeomAPI_Shape()); + aResultShape->setImpl(new TopoDS_Shape(aWireBuilder.Wire())); + return aResultShape; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.h new file mode 100644 index 000000000..99256bee6 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_WireBuilder.h @@ -0,0 +1,27 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_WireBuilder.h +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_WireBuilder_H_ +#define GeomAlgoAPI_WireBuilder_H_ + +#include "GeomAlgoAPI.h" + +#include + +/// \class GeomAlgoAPI_WireBuilder +/// \ingroup DataAlgo +/// \brief Allows to create wire-shapes by different parameters. +class GeomAlgoAPI_WireBuilder +{ + public: + /// \brief Creates a wire from edges and wires. + /// \param[in] theShapes list of shapes. Only edges and wires allowed. + /// The edges are not to be consecutive. But they are to be all connected geometrically or topologically. + /// \return wire created from theShapes. Empty in case of error or bad input. + GEOMALGOAPI_EXPORT static std::shared_ptr wire(const ListOfShape& theShapes); +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index f82daf66d..92327a03d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -36,6 +36,7 @@ #include "GeomAlgoAPI_PaveFiller.h" #include "GeomAlgoAPI_Intersection.h" #include "GeomAlgoAPI_Pipe.h" + #include "GeomAlgoAPI_WireBuilder.h" #include #include diff --git a/src/PartSet/PartSet_IconFactory.cpp b/src/PartSet/PartSet_IconFactory.cpp index 3926597d2..a76105434 100644 --- a/src/PartSet/PartSet_IconFactory.cpp +++ b/src/PartSet/PartSet_IconFactory.cpp @@ -77,24 +77,20 @@ QIcon PartSet_IconFactory::getIcon(ObjectPtr theObj) ResultPtr aResult = std::dynamic_pointer_cast(theObj); if (aResult.get()) { GeomShapePtr aShape = aResult->shape(); - if (aShape.get()) { - if (aShape->isSolid()) - return QIcon(":pictures/solid.png"); - else if (aShape->isCompound()) - return QIcon(":pictures/compound.png"); - else if (aShape->isCompoundOfSolids()) - return QIcon(":pictures/compoundofsolids.png"); - else if (aShape->isCompSolid()) - return QIcon(":pictures/compsolid.png"); - else if (aShape->isEdge()) - return QIcon(":pictures/edge.png"); - else if (aShape->isFace()) - return QIcon(":pictures/face.png"); - else if (aShape->isVertex()) - return QIcon(":pictures/vertex.png"); + if(aShape.get()) { + switch(aShape->shapeType()) { + case GeomAPI_Shape::COMPOUND: return QIcon(":pictures/compound.png"); + case GeomAPI_Shape::COMPSOLID: return QIcon(":pictures/compsolid.png"); + case GeomAPI_Shape::SOLID: return QIcon(":pictures/solid.png"); + case GeomAPI_Shape::SHELL: return QIcon(":pictures/shell.png"); + case GeomAPI_Shape::FACE: return QIcon(":pictures/face.png"); + case GeomAPI_Shape::WIRE: return QIcon(":pictures/wire.png"); + case GeomAPI_Shape::EDGE: return QIcon(":pictures/edge.png"); + case GeomAPI_Shape::VERTEX: return QIcon(":pictures/vertex.png"); + } } } - return anIcon; + return anIcon; } void PartSet_IconFactory::processEvent(const std::shared_ptr& theMessage) diff --git a/src/PartSet/PartSet_icons.qrc b/src/PartSet/PartSet_icons.qrc index ff09bfce3..fada5b9de 100644 --- a/src/PartSet/PartSet_icons.qrc +++ b/src/PartSet/PartSet_icons.qrc @@ -101,5 +101,6 @@ icons/pipe_simple_32x32.png icons/pipe_binormal_32x32.png icons/pipe_locations_32x32.png + icons/feature_wire.png diff --git a/src/PartSet/icons/feature_wire.png b/src/PartSet/icons/feature_wire.png new file mode 100644 index 0000000000000000000000000000000000000000..87b8556499fd6519fc72e7fcf9fa98f29ec310c0 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR43pu_#?G1mbSmy3nIl*y_*N85Y4AO0+0{={}emCu9q z!JAdp6Qi%mtYGp#@M(FQ)=Ca@2X2og7yJB-FS1?;N&I3d`Mo~)+PcHhhI^Qv%s6na zXWs&o#;FcL-xs$t<+~od*&>&)(CWu5+x^|o+wV7Mel%w~Tw%43eM9Kea~)RoQ@1_I i`1Wv~%``zd>umWKW_