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)
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)
\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.
-
-\n 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]
-
-<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).
-
-\image html repair8.png
+This operation splits an edge in two new edges.
+This operation is available in <b>OCC Viewer</b> only.
+
+The \b Result will be a \b GEOM_Object.
+
+\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.
+
+ 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 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".
*/
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.
* 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.
planeworkingorigin.png
point2.png
pointonedge.png
+ pointonedgebypoint.png
pointonface.png
point_line_intersection.png
polyline.png
<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>
<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!
RemoveInternalFaces(&HI, anOriginalShape, aShape);
break;
case DIVIDE_EDGE:
+ case DIVIDE_EDGE_BY_POINT:
AddPointOnEdge(&HI, anOriginalShape, aShape);
break;
case CHANGE_ORIENTATION:
//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)
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() );
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
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,
#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
#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
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
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);
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
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
## 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
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
#include <GEOMImpl_Types.hxx>
-#include <TopAbs.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <Geom_Curve.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopAbs.hxx>
#include <TopExp.hxx>
-#include <TopoDS_Edge.hxx>
-#include <BRep_Tool.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-#include <TColStd_IndexedMapOfInteger.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()
: 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" ) );
/***************************************************************/
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 );
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() );
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
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();
}
//=================================================================================
void RepairGUI_DivideEdgeDlg::displayPreview()
{
+ myProjectionOK = false;
erasePreview();
if ( myObject->_is_nil() )
return;
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);
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 );
- }
+ }
}
//=================================================================================
myEditCurrentArgument->setText( "" );
myObject = GEOM::GEOM_Object::_nil();
+ myPoint.nullify();
myIndex = -1;
+ myProjectionOK = false;
- initSelection();
+ ConstructorsClicked(getConstructorId());
return true;
}
{
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;
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;
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();
}
}
}
//=================================================================================
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();
}
myEditCurrentArgument = GroupPoints->LineEdit1;
GEOMBase_Skeleton::LineEditReturnPressed();
}
+ if ( sender() == GroupPoints->LineEdit2 &&
+ !GroupPoints->LineEdit2->isHidden() ) {
+ myEditCurrentArgument = GroupPoints->LineEdit2;
+ GEOMBase_Skeleton::LineEditReturnPressed();
+ }
}
myIndex = -1;
//myGeomGUI->SetState( 0 );
- initSelection();
+ ConstructorsClicked(getConstructorId());
}
//=================================================================================
//=================================================================================
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;
}
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 << "";
//=================================================================================
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() );
}
#include <GEOMBase_Skeleton.h>
-class DlgRef_1SelExt;
+class DlgRef_2SelExt;
class SalomeApp_DoubleSpinBox;
class QButtonGroup;
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid( QString& );
virtual bool execute( ObjectList& );
-
+ virtual void addSubshapesToStudy();
+
private:
void Init();
void enterEvent( QEvent* );
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();
void LineEditReturnPressed();
void SelectionIntoArgument();
void SetEditCurrentArgument();
+ void ConstructorsClicked( int );
};
#endif // REPAIRGUI_DIVIDEEDGEDLG_H
// Created: 30.04.04 16:44:47
// Author: Galina KULIKOVA
//
+#include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.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 <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 <ShHealOper_SplitCurve3d.hxx>
#include <ShapeAnalysis_Edge.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_Curve.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 <Geom_Curve.hxx>
#include <TopoDS_Face.hxx>
-#include <Geom2d_Curve.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-#include <TopExp.hxx>
-#include <Precision.hxx>
+
//#include <.hxx>
//#include <.hxx>
//=======================================================================
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()) {
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);
myErrorStatus = ShHealOper_InvalidParameters;
return Standard_False;
}
-
+
//split 3d curve and pcurve for each face reffering to edge.
Standard_Boolean isDone = Standard_True;
if(hasPCurves) {
#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.
//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,
//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 ----------