From: dbv Date: Tue, 26 Apr 2016 13:52:00 +0000 (+0300) Subject: Issue #1369: Added "Create Shell" feature. X-Git-Tag: V_2.3.0~98 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4aa37ed1eb429f7391098b5202922d43e85fcc30;p=modules%2Fshaper.git Issue #1369: Added "Create Shell" feature. --- diff --git a/src/BuildPlugin/BuildPlugin_Plugin.cpp b/src/BuildPlugin/BuildPlugin_Plugin.cpp index f11e4ba6e..d834be91f 100644 --- a/src/BuildPlugin/BuildPlugin_Plugin.cpp +++ b/src/BuildPlugin/BuildPlugin_Plugin.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include // the only created instance of this plugin @@ -46,6 +47,8 @@ FeaturePtr BuildPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new BuildPlugin_Wire()); } else if(theFeatureID == BuildPlugin_Face::ID()) { return FeaturePtr(new BuildPlugin_Face()); + } else if(theFeatureID == BuildPlugin_Shell::ID()) { + return FeaturePtr(new BuildPlugin_Shell()); } // Feature of such kind is not found. diff --git a/src/BuildPlugin/BuildPlugin_Shell.cpp b/src/BuildPlugin/BuildPlugin_Shell.cpp new file mode 100644 index 000000000..bb934a25d --- /dev/null +++ b/src/BuildPlugin/BuildPlugin_Shell.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: BuildPlugin_Shell.cpp +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#include "BuildPlugin_Shell.h" + +#include +#include +#include + +#include +#include + +//================================================================================================= +BuildPlugin_Shell::BuildPlugin_Shell() +{ +} + +//================================================================================================= +void BuildPlugin_Shell::initAttributes() +{ + data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()); +} + +//================================================================================================= +void BuildPlugin_Shell::execute() +{ + // Get base objects list. + AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); + + // Collect base shapes. + ListOfShape aShapes; + for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + GeomShapePtr aShape = aSelection->value(); + if(!aShape.get()) { + aShape = aSelection->context()->shape(); + } + aShapes.push_back(aShape); + } + + // Sew faces. + GeomAlgoAPI_Sewing aSewingAlgo(aShapes); + + // Check that algo is done. + if(!aSewingAlgo.isDone()) { + setError("Error: " + getKind() + " algorithm failed."); + return; + } + + // Check if shape is not null. + if(!aSewingAlgo.shape().get() || aSewingAlgo.shape()->isNull()) { + setError("Error: Resulting shape is null."); + return; + } + + // Check that resulting shape is valid. + if(!aSewingAlgo.isValid()) { + setError("Error: Resulting shape is not valid."); + return; + } + + // Store result. + GeomShapePtr aResult = aSewingAlgo.shape(); + std::shared_ptr aMapOfShapes = aSewingAlgo.mapOfSubShapes(); + + int anIndex = 0; + for(GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::SHELL); anExp.more(); anExp.next()) { + GeomShapePtr aShell = anExp.current(); + ResultBodyPtr aResultBody = document()->createBody(data(), anIndex); + aResultBody->store(aShell); + for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) { + for(GeomAPI_ShapeExplorer aFaceExp(*anIt, GeomAPI_Shape::FACE); aFaceExp.more(); aFaceExp.next()) { + GeomShapePtr aFace = aFaceExp.current(); + ListOfShape aHistory; + aSewingAlgo.modified(aFace, aHistory); + for(ListOfShape::const_iterator aHistoryIt = aHistory.cbegin(); + aHistoryIt != aHistory.cend(); + ++aHistoryIt) { + if(aShell->isSubShape(*aHistoryIt)) { + aResultBody->loadAndOrientModifiedShapes(&aSewingAlgo, aFace, GeomAPI_Shape::EDGE, + 1, "Modified", *aMapOfShapes.get()); + } + } + } + } + setResult(aResultBody, anIndex); + ++anIndex; + } + + removeResults(anIndex); +} diff --git a/src/BuildPlugin/BuildPlugin_Shell.h b/src/BuildPlugin/BuildPlugin_Shell.h new file mode 100644 index 000000000..be6341597 --- /dev/null +++ b/src/BuildPlugin/BuildPlugin_Shell.h @@ -0,0 +1,51 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: BuildPlugin_Shell.h +// Created: 14 April 2016 +// Author: Dmitry Bobylev + +#ifndef BuildPlugin_Shell_H_ +#define BuildPlugin_Shell_H_ + +#include "BuildPlugin.h" + +#include + +/// \class BuildPlugin_Shell +/// \ingroup Plugins +/// \brief Feature for creation of shell from faces and shells. +class BuildPlugin_Shell: public ModelAPI_Feature +{ +public: + /// Use plugin manager for features creation + BuildPlugin_Shell(); + + /// Feature kind. + inline static const std::string& ID() + { + static const std::string MY_ID("Shell"); + 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. + BUILDPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = BuildPlugin_Shell::ID(); + return MY_KIND; + } + + /// Request for initialization of data model of the feature: adding all attributes. + BUILDPLUGIN_EXPORT virtual void initAttributes(); + + /// Creates a new part document if needed. + BUILDPLUGIN_EXPORT virtual void execute(); +}; + +#endif diff --git a/src/BuildPlugin/BuildPlugin_Wire.cpp b/src/BuildPlugin/BuildPlugin_Wire.cpp index 439b082b0..523c81a03 100644 --- a/src/BuildPlugin/BuildPlugin_Wire.cpp +++ b/src/BuildPlugin/BuildPlugin_Wire.cpp @@ -148,13 +148,6 @@ bool BuildPlugin_Wire::addContour() AttributeSelectionPtr aSelection = *aListIt; std::shared_ptr anEdgeInList(new GeomAPI_Edge(aSelection->value())); - ListOfShape::const_iterator anEdgesIt = anAddedEdges.cbegin(); - for(; anEdgesIt != anAddedEdges.cend(); ++anEdgesIt) { - if(anEdgeInList->isEqual(*anEdgesIt)) { - break; - } - } - ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSelection->context()); std::shared_ptr aPlanarEdges = std::dynamic_pointer_cast(aConstruction->shape()); @@ -179,7 +172,7 @@ bool BuildPlugin_Wire::addContour() if(aFoundFace.get()) { for(GeomAPI_ShapeExplorer anExp(aFoundFace, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { std::shared_ptr anEdgeOnFace(new GeomAPI_Edge(anExp.current())); - anEdgesIt = anAddedEdges.cbegin(); + ListOfShape::const_iterator anEdgesIt = anAddedEdges.cbegin(); for(; anEdgesIt != anAddedEdges.cend(); ++anEdgesIt) { if(anEdgeOnFace->isEqual(*anEdgesIt)) { break; diff --git a/src/BuildPlugin/CMakeLists.txt b/src/BuildPlugin/CMakeLists.txt index a2ada0459..0a7cda8f9 100644 --- a/src/BuildPlugin/CMakeLists.txt +++ b/src/BuildPlugin/CMakeLists.txt @@ -18,6 +18,7 @@ SET(PROJECT_HEADERS BuildPlugin_Edge.h BuildPlugin_Wire.h BuildPlugin_Face.h + BuildPlugin_Shell.h BuildPlugin_Validators.h ) @@ -27,6 +28,7 @@ SET(PROJECT_SOURCES BuildPlugin_Edge.cpp BuildPlugin_Wire.cpp BuildPlugin_Face.cpp + BuildPlugin_Shell.cpp BuildPlugin_Validators.cpp ) @@ -36,6 +38,7 @@ SET(XML_RESOURCES edge_widget.xml wire_widget.xml face_widget.xml + shell_widget.xml ) SET(PROJECT_LIBRARIES diff --git a/src/BuildPlugin/icons/feature_shell.png b/src/BuildPlugin/icons/feature_shell.png new file mode 100644 index 000000000..5144ea8d0 Binary files /dev/null and b/src/BuildPlugin/icons/feature_shell.png differ diff --git a/src/BuildPlugin/plugin-Build.xml b/src/BuildPlugin/plugin-Build.xml index cfa04ecf0..362eb118f 100644 --- a/src/BuildPlugin/plugin-Build.xml +++ b/src/BuildPlugin/plugin-Build.xml @@ -9,12 +9,15 @@ - + - + + + + diff --git a/src/BuildPlugin/shell_widget.xml b/src/BuildPlugin/shell_widget.xml new file mode 100644 index 000000000..fc4bca3c5 --- /dev/null +++ b/src/BuildPlugin/shell_widget.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index cba5be5ce..1c97ef8b4 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +251,26 @@ std::string GeomAPI_Shape::shapeTypeStr() const return aShapeTypeStr; } +bool GeomAPI_Shape::isSubShape(const std::shared_ptr theShape) const +{ + if(!theShape.get()) { + return false; + } + + const TopoDS_Shape& aShapeToSearch = theShape->impl(); + if(aShapeToSearch.IsNull()) { + return false; + } + + for(TopExp_Explorer anExp(*MY_SHAPE, aShapeToSearch.ShapeType()); anExp.More(); anExp.Next()) { + if(aShapeToSearch.IsEqual(anExp.Current())) { + return true; + } + } + + return false; +} + bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmin, double& theXmax, double& theYmax, double& theZmax) const { diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 7adf4da80..1ed86db9c 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -78,6 +78,11 @@ public: GEOMAPI_EXPORT virtual std::string shapeTypeStr() const; + /// \return true if passed shape is a sub-shape of this shape. + /// \param theShape shape to search. + GEOMAPI_EXPORT virtual bool isSubShape(const std::shared_ptr theShape) const; + + /// Computes boundary dimensions of the shape /// Returns False if it is not possible GEOMAPI_EXPORT diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 84105385f..e765913a8 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -37,6 +37,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Intersection.h GeomAlgoAPI_Pipe.h GeomAlgoAPI_WireBuilder.h + GeomAlgoAPI_Sewing.h ) SET(PROJECT_SOURCES @@ -70,6 +71,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Intersection.cpp GeomAlgoAPI_Pipe.cpp GeomAlgoAPI_WireBuilder.cpp + GeomAlgoAPI_Sewing.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 8c9279226..e4efaa2ba 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -43,6 +43,7 @@ %include "GeomAlgoAPI_Intersection.h" %include "GeomAlgoAPI_Pipe.h" %include "GeomAlgoAPI_WireBuilder.h" +%include "GeomAlgoAPI_Sewing.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_Sewing.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp new file mode 100644 index 000000000..4539b0863 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Sewing.cpp +// Created: 25 April 2016 +// Author: Dmitry Bobylev + + +#include "GeomAlgoAPI_Sewing.h" + +#include +#include +#include +#include +#include +#include + +//================================================================================================== +GeomAlgoAPI_Sewing::GeomAlgoAPI_Sewing(const ListOfShape& theShapes) +{ + build(theShapes); +} + +void GeomAlgoAPI_Sewing::build(const ListOfShape& theShapes) +{ + if(theShapes.empty()) { + return; + } + + BRepBuilderAPI_Sewing* aSewingBuilder = new BRepBuilderAPI_Sewing(); + this->setImpl(aSewingBuilder); + + for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) { + const TopoDS_Shape& aShape = (*anIt)->impl(); + aSewingBuilder->Add(aShape); + } + + aSewingBuilder->Perform(); + + TopoDS_Shape aResult = aSewingBuilder->SewedShape(); + BRep_Builder aBuilder; + TopoDS_Compound aResultCompound; + aBuilder.MakeCompound(aResultCompound); + for(TopoDS_Iterator anIt(aResult); anIt.More(); anIt.Next()) { + const TopoDS_Shape aSubShape = anIt.Value(); + if(aSubShape.ShapeType() == TopAbs_SHELL) { + aBuilder.Add(aResultCompound, aSubShape); + } else if (aSubShape.ShapeType() == TopAbs_FACE) { + TopoDS_Shell aShell; + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, aSubShape); + aBuilder.Add(aResultCompound, aShell); + } + } + TopoDS_Iterator anIt(aResultCompound); + if(anIt.More()) { + aResult = aResultCompound; + } + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + this->setShape(aShape); + this->setDone(true); +} + +//================================================================================================== +void GeomAlgoAPI_Sewing::modified(const std::shared_ptr theShape, + ListOfShape& theHistory) +{ + static int anIndex = 0; + if(!theShape.get()) { + return; + } + + const TopoDS_Shape& aShape = theShape->impl(); + const BRepBuilderAPI_Sewing& aSewingBuilder = this->impl(); + + TopoDS_Shape aModifiedShape = aSewingBuilder.Modified(aShape); + if(aModifiedShape.IsEqual(aShape)) { + aModifiedShape = aSewingBuilder.ModifiedSubShape(aShape); + } + + for(TopExp_Explorer anExp(aModifiedShape, aShape.ShapeType()); anExp.More(); anExp.Next()) { + GeomShapePtr aGeomShape(new GeomAPI_Shape()); + aGeomShape->setImpl(new TopoDS_Shape(anExp.Current())); + theHistory.push_back(aGeomShape); + } +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h new file mode 100644 index 000000000..aa11b861e --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h @@ -0,0 +1,35 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: GeomAlgoAPI_Sewing.h +// Created: 25 April 2016 +// Author: Dmitry Bobylev + +#ifndef GeomAlgoAPI_Sewing_H_ +#define GeomAlgoAPI_Sewing_H_ + +#include "GeomAlgoAPI.h" +#include "GeomAlgoAPI_MakeShape.h" + +#include + +/// \class GeomAlgoAPI_Sewing +/// \ingroup DataAlgo +/// \brief Allows creation of connected topology (shells) from a set of separate topological elements (faces). +class GeomAlgoAPI_Sewing : public GeomAlgoAPI_MakeShape +{ +public: + /// Constructor. + GEOMALGOAPI_EXPORT GeomAlgoAPI_Sewing(const ListOfShape& theShapes); + + /// \return the list of shapes modified from the shape \a theShape. + /// \param[in] theShape base shape. + /// \param[out] theHistory modified shapes. + GEOMALGOAPI_EXPORT virtual void modified(const std::shared_ptr theShape, + ListOfShape& theHistory); + +private: + /// Builds resulting shape. + void build(const ListOfShape& theShapes); +}; + +#endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h index 92327a03d..3cf49122d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_swig.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_swig.h @@ -37,7 +37,8 @@ #include "GeomAlgoAPI_Intersection.h" #include "GeomAlgoAPI_Pipe.h" #include "GeomAlgoAPI_WireBuilder.h" - + #include "GeomAlgoAPI_Sewing.h" + #include #include #include