Salome HOME
Issue 0020747: EDF 1275 GEOM : Create one edge from one wire
authorvsr <vsr@opencascade.com>
Wed, 6 Oct 2010 13:34:46 +0000 (13:34 +0000)
committervsr <vsr@opencascade.com>
Wed, 6 Oct 2010 13:34:46 +0000 (13:34 +0000)
20 files changed:
doc/salome/gui/GEOM/images/edge1.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/edge2.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/neo-obj2.png [deleted file]
doc/salome/gui/GEOM/input/creating_edge.doc
doc/salome/gui/GEOM/input/tui_advanced_geom_objs.doc
idl/GEOM_Gen.idl
resources/Makefile.am
resources/build_edge_wire.png [new file with mode: 0644]
src/BuildGUI/BuildGUI_EdgeDlg.cxx
src/BuildGUI/BuildGUI_EdgeDlg.h
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMImpl/GEOMImpl_IShapes.hxx
src/GEOMImpl/GEOMImpl_IShapesOperations.cxx
src/GEOMImpl/GEOMImpl_IShapesOperations.hxx
src/GEOMImpl/GEOMImpl_ShapeDriver.cxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_IShapesOperations_i.cc
src/GEOM_I/GEOM_IShapesOperations_i.hh
src/GEOM_SWIG/geompyDC.py

diff --git a/doc/salome/gui/GEOM/images/edge1.png b/doc/salome/gui/GEOM/images/edge1.png
new file mode 100644 (file)
index 0000000..03840b2
Binary files /dev/null and b/doc/salome/gui/GEOM/images/edge1.png differ
diff --git a/doc/salome/gui/GEOM/images/edge2.png b/doc/salome/gui/GEOM/images/edge2.png
new file mode 100644 (file)
index 0000000..b17336e
Binary files /dev/null and b/doc/salome/gui/GEOM/images/edge2.png differ
diff --git a/doc/salome/gui/GEOM/images/neo-obj2.png b/doc/salome/gui/GEOM/images/neo-obj2.png
deleted file mode 100755 (executable)
index 3ce42b4..0000000
Binary files a/doc/salome/gui/GEOM/images/neo-obj2.png and /dev/null differ
index 6d45a541858e5e5970de5e3efc2287d0ef16ef7b..bc8c79b64ae0e21262da970e34212fc70003efc4 100644 (file)
@@ -2,25 +2,50 @@
 
 \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
+*/
index f9f402a7e158b66f7f93d10c051aba80c37da6a9..506e1039a655857a9173bb538b3178b9c7fcb97b 100644 (file)
@@ -10,6 +10,10 @@ import geompy
 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.)
@@ -18,10 +22,30 @@ 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
index 4cef6701aaa9ea7126cd11313a213b11301ca0ea..7f37c359b065a22b0f91cff177541a0679c9ea61 100644 (file)
@@ -1313,6 +1313,17 @@ module GEOM
      */
     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.
index f8bc0a9dcf168989eea3910632d529f78177ee81..76368f05bb4e9de8419a9fad241cfdd53321504f 100644 (file)
@@ -47,6 +47,7 @@ box2points.png                        \
 boxdxyz.png                    \
 build_compound.png             \
 build_edge.png                 \
+build_edge_wire.png                    \
 build_face.png                 \
 build_shell.png                        \
 build_solid.png                        \
diff --git a/resources/build_edge_wire.png b/resources/build_edge_wire.png
new file mode 100644 (file)
index 0000000..3c7b538
Binary files /dev/null and b/resources/build_edge_wire.png differ
index 5096b2a7ac70ffb6ab836cb0cb98c69099f78aa1..33e9f1e504c46eba3cf54c86002850992ea14149 100644 (file)
@@ -36,6 +36,7 @@
 #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();
 }
 
@@ -98,28 +119,35 @@ BuildGUI_EdgeDlg::~BuildGUI_EdgeDlg()
 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 );
 }
 
 //=================================================================================
@@ -142,11 +170,60 @@ bool BuildGUI_EdgeDlg::ClickOnApply()
     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
@@ -161,38 +238,67 @@ void BuildGUI_EdgeDlg::SelectionIntoArgument()
   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();
