From dadc434ff48893c2334461b325c096935b784436 Mon Sep 17 00:00:00 2001 From: Clarisse Genrault Date: Wed, 11 Sep 2019 09:28:48 +0200 Subject: [PATCH] Add Chamfer feature --- src/FeaturesAPI/CMakeLists.txt | 2 + src/FeaturesAPI/FeaturesAPI.i | 2 + src/FeaturesAPI/FeaturesAPI_Chamfer.cpp | 133 ++++++++++ src/FeaturesAPI/FeaturesAPI_Chamfer.h | 107 ++++++++ src/FeaturesAPI/FeaturesAPI_swig.h | 1 + src/FeaturesPlugin/CMakeLists.txt | 3 + src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp | 235 ++++++++++++++++++ src/FeaturesPlugin/FeaturesPlugin_Chamfer.h | 123 +++++++++ src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 3 + src/FeaturesPlugin/chamfer_widget.xml | 63 +++++ src/FeaturesPlugin/icons/chamfer.png | Bin 0 -> 566 bytes .../icons/chamfer_dist_angle.png | 0 .../icons/chamfer_distances.png | 0 src/FeaturesPlugin/plugin-Features.xml | 4 + src/GeomAlgoAPI/CMakeLists.txt | 3 +- src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp | 95 +++++++ src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h | 66 +++++ src/PythonAPI/model/features/__init__.py | 2 +- 18 files changed, 840 insertions(+), 2 deletions(-) create mode 100644 src/FeaturesAPI/FeaturesAPI_Chamfer.cpp create mode 100644 src/FeaturesAPI/FeaturesAPI_Chamfer.h create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp create mode 100644 src/FeaturesPlugin/FeaturesPlugin_Chamfer.h create mode 100644 src/FeaturesPlugin/chamfer_widget.xml create mode 100644 src/FeaturesPlugin/icons/chamfer.png create mode 100644 src/FeaturesPlugin/icons/chamfer_dist_angle.png create mode 100644 src/FeaturesPlugin/icons/chamfer_distances.png create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h diff --git a/src/FeaturesAPI/CMakeLists.txt b/src/FeaturesAPI/CMakeLists.txt index 9311f491d..acd6222f5 100644 --- a/src/FeaturesAPI/CMakeLists.txt +++ b/src/FeaturesAPI/CMakeLists.txt @@ -26,6 +26,7 @@ SET(PROJECT_HEADERS FeaturesAPI_BooleanCommon.h FeaturesAPI_BooleanSmash.h FeaturesAPI_BooleanFill.h + FeaturesAPI_Chamfer.h FeaturesAPI_Extrusion.h FeaturesAPI_ExtrusionBoolean.h FeaturesAPI_Fillet.h @@ -55,6 +56,7 @@ SET(PROJECT_SOURCES FeaturesAPI_BooleanCommon.cpp FeaturesAPI_BooleanSmash.cpp FeaturesAPI_BooleanFill.cpp + FeaturesAPI_Chamfer.cpp FeaturesAPI_Extrusion.cpp FeaturesAPI_ExtrusionBoolean.cpp FeaturesAPI_Fillet.cpp diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index 35bdfcefc..a1a7fbe1f 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -43,6 +43,7 @@ %shared_ptr(FeaturesAPI_BooleanCommon) %shared_ptr(FeaturesAPI_BooleanSmash) %shared_ptr(FeaturesAPI_BooleanFill) +%shared_ptr(FeaturesAPI_Chamfer) %shared_ptr(FeaturesAPI_Extrusion) %shared_ptr(FeaturesAPI_ExtrusionBoolean) %shared_ptr(FeaturesAPI_ExtrusionCut) @@ -74,6 +75,7 @@ %include "FeaturesAPI_BooleanCommon.h" %include "FeaturesAPI_BooleanSmash.h" %include "FeaturesAPI_BooleanFill.h" +%include "FeaturesAPI_Chamfer.h" %include "FeaturesAPI_Extrusion.h" %include "FeaturesAPI_ExtrusionBoolean.h" %include "FeaturesAPI_Fillet.h" diff --git a/src/FeaturesAPI/FeaturesAPI_Chamfer.cpp b/src/FeaturesAPI/FeaturesAPI_Chamfer.cpp new file mode 100644 index 000000000..a898a3c36 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_Chamfer.cpp @@ -0,0 +1,133 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesAPI_Chamfer.h" + +#include +#include +#include + +FeaturesAPI_Chamfer::FeaturesAPI_Chamfer(const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + +FeaturesAPI_Chamfer::FeaturesAPI_Chamfer(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const bool performDistances, + const ModelHighAPI_Double& theVal1, + const ModelHighAPI_Double& theVal2) + : ModelHighAPI_Interface(theFeature) +{ + if (initialize()) { + fillAttribute(theBaseObjects, mybaseObjects); + if (performDistances) { + fillAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_DISTANCE(), mycreationMethod); + fillAttribute(theVal1, myd1); + fillAttribute(theVal2, myd2); + } else { + fillAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_ANGLE(), mycreationMethod); + fillAttribute(theVal1, myd); + fillAttribute(theVal2, myangle); + } + + execIfBaseNotEmpty(); + } +} + +FeaturesAPI_Chamfer::~FeaturesAPI_Chamfer() +{ +} + +//================================================================================================== +void FeaturesAPI_Chamfer::setBase(const std::list& theBaseObjects) +{ + mybaseObjects->clear(); + fillAttribute(theBaseObjects, mybaseObjects); + + execIfBaseNotEmpty(); +} + +void FeaturesAPI_Chamfer::setDistances(const ModelHighAPI_Double& theD1, + const ModelHighAPI_Double& theD2) +{ + fillAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_DISTANCE(), mycreationMethod); + fillAttribute(theD1, myd1); + fillAttribute(theD2, myd2); + + execIfBaseNotEmpty(); +} + +void FeaturesAPI_Chamfer::setDistAngle(const ModelHighAPI_Double& theDistance, + const ModelHighAPI_Double& theAngle) +{ + fillAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_ANGLE(), mycreationMethod); + fillAttribute(theDistance, myd); + fillAttribute(theAngle, myangle); + + execIfBaseNotEmpty(); +} + +void FeaturesAPI_Chamfer::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionListPtr anAttrObjects = + aBase->selectionList(FeaturesPlugin_Chamfer::OBJECT_LIST_ID()); + + std::cout << "dump" << std::endl; + + theDumper << aBase << " = model.addChamfer(" << aDocName << ", " << anAttrObjects; + + std::string aCreationMethod = aBase->string(FeaturesPlugin_Chamfer::CREATION_METHOD())->value(); + + if(aCreationMethod == FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_DISTANCE()) { + AttributeDoublePtr anAttrD1 = aBase->real(FeaturesPlugin_Chamfer::D1_ID()); + AttributeDoublePtr anAttrD2 = aBase->real(FeaturesPlugin_Chamfer::D2_ID()); + theDumper << ", True, " << anAttrD1 << ", " << anAttrD2; + } else if(aCreationMethod == FeaturesPlugin_Chamfer::CREATION_METHOD_DISTANCE_ANGLE()) { + AttributeDoublePtr anAttrD = aBase->real(FeaturesPlugin_Chamfer::D_ID()); + AttributeDoublePtr anAttrAngle = aBase->real(FeaturesPlugin_Chamfer::ANGLE_ID()); + theDumper << ", False, " << anAttrD << ", " << anAttrAngle; + } + + theDumper << ")" << std::endl; +} + +void FeaturesAPI_Chamfer::execIfBaseNotEmpty() +{ + if (mybaseObjects->size() > 0) + execute(); +} + + +//================================================================================================== + +ChamferPtr addChamfer(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const bool performDistances, + const ModelHighAPI_Double& theVal1, + const ModelHighAPI_Double& theVal2) +{ + std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Chamfer::ID()); + return ChamferPtr(new FeaturesAPI_Chamfer(aFeature, theBaseObjects, performDistances, + theVal1, theVal2)); +} diff --git a/src/FeaturesAPI/FeaturesAPI_Chamfer.h b/src/FeaturesAPI/FeaturesAPI_Chamfer.h new file mode 100644 index 000000000..3baf2dde9 --- /dev/null +++ b/src/FeaturesAPI/FeaturesAPI_Chamfer.h @@ -0,0 +1,107 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeaturesAPI_Chamfer_H_ +#define FeaturesAPI_Chamfer_H_ + +#include "FeaturesAPI.h" + +#include + +#include +#include + +class ModelHighAPI_Double; +class ModelHighAPI_Selection; + +/// \class FeaturesAPI_Chamfer +/// \ingroup CPPHighAPI +/// \brief Interface for Chamfer feature. +class FeaturesAPI_Chamfer: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Chamfer(const std::shared_ptr& theFeature); + + /// Constructor with values. + FEATURESAPI_EXPORT + explicit FeaturesAPI_Chamfer(const std::shared_ptr& theFeature, + const std::list& theBaseObjects, + const bool performDistances, + const ModelHighAPI_Double& aVal1, + const ModelHighAPI_Double& aVal2); + + /// Destructor. + FEATURESAPI_EXPORT + virtual ~FeaturesAPI_Chamfer(); + + INTERFACE_6(FeaturesPlugin_Chamfer::ID(), + creationMethod, FeaturesPlugin_Chamfer::CREATION_METHOD(), + ModelAPI_AttributeString, + /** Creation method */, + baseObjects, FeaturesPlugin_Chamfer::OBJECT_LIST_ID(), + ModelAPI_AttributeSelectionList, + /** Base objects */, + d1, FeaturesPlugin_Chamfer::D1_ID(), + ModelAPI_AttributeDouble, + /** Value of the first distance chamfer */, + d2, FeaturesPlugin_Chamfer::D2_ID(), + ModelAPI_AttributeDouble, + /** Value of the second distance chamfer */, + d, FeaturesPlugin_Chamfer::D_ID(), + ModelAPI_AttributeDouble, + /** Value of the distance chamfer */, + angle, FeaturesPlugin_Chamfer::ANGLE_ID(), + ModelAPI_AttributeDouble, + /** Angle chamfer */) + + /// Modify base objects of the chamfer. + FEATURESAPI_EXPORT + void setBase(const std::list& theBaseObjects); + + /// Modify chamfer to have two distances + FEATURESAPI_EXPORT + void setDistances(const ModelHighAPI_Double& theD1, const ModelHighAPI_Double& theD2); + + /// Modify chamfer to have distance and angle + FEATURESAPI_EXPORT + void setDistAngle(const ModelHighAPI_Double& theDistance, const ModelHighAPI_Double& theAngle); + + /// Dump wrapped feature + FEATURESAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; + +private: + void execIfBaseNotEmpty(); +}; + +/// Pointer on Chamfer object. +typedef std::shared_ptr ChamferPtr; + +/// \ingroup CPPHighAPI +/// \brief Create Chamfer feature. +FEATURESAPI_EXPORT +ChamferPtr addChamfer(const std::shared_ptr& thePart, + const std::list& theBaseObjects, + const bool performDistances, + const ModelHighAPI_Double& theVal1, + const ModelHighAPI_Double& theVal2); + +#endif // FeaturesAPI_Chamfer_H_ diff --git a/src/FeaturesAPI/FeaturesAPI_swig.h b/src/FeaturesAPI/FeaturesAPI_swig.h index f427c3f7d..cd71216fa 100644 --- a/src/FeaturesAPI/FeaturesAPI_swig.h +++ b/src/FeaturesAPI/FeaturesAPI_swig.h @@ -28,6 +28,7 @@ #include "FeaturesAPI_BooleanCommon.h" #include "FeaturesAPI_BooleanSmash.h" #include "FeaturesAPI_BooleanFill.h" + #include "FeaturesAPI_Chamfer.h" #include "FeaturesAPI_Extrusion.h" #include "FeaturesAPI_ExtrusionBoolean.h" #include "FeaturesAPI_Fillet.h" diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 224e94084..5adf4e878 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -60,6 +60,7 @@ SET(PROJECT_HEADERS FeaturesPlugin_Measurement.h FeaturesPlugin_FusionFaces.h FeaturesPlugin_RemoveResults.h + FeaturesPlugin_Chamfer.h ) SET(PROJECT_SOURCES @@ -101,6 +102,7 @@ SET(PROJECT_SOURCES FeaturesPlugin_Measurement.cpp FeaturesPlugin_FusionFaces.cpp FeaturesPlugin_RemoveResults.cpp + FeaturesPlugin_Chamfer.cpp ) SET(XML_RESOURCES @@ -132,6 +134,7 @@ SET(XML_RESOURCES fillet_widget.xml measurement_widget.xml fusion_faces_widget.xml + chamfer_widget.xml ) SET(TEXT_RESOURCES diff --git a/src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp b/src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp new file mode 100644 index 000000000..47ebd45f1 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "FeaturesPlugin_Chamfer.h" +#include "FeaturesPlugin_Tools.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +// Obtain all sub-shapes from the shape and append them to the list +static void collectSubs(const GeomShapePtr& theShape, + ListOfShape& theSubs, + const GeomAPI_Shape::ShapeType theShapeType) +{ + GeomAPI_ShapeExplorer anExp(theShape, theShapeType); + for (; anExp.more(); anExp.next()) { + GeomShapePtr aShape = anExp.current(); + // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices + aShape->setOrientation(GeomAPI_Shape::FORWARD); + theSubs.push_back(aShape); + } +} + +// Extract edges from the list +static ListOfShape selectEdges(const ListOfShape& theShapes) +{ + ListOfShape anEdges; + for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt) + if ((*anIt)->isEdge()) + anEdges.push_back(*anIt); + return anEdges; +} + +// If theShape is a compound of a single sub-shape, return this sub-shape +static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape) +{ + GeomShapePtr aShape = theShape; + if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) { + int aSubResultsNb = 0; + GeomAPI_ShapeIterator anIt(aShape); + for(; anIt.more(); anIt.next()) + ++aSubResultsNb; + + if(aSubResultsNb == 1) { + anIt.init(aShape); + aShape = anIt.current(); + } + } + return aShape; +} + + +FeaturesPlugin_Chamfer::FeaturesPlugin_Chamfer() +{ +} + +void FeaturesPlugin_Chamfer::initAttributes() +{ + data()->addAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(FeaturesPlugin_Chamfer::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(FeaturesPlugin_Chamfer::D1_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Chamfer::D2_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Chamfer::D_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(FeaturesPlugin_Chamfer::ANGLE_ID(), ModelAPI_AttributeDouble::typeId()); +} + + +void FeaturesPlugin_Chamfer::execute() +{ + AttributeStringPtr aCreationMethod = string(CREATION_METHOD()); + if (!aCreationMethod) + return; + + std::list > aSolidsAndSubs; + std::map aMapEdgeFace; + + // getting objects and sort them according to parent solids + AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID()); + for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) { + AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); + GeomShapePtr anObject = anObjectAttr->value(); + if (!anObject) + return; + + ResultPtr aContext = anObjectAttr->context(); + GeomShapePtr aParent; + if (aContext.get()) { + ResultBodyPtr aCtxOwner = ModelAPI_Tools::bodyOwner(aContext); + aParent = aCtxOwner ? aCtxOwner->shape() : aContext->shape(); + } else { // get it from a feature + FeaturePtr aFeature = anObjectAttr->contextFeature(); + if (aFeature.get()) { + aParent = aFeature->firstResult()->shape(); + } + } + if (!aParent) + return; + + // searching this parent is already in the list aSolidsAndSubs + std::list >::iterator aSearch = aSolidsAndSubs.begin(); + ListOfShape* aFound; + for(; aSearch != aSolidsAndSubs.end(); aSearch++) { + if (aSearch->first->isSame(aParent)) { + aFound = &(aSearch->second); + break; + } + } + if (aSearch == aSolidsAndSubs.end()) { // not found, so, add a new one + aSolidsAndSubs.push_back(std::pair(aParent, ListOfShape())); + aFound = &(aSolidsAndSubs.back().second); + } + + ListOfShape anEdgesAndVertices; + collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE); + collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX); + for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin(); + aEIt != anEdgesAndVertices.end(); ++aEIt) + aFound->push_back(*aEIt); + + if (anObject->isFace()) { + for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin(); + aEIt != anEdgesAndVertices.end(); ++aEIt) { + if ((*aEIt)->isEdge()) { + aMapEdgeFace[(*aEIt)] = anObject; + } + } + } + } + + //bool isOption1 = true; + double aD1 = 0.0, aD2 = 0.0, aD = 0.0, anAngle = 0.0; + if (aCreationMethod->value() == CREATION_METHOD_DISTANCE_DISTANCE()) { + aD1 = real(FeaturesPlugin_Chamfer::D1_ID())->value(); + aD2 = real(FeaturesPlugin_Chamfer::D2_ID())->value(); + } else { + aD = real(FeaturesPlugin_Chamfer::D_ID())->value(); + anAngle = real(FeaturesPlugin_Chamfer::ANGLE_ID())->value(); + } + + // Perform chamfer operation + GeomAlgoAPI_MakeShapeList aMakeShapeList; + std::shared_ptr aChamferBuilder; + int aResultIndex = 0; + std::string anError; + + + std::vector aResultBaseAlgoList; + ListOfShape anOriginalShapesList, aResultShapesList; + + std::list >::iterator anIt = aSolidsAndSubs.begin(); + for (; anIt != aSolidsAndSubs.end(); ++anIt) { + GeomShapePtr aSolid = anIt->first; + ListOfShape aFilletEdgesAndVertices = anIt->second; + + ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices); + if (aCreationMethod->value() == CREATION_METHOD_DISTANCE_DISTANCE()) { + aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(aSolid, aFilletEdges, aMapEdgeFace, true, aD1, aD2)); + } else { + aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(aSolid, aFilletEdges, aMapEdgeFace, false, aD, anAngle)); + } + + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aChamferBuilder, getKind(), anError)) { + setError(anError); + return; + } + + GeomShapePtr aResult = unwrapCompound(aChamferBuilder->shape()); + std::shared_ptr aResultBody = + document()->createBody(data(), aResultIndex); + + ListOfShape aBaseShapes; + aBaseShapes.push_back(aSolid); + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(), + aChamferBuilder, aResult, "Chamfer"); + + setResult(aResultBody, aResultIndex); + aResultIndex++; + + FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = aSolid; + aRBA.makeShape = aChamferBuilder; + aResultBaseAlgoList.push_back(aRBA); + aResultShapesList.push_back(aResult); + anOriginalShapesList.push_back(aSolid); + + const std::string aFilletFaceName = "Chamfer"; + ListOfShape::iterator aSelectedBase = aFilletEdges.begin(); + for(; aSelectedBase != aFilletEdges.end(); aSelectedBase++) { + GeomShapePtr aBase = *aSelectedBase; + // Store new faces generated from edges and vertices + aResultBody->loadGeneratedShapes( + aChamferBuilder, aBase, GeomAPI_Shape::EDGE, aFilletFaceName, true); + } + } + + // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one + // result shape has been deleted, but in another it was modified or stayed. + GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); + FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + anOriginalShapesList, aResultShapesCompound); + + removeResults(aResultIndex); +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Chamfer.h b/src/FeaturesPlugin/FeaturesPlugin_Chamfer.h new file mode 100644 index 000000000..cad7204e9 --- /dev/null +++ b/src/FeaturesPlugin/FeaturesPlugin_Chamfer.h @@ -0,0 +1,123 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef FeaturesPlugin_Chamfer_H_ +#define FeaturesPlugin_Chamfer_H_ + +#include "FeaturesPlugin.h" + +#include + +#include + +class GeomAlgoAPI_MakeShape; +class GeomAPI_DataMapOfShapeMapOfShapes; + +/// \class FeaturesPlugin_Chamfer +/// \ingroup Plugins +/// \brief Feature for applying the Chamfer operations on Solids. +/// Supports two distances chamfer and distance-angle chamfer. +class FeaturesPlugin_Chamfer : public ModelAPI_Feature +{ +public: + /// Feature kind. + inline static const std::string& ID() + { + static const std::string MY_ID("Chamfer"); + return MY_ID; + } + + /// \return the kind of a feature. + FEATURESPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = FeaturesPlugin_Chamfer::ID(); + return MY_KIND; + } + + inline static const std::string& CREATION_METHOD() + { + static std::string MY_CREATION_METHOD("creation_method"); + return MY_CREATION_METHOD; + } + + inline static const std::string CREATION_METHOD_DISTANCE_DISTANCE() + { + static std::string MY_SINGLE_RADIUS("distance_distance"); + return MY_SINGLE_RADIUS; + } + + inline static const std::string CREATION_METHOD_DISTANCE_ANGLE() + { + static std::string MY_VARYING_RADIUS("distance_angle"); + return MY_VARYING_RADIUS; + } + + /// Attribute name of main objects. + inline static const std::string& OBJECT_LIST_ID() + { + static const std::string MY_OBJECT_LIST_ID("main_objects"); + return MY_OBJECT_LIST_ID; + } + + /// Attribute name of D1. + inline static const std::string& D1_ID() + { + static const std::string MY_D1_ID("d1"); + return MY_D1_ID; + } + + /// Attribute name of D2. + inline static const std::string& D2_ID() + { + static const std::string MY_D2_ID("d2"); + return MY_D2_ID; + } + + /// Attribute name of D. + inline static const std::string& D_ID() + { + static const std::string MY_D_ID("d"); + return MY_D_ID; + } + + /// Attribute name of Angle. + inline static const std::string& ANGLE_ID() + { + static const std::string MY_ANGLE_ID("angle"); + return MY_ANGLE_ID; + } + + /// Creates a new part document if needed. + FEATURESPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes. + FEATURESPLUGIN_EXPORT virtual void initAttributes(); + + /// Use plugin manager for features creation. + FeaturesPlugin_Chamfer(); + +private: + /// Load Naming data structure of the feature to the document + void loadNamingDS(std::shared_ptr theResultBody, + const std::shared_ptr theBaseShape, + const std::shared_ptr theResultShape, + const std::shared_ptr& theMakeShape); +}; + +#endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index 87db42a87..797343446 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID) return FeaturePtr(new FeaturesPlugin_Measurement); } else if (theFeatureID == FeaturesPlugin_RemoveResults::ID()) { return FeaturePtr(new FeaturesPlugin_RemoveResults); + } else if (theFeatureID == FeaturesPlugin_Chamfer::ID()) { + return FeaturePtr(new FeaturesPlugin_Chamfer); } // feature of such kind is not found diff --git a/src/FeaturesPlugin/chamfer_widget.xml b/src/FeaturesPlugin/chamfer_widget.xml new file mode 100644 index 000000000..ae881d55a --- /dev/null +++ b/src/FeaturesPlugin/chamfer_widget.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FeaturesPlugin/icons/chamfer.png b/src/FeaturesPlugin/icons/chamfer.png new file mode 100644 index 0000000000000000000000000000000000000000..3b5a98289beb35c659debbc7cecde2e9f7a62c56 GIT binary patch literal 566 zcmV-60?GY}P)! ztFQjYm*@9;{_yY$tu+9F=ukv!odw!y9UJs#f%t^5AC>0bECL9vHG$|*#8B#0YV2Xb z>+zo7P1P-Hb>`{)waoR5&$eZCspKo%o9zvKtF%p(-@ZeM;mL^y-?Jm>qspbb z8}F7a^P%ym_h;1@5dOZadY{Sw_93@f9KD!dzZL#+_@Gg5N|uU8-d~=+w5b4|O-}8G zG++WXz_cvOSYBBvoK8Itzr68op||Tt7~oV#r5m)CEw&2a0N??9N-6)jVDQSs_>
B1F``-7U&(pp8QLL{}MFkH#Rpu0>7LJns7Xs z=mF8+xWbkL-W^XSdTORMP@d1^{`432iMUXn&*T8M0e7sJ=nH<%umAu607*qoM6N<$ Ef{(!iF#rGn literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/icons/chamfer_dist_angle.png b/src/FeaturesPlugin/icons/chamfer_dist_angle.png new file mode 100644 index 000000000..e69de29bb diff --git a/src/FeaturesPlugin/icons/chamfer_distances.png b/src/FeaturesPlugin/icons/chamfer_distances.png new file mode 100644 index 000000000..e69de29bb diff --git a/src/FeaturesPlugin/plugin-Features.xml b/src/FeaturesPlugin/plugin-Features.xml index f7f414e98..65c1a1e45 100644 --- a/src/FeaturesPlugin/plugin-Features.xml +++ b/src/FeaturesPlugin/plugin-Features.xml @@ -106,6 +106,10 @@ icon="icons/Features/fillet.png" auto_preview="true" helpfile="filletFeature.html"> + + + diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index 33f39251f..71ed98af8 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -82,7 +82,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Offset.h GeomAlgoAPI_SolidClassifier.h GeomAlgoAPI_MapShapesAndAncestors.h - GeomAlgoAPI_Projection.h + GeomAlgoAPI_Chamfer.h ) SET(PROJECT_SOURCES @@ -145,6 +145,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_SolidClassifier.cpp GeomAlgoAPI_MapShapesAndAncestors.cpp GeomAlgoAPI_Projection.cpp + GeomAlgoAPI_Chamfer.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp new file mode 100644 index 000000000..d0bd06936 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp @@ -0,0 +1,95 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GeomAlgoAPI_Chamfer.h" + +#include +#include +#include +#include +#include +#include +#include + +//================================================================================================= +GeomAlgoAPI_Chamfer::GeomAlgoAPI_Chamfer(const GeomShapePtr& theBaseSolid, + const ListOfShape& theChamferShapes, + const std::map aMapEdgeFace, + const bool performDistances, + const double aVal1, + const double aVal2) +{ + build(theBaseSolid, theChamferShapes, aMapEdgeFace, performDistances, aVal1, aVal2); +} + +//================================================================================================= +void GeomAlgoAPI_Chamfer::build(const GeomShapePtr& theBaseSolid, + const ListOfShape& theChamferShapes, + const std::map aMapEdgeFace, + const bool performDistances, + const double aVal1, + const double aVal2) +{ + TopoDS_Shape aShapeBase = theBaseSolid->impl(); + TopTools_IndexedDataMapOfShapeListOfShape M; + TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); + + // create chamfer builder + BRepFilletAPI_MakeChamfer* aChamferBuilder = + new BRepFilletAPI_MakeChamfer(aShapeBase); + setImpl(aChamferBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + for (ListOfShape::const_iterator anIt = theChamferShapes.begin(); + anIt != theChamferShapes.end(); ++anIt) { + if ((*anIt)->isEdge()) { + TopoDS_Edge E = (*anIt)->impl(); + if (aMapEdgeFace.find(*anIt) != aMapEdgeFace.end()) { + TopoDS_Face F = (aMapEdgeFace[*anIt])->impl(); + if (!BRepTools::IsReallyClosed(E,F) && !BRep_Tool::Degenerated(E) && + M.FindFromKey(E).Extent() == 2) { + if (performDistances) { + aChamferBuilder->Add(aVal1, aVal2, E, F); + } else { + aChamferBuilder->AddDA(aVal1, aVal2 * M_PI / 180., E, F); + } + } + } else { + const TopTools_ListOfShape& aFacesList = M.FindFromKey(E); + TopoDS_Face F = TopoDS::Face(aFacesList.First()); + if (performDistances) { + aChamferBuilder->Add(aVal1, aVal2, E, F); + } else { + aChamferBuilder->AddDA(aVal1, aVal2 * M_PI / 180., E, F); + } + } + } + } + + // build and get result + aChamferBuilder->Build(); + if (!aChamferBuilder->IsDone()) + return; + const TopoDS_Shape& aResult = aChamferBuilder->Shape(); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h b/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h new file mode 100644 index 000000000..034966bb7 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h @@ -0,0 +1,66 @@ +// Copyright (C) 2017-2019 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GeomAlgoAPI_Chamfer_H_ +#define GeomAlgoAPI_Chamfer_H_ + +#include +#include + +#include +//#include +//#include + +/// \class GeomAlgoAPI_Chamfer +/// \ingroup DataAlgo +/// \brief Perform chamfer +class GeomAlgoAPI_Chamfer : public GeomAlgoAPI_MakeShape +{ +public: + /// Run chamfer operation with two distances or with a distance and an angle . + /// \param theBaseSolid a changing solid + /// \param theChamferShapes list of edges the chamfer is performed on + /// \param aMapEdgeFace map that associates an edge to a face when the chamfer is applied to a face + /// \param performDistances boolean that indicates whether the operation is performed with two distances or not + /// \param aVal1 double D1 if performDistances is true or D + /// \param aVal2 double D2 if performDistances is true or Angle + GEOMALGOAPI_EXPORT GeomAlgoAPI_Chamfer(const GeomShapePtr& theBaseSolid, + const ListOfShape& theChamferShapes, + const std::map aMapEdgeFace, + const bool performDistances, + const double aVal1, + const double aVal2); + +private: + /// Perform chamfer operation. + /// \param theBaseSolid a changing solid + /// \param theChamferShapes list of edges the chamfer is performed on + /// \param aMapEdgeFace map that associates an edge to a face when the chamfer is applied to a face + /// \param performDistances boolean that indicates whether the operation is performed with two distances or not + /// \param aVal1 double D1 if performDistances is true or D + /// \param aVal2 double D2 if performDistances is true or Angle + GEOMALGOAPI_EXPORT void build(const GeomShapePtr& theBaseSolid, + const ListOfShape& theChamferShapes, + const std::map aMapEdgeFace, + const bool performDistances, + const double aVal1, + const double aVal2); +}; + +#endif diff --git a/src/PythonAPI/model/features/__init__.py b/src/PythonAPI/model/features/__init__.py index 19f7b2ed0..475fdbae8 100644 --- a/src/PythonAPI/model/features/__init__.py +++ b/src/PythonAPI/model/features/__init__.py @@ -27,7 +27,7 @@ from FeaturesAPI import addPipe from FeaturesAPI import addCut, addFuse, addCommon, addSmash, addSplit from FeaturesAPI import addIntersection, addPartition, addUnion, addRemoveSubShapes from FeaturesAPI import addRecover -from FeaturesAPI import addFillet +from FeaturesAPI import addFillet, addChamfer from FeaturesAPI import addFusionFaces from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle from FeaturesAPI import addRemoveResults -- 2.39.2