diff --git a/doc/salome/gui/GEOM/input/fillet2d_operation.doc b/doc/salome/gui/GEOM/input/fillet2d_operation.doc
index bb0ba1bce..b6d8bfb5e 100755
--- a/doc/salome/gui/GEOM/input/fillet2d_operation.doc
+++ b/doc/salome/gui/GEOM/input/fillet2d_operation.doc
@@ -2,17 +2,22 @@
\page fillet2d_operation_page Fillet 2D
-This operation creates fillets on the corners of a 2D Planar Face.
+This operation creates fillets on the corners of a 2D Planar Face
+or a Shell, made of 2D Planar Faces.
\image html fillet2d_2.png
-To produce a \b Fillet 2D in the Main Menu select
+To produce a Fillet 2D in the Main Menu select
Operations - > Fillet 2D
-Define the Planar Face to create a fillet on, select the necessary
-vertexes on this face in the OCC Viewer and define the \b Radius of the Fillet.
+Define the Planar Face or the Shell to create a fillet
+on, select the necessary vertexes on this shape in the OCC Viewer and
+define the \b Radius of the Fillet.
-\b Note: This Operation Works for the Planar 2D Faces Only.
+\b Note: This operation works only for Planar 2D Faces and
+shells, made of such faces. For shells, only corner vertexes are
+available for fillet building, i.e. the vertexes that belong to only
+one face of this shell.
TUI Command: geompy.MakeFillet2D(Shape, R, ListVertexes)
\n Arguments: Name + 1 shape + one or several vertexes + 1 value (Fillet radius).
diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl
index 136310506..3da8faec1 100644
--- a/idl/GEOM_Gen.idl
+++ b/idl/GEOM_Gen.idl
@@ -2762,7 +2762,7 @@ module GEOM
in ListOfLong theFaces);
/*!
- * Perform a fillet on face of the specified vertexes of the given shape.
+ * Perform a fillet on a face or a shell at the specified vertexes.
* \param theShape Shape, to perform fillet on.
* \param theR Fillet radius.
* \param theVertexes Global indices of vertexes to perform fillet on.
diff --git a/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx b/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx
index 82827eb4d..0fb59351e 100755
--- a/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx
+++ b/src/GEOMImpl/GEOMImpl_Fillet2dDriver.cxx
@@ -15,7 +15,6 @@
// 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
@@ -23,17 +22,22 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
+#include
+#include
#include
#include
@@ -75,29 +79,96 @@ Standard_Integer GEOMImpl_Fillet2dDriver::Execute(TFunction_Logbook& log) const
TopoDS_Shape aShape;
Handle(GEOM_Function) aRefShape = aCI.GetShape();
- TopoDS_Face aFaceShape = TopoDS::Face(aRefShape->GetValue());
-
- if (aFaceShape.ShapeType() != TopAbs_FACE)
- Standard_ConstructionError::Raise("Wrong arguments: two faces must be given");
-
- BRepFilletAPI_MakeFillet2d fillet2d (aFaceShape);
+ TopoDS_Shape aFaceShape = aRefShape->GetValue();
int aLen = aCI.GetLength();
- int ind = 1;
double rad = aCI.GetR();
- for (; ind <= aLen; ind++) {
- TopoDS_Shape aShapeVertex;
- if (GEOMImpl_ILocalOperations::GetSubShape
- (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
- fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
- }
- }
- fillet2d.Build();
- if (!fillet2d.IsDone()) {
- StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ if (aFaceShape.ShapeType() == TopAbs_FACE) {
+ BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(aFaceShape));
+
+ int ind = 1;
+ for (; ind <= aLen; ind++) {
+ TopoDS_Shape aShapeVertex;
+ if (GEOMImpl_ILocalOperations::GetSubShape
+ (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
+ fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
+ }
+ }
+
+ fillet2d.Build();
+ if (!fillet2d.IsDone()) {
+ StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ }
+ aShape = fillet2d.Shape();
+ }
+ else if (aFaceShape.ShapeType() == TopAbs_SHELL) {
+ // 1. Map vertices to faces to build fillets only on corner vertices
+ TopTools_IndexedDataMapOfShapeListOfShape mapVertexFaces;
+ GEOMImpl_Block6Explorer::MapShapesAndAncestors
+ (aFaceShape, TopAbs_VERTEX, TopAbs_FACE, mapVertexFaces);
+
+ // 2. Map faces to vertices
+ TopTools_IndexedDataMapOfShapeListOfShape mapFaceVertices;
+ TopTools_ListOfShape empty;
+ int ind = 1;
+ for (; ind <= aLen; ind++) {
+ TopoDS_Shape aVi;
+ if (GEOMImpl_ILocalOperations::GetSubShape(aFaceShape, aCI.GetVertex(ind), aVi)) {
+ Standard_Integer aVi_index = mapVertexFaces.FindIndex(aVi);
+ if (aVi_index > 0) {
+ const TopTools_ListOfShape& aFacesOfVi = mapVertexFaces(aVi_index);
+ if (aFacesOfVi.Extent() == 1) { // we use only corner vertices of shell
+ TopoDS_Shape aFi = aFacesOfVi.First();
+ Standard_Integer aFi_index = mapFaceVertices.FindIndex(aFi);
+ if (aFi_index == 0) aFi_index = mapFaceVertices.Add(aFi, empty);
+ mapFaceVertices(aFi_index).Append(aVi);
+ }
+ }
+ }
+ }
+
+ // 3. Build fillet on each given vertex
+ TopoDS_Shell aResult;
+ BRep_Builder B;
+ B.MakeShell(aResult);
+
+ TopoDS_Iterator It (aFaceShape, Standard_True, Standard_True);
+ TopTools_MapOfShape mapShape;
+ for (; It.More(); It.Next()) {
+ if (mapShape.Add(It.Value())) {
+ Standard_Integer aFi_index = mapFaceVertices.FindIndex(It.Value());
+ if (aFi_index == 0) {
+ // No fillets requested on this face, add it as is
+ B.Add(aResult, It.Value());
+ }
+ else {
+ // Build a fillet and add the changed face
+ BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(It.Value()));
+ const TopTools_ListOfShape& aVertsOfFi = mapFaceVertices(aFi_index);
+ TopTools_ListIteratorOfListOfShape itV (aVertsOfFi);
+ for (; itV.More(); itV.Next()) {
+ fillet2d.AddFillet(TopoDS::Vertex(itV.Value()), rad);
+ }
+
+ fillet2d.Build();
+ if (!fillet2d.IsDone()) {
+ StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ }
+ TopoDS_Shape aFillet = fillet2d.Shape();
+
+ B.Add(aResult, aFillet);
+ }
+ }
+ }
+
+ // 4. Build a shell
+ // ?TODO?
+ aShape = aResult;
+ }
+ else {
+ Standard_ConstructionError::Raise("Wrong arguments: a face or a shell must be given");
}
- aShape = fillet2d.Shape();
if (aShape.IsNull()) return 0;
@@ -114,7 +185,6 @@ Standard_Integer GEOMImpl_Fillet2dDriver::Execute(TFunction_Logbook& log) const
//=======================================================================
Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet2dDriver_Type_()
{
-
static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
@@ -122,7 +192,6 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet2dDriver_Type_()
static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
-
static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_Fillet2dDriver",
sizeof(GEOMImpl_Fillet2dDriver),
@@ -137,7 +206,8 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet2dDriver_Type_()
//function : DownCast
//purpose :
//=======================================================================
-const Handle(GEOMImpl_Fillet2dDriver) Handle(GEOMImpl_Fillet2dDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
+const Handle(GEOMImpl_Fillet2dDriver) Handle(GEOMImpl_Fillet2dDriver)::DownCast
+ (const Handle(Standard_Transient)& AnObject)
{
Handle(GEOMImpl_Fillet2dDriver) _anOtherObject;
@@ -147,5 +217,5 @@ const Handle(GEOMImpl_Fillet2dDriver) Handle(GEOMImpl_Fillet2dDriver)::DownCast(
}
}
- return _anOtherObject ;
+ return _anOtherObject;
}
diff --git a/src/GEOMImpl/GEOMImpl_FilletDriver.cxx b/src/GEOMImpl/GEOMImpl_FilletDriver.cxx
index 93ed1eafd..355f4f95d 100644
--- a/src/GEOMImpl/GEOMImpl_FilletDriver.cxx
+++ b/src/GEOMImpl/GEOMImpl_FilletDriver.cxx
@@ -88,7 +88,8 @@ Standard_Integer GEOMImpl_FilletDriver::Execute(TFunction_Logbook& log) const
TopoDS_Edge E = TopoDS::Edge(Exp.Current());
fill.Add(E);
}
- } else if (aType == FILLET_SHAPE_EDGES || aType == FILLET_SHAPE_EDGES_2R) {
+ }
+ else if (aType == FILLET_SHAPE_EDGES || aType == FILLET_SHAPE_EDGES_2R) {
int aLen = aCI.GetLength();
int ind = 1;
for (; ind <= aLen; ind++) {
@@ -98,7 +99,8 @@ Standard_Integer GEOMImpl_FilletDriver::Execute(TFunction_Logbook& log) const
fill.Add(TopoDS::Edge(aShapeEdge));
}
}
- } else if (aType == FILLET_SHAPE_FACES || aType == FILLET_SHAPE_FACES_2R) {
+ }
+ else if (aType == FILLET_SHAPE_FACES || aType == FILLET_SHAPE_FACES_2R) {
int aLen = aCI.GetLength();
int ind = 1;
for (; ind <= aLen; ind++) {
@@ -111,16 +113,19 @@ Standard_Integer GEOMImpl_FilletDriver::Execute(TFunction_Logbook& log) const
}
}
}
- } else {
}
- if (aType == FILLET_SHAPE_FACES || aType == FILLET_SHAPE_EDGES || aType == FILLET_SHAPE_ALL)
+ else {
+ }
+
+ if (aType == FILLET_SHAPE_FACES || aType == FILLET_SHAPE_EDGES || aType == FILLET_SHAPE_ALL) {
for (int i = 1; i <= fill.NbContours(); i++)
fill.SetRadius(aCI.GetR(), i, 1);
- else if (aType == FILLET_SHAPE_FACES_2R || aType == FILLET_SHAPE_EDGES_2R)
- for (int i = 1; i <= fill.NbContours(); i++)
- {
- fill.SetRadius(aCI.GetR1(), aCI.GetR2(), i, 1);
- }
+ }
+ else if (aType == FILLET_SHAPE_FACES_2R || aType == FILLET_SHAPE_EDGES_2R) {
+ for (int i = 1; i <= fill.NbContours(); i++) {
+ fill.SetRadius(aCI.GetR1(), aCI.GetR2(), i, 1);
+ }
+ }
fill.Build();
if (!fill.IsDone()) {
diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py
index 5936e3b29..4ea478a23 100644
--- a/src/GEOM_SWIG/geompyDC.py
+++ b/src/GEOM_SWIG/geompyDC.py
@@ -3283,15 +3283,15 @@ class geompyDC(GEOM._objref_GEOM_Gen):
anObj.SetParameters(Parameters)
return anObj
- ## Perform a fillet on the specified edges/faces of the given shape
- # @param theShape - Face Shape to perform fillet on.
+ ## Perform a fillet at the specified vertices of the given face/shell.
+ # @param theShape - Face or Shell shape to perform fillet on.
# @param theR - Fillet radius.
# @param theListOfVertexes Global indices of vertexes to perform fillet on.
# \note Global index of sub-shape can be obtained, using method geompy.GetSubShapeID().
# @return New GEOM_Object, containing the result shape.
#
# @ref tui_fillet2d "Example"
- def MakeFillet2D(self,theShape, theR, theListOfVertexes):
+ def MakeFillet2D(self, theShape, theR, theListOfVertexes):
# Example: see GEOM_TestAll.py
theR,Parameters = ParseParameters(theR)
anObj = self.LocalOp.MakeFillet2D(theShape, theR, theListOfVertexes)
diff --git a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
index 4d769e28d..04eb64733 100644
--- a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
+++ b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
@@ -15,12 +15,11 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
// GEOM GEOMGUI : GUI for Geometry component
// File : OperationGUI_Fillet1d2dDlg.cxx
// Author : DMV, OCN.
-//
+
#include "OperationGUI_Fillet1d2dDlg.h"
#include
@@ -215,7 +214,8 @@ void OperationGUI_Fillet1d2dDlg::SelectionIntoArgument()
anObj = aFindedObject; // get Object from study
}
else { // Global Selection
- if ( aShape.ShapeType() != (myIs1D ? TopAbs_WIRE : TopAbs_FACE) ) {
+ if ((myIs1D && aShape.ShapeType() != TopAbs_WIRE) ||
+ (!myIs1D && aShape.ShapeType() != TopAbs_FACE && aShape.ShapeType() != TopAbs_SHELL)) {
anObj = GEOM::GEOM_Object::_nil();
aName = "";
}
@@ -349,8 +349,15 @@ void OperationGUI_Fillet1d2dDlg::activateSelection()
disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
globalSelection();
if (myEditCurrentArgument == GroupVertexes->LineEdit1)
- globalSelection( myIs1D ? GEOM_WIRE : GEOM_FACE ); // localSelection(myShape, myIs1D ? TopAbs_WIRE
- // : TopAbs_FACE);
+ //localSelection(myShape, myIs1D ? TopAbs_WIRE : TopAbs_FACE);
+ if (myIs1D)
+ globalSelection(GEOM_WIRE);
+ else {
+ TColStd_MapOfInteger aMap;
+ aMap.Add(GEOM_FACE);
+ aMap.Add(GEOM_SHELL);
+ globalSelection(aMap);
+ }
else if (!myShape->_is_nil() && myEditCurrentArgument == GroupVertexes->LineEdit2)
localSelection(myShape, TopAbs_VERTEX);