Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/geom.git] / src / BasicGUI / BasicGUI_WorkingPlaneDlg.cxx
index 5fc54525777470519bddd9d7f26fe97e9e19dfd5..31c84cb9e1dd6ea2e7f59db123d1522d967b27c8 100644 (file)
@@ -17,7 +17,7 @@
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //
 //
 #include "SalomeApp_Application.h"
 #include "LightApp_SelectionMgr.h"
 
-#include <Geom_Surface.hxx>
-#include <Geom_Plane.hxx>
+// OCCT Includes
+#include <BRep_Tool.hxx>
 #include <TopoDS.hxx>
-#include <TopoDS_Face.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopExp.hxx>
-#include <BRep_Tool.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Dir.hxx>
-#include <gp_Pln.hxx>
-#include <V3d_View.hxx>
-
-#include "GEOMImpl_Types.hxx"
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 
+// QT Includes
 #include <qcheckbox.h>
 #include <qlabel.h>
 
+#include "GEOMImpl_Types.hxx"
+
 using namespace std;
 
 //=================================================================================
@@ -104,8 +105,18 @@ BasicGUI_WorkingPlaneDlg::BasicGUI_WorkingPlaneDlg(GeometryGUI* theGeometryGUI,
   Layout1->addWidget(Group2, 1, 0);
   Layout1->addWidget(Group3, 1, 0);
   /***************************************************************/
-
-  setHelpFileName("working_plane.htm");
+  QGroupBox* aReverseGroupBox = new QGroupBox(this, "aReverseGroupBox");
+  aReverseGroupBox->setTitle(tr(""));
+  aReverseGroupBox->setColumnLayout(1, Qt::Horizontal);
+  aReverseGroupBox->setInsideMargin(10);
+  
+  myReverseCB = new QCheckBox(aReverseGroupBox, "myReverseCB");
+  myReverseCB->setText(tr("GEOM_REVERSE_PLANE"));
+    
+  Layout1->addWidget(aReverseGroupBox, 2, 0);
+  
+
+  setHelpFileName("create_wplane_page.html");
 
   Init();
 }
@@ -158,7 +169,9 @@ void BasicGUI_WorkingPlaneDlg::Init()
 
   connect(Group3->GroupBox1, SIGNAL(clicked(int)), this, SLOT(GroupClicked(int)));
 
-  connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
+  connect(myReverseCB, SIGNAL(clicked()), this, SLOT(onReverse()));
+
+  connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
          SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
 
   initName( tr( "GEOM_WPLANE" ) );
@@ -171,14 +184,19 @@ void BasicGUI_WorkingPlaneDlg::Init()
 //=================================================================================
 void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
 {
-  disconnect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 0, this, 0);
-  // myGeomGUI->SetState( 0 );
+  LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+
+  disconnect(aSelMgr, 0, this, 0);
 
   switch (constructorId)
     {
     case 0:
       {
-        globalSelection( GEOM_PLANE );
+        //globalSelection( GEOM_PLANE );
+        TColStd_MapOfInteger aMap;
+        aMap.Add( GEOM_PLANE );
+        aMap.Add( GEOM_MARKER );
+        globalSelection( aMap );
 
         Group2->hide();
         Group3->hide();
@@ -189,13 +207,14 @@ void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
         Group1->LineEdit1->setText("");
         myFace = GEOM::GEOM_Object::_nil();
 
-        connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
-               SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+        connect(aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
         break;
       }
     case 1:
       {
-        globalSelection( GEOM_LINE );
+       //globalSelection( GEOM_LINE );
+       GEOM::GEOM_Object_var anObj;
+       localSelection( anObj, TopAbs_EDGE );
 
         Group1->hide();
         Group3->hide();
@@ -204,12 +223,11 @@ void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
 
         myEditCurrentArgument = Group2->LineEdit1;
         Group2->LineEdit1->setText("");
-         Group2->LineEdit2->setText("");
+       Group2->LineEdit2->setText("");
         myVectX = GEOM::GEOM_Object::_nil();
         myVectZ = GEOM::GEOM_Object::_nil();
 
-        connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
-               SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+        connect(aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
         break;
       }
     case 2:
@@ -221,10 +239,11 @@ void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
 
         Group3->RadioButton1->setChecked(true);
         aOriginType = 1;
-              break;
+        break;
       }
     }
-  displayPreview();
+  
+  updateWPlane();
 }
 
 //=================================================================================
