From: jfa Date: Fri, 27 Jul 2012 11:32:14 +0000 (+0000) Subject: IMPs 0021476 (fuse edges) and 0021477 (suppress a vertex from a wire for fillet1d). X-Git-Tag: V6_6_0a1~61 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e184734288441d2816e0a6f3f89e09f52ab717eb;p=modules%2Fgeom.git IMPs 0021476 (fuse edges) and 0021477 (suppress a vertex from a wire for fillet1d). --- diff --git a/doc/salome/gui/GEOM/images/fillet1d_2.png b/doc/salome/gui/GEOM/images/fillet1d_2.png index e9da08fa3..053053370 100644 Binary files a/doc/salome/gui/GEOM/images/fillet1d_2.png and b/doc/salome/gui/GEOM/images/fillet1d_2.png differ diff --git a/doc/salome/gui/GEOM/images/fuse_collinear_edges.png b/doc/salome/gui/GEOM/images/fuse_collinear_edges.png new file mode 100644 index 000000000..85531b25e Binary files /dev/null and b/doc/salome/gui/GEOM/images/fuse_collinear_edges.png differ diff --git a/doc/salome/gui/GEOM/input/fillet1d_operation.doc b/doc/salome/gui/GEOM/input/fillet1d_operation.doc index 861a6ae93..322b7c965 100644 --- a/doc/salome/gui/GEOM/input/fillet1d_operation.doc +++ b/doc/salome/gui/GEOM/input/fillet1d_operation.doc @@ -17,9 +17,13 @@ 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. +\b Note: Use option Fuse collinear edges to allow bigger radius + to allow ignoring of possible secant points, i.e. the + joints of collinear edges, thus processing such edges as one. + TUI Command: geompy.MakeFillet1D(Shape, R, ListVertexes) \n Arguments: Name + 1 shape + empty list or several vertexes + 1 value (Fillet radius). -\n Advanced options \ref preview_anchor "Preview" +\n Advanced options: \ref preview_anchor "Preview" Examples: diff --git a/doc/salome/gui/GEOM/input/fuse_edges_operation.doc b/doc/salome/gui/GEOM/input/fuse_edges_operation.doc new file mode 100644 index 000000000..7924f73eb --- /dev/null +++ b/doc/salome/gui/GEOM/input/fuse_edges_operation.doc @@ -0,0 +1,23 @@ +/*! + +\page fuse_edges_operation_page Fuse Collinear Edges within a Wire + +\n To Fuse Collinear Edges within a Wire in the Main Menu +select Repair - > Fuse Collinear Edges within a Wire. +\n This operation removes selected vertices from a given wire in case +if adjacent edges are C1 continuous. The function takes a list of +vertices to suppress as a parameter. If the list is empty, all +vertices in a wire are assumed. + +\n Arguments: Name + a wire + a list of vertices (can be empty). + +\image html fuse_collinear_edges.png + +\n TUI Command: geompy.FuseCollinearEdgesWithinWire(wire, vertices), +where wire is a wire and vertices is a list of +vertices to be suppressed. + +Our TUI Scripts provide you with useful examples of the +\ref tui_fuse_collinear_edges "Fuse Collinear Edges" functionality usage. + +*/ diff --git a/doc/salome/gui/GEOM/input/repairing_operations.doc b/doc/salome/gui/GEOM/input/repairing_operations.doc index 96ff03ae0..8fd31bab1 100644 --- a/doc/salome/gui/GEOM/input/repairing_operations.doc +++ b/doc/salome/gui/GEOM/input/repairing_operations.doc @@ -27,6 +27,9 @@ splits an edge in two. reverses the normals of the selected faces.
  • \subpage remove_extra_edges_operation_page "Remove extra edges" - removes seam and degenerated edges from the given shape.
  • +
  • \subpage fuse_edges_operation_page "Fuse Collinear Edges within a Wire" - +removes selected vertices from a given wire in case if adjacent edges +are C1 continuous.
  • */ diff --git a/doc/salome/gui/GEOM/input/tui_repairing_operations.doc b/doc/salome/gui/GEOM/input/tui_repairing_operations.doc index 4b1f067cc..0ce8b63db 100644 --- a/doc/salome/gui/GEOM/input/tui_repairing_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_repairing_operations.doc @@ -391,5 +391,57 @@ for point in edge_points: salome.sg.updateObjBrowser(1) \endcode +\anchor tui_fuse_collinear_edges +

    Fuse Collinear Edges within a Wire

    + +\code +import geompy +import salome + +# create vertices +p1 = geompy.MakeVertex(0, 0, 0) +p2 = geompy.MakeVertex(70, 0, 0) +p3 = geompy.MakeVertex(70, 50, 0) +p4 = geompy.MakeVertex(70, 80, 0) +p5 = geompy.MakeVertex(50, 80, 0) +p6 = geompy.MakeVertex(20, 80, 0) +p7 = geompy.MakeVertex(0, 80, 0) +p8 = geompy.MakeVertex(0, 30, 0) + +points = [p1, p2, p3, p4, p5, p6, p7, p8] + +# make a wire +wire_1 = geompy.MakePolyline(points, True) + +# suppress some vertices in the wire +wire_2 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p3]) +wire_3 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p5, p6]) + +# suppress all suitable vertices in the wire +wire_4 = geompy.FuseCollinearEdgesWithinWire(wire_1, []) + +wires = [wire_1, wire_2, wire_3, wire_4] + +# add objects in the study +ii = 1 +for point in points: + geompy.addToStudy(point, "p%d"%ii) + ii = ii + 1 + pass + +ii = 1 +for wire in wires: + geompy.addToStudy(wire, "wire_%d"%ii) + wire_points = geompy.SubShapeAllSortedCentres(wire, geompy.ShapeType["VERTEX"]) + jj = 1 + for point in wire_points: + geompy.addToStudyInFather(wire, point, "point_%d"%jj) + jj = jj + 1 + pass + ii = ii + 1 + pass + +salome.sg.updateObjBrowser(1) +\endcode */ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index a3819178c..f3a41ad16 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2905,11 +2905,18 @@ module GEOM * GEOM_IShapesOperations.GetSubShapeIndex(). * \note The list of vertices coudl be empty, in this case fillet fill be done * at all vertices in given wire + * \param doIgnoreSecantVertices If FALSE, fillet radius is always limited + * by the length of the edges, nearest to the fillet vertex. + * But sometimes the next edge is C1 continuous with the one, nearest to + * the fillet point, and such two (or more) edges can be united to allow + * bigger radius. Set this flag to TRUE to allow collinear edges union, + * thus ignoring the secant vertex (vertices). * \return New GEOM_Object, containing the result shape. */ GEOM_Object MakeFillet1D (in GEOM_Object theShape, in double theR, - in ListOfLong theVertexes); + in ListOfLong theVertexes, + in boolean doIgnoreSecantVertices); /*! * \brief Perform a symmetric chamfer on all edges of the given shape. @@ -3120,6 +3127,16 @@ module GEOM GEOM_Object DivideEdge (in GEOM_Object theObject, in short theEdgeIndex, in double theValue, in boolean isByParameter); + /*! + * \brief Suppress the vertices in the wire in case if adjacent edges are C1 continuous. + * \param theWire Wire to minimize the number of C1 continuous edges in. + * \param theVertices A list of vertices to suppress. If the list + * is empty, all vertices in a wire will be assumed. + * \return New GEOM_Object with modified wire. + */ + GEOM_Object FuseCollinearEdgesWithinWire (in GEOM_Object theWire, + in ListOfGO theVertices); + /*! * \brief Get a list of wires (wrapped in GEOM_Object-s), * that constitute a free boundary of the given shape. diff --git a/resources/Makefile.am b/resources/Makefile.am index 6ec86cabe..d5aab779c 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -98,6 +98,7 @@ filletwire.png \ filletface.png \ filling.png \ fuse.png \ +fuse_collinear_edges.png \ geometry.png \ import_picture.png \ limit_tolerance.png \ diff --git a/resources/fuse_collinear_edges.png b/resources/fuse_collinear_edges.png new file mode 100644 index 000000000..52d8ff8da Binary files /dev/null and b/resources/fuse_collinear_edges.png differ diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index a1580cdd4..d15ade1d2 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -155,6 +155,10 @@ ICON_DLG_REMOVE_EXTRA_EDGES remove_extra_edges.png + + ICON_DLG_FUSE_EDGES + fuse_collinear_edges.png + ICON_DLG_CHECKSHAPE check.png @@ -979,6 +983,10 @@ ICO_REMOVE_EXTRA_EDGES remove_extra_edges.png + + ICO_FUSE_EDGES + fuse_collinear_edges.png + ICO_NORMALE normale.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 1da62ff22..cf4c13db2 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -710,6 +710,10 @@ Please, select face, shell or solid and try again GEOM_FILLET_1D Fillet 1D + + GEOM_FILLET_1D_IGNORE_SECANT + Fuse collinear edges to allow bigger radius + GEOM_FILLET_ABORT Fillet can't be computed with radius %1 @@ -4306,6 +4310,30 @@ Please, select face, shell or solid and try again STB_REMOVE_EXTRA_EDGES Remove extra edges + + GEOM_FUSE_EDGES_TITLE + Fuse Collinear Edges within a Wire + + + GEOM_FUSE_EDGES + Fuse edges + + + FUSE_EDGES_NEW_OBJ_NAME + FuseEdges + + + TOP_FUSE_EDGES + Fuse collinear edges within a wire + + + MEN_FUSE_EDGES + Fuse Collinear Edges within a Wire + + + STB_FUSE_EDGES + Fuse collinear edges within a wire + TOP_NORMALE Normal to a face diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 1ae3b2977..23694246d 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -535,6 +535,7 @@ void GeometryGUI::OnGUIEvent( int id ) case GEOMOp::OpGlueEdges: // MENU REPAIR - GLUE EDGES case GEOMOp::OpLimitTolerance: // MENU REPAIR - LIMIT TOLERANCE case GEOMOp::OpRemoveExtraEdges: // MENU REPAIR - REMOVE EXTRA EDGES + case GEOMOp::OpFuseEdges: // MENU REPAIR - FUSE COLLINEAR EDGES libName = "RepairGUI"; break; case GEOMOp::OpProperties: // MENU MEASURE - PROPERTIES @@ -813,6 +814,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpFreeFaces, "CHECK_FREE_FACES" ); createGeomAction( GEOMOp::OpOrientation, "CHANGE_ORIENTATION" ); createGeomAction( GEOMOp::OpRemoveExtraEdges, "REMOVE_EXTRA_EDGES" ); + createGeomAction( GEOMOp::OpFuseEdges, "FUSE_EDGES" ); createGeomAction( GEOMOp::OpPointCoordinates, "POINT_COORDS" ); createGeomAction( GEOMOp::OpProperties, "BASIC_PROPS" ); @@ -1032,6 +1034,7 @@ void GeometryGUI::initialize( CAM_Application* app ) //createMenu( GEOMOp::OpFreeFaces, repairId, -1 ); createMenu( GEOMOp::OpOrientation, repairId, -1 ); createMenu( GEOMOp::OpRemoveExtraEdges, repairId, -1 ); + createMenu( GEOMOp::OpFuseEdges, repairId, -1 ); int measurId = createMenu( tr( "MEN_MEASURES" ), -1, -1, 10 ); createMenu( GEOMOp::OpPointCoordinates, measurId, -1 ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 77e51f1c3..3d8a41d4e 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -157,6 +157,7 @@ namespace GEOMOp { OpRemoveExtraEdges = 4011, // MENU REPAIR - REMOVE EXTRA EDGES OpLimitTolerance = 4012, // MENU REPAIR - LIMIT TOLERANCE OpGlueEdges = 4013, // MENU REPAIR - GLUE EDGES + OpFuseEdges = 4014, // MENU REPAIR - FUSE COLLINEAR EDGES // MeasureGUI ----------------//-------------------------------- OpProperties = 5000, // MENU MEASURES - PROPERTIES OpCenterMass = 5001, // MENU MEASURES - CENTRE OF MASS diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.cxx b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx index c4780bd33..0a648ad2c 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1d.cxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx @@ -15,7 +15,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : GEOMImpl_Fillet1d.cxx // Module : GEOMImpl @@ -401,7 +400,7 @@ void GEOMImpl_Fillet1d::performNewton(GEOMImpl_Fillet1dPoint* theLeft, else { if (fabs(aB) > fabs(aDet * 1000000.)) - { // possible floating point operations accurancy errors + { // possible floating point operations accuracy errors processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise } else diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.hxx b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx index 1fb32c489..679e3fc70 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1d.hxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx @@ -15,128 +15,129 @@ // 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; - Standard_Integer myDegreeOfRecursion; -}; - - -/** -* 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 + +// 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 is initialised 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; + Standard_Integer myDegreeOfRecursion; +}; + + +/** +* 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*); + + //! Checks if point contains solution and returns the index of it 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 index bd99d94d7..f781f228e 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx @@ -15,7 +15,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -24,21 +23,10 @@ #include #include #include -#include #include +#include #include -#include -#include -#include - -#include -#include -#include -#include - -#include - #include #include #include @@ -54,6 +42,18 @@ #include #include #include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include //======================================================================= //function : GetID @@ -161,32 +161,112 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const TopoDS_Wire aWire = TopoDS::Wire(aShape); - double rad = aCI.GetR(); + bool doIgnoreSecantPoints = aCI.GetFlag(); - if ( rad < Precision::Confusion()) + double rad = aCI.GetR(); + if (rad < Precision::Confusion()) return 0; // collect vertices for make fillet TopTools_ListOfShape aVertexList; - TopTools_MapOfShape mapShape; + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aWire, anIndices); 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)) - if (mapShape.Add(aShapeVertex)) - aVertexList.Append( aShapeVertex ); + if (aLen > 0) { + for (int ii = 1; ii <= aLen; ii++) { + int ind = aCI.GetVertex(ii); + if (1 <= ind && ind <= anIndices.Extent()) { + TopoDS_Shape aShapeVertex = anIndices.FindKey(ind); + if (aShapeVertex.ShapeType() == TopAbs_VERTEX) + aVertexList.Append(aShapeVertex); + } } - } else { // get all vertices from wire - TopExp_Explorer anExp( aWire, TopAbs_VERTEX ); - for ( ; anExp.More(); anExp.Next() ) { + } + else { // get all vertices from wire + TopTools_MapOfShape mapShape; + TopExp_Explorer anExp (aWire, TopAbs_VERTEX); + for (; anExp.More(); anExp.Next()) { if (mapShape.Add(anExp.Current())) - aVertexList.Append( anExp.Current() ); + aVertexList.Append(anExp.Current()); } } if (aVertexList.IsEmpty()) - Standard_ConstructionError::Raise("Invalid input no vertices to make fillet"); + Standard_ConstructionError::Raise("Invalid input: no vertices to make fillet"); + + // at first we try to make fillet on the initial wire (without edges fusing) + bool isFinalPass = !doIgnoreSecantPoints; + TopoDS_Wire aResult; + bool isAllStepsOk = MakeFillet(aWire, aVertexList, rad, isFinalPass, aResult); + + // try to fuse collinear edges to allow bigger radius + if (!isFinalPass && !isAllStepsOk) { + // 1. Fuse + TopoDS_Shape aShapeNew; + Handle(TColStd_HSequenceOfTransient) aVerts; + GEOMImpl_HealingDriver::FuseCollinearEdges(aWire, aVerts, aShapeNew); + TopoDS_Wire aWireNew = TopoDS::Wire(aShapeNew); + + // 2. Rebuild the list of vertices (by coincidence) + Standard_Real tol, tolMax = Precision::Confusion(); + for (TopExp_Explorer ExV (aWireNew, TopAbs_VERTEX); ExV.More(); ExV.Next()) { + TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current()); + tol = BRep_Tool::Tolerance(Vertex); + if (tol > tolMax) + tolMax = tol; + } + + TopTools_ListOfShape aVertexListNew; + TopTools_IndexedMapOfShape anIndicesNew; + TopExp::MapShapes(aWireNew, anIndicesNew); + TopTools_ListIteratorOfListOfShape anIt (aVertexList); + for (; anIt.More(); anIt.Next()) { + TopoDS_Vertex aV = TopoDS::Vertex(anIt.Value()); + if (anIndicesNew.Contains(aV)) + aVertexListNew.Append(aV); + else { + // try to find by coords in the new wire + gp_Pnt aP = BRep_Tool::Pnt(aV); + + bool isFound = false; + TopTools_MapOfShape mapShape; + TopExp_Explorer exp (aWireNew, TopAbs_VERTEX); + for (; exp.More() && !isFound; exp.Next()) { + if (mapShape.Add(exp.Current())) { + TopoDS_Vertex aVi = TopoDS::Vertex(exp.Current()); + gp_Pnt aPi = BRep_Tool::Pnt(aVi); + if (aPi.Distance(aP) < tolMax) { + aVertexListNew.Append(aVi); + isFound = true; + } + } + } + } + } + + // 3. Repeat the fillet algorithm + isFinalPass = true; + MakeFillet(aWireNew, aVertexListNew, rad, isFinalPass, aResult); + } + + aFunction->SetValue(aResult); + log.SetTouched(Label()); + + return 1; +} + +//======================================================================= +//function : MakeFillet +//purpose : +//======================================================================= +bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire, + const TopTools_ListOfShape& aVertexList, + const Standard_Real rad, + bool isFinalPass, + TopoDS_Wire& aResult) const +{ + // this variable is needed to break execution + // in case of fillet failure and try to fuse edges + bool isAllStepsOk = true; //INFO: this algorithm implemented in assumption that user can select both // vertices of some edges to make fillet. In this case we should remember @@ -220,54 +300,69 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const 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 + GEOMImpl_Fillet1d aFilletAlgo (anEdge1, anEdge2, aPlane); + if (!aFilletAlgo.Perform(rad)) { + if (isFinalPass) + continue; // can not create fillet with given radius + else { + isAllStepsOk = false; + break; // 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 + if (aNewE.IsNull()) { + if (isFinalPass) + continue; // no result found + else { + isAllStepsOk = false; + break; // no result found + } + } // add new created edges and take modified edges - aListOfNewEdge.Append( aNewE ); + 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 + // check if wire edges modified, + // if yes, then map to original edges (from vertex-edges list), because edges can be modified before if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 ); if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 ); } - if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) { - StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius"); - return 0; + if (anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty()) { + if (isFinalPass) + StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius"); + else + isAllStepsOk = false; } + if (!isAllStepsOk) + return false; + // create new wire instead of original - for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) { + for (TopExp_Explorer anExp (aWire, TopAbs_EDGE); anExp.More(); anExp.Next()) { TopoDS_Shape anEdge = anExp.Current(); - if ( !anEdgeToEdgeMap.IsBound( anEdge ) ) - aListOfNewEdge.Append( anEdge ); - else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull()) - aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) ); + if (!anEdgeToEdgeMap.IsBound(anEdge)) + aListOfNewEdge.Append(anEdge); + else if (!anEdgeToEdgeMap.Find(anEdge).IsNull()) + aListOfNewEdge.Append(anEdgeToEdgeMap.Find(anEdge)); } - GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge ); + GEOMImpl_IShapesOperations::SortShapes(aListOfNewEdge); BRepBuilderAPI_MakeWire aWireTool; - aWireTool.Add( aListOfNewEdge ); + aWireTool.Add(aListOfNewEdge); aWireTool.Build(); if (!aWireTool.IsDone()) return 0; - aWire = aWireTool.Wire(); - aFunction->SetValue(aWire); - log.SetTouched(Label()); + aResult = aWireTool.Wire(); - return 1; + return isAllStepsOk; } diff --git a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx index 87b9ce897..dc8b9da89 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.hxx @@ -15,11 +15,10 @@ // 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 @@ -48,6 +47,9 @@ #include #endif +#include +#include + class Standard_Transient; class Handle_Standard_Type; class Handle(TFunction_Driver); @@ -123,37 +125,42 @@ 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)); } - + 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 ~GEOMImpl_Fillet1dDriver() {}; + + Standard_EXPORT static const Standard_GUID& GetID(); + + 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; } + + // 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)); } + +private: + + Standard_EXPORT bool MakeFillet(const TopoDS_Wire&, const TopTools_ListOfShape&, + const Standard_Real, bool, TopoDS_Wire&) const; }; diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx index f21bc14f9..7771033fb 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -28,6 +27,7 @@ #include #include +#include #include #include @@ -38,22 +38,30 @@ #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 : raiseNotDoneExeption @@ -135,6 +143,12 @@ Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const case LIMIT_TOLERANCE: LimitTolerance(&HI, anOriginalShape, aShape); break; + case FUSE_COLLINEAR_EDGES: + { + Handle(TColStd_HSequenceOfTransient) aVerts = HI.GetShapes(); + FuseCollinearEdges(anOriginalShape, aVerts, aShape); + } + break; default: return 0; } @@ -505,6 +519,258 @@ void GEOMImpl_HealingDriver::LimitTolerance (GEOMImpl_IHealing* theHI, StdFail_NotDone::Raise("Non valid shape result"); } +//======================================================================= +//function : FuseCollinearEdges +//purpose : +//======================================================================= +void GEOMImpl_HealingDriver::FuseCollinearEdges (const TopoDS_Shape& theOriginalShape, + const Handle(TColStd_HSequenceOfTransient)& aVerts, + TopoDS_Shape& theOutShape) +{ + if (theOriginalShape.ShapeType() != TopAbs_WIRE) + Standard_TypeMismatch::Raise("Not a wire is given"); + + // Tolerances + Standard_Real AngTol = Precision::Angular(); + Standard_Real LinTol = Precision::Confusion(); + Standard_Real tol; + for (TopExp_Explorer ExV (theOriginalShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) { + TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current()); + tol = BRep_Tool::Tolerance(Vertex); + if (tol > LinTol) + LinTol = tol; + } + + // 1. Make a copy to prevent the original shape changes. + TopoDS_Shape aWire; + TColStd_IndexedDataMapOfTransientTransient aMapTShapes; + TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aWire); + TopoDS_Wire theWire = TopoDS::Wire(aWire); + + // 2. Sub-shapes of the wire + TopTools_MapOfShape aMapToRemove; + + TopTools_IndexedMapOfShape anOldIndices; + TopExp::MapShapes(theOriginalShape, anOldIndices); + + TopTools_IndexedMapOfShape aNewIndices; + TopExp::MapShapes(theWire, aNewIndices); + + // 3. Collect vertices of the wire, same or equal to the given vertices + bool removeAll = false; + if (aVerts.IsNull() || aVerts->Length() < 1) + removeAll = true; + + if (!removeAll) { + for (unsigned int ind = 1; ind <= aVerts->Length(); ind++) { + Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aVerts->Value(ind)); + TopoDS_Shape aShape_i = aRefShape->GetValue(); + if (aShape_i.IsNull()) + Standard_NullObject::Raise("Null vertex given"); + if (aShape_i.ShapeType() != TopAbs_VERTEX) + Standard_TypeMismatch::Raise("Shape to suppress is not a vertex"); + + // find vertices shared with the initial wire + if (anOldIndices.Contains(aShape_i)) { + aMapToRemove.Add(aNewIndices.FindKey(anOldIndices.FindIndex(aShape_i))); + } else { + // try to find by coords in the new wire + TopoDS_Vertex aVert = TopoDS::Vertex(aShape_i); + gp_Pnt aP = BRep_Tool::Pnt(aVert); + + bool isFound = false; + TopTools_MapOfShape mapShape; + TopExp_Explorer exp (theWire, TopAbs_VERTEX); + for (; exp.More() && !isFound; exp.Next()) { + if (mapShape.Add(exp.Current())) { + TopoDS_Vertex aVi = TopoDS::Vertex(exp.Current()); + gp_Pnt aPi = BRep_Tool::Pnt(aVi); + if (aPi.Distance(aP) < LinTol) { + aMapToRemove.Add(aVi); + isFound = true; + } + } + } + } + } + } + + /* + BRepLib::BuildCurves3d(theWire); + Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(theWire); + Fixer->SetPrecision(LinTol); + Fixer->SetMaxTolerance(LinTol); + Fixer->Perform(); + theWire = TopoDS::Wire(Fixer->Shape()); + */ + + TopoDS_Edge prevEdge; + TopTools_ListOfShape finalList, currChain; + + BRepTools_WireExplorer wexp (theWire); + if (wexp.More()) { + prevEdge = wexp.Current(); + currChain.Append(prevEdge); + wexp.Next(); + } + else { + Standard_NullObject::Raise("Empty wire given"); + } + + for (; wexp.More(); wexp.Next()) { + TopoDS_Edge anEdge = wexp.Current(); + TopoDS_Vertex CurVertex = wexp.CurrentVertex(); + + bool continueChain = false; + if (aMapToRemove.Contains(CurVertex) || removeAll) { + // if C1 -> continue chain + if (AreEdgesC1(prevEdge, anEdge)) { + continueChain = true; + } + } + + if (!continueChain) { + if (currChain.Extent() == 1) { + // add one edge to the final list + finalList.Append(currChain.First()); + } + else { + // make wire from the list of edges + BRep_Builder B; + TopoDS_Wire aCurrWire; + B.MakeWire(aCurrWire); + TopTools_ListIteratorOfListOfShape itEdges (currChain); + for (; itEdges.More(); itEdges.Next()) { + TopoDS_Shape aValue = itEdges.Value(); + B.Add(aCurrWire, TopoDS::Edge(aValue)); + } + + // make edge from the wire + TopoDS_Edge anEdge = GEOMImpl_ShapeDriver::MakeEdgeFromWire(aCurrWire, LinTol, AngTol); + + // add this new edge to the final list + finalList.Append(anEdge); + } + currChain.Clear(); + } + + // add one edge to the chain + currChain.Append(anEdge); + prevEdge = anEdge; + } + + if (currChain.Extent() == 1) { + // add one edge to the final list + finalList.Append(currChain.First()); + } + else { + // make wire from the list of edges + BRep_Builder B; + TopoDS_Wire aCurrWire; + B.MakeWire(aCurrWire); + TopTools_ListIteratorOfListOfShape itEdges (currChain); + for (; itEdges.More(); itEdges.Next()) { + TopoDS_Shape aValue = itEdges.Value(); + B.Add(aCurrWire, TopoDS::Edge(aValue)); + } + + // make edge from the wire + TopoDS_Edge anEdge = GEOMImpl_ShapeDriver::MakeEdgeFromWire(aCurrWire, LinTol, AngTol); + + // add this new edge to the final list + finalList.Append(anEdge); + } + + BRep_Builder B; + TopoDS_Wire aFinalWire; + B.MakeWire(aFinalWire); + TopTools_ListIteratorOfListOfShape itEdges (finalList); + for (; itEdges.More(); itEdges.Next()) { + TopoDS_Shape aValue = itEdges.Value(); + B.Add(aFinalWire, TopoDS::Edge(aValue)); + } + theOutShape = aFinalWire; + + BRepCheck_Analyzer ana (theOutShape, Standard_True); + if (!ana.IsValid()) + StdFail_NotDone::Raise("Non valid shape result"); +} + +//======================================================================= +//function : AreEdgesC1 +//purpose : +//======================================================================= +Standard_Boolean GEOMImpl_HealingDriver::AreEdgesC1 (const TopoDS_Edge& E1, const TopoDS_Edge& E2) +{ + BRepAdaptor_Curve aCurve1 (E1); + BRepAdaptor_Curve aCurve2 (E2); + + if (aCurve1.Continuity() == GeomAbs_C0 || aCurve2.Continuity() == GeomAbs_C0) + return Standard_False; + + Standard_Real tol, tolMax = Precision::Confusion(); + for (TopExp_Explorer ExV1 (E1, TopAbs_VERTEX); ExV1.More(); ExV1.Next()) { + TopoDS_Vertex Vertex = TopoDS::Vertex(ExV1.Current()); + tol = BRep_Tool::Tolerance(Vertex); + if (tol > tolMax) + tolMax = tol; + } + for (TopExp_Explorer ExV2 (E2, TopAbs_VERTEX); ExV2.More(); ExV2.Next()) { + TopoDS_Vertex Vertex = TopoDS::Vertex(ExV2.Current()); + tol = BRep_Tool::Tolerance(Vertex); + if (tol > tolMax) + tolMax = tol; + } + + Standard_Real f1, l1, f2, l2; + f1 = aCurve1.FirstParameter(); + l1 = aCurve1.LastParameter(); + f2 = aCurve2.FirstParameter(); + l2 = aCurve2.LastParameter(); + + if (f1 > l1) { + Standard_Real tmp = f1; + f1 = l1; + l1 = tmp; + } + + if (f2 > l2) { + Standard_Real tmp = f2; + f2 = l2; + l2 = tmp; + } + + gp_Pnt pf1, pl1, pf2, pl2; + gp_Vec vf1, vl1, vf2, vl2; + aCurve1.D1(f1, pf1, vf1); + aCurve1.D1(l1, pl1, vl1); + aCurve2.D1(f2, pf2, vf2); + aCurve2.D1(l2, pl2, vl2); + + // pf1--->---pl1.pf2--->---pl2 + if (pl1.SquareDistance(pf2) < tolMax*tolMax) { + if (vl1.Angle(vf2) < Precision::Angular()) + return Standard_True; + } + // pl1---<---pf1.pf2--->---pl2 + else if (pf1.SquareDistance(pf2) < tolMax*tolMax) { + if (vf1.Angle(-vf2) < Precision::Angular()) + return Standard_True; + } + // pf1--->---pl1.pl2---<---pf2 + else if (pl1.SquareDistance(pl2) < tolMax*tolMax) { + if (vl1.Angle(-vl2) < Precision::Angular()) + return Standard_True; + } + // pl1---<---pf1.pl2---<---pf2 + else { + if (vf1.Angle(vl2) < Precision::Angular()) + return Standard_True; + } + + return Standard_False; +} + //======================================================================= //function : GEOMImpl_HealingDriver_Type_ //purpose : diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.hxx b/src/GEOMImpl/GEOMImpl_HealingDriver.hxx index 9493912d9..f1d740d6f 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.hxx @@ -57,6 +57,8 @@ class GEOMImpl_HealingDriver; class GEOMImpl_IHealing; #include +#include +#include Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOMImpl_HealingDriver); @@ -128,45 +130,51 @@ class GEOMImpl_HealingDriver : 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_HealingDriver(); -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_HealingDriver() {}; - - - // Type management - // -Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_HealingDriver_Type_(); -Standard_EXPORT const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(GEOMImpl_HealingDriver) ; } -Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_HealingDriver) == AType || TFunction_Driver::IsKind(AType)); } + 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_HealingDriver(); + Standard_EXPORT ~GEOMImpl_HealingDriver() {}; + + Standard_EXPORT static const Standard_GUID& GetID(); + + 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 Standard_Boolean AreEdgesC1 (const TopoDS_Edge& E1, const TopoDS_Edge& E2); + Standard_EXPORT static void FuseCollinearEdges (const TopoDS_Shape&, + const Handle(TColStd_HSequenceOfTransient)&, + TopoDS_Shape&); + + // Type management + // + Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_HealingDriver_Type_(); + Standard_EXPORT const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(GEOMImpl_HealingDriver) ; } + Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_HealingDriver) == AType || TFunction_Driver::IsKind(AType)); } private: -Standard_Boolean ShapeProcess ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean SuppressFaces ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean CloseContour ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean RemoveIntWires( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean RemoveHoles ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean Sew ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean AddPointOnEdge( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -Standard_Boolean ChangeOrientation( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; -void LimitTolerance( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean ShapeProcess ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean SuppressFaces ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean CloseContour ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean RemoveIntWires( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean RemoveHoles ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean Sew ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean AddPointOnEdge( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + Standard_Boolean ChangeOrientation( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + void LimitTolerance( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; }; diff --git a/src/GEOMImpl/GEOMImpl_IFillet1d.hxx b/src/GEOMImpl/GEOMImpl_IFillet1d.hxx index 484d92b65..eb3ef0ee6 100644 --- a/src/GEOMImpl/GEOMImpl_IFillet1d.hxx +++ b/src/GEOMImpl/GEOMImpl_IFillet1d.hxx @@ -15,16 +15,16 @@ // 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 +#define FILLET1D_ARG_BOOL 3 +#define FILLET1D_ARG_LENG 4 +#define FILLET1D_ARG_LAST 5 class GEOMImpl_IFillet1d { @@ -36,11 +36,13 @@ class GEOMImpl_IFillet1d Handle(GEOM_Function) GetShape() { return _func->GetReference(FILLET1D_ARG_SH); } void SetR(double theR) { _func->SetReal(FILLET1D_ARG_R, theR); } + void SetFlag(const Standard_Boolean theFlag) { _func->SetInteger(FILLET1D_ARG_BOOL, theFlag ? 1 : 0); } 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); } + Standard_Boolean GetFlag() { return (_func->GetInteger(FILLET1D_ARG_BOOL) == 1); } int GetLength() { return _func->GetInteger(FILLET1D_ARG_LENG); } int GetVertex(int theInd) { return _func->GetInteger(FILLET1D_ARG_LAST + theInd); } diff --git a/src/GEOMImpl/GEOMImpl_IHealing.hxx b/src/GEOMImpl/GEOMImpl_IHealing.hxx index 91f8c34f0..2ee387908 100755 --- a/src/GEOMImpl/GEOMImpl_IHealing.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealing.hxx @@ -18,28 +18,31 @@ // 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 "GEOM_Function.hxx" #include #include - -#define ARG_SHAPE_PROCESS_OPERATORS 1 -#define ARG_SHAPE_PROCESS_PARAMS 2 -#define ARG_SHAPE_PROCESS_VALUES 3 -#define ARG_ORIGINAL 4 -#define ARG_LIST_ARGUMENTS 5 -#define ARG_IS_COMMON_VERTEX 6 -#define ARG_TOLERANCE 7 -#define ARG_DEV_EDGE_VALUE 8 -#define ARG_IS_BY_PARAMETER 9 -#define ARG_SUBSHAPE_INDEX 10 - +#include "TColStd_HSequenceOfTransient.hxx" class GEOMImpl_IHealing { public: + + enum { + ARG_SHAPE_PROCESS_OPERATORS = 1, + ARG_SHAPE_PROCESS_PARAMS = 2, + ARG_SHAPE_PROCESS_VALUES = 3, + ARG_ORIGINAL = 4, + ARG_LIST_ARGUMENTS = 5, + ARG_IS_COMMON_VERTEX = 6, + ARG_TOLERANCE = 7, + ARG_DEV_EDGE_VALUE = 8, + ARG_IS_BY_PARAMETER = 9, + ARG_SUBSHAPE_INDEX = 10, + ARG_LIST_SHAPES = 11 + }; + GEOMImpl_IHealing(Handle(GEOM_Function) theFunction): _func(theFunction) {} void SetOperators( const Handle(TColStd_HArray1OfExtendedString)& arr ) { if ( !arr.IsNull() ) _func->SetStringArray(ARG_SHAPE_PROCESS_OPERATORS, arr); } @@ -75,6 +78,11 @@ public: void SetIndex( Standard_Integer val ) { _func->SetInteger(ARG_SUBSHAPE_INDEX, val); } Standard_Integer GetIndex() { return _func->GetInteger(ARG_SUBSHAPE_INDEX); } + void SetShapes(const Handle(TColStd_HSequenceOfTransient)& theShapes) + { _func->SetReferenceList(ARG_LIST_SHAPES, theShapes); } + Handle(TColStd_HSequenceOfTransient) GetShapes() + { return _func->GetReferenceList(ARG_LIST_SHAPES); } + private: Handle(GEOM_Function) _func; }; diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx index 9043f811a..3db0e6a93 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx @@ -691,15 +691,13 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) #if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif - if (!GetSolver()->ComputeFunction(aFunction)) - { + if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) - { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); return NULL; } @@ -712,6 +710,81 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) return aNewObject; } +//============================================================================= +/*! + * FuseCollinearEdgesWithinWire + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire + (Handle(GEOM_Object) theWire, + std::list theVertices) +{ + SetErrorCode(KO); + + if (theWire.IsNull()) return NULL; + + // Add a new object + Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), theWire->GetType()); + + // Add a new function + Handle(GEOM_Function) aFunction; + aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES); + if (aFunction.IsNull()) return NULL; + + // Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + GEOMImpl_IHealing aCI (aFunction); + + Handle(GEOM_Function) aRefShape = theWire->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + aCI.SetOriginal(aRefShape); + + Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient; + std::list::iterator it = theVertices.begin(); + for (; it != theVertices.end(); it++) { + Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction(); + if (aRefSh.IsNull()) { + SetErrorCode("NULL argument shape for the shape construction"); + return NULL; + } + aVertices->Append(aRefSh); + } + aCI.SetShapes(aVertices); + + // Compute the new wire + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing 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 << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", ["; + // Vertices + it = theVertices.begin(); + if (it != theVertices.end()) { + pd << (*it++); + while (it != theVertices.end()) { + pd << ", " << (*it++); + } + } + pd << "])"; + + SetErrorCode(OK); + return aRes; +} + //============================================================================= /*! * GetFreeBoundary diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx index e65976190..7434d937c 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOMImpl_IHealingOperations_HXX_ #define _GEOMImpl_IHealingOperations_HXX_ @@ -78,6 +77,10 @@ class GEOMImpl_IHealingOperations : public GEOM_IOperations { double theValue, bool isByParameter ); + Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire + (Handle(GEOM_Object) theWire, + std::list theVertices); + // this function does not use Function-Driver mechanism, it just computes the free // boundary edges and returns them in the sequence. It is called just for information reasons // and it's not intended for history/undo/redo/etc.. diff --git a/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx b/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx index 92b3c91a4..76b8f0563 100644 --- a/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ILocalOperations.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -492,7 +491,8 @@ Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet2D */ //============================================================================= Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet1D - (Handle(GEOM_Object) theShape, double theR, std::list theVertexes) + (Handle(GEOM_Object) theShape, double theR, + std::list theVertexes, bool doIgnoreSecantVertices) { SetErrorCode(KO); @@ -514,6 +514,7 @@ Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet1D aCI.SetShape(aRefShape); aCI.SetR(theR); + aCI.SetFlag(doIgnoreSecantVertices); int aLen = theVertexes.size(); aCI.SetLength(aLen); diff --git a/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx b/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx index e1588da41..e3877b63b 100644 --- a/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ILocalOperations.hxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOMImpl_ILocalOperations_HXX_ #define _GEOMImpl_ILocalOperations_HXX_ @@ -50,7 +49,7 @@ class GEOMImpl_ILocalOperations : public GEOM_IOperations { 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); + std::list theVertexes, bool doIgnoreSecantVertices); 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_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index b81b261ce..682311302 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : GEOMImpl_IShapesOperations.cxx // Created : @@ -1010,10 +1009,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages); for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) { // some key shape - //const TopoDS_Shape& aSkey = aItDMSLS.Key(); + //const TopoDS_Shape& aSkey = aItDMSLS.Key(); // list of shapes of the argument that can be glued - const TopTools_ListOfShape& aLSD = aItDMSLS.Value(); + const TopTools_ListOfShape& aLSD = aItDMSLS.Value(); //listShape.Append(aLSD.First()); TopoDS_Shape aValue = aLSD.First(); @@ -3920,8 +3919,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) return NULL; } - // the list of shapes aLSA contains the shapes - // of the Shape For Search that corresponds + // the list of shapes aLSA contains the shapes + // of the Shape For Search that corresponds // to the Argument aWhat const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat); if (aLSA.Extent() == 0) { @@ -4920,7 +4919,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object //function : GetSameIDs //purpose : //======================================================================= -Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs(const Handle(GEOM_Object)& theShapeWhere, +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs + (const Handle(GEOM_Object)& theShapeWhere, const Handle(GEOM_Object)& theShapeWhat) { SetErrorCode(KO); @@ -4931,8 +4931,6 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs(const if (aWhere.IsNull() || aWhat.IsNull()) return NULL; - int anIndex = -1; - bool isFound = false; TopTools_ListOfShape listShape; TopTools_MapOfShape aMap; @@ -5017,6 +5015,6 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs(const return aSeq; } else { SetErrorCode(NOT_FOUND_ANY); - return NULL; + return NULL; } } diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index c05db9fc1..e1ef28022 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -144,14 +144,14 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if (aShape_i.IsNull()) { Standard_NullObject::Raise("Shape for wire construction is null"); } - if (aShape_i.ShapeType() == TopAbs_EDGE || aShape_i.ShapeType() == TopAbs_WIRE) { - TopExp_Explorer exp (aShape_i, TopAbs_EDGE); - for (; exp.More(); exp.Next()) - B.Add(aWire, TopoDS::Edge(exp.Current())); - } else { - Standard_TypeMismatch::Raise - ("Shape for wire construction is neither an edge nor a wire"); - } + if (aShape_i.ShapeType() == TopAbs_EDGE || aShape_i.ShapeType() == TopAbs_WIRE) { + TopExp_Explorer exp (aShape_i, TopAbs_EDGE); + for (; exp.More(); exp.Next()) + B.Add(aWire, TopoDS::Edge(exp.Current())); + } else { + Standard_TypeMismatch::Raise + ("Shape for wire construction is neither an edge nor a wire"); + } } // fix edges order @@ -491,6 +491,108 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const Standard_Real AngTol = aCI.GetAngularTolerance(); if (aWire.IsNull()) Standard_NullObject::Raise("Argument Wire is null"); + aShape = MakeEdgeFromWire(aWire, LinTol, AngTol); + } + else if (aType == EDGE_CURVE_LENGTH) { + GEOMImpl_IVector aVI (aFunction); + + // RefCurve + Handle(GEOM_Function) aRefCurve = aVI.GetPoint1(); + if (aRefCurve.IsNull()) Standard_NullObject::Raise("Argument Curve is null"); + TopoDS_Shape aRefShape1 = aRefCurve->GetValue(); + if (aRefShape1.ShapeType() != TopAbs_EDGE) { + Standard_TypeMismatch::Raise + ("Edge On Curve creation aborted : curve shape is not an edge"); + } + TopoDS_Edge aRefEdge = TopoDS::Edge(aRefShape1); + TopoDS_Vertex V1, V2; + TopExp::Vertices(aRefEdge, V1, V2, Standard_True); + + // RefPoint + TopoDS_Vertex aRefVertex; + Handle(GEOM_Function) aRefPoint = aVI.GetPoint2(); + if (aRefPoint.IsNull()) { + aRefVertex = V1; + } + else { + TopoDS_Shape aRefShape2 = aRefPoint->GetValue(); + if (aRefShape2.ShapeType() != TopAbs_VERTEX) { + Standard_TypeMismatch::Raise + ("Edge On Curve creation aborted : start point shape is not a vertex"); + } + aRefVertex = TopoDS::Vertex(aRefShape2); + } + gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex); + + // Length + Standard_Real aLength = aVI.GetParameter(); + //Standard_Real aCurveLength = IntTools::Length(aRefEdge); + //if (aLength > aCurveLength) { + // Standard_ConstructionError::Raise + // ("Edge On Curve creation aborted : given length is greater than edges length"); + //} + if (fabs(aLength) < Precision::Confusion()) { + Standard_ConstructionError::Raise + ("Edge On Curve creation aborted : given length is smaller than Precision::Confusion()"); + } + + // Check orientation + Standard_Real UFirst, ULast; + Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast); + Handle(Geom_Curve) ReOrientedCurve = EdgeCurve; + + Standard_Real dU = ULast - UFirst; + Standard_Real par1 = UFirst + 0.1 * dU; + Standard_Real par2 = ULast - 0.1 * dU; + + gp_Pnt P1 = EdgeCurve->Value(par1); + gp_Pnt P2 = EdgeCurve->Value(par2); + + if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) { + ReOrientedCurve = EdgeCurve->Reversed(); + UFirst = EdgeCurve->ReversedParameter(ULast); + } + + // Get the point by length + GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve); + GCPnts_AbscissaPoint anAbsPnt (AdapCurve, aLength, UFirst); + Standard_Real aParam = anAbsPnt.Parameter(); + + if (AdapCurve.IsClosed() && aLength < 0.0) { + Standard_Real aTmp = aParam; + aParam = UFirst; + UFirst = aTmp; + } + + BRepBuilderAPI_MakeEdge aME (ReOrientedCurve, UFirst, aParam); + if (aME.IsDone()) + aShape = aME.Shape(); + } + else { + } + + if (aShape.IsNull()) return 0; + + // Check shape validity + BRepCheck_Analyzer ana (aShape, false); + if (!ana.IsValid()) { + //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); + } + + aFunction->SetValue(aShape); + + log.SetTouched(Label()); + + if (!aWarning.IsEmpty()) + Standard_Failure::Raise(aWarning.ToCString()); + + return 1; +} + +TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, + const Standard_Real LinTol, + const Standard_Real AngTol) +{ TopoDS_Edge ResEdge; BRepLib::BuildCurves3d(aWire); @@ -834,105 +936,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if (FinalReverse) ResEdge.Reverse(); - aShape = ResEdge; - } - else if (aType == EDGE_CURVE_LENGTH) { - GEOMImpl_IVector aVI (aFunction); - - // RefCurve - Handle(GEOM_Function) aRefCurve = aVI.GetPoint1(); - if (aRefCurve.IsNull()) Standard_NullObject::Raise("Argument Curve is null"); - TopoDS_Shape aRefShape1 = aRefCurve->GetValue(); - if (aRefShape1.ShapeType() != TopAbs_EDGE) { - Standard_TypeMismatch::Raise - ("Edge On Curve creation aborted : curve shape is not an edge"); - } - TopoDS_Edge aRefEdge = TopoDS::Edge(aRefShape1); - TopoDS_Vertex V1, V2; - TopExp::Vertices(aRefEdge, V1, V2, Standard_True); - - // RefPoint - TopoDS_Vertex aRefVertex; - Handle(GEOM_Function) aRefPoint = aVI.GetPoint2(); - if (aRefPoint.IsNull()) { - aRefVertex = V1; - } - else { - TopoDS_Shape aRefShape2 = aRefPoint->GetValue(); - if (aRefShape2.ShapeType() != TopAbs_VERTEX) { - Standard_TypeMismatch::Raise - ("Edge On Curve creation aborted : start point shape is not a vertex"); - } - aRefVertex = TopoDS::Vertex(aRefShape2); - } - gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex); - - // Length - Standard_Real aLength = aVI.GetParameter(); - //Standard_Real aCurveLength = IntTools::Length(aRefEdge); - //if (aLength > aCurveLength) { - // Standard_ConstructionError::Raise - // ("Edge On Curve creation aborted : given length is greater than edges length"); - //} - if (fabs(aLength) < Precision::Confusion()) { - Standard_ConstructionError::Raise - ("Edge On Curve creation aborted : given length is smaller than Precision::Confusion()"); - } - - // Check orientation - Standard_Real UFirst, ULast; - Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast); - Handle(Geom_Curve) ReOrientedCurve = EdgeCurve; - - Standard_Real dU = ULast - UFirst; - Standard_Real par1 = UFirst + 0.1 * dU; - Standard_Real par2 = ULast - 0.1 * dU; - - gp_Pnt P1 = EdgeCurve->Value(par1); - gp_Pnt P2 = EdgeCurve->Value(par2); - - if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) { - ReOrientedCurve = EdgeCurve->Reversed(); - UFirst = EdgeCurve->ReversedParameter(ULast); - } - - // Get the point by length - GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve); - GCPnts_AbscissaPoint anAbsPnt (AdapCurve, aLength, UFirst); - Standard_Real aParam = anAbsPnt.Parameter(); - - if (AdapCurve.IsClosed() && aLength < 0.0) { - Standard_Real aTmp = aParam; - aParam = UFirst; - UFirst = aTmp; - } - - BRepBuilderAPI_MakeEdge aME (ReOrientedCurve, UFirst, aParam); - if (aME.IsDone()) - aShape = aME.Shape(); - } - else { - } - - if (aShape.IsNull()) return 0; - - // Check shape validity - BRepCheck_Analyzer ana (aShape, false); - if (!ana.IsValid()) { - //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); - } - - aFunction->SetValue(aShape); - - log.SetTouched(Label()); - - if (!aWarning.IsEmpty()) - Standard_Failure::Raise(aWarning.ToCString()); - - return 1; + return ResEdge; } - //======================================================================= //function : GEOMImpl_ShapeDriver_Type_ //purpose : diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx index 41c0fd6ae..653ad7e13 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.hxx @@ -18,11 +18,10 @@ // 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_ShapeDriver.ixx // Module : GEOMImpl -// + #ifndef _GEOMImpl_ShapeDriver_HeaderFile #define _GEOMImpl_ShapeDriver_HeaderFile @@ -119,6 +118,9 @@ class Handle(GEOMImpl_ShapeDriver) : public Handle(TFunction_Driver) { #include #endif +#include +#include + class TColStd_SequenceOfExtendedString; @@ -126,35 +128,38 @@ class GEOMImpl_ShapeDriver : 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_ShapeDriver(); -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_ShapeDriver() {}; - - - // Type management - // -Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_ShapeDriver_Type_(); -Standard_EXPORT const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(GEOMImpl_ShapeDriver) ; } -Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_ShapeDriver) == AType || TFunction_Driver::IsKind(AType)); } - + 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_ShapeDriver(); + Standard_EXPORT ~GEOMImpl_ShapeDriver() {}; + + 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 static TopoDS_Edge MakeEdgeFromWire(const TopoDS_Shape& aWire, + const Standard_Real LinTol, + const Standard_Real AngTol); + + // Type management + // + Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_ShapeDriver_Type_(); + Standard_EXPORT const Handle(Standard_Type)& DynamicType() const { return STANDARD_TYPE(GEOMImpl_ShapeDriver) ; } + Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_ShapeDriver) == AType || TFunction_Driver::IsKind(AType)); } }; diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index b8a332987..2e5f871b8 100755 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -285,6 +285,7 @@ #define DIVIDE_EDGE 7 #define CHANGE_ORIENTATION 8 #define LIMIT_TOLERANCE 9 +#define FUSE_COLLINEAR_EDGES 10 #define BASIC_FILLING 1 diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.cc b/src/GEOM_I/GEOM_IHealingOperations_i.cc index 84f1e2324..9a064b3d0 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.cc +++ b/src/GEOM_I/GEOM_IHealingOperations_i.cc @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -396,6 +395,43 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::DivideEdge (GEOM::GEOM_Object_p return GetObject(aNewObject); } +//============================================================================= +/*! + * FuseCollinearEdgesWithinWire + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::FuseCollinearEdgesWithinWire + (GEOM::GEOM_Object_ptr theWire, + const GEOM::ListOfGO& theVertices) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference objects + Handle(GEOM_Object) aWire = GetObjectImpl(theWire); + if (aWire.IsNull()) return aGEOMObject._retn(); + + int ind, aLen; + std::list aVerts; + //Get the shapes + aLen = theVertices.length(); + for (ind = 0; ind < aLen; ind++) { + Handle(GEOM_Object) aSh = GetObjectImpl(theVertices[ind]); + if (aSh.IsNull()) return aGEOMObject._retn(); + aVerts.push_back(aSh); + } + + //Perform operation + Handle(GEOM_Object) anObject = + GetOperations()->FuseCollinearEdgesWithinWire(aWire, aVerts); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * GetFreeBoundary diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.hh b/src/GEOM_I/GEOM_IHealingOperations_i.hh index b7344e9cc..bdbaf8689 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.hh +++ b/src/GEOM_I/GEOM_IHealingOperations_i.hh @@ -18,8 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - #ifndef _GEOM_IHealingOperations_i_HeaderFile #define _GEOM_IHealingOperations_i_HeaderFile @@ -81,6 +79,9 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i : CORBA::Double theValue, CORBA::Boolean isByParameter); + GEOM::GEOM_Object_ptr FuseCollinearEdgesWithinWire (GEOM::GEOM_Object_ptr theWire, + const GEOM::ListOfGO& theVertices); + CORBA::Boolean GetFreeBoundary(GEOM::GEOM_Object_ptr theObject, GEOM::ListOfGO_out theClosedWires, GEOM::ListOfGO_out theOpenWires ); diff --git a/src/GEOM_I/GEOM_ILocalOperations_i.cc b/src/GEOM_I/GEOM_ILocalOperations_i.cc index ec764c2be..954778614 100644 --- a/src/GEOM_I/GEOM_ILocalOperations_i.cc +++ b/src/GEOM_I/GEOM_ILocalOperations_i.cc @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -245,7 +244,8 @@ GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet2D //============================================================================= GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR, - const GEOM::ListOfLong& theVertexes) + const GEOM::ListOfLong& theVertexes, + CORBA::Boolean doIgnoreSecantVertices) { GEOM::GEOM_Object_var aGEOMObject; @@ -263,7 +263,7 @@ GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet1D //Create the Fillet Handle(GEOM_Object) anObject = - GetOperations()->MakeFillet1D(aShapeRef, theR, aVertexes); + GetOperations()->MakeFillet1D(aShapeRef, theR, aVertexes, doIgnoreSecantVertices); if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); diff --git a/src/GEOM_I/GEOM_ILocalOperations_i.hh b/src/GEOM_I/GEOM_ILocalOperations_i.hh index 432f56ffc..764f8e5cb 100644 --- a/src/GEOM_I/GEOM_ILocalOperations_i.hh +++ b/src/GEOM_I/GEOM_ILocalOperations_i.hh @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOM_ILocalOperations_i_HeaderFile #define _GEOM_ILocalOperations_i_HeaderFile @@ -65,7 +64,8 @@ class GEOM_I_EXPORT GEOM_ILocalOperations_i : const GEOM::ListOfLong& theVertexes); GEOM::GEOM_Object_ptr MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR, - const GEOM::ListOfLong& theVertexes); + const GEOM::ListOfLong& theVertexes, + CORBA::Boolean doIgnoreSecantVertices); GEOM::GEOM_Object_ptr MakeChamferAll (GEOM::GEOM_Object_ptr theShape, CORBA::Double theD); diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 684558c07..b3c2cf038 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include "GEOM_Superv_i.hh" #include "SALOME_LifeCycleCORBA.hxx" @@ -3034,14 +3033,16 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFillet2D (GEOM::GEOM_Object_ptr theShap //============================================================================= GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR, - GEOM::GEOM_List_ptr theVertexes) + GEOM::GEOM_List_ptr theVertexes, + CORBA::Boolean doIgnoreSecantVertices) { 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()); + GEOM::GEOM_Object_ptr anObj = myLocalOp->MakeFillet1D + (theShape, theR, aListImplV->GetList(), doIgnoreSecantVertices); endService( " GEOM_Superv_i::MakeFillet1D" ); return anObj; } diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.hh b/src/GEOM_I_Superv/GEOM_Superv_i.hh index 3dd0192fe..7a9014af8 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.hh +++ b/src/GEOM_I_Superv/GEOM_Superv_i.hh @@ -642,7 +642,7 @@ public: 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_List_ptr theVertexes, CORBA::Boolean doIgnoreSecantVertices); 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/GEOM_TestHealing.py b/src/GEOM_SWIG/GEOM_TestHealing.py index 6fe6df6c0..abe4a9810 100644 --- a/src/GEOM_SWIG/GEOM_TestHealing.py +++ b/src/GEOM_SWIG/GEOM_TestHealing.py @@ -19,14 +19,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# GEOM GEOM_SWIG : binding of C++ implementaion with Python +# GEOM_SWIG : binding of C++ implementaion with Python # File : GEOM_TestHealing.py # Author : Julia DOROVSKIKH # Module : GEOM -# $Header$ -# + def TestProcessShape (geompy): ##Load shape from BREP file @@ -324,6 +322,51 @@ def TestDivideEdge (geompy): Id_Box = geompy.addToStudy(Box, "Box") Id_Divide = geompy.addToStudy(Divide, "Box with Divided Edge") +def TestFuseEdges (geompy): + + # create vertices + p1 = geompy.MakeVertex(0, 0, 0) + p2 = geompy.MakeVertex(70, 0, 0) + p3 = geompy.MakeVertex(70, 50, 0) + p4 = geompy.MakeVertex(70, 80, 0) + p5 = geompy.MakeVertex(50, 80, 0) + p6 = geompy.MakeVertex(20, 80, 0) + p7 = geompy.MakeVertex(0, 80, 0) + p8 = geompy.MakeVertex(0, 30, 0) + + points = [p1, p2, p3, p4, p5, p6, p7, p8] + + # make a wire + wire_1 = geompy.MakePolyline(points, True) + + # suppress some vertices in the wire + wire_2 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p3]) + wire_3 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p5, p6]) + + # suppress all suitable vertices in the wire + wire_4 = geompy.FuseCollinearEdgesWithinWire(wire_1, []) + + wires = [wire_1, wire_2, wire_3, wire_4] + + # add objects in the study + ii = 1 + for point in points: + geompy.addToStudy(point, "p%d"%ii) + ii = ii + 1 + pass + + ii = 1 + for wire in wires: + geompy.addToStudy(wire, "wire_%d"%ii) + wire_points = geompy.SubShapeAllSortedCentres(wire, geompy.ShapeType["VERTEX"]) + jj = 1 + for point in wire_points: + geompy.addToStudyInFather(wire, point, "point_%d"%jj) + jj = jj + 1 + pass + ii = ii + 1 + pass + def TestHealingOperations (geompy, math): TestMakeSewing(geompy, math) @@ -333,3 +376,4 @@ def TestHealingOperations (geompy, math): TestCloseContour(geompy) TestSuppressFaces(geompy) TestProcessShape(geompy) + TestFuseEdges(geompy) diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index f07490efb..46a7d224d 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -4642,6 +4642,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj.SetParameters(Parameters) return anObj + ## Suppress the vertices in the wire in case if adjacent edges are C1 continuous. + # @param theWire Wire to minimize the number of C1 continuous edges in. + # @param theVertices A list of vertices to suppress. If the list + # is empty, all vertices in a wire will be assumed. + # @return New GEOM.GEOM_Object with modified wire. + # + # @ref tui_fuse_collinear_edges "Example" + def FuseCollinearEdgesWithinWire(self, theWire, theVertices = []): + """ + Suppress the vertices in the wire in case if adjacent edges are C1 continuous. + + Parameters: + theWire Wire to minimize the number of C1 continuous edges in. + theVertices A list of vertices to suppress. If the list + is empty, all vertices in a wire will be assumed. + + Returns: + New GEOM.GEOM_Object with modified wire. + """ + anObj = self.HealOp.FuseCollinearEdgesWithinWire(theWire, theVertices) + RaiseIfFailed("FuseCollinearEdgesWithinWire", self.HealOp) + return anObj + ## Change orientation of the given object. Updates given shape. # @param theObject Shape to be processed. # @return Updated theObject @@ -6001,10 +6024,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # \note Global index of sub-shape can be obtained, using method GetSubShapeID() # \note The list of vertices could be empty, # in this case fillet will done done at all vertices in wire + # @param doIgnoreSecantVertices If FALSE, fillet radius is always limited + # by the length of the edges, nearest to the fillet vertex. + # But sometimes the next edge is C1 continuous with the one, nearest to + # the fillet point, and such two (or more) edges can be united to allow + # bigger radius. Set this flag to TRUE to allow collinear edges union, + # thus ignoring the secant vertex (vertices). # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fillet2d "Example" - def MakeFillet1D(self,theShape, theR, theListOfVertexes): + def MakeFillet1D(self,theShape, theR, theListOfVertexes, doIgnoreSecantVertices = True): """ Perform a fillet on the specified edges of the given shape @@ -6012,6 +6041,12 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Wire Shape to perform fillet on. theR Fillet radius. theListOfVertexes Global indices of vertexes to perform fillet on. + doIgnoreSecantVertices If FALSE, fillet radius is always limited + by the length of the edges, nearest to the fillet vertex. + But sometimes the next edge is C1 continuous with the one, nearest to + the fillet point, and such two (or more) edges can be united to allow + bigger radius. Set this flag to TRUE to allow collinear edges union, + thus ignoring the secant vertex (vertices). Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6027,8 +6062,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): Fillet_1D_1 = geompy.MakeFillet1D(Wire_1, 55, [3, 4, 6, 8, 10]) """ # Example: see GEOM_TestAll.py - theR,Parameters = ParseParameters(theR) - anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes) + theR,doIgnoreSecantVertices,Parameters = ParseParameters(theR,doIgnoreSecantVertices) + anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes, doIgnoreSecantVertices) RaiseIfFailed("MakeFillet1D", self.LocalOp) anObj.SetParameters(Parameters) return anObj diff --git a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx index 16cc60845..ee5b86633 100644 --- a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx +++ b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.cxx @@ -15,7 +15,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : OperationGUI_Fillet1d2dDlg.cxx @@ -68,7 +67,7 @@ OperationGUI_Fillet1d2dDlg::OperationGUI_Fillet1d2dDlg (GeometryGUI* theGeometry mainFrame()->RadioButton2->close(); mainFrame()->RadioButton3->close(); - GroupVertexes = new DlgRef_2Sel1Spin(centralWidget()); + GroupVertexes = new DlgRef_2Sel1Spin2Check (centralWidget()); 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")); @@ -77,6 +76,13 @@ OperationGUI_Fillet1d2dDlg::OperationGUI_Fillet1d2dDlg (GeometryGUI* theGeometry GroupVertexes->PushButton2->setIcon(iconSelect); GroupVertexes->LineEdit1->setReadOnly(true); GroupVertexes->LineEdit2->setReadOnly(true); + if (myIs1D) { + GroupVertexes->CheckButton1->setText(tr("GEOM_FILLET_1D_IGNORE_SECANT")); + GroupVertexes->CheckButton1->setChecked(true); + } + else + GroupVertexes->CheckButton1->close(); + GroupVertexes->CheckButton2->close(); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -127,8 +133,6 @@ void OperationGUI_Fillet1d2dDlg::Init() connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk() )); connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); - // connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); - connect(GroupVertexes->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(GroupVertexes->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); @@ -137,6 +141,8 @@ void OperationGUI_Fillet1d2dDlg::Init() connect(GroupVertexes->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupVertexes->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(processPreview())); + initName(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D")); GroupVertexes->PushButton1->click(); @@ -401,7 +407,7 @@ bool OperationGUI_Fillet1d2dDlg::execute (ObjectList& objects) GEOM::GEOM_ILocalOperations_var anOper = GEOM::GEOM_ILocalOperations::_narrow(getOperation()); GEOM::GEOM_Object_var anObj = myIs1D ? - anOper->MakeFillet1D(myShape, getRadius(), aListOfIndexes) : + anOper->MakeFillet1D(myShape, getRadius(), aListOfIndexes, GroupVertexes->CheckButton1->isChecked()) : anOper->MakeFillet2D(myShape, getRadius(), aListOfIndexes); if (!anObj->_is_nil()) @@ -416,5 +422,5 @@ bool OperationGUI_Fillet1d2dDlg::execute (ObjectList& objects) //================================================================================= double OperationGUI_Fillet1d2dDlg::getRadius() const { - return GroupVertexes ->SpinBox_DX->value(); + return GroupVertexes->SpinBox_DX->value(); } diff --git a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h index 85fdf27f7..04b4a7fce 100644 --- a/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h +++ b/src/OperationGUI/OperationGUI_Fillet1d2dDlg.h @@ -15,12 +15,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : OperationGUI_Fillet1d2dDlg.h // Author : DMV, OCN -// + #ifndef OPERATIONGUI_Fillet1d2dDLG_H #define OPERATIONGUI_Fillet1d2dDLG_H @@ -28,7 +27,7 @@ #include -class DlgRef_2Sel1Spin; +class DlgRef_2Sel1Spin2Check; //================================================================================= // class : OperationGUI_Fillet1d2dDlg @@ -68,7 +67,7 @@ private: GEOM::GEOM_Object_var myShape; TColStd_IndexedMapOfInteger myVertexes; - DlgRef_2Sel1Spin* GroupVertexes; + DlgRef_2Sel1Spin2Check* GroupVertexes; }; #endif // OPERATIONGUI_Fillet1d2dDLG_H diff --git a/src/RepairGUI/Makefile.am b/src/RepairGUI/Makefile.am index a4453ae5c..4c1bf3d8e 100644 --- a/src/RepairGUI/Makefile.am +++ b/src/RepairGUI/Makefile.am @@ -15,13 +15,11 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# GEOM REPAIRGUI : # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. (alexander.borodin@opencascade.com) # Package : RepairGUI -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -39,7 +37,8 @@ salomeinclude_HEADERS = \ RepairGUI_ChangeOrientationDlg.h \ RepairGUI_GlueDlg.h \ RepairGUI_LimitToleranceDlg.h \ - RepairGUI_RemoveExtraEdgesDlg.h + RepairGUI_RemoveExtraEdgesDlg.h \ + RepairGUI_FuseEdgesDlg.h # Libraries targets lib_LTLIBRARIES = libRepairGUI.la @@ -59,6 +58,7 @@ dist_libRepairGUI_la_SOURCES = \ RepairGUI_GlueDlg.h \ RepairGUI_LimitToleranceDlg.h \ RepairGUI_RemoveExtraEdgesDlg.h \ + RepairGUI_FuseEdgesDlg.h \ \ RepairGUI.cxx \ RepairGUI_SewingDlg.cxx \ @@ -73,7 +73,8 @@ dist_libRepairGUI_la_SOURCES = \ RepairGUI_ChangeOrientationDlg.cxx \ RepairGUI_GlueDlg.cxx \ RepairGUI_LimitToleranceDlg.cxx \ - RepairGUI_RemoveExtraEdgesDlg.cxx + RepairGUI_RemoveExtraEdgesDlg.cxx \ + RepairGUI_FuseEdgesDlg.cxx MOC_FILES = \ RepairGUI_SewingDlg_moc.cxx \ @@ -88,7 +89,8 @@ MOC_FILES = \ RepairGUI_ChangeOrientationDlg_moc.cxx \ RepairGUI_GlueDlg_moc.cxx \ RepairGUI_LimitToleranceDlg_moc.cxx \ - RepairGUI_RemoveExtraEdgesDlg_moc.cxx + RepairGUI_RemoveExtraEdgesDlg_moc.cxx \ + RepairGUI_FuseEdgesDlg_moc.cxx nodist_libRepairGUI_la_SOURCES = \ $(MOC_FILES) diff --git a/src/RepairGUI/RepairGUI.cxx b/src/RepairGUI/RepairGUI.cxx index 3c72cbac3..5144986fa 100644 --- a/src/RepairGUI/RepairGUI.cxx +++ b/src/RepairGUI/RepairGUI.cxx @@ -44,6 +44,7 @@ #include "RepairGUI_LimitToleranceDlg.h" // Method LIMIT TOLERANCE #include "RepairGUI_ChangeOrientationDlg.h" // Method CHANGE ORIENTATION #include "RepairGUI_RemoveExtraEdgesDlg.h" // Method REMOVE EXTRA EDGES +#include "RepairGUI_FuseEdgesDlg.h" // Method FUSE COLLINEAR EDGES //======================================================================= // function : RepairGUI() @@ -90,9 +91,10 @@ bool RepairGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpFreeFaces: aDlg = new RepairGUI_FreeFacesDlg (getGeometryGUI(), parent); break; case GEOMOp::OpOrientation: aDlg = new RepairGUI_ChangeOrientationDlg (getGeometryGUI(), parent); break; case GEOMOp::OpRemoveExtraEdges: aDlg = new RepairGUI_RemoveExtraEdgesDlg (getGeometryGUI(), parent); break; - default: - app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); - break; + case GEOMOp::OpFuseEdges: aDlg = new RepairGUI_FuseEdgesDlg (getGeometryGUI(), parent); break; + default: + app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); + break; } if (aDlg) diff --git a/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx b/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx new file mode 100644 index 000000000..4356b1896 --- /dev/null +++ b/src/RepairGUI/RepairGUI_FuseEdgesDlg.cxx @@ -0,0 +1,347 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 "RepairGUI_FuseEdgesDlg.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// OCCT Includes +#include +#include + +#include + +//================================================================================= +// class : RepairGUI_FuseEdgesDlg() +// purpose : Constructs a RepairGUI_FuseEdgesDlg 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. +//================================================================================= +RepairGUI_FuseEdgesDlg::RepairGUI_FuseEdgesDlg (GeometryGUI* theGeometryGUI, + QWidget* parent) + : GEOMBase_Skeleton(theGeometryGUI, parent, false) +{ + SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FUSE_EDGES"))); + QPixmap iconSelect (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("GEOM_FUSE_EDGES_TITLE")); + + mainFrame()->GroupConstructors->setTitle(tr("GEOM_FUSE_EDGES")); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->close(); + + GroupVertexes = new DlgRef_2Sel1Spin (centralWidget()); + GroupVertexes->GroupBox1->setTitle(tr("GEOM_FUSE_EDGES")); + GroupVertexes->TextLabel1->setText(tr("GEOM_WIRE")); + GroupVertexes->TextLabel2->setText(tr("GEOM_VERTEXES")); + GroupVertexes->PushButton1->setIcon(iconSelect); + GroupVertexes->PushButton2->setIcon(iconSelect); + GroupVertexes->LineEdit1->setReadOnly(true); + GroupVertexes->LineEdit2->setReadOnly(true); + + GroupVertexes->TextLabel3->setShown(false); + GroupVertexes->SpinBox_DX->setShown(false); + + QVBoxLayout* layout = new QVBoxLayout (centralWidget()); + layout->setMargin(0); + layout->setSpacing(6); + layout->addWidget(GroupVertexes); + + setHelpFileName("fuse_edges_operation_page.html"); + + // Initialisation + Init(); + resize(100,100); +} + +//================================================================================= +// function : ~RepairGUI_FuseEdgesDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +RepairGUI_FuseEdgesDlg::~RepairGUI_FuseEdgesDlg() +{ +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::Init() +{ + // Clear line edits + GroupVertexes->LineEdit1->setText(""); + GroupVertexes->LineEdit2->setText(""); + + myShape = GEOM::GEOM_Object::_nil(); + + myPoints.clear(); + + // signals and slots connections + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(GroupVertexes->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(GroupVertexes->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + + connect(GroupVertexes->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + connect(GroupVertexes->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + + initName(tr("FUSE_EDGES_NEW_OBJ_NAME")); + GroupVertexes->PushButton1->click(); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::ClickOnOk() +{ + setIsApplyAndClose(true); + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool RepairGUI_FuseEdgesDlg::ClickOnApply() +{ + if (!onAccept()) + return false; + + initName(); + // Reset dialog state + GroupVertexes->LineEdit1->setText(""); + GroupVertexes->LineEdit2->setText(""); + myShape = GEOM::GEOM_Object::_nil(); + myPoints.clear(); + GroupVertexes->PushButton1->click(); + + return true; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection is changed or on dialog initialization or activation +//================================================================================= +void RepairGUI_FuseEdgesDlg::SelectionIntoArgument() +{ + myEditCurrentArgument->setText(""); + + LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); + + // If selection of main object is activated + if (myEditCurrentArgument == GroupVertexes->LineEdit1) { + myShape = GEOM::GEOM_Object::_nil(); + if (aSelList.Extent() == 1) { + GEOM::GEOM_Object_var anObj = + GEOMBase::ConvertIOinGEOMObject(aSelList.First()); + + if (!anObj->_is_nil()) { + QString aName = GEOMBase::GetName(anObj); + TopoDS_Shape aShape; + if (GEOMBase::GetShape(anObj, aShape, TopAbs_SHAPE) && !aShape.IsNull()) { + TColStd_IndexedMapOfInteger aMap; + aSelMgr->GetIndexes(aSelList.First(), aMap); + if (aMap.Extent() == 1) { // Local Selection + int anIndex = aMap(1); + aName += QString(":wire_%1").arg(anIndex); + + //Find SubShape Object in Father + GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather(anObj, aName); + + if (aFindedObject->_is_nil()) { // Object not found in study + GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId()); + anObj = aShapesOp->GetSubShape(anObj, anIndex); + } + else + anObj = aFindedObject; // get Object from study + } + else { // Global Selection + if (aShape.ShapeType() != TopAbs_WIRE) { + anObj = GEOM::GEOM_Object::_nil(); + aName = ""; + } + } + } + myShape = anObj; + myEditCurrentArgument->setText(aName); + } + } + + if (!myShape->_is_nil() && myPoints.isEmpty()) + GroupVertexes->PushButton2->click(); + } + else if (myEditCurrentArgument == GroupVertexes->LineEdit2) { + myPoints = getSelected(TopAbs_VERTEX, -1); + if (!myPoints.isEmpty()) + myEditCurrentArgument->setText(QString::number(myPoints.count()) + "_" + tr("GEOM_POINT") + tr("_S_")); + else + myEditCurrentArgument->setText(""); + } +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + if (send == GroupVertexes->PushButton1) { + myEditCurrentArgument = GroupVertexes->LineEdit1; + GroupVertexes->PushButton2->setDown(false); + GroupVertexes->LineEdit2->setEnabled(false); + } + else if (send == GroupVertexes->PushButton2) { + myEditCurrentArgument = GroupVertexes->LineEdit2; + GroupVertexes->PushButton1->setDown(false); + GroupVertexes->LineEdit1->setEnabled(false); + } + + // enable line edit + myEditCurrentArgument->setEnabled(true); + myEditCurrentArgument->setFocus(); + // after setFocus(), because it will be setDown(false) when loses focus + send->setDown(true); + + activateSelection(); +} + +//================================================================================= +// function : LineEditReturnPressed() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::LineEditReturnPressed() +{ + QLineEdit* send = (QLineEdit*)sender(); + + if (send == GroupVertexes->LineEdit1) + myEditCurrentArgument = GroupVertexes->LineEdit1; + else if (send == GroupVertexes->LineEdit2) + myEditCurrentArgument = GroupVertexes->LineEdit2; + else + return; + + GEOMBase_Skeleton::LineEditReturnPressed(); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void RepairGUI_FuseEdgesDlg::enterEvent (QEvent*) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) + this->ActivateThisDialog(); +} + +//================================================================================= +// function : activateSelection +// purpose : Activate selection in accordance with myEditCurrentArgument +//================================================================================= +void RepairGUI_FuseEdgesDlg::activateSelection() +{ + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + globalSelection(); + if (myEditCurrentArgument == GroupVertexes->LineEdit1) + globalSelection(GEOM_WIRE); + else if (!myShape->_is_nil() && myEditCurrentArgument == GroupVertexes->LineEdit2) + localSelection(myShape, TopAbs_VERTEX); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr RepairGUI_FuseEdgesDlg::createOperation() +{ + return getGeomEngine()->GetIHealingOperations(getStudyId()); +} + +//================================================================================= +// function : isValid() +// purpose : Verify validity of input data +//================================================================================= +bool RepairGUI_FuseEdgesDlg::isValid (QString& msg) +{ + return (!myShape->_is_nil()); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool RepairGUI_FuseEdgesDlg::execute (ObjectList& objects) +{ + GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow(getOperation()); + + GEOM::ListOfGO_var points = new GEOM::ListOfGO(); + points->length(myPoints.count()); + for (int i = 0; i < myPoints.count(); i++) + points[i] = myPoints[i].copy(); + + GEOM::GEOM_Object_var anObj = anOper->FuseCollinearEdgesWithinWire(myShape, points.in()); + + if (!anObj->_is_nil()) + objects.push_back(anObj._retn()); + + return true; +} + +//================================================================================= +// function : addSubshapeToStudy +// purpose : virtual method to add new SubObjects if local selection +//================================================================================= +void RepairGUI_FuseEdgesDlg::addSubshapesToStudy() +{ + for (int i = 0; i < myPoints.count(); i++) + GEOMBase::PublishSubObject(myPoints[i].get()); +} diff --git a/src/RepairGUI/RepairGUI_FuseEdgesDlg.h b/src/RepairGUI/RepairGUI_FuseEdgesDlg.h new file mode 100644 index 000000000..38d019aff --- /dev/null +++ b/src/RepairGUI/RepairGUI_FuseEdgesDlg.h @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 + +#ifndef REPAIRGUI_FuseEdgesDLG_H +#define REPAIRGUI_FuseEdgesDLG_H + +#include + +#include + +class DlgRef_2Sel1Spin; + +//================================================================================= +// class : RepairGUI_FuseEdgesDlg +// purpose : +//================================================================================= +class RepairGUI_FuseEdgesDlg : public GEOMBase_Skeleton +{ + Q_OBJECT + +public: + RepairGUI_FuseEdgesDlg (GeometryGUI*, QWidget*); + ~RepairGUI_FuseEdgesDlg(); + +protected: + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid (QString&); + virtual bool execute (ObjectList&); + virtual void addSubshapesToStudy(); + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void ActivateThisDialog(); + void LineEditReturnPressed(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); + +private: + void Init(); + void enterEvent (QEvent*); + void activateSelection(); + +private: + GEOM::GEOM_Object_var myShape; + QList myPoints; + + DlgRef_2Sel1Spin* GroupVertexes; +}; + +#endif // REPAIRGUI_FuseEdgesDLG_H