\page create_edge_page Edge
-\n To create an \b Edge in the <b>Main Menu</b> select <b>New Entity- > Build - > Edge</b>
+To create an \b Edge, in the <b>Main Menu</b> select <b>New Entity >
+Build > Edge</b>
-\n You can create an \b Edge from two points (\b Point1 and \b Point2), being the first and the last vertices of the edge.
+There are two ways to create an edge. In both cases the \b Result
+will be a \b GEOM_Object (EDGE).
-The \b Result will be a \b GEOM_Object (EDGE).
+1. You can create an \b Edge by specifying two points (\b Point1 and
+\b Point2), being the first and the last vertices of the edge.
-<b>TUI Command:</b> <em>geompy.MakeEdge(Vertex1, Vertex2),</em> where
-Vertex1 and Vertex2 are correspondingly the first and the last vertex
-of the edge.
+<b>TUI Command:</b> <em>geompy.MakeEdge(Vertex1, Vertex2)</em><br>
+<b>Arguments:</b> Name + 2 vertices (Vertex1 and Vertex2 are
+correspondingly the first and the last vertex of the edge).
-<b>Arguments:</b> Name + 2 vertices.
+\image html edge1.png "Create edge by two points"
-\image html neo-obj2.png
+2. You can create an \b Edge by specifying single wire.
-\n <b>Example:</b>
+In this mode the following use cases are possible:
+- All the edges, forming the wire, lie on the single geometrical curve
+(i.e. curve(edge1) == curve(edge2)).
+- The edges forming the wire, lie on the analytical curves of the same
+type, for example, segments of line, arcs, etc. In this case, an
+algorithm checks the geometrical coincidence of these curves using
+some tolerance. If the curves are coinciding in terms of given
+tolerance, resulting edge is built as on a single curve.
+- The edges forming the wire have the same tangency in the connection
+points. In this case the curves are interpolated by the single
+b-spline curve with the sufficient precision. The resulting edge will
+be then built on this curve.
+
+The case when the edges forming the wire have different tangency in
+the connection points (sharp bend) is not processed.
+
+<b>TUI Command:</b> <em>geompy.MakeEdgeWire(Wire, LinearTolerance, AngularTolerance)</em><br>
+<b>Arguments:</b> Name + 1 wire + Linear Tolerance + Angular Tolerance
+(tolerance are used to check coincidence of the edges' underlying curves).
+
+\image html edge2.png "Create edge from wire"
+
+<b>Example:</b>
\image html edgesn.png "Edge"
Our <b>TUI Scripts</b> provide you with useful examples of creation of
\ref tui_creation_edge "Advanced Geometric Objects".
-*/
\ No newline at end of file
+*/
import salome
gg = salome.ImportComponentGUI("GEOM")
+#
+# create edge by two points
+#
+
# create vertices
p0 = geompy.MakeVertex(0. , 0. , 0. )
pxyz = geompy.MakeVertex(100., 100., 100.)
edge = geompy.MakeEdge(p0, pxyz)
# add object in the study
-id_edge = geompy.addToStudy(edge,"Edge")
+id_edge = geompy.addToStudy(edge,"Edge_1")
+
+# display an edge
+gg.createAndDisplayGO(id_edge)
+
+#
+# create edge from wire
+#
+
+# create a circle
+c = geompy.MakeCircle(None, None, 100)
+
+# create a wire
+w = geompy.MakeWire([c], 1e-07)
+
+# create an edge from wire
+edge = geompy.MakeEdgeWire(w)
+
+# add object in the study
+id_edge = geompy.addToStudy(edge,"Edge_2")
# display an edge
gg.createAndDisplayGO(id_edge)
+
\endcode
\anchor tui_creation_wire
*/
GEOM_Object MakeEdge (in GEOM_Object thePnt1, in GEOM_Object thePnt2);
+ /*!
+ * Create an edge from specified wire.
+ * \param theWire source Wire.
+ * \param theLinearTolerance linear tolerance value
+ * \param theAngularTolerance angular tolerance value
+ * \return New GEOM_Object, containing the created edge.
+ */
+ GEOM_Object MakeEdgeWire (in GEOM_Object theWire,
+ in double theLinearTolerance,
+ in double theAngularTolerance);
+
/*!
* Create a wire from the set of edges and wires.
* \param theEdgesAndWires List of edge and/or wires.
boxdxyz.png \
build_compound.png \
build_edge.png \
+build_edge_wire.png \
build_face.png \
build_shell.png \
build_solid.png \
#include <LightApp_SelectionMgr.h>
#include <GEOMImpl_Types.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
//=================================================================================
// class : BuildGUI_EdgeDlg()
BuildGUI_EdgeDlg::BuildGUI_EdgeDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
: GEOMBase_Skeleton(theGeometryGUI, parent)
{
- QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE")));
- QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
+ QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
+ QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE")));
+ QPixmap image2 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE_WIRE")));
setWindowTitle(tr("GEOM_EDGE_TITLE"));
/***************************************************************/
mainFrame()->GroupConstructors->setTitle(tr("GEOM_EDGE"));
- mainFrame()->RadioButton1->setIcon(image0);
- mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
- mainFrame()->RadioButton2->close();
- mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
+ mainFrame()->RadioButton1->setIcon(image1);
+ mainFrame()->RadioButton2->setIcon(image2);
+ mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close();
- GroupPoints = new DlgRef_2Sel(centralWidget());
+ // two points
+ GroupPoints = new DlgRef_2Sel(centralWidget());
GroupPoints->GroupBox1->setTitle(tr("GEOM_POINTS"));
GroupPoints->TextLabel1->setText(tr("GEOM_POINT_I").arg(1));
GroupPoints->TextLabel2->setText(tr("GEOM_POINT_I").arg(2));
- GroupPoints->PushButton1->setIcon(image1);
- GroupPoints->PushButton2->setIcon(image1);
-
+ GroupPoints->PushButton1->setIcon(image0);
+ GroupPoints->PushButton2->setIcon(image0);
GroupPoints->LineEdit1->setReadOnly(true);
GroupPoints->LineEdit2->setReadOnly(true);
+ // wire
+
+ GroupWire = new DlgRef_1Sel2Spin(centralWidget());
+ GroupWire->GroupBox1->setTitle(tr("GEOM_WIRE"));
+ GroupWire->TextLabel1->setText(tr("GEOM_WIRE"));
+ GroupWire->PushButton1->setIcon(image0);
+ GroupWire->LineEdit1->setReadOnly(true);
+ GroupWire->TextLabel2->setText( tr( "GEOM_LINEAR_TOLERANCE" ) );
+ GroupWire->TextLabel3->setText( tr( "GEOM_ANGULAR_TOLERANCE" ) );
+ double SpecificStep = 0.0001;
+ double prec1 = Precision::Confusion();
+ double prec2 = Precision::Angular();
+ initSpinBox(GroupWire->SpinBox_DX, prec1, MAX_NUMBER, SpecificStep, "len_tol_precision" );
+ initSpinBox(GroupWire->SpinBox_DY, prec2, MAX_NUMBER, SpecificStep, "ang_tol_precision" );
+ GroupWire->SpinBox_DX->setValue(prec1);
+ GroupWire->SpinBox_DY->setValue(prec2);
+
+ // layout
+
QVBoxLayout* layout = new QVBoxLayout(centralWidget());
layout->setMargin(0); layout->setSpacing(6);
layout->addWidget(GroupPoints);
+ layout->addWidget(GroupWire);
/***************************************************************/
setHelpFileName("create_edge_page.html");
- // Initialisation
+ // initialisation
Init();
}
void BuildGUI_EdgeDlg::Init()
{
// init variables
- GroupPoints->LineEdit1->setReadOnly(true);
- GroupPoints->LineEdit2->setReadOnly(true);
-
- GroupPoints->LineEdit1->setText("");
- GroupPoints->LineEdit2->setText("");
- myPoint1 = myPoint2 = GEOM::GEOM_Object::_nil();
- myOkPoint1 = myOkPoint2 = false;
+ myPoint1 = myPoint2 = myWire = GEOM::GEOM_Object::_nil();
+ myEditCurrentArgument = GroupPoints->LineEdit1;
+ GroupPoints->PushButton1->setDown(true);
+ globalSelection(); // close local contexts, if any
+ localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
// signals and slots connections
+ connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) );
+ connect( myGeomGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) );
+
+ connect( this, SIGNAL( constructorsClicked( int ) ), this, SLOT( ConstructorsClicked( int ) ) );
+
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(GroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+ connect(GroupWire->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
connect(GroupPoints->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
connect(GroupPoints->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+ connect(GroupWire->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+
+ connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
+ this, SLOT( SelectionIntoArgument() ) );
initName(tr("GEOM_EDGE"));
- GroupPoints->PushButton1->click();
- SelectionIntoArgument();
+ ConstructorsClicked( 0 );
}
//=================================================================================
return false;
initName();
- // activate selection and connect selection manager
- GroupPoints->PushButton1->click();
+
+ myEditCurrentArgument->setText( "" );
+ ConstructorsClicked( getConstructorId() );
+
return true;
}
+//=================================================================================
+// function : ConstructorsClicked()
+// purpose : Radio button management
+//=================================================================================
+void BuildGUI_EdgeDlg::ConstructorsClicked( int constructorId )
+{
+ switch ( constructorId ) {
+ case 0:
+ {
+ globalSelection(); // close local contexts, if any
+ localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
+
+ myEditCurrentArgument = GroupPoints->LineEdit1;
+ GroupPoints->LineEdit1->setText( "" );
+ GroupPoints->LineEdit2->setText( "" );
+ myPoint1 = GEOM::GEOM_Object::_nil();
+ myPoint2 = GEOM::GEOM_Object::_nil();
+ GroupPoints->PushButton1->setDown(true);
+ GroupPoints->PushButton2->setDown(false);
+ GroupPoints->LineEdit1->setEnabled(true);
+ GroupPoints->LineEdit2->setEnabled(false);
+ GroupPoints->show();
+ GroupWire->hide();
+ break;
+ }
+ case 1:
+ {
+ globalSelection(); // close local contexts, if any
+ localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE );
+
+ myEditCurrentArgument = GroupWire->LineEdit1;
+ GroupWire->LineEdit1->setText("");
+ myWire = GEOM::GEOM_Object::_nil();
+ GroupWire->PushButton1->setDown(true);
+ GroupWire->LineEdit1->setEnabled(true);
+ GroupPoints->hide();
+ GroupWire->show();
+ break;
+ }
+ }
+
+ qApp->processEvents();
+ updateGeometry();
+ resize( minimumSizeHint() );
+ SelectionIntoArgument();
+}
+
//=================================================================================
// function : SelectionIntoArgument()
// purpose : Called when selection is changed or on dialog initialization or activation
aSelMgr->selectedObjects(aSelList);
if (aSelList.Extent() != 1) {
- if (myEditCurrentArgument == GroupPoints->LineEdit1)
- myOkPoint1 = false;
- else if (myEditCurrentArgument == GroupPoints->LineEdit2)
- myOkPoint2 = false;
+ if (myEditCurrentArgument == GroupPoints->LineEdit1) myPoint1 = GEOM::GEOM_Object::_nil();
+ else if (myEditCurrentArgument == GroupPoints->LineEdit2) myPoint2 = GEOM::GEOM_Object::_nil();
+ else if (myEditCurrentArgument == GroupWire->LineEdit1) myWire = GEOM::GEOM_Object::_nil();
+ displayPreview();
return;
}
// nbSel == 1
Standard_Boolean testResult = Standard_False;
GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), testResult);
- if (!testResult || aSelectedObject->_is_nil())
- return;
-
- myEditCurrentArgument->setText(GEOMBase::GetName(aSelectedObject));
- // clear selection
- disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
- myGeomGUI->getApp()->selectionMgr()->clearSelected();
- connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
- this, SLOT(SelectionIntoArgument()));
-
- if (myEditCurrentArgument == GroupPoints->LineEdit1) {
- myPoint1 = aSelectedObject;
- myOkPoint1 = true;
- if (!myOkPoint2)
- GroupPoints->PushButton2->click();
- }
- else if (myEditCurrentArgument == GroupPoints->LineEdit2) {
- myPoint2 = aSelectedObject;
- myOkPoint2 = true;
- if (!myOkPoint1)
- GroupPoints->PushButton1->click();
+ if ( testResult && !aSelectedObject->_is_nil() ) {
+ QString aName = GEOMBase::GetName( aSelectedObject );
+ TopAbs_ShapeEnum aNeedType = myEditCurrentArgument == GroupWire->LineEdit1 ? TopAbs_WIRE : TopAbs_VERTEX;
+
+ TopoDS_Shape aShape;
+ if ( GEOMBase::GetShape( aSelectedObject, aShape, TopAbs_SHAPE ) && !aShape.IsNull() ) {
+ TColStd_IndexedMapOfInteger aMap;
+ aSelMgr->GetIndexes( aSelList.First(), aMap );
+ if ( aMap.Extent() == 1 ) { // Local Selection
+ int anIndex = aMap( 1 );
+ aName += ( aNeedType == TopAbs_WIRE ? QString( ":wire_%1" ).arg( anIndex ) : QString( ":vertex_%1" ).arg( anIndex ) );
+
+ //Find SubShape Object in Father
+ GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather( aSelectedObject, aName );
+ if ( CORBA::is_nil( aFindedObject ) ) { // Object not found in study
+ GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
+ aSelectedObject = aShapesOp->GetSubShape( aSelectedObject, anIndex );
+ }
+ else {
+ aSelectedObject = aFindedObject; // get Object from study
+ }
+ }
+ else { // Global Selection
+ if ( aShape.ShapeType() != aNeedType ) {
+ aSelectedObject = GEOM::GEOM_Object::_nil();
+ aName = "";
+ }
+ }
+ }
+
+ myEditCurrentArgument->setText( aName );
+
+ if (!aSelectedObject->_is_nil()) { // clear selection if something selected
+ globalSelection();
+ localSelection( GEOM::GEOM_Object::_nil(), aNeedType );
+ }
+
+ if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) {
+ myPoint1 = aSelectedObject;
+ if ( !myPoint1->_is_nil() && myPoint2->_is_nil() )
+ GroupPoints->PushButton2->click();
+ }
+ else if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) {
+ myPoint2 = aSelectedObject;
+ if ( !myPoint2->_is_nil() && myPoint1->_is_nil() )
+ GroupPoints->PushButton1->click();
+ }
+ else if ( myEditCurrentArgument == GroupWire->LineEdit1 ) {
+ myWire = aSelectedObject;
+ }
}
displayPreview();
void BuildGUI_EdgeDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
- //globalSelection();//??
if (send == GroupPoints->PushButton1) {
myEditCurrentArgument = GroupPoints->LineEdit1;
GroupPoints->PushButton1->setDown(false);
GroupPoints->LineEdit1->setEnabled(false);
}
+ else if (send == GroupWire->PushButton1) {
+ myEditCurrentArgument = GroupWire->LineEdit1;
+ }
// enable line edit
myEditCurrentArgument->setEnabled(true);
myEditCurrentArgument->setFocus();
- // after setFocus(), because it will be setDown(false) when loses focus
send->setDown(true);
-
- disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
- globalSelection(GEOM_POINT);
- connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
- this, SLOT(SelectionIntoArgument()));
-
- // seems we need it only to avoid preview disappearing, caused by selection mode change
displayPreview();
}
void BuildGUI_EdgeDlg::LineEditReturnPressed()
{
QLineEdit* send = (QLineEdit*)sender();
- if (send == GroupPoints->LineEdit1 || send == GroupPoints->LineEdit2) {
+ if (send == GroupPoints->LineEdit1 || send == GroupPoints->LineEdit2 || send == GroupWire->LineEdit1 ) {
myEditCurrentArgument = send;
GEOMBase_Skeleton::LineEditReturnPressed();
}
connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
this, SLOT( SelectionIntoArgument() ) );
- displayPreview();
+ ConstructorsClicked( getConstructorId() );
}
//=================================================================================
// function : isValid
// purpose :
//=================================================================================
-bool BuildGUI_EdgeDlg::isValid (QString&)
+bool BuildGUI_EdgeDlg::isValid (QString& msg)
{
- return myOkPoint1 && myOkPoint2;
+ bool ok = false;
+ if ( getConstructorId() == 0 ) {
+ ok = !myPoint1->_is_nil() && !myPoint2->_is_nil();
+ }
+ else {
+ ok = !myWire->_is_nil();
+ ok = ok && GroupWire->SpinBox_DX->isValid( msg, !IsPreview() );
+ ok = ok && GroupWire->SpinBox_DY->isValid( msg, !IsPreview() );
+ }
+ return ok;
}
//=================================================================================
//=================================================================================
bool BuildGUI_EdgeDlg::execute (ObjectList& objects)
{
+ bool res = false;
+ GEOM::GEOM_Object_var anObj;
+
GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow( getOperation() );
- GEOM::GEOM_Object_var anObj = anOper->MakeEdge(myPoint1, myPoint2);
- if (!anObj->_is_nil())
- objects.push_back(anObj._retn());
+ switch ( getConstructorId() ) {
+ case 0 :
+ {
+ anObj = anOper->MakeEdge( myPoint1, myPoint2 );
+ res = true;
+ break;
+ }
+ case 1:
+ {
+ double aLinearTolerance = GroupWire->SpinBox_DX->value();
+ double anAngularTolerance = GroupWire->SpinBox_DY->value();
+
+ QStringList aParameters;
+ aParameters << GroupWire->SpinBox_DX->text();
+ aParameters << GroupWire->SpinBox_DY->text();
+
+ anObj = anOper->MakeEdgeWire( myWire, aLinearTolerance, anAngularTolerance );
+
+ if ( !anObj->_is_nil() && !IsPreview() )
+ anObj->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+ res = true;
+ break;
+ }
+ }
- return true;
+ if ( !anObj->_is_nil() ) objects.push_back( anObj._retn() );
+
+ return res;
+}
+
+//=================================================================================
+// function : addSubshapeToStudy
+// purpose : virtual method to add new SubObjects if local selection
+//=================================================================================
+void BuildGUI_EdgeDlg::addSubshapesToStudy()
+{
+ QMap<QString, GEOM::GEOM_Object_var> objMap;
+ switch ( getConstructorId() ) {
+ case 0 :
+ objMap[GroupPoints->LineEdit1->text()] = myPoint1;
+ objMap[GroupPoints->LineEdit2->text()] = myPoint2;
+ break;
+ case 1 :
+ objMap[GroupWire->LineEdit1->text()] = myWire;
+ break;
+ }
+ addSubshapesToFather( objMap );
}
#include <GEOMBase_Skeleton.h>
+class DlgRef_1Sel2Spin;
class DlgRef_2Sel;
//=================================================================================
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid( QString& );
virtual bool execute( ObjectList& );
+ virtual void addSubshapesToStudy();
private:
void Init();
void enterEvent( QEvent* );
private:
- GEOM::GEOM_Object_var myPoint1, myPoint2; /* Points containing the edge */
- bool myOkPoint1; /* true when myPoint is defined */
- bool myOkPoint2;
+ GEOM::GEOM_Object_var myPoint1, myPoint2; /* Points containing the edge */
+ GEOM::GEOM_Object_var myWire; /* Wire */
DlgRef_2Sel* GroupPoints;
+ DlgRef_1Sel2Spin* GroupWire;
private slots:
+ void ConstructorsClicked( int );
void ClickOnOk();
bool ClickOnApply();
void ActivateThisDialog();
<source>ICON_DLG_BUILD_EDGE</source>
<translation>build_edge.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_BUILD_EDGE_WIRE</source>
+ <translation>build_edge_wire.png</translation>
+ </message>
<message>
<source>ICON_DLG_BUILD_FACE</source>
<translation>build_face.png</translation>
<source>GEOM_TOLERANCE</source>
<translation>Tolerance</translation>
</message>
+ <message>
+ <source>GEOM_LINEAR_TOLERANCE</source>
+ <translation>Linear Tolerance</translation>
+ </message>
+ <message>
+ <source>GEOM_ANGULAR_TOLERANCE</source>
+ <translation>Angular Tolerance</translation>
+ </message>
<message>
<source>GEOM_TOLERANCE_CONSTR</source>
<translation>Object And Its Tolerances</translation>
SHAPE_ARG_PLANAR = 3, // for Face
SHAPE_ARG_SUBTYPE = 4, // for Sub-shape
SHAPE_ARG_INDICES = 5, // for Sub-shape
- SHAPE_ARG_TOLERANCE = 6 // for Wire
+ SHAPE_ARG_TOLERANCE = 6, // linear tolerance (for Wire, Edge)
+ SHAPE_ARG_ANGLE_TOL = 7, // angular tolerance (for Edge)
};
GEOMImpl_IShapes(Handle(GEOM_Function) theFunction): _func(theFunction) {}
Standard_Real GetTolerance() { return _func->GetReal(SHAPE_ARG_TOLERANCE); }
+ void SetAngularTolerance(const Standard_Real theValue)
+ { _func->SetReal(SHAPE_ARG_ANGLE_TOL, theValue); }
+
+ Standard_Real GetAngularTolerance() { return _func->GetReal(SHAPE_ARG_ANGLE_TOL); }
+
private:
Handle(GEOM_Function) _func;
return anEdge;
}
+//=============================================================================
+/*!
+ * MakeEdgeWire
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
+ (Handle(GEOM_Object) theWire,
+ const Standard_Real theLinearTolerance,
+ const Standard_Real theAngularTolerance)
+{
+ SetErrorCode(KO);
+
+ if (theWire.IsNull()) return NULL;
+
+ //Add a new Edge object
+ Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
+
+ //Add a new Vector function
+ Handle(GEOM_Function) aFunction =
+ anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
+
+ GEOMImpl_IShapes aCI (aFunction);
+
+ Handle(GEOM_Function) aWire = theWire->GetLastFunction();
+
+ if (aWire.IsNull()) return NULL;
+
+ aCI.SetBase(aWire);
+ aCI.SetTolerance(theLinearTolerance);
+ aCI.SetAngularTolerance(theAngularTolerance);
+
+ //Compute the Edge value
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Shape driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ const double DEF_LIN_TOL = Precision::Confusion();
+ const double DEF_ANG_TOL = Precision::Angular();
+ //Make a Python command
+ if ( theAngularTolerance == DEF_ANG_TOL ) {
+ if ( theLinearTolerance == DEF_LIN_TOL )
+ GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
+ << theWire << ")";
+ else
+ GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
+ << theWire << ", " << theLinearTolerance << ")";
+ }
+ else {
+ GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
+ << theWire << ", " << theLinearTolerance << ", "
+ << theAngularTolerance << ")";
+ }
+
+ SetErrorCode(OK);
+ return anEdge;
+}
+
//=============================================================================
/*!
* MakeWire
Standard_EXPORT ~GEOMImpl_IShapesOperations();
Standard_EXPORT Handle(GEOM_Object) MakeEdge (Handle(GEOM_Object) thePoint1,
- Handle(GEOM_Object) thePoint2);
+ Handle(GEOM_Object) thePoint2);
+ Standard_EXPORT Handle(GEOM_Object) MakeEdgeWire (Handle(GEOM_Object) theWire,
+ const Standard_Real theLinearTolerance,
+ const Standard_Real theAngularTolerance);
Standard_EXPORT Handle(GEOM_Object) MakeWire (std::list<Handle(GEOM_Object)> theEdgesAndWires,
const Standard_Real theTolerance);
// OCCT Includes
#include <ShapeFix_Wire.hxx>
#include <ShapeFix_Edge.hxx>
+#include <ShapeFix_Shape.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
+#include <ElCLib.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
+#include <TColStd_SequenceOfReal.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColGeom_SequenceOfCurve.hxx>
+#include <TColGeom_Array1OfBSplineCurve.hxx>
+#include <TColGeom_HArray1OfBSplineCurve.hxx>
+
+#include <GeomAbs_CurveType.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomConvert_CompCurveToBSplineCurve.hxx>
+#include <GeomConvert.hxx>
+#include <GeomLProp.hxx>
#include <Precision.hxx>
#include <Standard_NullObject.hxx>
aShape = tds;
}
}
+ else if (aType == EDGE_WIRE) {
+ Handle(GEOM_Function) aRefBase = aCI.GetBase();
+ TopoDS_Shape aWire = aRefBase->GetValue();
+ Standard_Real LinTol = aCI.GetTolerance();
+ Standard_Real AngTol = aCI.GetAngularTolerance();
+ if (aWire.IsNull()) Standard_NullObject::Raise("Argument Wire is null");
+
+ TopoDS_Edge ResEdge;
+
+ BRepLib::BuildCurves3d(aWire);
+ Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(aWire);
+ Fixer->SetPrecision(LinTol);
+ Fixer->SetMaxTolerance(LinTol);
+ Fixer->Perform();
+ TopoDS_Wire theWire = TopoDS::Wire(Fixer->Shape());
+
+ TColGeom_SequenceOfCurve CurveSeq;
+ TopTools_SequenceOfShape LocSeq;
+ TColStd_SequenceOfReal FparSeq;
+ TColStd_SequenceOfReal LparSeq;
+ TColStd_SequenceOfReal TolSeq;
+ GeomAbs_CurveType CurType;
+ TopoDS_Vertex FirstVertex, LastVertex;
+
+ BRepTools_WireExplorer wexp(theWire) ;
+ for (; wexp.More(); wexp.Next())
+ {
+ TopoDS_Edge anEdge = wexp.Current();
+ Standard_Real fpar, lpar;
+ TopLoc_Location aLoc;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, fpar, lpar);
+ if (aCurve.IsNull())
+ continue;
+
+ BRepAdaptor_Curve BAcurve(anEdge);
+ GeomAbs_CurveType aType = BAcurve.GetType();
+
+ Handle(Geom_Curve) aBasisCurve = BAcurve.Curve().Curve();
+
+ if (aBasisCurve->IsPeriodic())
+ ElCLib::AdjustPeriodic(aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(),
+ Precision::PConfusion(), fpar, lpar);
+
+ if (CurveSeq.IsEmpty())
+ {
+ CurveSeq.Append(aCurve);
+ TopoDS_Shape aLocShape;
+ aLocShape.Location(aLoc);
+ aLocShape.Orientation(wexp.Orientation());
+ LocSeq.Append(aLocShape);
+ FparSeq.Append(fpar);
+ LparSeq.Append(lpar);
+ CurType = aType;
+ FirstVertex = wexp.CurrentVertex();
+ }
+ else
+ {
+ Standard_Boolean Done = Standard_False;
+ Standard_Real NewFpar, NewLpar;
+ GeomAdaptor_Curve GAprevcurve(CurveSeq.Last());
+ TopoDS_Vertex CurVertex = wexp.CurrentVertex();
+ TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge);
+ TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED;
+ if (aCurve == CurveSeq.Last())
+ {
+ NewFpar = fpar;
+ NewLpar = lpar;
+ if (aBasisCurve->IsPeriodic())
+ {
+ if (NewLpar < NewFpar)
+ NewLpar += aBasisCurve->Period();
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + aBasisCurve->Period(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - aBasisCurve->Period(),
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ }
+ Done = Standard_True;
+ }
+ else if (aType == CurType &&
+ aType != GeomAbs_BezierCurve &&
+ aType != GeomAbs_BSplineCurve &&
+ aType != GeomAbs_OtherCurve)
+ {
+ switch (aType)
+ {
+ case GeomAbs_Line:
+ {
+ gp_Lin aLine = BAcurve.Line();
+ gp_Lin PrevLine = GAprevcurve.Line();
+ if (aLine.Contains(PrevLine.Location(), LinTol) &&
+ aLine.Direction().IsParallel(PrevLine.Direction(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aLine);
+ gp_Pnt P2 = ElCLib::Value(lpar, aLine);
+ NewFpar = ElCLib::Parameter(PrevLine, P1);
+ NewLpar = ElCLib::Parameter(PrevLine, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Circle:
+ {
+ gp_Circ aCircle = BAcurve.Circle();
+ gp_Circ PrevCircle = GAprevcurve.Circle();
+ if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol &&
+ Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol &&
+ aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol))
+ {
+ if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.)
+ {
+ Standard_Real memfpar = fpar;
+ fpar = lpar;
+ lpar = memfpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ gp_Pnt P1 = ElCLib::Value(fpar, aCircle);
+ gp_Pnt P2 = ElCLib::Value(lpar, aCircle);
+ NewFpar = ElCLib::Parameter(PrevCircle, P1);
+ NewLpar = ElCLib::Parameter(PrevCircle, P2);
+ if (NewLpar < NewFpar)
+ NewLpar += 2.*PI;
+ //Standard_Real MemNewFpar = NewFpar, MemNewLpar = NewLpar;
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + 2.*PI,
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*PI,
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Ellipse:
+ {
+ gp_Elips anEllipse = BAcurve.Ellipse();
+ gp_Elips PrevEllipse = GAprevcurve.Ellipse();
+ if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol &&
+ anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol &&
+ Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol &&
+ Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol &&
+ anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol))
+ {
+ if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.)
+ {
+ Standard_Real memfpar = fpar;
+ fpar = lpar;
+ lpar = memfpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ gp_Pnt P1 = ElCLib::Value(fpar, anEllipse);
+ gp_Pnt P2 = ElCLib::Value(lpar, anEllipse);
+ NewFpar = ElCLib::Parameter(PrevEllipse, P1);
+ NewLpar = ElCLib::Parameter(PrevEllipse, P2);
+ if (NewLpar < NewFpar)
+ NewLpar += 2.*PI;
+ if (ConnectByOrigin == TopAbs_FORWARD)
+ ElCLib::AdjustPeriodic(FparSeq.Last(),
+ FparSeq.Last() + 2.*PI,
+ Precision::PConfusion(), NewFpar, NewLpar);
+ else
+ ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*PI,
+ FparSeq.Last(),
+ Precision::PConfusion(), NewFpar, NewLpar);
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Hyperbola:
+ {
+ gp_Hypr aHypr = BAcurve.Hyperbola();
+ gp_Hypr PrevHypr = GAprevcurve.Hyperbola();
+ if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol &&
+ aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol &&
+ Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol &&
+ Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol &&
+ aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aHypr);
+ gp_Pnt P2 = ElCLib::Value(lpar, aHypr);
+ NewFpar = ElCLib::Parameter(PrevHypr, P1);
+ NewLpar = ElCLib::Parameter(PrevHypr, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ case GeomAbs_Parabola:
+ {
+ gp_Parab aParab = BAcurve.Parabola();
+ gp_Parab PrevParab = GAprevcurve.Parabola();
+ if (aParab.Location().Distance(PrevParab.Location()) <= LinTol &&
+ aParab.Focus().Distance(PrevParab.Focus()) <= LinTol &&
+ Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol &&
+ aParab.Axis().IsParallel(PrevParab.Axis(), AngTol))
+ {
+ gp_Pnt P1 = ElCLib::Value(fpar, aParab);
+ gp_Pnt P2 = ElCLib::Value(lpar, aParab);
+ NewFpar = ElCLib::Parameter(PrevParab, P1);
+ NewLpar = ElCLib::Parameter(PrevParab, P2);
+ if (NewLpar < NewFpar)
+ {
+ Standard_Real MemNewFpar = NewFpar;
+ NewFpar = NewLpar;
+ NewLpar = MemNewFpar;
+ ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin);
+ }
+ Done = Standard_True;
+ }
+ break;
+ }
+ } //end of switch (aType)
+ } // end of else if (aType == CurType && ...
+ if (Done)
+ {
+ if (NewFpar < FparSeq.Last())
+ FparSeq(FparSeq.Length()) = NewFpar;
+ else
+ LparSeq(LparSeq.Length()) = NewLpar;
+ }
+ else
+ {
+ CurveSeq.Append(aCurve);
+ TopoDS_Shape aLocShape;
+ aLocShape.Location(aLoc);
+ aLocShape.Orientation(wexp.Orientation());
+ LocSeq.Append(aLocShape);
+ FparSeq.Append(fpar);
+ LparSeq.Append(lpar);
+ TolSeq.Append(BRep_Tool::Tolerance(CurVertex));
+ CurType = aType;
+ }
+ } // end of else (CurveSeq.IsEmpty()) -> not first time
+ } // end for (; wexp.More(); wexp.Next())
+
+ LastVertex = wexp.CurrentVertex();
+ TolSeq.Append(BRep_Tool::Tolerance(LastVertex));
+
+ if (!CurveSeq.IsEmpty())
+ {
+ Standard_Integer nb_curve = CurveSeq.Length(); //number of curves
+ TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1); //array of the curves
+ TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances
+
+ Standard_Integer i;
+
+ if (nb_curve > 1)
+ {
+ for (i = 1; i <= nb_curve; i++)
+ {
+ if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
+ CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
+
+ Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i));
+ tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
+ tab(i-1)->Transform(LocSeq(i).Location().Transformation());
+ GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion());
+ if (LocSeq(i).Orientation() == TopAbs_REVERSED)
+ tab(i-1)->Reverse();
+
+ //Temporary
+ //char* name = new char[100];
+ //sprintf(name, "c%d", i);
+ //DrawTrSurf::Set(name, tab(i-1));
+
+ if (i > 1)
+ tabtolvertex(i-2) = TolSeq(i-1);
+ } // end for (i = 1; i <= nb_curve; i++)
+ tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length());
+
+ Standard_Boolean closed_flag = Standard_False;
+ Standard_Real closed_tolerance = 0.;
+ if (FirstVertex.IsSame(LastVertex) &&
+ GeomLProp::Continuity(tab(0), tab(nb_curve-1),
+ tab(0)->FirstParameter(),
+ tab(nb_curve-1)->LastParameter(),
+ Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1)
+ {
+ closed_flag = Standard_True ;
+ closed_tolerance = BRep_Tool::Tolerance(FirstVertex);
+ }
+
+ Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves
+ Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex
+ GeomConvert::ConcatC1(tab,
+ tabtolvertex,
+ ArrayOfIndices,
+ concatcurve,
+ closed_flag,
+ closed_tolerance); //C1 concatenation
+
+ if (concatcurve->Length() > 1)
+ {
+ GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
+
+ for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
+ Concat.Add( concatcurve->Value(i), LinTol, Standard_True );
+
+ concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
+ }
+
+ ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()),
+ FirstVertex, LastVertex);
+ }
+ else
+ {
+ if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
+ CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve();
+
+ CurveSeq(1)->Transform(LocSeq(1).Location().Transformation());
+ ResEdge = BRepLib_MakeEdge(CurveSeq(1),
+ FirstVertex, LastVertex,
+ FparSeq(1), LparSeq(1));
+ }
+ }
+
+ aShape = ResEdge;
+ }
if (aShape.IsNull()) return 0;
#define SUBSHAPE_NOT_SORTED 8
#define FACE_WIRES 9
#define REVERSE_ORIENTATION 10
+#define EDGE_WIRE 11
#define ARCHIMEDE_TYPE 1
return GetObject(anObject);
}
+//=============================================================================
+/*!
+ * MakeEdgeWire
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeEdgeWire
+ (GEOM::GEOM_Object_ptr theWire,
+ const CORBA::Double theLinearTolerance,
+ const CORBA::Double theAngularTolerance)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Set a not done flag
+ GetOperations()->SetNotDone();
+
+ //Get the source wire
+ Handle(GEOM_Object) aWire = GetObjectImpl(theWire);
+
+ if (aWire.IsNull()) return aGEOMObject._retn();
+
+ //Create the Edge
+ Handle(GEOM_Object) anObject = GetOperations()->MakeEdgeWire(aWire, theLinearTolerance, theAngularTolerance);
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
//=============================================================================
/*!
* MakeWire
GEOM::GEOM_Object_ptr MakeEdge (GEOM::GEOM_Object_ptr thePnt1,
GEOM::GEOM_Object_ptr thePnt2);
+ GEOM::GEOM_Object_ptr MakeEdgeWire (GEOM::GEOM_Object_ptr theWire,
+ const CORBA::Double theLinearTolerance,
+ const CORBA::Double theAngularTolerance);
GEOM::GEOM_Object_ptr MakeWire (const GEOM::ListOfGO& theEdgesAndWires,
const CORBA::Double theTolerance);
RaiseIfFailed("MakeEdge", self.ShapesOp)
return anObj
+ ## Create an edge from specified wire.
+ # @param theWire source Wire.
+ # @param theLinearTolerance linear tolerance value.
+ # @param theAngularTolerance angular tolerance value.
+ # @return New GEOM_Object, containing the created edge.
+ #
+ # @ref tui_creation_edge "Example"
+ def MakeEdgeWire(self, theWire, theLinearTolerance = 1e-07, theAngularTolerance = 1e-12):
+ # Example: see GEOM_TestAll.py
+ anObj = self.ShapesOp.MakeEdgeWire(theWire, theLinearTolerance, theAngularTolerance)
+ RaiseIfFailed("MakeEdgeWire", self.ShapesOp)
+ return anObj
+
## Create a wire from the set of edges and wires.
# @param theEdgesAndWires List of edges and/or wires.
# @param theTolerance Maximum distance between vertices, that will be merged.