0022757: [EDF] Vertex on Edge

This commit is contained in:
eap 2014-10-21 20:06:51 +04:00 committed by vsr
parent d632c33a6e
commit 0c260c9c89
21 changed files with 564 additions and 121 deletions

View File

@ -6,6 +6,8 @@ import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
# Variant 1: using DivideEdge()
# create vertices
p1 = geompy.MakeVertex(0,0,50)
p2 = geompy.MakeVertex(60,0,50)
@ -27,4 +29,14 @@ edge_points = geompy.SubShapeAllSortedCentres(divide, geompy.ShapeType["VERTEX"]
for point in edge_points:
geompy.addToStudyInFather(divide, point, "Edge's point after divide")
# Variant 2: using DivideEdgeByPoint()
box = geompy.MakeBox(0,0,0, 10,10,10, theName="box")
p = geompy.MakeVertex( 3, -2, 1, theName="point to project" )
edge = geompy.GetEdgeNearPoint( box, p, theName="edge to split")
div = geompy.DivideEdgeByPoint( box, edge, p, theName="box (edge divided)")
salome.sg.updateObjBrowser(1)

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
doc/salome/gui/GEOM/images/repair8.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -5,44 +5,66 @@
\n To <b>Add Point on Edge</b> in the <b>Main Menu</b> select
<b>Repair - > Add Point on Edge</b>.
\n This operation splits an edge in two new edges in accordance with the
specified mode (by length or by parameter) and a value specifying the
position of the point on edge (for example val =0.5; mode =
by length). This operation is available in <b>OCC Viewer</b> only.
This operation splits an edge in two new edges.
This operation is available in <b>OCC Viewer</b> only.
\n The \b Result will be a \b GEOM_Object.
The \b Result will be a \b GEOM_Object.
\n <b>TUI Command:</b> <em>geompy.DivideEdge(Shape, EdgeID, Value,
IsByParameter)</em>
- \em Shape is a shape which contains an edge to be divided
- \em EdgeID is the ID of the edge to be divided, if it is = -1,
then \em Shape should be an edge itself
- \em Value is a value of parameter on edge or length parameter,
depending on \em IsByParameter.
- \em IsByParameter is a boolean flag, specifying operation mode:
- \c True: \em Value is treated as a curve parameter [0..1]
- \c False: \em Value is treated as a length parameter [0..1]
\n Location of a new vertex on a selected edge can be defined two ways:
<ol>
<li> We can specify a position (ranging from 0.0 to 1.0) of the
vertex on the selected edge either by length or by parameter.
<p>
<b>TUI Command:</b> <em>geompy.DivideEdge(Shape, EdgeID, Value,
IsByParameter)</em>
<ul>
<li> \em Shape is a shape which contains an edge to be divided</li>
<li>\em EdgeID is the ID of the edge to be divided, if it is = -1,
then \em Shape should be an edge itself.</li>
<li> \em Value is a value of parameter on edge or length parameter,
depending on \em IsByParameter. </li>
<li> \em IsByParameter is a boolean flag, specifying operation mode:
- \c True: \em Value is treated as a curve parameter [0..1]
- \c False: \em Value is treated as a length parameter [0..1] </li>
</ul>
\b Arguments: Name + 1 Edge + 1 Value setting the position of
the point according to one of the selected modes.
<b>Arguments:</b> Name + 1 Edge + 1 Value setting the position of
the point according to one of the selected modes.
The difference between "by parameter" and "by length" modes becomes
apparent on the edges with irregular parametrization (for example,
b-splines which usually have irregular density by the length).
For example, value 0.5 "by length" on such edge will produce the point
in the middle of this edge (equidistant from both its ends); the same
0.5 value "by parameter" will result in the point situated closer to
one of the ends (depending on the actual parametrization).
The difference between "by parameter" and "by length" modes becomes
apparent on the edges with irregular parametrization (for example,
b-splines which usually have irregular density by the length).
For example, value 0.5 "by length" on such edge will produce the point
in the middle of this edge (equidistant from both its ends); the same
0.5 value "by parameter" will result in the point situated closer to
one of the ends (depending on the actual parametrization).
\image html repair8.png
\n\n
</li>
<li>We can select a point that will be projected to the selected
edge to find the location of the new vertex.
<p>
<b>TUI Command:</b> <em>geompy.DivideEdgeByPoint(Shape, Edge, Point)</em>
<ul>
<li> \em Shape is a shape which contains an edge to be divided</li>
<li>\em Edge is an edge to be divided (or it's ID, if it is = -1,
then \em Shape should be an edge itself).</li>
<li> \em Point is a point to project to \a Edge. </li>
</ul>
\b Arguments: Name + 1 Edge + 1 Point.
\image html repair8.png
\image html divedgebypoint.png
</li>
</ol>
\n <b>Example:</b>
\image html image167.png "The initial edge"
\image html image168.png "The edge split in two segments"
\image html image168.png "The edge split in two segments"
Our <b>TUI Scripts</b> provide you with useful examples of the use of
Our <b>TUI Scripts</b> provide you with useful examples of the use of
\ref tui_add_point_on_edge "Repairing Operations".
*/

View File

@ -3722,7 +3722,7 @@ module GEOM
GEOM_Object RemoveInternalFaces (in ListOfGO theSolids);
/*!
* \brief Addition of a point to a given edge object.
* \brief Addition of a point to a given edge of \a theObject.
* \param theObject Shape to be processed.
* \param theEdgeIndex Index of edge to be divided within theObject's shape,
* if -1, then theObject itself is the edge.
@ -3730,11 +3730,24 @@ module GEOM
* depending on \a isByParameter.
* \param isByParameter If TRUE : \a theValue is treated as a curve parameter [0..1],
* if FALSE : \a theValue is treated as a length parameter [0..1]
* \return New GEOM_Object, containing processed shape.
* \return New GEOM_Object, containing the processed shape.
*/
GEOM_Object DivideEdge (in GEOM_Object theObject, in short theEdgeIndex,
in double theValue, in boolean isByParameter);
/*!
* \brief Addition of a point to a given edge of \a theObject by projecting
* another point to the given edge.
* \param theObject Shape to be processed.
* \param theEdgeIndex Index of edge to be divided within theObject's shape,
* if -1, then theObject itself is the edge.
* \param thePoint Point to project to theEdgeIndex-th edge.
* \return New GEOM_Object, containing the processed shape.
*/
GEOM_Object DivideEdgeByPoint (in GEOM_Object theObject,
in short theEdgeIndex,
in GEOM_Object thePoint);
/*!
* \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.

View File

@ -145,6 +145,7 @@ SET( _res_files
planeworkingorigin.png
point2.png
pointonedge.png
pointonedgebypoint.png
pointonface.png
point_line_intersection.png
polyline.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

View File

@ -291,6 +291,10 @@
<source>ICON_DLG_DIVIDE_EDGE</source>
<translation>pointonedge.png</translation>
</message>
<message>
<source>ICON_DLG_DIVIDE_EDGE_BY_PNT</source>
<translation>pointonedgebypoint.png</translation>
</message>
<message>
<source>ICON_DLG_ELLIPSE_PV</source>
<translation>ellipsepointvector.png</translation>

View File

@ -38,6 +38,14 @@ Do you still want to delete these objects?</translation>
<source>DEVIDE_EDGE_NEW_OBJECT_NAME</source>
<translation>NewObject</translation>
</message>
<message>
<source>DEVIDE_EDGE_BAD_PROJ_MSG</source>
<translation>Projection outside the edge</translation>
</message>
<message>
<source>DEVIDE_EDGE_BY_PROJ_POINT</source>
<translation>Point to project</translation>
</message>
<message>
<source>ERROR_SHAPE_TYPE</source>
<translation>Object of incorrect type selected!

View File

@ -145,6 +145,7 @@ Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
RemoveInternalFaces(&HI, anOriginalShape, aShape);
break;
case DIVIDE_EDGE:
case DIVIDE_EDGE_BY_POINT:
AddPointOnEdge(&HI, anOriginalShape, aShape);
break;
case CHANGE_ORIENTATION:
@ -533,26 +534,44 @@ GEOMImpl_HealingDriver::RemoveInternalFaces (GEOMImpl_IHealing* theHI,
//function : AddPointOnEdge
//purpose :
//=======================================================================
Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
const TopoDS_Shape& theOriginalShape,
TopoDS_Shape& theOutShape) const
TopoDS_Shape& theOutShape) const
{
Standard_Boolean isByParameter = theHI->GetIsByParameter();
Standard_Integer anIndex = theHI->GetIndex();
Standard_Real aValue = theHI->GetDevideEdgeValue();
Standard_Integer anIndex = theHI->GetIndex();
Standard_Real aValue = theHI->GetDevideEdgeValue();
TopoDS_Shape pointToProject;
{
Handle(TColStd_HSequenceOfTransient) funs = theHI->GetShapes();
if ( !funs.IsNull() && funs->Length() > 0 ) {
Handle(GEOM_Function) fun = Handle(GEOM_Function)::DownCast( funs->Value(1) );
if ( !fun.IsNull() )
pointToProject = fun->GetValue();
}
}
ShHealOper_EdgeDivide aHealer (theOriginalShape);
Standard_Boolean aResult = Standard_False;
if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
if (theOriginalShape.ShapeType() == TopAbs_EDGE)
aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
if (anIndex == -1) { // apply algorithm for the whole shape which is EDGE
if (theOriginalShape.ShapeType() == TopAbs_EDGE) {
if ( pointToProject.IsNull() )
aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
else
aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), pointToProject);
}
} else {
TopTools_IndexedMapOfShape aShapes;
TopExp::MapShapes(theOriginalShape, aShapes);
TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
if (aEdgeShape.ShapeType() == TopAbs_EDGE)
aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
if (aEdgeShape.ShapeType() == TopAbs_EDGE) {
if ( pointToProject.IsNull() )
aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
else
aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), pointToProject);
}
}
if (aResult)
@ -946,6 +965,14 @@ GetCreationInformation(std::string& theOperationName,
AddParam( theParams, "By parameter", aCI.GetIsByParameter() );
AddParam( theParams, "Value", aCI.GetDevideEdgeValue() );
break;
case DIVIDE_EDGE_BY_POINT:
theOperationName = "POINT_ON_EDGE";
if ( aCI.GetIndex() > 0 )
AddParam( theParams, "Edge", "#" ) << aCI.GetIndex() << " of " << aCI.GetOriginal();
else
AddParam( theParams, "Edge", aCI.GetOriginal() );
AddParam( theParams, "Point", aCI.GetShapes() );
break;
case CHANGE_ORIENTATION:
theOperationName = "CHANGE_ORIENTATION";
AddParam( theParams, "Selected shape", aCI.GetOriginal() );

View File

@ -764,6 +764,70 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object)
return aNewObject;
}
//=============================================================================
/*!
* DivideEdgeByPoint
*/
//=============================================================================
Handle(GEOM_Object)
GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject,
int theIndex,
Handle(GEOM_Object) thePoint)
{
// set error code, check parameters
SetErrorCode(KO);
if (theObject.IsNull() || thePoint.IsNull())
return NULL;
Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
Handle(GEOM_Function) aPointFunc = thePoint->GetLastFunction();
if (aLastFunction.IsNull() || aPointFunc.IsNull())
return NULL; //There is no function which creates an object to be processed
// Add a new object
Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
//Add the function
aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT);
if (aFunction.IsNull()) return NULL;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
// prepare "data container" class IHealing
GEOMImpl_IHealing HI(aFunction);
HI.SetIndex( theIndex );
HI.SetOriginal( aLastFunction );
Handle(TColStd_HSequenceOfTransient) funSeq = new TColStd_HSequenceOfTransient;
funSeq->Append( aPointFunc );
HI.SetShapes( funSeq );
//Compute the translation
try {
OCC_CATCH_SIGNALS;
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(aFunction)
<< aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
<< ", " << theIndex << ", " << thePoint << ")";
SetErrorCode(OK);
return aNewObject;
}
//=============================================================================
/*!
* FuseCollinearEdgesWithinWire

View File

@ -77,9 +77,13 @@ class GEOMImpl_IHealingOperations : public GEOM_IOperations {
Standard_EXPORT Handle(GEOM_Object) RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids);
Standard_EXPORT Handle(GEOM_Object) DivideEdge( Handle(GEOM_Object) theObject,
int theIndex,
double theValue,
bool isByParameter );
int theIndex,
double theValue,
bool isByParameter );
Standard_EXPORT Handle(GEOM_Object) DivideEdgeByPoint( Handle(GEOM_Object) theObject,
int theIndex,
Handle(GEOM_Object) thePoint );
Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire
(Handle(GEOM_Object) theWire,

View File

@ -205,10 +205,10 @@
#define DISK_THREE_PNT 2
#define DISK_R 3
#define CYLINDER_R_H 1
#define CYLINDER_PNT_VEC_R_H 2
#define CYLINDER_R_H_A 3
#define CYLINDER_PNT_VEC_R_H_A 4
#define CYLINDER_R_H 1
#define CYLINDER_PNT_VEC_R_H 2
#define CYLINDER_R_H_A 3
#define CYLINDER_PNT_VEC_R_H_A 4
#define CONE_R1_R2_H 1
#define CONE_PNT_VEC_R1_R2_H 2
@ -321,6 +321,7 @@
#define FUSE_COLLINEAR_EDGES 10
#define SEWING_NON_MANIFOLD 11
#define REMOVE_INTERNAL_FACES 12
#define DIVIDE_EDGE_BY_POINT 13
#define BASIC_FILLING 1

View File

@ -431,6 +431,40 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::DivideEdge (GEOM::GEOM_Object_p
return GetObject(aNewObject);
}
//=============================================================================
/*!
* DivideEdgeByPoint
*/
//=============================================================================
GEOM::GEOM_Object_ptr
GEOM_IHealingOperations_i::DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject,
CORBA::Short theIndex,
GEOM::GEOM_Object_ptr thePoint)
{
GEOM::GEOM_Object_var aGEOMObject;
// Set a not done flag
GetOperations()->SetNotDone();
// Get the object itself
Handle(GEOM_Object) anObject = GetObjectImpl(theObject);
if (anObject.IsNull())
return aGEOMObject._retn();
// Get the point
Handle(GEOM_Object) aPoint = GetObjectImpl(thePoint);
if (aPoint.IsNull())
return aGEOMObject._retn();
// Perform
Handle(GEOM_Object) aNewObject =
GetOperations()->DivideEdgeByPoint( anObject, theIndex, aPoint );
if (!GetOperations()->IsDone() || aNewObject.IsNull())
return aGEOMObject._retn();
return GetObject(aNewObject);
}
//=============================================================================
/*!
* FuseCollinearEdgesWithinWire

View File

@ -78,9 +78,13 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i :
GEOM::GEOM_Object_ptr RemoveInternalFaces (const GEOM::ListOfGO& theSolids);
GEOM::GEOM_Object_ptr DivideEdge (GEOM::GEOM_Object_ptr theObject,
CORBA::Short theIndex,
CORBA::Double theValue,
CORBA::Boolean isByParameter);
CORBA::Short theIndex,
CORBA::Double theValue,
CORBA::Boolean isByParameter);
GEOM::GEOM_Object_ptr DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject,
CORBA::Short theIndex,
GEOM::GEOM_Object_ptr thePoint);
GEOM::GEOM_Object_ptr FuseCollinearEdgesWithinWire (GEOM::GEOM_Object_ptr theWire,
const GEOM::ListOfGO& theVertices);

View File

@ -323,6 +323,12 @@ def TestDivideEdge (geompy):
Id_Box = geompy.addToStudy(Box, "Box")
Id_Divide = geompy.addToStudy(Divide, "Box with Divided Edge")
# using geompy.DivideEdgeByPoint()
p = geompy.MakeVertex( 30, -5, 10, theName="Point to project" )
edge = geompy.GetEdgeNearPoint( Box, p, theName="Edge to split")
div = geompy.DivideEdgeByPoint( Box, edge, p, theName="Box (edge divided)")
assert geompy.NumberOfEdges( Box ) == geompy.NumberOfEdges( div ) - 1
def TestFuseEdges (geompy):
# create vertices

View File

@ -6609,6 +6609,45 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
self._autoPublish(anObj, theName, "divideEdge")
return anObj
## Addition of a point to a given edge of \a theObject by projecting
# another point to the given edge.
# @param theObject Shape to be processed.
# @param theEdgeIndex Index of edge to be divided within theObject's shape,
# if -1, then theObject itself is the edge.
# @param thePoint Point to project to theEdgeIndex-th edge.
# @param theName Object name; when specified, this parameter is used
# for result publication in the study. Otherwise, if automatic
# publication is switched on, default value is used for result name.
#
# @return New GEOM.GEOM_Object, containing processed shape.
#
# @ref tui_add_point_on_edge "Example"
@ManageTransactions("HealOp")
def DivideEdgeByPoint(self, theObject, theEdgeIndex, thePoint, theName=None):
"""
Addition of a point to a given edge of \a theObject by projecting
another point to the given edge.
Parameters:
theObject Shape to be processed.
theEdgeIndex The edge or its index to be divided within theObject's shape,
if -1, then theObject itself is the edge.
thePoint Point to project to theEdgeIndex-th edge.
theName Object name; when specified, this parameter is used
for result publication in the study. Otherwise, if automatic
publication is switched on, default value is used for result name.
Returns:
New GEOM.GEOM_Object, containing processed shape.
"""
# Example: see GEOM_TestHealing.py
if isinstance( theEdgeIndex, GEOM._objref_GEOM_Object ):
theEdgeIndex = self.GetSubShapeID( theObject, theEdgeIndex )
anObj = self.HealOp.DivideEdgeByPoint(theObject, theEdgeIndex, thePoint)
RaiseIfFailed("DivideEdgeByPoint", self.HealOp)
self._autoPublish(anObj, theName, "divideEdge")
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
@ -9707,7 +9746,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
## Perform an Archimde operation on the given shape with given parameters.
# The object presenting the resulting face is returned.
# @param theShape Shape to be put in water.
# @param theWeight Weight og the shape.
# @param theWeight Weight of the shape.
# @param theWaterDensity Density of the water.
# @param theMeshDeflection Deflection of the mesh, using to compute the section.
# @param theName Object name; when specified, this parameter is used
@ -9726,7 +9765,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
Parameters:
theShape Shape to be put in water.
theWeight Weight og the shape.
theWeight Weight of the shape.
theWaterDensity Density of the water.
theMeshDeflection Deflection of the mesh, using to compute the section.
theName Object name; when specified, this parameter is used

View File

@ -38,16 +38,23 @@
#include <GEOMImpl_Types.hxx>
#include <TopAbs.hxx>
#include <Geom_Curve.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS.hxx>
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <BRep_Tool.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <Geom_Curve.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <gp_Pnt.hxx>
enum { BY_PARAM, BY_POINT_PROJ };
//=================================================================================
// class : RepairGUI_DivideEdgeDlg()
@ -61,6 +68,7 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
: GEOMBase_Skeleton( theGeometryGUI, parent, modal )
{
QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_DIVIDE_EDGE" ) ) );
QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_DIVIDE_EDGE_BY_PNT" ) ) );
QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
setWindowTitle( tr( "GEOM_DIVIDE_EDGE_TITLE" ) );
@ -68,16 +76,18 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
/***************************************************************/
mainFrame()->GroupConstructors->setTitle(tr("GEOM_DIVIDE_EDGE_TITLE"));
mainFrame()->RadioButton1->setIcon( image0 );
mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton2->close();
mainFrame()->RadioButton2->setIcon( image2 );
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close();
GroupPoints = new DlgRef_1SelExt( centralWidget() );
GroupPoints = new DlgRef_2SelExt( centralWidget() );
GroupPoints->GroupBox1->setTitle( tr( "GEOM_ADD_POINT" ) );
GroupPoints->TextLabel1->setText( tr( "GEOM_EDGE" ) );
GroupPoints->PushButton1->setIcon( image1 );
GroupPoints->LineEdit1->setReadOnly( true );
GroupPoints->TextLabel2->setText( tr( "DEVIDE_EDGE_BY_PROJ_POINT" ) );
GroupPoints->PushButton2->setIcon( image1 );
GroupPoints->LineEdit2->setReadOnly( true );
QRadioButton* rb1 = new QRadioButton( tr( "GEOM_BY_PARAMETER" ), GroupPoints->Box );
QRadioButton* rb2 = new QRadioButton( tr( "GEOM_BY_LENGTH" ), GroupPoints->Box );
@ -90,13 +100,13 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
myValEdt = new SalomeApp_DoubleSpinBox( GroupPoints->Box );
initSpinBox( myValEdt, 0., 1., 0.1, "parametric_precision" );
myValEdt->setValue( 0.5 );
QLabel* aLbl1 = new QLabel( tr( "GEOM_VALUE" ), GroupPoints->Box );
myValLbl = new QLabel( tr( "GEOM_VALUE" ), GroupPoints->Box );
QGridLayout* l = new QGridLayout( GroupPoints->Box );
l->setMargin( 0 ); l->setSpacing( 6 );
l->addWidget( rb1, 0, 0, 1, 2 );
l->addWidget( rb2, 1, 0, 1, 2 );
l->addWidget( aLbl1, 2, 0 );
l->addWidget( myValLbl, 2, 0 );
l->addWidget( myValEdt, 2, 1 );
QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
@ -110,6 +120,29 @@ RepairGUI_DivideEdgeDlg::RepairGUI_DivideEdgeDlg( GeometryGUI* theGeometryGUI, Q
Init();
}
//=======================================================================
//function : ConstructorsClicked
//purpose : hide/show widgets depending on a selected constructor
//=======================================================================
void RepairGUI_DivideEdgeDlg::ConstructorsClicked( int constructorId )
{
myIsParameterGr->button( 0 )->setShown( constructorId == BY_PARAM );
myIsParameterGr->button( 1 )->setShown( constructorId == BY_PARAM );
myValEdt ->setShown( constructorId == BY_PARAM );
myValLbl ->setShown( constructorId == BY_PARAM );
GroupPoints->TextLabel2 ->setShown( constructorId == BY_POINT_PROJ );
GroupPoints->PushButton2 ->setShown( constructorId == BY_POINT_PROJ );
GroupPoints->LineEdit2 ->setShown( constructorId == BY_POINT_PROJ );
initSelection();
if ( constructorId == BY_PARAM &&
!GroupPoints->PushButton1->isDown() )
GroupPoints->PushButton1->click();
displayPreview();
}
//=================================================================================
// function : ~RepairGUI_DivideEdgeDlg()
// purpose : Destroys the object and frees any allocated resources
@ -128,25 +161,31 @@ void RepairGUI_DivideEdgeDlg::Init()
myEditCurrentArgument = GroupPoints->LineEdit1;
myObject = GEOM::GEOM_Object::_nil();
myIndex = -1;
myPoint.nullify();
myIndex = -1;
myProjectionOK = false;
//myGeomGUI->SetState( 0 );
initSelection();
/* signals and slots connections */
connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
connect( myValEdt, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox() ) );
connect( GroupPoints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( GroupPoints->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
connect( GroupPoints->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( GroupPoints->LineEdit2, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(),
SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
initName( tr( "DEVIDE_EDGE_NEW_OBJECT_NAME" ) );
resize(100,100);
ConstructorsClicked( BY_PARAM );
SelectionIntoArgument();
}
@ -165,6 +204,7 @@ void RepairGUI_DivideEdgeDlg::ValueChangedInSpinBox()
//=================================================================================
void RepairGUI_DivideEdgeDlg::displayPreview()
{
myProjectionOK = false;
erasePreview();
if ( myObject->_is_nil() )
return;
@ -173,7 +213,7 @@ void RepairGUI_DivideEdgeDlg::displayPreview()
gp_Pnt aPnt;
GEOMBase::GetShape( myObject, aShape, TopAbs_SHAPE );
if ( myIndex != -1) {
if ( myIndex != -1 ) {
TopTools_IndexedMapOfShape aShapes;
TopExp::MapShapes(aShape, aShapes);
aShape = aShapes.FindKey(myIndex);
@ -182,15 +222,55 @@ void RepairGUI_DivideEdgeDlg::displayPreview()
if (aShape.ShapeType() == TopAbs_EDGE) {
Standard_Real aFP, aLP, aP;
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
aP = aFP + (aLP - aFP) * myValEdt->value();
aPnt = aCurve->Value(aP);
BRepBuilderAPI_MakeVertex mkVertex (aPnt);
aShape = mkVertex.Shape();
if ( aCurve.IsNull() ) return;
if ( getConstructorId() == BY_PARAM )
{
aP = aFP + (aLP - aFP) * myValEdt->value();
aPnt = aCurve->Value(aP);
BRepBuilderAPI_MakeVertex mkVertex (aPnt);
aShape = mkVertex.Shape();
}
else if ( getConstructorId() == BY_POINT_PROJ && myPoint )
{
TopoDS_Shape aPoints;
GEOMBase::GetShape( myPoint.get(), aPoints, TopAbs_SHAPE );
BRep_Builder builder;
TopoDS_Compound compoundOfVV;
builder.MakeCompound(compoundOfVV);
aShape = compoundOfVV;
GeomAPI_ProjectPointOnCurve aProjector;
aProjector.Init( aCurve, aFP, aLP );
TopTools_MapOfShape vMap;
TopExp_Explorer vertex( aPoints, TopAbs_VERTEX );
for ( ; vertex.More(); vertex.Next() )
{
if ( !vMap.Add( vertex.Current() )) continue;
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vertex.Current() ));
aProjector.Perform( p );
if ( aProjector.NbPoints() > 0 )
{
double u = aProjector.LowerDistanceParameter();
if ( Min( u - aFP, aLP - u ) > Precision::Confusion() )
{
builder.Add( compoundOfVV, BRepBuilderAPI_MakeVertex( aProjector.NearestPoint()));
myProjectionOK = true;
}
}
}
}
else
{
return;
}
// Build prs
SALOME_Prs* aPrs = getDisplayer()->BuildPrs( aShape );
if ( aPrs != 0 && !aPrs->IsNull() )
GEOMBase_Helper::displayPreview( aPrs, false, true );
}
}
}
//=================================================================================
@ -218,9 +298,11 @@ bool RepairGUI_DivideEdgeDlg::ClickOnApply()
myEditCurrentArgument->setText( "" );
myObject = GEOM::GEOM_Object::_nil();
myPoint.nullify();
myIndex = -1;
myProjectionOK = false;
initSelection();
ConstructorsClicked(getConstructorId());
return true;
}
@ -235,8 +317,17 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
{
myEditCurrentArgument->setText( "" );
myObject = GEOM::GEOM_Object::_nil();
myIndex = -1;
const bool toSelectObject = ( myEditCurrentArgument == GroupPoints->LineEdit1 );
if ( toSelectObject )
{
myObject = GEOM::GEOM_Object::_nil();
myIndex = -1;
}
else //if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
{
myPoint.nullify();
myProjectionOK = false;
}
LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
SALOME_ListIO aSelList;
@ -252,7 +343,7 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
if ( GEOMBase::GetShape( aSelectedObj, aShape, TopAbs_SHAPE ) )
{
const int aType = aShape.ShapeType();
if ( aType <= TopAbs_EDGE ) // edge, wire, face, shell, solid, compound
if ( aType <= TopAbs_EDGE || !toSelectObject ) // edge, wire, face, shell, solid, compound
{
GEOM::short_array anIndexes;
@ -263,20 +354,29 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
if ( !aMap.IsEmpty() ) // sub-shape selection
{
myIndex = aMap( 1 );
myObject = aSelectedObj;
myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) );
if ( toSelectObject ) {
myIndex = aMap( 1 );
myObject = aSelectedObj;
myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) );
}
else if (( myPoint = getSelected( TopAbs_VERTEX )))
{
myEditCurrentArgument->setText( aName += QString( ":vertex_%1" ).arg( aMap( 1 )));
}
}
else if ( aType == TopAbs_EDGE ) // single shape selection
else if ( aType == TopAbs_EDGE && toSelectObject ) // single shape selection
{
myIndex = -1;
myObject = aSelectedObj;
myEditCurrentArgument->setText( GEOMBase::GetName( myObject ) );
myEditCurrentArgument->setText( aName );
}
else if ( aType == TopAbs_VERTEX && !toSelectObject ) // single shape selection
{
myPoint = aSelectedObj;
myEditCurrentArgument->setText( aName );
}
else // face, shell, solid or compound was selected, and NOT its sub-shape.
{
myIndex = -1;
myObject = GEOM::GEOM_Object::_nil();
}
}
}
@ -292,10 +392,29 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument()
//=================================================================================
void RepairGUI_DivideEdgeDlg::SetEditCurrentArgument()
{
if ( sender() == GroupPoints->PushButton1 ) {
QPushButton* send = (QPushButton*)sender();
if ( send == GroupPoints->PushButton1 ) {
GroupPoints->LineEdit1->setFocus();
myEditCurrentArgument = GroupPoints->LineEdit1;
GroupPoints->PushButton2->setDown(false);
GroupPoints->LineEdit2->setEnabled(false);
}
if ( send == GroupPoints->PushButton2 ) {
GroupPoints->LineEdit2->setFocus();
myEditCurrentArgument = GroupPoints->LineEdit2;
GroupPoints->PushButton1->setDown(false);
GroupPoints->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);
initSelection();
SelectionIntoArgument();
}
@ -310,6 +429,11 @@ void RepairGUI_DivideEdgeDlg::LineEditReturnPressed()
myEditCurrentArgument = GroupPoints->LineEdit1;
GEOMBase_Skeleton::LineEditReturnPressed();
}
if ( sender() == GroupPoints->LineEdit2 &&
!GroupPoints->LineEdit2->isHidden() ) {
myEditCurrentArgument = GroupPoints->LineEdit2;
GEOMBase_Skeleton::LineEditReturnPressed();
}
}
@ -327,7 +451,7 @@ void RepairGUI_DivideEdgeDlg::ActivateThisDialog()
myIndex = -1;
//myGeomGUI->SetState( 0 );
initSelection();
ConstructorsClicked(getConstructorId());
}
//=================================================================================
@ -356,7 +480,16 @@ GEOM::GEOM_IOperations_ptr RepairGUI_DivideEdgeDlg::createOperation()
//=================================================================================
bool RepairGUI_DivideEdgeDlg::isValid( QString& msg )
{
bool ok = myValEdt->isValid( msg, !IsPreview() );
bool ok = false;
if ( getConstructorId() == BY_PARAM )
{
ok = myValEdt->isValid( msg, !IsPreview() );
}
else if ( getConstructorId() == BY_POINT_PROJ )
{
if (( ok = myPoint ) && !( ok = myProjectionOK ))
msg = tr("DEVIDE_EDGE_BAD_PROJ_MSG");
}
return !myObject->_is_nil() && ok;
}
@ -367,11 +500,16 @@ bool RepairGUI_DivideEdgeDlg::isValid( QString& msg )
bool RepairGUI_DivideEdgeDlg::execute( ObjectList& objects )
{
GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow( getOperation() );
GEOM::GEOM_Object_var anObj = anOper->DivideEdge( myObject, myIndex, myValEdt->value(), getIsByParameter() );
GEOM::GEOM_Object_var anObj;
if ( getConstructorId() == BY_PARAM )
anObj = anOper->DivideEdge( myObject, myIndex, myValEdt->value(), getIsByParameter() );
else
anObj = anOper->DivideEdgeByPoint( myObject, myIndex, myPoint.get() );
bool aResult = !anObj->_is_nil();
if ( aResult )
{
if ( !IsPreview() )
if ( !IsPreview() && ( getConstructorId() == BY_PARAM ))
{
QStringList aParameters;
aParameters << "";
@ -400,6 +538,19 @@ bool RepairGUI_DivideEdgeDlg::getIsByParameter() const
//=================================================================================
void RepairGUI_DivideEdgeDlg::initSelection()
{
GEOM::GEOM_Object_var aNullGeomObject;
localSelection( aNullGeomObject, TopAbs_EDGE ); // load local selection on ALL objects
TopAbs_ShapeEnum type = TopAbs_EDGE;
if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
type = TopAbs_VERTEX;
globalSelection(); // close local contexts, if any
localSelection( GEOM::GEOM_Object::_nil(), type ); // load local selection on ALL objects
}
//=================================================================================
// function : addSubshapeToStudy
// purpose : virtual method to add new SubObjects if local selection
//=================================================================================
void RepairGUI_DivideEdgeDlg::addSubshapesToStudy()
{
GEOMBase::PublishSubObject( myPoint.get() );
}

View File

@ -29,7 +29,7 @@
#include <GEOMBase_Skeleton.h>
class DlgRef_1SelExt;
class DlgRef_2SelExt;
class SalomeApp_DoubleSpinBox;
class QButtonGroup;
@ -50,7 +50,8 @@ protected:
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid( QString& );
virtual bool execute( ObjectList& );
virtual void addSubshapesToStudy();
private:
void Init();
void enterEvent( QEvent* );
@ -58,13 +59,16 @@ private:
bool getIsByParameter() const;
int myIndex;
private:
GEOM::GEOM_Object_var myObject;
DlgRef_1SelExt* GroupPoints;
GEOM::GeomObjPtr myPoint;
bool myProjectionOK;
DlgRef_2SelExt* GroupPoints;
QButtonGroup* myIsParameterGr;
SalomeApp_DoubleSpinBox* myValEdt;
QLabel* myValLbl;
protected slots:
void ClickOnOk();
@ -76,6 +80,7 @@ protected slots:
void LineEditReturnPressed();
void SelectionIntoArgument();
void SetEditCurrentArgument();
void ConstructorsClicked( int );
};
#endif // REPAIRGUI_DIVIDEEDGEDLG_H

View File

@ -24,24 +24,28 @@
// Created: 30.04.04 16:44:47
// Author: Galina KULIKOVA
//
#include <ShHealOper_EdgeDivide.hxx>
#include <ShapeUpgrade_WireDivide.hxx>
#include <ShHealOper_SplitCurve3d.hxx>
#include <ShHealOper_SplitCurve2d.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <BRep_Tool.hxx>
#include <ShapeFix_Edge.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <TopoDS.hxx>
#include <Geom_Curve.hxx>
#include <TopoDS_Face.hxx>
#include <Geom2d_Curve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <TopExp.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Curve.hxx>
#include <Precision.hxx>
#include <ShHealOper_EdgeDivide.hxx>
#include <ShHealOper_SplitCurve2d.hxx>
#include <ShHealOper_SplitCurve3d.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeFix_Edge.hxx>
#include <ShapeUpgrade_WireDivide.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
//#include <.hxx>
//#include <.hxx>
//=======================================================================
@ -113,10 +117,51 @@ Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge,
return myDone;
}
//=======================================================================
//function : build
//function : Perform
//purpose :
//=======================================================================
Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge,
const TopoDS_Shape& thePoints)
{
myDone = Standard_False;
myErrorStatus = ShHealOper_NotError;
if(theEdge.ShapeType() != TopAbs_EDGE) {
myErrorStatus = ShHealOper_InvalidParameters;
return myDone;
}
myDivideParamMode = true;
myEdge = TopoDS::Edge(theEdge);
Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
double aFirst,aLast;
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge,aFirst,aLast);
if ( aCurve.IsNull() ) return false;
GeomAPI_ProjectPointOnCurve aProjector;
aProjector.Init( aCurve, aFirst, aLast );
TopTools_MapOfShape vMap;
TopExp_Explorer vertex( thePoints, TopAbs_VERTEX );
for ( ; vertex.More(); vertex.Next() )
{
if ( !vMap.Add( vertex.Current() )) continue;
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vertex.Current() ));
aProjector.Perform( p );
if ( aProjector.NbPoints() > 0 )
{
double u = double( aProjector.LowerDistanceParameter() );
double param = ( u - aFirst ) / ( aLast - aFirst );
aSeqValues->Append( param );
}
}
myDone = build(aSeqValues);
return myDone;
}
//=======================================================================
//function : build
//purpose :
//=======================================================================
Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfReal)& theValues)
{
if(myEdge.IsNull() || !theValues->Length()) {
@ -124,16 +169,16 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
return Standard_False;
}
Standard_Boolean has3d = Standard_False,
has2d = Standard_False,
hasPCurves = Standard_False;
Standard_Boolean has3d = Standard_False,
has2d = Standard_False,
hasPCurves = Standard_False;
//computation of the split values in dependance from specified mode and values.
if(!computeValues(theValues, has3d,has2d,hasPCurves)) {
myErrorStatus = ShHealOper_InvalidParameters;
return Standard_False;
}
//setting split values in the splitting curve tools.
Handle(ShapeUpgrade_WireDivide) aSplitTool = new ShapeUpgrade_WireDivide;
aSplitTool->Load(myEdge);
@ -152,7 +197,7 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe
myErrorStatus = ShHealOper_InvalidParameters;
return Standard_False;
}
//split 3d curve and pcurve for each face reffering to edge.
Standard_Boolean isDone = Standard_True;
if(hasPCurves) {

View File

@ -27,12 +27,11 @@
#ifndef ShHealOper_EdgeDivide_HeaderFile
#define ShHealOper_EdgeDivide_HeaderFile
#include <ShHealOper_Tool.hxx>
#include <TColStd_HSequenceOfReal.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <ShHealOper_Tool.hxx>
#include <TColStd_SequenceOfReal.hxx>
/// Class ShHealOper_EdgeDivide
//Intended for spitting edge in accordance to the specified mode and value.
@ -59,7 +58,7 @@ class ShHealOper_EdgeDivide : public ShHealOper_Tool
//specified mode and value.
//If theDivideParamMode is equal to true edge will be splitted by parameter.
//Else edge will be spliited by length (default true).
//theValue is koefficient for splitting from 0 to 1.
//theValue is coefficient for splitting from 0 to 1.
Standard_EXPORT Standard_Boolean Perform(const TopoDS_Shape& theEdge,
const TColStd_SequenceOfReal& theValues,
@ -67,7 +66,11 @@ class ShHealOper_EdgeDivide : public ShHealOper_Tool
//Performs spitting of the specified edge in the accoradnce to
//specified mode and sequence of values the same way as previous.
protected:
Standard_EXPORT Standard_Boolean Perform(const TopoDS_Shape& theEdge,
const TopoDS_Shape& thePoint);
//Performs spitting of the specified edge by projecting a point to it.
protected:
// ---------- PROTECTED METHODS ----------