@@ -205,7 +311,6 @@ void BuildGUI_EdgeDlg::SelectionIntoArgument()
 void BuildGUI_EdgeDlg::SetEditCurrentArgument()
 {
   QPushButton* send = (QPushButton*)sender();
-  //globalSelection();//??
 
   if (send == GroupPoints->PushButton1) {
     myEditCurrentArgument = GroupPoints->LineEdit1;
@@ -217,19 +322,14 @@ void BuildGUI_EdgeDlg::SetEditCurrentArgument()
     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();
 }
 
@@ -240,7 +340,7 @@ void BuildGUI_EdgeDlg::SetEditCurrentArgument()
 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();
   }
@@ -257,7 +357,7 @@ void BuildGUI_EdgeDlg::ActivateThisDialog()
   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
            this, SLOT( SelectionIntoArgument() ) );
 
-  displayPreview();
+  ConstructorsClicked( getConstructorId() );
 }
 
 //=================================================================================
@@ -283,9 +383,18 @@ GEOM::GEOM_IOperations_ptr BuildGUI_EdgeDlg::createOperation()
 // 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;
 }
 
 //=================================================================================
@@ -294,11 +403,57 @@ bool BuildGUI_EdgeDlg::isValid (QString&)
 //=================================================================================
 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 );
 }
index 1f95ea8658e1f8b4c26b1893a2abf017cb2bcf08..f6e09236f3e91b46b95f3740cce6210b348530b1 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <GEOMBase_Skeleton.h>
 
+class DlgRef_1Sel2Spin;
 class DlgRef_2Sel;
 
 //=================================================================================
@@ -48,19 +49,21 @@ protected:
   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();
index e41de1d956ae89e7be97933ecdde9606d0c01ee5..e0dd7d86c0278e8df2517b1f097c5561a7b0fbec 100644 (file)
             <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>
index 01b728a308a496fcd1509a9bd689eb0aeaa20d56..e0324cbe80b6063845ad93a24a375c4eda15e139 100644 (file)
@@ -1821,6 +1821,14 @@ Please, select face, shell or solid and try again</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>
index cd8dbe705a2bd498c3d2d37e0a2975e44eba96e3..dcdb5926588a428947fd6c89c5b12ea3a7640d80 100644 (file)
@@ -38,7 +38,8 @@ class GEOMImpl_IShapes
     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) {}
@@ -75,6 +76,11 @@ class GEOMImpl_IShapes
 
   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;
index 93eb4535e3f2e52bcf22a255838f51db8d632c21..851186aba05ecc8e6310f17bb5c13415e46b6b23 100644 (file)
@@ -210,6 +210,77 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
   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
index 23dbccb5355a7a2ab347fcbe1c1344d707ab93fb..b097ef81ec77b5896f5beceb34ea21abc26c912a 100644 (file)
@@ -55,7 +55,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
   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);
index 6990682cf2e64ff254eb37f746b35def5c212ec1..54d149b3a625b3fca8706082fe915d45f14c576c 100644 (file)
@@ -31,6 +31,7 @@
 // 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>
@@ -441,6 +458,342 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
       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;
 
index d1dcbe27446ebe862becba24edd5a6592a552ced..b954ec438f89401f360fa1f53536d49e4b253d1f 100755 (executable)
 #define SUBSHAPE_NOT_SORTED 8
 #define FACE_WIRES          9
 #define REVERSE_ORIENTATION 10
+#define EDGE_WIRE           11
 
 #define ARCHIMEDE_TYPE 1
 
index 07c9943a98d08fe74243bc9e1517be841d943a5f..310111aaa864daf96a8f939de445d7d7977c0da4 100644 (file)
@@ -85,6 +85,34 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeEdge
   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
index fdc3e4ba05855532334c33c5520292308d70f18d..54752caf22bc4356ff940ea96d0468d299218380 100644 (file)
@@ -44,6 +44,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i :
 
   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);
index 954896f5eeccd6f505eeaf368fbf66a0fc3bc4cd..a9d9babb0f1904af46fffc250b4496e00ad7b792 100644 (file)
@@ -1551,6 +1551,19 @@ class geompyDC(GEOM._objref_GEOM_Gen):
             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.