]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Add Chamfer feature
authorClarisse Genrault <cgenrault@is231796.intra.cea.fr>
Wed, 11 Sep 2019 07:28:48 +0000 (09:28 +0200)
committervsv <vsv@opencascade.com>
Wed, 6 Nov 2019 08:22:40 +0000 (11:22 +0300)
18 files changed:
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Chamfer.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_Chamfer.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Chamfer.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Chamfer.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/chamfer_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/icons/chamfer.png [new file with mode: 0644]
src/FeaturesPlugin/icons/chamfer_dist_angle.png [new file with mode: 0644]
src/FeaturesPlugin/icons/chamfer_distances.png [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Chamfer.h [new file with mode: 0644]
src/PythonAPI/model/features/__init__.py

index 9311f491d42cef0d6eabb07111bbfefbc0851865..acd6222f5e1cc4c674c701072acaf6b93b2f4f21 100644 (file)
@@ -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
index 35bdfcefcc62383ddad656957c4c2b174045629b..a1a7fbe1f9ff9d59c25704a4e4f2ff37a450b591 100644 (file)
@@ -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 (file)
index 0000000..a898a3c
--- /dev/null
@@ -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 <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+FeaturesAPI_Chamfer::FeaturesAPI_Chamfer(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+  : ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+FeaturesAPI_Chamfer::FeaturesAPI_Chamfer(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                         const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& 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<ModelAPI_Document>& thePart,
+                      const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                      const bool performDistances,
+                      const ModelHighAPI_Double& theVal1,
+                      const ModelHighAPI_Double& theVal2)
+{
+  std::shared_ptr<ModelAPI_Feature> 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 (file)
index 0000000..3baf2dd
--- /dev/null
@@ -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 <FeaturesPlugin_Chamfer.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+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<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_Chamfer(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                               const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& 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<FeaturesAPI_Chamfer> ChamferPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Chamfer feature.
+FEATURESAPI_EXPORT
+ChamferPtr addChamfer(const std::shared_ptr<ModelAPI_Document>& thePart,
+                      const std::list<ModelHighAPI_Selection>& theBaseObjects,
+                      const bool performDistances,
+                      const ModelHighAPI_Double& theVal1,
+                      const ModelHighAPI_Double& theVal2);
+
+#endif // FeaturesAPI_Chamfer_H_
index f427c3f7da8f4c63d3632babaef77d7e5516f894..cd71216fae72dacf4ad6f159760cf424ba686105 100644 (file)
@@ -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"
index 224e940847ea804c34f912c8e7e64793b78c83cd..5adf4e878f0a925d9c990479a910f84e84f31ad2 100644 (file)
@@ -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 (file)
index 0000000..47ebd45
--- /dev/null
@@ -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 <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_Chamfer.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_Tools.h>
+
+#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+// 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<std::pair<GeomShapePtr, ListOfShape> > aSolidsAndSubs; 
+   std::map<GeomShapePtr, GeomShapePtr> 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<std::pair<GeomShapePtr, ListOfShape> >::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<GeomShapePtr, ListOfShape>(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<GeomAlgoAPI_Chamfer> aChamferBuilder;
+   int aResultIndex = 0;
+   std::string anError;
+   
+   std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
+   ListOfShape anOriginalShapesList, aResultShapesList;
+   std::list<std::pair<GeomShapePtr, ListOfShape> >::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<ModelAPI_ResultBody> 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 (file)
index 0000000..cad7204
--- /dev/null
@@ -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 <GeomAPI_Shape.h>
+
+#include <ModelAPI_Feature.h>
+
+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<ModelAPI_ResultBody> theResultBody,
+                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                    const std::shared_ptr<GeomAPI_Shape> theResultShape,
+                    const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+};
+
+#endif
index 87db42a877e209be75b8d0261aac0777cd56eb00..7973434462db3f8af12183e9c78748163ed714b5 100644 (file)
@@ -24,6 +24,7 @@
 #include <FeaturesPlugin_BooleanCommon.h>
 #include <FeaturesPlugin_BooleanSmash.h>
 #include <FeaturesPlugin_BooleanFill.h>
+#include <FeaturesPlugin_Chamfer.h>
 #include <FeaturesPlugin_Extrusion.h>
 #include <FeaturesPlugin_ExtrusionCut.h>
 #include <FeaturesPlugin_ExtrusionFuse.h>
@@ -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 (file)
index 0000000..ae881d5
--- /dev/null
@@ -0,0 +1,63 @@
+<source>
+  <toolbox id="creation_method">
+    <box id="distance_distance"
+         title="Two distances"
+         tooltip="Chamfer with two distances"
+         icon="icons/Features/chamfer_distances.png">
+      <multi_selector id="main_objects"
+                      label="Faces or/and edges"
+                      icon=""
+                      tooltip="Select objects"
+                      shape_types="edges faces"
+                      use_choice="false"
+                      concealment="true">
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+      </multi_selector>
+      <doublevalue id="d1"
+                   label="D1"
+                   tooltip="First distance."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+      <doublevalue id="d2"
+                   label="D2"
+                   tooltip="Second distance."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+    </box>
+    <box id="distance_angle"
+         title="Distance and angle"
+         tooltip="Chamfer with a distance and an angle"
+         icon="icons/Features/chamfer_dist_angle.png">
+      <multi_selector id="main_objects"
+                      label="Faces or/and edges"
+                      icon=""
+                      tooltip="Select objects"
+                      shape_types="edges faces"
+                      use_choice="false"
+                      concealment="true">
+        <validator id="PartSet_DifferentObjects"/>
+        <validator id="FeaturesPlugin_ValidatorFilletSelection"/>
+      </multi_selector>
+      <doublevalue id="d"
+                   label="D"
+                   tooltip="Distance."
+                   min="0"
+                   default="2">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+      <doublevalue id="angle"
+                   label="Angle"
+                   tooltip="Angle."
+                   min="0"
+                   max="90"
+                   default="25">
+        <validator id="GeomValidators_Positive"/>
+      </doublevalue>
+    </box>
+  </toolbox>
+</source>
diff --git a/src/FeaturesPlugin/icons/chamfer.png b/src/FeaturesPlugin/icons/chamfer.png
new file mode 100644 (file)
index 0000000..3b5a982
Binary files /dev/null and b/src/FeaturesPlugin/icons/chamfer.png differ
diff --git a/src/FeaturesPlugin/icons/chamfer_dist_angle.png b/src/FeaturesPlugin/icons/chamfer_dist_angle.png
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/FeaturesPlugin/icons/chamfer_distances.png b/src/FeaturesPlugin/icons/chamfer_distances.png
new file mode 100644 (file)
index 0000000..e69de29
index f7f414e98683f74358dec8ef2baa343558b34edb..65c1a1e45998eb49143b4a11e0321efc1f02a32c 100644 (file)
                icon="icons/Features/fillet.png" auto_preview="true" helpfile="filletFeature.html">
         <source path="fillet_widget.xml"/>
       </feature>
+      <feature id="Chamfer" title="Chamfer" tooltip="Perform chamfer on face or edge"
+               icon="icons/Features/chamfer.png" auto_preview="true" helpfile="chamferFeature.html">
+        <source path="chamfer_widget.xml"/>
+      </feature>
       <feature id="FusionFaces" title="Fuse Faces" tooltip="Performs fusion of connected faces"
                icon="icons/Features/fusion_faces.png" auto_preview="true" helpfile="FeaturesPlugin/fusionFacesFeature.html">
         <source path="fusion_faces_widget.xml"/>
index 33f39251f7a0efa17bea2345f5fbf602941347a6..71ed98af8bc6b0eedfa4705c017b2f57339ba77b 100644 (file)
@@ -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 (file)
index 0000000..d0bd069
--- /dev/null
@@ -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 <BRep_Tool.hxx>
+#include <BRepFilletAPI_MakeChamfer.hxx>
+#include <BRepTools.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+
+//=================================================================================================
+GeomAlgoAPI_Chamfer::GeomAlgoAPI_Chamfer(const GeomShapePtr& theBaseSolid,
+                                         const ListOfShape&  theChamferShapes,
+                                         const std::map<GeomShapePtr, GeomShapePtr> 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<GeomShapePtr, GeomShapePtr> aMapEdgeFace,
+                                const bool performDistances,
+                                const double aVal1,
+                                const double aVal2)
+{
+  TopoDS_Shape aShapeBase = theBaseSolid->impl<TopoDS_Shape>();
+  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<TopoDS_Edge>();
+      if (aMapEdgeFace.find(*anIt) != aMapEdgeFace.end()) {
+        TopoDS_Face F = (aMapEdgeFace[*anIt])->impl<TopoDS_Face>();
+        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<GeomAPI_Shape> 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 (file)
index 0000000..034966b
--- /dev/null
@@ -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 <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_Shape.h>
+//#include <GeomAPI_Edge.h>
+//#include <GeomAPI_Face.h>
+
+/// \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<GeomShapePtr, GeomShapePtr> 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<GeomShapePtr, GeomShapePtr> aMapEdgeFace,
+                                const bool performDistances,
+                                const double aVal1,
+                                const double aVal2);
+};
+
+#endif
index 19f7b2ed03a94e9394086f0a5632e3dd520ec49d..475fdbae834ef5d578a50c2407ce91628d8e4fa5 100644 (file)
@@ -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