\page fillet2d_operation_page Fillet 2D
-This operation creates fillets on the corners of a <b>2D Planar Face</b>.
+This operation creates fillets on the corners of a <b>2D Planar Face</b>
+or a <b>Shell, made of 2D Planar Faces</b>.
\image html fillet2d_2.png
-To produce a \b Fillet 2D in the <b>Main Menu</b> select
+To produce a <b>Fillet 2D</b> in the <b>Main Menu</b> select
<b>Operations - > Fillet 2D</b>
-Define the <b>Planar Face</b> 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 <b>Planar Face</b> or the <b>Shell</b> 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 <b>Planar 2D</b> Faces Only.
+\b Note: This operation works only for <b>Planar 2D Faces</b> 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.
<b>TUI Command:</b> <em>geompy.MakeFillet2D(Shape, R, ListVertexes)</em>
\n <b>Arguments:</b> Name + 1 shape + one or several vertexes + 1 value (Fillet radius).
// 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 <Standard_Stream.hxx>
#include <GEOMImpl_IFillet2d.hxx>
#include <GEOMImpl_Types.hxx>
#include <GEOMImpl_ILocalOperations.hxx>
+#include <GEOMImpl_Block6Explorer.hxx>
#include <GEOM_Function.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
#include <TopAbs.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Shape.hxx>
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);
+
+ 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);
+ }
+ }
+ }
- fillet2d.Build();
- if (!fillet2d.IsDone()) {
- StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ // 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;
//=======================================================================
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);
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),
//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;
}
}
- return _anOtherObject ;
+ return _anOtherObject;
}
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++) {
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++) {
}
}
}
- } 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()) {
// 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 <DlgRef.h>
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 = "";
}
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);