\b Note: This Operation Works for the Wires with <b>Planar Edges</b> only.
+\b Note: Use option <b>Fuse collinear edges to allow bigger radius</b>
+ to allow ignoring of possible secant points, i.e. the
+ joints of collinear edges, thus processing such edges as one.
+
<b>TUI Command:</b> <em>geompy.MakeFillet1D(Shape, R, ListVertexes)</em>
\n <b>Arguments:</b> Name + 1 shape + empty list or several vertexes + 1 value (Fillet radius).
-\n <b>Advanced options</b> \ref preview_anchor "Preview"
+\n <b>Advanced options:</b> \ref preview_anchor "Preview"
<b>Examples:</b>
--- /dev/null
+/*!
+
+\page fuse_edges_operation_page Fuse Collinear Edges within a Wire
+
+\n To <b>Fuse Collinear Edges within a Wire</b> in the <b>Main Menu</b>
+select <b>Repair - > Fuse Collinear Edges within a Wire</b>.
+\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 <b>Arguments:</b> Name + a wire + a list of vertices (can be empty).
+
+\image html fuse_collinear_edges.png
+
+\n <b>TUI Command:</b> <em>geompy.FuseCollinearEdgesWithinWire(wire, vertices)</em>,
+where <em>wire</em> is a wire and <em>vertices</em> is a list of
+vertices to be suppressed.
+
+Our <b>TUI Scripts</b> provide you with useful examples of the
+\ref tui_fuse_collinear_edges "Fuse Collinear Edges" functionality usage.
+
+*/
reverses the normals of the selected faces.</li>
<li>\subpage remove_extra_edges_operation_page "Remove extra edges" -
removes seam and degenerated edges from the given shape.</li>
+<li>\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.</li>
</ul>
*/
salome.sg.updateObjBrowser(1)
\endcode
+\anchor tui_fuse_collinear_edges
+<br><h2>Fuse Collinear Edges within a Wire</h2>
+
+\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
*/
* <VAR>GEOM_IShapesOperations.GetSubShapeIndex()</VAR>.
* \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.
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.
filletface.png \
filling.png \
fuse.png \
+fuse_collinear_edges.png \
geometry.png \
import_picture.png \
limit_tolerance.png \
<source>ICON_DLG_REMOVE_EXTRA_EDGES</source>
<translation>remove_extra_edges.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_FUSE_EDGES</source>
+ <translation>fuse_collinear_edges.png</translation>
+ </message>
<message>
<source>ICON_DLG_CHECKSHAPE</source>
<translation>check.png</translation>
<source>ICO_REMOVE_EXTRA_EDGES</source>
<translation>remove_extra_edges.png</translation>
</message>
+ <message>
+ <source>ICO_FUSE_EDGES</source>
+ <translation>fuse_collinear_edges.png</translation>
+ </message>
<message>
<source>ICO_NORMALE</source>
<translation>normale.png</translation>
<source>GEOM_FILLET_1D</source>
<translation>Fillet 1D</translation>
</message>
+ <message>
+ <source>GEOM_FILLET_1D_IGNORE_SECANT</source>
+ <translation>Fuse collinear edges to allow bigger radius</translation>
+ </message>
<message>
<source>GEOM_FILLET_ABORT</source>
<translation>Fillet can't be computed with radius %1</translation>
<source>STB_REMOVE_EXTRA_EDGES</source>
<translation>Remove extra edges</translation>
</message>
+ <message>
+ <source>GEOM_FUSE_EDGES_TITLE</source>
+ <translation>Fuse Collinear Edges within a Wire</translation>
+ </message>
+ <message>
+ <source>GEOM_FUSE_EDGES</source>
+ <translation>Fuse edges</translation>
+ </message>
+ <message>
+ <source>FUSE_EDGES_NEW_OBJ_NAME</source>
+ <translation>FuseEdges</translation>
+ </message>
+ <message>
+ <source>TOP_FUSE_EDGES</source>
+ <translation>Fuse collinear edges within a wire</translation>
+ </message>
+ <message>
+ <source>MEN_FUSE_EDGES</source>
+ <translation>Fuse Collinear Edges within a Wire</translation>
+ </message>
+ <message>
+ <source>STB_FUSE_EDGES</source>
+ <translation>Fuse collinear edges within a wire</translation>
+ </message>
<message>
<source>TOP_NORMALE</source>
<translation>Normal to a face</translation>
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
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" );
//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 );
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
// 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
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
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-\r
-// File : GEOMImpl_Fillet1d.hxx\r
-// Module : GEOMImpl\r
-//\r
-#ifndef _GEOMImpl_Fillet1d_HeaderFile\r
-#define _GEOMImpl_Fillet1d_HeaderFile\r
-\r
-#include <gp_Pnt.hxx>\r
-#include <Geom_Plane.hxx>\r
-#include <Geom2d_Curve.hxx>\r
-\r
-#include <TopoDS_Edge.hxx>\r
-#include <TColStd_ListOfReal.hxx>\r
-#include <TColStd_SequenceOfReal.hxx>\r
-#include <TColStd_SequenceOfInteger.hxx>\r
-\r
-class GEOMImpl_Fillet1dPoint;\r
-\r
-/**\r
-* GEOMImpl_Fillet1d is 1D fillet algorithm on two planar edges with given radius\r
-*/\r
-\r
-class GEOMImpl_Fillet1d \r
-{\r
-public:\r
- //! Constructor\r
- //! The fillet 1D algorithm initialise by two edges and plane\r
- Standard_EXPORT GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,\r
- const TopoDS_Edge& theEdge2,\r
- const gp_Pln& thePlane);\r
- //! Makes fillet with given radius\r
- //! @returns Standard_True, if at least one result computed\r
- Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);\r
- //! Returns result fillet edge and modified edges as out parameters\r
- Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2);\r
-\r
-private:\r
- //! private methods\r
- void fillPoint(GEOMImpl_Fillet1dPoint*);\r
- void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean);\r
- void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);\r
- Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);\r
-\r
-\r
-private:\r
- //! private fields\r
- TopoDS_Edge myEdge1, myEdge2;\r
- Handle(Geom_Plane) myPlane;\r
- Handle(Geom2d_Curve) myCurve1, myCurve2;\r
- Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;\r
- TColStd_ListOfReal myResultParams;\r
- TColStd_SequenceOfInteger myResultOrientation;\r
- Standard_Boolean myStartSide, myEdgesExchnged;\r
- Standard_Integer myDegreeOfRecursion;\r
-};\r
-\r
-\r
-/**\r
-* GEOMImpl_Fillet1dPoint is an internal class for 1D fillet algorithm\r
-* to store and compare computed solutions on edges\r
-*/\r
-\r
-class GEOMImpl_Fillet1dPoint\r
-{\r
-public:\r
- //! Puiblic methods\r
-\r
- //! Constructor\r
- Standard_EXPORT GEOMImpl_Fillet1dPoint(Standard_Real theParam)\r
- {myParam = theParam;}\r
- \r
- //! Make copy of point\r
- //!WARNING: Copies only field values: myParam, myV, myD, myValid\r
- Standard_EXPORT GEOMImpl_Fillet1dPoint* Copy(); // warning: this is not the full copy! \r
-\r
- //! Set/Get parameter\r
- Standard_EXPORT inline void SetParam(Standard_Real theParam)\r
- {myParam = theParam;}\r
- Standard_EXPORT inline Standard_Real GetParam() const\r
- {return myParam;}\r
- Standard_EXPORT inline void SetParam2(const Standard_Real theParam2)\r
- {myParam2 = theParam2;}\r
- Standard_EXPORT inline Standard_Real GetParam2()\r
- { return myParam2 ; }\r
-\r
- //! Returns validity \r
- Standard_EXPORT inline Standard_Boolean IsValid(int theIndex)\r
- {return (Standard_Boolean)myValid.Value(theIndex);}\r
-\r
- //! Get values\r
- Standard_EXPORT inline Standard_Integer GetNBValues() {return myV.Length();}\r
- Standard_EXPORT inline Standard_Real GetValue(Standard_Integer theIndex)\r
- {return myV.Value(theIndex);}\r
- Standard_EXPORT inline Standard_Real GetDiff(Standard_Integer theIndex)\r
- {return myD.Value(theIndex);}\r
- Standard_EXPORT inline Standard_Integer GetNear(Standard_Integer theIndex)\r
- {return myNear.Value(theIndex);}\r
-\r
- //! Set/Get center point\r
- Standard_EXPORT inline void SetCenter(const gp_Pnt2d thePoint)\r
- {myCenter = thePoint;}\r
- Standard_EXPORT inline const gp_Pnt2d GetCenter()\r
- {return myCenter;}\r
-\r
- Standard_EXPORT void AddValue(Standard_Real theValue, Standard_Boolean theIsValid);\r
-\r
- //! compute difference between this and given point\r
- Standard_EXPORT Standard_Boolean ComputeDifference(GEOMImpl_Fillet1dPoint*);\r
- Standard_EXPORT void FilterPoints(GEOMImpl_Fillet1dPoint*);\r
- \r
- //! Check is point contains solution and returns the index of them if any\r
- Standard_EXPORT Standard_Integer HasSolution(Standard_Real theRadius); \r
- //! Remove solution by index\r
- void RemoveSolution(Standard_Integer theIndex);\r
-\r
-private:\r
- //! Private fields\r
- gp_Pnt2d myCenter;\r
- Standard_Real myParam, myParam2;\r
- TColStd_SequenceOfReal myV, myD;\r
- TColStd_SequenceOfInteger myValid, myNear;\r
-};\r
-\r
-#endif\r
+
+// File : GEOMImpl_Fillet1d.hxx
+// Module : GEOMImpl
+
+#ifndef _GEOMImpl_Fillet1d_HeaderFile
+#define _GEOMImpl_Fillet1d_HeaderFile
+
+#include <TopoDS_Edge.hxx>
+
+#include <Geom_Plane.hxx>
+#include <Geom2d_Curve.hxx>
+
+#include <gp_Pnt.hxx>
+
+#include <TColStd_ListOfReal.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+
+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
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
#include <Standard_Stream.hxx>
#include <GEOMImpl_Fillet1d.hxx>
#include <GEOMImpl_IFillet1d.hxx>
#include <GEOMImpl_Types.hxx>
-#include <GEOMImpl_ILocalOperations.hxx>
#include <GEOMImpl_IShapesOperations.hxx>
+#include <GEOMImpl_HealingDriver.hxx>
#include <GEOM_Function.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Dir.hxx>
-#include <gp_XYZ.hxx>
-
-#include <BRep_Tool.hxx>
-#include <BRepTools.hxx>
-#include <BRepBuilderAPI_MakeWire.hxx>
-#include <BRepCheck_Analyzer.hxx>
-
-#include <Precision.hxx>
-
#include <ShapeFix_Wire.hxx>
#include <StdFail_NotDone.hxx>
#include <Standard_ConstructionError.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepCheck_Analyzer.hxx>
+
+#include <gp_Pln.hxx>
+#include <gp_Dir.hxx>
+#include <gp_XYZ.hxx>
+
+#include <Precision.hxx>
//=======================================================================
//function : GetID
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
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;
}
// 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
#include <Handle_TFunction_Driver.hxx>
#endif
+#include <TopoDS_Wire.hxx>
+#include <TopTools_ListOfShape.hxx>
+
class Standard_Transient;
class Handle_Standard_Type;
class Handle(TFunction_Driver);
public:
- inline void* operator new(size_t,void* anAddress)
- {
- return anAddress;
- }
- inline void* operator new(size_t size)
- {
- return Standard::Allocate(size);
- }
- inline void operator delete(void *anAddress)
- {
- if (anAddress) Standard::Free((Standard_Address&)anAddress);
- }
-
- // 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;
};
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
#include <Standard_Stream.hxx>
#include <GEOM_Function.hxx>
#include <GEOMImpl_GlueDriver.hxx>
+#include <GEOMImpl_ShapeDriver.hxx>
#include <ShHealOper_ShapeProcess.hxx>
#include <ShHealOper_RemoveFace.hxx>
#include <ShHealOper_EdgeDivide.hxx>
#include <ShHealOper_ChangeOrientation.hxx>
+#include <TNaming_CopyShape.hxx>
+
+#include <ShapeFix_ShapeTolerance.hxx>
+#include <ShapeFix_Shape.hxx>
+
#include <BRep_Builder.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <BRepTools_WireExplorer.hxx>
#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TColStd_IndexedDataMapOfTransientTransient.hxx>
-#include <TNaming_CopyShape.hxx>
-#include <ShapeFix_ShapeTolerance.hxx>
-#include <ShapeFix_Shape.hxx>
-#include <BRepCheck_Analyzer.hxx>
#include <Precision.hxx>
#include <StdFail_NotDone.hxx>
+#include <Standard_NullObject.hxx>
//=======================================================================
//function : raiseNotDoneExeption
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;
}
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 :
class GEOMImpl_IHealing;
#include <TopoDS_Shape.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TColStd_HSequenceOfTransient.hxx>
Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOMImpl_HealingDriver);
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;
};
// 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
{
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); }
// 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 <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfExtendedString.hxx>
-
-#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); }
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;
};
#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;
}
return aNewObject;
}
+//=============================================================================
+/*!
+ * FuseCollinearEdgesWithinWire
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
+ (Handle(GEOM_Object) theWire,
+ std::list<Handle(GEOM_Object)> 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<Handle(GEOM_Object)>::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
// 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_
double theValue,
bool isByParameter );
+ Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire
+ (Handle(GEOM_Object) theWire,
+ std::list<Handle(GEOM_Object)> 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..
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
#include <Standard_Stream.hxx>
*/
//=============================================================================
Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet1D
- (Handle(GEOM_Object) theShape, double theR, std::list<int> theVertexes)
+ (Handle(GEOM_Object) theShape, double theR,
+ std::list<int> theVertexes, bool doIgnoreSecantVertices)
{
SetErrorCode(KO);
aCI.SetShape(aRefShape);
aCI.SetR(theR);
+ aCI.SetFlag(doIgnoreSecantVertices);
int aLen = theVertexes.size();
aCI.SetLength(aLen);
// 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_
Standard_EXPORT Handle(GEOM_Object) MakeFillet2D (Handle(GEOM_Object) theShape, double theR,
std::list<int> theVertexes);
Standard_EXPORT Handle(GEOM_Object) MakeFillet1D (Handle(GEOM_Object) theShape, double theR,
- std::list<int> theVertexes);
+ std::list<int> 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,
// 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 :
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();
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) {
//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);
if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
- int anIndex = -1;
- bool isFound = false;
TopTools_ListOfShape listShape;
TopTools_MapOfShape aMap;
return aSeq;
} else {
SetErrorCode(NOT_FOUND_ANY);
- return NULL;
+ return NULL;
}
}
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
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);
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 :
// 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
#include <Standard_CString.hxx>
#endif
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Edge.hxx>
+
class TColStd_SequenceOfExtendedString;
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)); }
};
#define DIVIDE_EDGE 7
#define CHANGE_ORIENTATION 8
#define LIMIT_TOLERANCE 9
+#define FUSE_COLLINEAR_EDGES 10
#define BASIC_FILLING 1
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
#include <Standard_Stream.hxx>
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<Handle(GEOM_Object)> 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
// 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
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 );
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
#include <Standard_Stream.hxx>
//=============================================================================
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;
//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();
// 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
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);
// 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"
//=============================================================================
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<GEOM::ListOfLong>* aListImplV =
dynamic_cast<GEOM_List_i<GEOM::ListOfLong>*>(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;
}
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,
# 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
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)
TestCloseContour(geompy)
TestSuppressFaces(geompy)
TestProcessShape(geompy)
+ TestFuseEdges(geompy)
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 <var>theObject</var>
# \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
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
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
// 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
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"));
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);
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()));
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();
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())
//=================================================================================
double OperationGUI_Fillet1d2dDlg::getRadius() const
{
- return GroupVertexes ->SpinBox_DX->value();
+ return GroupVertexes->SpinBox_DX->value();
}
// 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
#include <TColStd_IndexedMapOfInteger.hxx>
-class DlgRef_2Sel1Spin;
+class DlgRef_2Sel1Spin2Check;
//=================================================================================
// class : OperationGUI_Fillet1d2dDlg
GEOM::GEOM_Object_var myShape;
TColStd_IndexedMapOfInteger myVertexes;
- DlgRef_2Sel1Spin* GroupVertexes;
+ DlgRef_2Sel1Spin2Check* GroupVertexes;
};
#endif // OPERATIONGUI_Fillet1d2dDLG_H
# 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
RepairGUI_ChangeOrientationDlg.h \
RepairGUI_GlueDlg.h \
RepairGUI_LimitToleranceDlg.h \
- RepairGUI_RemoveExtraEdgesDlg.h
+ RepairGUI_RemoveExtraEdgesDlg.h \
+ RepairGUI_FuseEdgesDlg.h
# Libraries targets
lib_LTLIBRARIES = libRepairGUI.la
RepairGUI_GlueDlg.h \
RepairGUI_LimitToleranceDlg.h \
RepairGUI_RemoveExtraEdgesDlg.h \
+ RepairGUI_FuseEdgesDlg.h \
\
RepairGUI.cxx \
RepairGUI_SewingDlg.cxx \
RepairGUI_ChangeOrientationDlg.cxx \
RepairGUI_GlueDlg.cxx \
RepairGUI_LimitToleranceDlg.cxx \
- RepairGUI_RemoveExtraEdgesDlg.cxx
+ RepairGUI_RemoveExtraEdgesDlg.cxx \
+ RepairGUI_FuseEdgesDlg.cxx
MOC_FILES = \
RepairGUI_SewingDlg_moc.cxx \
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)
#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()
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)
--- /dev/null
+// 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 <DlgRef.h>
+#include <GeometryGUI.h>
+#include <GEOMBase.h>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <SalomeApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+#include <OCCViewer_ViewModel.h>
+
+// OCCT Includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+#include <GEOMImpl_Types.hxx>
+
+//=================================================================================
+// 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());
+}
--- /dev/null
+// 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 <GEOMBase_Skeleton.h>
+
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+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<GEOM::GeomObjPtr> myPoints;
+
+ DlgRef_2Sel1Spin* GroupVertexes;
+};
+
+#endif // REPAIRGUI_FuseEdgesDLG_H