IMPs 0021476 (fuse edges) and 0021477 (suppress a vertex from a wire for fillet1d).

This commit is contained in:
jfa 2012-07-27 11:32:14 +00:00
parent 377b28e6c4
commit e184734288
43 changed files with 1605 additions and 453 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -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 <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>

View File

@ -0,0 +1,23 @@
/*!
\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.
*/

View File

@ -27,6 +27,9 @@ splits an edge in two.</li>
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>
*/

View File

@ -391,5 +391,57 @@ for point in edge_points:
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
*/

View File

@ -2905,11 +2905,18 @@ module GEOM
* <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.
@ -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.

View File

@ -98,6 +98,7 @@ filletwire.png \
filletface.png \
filling.png \
fuse.png \
fuse_collinear_edges.png \
geometry.png \
import_picture.png \
limit_tolerance.png \

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

View File

@ -155,6 +155,10 @@
<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>
@ -979,6 +983,10 @@
<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>

View File

@ -710,6 +710,10 @@ Please, select face, shell or solid and try again</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&apos;t be computed with radius %1</translation>
@ -4306,6 +4310,30 @@ Please, select face, shell or solid and try again</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>

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -15,19 +15,20 @@
// 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 <gp_Pnt.hxx>
#include <TopoDS_Edge.hxx>
#include <Geom_Plane.hxx>
#include <Geom2d_Curve.hxx>
#include <TopoDS_Edge.hxx>
#include <gp_Pnt.hxx>
#include <TColStd_ListOfReal.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColStd_SequenceOfInteger.hxx>
@ -42,13 +43,14 @@ class GEOMImpl_Fillet1d
{
public:
//! Constructor
//! The fillet 1D algorithm initialise by two edges and plane
//! 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);
@ -59,7 +61,6 @@ private:
void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);
Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);
private:
//! private fields
TopoDS_Edge myEdge1, myEdge2;
@ -126,7 +127,7 @@ public:
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
//! 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);

View File

@ -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 <Standard_Stream.hxx>
@ -24,21 +23,10 @@
#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>
@ -54,6 +42,18 @@
#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
@ -161,24 +161,29 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
TopoDS_Wire aWire = TopoDS::Wire(aShape);
double rad = aCI.GetR();
bool doIgnoreSecantPoints = aCI.GetFlag();
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))
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
}
}
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()))
@ -186,7 +191,82 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
}
}
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
@ -221,20 +301,32 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
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) )
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())
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);
// 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 ))
@ -242,10 +334,15 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
}
if (anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty()) {
if (isFinalPass)
StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
return 0;
else
isAllStepsOk = false;
}
if (!isAllStepsOk)
return false;
// create new wire instead of original
for (TopExp_Explorer anExp (aWire, TopAbs_EDGE); anExp.More(); anExp.Next()) {
TopoDS_Shape anEdge = anExp.Current();
@ -263,11 +360,9 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
if (!aWireTool.IsDone())
return 0;
aWire = aWireTool.Wire();
aFunction->SetValue(aWire);
log.SetTouched(Label());
aResult = aWireTool.Wire();
return 1;
return isAllStepsOk;
}

View File

@ -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 <Handle_TFunction_Driver.hxx>
#endif
#include <TopoDS_Wire.hxx>
#include <TopTools_ListOfShape.hxx>
class Standard_Transient;
class Handle_Standard_Type;
class Handle(TFunction_Driver);
@ -139,12 +141,13 @@ public:
// 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; }
Standard_EXPORT static const Standard_GUID& GetID();
Standard_EXPORT ~GEOMImpl_Fillet1dDriver() {};
// Type management
//
@ -154,6 +157,10 @@ Standard_EXPORT const Handle(Standard_Type)& DynamicType() const
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;
};

View File

@ -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 <Standard_Stream.hxx>
@ -28,6 +27,7 @@
#include <GEOM_Function.hxx>
#include <GEOMImpl_GlueDriver.hxx>
#include <GEOMImpl_ShapeDriver.hxx>
#include <ShHealOper_ShapeProcess.hxx>
#include <ShHealOper_RemoveFace.hxx>
@ -38,22 +38,30 @@
#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
@ -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 :

View File

@ -57,6 +57,8 @@ class GEOMImpl_HealingDriver;
class GEOMImpl_IHealing;
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOMImpl_HealingDriver);
@ -144,12 +146,18 @@ public:
// 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 const Standard_GUID& GetID();
Standard_EXPORT ~GEOMImpl_HealingDriver() {};
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
//

View File

@ -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); }

View File

@ -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 <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); }
@ -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;
};

View File

@ -691,14 +691,12 @@ 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)
{
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<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

View File

@ -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<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..

View File

@ -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 <Standard_Stream.hxx>
@ -492,7 +491,8 @@ Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet2D
*/
//=============================================================================
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);
@ -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);

View File

@ -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<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,

View File

@ -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 :
@ -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;

View File

@ -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,104 +936,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
if (FinalReverse)
ResEdge.Reverse();
aShape = ResEdge;
return 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;
}
//=======================================================================
//function : GEOMImpl_ShapeDriver_Type_

View File

@ -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 <Standard_CString.hxx>
#endif
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
class TColStd_SequenceOfExtendedString;
@ -142,12 +144,16 @@ public:
// 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 ~GEOMImpl_ShapeDriver() {};
Standard_EXPORT static TopoDS_Edge MakeEdgeFromWire(const TopoDS_Shape& aWire,
const Standard_Real LinTol,
const Standard_Real AngTol);
// Type management
//
@ -155,7 +161,6 @@ 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)); }
};
#endif

View File

@ -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

View File

@ -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 <Standard_Stream.hxx>
@ -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<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

View File

@ -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 );

View File

@ -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 <Standard_Stream.hxx>
@ -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();

View File

@ -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);

View File

@ -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<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;
}

View File

@ -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,

View File

@ -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)

View File

@ -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 <var>theObject</var>
@ -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

View File

@ -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())

View File

@ -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 <TColStd_IndexedMapOfInteger.hxx>
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

View File

@ -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)

View File

@ -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,6 +91,7 @@ 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;
case GEOMOp::OpFuseEdges: aDlg = new RepairGUI_FuseEdgesDlg (getGeometryGUI(), parent); break;
default:
app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
break;

View File

@ -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 <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());
}

View File

@ -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 <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