From 3f0d8467530f7c60b842c2ebacc4133e085f42d1 Mon Sep 17 00:00:00 2001 From: ptv Date: Tue, 18 Aug 2009 11:15:10 +0000 Subject: [PATCH] 0020432: EDF 1029 GEOM : Fillet 1D --- doc/salome/gui/GEOM/images/fillet1d_1.png | Bin 0 -> 2582 bytes doc/salome/gui/GEOM/images/fillet1d_2.png | Bin 0 -> 15465 bytes .../gui/GEOM/input/fillet1d_operation.doc | 29 + .../gui/GEOM/input/fillet2d_operation.doc | 2 +- .../GEOM/input/transformation_operations.doc | 4 +- .../input/tui_transformation_operations.doc | 23 + idl/GEOM_Gen.idl | 15 + resources/Makefile.am | 2 + resources/fillet1d.png | Bin 0 -> 819 bytes resources/filletwire.png | Bin 0 -> 772 bytes src/GEOMGUI/GEOM_images.ts | 12 + src/GEOMGUI/GEOM_msg_en.ts | 20 + src/GEOMGUI/GEOM_msg_fr.ts | 4 + src/GEOMGUI/GeometryGUI.cxx | 5 +- src/GEOMImpl/GEOMImpl.pro | 1 + src/GEOMImpl/GEOMImpl_Fillet1d.cxx | 759 ++++++++++++++++++ src/GEOMImpl/GEOMImpl_Fillet1d.hxx | 141 ++++ src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx | 312 +++++++ src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx | 160 ++++ src/GEOMImpl/GEOMImpl_Gen.cxx | 2 + src/GEOMImpl/GEOMImpl_IFillet1d.hxx | 51 ++ src/GEOMImpl/GEOMImpl_ILocalOperations.cxx | 71 ++ src/GEOMImpl/GEOMImpl_ILocalOperations.hxx | 2 + src/GEOMImpl/GEOMImpl_Types.hxx | 2 + src/GEOMImpl/Makefile.am | 5 + src/GEOM_I/GEOM_ILocalOperations_i.cc | 32 + src/GEOM_I/GEOM_ILocalOperations_i.hh | 3 + src/GEOM_I_Superv/GEOM_Superv_i.cc | 20 + src/GEOM_I_Superv/GEOM_Superv_i.hh | 2 + src/GEOM_SWIG/geompyDC.py | 30 + src/OperationGUI/Makefile.am | 6 +- src/OperationGUI/OperationGUI.cxx | 5 +- ...Dlg.cxx => OperationGUI_Fillet1d2dDlg.cxx} | 82 +- ...et2dDlg.h => OperationGUI_Fillet1d2dDlg.h} | 17 +- 34 files changed, 1767 insertions(+), 52 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/fillet1d_1.png create mode 100644 doc/salome/gui/GEOM/images/fillet1d_2.png create mode 100644 doc/salome/gui/GEOM/input/fillet1d_operation.doc create mode 100644 resources/fillet1d.png create mode 100644 resources/filletwire.png create mode 100644 src/GEOMImpl/GEOMImpl_Fillet1d.cxx create mode 100644 src/GEOMImpl/GEOMImpl_Fillet1d.hxx create mode 100644 src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx create mode 100644 src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx create mode 100644 src/GEOMImpl/GEOMImpl_IFillet1d.hxx rename src/OperationGUI/{OperationGUI_Fillet2dDlg.cxx => OperationGUI_Fillet1d2dDlg.cxx} (81%) mode change 100755 => 100644 rename src/OperationGUI/{OperationGUI_Fillet2dDlg.h => OperationGUI_Fillet1d2dDlg.h} (85%) mode change 100755 => 100644 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 0000000000000000000000000000000000000000..00ddc08549e53edb0df6c96bb7e39c8c3414cebd GIT binary patch literal 2582 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c62a1769b91946a1512ba7a55f3ca675954cb2c9 GIT binary patch literal 819 zcmV-31I+x1P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXV? z1R5thWIWjb00Of~L_t(I%dM18h}BgT$3N%(e$S+_Ku|X>+_(#*pnn81q!6MECADx7 zF8YHNxoVXQ8Cxi}5^QIJxN)N^MJA&^kc860DBNVwC=5L6y_v!J{lE8~)8hBuYo0UX zM0DYD|D8YIbI$i%F*E+p;Q&PBKPk`q_wC;9-PWz28KDw0nV7>%IH^7I}(bl3oX z{OPKcb>Lyq(C_!y{^5Rmr>edOeg-axnIR&4aP}r?;&2YkAVejq!6P-BdiJ2*U;IWE z7Z&JsAF%ECdv>g8t^qfJ%jr;XA**qN;;300wi>462G8EOC`Vu0YqR&hkfp_Wo@}qX z1B6{S6wIr@Qt4SLJz43=t3XzIvTA(RRmI6mpUdP6A6pEb*s5nh*Ua)1U>Nq)^jE`r z;-p|c;J+|N8ZL9G(k}_%-TGv>Igl^zweY` z*j3}H%95(cXo`$b<;1!q`WlTMGX;#tb?X@7?@mt7002ovPDHLkV1m0Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FZT01FZU(%pXi00007bV*G`2iXV? z1QZ+;?D%s400M+bL_t(I%dM2VY8_V;hQB$QV0?K1_qJ;18PZ5k;6iZ`5n)$$WpFG~ z7~>~MXD}g8k)#O3VAm#fP-)|1&}B4dX7+7eQp`EhktYceWMDJQ!2b6C|7-14xjX;o zQv+00b>ZjU-kt-f>e(_g+#OXVgupNiv~5e%H2m^sU~~4NIs<+VyY&zqT{9{^hxNVFr*RC$3hnii=puB z@jV{wzg%tK25z1y+}YXj+gp#wVuU2nxz=cpPzgV6j-x1wnEooX**(uQ1;3YE%c{4ys_v$)STg6%_}+{|NB<0BU-+B|~+tQ1}cZUQ$hsc^my1NaNTz(WxICON_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