@@ -234,6 +253,7 @@ void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
 void BasicGUI_WorkingPlaneDlg::GroupClicked(int groupId)
 {
   aOriginType = groupId;
+  updateWPlane();
 }
 
 //=================================================================================
@@ -254,89 +274,13 @@ bool BasicGUI_WorkingPlaneDlg::ClickOnApply()
 {
   buttonApply->setFocus();
   myGeomGUI->application()->putInfo(tr(""));
-  const int id = getConstructorId();
-
-  if (id == 0) {
-    if ( !CORBA::is_nil( myFace ) ) {
-      TopoDS_Face aPlaneShape;
-      if ( GEOMBase::GetShape( myFace, aPlaneShape, TopAbs_FACE ) ) {
-        Handle(Geom_Surface) aGS = BRep_Tool::Surface( TopoDS::Face( aPlaneShape ) );
-        if ( !aGS.IsNull() && aGS->IsKind( STANDARD_TYPE( Geom_Plane ) ) ) {
-          Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast( aGS );
-          gp_Pln aPln = aGPlane->Pln();
-
-          myWPlane = aPln.Position();
-          myGeomGUI->SetWorkingPlane(myWPlane);
-          myGeomGUI->ActiveWorkingPlane();
-          return true;
-        }
-      }
-    }
-  } else if (id == 1) {
-    if ( CORBA::is_nil( myVectX ) || CORBA::is_nil( myVectZ ) ) {
-      showError( "Two vectors have to be selected" );
-      return false;
-    }
-
-    TopoDS_Edge aVectX, aVectZ;
-    TopoDS_Vertex V1, V2;
-    gp_Vec aVX, aVZ;
-    if (GEOMBase::GetShape( myVectX, aVectX, TopAbs_EDGE ) &&
-        GEOMBase::GetShape( myVectZ, aVectZ, TopAbs_EDGE )) {
-      TopExp::Vertices(aVectZ, V1, V2, Standard_True);
-      if (!V1.IsNull() && !V2.IsNull())
-        aVZ = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
-      else {
-        showError( "Bad OZ vector" );
-        return false;
-      }
-
-      TopExp::Vertices(aVectX, V1, V2, Standard_True);
-      if (!V1.IsNull() && !V2.IsNull())
-        aVX = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
-      else {
-        showError( "Bad OX vector" );
-        return false;
-      }
-
-      gp_Dir aDirZ = gp_Dir(aVZ.X(), aVZ.Y(), aVZ.Z());
-      gp_Dir aDirX = gp_Dir(aVX.X(), aVX.Y(), aVX.Z());
-
-      if (aDirX.IsParallel(aDirZ, Precision::Confusion())) {
-        showError( "Parallel vectors selected" );
-        return false;
-      }
-
-      myWPlane = gp_Ax3(BRep_Tool::Pnt(V1), aDirZ, aDirX);
-
-      myGeomGUI->SetWorkingPlane(myWPlane);
-      myGeomGUI->ActiveWorkingPlane();
-      return true;
-    }
-  } else if (id == 2) {
-    gp_Pnt P1 = gp_Pnt(0., 0., 0.);
-    gp_Dir aDirZ, aDirX;
-
-    if (aOriginType == 1) {
-      aDirZ = gp_Dir(0., 0., 1.);
-      aDirX = gp_Dir(1., 0., 0.);
-    }
-    else if (aOriginType == 2) {
-      aDirZ = gp_Dir(1., 0., 0.);
-      aDirX = gp_Dir(0., 1., 0.);
-    }
-    else if (aOriginType == 0) {
-      aDirZ = gp_Dir(0., 1., 0.);
-      aDirX = gp_Dir(0., 0., 1.);
-    }
-
-    myWPlane = gp_Ax3(P1, aDirZ, aDirX);
-
+  if (updateWPlane(false)){
     myGeomGUI->SetWorkingPlane(myWPlane);
     myGeomGUI->ActiveWorkingPlane();
-    return true;
   }
-  return false;
+  
+  return true;
 }
 
 //=================================================================================
@@ -346,12 +290,13 @@ bool BasicGUI_WorkingPlaneDlg::ClickOnApply()
 void BasicGUI_WorkingPlaneDlg::SelectionIntoArgument()
 {
   myEditCurrentArgument->setText("");
+  QString aName;
 
   const int id = getConstructorId();
-  if ( IObjectCount() != 1 ) {
-    if(id == 0)
+  if (IObjectCount() != 1) {
+    if (id == 0)
       myFace = GEOM::GEOM_Object::_nil();
-    else if(id == 1) {
+    else if (id == 1) {
       if (myEditCurrentArgument == Group2->LineEdit1)
         myVectX = GEOM::GEOM_Object::_nil();
       else if (myEditCurrentArgument == Group2->LineEdit2)
@@ -364,19 +309,50 @@ void BasicGUI_WorkingPlaneDlg::SelectionIntoArgument()
   Standard_Boolean aRes = Standard_False;
   GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(firstIObject(), aRes);
 
-  if(!aRes || CORBA::is_nil( aSelectedObject ))
+  if (!aRes || CORBA::is_nil(aSelectedObject))
     return;
 
-  if(myEditCurrentArgument == Group1->LineEdit1)
+  aName = GEOMBase::GetName(aSelectedObject);
+
+  if (myEditCurrentArgument == Group1->LineEdit1)
     myFace = aSelectedObject;
-  else if(myEditCurrentArgument == Group2->LineEdit1)
-    myVectX = aSelectedObject;
-  else if(myEditCurrentArgument == Group2->LineEdit2)
-    myVectZ = aSelectedObject;
+  else if (myEditCurrentArgument == Group2->LineEdit1 || myEditCurrentArgument == Group2->LineEdit2)
+  {
+    if ( aRes && !aSelectedObject->_is_nil() )
+    {
+      TopoDS_Shape aShape;
+      if ( GEOMBase::GetShape( aSelectedObject, aShape, TopAbs_SHAPE ) && !aShape.IsNull() )
+      {
+        LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+        TColStd_IndexedMapOfInteger aMap;
+        aSelMgr->GetIndexes( firstIObject(), aMap );
+        if ( aMap.Extent() == 1 )
+        {
+          int anIndex = aMap( 1 );
+          aName = aName + ":edge_" + QString::number( anIndex );
+
+         GEOM::GEOM_IShapesOperations_var aShapesOp =
+           getGeomEngine()->GetIShapesOperations( getStudyId() );
+         if(myEditCurrentArgument == Group2->LineEdit1)
+           myVectX = aShapesOp->GetSubShape(aSelectedObject, anIndex);
+         else
+           myVectZ = aShapesOp->GetSubShape(aSelectedObject, anIndex);
+        }
+        else {
+          if (myEditCurrentArgument == Group2->LineEdit1)
+            myVectX = aSelectedObject;
+          else
+            myVectZ = aSelectedObject;
+        }
+        aSelMgr->clearSelected();
+      }
+    }
+  }
 
-  myEditCurrentArgument->setText( GEOMBase::GetName( aSelectedObject ) );
-}
+  myEditCurrentArgument->setText( aName );
 
+  updateWPlane();
+}
 
 //=================================================================================
 // function : SetEditCurrentArgument()
@@ -386,24 +362,25 @@ void BasicGUI_WorkingPlaneDlg::SetEditCurrentArgument()
 {
   QPushButton* send = (QPushButton*)sender();
 
-  if(send == Group1->PushButton1) {
+  if (send == Group1->PushButton1) {
     myEditCurrentArgument = Group1->LineEdit1;
     globalSelection( GEOM_PLANE );
   }
-  else if(send == Group2->PushButton1) {
+  else if (send == Group2->PushButton1) {
     myEditCurrentArgument = Group2->LineEdit1;
-    globalSelection( GEOM_LINE );
+    GEOM::GEOM_Object_var anObj;
+    localSelection( anObj, TopAbs_EDGE );
   }
-  else if(send == Group2->PushButton2) {
+  else if (send == Group2->PushButton2) {
     myEditCurrentArgument = Group2->LineEdit2;
-    globalSelection( GEOM_LINE );
+    GEOM::GEOM_Object_var anObj;
+    localSelection( anObj, TopAbs_EDGE );
   }
 
   myEditCurrentArgument->setFocus();
   SelectionIntoArgument();
 }
 
-
 //=================================================================================
 // function : LineEditReturnPressed()
 // purpose  :
@@ -417,6 +394,14 @@ void BasicGUI_WorkingPlaneDlg::LineEditReturnPressed()
   }
 }
 
+//=================================================================================
+// function : onReverse()
+// purpose  :
+//=================================================================================
+void BasicGUI_WorkingPlaneDlg::onReverse()
+{
+  updateWPlane();
+}
 
 //=================================================================================
 // function : ActivateThisDialog()
@@ -425,27 +410,25 @@ void BasicGUI_WorkingPlaneDlg::LineEditReturnPressed()
 void BasicGUI_WorkingPlaneDlg::ActivateThisDialog( )
 {
   GEOMBase_Skeleton::ActivateThisDialog();
-  connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
+  connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
          SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
 
   ConstructorsClicked( getConstructorId() );
 }
 
-
 //=================================================================================
 // function : DeactivateActiveDialog()
 // purpose  : public slot to deactivate if active
 //=================================================================================
 void BasicGUI_WorkingPlaneDlg::DeactivateActiveDialog()
 {
-  // myGeomGUI->SetState( -1 );
   GEOMBase_Skeleton::DeactivateActiveDialog();
 }
 
-//=======================================================================
+//=================================================================================
 // function : ClickOnCancel()
 // purpose  :
-//=======================================================================
+//=================================================================================
 void BasicGUI_WorkingPlaneDlg::ClickOnCancel()
 {
   GEOMBase_Skeleton::ClickOnCancel();
@@ -469,3 +452,131 @@ void BasicGUI_WorkingPlaneDlg::closeEvent( QCloseEvent* e )
 {
   GEOMBase_Skeleton::closeEvent( e );
 }
+
+//=================================================================================
+// function : updateWPlane
+// purpose  :
+//=================================================================================
+bool BasicGUI_WorkingPlaneDlg::updateWPlane( const bool showPreview )
+{
+  erasePreview();
+  
+  const int id = getConstructorId();
+
+  if (id == 0) { // by planar face selection
+    if (CORBA::is_nil(myFace)) {
+      if(!showPreview)
+       showError( "Face has to be selected" );
+      return false;
+    }
+
+    // PAL12781: set center of WPL to face's center of mass
+    // like it is done for LCS creation
+    CORBA::Double Ox,Oy,Oz, Zx,Zy,Zz, Xx,Xy,Xz;
+    Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
+    Zz = Xx = 1.;
+
+    GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
+      myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
+    aMeasureOp->GetPosition(myFace, Ox,Oy,Oz, Zx,Zy,Zz, Xx,Xy,Xz);
+
+    if (aMeasureOp->IsDone()) {
+      gp_Pnt aPnt (Ox,Oy,Oz);
+      gp_Dir aDirN (Zx,Zy,Zz);
+      gp_Dir aDirX (Xx,Xy,Xz);
+      myWPlane = gp_Ax3(aPnt, aDirN, aDirX);
+    } else {
+      if(!showPreview)
+       showError( "Wrong shape selected (has to be a planar face)" );
+      return false;
+    }
+  }
+  else if (id == 1) { // by two vectors (Ox & Oz)
+    if ( CORBA::is_nil( myVectX ) || CORBA::is_nil( myVectZ ) ) {
+      if(!showPreview)
+       showError( "Two vectors have to be selected" );
+      return false;
+    }
+
+    TopoDS_Edge aVectX, aVectZ;
+    TopoDS_Vertex VX1, VX2, VZ1, VZ2;
+    gp_Vec aVX, aVZ;
+
+    if (!GEOMBase::GetShape( myVectX, aVectX, TopAbs_EDGE ) ||
+        !GEOMBase::GetShape( myVectZ, aVectZ, TopAbs_EDGE )) {
+      if(!showPreview)
+       showError( "Wrong shape selected (two vectors(edges) have to be selected)" );
+      return false;
+    }
+
+    TopExp::Vertices(aVectX, VX1, VX2, Standard_True);
+    TopExp::Vertices(aVectZ, VZ1, VZ2, Standard_True);
+
+    if (VX1.IsNull() || VX2.IsNull()) {
+      if(!showPreview)
+       showError( "Bad OX vector" );
+      return false;
+    }
+    if (VZ1.IsNull() || VZ2.IsNull()) {
+      if(!showPreview)
+       showError( "Bad OZ vector" );
+      return false;
+    }
+
+    aVX = gp_Vec(BRep_Tool::Pnt(VX1), BRep_Tool::Pnt(VX2));
+    aVZ = gp_Vec(BRep_Tool::Pnt(VZ1), BRep_Tool::Pnt(VZ2));
+
+    if (aVX.Magnitude() < Precision::Confusion()) {
+      if(!showPreview)
+       showError( "Bad OX vector" );
+      return false;
+    }
+    if (aVZ.Magnitude() < Precision::Confusion()) {
+      if(!showPreview)
+       showError( "Bad OZ vector" );
+      return false;
+    }
+
+    gp_Dir aDirX = gp_Dir(aVX.X(), aVX.Y(), aVX.Z());
+    gp_Dir aDirZ = gp_Dir(aVZ.X(), aVZ.Y(), aVZ.Z());
+
+    if (aDirX.IsParallel(aDirZ, Precision::Angular())) {
+      if(!showPreview)
+       showError( "Parallel vectors selected" );
+      return false;
+    }
+
+    myWPlane = gp_Ax3(BRep_Tool::Pnt(VX1), aDirZ, aDirX);
+  }
+  else if (id == 2) { // by selection from standard (OXY or OYZ, or OZX)
+    gp_Ax2 anAx2;
+
+    if      (aOriginType == 1) anAx2 = gp::XOY();
+    else if (aOriginType == 2) anAx2 = gp::YOZ();
+    else if (aOriginType == 0) anAx2 = gp::ZOX();
+
+    myWPlane = gp_Ax3(anAx2);
+  }
+  else {
+    return false;
+  }
+
+  if (myReverseCB->isChecked())
+  {
+    myWPlane.YReverse();
+    myWPlane.ZReverse();
+  }
+
+  if (showPreview)
+  {
+    GEOM::GEOM_IBasicOperations_var aBasicOp = getGeomEngine()->GetIBasicOperations(getStudyId());
+    GEOM::GEOM_Object_var anObj = aBasicOp->MakeMarker
+      (myWPlane.Location().X()  , myWPlane.Location().Y()  , myWPlane.Location().Z(),
+       myWPlane.XDirection().X(), myWPlane.XDirection().Y(), myWPlane.XDirection().Z(),
+       myWPlane.YDirection().X(), myWPlane.YDirection().Y(), myWPlane.YDirection().Z());
+    displayPreview(anObj);
+  }
+
+  return true;
+}
+