diff --git a/doc/salome/gui/GEOM/images/fillet1d_1.png b/doc/salome/gui/GEOM/images/fillet1d_1.png
new file mode 100644
index 000000000..00ddc0854
Binary files /dev/null and b/doc/salome/gui/GEOM/images/fillet1d_1.png differ
diff --git a/doc/salome/gui/GEOM/images/fillet1d_2.png b/doc/salome/gui/GEOM/images/fillet1d_2.png
new file mode 100644
index 000000000..a67c4ba5b
Binary files /dev/null and b/doc/salome/gui/GEOM/images/fillet1d_2.png differ
diff --git a/doc/salome/gui/GEOM/input/fillet1d_operation.doc b/doc/salome/gui/GEOM/input/fillet1d_operation.doc
new file mode 100644
index 000000000..4d9ef7f9d
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/fillet1d_operation.doc
@@ -0,0 +1,29 @@
+/*!
+
+\page fillet1d_operation_page Fillet 1D
+
+This operation creates fillets on the corners of a Wire with Planar
+Edges .
+Note, that each couple of edges connected with a vertex, where 1D fillet should be
+constructed, have to be in same plane.
+\image html fillet1d_2.png
+
+To produce a \b Fillet 1D in the Main Menu select
+Operations - > Transformation - > Fillet 1D
+
+Define the Wire with planar Edges to create a fillet on, select the necessary
+vertexes on this wire in the OCC Viewer and define the \b Radius of the Fillet.
+
+\b Note: This Operation Works for the Wires with Planar Edges Only.
+
+TUI Command: geompy.MakeFillet1D(Shape, R, ListVertexes)
+\n Arguments: Name + 1 shape + empty list or several vertexes + 1 value (Fillet radius).
+
+Examples:
+
+\image html fillet1d_1.png
+
+Our TUI Scripts provide you with useful examples of the use of
+\ref tui_fillet1d "Transformation Operations".
+
+*/
diff --git a/doc/salome/gui/GEOM/input/fillet2d_operation.doc b/doc/salome/gui/GEOM/input/fillet2d_operation.doc
index 43701ed90..74b044b05 100755
--- a/doc/salome/gui/GEOM/input/fillet2d_operation.doc
+++ b/doc/salome/gui/GEOM/input/fillet2d_operation.doc
@@ -14,7 +14,7 @@ vertexes on this face in the OCC Viewer and define the \b Radius of the Fillet.
\b Note: This Operation Works for the Planar 2D Faces Only.
-TUI Command: geompy.MakeFillet(Shape, R, ListVertexes)
+TUI Command: geompy.MakeFillet2D(Shape, R, ListVertexes)
\n Arguments: Name + 1 shape + one or several vertexes + 1 value (Fillet radius).
Examples:
diff --git a/doc/salome/gui/GEOM/input/transformation_operations.doc b/doc/salome/gui/GEOM/input/transformation_operations.doc
index faa58dc93..3a46456d4 100644
--- a/doc/salome/gui/GEOM/input/transformation_operations.doc
+++ b/doc/salome/gui/GEOM/input/transformation_operations.doc
@@ -20,9 +20,11 @@ factors.
Create a simultaneous \subpage multi_rotation_operation_page "Rotation in several directions".
Produce a \subpage fillet_operation_page "Fillet" on the selected
edges of the object.
+Produce a \subpage fillet1d_operation_page "1D Fillet" on the
+corners of a Wire with Planar Edges.
Produce a \subpage fillet2d_operation_page "2D Fillet" on the corners of a Planar Face.
Produce a \subpage chamfer_operation_page "Chamfer" on the
selected edges of the object.
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc
index 7fd356e7c..247568840 100644
--- a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc
+++ b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc
@@ -370,6 +370,29 @@ gg.createAndDisplayGO(id_face)
gg.createAndDisplayGO(id_fillet2d)
\endcode
+\anchor tui_fillet1d
+Fillet 1D
+
+\code
+import geompy
+import salome
+gg = salome.ImportComponentGUI("GEOM")
+
+# create box
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+# take box edges to create custom complex wire
+[Edge_1,Edge_2,Edge_3,Edge_4,Edge_5,Edge_6,Edge_7,Edge_8,Edge_9,Edge_10,Edge_11,Edge_12] = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["EDGE"])
+# create wire
+Wire_1 = geompy.MakeWire([Edge_12, Edge_7, Edge_11, Edge_6, Edge_1,Edge_4])
+# make fillet at given wire vertices with giver radius
+Fillet_1D_1 = geompy.MakeFillet1D(Wire_1, 55, [3, 4, 6, 8, 10])
+
+
+# display disks
+gg.createAndDisplayGO(Wire_1)
+gg.createAndDisplayGO(Fillet_1D_1)
+\endcode
+
\anchor tui_fillet
Fillet
diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl
index 62e06e217..5ab6a4070 100644
--- a/idl/GEOM_Gen.idl
+++ b/idl/GEOM_Gen.idl
@@ -2333,6 +2333,21 @@ module GEOM
in double theR,
in ListOfLong theVertexes);
+ /*!
+ * Perform a fillet on edges of the specified vertexes of the given wire.
+ * \param theShape Shape, to perform fillet on.
+ * \param theR Fillet radius.
+ * \param theVertexes Global indices of vertexes to perform fillet on.
+ * \note Global index of sub-shape can be obtained, using method
+ * GEOM_IShapesOperations.GetSubShapeIndex() .
+ * \note The list of vertices coudl be empty, in this case fillet fill be done
+ * at all vertices in given wire
+ * \return New GEOM_Object, containing the result shape.
+ */
+ GEOM_Object MakeFillet1D (in GEOM_Object theShape,
+ in double theR,
+ in ListOfLong theVertexes);
+
/*!
* Perform a symmetric chamfer on all edges of the given shape.
* \param theShape Shape, to perform chamfer on.
diff --git a/resources/Makefile.am b/resources/Makefile.am
index e8bc26310..7e74345c4 100644
--- a/resources/Makefile.am
+++ b/resources/Makefile.am
@@ -86,9 +86,11 @@ eraseall.png \
face_hw.png \
face_vechw.png \
fillet.png \
+fillet1d.png \
fillet2d.png \
filletall.png \
filletedge.png \
+filletwire.png \
filletface.png \
filling.png \
fuse.png \
diff --git a/resources/fillet1d.png b/resources/fillet1d.png
new file mode 100644
index 000000000..c62a1769b
Binary files /dev/null and b/resources/fillet1d.png differ
diff --git a/resources/filletwire.png b/resources/filletwire.png
new file mode 100644
index 000000000..961c17cc5
Binary files /dev/null and b/resources/filletwire.png differ
diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts
index 91d67566e..2e25def67 100644
--- a/src/GEOMGUI/GEOM_images.ts
+++ b/src/GEOMGUI/GEOM_images.ts
@@ -225,6 +225,10 @@
ICON_DLG_FILLET
fillet.png
+
+ ICON_DLG_FILLET_1D
+ fillet1d.png
+
ICON_DLG_FILLET_2D
fillet2d.png
@@ -237,6 +241,10 @@
ICON_DLG_FILLET_EDGE
filletedge.png
+
+ ICON_DLG_FILLET_WIRE
+ filletwire.png
+
ICON_DLG_FILLET_FACE
filletface.png
@@ -765,6 +773,10 @@
ICO_FILLET
fillet.png
+
+ ICO_FILLET_1D
+ fillet1d.png
+
ICO_FILLET_2D
fillet2d.png
diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts
index 9abfa6421..a63dd13e1 100644
--- a/src/GEOMGUI/GEOM_msg_en.ts
+++ b/src/GEOMGUI/GEOM_msg_en.ts
@@ -623,6 +623,10 @@ Please, select face, shell or solid and try again
GEOM_FILLET_2D
Fillet 2D
+
+ GEOM_FILLET_1D
+ Fillet 1D
+
GEOM_FILLET_ABORT
Fillet can't be computed with radius %1
@@ -635,6 +639,10 @@ Please, select face, shell or solid and try again
GEOM_FILLET_EDGES
Fillet On Edges From Shape
+
+ GEOM_FILLET_WIRES
+ Fillet On Wires From Shape
+
GEOM_FILLET_FACES
Fillet On Faces From Shape
@@ -651,6 +659,10 @@ Please, select face, shell or solid and try again
GEOM_FILLET_2D_TITLE
2D Fillet Construction
+
+ GEOM_FILLET_1D_TITLE
+ 1D Fillet Construction
+
GEOM_FILLING
Filling
@@ -2187,6 +2199,10 @@ Please, select face, shell or solid and try again
MEN_FILLET
Fillet
+
+ MEN_FILLET_1D
+ Fillet 1D
+
MEN_FILLET_2D
Fillet 2D
@@ -3707,6 +3723,10 @@ Please, select face, shell or solid and try again
GEOM_PLANAR_FACE
Planar Face
+
+ GEOM_PLANAR_EDGE_WIRE
+ Wire with Planar Edges
+
GEOM_POLYGON
Polygon
diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts
index 608ad2570..4ba2ff038 100644
--- a/src/GEOMGUI/GEOM_msg_fr.ts
+++ b/src/GEOMGUI/GEOM_msg_fr.ts
@@ -397,6 +397,10 @@
GEOM_FILLET_EDGES
Cong sur Edges de la Shape
+
+ GEOM_FILLET_WIRES
+ Cong sur Wires de la Shape
+
GEOM_FILLET_FACES
Cong sur Faces de la Shape
diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx
index 86ef36d17..e33a927cc 100644
--- a/src/GEOMGUI/GeometryGUI.cxx
+++ b/src/GEOMGUI/GeometryGUI.cxx
@@ -505,7 +505,8 @@ void GeometryGUI::OnGUIEvent( int id )
id == 506 || // MENU OPERATION - CHAMFER
id == 507 || // MENU OPERATION - CLIPPING RANGE
id == 508 || // MENU OPERATION - GET SHAPES ON SHAPE
- id == 509 ) { // MENU OPERATION - FILLET 2D
+ id == 509 || // MENU OPERATION - FILLET 2D
+ id == 510 ) { // MENU OPERATION - FILLET 1D
#ifndef WNT
library = getLibrary( "libOperationGUI.so" );
#else
@@ -842,6 +843,7 @@ void GeometryGUI::initialize( CAM_Application* app )
createGeomAction( 506, "CHAMFER" );
//createGeomAction( 507, "CLIPPING" );
createGeomAction( 508, "GET_SHAPES_ON_SHAPES" );
+ createGeomAction( 510, "FILLET_1D" );
createGeomAction( 509, "FILLET_2D" );
createGeomAction( 9998, "MUL_TRANSFORM" );
@@ -1001,6 +1003,7 @@ void GeometryGUI::initialize( CAM_Application* app )
createMenu( 504, operId, -1 );
createMenu( 508, operId, -1 );
createMenu( separator(), operId, -1 );
+ createMenu( 510, transId, -1 );
createMenu( 509, transId, -1 );
createMenu( 505, transId, -1 );
createMenu( 506, transId, -1 );
diff --git a/src/GEOMImpl/GEOMImpl.pro b/src/GEOMImpl/GEOMImpl.pro
index 87d10eaee..1af0cc929 100644
--- a/src/GEOMImpl/GEOMImpl.pro
+++ b/src/GEOMImpl/GEOMImpl.pro
@@ -108,6 +108,7 @@ SOURCES += GEOMImpl_ArcDriver.cxx
SOURCES += GEOMImpl_SplineDriver.cxx
SOURCES += GEOMImpl_SketcherDriver.cxx
SOURCES += GEOMImpl_FilletDriver.cxx
+SOURCES += GEOMImpl_Fillet1dDriver.cxx
SOURCES += GEOMImpl_Fillet2dDriver.cxx
SOURCES += GEOMImpl_ChamferDriver.cxx
SOURCES += GEOMImpl_BooleanDriver.cxx
diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.cxx b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx
new file mode 100644
index 000000000..27153dbb4
--- /dev/null
+++ b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx
@@ -0,0 +1,759 @@
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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
+//
+// File : GEOMImpl_Fillet1d.cxx
+// Module : GEOMImpl
+
+#include "GEOMImpl_Fillet1d.hxx"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * class GEOMImpl_Fillet1d
+ */
+
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1d::GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane)
+: myEdgesExchnged( Standard_False )
+{
+ myPlane = new Geom_Plane(thePlane);
+
+ BRepAdaptor_Curve aBAC1(theEdge1);
+ BRepAdaptor_Curve aBAC2(theEdge2);
+ if (aBAC1.GetType() < aBAC2.GetType())
+ { // first curve must be more complicated
+ myEdge1 = theEdge2;
+ myEdge2 = theEdge1;
+ myEdgesExchnged = Standard_True;
+ }
+ else
+ {
+ myEdge1 = theEdge1;
+ myEdge2 = theEdge2;
+ }
+
+ Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(myEdge1, myStart1, myEnd1);
+ Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(myEdge2, myStart2, myEnd2);
+
+ myCurve1 = GeomProjLib::Curve2d(aCurve1, myStart1, myEnd1, myPlane);
+ myCurve2 = GeomProjLib::Curve2d(aCurve2, myStart2, myEnd2, myPlane);
+
+ while (myCurve1->IsPeriodic() && myStart1 >= myEnd1)
+ myEnd1 += myCurve1->Period();
+ while (myCurve2->IsPeriodic() && myStart2 >= myEnd2)
+ myEnd2 += myCurve2->Period();
+
+ if (aBAC1.GetType() == aBAC2.GetType())
+ {
+ if (myEnd2 - myStart2 < myEnd1 - myStart1)
+ { // first curve must be parametrically shorter
+ TopoDS_Edge anEdge = myEdge1;
+ myEdge1 = myEdge2;
+ myEdge2 = anEdge;
+ Handle(Geom2d_Curve) aCurve = myCurve1;
+ myCurve1 = myCurve2;
+ myCurve2 = aCurve;
+ Standard_Real a = myStart1;
+ myStart1 = myStart2;
+ myStart2 = a;
+ a = myEnd1;
+ myEnd1 = myEnd2;
+ myEnd2 = a;
+ myEdgesExchnged = Standard_True;
+ }
+ }
+}
+
+//=======================================================================
+//function : isRadiusIntersected
+//purpose : local function
+//=======================================================================
+static Standard_Boolean isRadiusIntersected(const Handle(Geom2d_Curve)& theCurve,
+ const gp_Pnt2d theStart,
+ const gp_Pnt2d theEnd,
+ const Standard_Boolean theStartConnected)
+{
+ const Standard_Real aTol = Precision::Confusion();
+ const Standard_Real anAngTol = Precision::Angular();
+ Geom2dAPI_InterCurveCurve anInter(theCurve, new Geom2d_Line(theStart,
+ gp_Dir2d(gp_Vec2d(theStart, theEnd))), aTol);
+ Standard_Integer a;
+ gp_Pnt2d aPoint;
+ for(a = anInter.NbPoints(); a > 0; a--)
+ {
+ aPoint = anInter.Point(a);
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ }
+ Handle(Geom2d_Curve) aCurve;
+ for(a = anInter.NbSegments(); a > 0; a--)
+ {
+ anInter.Segment(a, aCurve);
+ aPoint = aCurve->Value(aCurve->FirstParameter());
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ aPoint = aCurve->Value(aCurve->LastParameter());
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+
+//=======================================================================
+//function : fillPoint
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::fillPoint(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ gp_Pnt2d aPoint;
+ gp_Vec2d aVec;
+ const Standard_Real aTol = Precision::Confusion();
+ myCurve1->D1(thePoint->GetParam(), aPoint, aVec);
+ if (aVec.SquareMagnitude() < aTol)
+ return;
+
+ gp_Vec2d aPerp(((myStartSide)?-1:1) * aVec.Y(), ((myStartSide)?1:-1) * aVec.X());
+ aPerp.Normalize();
+ aPerp.Multiply(myRadius);
+ gp_Pnt2d aCenter = aPoint.Translated(aPerp);
+ thePoint->SetCenter(aCenter);
+
+ // on the intersection point
+ Standard_Boolean aValid = Standard_True;
+ Geom2dAPI_ProjectPointOnCurve aProjInt(aPoint, myCurve2);
+ if (aProjInt.NbPoints() && aPoint.Distance(aProjInt.NearestPoint()) < aTol)
+ aValid = Standard_False;
+ else
+ aValid = !isRadiusIntersected(myCurve2, aPoint, aCenter, Standard_True);
+
+ Geom2dAPI_ProjectPointOnCurve aProj(aCenter, myCurve2);
+ Standard_Integer a, aNB = aProj.NbPoints();
+ for(a = aNB; a > 0; a--)
+ {
+ if (aPoint.Distance(aProj.Point(a)) < aTol)
+ continue;
+
+ Standard_Boolean aValid2 = aValid;
+ if (aValid2)
+ aValid2 = !isRadiusIntersected(myCurve1, aCenter, aProj.Point(a), Standard_False);
+
+ // checking the right parameter
+ Standard_Real aParam = aProj.Parameter(a);
+ while(myCurve2->IsPeriodic() && aParam < myStart2)
+ aParam += myCurve2->Period();
+
+ thePoint->AddValue(aProj.Distance(a) * aProj.Distance(a) - myRadius * myRadius,
+ (aParam >= myStart2 && aParam <= myEnd2 && aValid2));
+ if (fabs(fabs(aProj.Distance(a)) - myRadius) < aTol)
+ thePoint->SetParam2(aParam);
+ }
+}
+
+//=======================================================================
+//function : fillDiff
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::fillDiff(GEOMImpl_Fillet1dPoint* thePoint, Standard_Real theDiffStep, Standard_Boolean theFront)
+{
+ GEOMImpl_Fillet1dPoint* aDiff =
+ new GEOMImpl_Fillet1dPoint(thePoint->GetParam() + (theFront?(theDiffStep):(-theDiffStep)));
+ fillPoint(aDiff);
+ if (!thePoint->ComputeDifference(aDiff))
+ {
+ aDiff->SetParam(thePoint->GetParam() + (theFront?(-theDiffStep):(theDiffStep)));
+ fillPoint(aDiff);
+ thePoint->ComputeDifference(aDiff);
+ }
+ delete aDiff;
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius)
+{
+ myResultParams.Clear();
+ myResultOrientation.Clear();
+
+ Standard_Real aNBSteps = 100;
+ Geom2dAdaptor_Curve aGAC(myCurve1);
+ switch (aGAC.GetType())
+ {
+ case GeomAbs_Line:
+ aNBSteps = 2;
+ break;
+ case GeomAbs_Circle:
+ aNBSteps = 4;
+ break;
+ case GeomAbs_Ellipse:
+ aNBSteps = 5;
+ break;
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ aNBSteps = 2 + aGAC.Degree() * aGAC.NbPoles();
+ break;
+ default: // unknown: maximum
+ aNBSteps = 100;
+ }
+
+ myRadius = theRadius;
+ Standard_Real aParam, aStep, aDStep;
+ aStep = (myEnd1 - myStart1) / aNBSteps;
+ aDStep = aStep/1000.;
+
+ Standard_Integer aCycle;
+ for(aCycle = 2, myStartSide = Standard_False; aCycle; myStartSide = !myStartSide, aCycle--)
+ {
+ GEOMImpl_Fillet1dPoint *aLeft = NULL, *aRight = NULL;
+
+ for(aParam = myStart1 + aStep; aParam < myEnd1 || fabs(myEnd1 - aParam) < Precision::Confusion(); aParam += aStep)
+ {
+ if (!aLeft)
+ {
+ aLeft = new GEOMImpl_Fillet1dPoint(aParam - aStep);
+ fillPoint(aLeft);
+ fillDiff(aLeft, aDStep, Standard_True);
+ }
+
+ aRight = new GEOMImpl_Fillet1dPoint(aParam);
+ fillPoint(aRight);
+ fillDiff(aRight, aDStep, Standard_False);
+
+ aLeft->FilterPoints(aRight);
+ performNewton(aLeft, aRight);
+
+ delete aLeft;
+ aLeft = aRight;
+ }
+ delete aLeft;
+ }
+
+ if (myResultParams.Extent())
+ return Standard_True;
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : processPoint
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1d::processPoint(GEOMImpl_Fillet1dPoint* theLeft,
+ GEOMImpl_Fillet1dPoint* theRight,
+ Standard_Real theParameter)
+{
+ if (theParameter >= theLeft->GetParam() && theParameter < theRight->GetParam())
+ {
+ Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
+ if (theParameter - theLeft->GetParam() < aDX / 100.)
+ {
+ theParameter = theLeft->GetParam() + aDX / 100.;
+ }
+ if (theRight->GetParam() - theParameter < aDX / 100.)
+ {
+ theParameter = theRight->GetParam() - aDX / 100.;
+ }
+
+ GEOMImpl_Fillet1dPoint* aPoint1 = theLeft->Copy();
+ GEOMImpl_Fillet1dPoint* aPoint2 = new GEOMImpl_Fillet1dPoint(theParameter);
+ fillPoint(aPoint2);
+ fillDiff(aPoint2, aDX / 1000., Standard_True);
+
+ aPoint1->FilterPoints(aPoint2);
+ performNewton(aPoint1, aPoint2);
+ aPoint2->FilterPoints(theRight);
+ performNewton(aPoint2, theRight);
+
+ delete aPoint1;
+ delete aPoint2;
+ return Standard_True;
+ }
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : performNewton
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::performNewton(GEOMImpl_Fillet1dPoint* theLeft,
+ GEOMImpl_Fillet1dPoint* theRight)
+{
+ Standard_Integer a;
+ // check the left: if this is solution store it and remove it from the list of researching points of theLeft
+ a = theLeft->HasSolution(myRadius);
+ if (a)
+ {
+ if (theLeft->IsValid(a))
+ {
+ myResultParams.Append(theLeft->GetParam());
+ myResultOrientation.Append(myStartSide);
+ }
+ return;
+ }
+
+ Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
+ if (aDX < gp::Resolution()/*Precision::Confusion() / 1000000.*/)
+ {
+ a = theRight->HasSolution(myRadius);
+ if (a)
+ if (theRight->IsValid(a))
+ {
+ myResultParams.Append(theRight->GetParam());
+ myResultOrientation.Append(myStartSide);
+ }
+ return;
+ }
+
+ for(a = 1; a <= theLeft->GetNBValues(); a++)
+ {
+ Standard_Integer aNear = theLeft->GetNear(a);
+
+ Standard_Real aA = (theRight->GetDiff(aNear) - theLeft->GetDiff(a)) / aDX;
+ Standard_Real aB = theLeft->GetDiff(a) - aA * theLeft->GetParam();
+ Standard_Real aC = theLeft->GetValue(a) - theLeft->GetDiff(a) * theLeft->GetParam() +
+ aA * theLeft->GetParam() * theLeft->GetParam() / 2.0;
+ Standard_Real aDet = aB * aB - 2.0 * aA * aC;
+
+ if (fabs(aA) < Precision::Confusion())
+ { // linear case
+ if (fabs(aB) > 10e-20)
+ {
+ Standard_Real aX0 = - aC / aB; // use extremum
+ if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
+ processPoint(theLeft, theRight, aX0);
+ }
+ else
+ {
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ }
+ else
+ {
+ if (fabs(aB) > fabs(aDet * 1000000.))
+ { // possible floating point operations accurancy errors
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ else
+ {
+ if (aDet > 0)
+ { // two solutions
+ aDet = sqrt(aDet);
+ Standard_Boolean aRes = processPoint(theLeft, theRight, (- aB + aDet) / aA);
+ if (!aRes)
+ aRes = processPoint(theLeft, theRight, (- aB - aDet) / aA);
+ if (!aRes)
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ else
+ {
+ Standard_Real aX0 = - aB / aA; // use extremum
+ if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
+ processPoint(theLeft, theRight, aX0);
+ else
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : Result
+//purpose :
+//=======================================================================
+TopoDS_Edge GEOMImpl_Fillet1d::Result(const gp_Pnt& thePoint,
+ TopoDS_Edge& theEdge1,
+ TopoDS_Edge& theEdge2)
+{
+ TopoDS_Edge aResult;
+ gp_Pnt2d aTargetPoint2d;
+ Standard_Real aX, aY;
+ ElSLib::PlaneParameters(myPlane->Pln().Position(), thePoint, aX, aY);
+ aTargetPoint2d.SetCoord(aX, aY);
+
+ // choose the nearest circle
+ Standard_Real aDistance, aP;
+ GEOMImpl_Fillet1dPoint *aNearest;
+ Standard_Integer a;
+ TColStd_ListIteratorOfListOfReal anIter(myResultParams);
+ for(aNearest = NULL, a = 1; anIter.More(); anIter.Next(), a++)
+ {
+ myStartSide = (myResultOrientation.Value(a)) ? Standard_True : Standard_False;
+ GEOMImpl_Fillet1dPoint *aPoint = new GEOMImpl_Fillet1dPoint(anIter.Value());
+ fillPoint(aPoint);
+ if (!aPoint->HasSolution(myRadius))
+ continue;
+ aP = fabs(aPoint->GetCenter().Distance(aTargetPoint2d) - myRadius);
+ if (!aNearest || aP < aDistance)
+ {
+ aNearest = aPoint;
+ aDistance = aP;
+ }
+ else
+ {
+ delete aPoint;
+ }
+ }
+
+ if (!aNearest)
+ return aResult;
+
+ // create circle edge
+ gp_Pnt aCenter = ElSLib::PlaneValue(aNearest->GetCenter().X(),
+ aNearest->GetCenter().Y(),
+ myPlane->Pln().Position());
+ Handle(Geom_Circle) aCircle =
+ new Geom_Circle(gp_Ax2(aCenter, myPlane->Pln().Axis().Direction()), myRadius);
+ gp_Pnt2d aPoint2d1, aPoint2d2;
+ myCurve1->D0(aNearest->GetParam(), aPoint2d1);
+ myCurve2->D0(aNearest->GetParam2(), aPoint2d2);
+ gp_Pnt aPoint1 = ElSLib::PlaneValue(aPoint2d1.X(), aPoint2d1.Y(), myPlane->Pln().Position());
+ gp_Pnt aPoint2 = ElSLib::PlaneValue(aPoint2d2.X(), aPoint2d2.Y(), myPlane->Pln().Position());
+
+ GeomAPI_ProjectPointOnCurve aProj(thePoint, aCircle);
+ Standard_Real aTarGetParam = aProj.LowerDistanceParameter();
+ gp_Pnt aPointOnCircle = aProj.NearestPoint();
+
+ // Check extrema point manually, because there is a bug in Open CASCADE
+ // in calculation of nearest point to a circle near the parameter 0.0
+ gp_Pnt p0 = ElCLib::Value(0.0, aCircle->Circ());
+ if (p0.Distance(thePoint) < aPointOnCircle.Distance(thePoint))
+ {
+ aTarGetParam = 0.0;
+ aPointOnCircle = p0;
+ }
+
+ aProj.Perform(aPoint1);
+ Standard_Real aParam1 = aProj.LowerDistanceParameter();
+ aProj.Perform(aPoint2);
+ Standard_Real aParam2 = aProj.LowerDistanceParameter();
+ Standard_Boolean aIsOut = ((aParam1 < aTarGetParam && aParam2 < aTarGetParam) ||
+ (aParam1 > aTarGetParam && aParam2 > aTarGetParam));
+ if (aParam1 > aParam2)
+ aIsOut = !aIsOut;
+ BRepBuilderAPI_MakeEdge aBuilder(aCircle->Circ(),
+ aIsOut ? aParam2 : aParam1,
+ aIsOut? aParam1 : aParam2);
+ aResult = aBuilder.Edge();
+
+ // divide edges
+ Standard_Real aStart, anEnd;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge1, aStart, anEnd);
+ gp_Vec aDir;
+ aCurve->D1(aNearest->GetParam(), aPoint1, aDir);
+
+ gp_Vec aCircleDir;
+ aCircle->D1(aParam1, aPoint1, aCircleDir);
+ if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ aIsOut)
+ aStart = aNearest->GetParam();
+ else
+ anEnd = aNearest->GetParam();
+
+ //Check the case when start and end are identical. This happens
+ //when the edge decreases to size 0. Old ww5 allows such
+ //cases. So we are again bug compatible
+ if (fabs(aStart - anEnd) < Precision::PConfusion()/*gp::Resolution()*/)
+ anEnd = 0.01;
+ //Divide edge
+ BRepBuilderAPI_MakeEdge aDivider1(aCurve, aStart, anEnd);
+ if (myEdgesExchnged)
+ theEdge2 = aDivider1.Edge();
+ else
+ theEdge1 = aDivider1.Edge();
+
+
+ aCurve = BRep_Tool::Curve(myEdge2, aStart, anEnd);
+ aCurve->D1(aNearest->GetParam2(), aPoint2, aDir);
+
+ aCircle->D1(aParam2, aPoint2, aCircleDir);
+ if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ (!aIsOut))
+ aStart = aNearest->GetParam2();
+ else
+ anEnd = aNearest->GetParam2();
+
+ //Check the case when start and end are identical. This happens
+ //when the edge decreases to size 0. Old ww5 allows such
+ //cases. So we are again bug compatible
+ if (fabs(aStart - anEnd) < Precision::PConfusion()/*gp::Resolution()*/)
+ anEnd = 0.01;
+ BRepBuilderAPI_MakeEdge aDivider2(aCurve, aStart, anEnd);
+ if (myEdgesExchnged)
+ theEdge1 = aDivider2.Edge();
+ else
+ theEdge2 = aDivider2.Edge();
+
+ delete aNearest;
+ return aResult;
+}
+
+//=======================================================================
+//function : AddValue
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::AddValue(Standard_Real theValue, Standard_Boolean theValid)
+{
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ if (theValue < myV.Value(a))
+ {
+ myV.InsertBefore(a, theValue);
+ myValid.InsertBefore(a, (Standard_Integer)theValid);
+ return;
+ }
+ }
+ myV.Append(theValue);
+ myValid.Append((Standard_Integer)theValid);
+}
+
+//=======================================================================
+//function : ComputeDifference
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1dPoint::ComputeDifference(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ Standard_Integer a;
+ Standard_Boolean aDiffsSet = (myD.Length() != 0);
+ Standard_Real aDX = thePoint->GetParam() - myParam, aDY;
+ if (thePoint->myV.Length() == myV.Length())
+ { // absolutely the same points
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ aDY = thePoint->myV.Value(a) - myV.Value(a);
+ if (aDiffsSet)
+ myD.SetValue(a, aDY / aDX);
+ else
+ myD.Append(aDY / aDX);
+ }
+ return Standard_True;
+ }
+ // between the diffeerent points searching for nearest analogs
+ Standard_Integer b;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ for(b = 1; b <= thePoint->myV.Length(); b++)
+ {
+ if (b == 1 || fabs(thePoint->myV.Value(b) - myV.Value(a)) < fabs(aDY))
+ aDY = thePoint->myV.Value(b) - myV.Value(a);
+ }
+ if (aDiffsSet)
+ {
+ if (fabs(aDY / aDX) < fabs(myD.Value(a)))
+ myD.SetValue(a, aDY / aDX);
+ }
+ else
+ {
+ myD.Append(aDY / aDX);
+ }
+ }
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : FilterPoints
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::FilterPoints(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ Standard_Integer a, b;
+ TColStd_SequenceOfReal aDiffs;
+ Standard_Real aY, aY2, aDX = thePoint->GetParam() - myParam;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ // searching for near point from thePoint
+ Standard_Integer aNear = 0;
+ Standard_Real aDiff = aDX * 10000.;
+ aY = myV.Value(a) + myD.Value(a) * aDX;
+ for(b = 1; b <= thePoint->myV.Length(); b++)
+ {
+ // calculate hypothesis value of the Y2 with the constant first and second derivative
+ aY2 = aY + aDX * (thePoint->myD.Value(b) - myD.Value(a)) / 2.0;
+ if (aNear == 0 || fabs(aY2 - thePoint->myV.Value(b)) < fabs(aDiff))
+ {
+ aNear = b;
+ aDiff = aY2 - thePoint->myV.Value(b);
+ }
+ }//for b...
+
+ if (aNear)
+ {
+ if (myV.Value(a) * thePoint->myV.Value(aNear) > 0)
+ {// the same sign at the same sides of the interval
+ if (myV.Value(a) * myD.Value(a) > 0)
+ {
+ if (fabs(myD.Value(a)) > Precision::Confusion())
+ aNear = 0;
+ }
+ else
+ {
+ if (fabs(myV.Value(a)) > fabs(thePoint->myV.Value(aNear)))
+ if (thePoint->myV.Value(aNear) * thePoint->myD.Value(aNear) < 0 &&
+ fabs(thePoint->myD.Value(aNear)) > Precision::Confusion())
+ {
+ aNear = 0;
+ }
+ }
+ }
+ }
+
+ if (aNear)
+ {
+ if (myV.Value(a) * thePoint->myV.Value(aNear) > 0)
+ {
+ if ((myV.Value(a) + myD.Value(a) * aDX) * myV.Value(a) > Precision::Confusion() &&
+ (thePoint->myV.Value(aNear) + thePoint->myD.Value(aNear) * aDX) * thePoint->myV.Value(aNear) > Precision::Confusion())
+ {
+ aNear = 0;
+ }
+ }
+ }
+
+ if (aNear)
+ {
+ if (fabs(aDiff / aDX) > 1.e+7)
+ {
+ aNear = 0;
+ }
+ }
+
+ if (aNear == 0)
+ { // there is no near: remove it from the list
+ myV.Remove(a);
+ myD.Remove(a);
+ myValid.Remove(a);
+ a--;
+ }
+ else
+ {
+ Standard_Boolean aFound = Standard_False;
+ for(b = 1; b <= myNear.Length(); b++)
+ {
+ if (myNear.Value(b) == aNear)
+ {
+ if (fabs(aDiffs.Value(b)) < fabs(aDiff))
+ { // return this 'near'
+ aFound = Standard_True;
+ myV.Remove(a);
+ myD.Remove(a);
+ myValid.Remove(a);
+ a--;
+ break;
+ }
+ else
+ { // remove the old 'near'
+ myV.Remove(b);
+ myD.Remove(b);
+ myValid.Remove(b);
+ myNear.Remove(b);
+ aDiffs.Remove(b);
+ a--;
+ break;
+ }
+ }
+ }//for b...
+ if (!aFound)
+ {
+ myNear.Append(aNear);
+ aDiffs.Append(aDiff);
+ }
+ }
+ }//for a...
+}
+
+//=======================================================================
+//function : Copy
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1dPoint* GEOMImpl_Fillet1dPoint::Copy()
+{
+ GEOMImpl_Fillet1dPoint* aCopy = new GEOMImpl_Fillet1dPoint(myParam);
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ aCopy->myV.Append(myV.Value(a));
+ aCopy->myD.Append(myD.Value(a));
+ aCopy->myValid.Append(myValid.Value(a));
+ }
+ return aCopy;
+}
+
+//=======================================================================
+//function : HasSolution
+//purpose :
+//=======================================================================
+Standard_Integer GEOMImpl_Fillet1dPoint::HasSolution(const Standard_Real theRadius)
+{
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ if (fabs(sqrt(fabs(fabs(myV.Value(a)) + theRadius * theRadius)) - theRadius) < Precision::Confusion() / 10.)
+ return a;
+ }
+ return 0;
+}
+
+//=======================================================================
+//function : RemoveSolution
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::RemoveSolution(Standard_Integer theIndex)
+{
+ myV.Remove(theIndex);
+ myD.Remove(theIndex);
+ myValid.Remove(theIndex);
+ myNear.Remove(theIndex);
+}
diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.hxx b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx
new file mode 100644
index 000000000..90c5ae9e8
--- /dev/null
+++ b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx
@@ -0,0 +1,141 @@
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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
+//
+// File : GEOMImpl_Fillet1d.hxx
+// Module : GEOMImpl
+
+#ifndef _GEOMImpl_Fillet1d_HeaderFile
+#define _GEOMImpl_Fillet1d_HeaderFile
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+class GEOMImpl_Fillet1dPoint;
+
+/**
+* GEOMImpl_Fillet1d is 1D fillet algorithm on two planar edges with given radius
+*/
+
+class GEOMImpl_Fillet1d
+{
+public:
+ //! Constructor
+ //! The fillet 1D algorithm initialise by two edges and plane
+ Standard_EXPORT GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane);
+ //! Makes fillet with given radius
+ //! @returns Standard_True, if at least one result computed
+ Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);
+ //! Returns result fillet edge and modified edges as out parameters
+ Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2);
+
+private:
+ //! private methods
+ void fillPoint(GEOMImpl_Fillet1dPoint*);
+ void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean);
+ void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);
+ Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);
+
+
+private:
+ //! private fields
+ TopoDS_Edge myEdge1, myEdge2;
+ Handle(Geom_Plane) myPlane;
+ Handle(Geom2d_Curve) myCurve1, myCurve2;
+ Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;
+ TColStd_ListOfReal myResultParams;
+ TColStd_SequenceOfInteger myResultOrientation;
+ Standard_Boolean myStartSide, myEdgesExchnged;
+};
+
+
+/**
+* GEOMImpl_Fillet1dPoint is an internal class for 1D fillet algorithm
+* to store and compare computed solutions on edges
+*/
+
+class GEOMImpl_Fillet1dPoint
+{
+public:
+ //! Puiblic methods
+
+ //! Constructor
+ Standard_EXPORT GEOMImpl_Fillet1dPoint(Standard_Real theParam)
+ {myParam = theParam;}
+
+ //! Make copy of point
+ //!WARNING: Copies only field values: myParam, myV, myD, myValid
+ Standard_EXPORT GEOMImpl_Fillet1dPoint* Copy(); // warning: this is not the full copy!
+
+ //! Set/Get parameter
+ Standard_EXPORT inline void SetParam(Standard_Real theParam)
+ {myParam = theParam;}
+ Standard_EXPORT inline Standard_Real GetParam() const
+ {return myParam;}
+ Standard_EXPORT inline void SetParam2(const Standard_Real theParam2)
+ {myParam2 = theParam2;}
+ Standard_EXPORT inline Standard_Real GetParam2()
+ { return myParam2 ; }
+
+ //! Returns validity
+ Standard_EXPORT inline Standard_Boolean IsValid(int theIndex)
+ {return (Standard_Boolean)myValid.Value(theIndex);}
+
+ //! Get values
+ Standard_EXPORT inline Standard_Integer GetNBValues() {return myV.Length();}
+ Standard_EXPORT inline Standard_Real GetValue(Standard_Integer theIndex)
+ {return myV.Value(theIndex);}
+ Standard_EXPORT inline Standard_Real GetDiff(Standard_Integer theIndex)
+ {return myD.Value(theIndex);}
+ Standard_EXPORT inline Standard_Integer GetNear(Standard_Integer theIndex)
+ {return myNear.Value(theIndex);}
+
+ //! Set/Get center point
+ Standard_EXPORT inline void SetCenter(const gp_Pnt2d thePoint)
+ {myCenter = thePoint;}
+ Standard_EXPORT inline const gp_Pnt2d GetCenter()
+ {return myCenter;}
+
+ Standard_EXPORT void AddValue(Standard_Real theValue, Standard_Boolean theIsValid);
+
+ //! compute difference between this and given point
+ Standard_EXPORT Standard_Boolean ComputeDifference(GEOMImpl_Fillet1dPoint*);
+ Standard_EXPORT void FilterPoints(GEOMImpl_Fillet1dPoint*);
+
+ //! Check is point contains solution and returns the index of them if any
+ Standard_EXPORT Standard_Integer HasSolution(Standard_Real theRadius);
+ //! Remove solution by index
+ void RemoveSolution(Standard_Integer theIndex);
+
+private:
+ //! Private fields
+ gp_Pnt2d myCenter;
+ Standard_Real myParam, myParam2;
+ TColStd_SequenceOfReal myV, myD;
+ TColStd_SequenceOfInteger myValid, myNear;
+};
+
+#endif
diff --git a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx
new file mode 100644
index 000000000..fc54a402b
--- /dev/null
+++ b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx
@@ -0,0 +1,312 @@
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//=======================================================================
+//function : GetID
+//purpose :
+//=======================================================================
+const Standard_GUID& GEOMImpl_Fillet1dDriver::GetID()
+{
+ static Standard_GUID aFillet1dDriver("FF60908B-AB2E-4b71-B098-5C256C37D961");
+ return aFillet1dDriver;
+}
+
+//=======================================================================
+//function : GEOMImpl_Fillet1dDriver
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1dDriver::GEOMImpl_Fillet1dDriver()
+{
+}
+
+//=======================================================================
+//function : anotherVertex
+//purpose : local function to get vertex from edge
+//=======================================================================
+static TopoDS_Vertex anotherVertex( const TopoDS_Edge& theE,
+ const TopoDS_Vertex& theV )
+{
+ // here is an assumption that edge has different vertices
+ TopoDS_Vertex aV;
+ TopExp_Explorer anExp( theE, TopAbs_VERTEX );
+ for ( ; anExp.More(); anExp.Next() )
+ {
+ if ( BRepTools::Compare(theV,TopoDS::Vertex(anExp.Current())) /*theV.IsSame(anExp.Current())*/ )
+ continue;
+ aV = TopoDS::Vertex( anExp.Current() );
+ break;
+ }
+ return aV;
+}
+
+//=======================================================================
+//function : takePlane
+//purpose : local function returns plane of given edges
+//=======================================================================
+static Standard_Boolean takePlane( const TopoDS_Edge& theE1,
+ const TopoDS_Edge& theE2,
+ const TopoDS_Vertex& theV,
+ gp_Pln& thePlane )
+{
+ TopoDS_Vertex aV12 = anotherVertex( theE1, theV );
+ TopoDS_Vertex aV22 = anotherVertex( theE2, theV );
+ // check can closed wire be created by two initial edges
+ if ( aV12.IsNull() || aV22.IsNull() || aV12.IsSame( aV22 ) )
+ return false;
+
+ // create plane by 3 points
+ gp_XYZ aXYZ = BRep_Tool::Pnt( theV ).XYZ();
+ gp_XYZ aXYZ1 = BRep_Tool::Pnt( aV12 ).XYZ();
+ gp_XYZ aXYZ2 = BRep_Tool::Pnt( aV22 ).XYZ();
+ try {
+ gp_Dir aDir1( aXYZ - aXYZ1 );
+ gp_Dir aDir2( aXYZ2 - aXYZ );
+ Standard_Real anAngle = aDir1.Angle(aDir2);
+ if ( fabs(anAngle) <= gp::Resolution() ||
+ fabs(anAngle - PI) <= gp::Resolution() )
+ return false;
+ //thePlane = gp_Pln( gp_Pnt(aXYZ), aDir1^ aDir2);
+ thePlane = gp_Pln( gp_Pnt(aXYZ), gp_Dir(0,0,1));
+ }
+ catch (Standard_Failure) {
+ return false;
+ }
+ return true;
+}
+
+//=======================================================================
+//function : addEdgeRelation
+//purpose : local function to remember relation between initial and modified edge
+//=======================================================================
+static void addEdgeRelation(TopTools_DataMapOfShapeShape& theMap,
+ const TopoDS_Edge& theInitE,
+ const TopoDS_Edge& theResE)
+{
+ if ( theMap.IsBound( theInitE ) )
+ theMap.ChangeFind( theInitE ) = theResE;
+ else
+ theMap.Bind( theInitE, theResE );
+}
+
+//=======================================================================
+//function : Execute
+//purpose :
+//=======================================================================
+Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
+{
+ if (Label().IsNull()) return 0;
+ Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+
+ GEOMImpl_IFillet1d aCI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = aCI.GetShape();
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.ShapeType() != TopAbs_WIRE)
+ Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");
+
+ TopoDS_Wire aWire = TopoDS::Wire(aShape);
+
+ double rad = aCI.GetR();
+
+ // collect vertices for make fillet
+ TopTools_ListOfShape aVertexList;
+ int aLen = aCI.GetLength();
+ if ( aLen > 0 )
+ {
+ for (int ind = 1; ind <= aLen; ind++) {
+ TopoDS_Shape aShapeVertex;
+ if (GEOMImpl_ILocalOperations::GetSubShape
+ (aWire, aCI.GetVertex(ind), aShapeVertex))
+ aVertexList.Append( aShapeVertex );
+ }
+ }
+ else
+ {
+ // get all vertices from wire
+ TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
+ for ( ; anExp.More(); anExp.Next() )
+ aVertexList.Append( anExp.Current() );
+ }
+ if (aVertexList.IsEmpty())
+ Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");
+
+ bool res = false;
+ //INFO: this algorithm implemented in assumption that user can select both
+ // vertices of some edges to make fillet. In this case we should remember
+ // already modified initial edges to take care in next fillet step
+ TopTools_DataMapOfShapeShape anEdgeToEdgeMap;
+
+ //iterates on vertices, and make fillet on each couple of edges
+ //collect result fillet edges in list
+ TopTools_ListOfShape aListOfNewEdge;
+ // remember relation between initial and modified map
+ TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
+ TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
+ TopTools_ListIteratorOfListOfShape anIt( aVertexList );
+ for ( ; anIt.More(); anIt.Next() )
+ {
+ TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
+ if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
+ continue;
+ const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
+ if ( aVertexEdges.Extent() != 2 )
+ continue; // no input data to make fillet
+ TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
+ TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
+ // check if initial edges already modified in previous fillet operation
+ if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
+ if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
+ if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
+ continue; //no input data to make fillet
+
+ // create plane on 2 edges
+ gp_Pln aPlane;
+ if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
+ continue; // seems edges does not belong to same plane or parallel (fillet can not be build)
+
+ GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
+ if ( !aFilletAlgo.Perform(rad) )
+ continue; // can not create fillet with given radius
+
+ // take fillet result in given vertex
+ TopoDS_Edge aModifE1, aModifE2;
+ TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
+ if (aNewE.IsNull())
+ continue; // no result found
+
+ res |= true;
+ // add new created edges and take modified edges
+ aListOfNewEdge.Append( aNewE );
+
+ // check if face edges modified,
+ // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
+ if (!aModifE1.IsNull() || !aModifE1.IsSame( anEdge1 ))
+ addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
+ if (!aModifE2.IsNull() || !aModifE2.IsSame( anEdge2 ))
+ addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
+ }
+
+ if ( !res && anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() )
+ {
+ StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
+ return 0; // nothing done :(
+ }
+
+ // create new wire instead of original
+ for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() )
+ {
+ TopoDS_Shape anEdge = anExp.Current();
+ if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
+ aListOfNewEdge.Append( anEdge );
+ else
+ aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
+ }
+ BRepBuilderAPI_MakeWire aWireTool;
+ aWireTool.Add( aListOfNewEdge );
+ aWireTool.Build();
+ if (!aWireTool.IsDone())
+ return 0;
+
+ aWire = aWireTool.Wire();
+ aFunction->SetValue(aWire);
+ log.SetTouched(Label());
+
+ return 1;
+}
+
+
+//=======================================================================
+//function : GEOMImpl_Fillet1dDriver_Type_
+//purpose :
+//=======================================================================
+Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet1dDriver_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);
+ if ( aType2.IsNull()) 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_Fillet1dDriver",
+ sizeof(GEOMImpl_Fillet1dDriver),
+ 1,
+ (Standard_Address)_Ancestors,
+ (Standard_Address)NULL);
+
+ return _aType;
+}
+
+//=======================================================================
+//function : DownCast
+//purpose :
+//=======================================================================
+const Handle(GEOMImpl_Fillet1dDriver) Handle(GEOMImpl_Fillet1dDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
+{
+ Handle(GEOMImpl_Fillet1dDriver) _anOtherObject;
+
+ if (!AnObject.IsNull()) {
+ if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_Fillet1dDriver))) {
+ _anOtherObject = Handle(GEOMImpl_Fillet1dDriver)((Handle(GEOMImpl_Fillet1dDriver)&)AnObject);
+ }
+ }
+
+ return _anOtherObject ;
+}
diff --git a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx
new file mode 100644
index 000000000..a8aeb60e7
--- /dev/null
+++ b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx
@@ -0,0 +1,160 @@
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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
+//
+// File : GEOMImpl_Fillet1dDriver.ixx
+// Module : GEOMImpl
+
+#ifndef _GEOMImpl_Fillet1dDriver_HeaderFile
+#define _GEOMImpl_Fillet1dDriver_HeaderFile
+
+#ifndef _TColStd_SequenceOfExtendedString_HeaderFile
+#include
+#endif
+#ifndef _Standard_TypeMismatch_HeaderFile
+#include
+#endif
+
+#ifndef _Standard_HeaderFile
+#include
+#endif
+
+#ifndef _Standard_Macro_HeaderFile
+#include
+#endif
+#ifndef _Standard_HeaderFile
+#include
+#endif
+#ifndef _Standard_GUID_HeaderFile
+#include
+#endif
+
+#ifndef _Handle_TFunction_Driver_HeaderFile
+#include
+#endif
+
+class Standard_Transient;
+class Handle_Standard_Type;
+class Handle(TFunction_Driver);
+class GEOMImpl_Fillet1dDriver;
+
+Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOMImpl_Fillet1dDriver);
+
+class Handle(GEOMImpl_Fillet1dDriver) : public Handle(TFunction_Driver) {
+ public:
+ inline void* operator new(size_t,void* anAddress)
+ {
+ return anAddress;
+ }
+ inline void* operator new(size_t size)
+ {
+ return Standard::Allocate(size);
+ }
+ inline void operator delete(void *anAddress)
+ {
+ if (anAddress) Standard::Free((Standard_Address&)anAddress);
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)():Handle(TFunction_Driver)() {}
+ Handle(GEOMImpl_Fillet1dDriver)(const Handle(GEOMImpl_Fillet1dDriver)& aHandle) : Handle(TFunction_Driver)(aHandle)
+ {
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)(const GEOMImpl_Fillet1dDriver* anItem) : Handle(TFunction_Driver)((TFunction_Driver *)anItem)
+ {
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)& operator=(const Handle(GEOMImpl_Fillet1dDriver)& aHandle)
+ {
+ Assign(aHandle.Access());
+ return *this;
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)& operator=(const GEOMImpl_Fillet1dDriver* anItem)
+ {
+ Assign((Standard_Transient *)anItem);
+ return *this;
+ }
+
+ GEOMImpl_Fillet1dDriver* operator->()
+ {
+ return (GEOMImpl_Fillet1dDriver *)ControlAccess();
+ }
+
+ GEOMImpl_Fillet1dDriver* operator->() const
+ {
+ return (GEOMImpl_Fillet1dDriver *)ControlAccess();
+ }
+
+ Standard_EXPORT ~Handle(GEOMImpl_Fillet1dDriver)() {};
+
+ Standard_EXPORT static const Handle(GEOMImpl_Fillet1dDriver) DownCast(const Handle(Standard_Transient)& AnObject);
+};
+
+#ifndef _TFunction_Driver_HeaderFile
+#include
+#endif
+#ifndef _TFunction_Logbook_HeaderFile
+#include
+#endif
+#ifndef _Standard_CString_HeaderFile
+#include
+#endif
+
+class TColStd_SequenceOfExtendedString;
+
+
+class GEOMImpl_Fillet1dDriver : public TFunction_Driver {
+
+public:
+
+ inline void* operator new(size_t,void* anAddress)
+ {
+ return anAddress;
+ }
+ inline void* operator new(size_t size)
+ {
+ return Standard::Allocate(size);
+ }
+ inline void operator delete(void *anAddress)
+ {
+ if (anAddress) Standard::Free((Standard_Address&)anAddress);
+ }
+
+ // Methods PUBLIC
+ //
+Standard_EXPORT GEOMImpl_Fillet1dDriver();
+Standard_EXPORT virtual Standard_Integer Execute(TFunction_Logbook& log) const;
+Standard_EXPORT virtual void Validate(TFunction_Logbook&) const {}
+Standard_EXPORT Standard_Boolean MustExecute(const TFunction_Logbook&) const { return Standard_True; }
+Standard_EXPORT static const Standard_GUID& GetID();
+Standard_EXPORT ~GEOMImpl_Fillet1dDriver() {};
+
+
+ // Type management
+ //
+Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_Fillet1dDriver_Type_();
+Standard_EXPORT const Handle(Standard_Type)& DynamicType() const
+ { return STANDARD_TYPE(GEOMImpl_Fillet1dDriver) ; }
+Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const
+ { return (STANDARD_TYPE(GEOMImpl_Fillet1dDriver) == AType || TFunction_Driver::IsKind(AType)); }
+
+
+};
+
+#endif
diff --git a/src/GEOMImpl/GEOMImpl_Gen.cxx b/src/GEOMImpl/GEOMImpl_Gen.cxx
index b01b3f88a..a920fe3cf 100644
--- a/src/GEOMImpl/GEOMImpl_Gen.cxx
+++ b/src/GEOMImpl/GEOMImpl_Gen.cxx
@@ -62,6 +62,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -134,6 +135,7 @@ GEOMImpl_Gen::GEOMImpl_Gen()
// Local Operations
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ChamferDriver::GetID(), new GEOMImpl_ChamferDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FilletDriver::GetID(), new GEOMImpl_FilletDriver());
+ TFunction_DriverTable::Get()->AddDriver(GEOMImpl_Fillet1dDriver::GetID(), new GEOMImpl_Fillet1dDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_Fillet2dDriver::GetID(), new GEOMImpl_Fillet2dDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ArchimedeDriver::GetID(), new GEOMImpl_ArchimedeDriver());
diff --git a/src/GEOMImpl/GEOMImpl_IFillet1d.hxx b/src/GEOMImpl/GEOMImpl_IFillet1d.hxx
new file mode 100644
index 000000000..daa0ebca9
--- /dev/null
+++ b/src/GEOMImpl/GEOMImpl_IFillet1d.hxx
@@ -0,0 +1,51 @@
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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
+//
+//NOTE: This is an interface to a function for the Fillet1d and creation.
+
+
+#include "GEOM_Function.hxx"
+
+#define FILLET1D_ARG_SH 1
+#define FILLET1D_ARG_R 2
+#define FILLET1D_ARG_LENG 3
+#define FILLET1D_ARG_LAST 4
+
+class GEOMImpl_IFillet1d
+{
+ public:
+
+ GEOMImpl_IFillet1d(Handle(GEOM_Function) theFunction): _func(theFunction) {}
+
+ void SetShape(Handle(GEOM_Function) theRef) { _func->SetReference(FILLET1D_ARG_SH, theRef); }
+ Handle(GEOM_Function) GetShape() { return _func->GetReference(FILLET1D_ARG_SH); }
+
+ void SetR(double theR) { _func->SetReal(FILLET1D_ARG_R, theR); }
+ void SetLength(int theLen) { _func->SetInteger(FILLET1D_ARG_LENG, theLen); }
+ void SetVertex(int theInd, int theVertex)
+ { _func->SetInteger(FILLET1D_ARG_LAST + theInd, theVertex); }
+
+ double GetR() { return _func->GetReal(FILLET1D_ARG_R); }
+ int GetLength() { return _func->GetInteger(FILLET1D_ARG_LENG); }
+ int GetVertex(int theInd) { return _func->GetInteger(FILLET1D_ARG_LAST + theInd); }
+
+ private:
+
+ Handle(GEOM_Function) _func;
+};
diff --git a/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx b/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx
index 9e552229a..61a737697 100644
--- a/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx
+++ b/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx
@@ -29,10 +29,12 @@
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
@@ -481,6 +483,75 @@ Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet2D
return aFillet2D;
}
+//=============================================================================
+/*!
+ * MakeFillet1D
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet1D
+ (Handle(GEOM_Object) theShape, double theR, std::list theVertexes)
+{
+ SetErrorCode(KO);
+
+ //Add a new Fillet object
+ Handle(GEOM_Object) aFillet1D = GetEngine()->AddObject(GetDocID(), GEOM_FILLET_1D);
+
+ //Add a new Fillet function
+ Handle(GEOM_Function) aFunction =
+ aFillet1D->AddFunction(GEOMImpl_Fillet1dDriver::GetID(), FILLET_1D_SHAPE_VERTEXES);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_Fillet1dDriver::GetID()) return NULL;
+
+ GEOMImpl_IFillet1d aCI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ aCI.SetShape(aRefShape);
+ aCI.SetR(theR);
+ int aLen = theVertexes.size();
+ aCI.SetLength(aLen);
+
+ int ind = 1;
+ std::list::iterator it = theVertexes.begin();
+ for (; it != theVertexes.end(); it++, ind++) {
+ aCI.SetVertex(ind, (*it));
+ }
+
+ //Compute the Fillet value
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("1D Fillet driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump pd (aFunction);
+ pd << aFillet1D << " = geompy.MakeFillet1D(" << theShape
+ << ", " << theR << ", [";
+
+ it = theVertexes.begin();
+ pd << (*it++);
+ while (it != theVertexes.end()) {
+ pd << ", " << (*it++);
+ }
+ pd << "])";
+
+ SetErrorCode(OK);
+ return aFillet1D;
+}
+
//=============================================================================
/*!
* MakeChamferAll
diff --git a/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx b/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx
index 15acc6eaf..5bdf61848 100644
--- a/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx
+++ b/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx
@@ -48,6 +48,8 @@ class GEOMImpl_ILocalOperations : public GEOM_IOperations {
std::list theFaces);
Standard_EXPORT Handle(GEOM_Object) MakeFillet2D (Handle(GEOM_Object) theShape, double theR,
std::list theVertexes);
+ Standard_EXPORT Handle(GEOM_Object) MakeFillet1D (Handle(GEOM_Object) theShape, double theR,
+ std::list theVertexes);
Standard_EXPORT Handle(GEOM_Object) MakeChamferAll (Handle(GEOM_Object) theShape, double theD);
Standard_EXPORT Handle(GEOM_Object) MakeChamferEdge (Handle(GEOM_Object) theShape,
diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx
index 01c24ccb0..d1f474acf 100755
--- a/src/GEOMImpl/GEOMImpl_Types.hxx
+++ b/src/GEOMImpl/GEOMImpl_Types.hxx
@@ -49,6 +49,7 @@
#define GEOM_FILLET 20
#define GEOM_FILLET_2D 45
+#define GEOM_FILLET_1D 46
#define GEOM_CHAMFER 21
#define GEOM_EDGE 22
@@ -233,6 +234,7 @@
#define FILLET_SHAPE_FACES_2R 5
#define FILLET_2D_SHAPE_VERTEXES 1
+#define FILLET_1D_SHAPE_VERTEXES 1
#define CHAMFER_SHAPE_ALL 1
#define CHAMFER_SHAPE_EDGE 2
diff --git a/src/GEOMImpl/Makefile.am b/src/GEOMImpl/Makefile.am
index 1c403da1b..0bbbdf176 100644
--- a/src/GEOMImpl/Makefile.am
+++ b/src/GEOMImpl/Makefile.am
@@ -56,6 +56,7 @@ salomeinclude_HEADERS = \
GEOMImpl_ISpline.hxx \
GEOMImpl_IEllipse.hxx \
GEOMImpl_IFillet.hxx \
+ GEOMImpl_IFillet1d.hxx \
GEOMImpl_IFillet2d.hxx \
GEOMImpl_IChamfer.hxx \
GEOMImpl_ICopy.hxx \
@@ -128,6 +129,8 @@ salomeinclude_HEADERS = \
GEOMImpl_SketcherDriver.hxx \
GEOMImpl_3DSketcherDriver.hxx \
GEOMImpl_FilletDriver.hxx \
+ GEOMImpl_Fillet1d.hxx \
+ GEOMImpl_Fillet1dDriver.hxx \
GEOMImpl_Fillet2dDriver.hxx \
GEOMImpl_ChamferDriver.hxx \
GEOMImpl_BooleanDriver.hxx \
@@ -191,6 +194,8 @@ dist_libGEOMimpl_la_SOURCES = \
GEOMImpl_SketcherDriver.cxx \
GEOMImpl_3DSketcherDriver.cxx \
GEOMImpl_FilletDriver.cxx \
+ GEOMImpl_Fillet1d.cxx \
+ GEOMImpl_Fillet1dDriver.cxx \
GEOMImpl_Fillet2dDriver.cxx \
GEOMImpl_ChamferDriver.cxx \
GEOMImpl_BooleanDriver.cxx \
diff --git a/src/GEOM_I/GEOM_ILocalOperations_i.cc b/src/GEOM_I/GEOM_ILocalOperations_i.cc
index 5b3289eec..fe1091f5b 100644
--- a/src/GEOM_I/GEOM_ILocalOperations_i.cc
+++ b/src/GEOM_I/GEOM_ILocalOperations_i.cc
@@ -237,6 +237,38 @@ GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet2D
return GetObject(anObject);
}
+//=============================================================================
+/*!
+ * MakeFillet1D
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet1D
+ (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ const GEOM::ListOfLong& theVertexes)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Get the reference shape (wire)
+ Handle(GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+ if (aShapeRef.IsNull()) return aGEOMObject._retn();
+
+ //Get the reference vertex
+ int ind = 0;
+ int aLen = theVertexes.length();
+ list aVertexes;
+ for (; ind < aLen; ind++) {
+ aVertexes.push_back(theVertexes[ind]);
+ }
+
+ //Create the Fillet
+ Handle(GEOM_Object) anObject =
+ GetOperations()->MakeFillet1D(aShapeRef, theR, aVertexes);
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
//=============================================================================
/*!
* MakeChamferAll
diff --git a/src/GEOM_I/GEOM_ILocalOperations_i.hh b/src/GEOM_I/GEOM_ILocalOperations_i.hh
index e13d37f49..6fa95411a 100644
--- a/src/GEOM_I/GEOM_ILocalOperations_i.hh
+++ b/src/GEOM_I/GEOM_ILocalOperations_i.hh
@@ -63,6 +63,9 @@ class GEOM_I_EXPORT GEOM_ILocalOperations_i :
GEOM::GEOM_Object_ptr MakeFillet2D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
const GEOM::ListOfLong& theVertexes);
+ GEOM::GEOM_Object_ptr MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ const GEOM::ListOfLong& theVertexes);
+
GEOM::GEOM_Object_ptr MakeChamferAll (GEOM::GEOM_Object_ptr theShape, CORBA::Double theD);
GEOM::GEOM_Object_ptr MakeChamferEdge (GEOM::GEOM_Object_ptr theShape,
diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc
index f749b8641..199f1e693 100644
--- a/src/GEOM_I_Superv/GEOM_Superv_i.cc
+++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc
@@ -2850,6 +2850,26 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFillet2D (GEOM::GEOM_Object_ptr theShap
return NULL;
}
+//=============================================================================
+// MakeFillet1D:
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFillet1D (GEOM::GEOM_Object_ptr theShape,
+ CORBA::Double theR,
+ GEOM::GEOM_List_ptr theVertexes)
+{
+ beginService( " GEOM_Superv_i::MakeFillet1D" );
+ MESSAGE("GEOM_Superv_i::MakeFillet1D");
+ if (GEOM_List_i* aListImplV =
+ dynamic_cast*>(GetServant(theVertexes, myPOA).in())) {
+ getLocalOp();
+ GEOM::GEOM_Object_ptr anObj = myLocalOp->MakeFillet1D(theShape, theR, aListImplV->GetList());
+ endService( " GEOM_Superv_i::MakeFillet1D" );
+ return anObj;
+ }
+ endService( " GEOM_Superv_i::MakeFillet1D" );
+ return NULL;
+}
+
//=============================================================================
// MakeChamferAll:
//=============================================================================
diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.hh b/src/GEOM_I_Superv/GEOM_Superv_i.hh
index 1568f0bb1..4ac9969b6 100644
--- a/src/GEOM_I_Superv/GEOM_Superv_i.hh
+++ b/src/GEOM_I_Superv/GEOM_Superv_i.hh
@@ -604,6 +604,8 @@ public:
CORBA::Double theR2, GEOM::GEOM_List_ptr theFaces);
GEOM::GEOM_Object_ptr MakeFillet2D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
GEOM::GEOM_List_ptr theVertexes);
+ GEOM::GEOM_Object_ptr MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ GEOM::GEOM_List_ptr theVertexes);
GEOM::GEOM_Object_ptr MakeChamferAll (GEOM::GEOM_Object_ptr theShape, CORBA::Double theD);
GEOM::GEOM_Object_ptr MakeChamferEdge (GEOM::GEOM_Object_ptr theShape,
CORBA::Double theD1, CORBA::Double theD2,
diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py
index 8cf504f7b..879b02292 100644
--- a/src/GEOM_SWIG/geompyDC.py
+++ b/src/GEOM_SWIG/geompyDC.py
@@ -2716,6 +2716,20 @@ class geompyDC(GEOM._objref_GEOM_Gen):
anObj.SetParameters(Parameters)
return anObj
+ ## Perform a fillet on the specified edges of the given wire shape
+ # @param theShape - Wire Shape(with planar edges) 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_fillet1d "Example"
+ def MakeFillet1D(self,theShape, theR, theListOfVertexes):
+ # Example: see GEOM_TestAll.py
+ anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes)
+ RaiseIfFailed("MakeFillet1D", self.LocalOp)
+ return anObj
+
## Perform a fillet on the specified edges/faces of the given shape
# @param theShape - Face Shape to perform fillet on.
# @param theR - Fillet radius.
@@ -2730,6 +2744,22 @@ class geompyDC(GEOM._objref_GEOM_Gen):
RaiseIfFailed("MakeFillet2D", self.LocalOp)
return anObj
+ ## Perform a fillet on the specified edges of the given shape
+ # @param theShape - Wire 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().
+ # \note The list of vertices could be empty,
+ # in this case fillet will done done at all vertices in wire
+ # @return New GEOM_Object, containing the result shape.
+ #
+ # @ref tui_fillet2d "Example"
+ def MakeFillet1D(self,theShape, theR, theListOfVertexes):
+ # Example: see GEOM_TestAll.py
+ anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes)
+ RaiseIfFailed("MakeFillet1D", self.LocalOp)
+ return anObj
+
## Perform a symmetric chamfer on all edges of the given shape.
# @param theShape Shape, to perform chamfer on.
# @param theD Chamfer size along each face.
diff --git a/src/OperationGUI/Makefile.am b/src/OperationGUI/Makefile.am
index fe874c13d..39ca44890 100644
--- a/src/OperationGUI/Makefile.am
+++ b/src/OperationGUI/Makefile.am
@@ -32,7 +32,7 @@ salomeinclude_HEADERS = \
OperationGUI_ArchimedeDlg.h \
OperationGUI_PartitionDlg.h \
OperationGUI_FilletDlg.h \
- OperationGUI_Fillet2dDlg.h \
+ OperationGUI_Fillet1d2dDlg.h \
OperationGUI_ChamferDlg.h \
OperationGUI_GetShapesOnShapeDlg.h \
OperationGUI_ClippingDlg.h
@@ -46,7 +46,7 @@ dist_libOperationGUI_la_SOURCES = \
OperationGUI_PartitionDlg.cxx \
OperationGUI_GetShapesOnShapeDlg.cxx \
OperationGUI_FilletDlg.cxx \
- OperationGUI_Fillet2dDlg.cxx \
+ OperationGUI_Fillet1d2dDlg.cxx \
OperationGUI_ChamferDlg.cxx \
OperationGUI_ClippingDlg.cxx
@@ -55,7 +55,7 @@ MOC_FILES = \
OperationGUI_PartitionDlg_moc.cxx \
OperationGUI_GetShapesOnShapeDlg_moc.cxx\
OperationGUI_FilletDlg_moc.cxx \
- OperationGUI_Fillet2dDlg_moc.cxx \
+ OperationGUI_Fillet1d2dDlg_moc.cxx \
OperationGUI_ChamferDlg_moc.cxx \
OperationGUI_ClippingDlg_moc.cxx
diff --git a/src/OperationGUI/OperationGUI.cxx b/src/OperationGUI/OperationGUI.cxx
index ebc81748d..74906380d 100644
--- a/src/OperationGUI/OperationGUI.cxx
+++ b/src/OperationGUI/OperationGUI.cxx
@@ -38,7 +38,7 @@
#include "OperationGUI_PartitionDlg.h" // Method PARTITION
#include "OperationGUI_ArchimedeDlg.h" // Method ARCHIMEDE
#include "OperationGUI_FilletDlg.h" // Method FILLET
-#include "OperationGUI_Fillet2dDlg.h" // Method FILLET 2D
+#include "OperationGUI_Fillet1d2dDlg.h" // Method FILLET 2D and FILLET 1D
#include "OperationGUI_ChamferDlg.h" // Method CHAMFER
#include "OperationGUI_ClippingDlg.h" // Clipping dialog box
#include "OperationGUI_GetShapesOnShapeDlg.h"
@@ -79,7 +79,8 @@ bool OperationGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
case 506: ( new OperationGUI_ChamferDlg ( getGeometryGUI(), parent ) )->show(); break;
case 507: ( new OperationGUI_ClippingDlg ( getGeometryGUI(), parent ) )->show(); break;
case 508: ( new OperationGUI_GetShapesOnShapeDlg( getGeometryGUI(), parent ) )->show(); break;
- case 509: ( new OperationGUI_Fillet2dDlg ( getGeometryGUI(), parent ) )->show(); break;
+ case 510: ( new OperationGUI_Fillet1d2dDlg ( getGeometryGUI(), parent,true ) )->show(); break;
+ case 509: ( new OperationGUI_Fillet1d2dDlg ( getGeometryGUI(), parent,false ) )->show(); break;
default:
app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) );
}
diff --git a/src/OperationGUI/OperationGUI_Fillet2dDlg.cxx b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
old mode 100755
new mode 100644
similarity index 81%
rename from src/OperationGUI/OperationGUI_Fillet2dDlg.cxx
rename to src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
index dcb073800..43671b149
--- a/src/OperationGUI/OperationGUI_Fillet2dDlg.cxx
+++ b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx
@@ -19,11 +19,11 @@
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File : OperationGUI_Fillet2dDlg.cxx
+// File : OperationGUI_Fillet1d2dDlg.cxx
// Author : DMV, OCN.
//
-#include "OperationGUI_Fillet2dDlg.h"
+#include "OperationGUI_Fillet1d2dDlg.h"
#include
#include
@@ -45,30 +45,34 @@
#include
//=================================================================================
-// class : OperationGUI_Fillet2dDlg()
-// purpose : Constructs a OperationGUI_Fillet2dDlg which is a child of 'parent', with the
+// class : OperationGUI_Fillet1d2dDlg()
+// purpose : Constructs a OperationGUI_Fillet1d2dDlg which is a child of 'parent', with the
// name 'name' and widget flags set to 'f'.
// The dialog will by default be modeless, unless you set 'modal' to
// TRUE to construct a modal dialog.
//=================================================================================
-OperationGUI_Fillet2dDlg::OperationGUI_Fillet2dDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
- : GEOMBase_Skeleton(theGeometryGUI, parent, false)
+OperationGUI_Fillet1d2dDlg::OperationGUI_Fillet1d2dDlg (GeometryGUI* theGeometryGUI,
+ QWidget* parent,
+ bool is1D)
+ : GEOMBase_Skeleton(theGeometryGUI, parent, false),
+ myIs1D( is1D )
{
SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
- QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FILLET_2D")));
+ QPixmap image0 (aResMgr->loadPixmap("GEOM", myIs1D ? tr("ICON_DLG_FILLET_1D")
+ : tr("ICON_DLG_FILLET_2D")));
QPixmap iconSelect (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
- setWindowTitle(tr("GEOM_FILLET_2D_TITLE"));
+ setWindowTitle(myIs1D ? tr("GEOM_FILLET_1D_TITLE") : tr("GEOM_FILLET_2D_TITLE"));
/***************************************************************/
- mainFrame()->GroupConstructors->setTitle(tr("GEOM_FILLET_2D"));
+ mainFrame()->GroupConstructors->setTitle(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
mainFrame()->RadioButton1->setIcon(image0);
mainFrame()->RadioButton2->close();
mainFrame()->RadioButton3->close();
GroupVertexes = new DlgRef_2Sel1Spin(centralWidget());
- GroupVertexes->GroupBox1->setTitle(tr("GEOM_FILLET_2D"));
- GroupVertexes->TextLabel1->setText(tr("GEOM_PLANAR_FACE"));
+ GroupVertexes->GroupBox1->setTitle(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
+ GroupVertexes->TextLabel1->setText(myIs1D ? tr("GEOM_PLANAR_EDGE_WIRE") : tr("GEOM_PLANAR_FACE"));
GroupVertexes->TextLabel2->setText(tr("GEOM_VERTEXES"));
GroupVertexes->TextLabel3->setText(tr("GEOM_RADIUS"));
GroupVertexes->PushButton1->setIcon(iconSelect);
@@ -86,7 +90,7 @@ OperationGUI_Fillet2dDlg::OperationGUI_Fillet2dDlg (GeometryGUI* theGeometryGUI,
double SpecificStep = 10.0;
initSpinBox(GroupVertexes->SpinBox_DX, 0.00001, COORD_MAX, SpecificStep, 5); // VSR: TODO: DBL_DIGITS_DISPLAY
- setHelpFileName("fillet2d_operation_page.html");
+ setHelpFileName(myIs1D ? "fillet1d_operation_page.html" : "fillet2d_operation_page.html");
// Initialisation
Init();
@@ -94,10 +98,10 @@ OperationGUI_Fillet2dDlg::OperationGUI_Fillet2dDlg (GeometryGUI* theGeometryGUI,
}
//=================================================================================
-// function : ~OperationGUI_Fillet2dDlg()
+// function : ~OperationGUI_Fillet1d2dDlg()
// purpose : Destroys the object and frees any allocated resources
//=================================================================================
-OperationGUI_Fillet2dDlg::~OperationGUI_Fillet2dDlg()
+OperationGUI_Fillet1d2dDlg::~OperationGUI_Fillet1d2dDlg()
{
}
@@ -105,7 +109,7 @@ OperationGUI_Fillet2dDlg::~OperationGUI_Fillet2dDlg()
// function : Init()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::Init()
+void OperationGUI_Fillet1d2dDlg::Init()
{
// Set Initial values of spinboxes
GroupVertexes->SpinBox_DX->setValue(5);
@@ -133,7 +137,7 @@ void OperationGUI_Fillet2dDlg::Init()
connect(GroupVertexes->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
- initName(tr("GEOM_FILLET_2D"));
+ initName(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
GroupVertexes->PushButton1->click();
}
@@ -141,7 +145,7 @@ void OperationGUI_Fillet2dDlg::Init()
// function : ClickOnOk()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::ClickOnOk()
+void OperationGUI_Fillet1d2dDlg::ClickOnOk()
{
if (ClickOnApply())
ClickOnCancel();
@@ -151,7 +155,7 @@ void OperationGUI_Fillet2dDlg::ClickOnOk()
// function : ClickOnApply()
// purpose :
//=================================================================================
-bool OperationGUI_Fillet2dDlg::ClickOnApply()
+bool OperationGUI_Fillet1d2dDlg::ClickOnApply()
{
if (!onAccept())
return false;
@@ -171,7 +175,7 @@ bool OperationGUI_Fillet2dDlg::ClickOnApply()
// function : SelectionIntoArgument()
// purpose : Called when selection is changed or on dialog initialization or activation
//=================================================================================
-void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
+void OperationGUI_Fillet1d2dDlg::SelectionIntoArgument()
{
erasePreview();
myEditCurrentArgument->setText("");
@@ -196,7 +200,7 @@ void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
aSelMgr->GetIndexes(aSelList.First(), aMap);
if ( aMap.Extent() == 1 ) { // Local Selection
int anIndex = aMap( 1 );
- aName += QString( ":face_%1" ).arg( anIndex );
+ aName += QString( myIs1D ? ":wire_%1" : ":face_%1" ).arg( anIndex );
//Find SubShape Object in Father
GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather( anObj, aName );
@@ -209,7 +213,7 @@ void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
anObj = aFindedObject; // get Object from study
}
else { // Global Selection
- if ( aShape.ShapeType() != TopAbs_FACE ) {
+ if ( aShape.ShapeType() != (myIs1D ? TopAbs_WIRE : TopAbs_FACE) ) {
anObj = GEOM::GEOM_Object::_nil();
aName = "";
}
@@ -223,6 +227,7 @@ void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
}
} else if (myEditCurrentArgument == GroupVertexes->LineEdit2) {
myVertexes.Clear();
+ bool isPreview = myIs1D;
if (aSelList.Extent() == 1) {
Standard_Boolean aResult = Standard_False;
GEOM::GEOM_Object_var anObj =
@@ -241,12 +246,14 @@ void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
else
aName = tr("GEOM_MEN_POPUP_NAME").arg(anIndexes.Extent());
+ isPreview = true;
myEditCurrentArgument->setText(aName);
myVertexes = anIndexes;
- displayPreview();
}
}
}
+ if ( isPreview )
+ displayPreview();
}
if (myEditCurrentArgument == GroupVertexes->LineEdit1) {
@@ -259,7 +266,7 @@ void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
// function : SetEditCurrentArgument()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::SetEditCurrentArgument()
+void OperationGUI_Fillet1d2dDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
@@ -290,7 +297,7 @@ void OperationGUI_Fillet2dDlg::SetEditCurrentArgument()
// function : LineEditReturnPressed()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::LineEditReturnPressed()
+void OperationGUI_Fillet1d2dDlg::LineEditReturnPressed()
{
QLineEdit* send = (QLineEdit*)sender();
@@ -308,7 +315,7 @@ void OperationGUI_Fillet2dDlg::LineEditReturnPressed()
// function : ActivateThisDialog()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::ActivateThisDialog()
+void OperationGUI_Fillet1d2dDlg::ActivateThisDialog()
{
GEOMBase_Skeleton::ActivateThisDialog();
}
@@ -317,7 +324,7 @@ void OperationGUI_Fillet2dDlg::ActivateThisDialog()
// function : enterEvent()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::enterEvent (QEvent*)
+void OperationGUI_Fillet1d2dDlg::enterEvent (QEvent*)
{
if (!mainFrame()->GroupConstructors->isEnabled())
this->ActivateThisDialog();
@@ -327,7 +334,7 @@ void OperationGUI_Fillet2dDlg::enterEvent (QEvent*)
// function : ValueChangedInSpinBox()
// purpose :
//=================================================================================
-void OperationGUI_Fillet2dDlg::ValueChangedInSpinBox (double)
+void OperationGUI_Fillet1d2dDlg::ValueChangedInSpinBox (double)
{
displayPreview();
}
@@ -336,12 +343,13 @@ void OperationGUI_Fillet2dDlg::ValueChangedInSpinBox (double)
// function : activateSelection
// purpose : Activate selection in accordance with myEditCurrentArgument
//=================================================================================
-void OperationGUI_Fillet2dDlg::activateSelection()
+void OperationGUI_Fillet1d2dDlg::activateSelection()
{
disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
globalSelection();
if (myEditCurrentArgument == GroupVertexes->LineEdit1)
- globalSelection( GEOM_FACE ); // localSelection(myShape, TopAbs_FACE);
+ globalSelection( myIs1D ? GEOM_WIRE : GEOM_FACE ); // localSelection(myShape, myIs1D ? TopAbs_WIRE
+ // : TopAbs_FACE);
else if (!myShape->_is_nil() && myEditCurrentArgument == GroupVertexes->LineEdit2)
localSelection(myShape, TopAbs_VERTEX);
@@ -353,7 +361,7 @@ void OperationGUI_Fillet2dDlg::activateSelection()
// function : createOperation
// purpose :
//=================================================================================
-GEOM::GEOM_IOperations_ptr OperationGUI_Fillet2dDlg::createOperation()
+GEOM::GEOM_IOperations_ptr OperationGUI_Fillet1d2dDlg::createOperation()
{
return getGeomEngine()->GetILocalOperations(getStudyId());
}
@@ -362,16 +370,16 @@ GEOM::GEOM_IOperations_ptr OperationGUI_Fillet2dDlg::createOperation()
// function : isValid()
// purpose : Verify validity of input data
//=================================================================================
-bool OperationGUI_Fillet2dDlg::isValid (QString&)
+bool OperationGUI_Fillet1d2dDlg::isValid (QString&)
{
- return !myShape->_is_nil() && myVertexes.Extent() > 0;
+ return !myShape->_is_nil() && (myIs1D || myVertexes.Extent() > 0);
}
//=================================================================================
// function : execute
// purpose :
//=================================================================================
-bool OperationGUI_Fillet2dDlg::execute (ObjectList& objects)
+bool OperationGUI_Fillet1d2dDlg::execute (ObjectList& objects)
{
GEOM::GEOM_Object_var anObj;
@@ -381,8 +389,10 @@ bool OperationGUI_Fillet2dDlg::execute (ObjectList& objects)
for (int i = 1, n = myVertexes.Extent(); i <= n; i++)
aListOfIndexes[ i - 1 ] = myVertexes(i);
- anObj = GEOM::GEOM_ILocalOperations::_narrow(getOperation())->
- MakeFillet2D(myShape, getRadius(), aListOfIndexes);
+ GEOM::GEOM_ILocalOperations_ptr op =
+ GEOM::GEOM_ILocalOperations::_narrow(getOperation());
+ anObj = (myIs1D ? op->MakeFillet1D(myShape, getRadius(), aListOfIndexes)
+ : op->MakeFillet2D(myShape, getRadius(), aListOfIndexes));
if (!anObj->_is_nil())
objects.push_back(anObj._retn());
@@ -394,7 +404,7 @@ bool OperationGUI_Fillet2dDlg::execute (ObjectList& objects)
// function : getRadius
// purpose : Get radius
//=================================================================================
-double OperationGUI_Fillet2dDlg::getRadius() const
+double OperationGUI_Fillet1d2dDlg::getRadius() const
{
return GroupVertexes ->SpinBox_DX->value();
}
diff --git a/src/OperationGUI/OperationGUI_Fillet2dDlg.h b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h
old mode 100755
new mode 100644
similarity index 85%
rename from src/OperationGUI/OperationGUI_Fillet2dDlg.h
rename to src/OperationGUI/OperationGUI_Fillet1d2dDlg.h
index 523dbad04..9e7f679d9
--- a/src/OperationGUI/OperationGUI_Fillet2dDlg.h
+++ b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h
@@ -19,12 +19,12 @@
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File : OperationGUI_Fillet2dDlg.h
+// File : OperationGUI_Fillet1d2dDlg.h
// Author : DMV, OCN
//
-#ifndef OPERATIONGUI_FILLET2DDLG_H
-#define OPERATIONGUI_FILLET2DDLG_H
+#ifndef OPERATIONGUI_Fillet1d2dDLG_H
+#define OPERATIONGUI_Fillet1d2dDLG_H
#include
@@ -33,16 +33,16 @@
class DlgRef_2Sel1Spin;
//=================================================================================
-// class : OperationGUI_Fillet2dDlg
+// class : OperationGUI_Fillet1d2dDlg
// purpose :
//=================================================================================
-class OperationGUI_Fillet2dDlg : public GEOMBase_Skeleton
+class OperationGUI_Fillet1d2dDlg : public GEOMBase_Skeleton
{
Q_OBJECT
public:
- OperationGUI_Fillet2dDlg( GeometryGUI*, QWidget* );
- ~OperationGUI_Fillet2dDlg();
+ OperationGUI_Fillet1d2dDlg( GeometryGUI*, QWidget*, bool theIs1D );
+ ~OperationGUI_Fillet1d2dDlg();
protected:
// redefined from GEOMBase_Helper
@@ -66,10 +66,11 @@ private:
double getRadius() const;
private:
+ bool myIs1D;
GEOM::GEOM_Object_var myShape;
TColStd_IndexedMapOfInteger myVertexes;
DlgRef_2Sel1Spin* GroupVertexes;
};
-#endif // OPERATIONGUI_FILLET2DDLG_H
+#endif // OPERATIONGUI_Fillet1d2dDLG_H