]> SALOME platform Git repositories - modules/geom.git/blob - src/BasicGUI/BasicGUI_WorkingPlaneDlg.cxx
Salome HOME
Porting to Qt4.
[modules/geom.git] / src / BasicGUI / BasicGUI_WorkingPlaneDlg.cxx
1 //  GEOM GEOMGUI : GUI for Geometry component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : BasicGUI_WorkingPlaneDlg.cxx
25 //  Author : Lucien PIGNOLONI
26 //  Module : GEOM
27
28 #include "BasicGUI_WorkingPlaneDlg.h"
29
30 #include "GeometryGUI.h"
31 #include "GEOMBase.h"
32
33 #include "SUIT_ResourceMgr.h"
34 #include "SUIT_Session.h"
35 #include "SalomeApp_Application.h"
36 #include "LightApp_SelectionMgr.h"
37
38 // OCCT Includes
39 #include <BRep_Tool.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopExp.hxx>
43 #include <gp_Pnt.hxx>
44 #include <gp_Dir.hxx>
45 #include <TColStd_MapOfInteger.hxx>
46
47 // QT Includes
48 #include <QCheckBox>
49
50 #include "GEOMImpl_Types.hxx"
51
52 using namespace std;
53
54 //=================================================================================
55 // class    : BasicGUI_WorkingPlaneDlg()
56 // purpose  : Constructs a BasicGUI_WorkingPlaneDlg which is a child of 'parent', with the
57 //            name 'name' and widget flags set to 'f'.
58 //            The dialog will by default be modeless, unless you set 'modal' to
59 //            TRUE to construct a modal dialog.
60 //=================================================================================
61 BasicGUI_WorkingPlaneDlg::BasicGUI_WorkingPlaneDlg(GeometryGUI* theGeometryGUI, QWidget* parent,
62                                                    const char* name, bool modal, Qt::WindowFlags fl)
63   :GEOMBase_Skeleton(theGeometryGUI, parent, name, modal, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
64 {
65   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_SELECT")));
66   QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_DLG_WPLANE_FACE")));
67   QPixmap image2(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_DLG_WPLANE_VECTOR")));
68   QPixmap image3(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_DLG_WPLANE_ORIGIN")));
69
70   setWindowTitle(tr("GEOM_WPLANE_TITLE"));
71
72   /***************************************************************/
73   GroupConstructors->setTitle(tr("GEOM_WPLANE"));
74   RadioButton1->setIcon(image1);
75   RadioButton2->setIcon(image2);
76   RadioButton3->setIcon(image3);
77
78   Group1 = new Ui::DlgRef_1Sel_QTD();
79   QWidget* aGroup1Widget = new QWidget(this);
80   Group1->setupUi(aGroup1Widget);
81   aGroup1Widget->setObjectName("Group1");
82
83   Group1->GroupBox1->setTitle(tr("GEOM_WPLANE_FACE"));
84   Group1->TextLabel1->setText(tr("GEOM_SELECTION"));
85   Group1->PushButton1->setIcon(image0);
86   Group1->LineEdit1->setReadOnly( true );
87
88   Group2 = new Ui::DlgRef_2Sel_QTD();
89   QWidget* aGroup2Widget = new QWidget(this);
90   Group2->setupUi(aGroup2Widget);
91   aGroup2Widget->setObjectName("Group2");
92
93   Group2->GroupBox1->setTitle(tr("GEOM_WPLANE_VECTOR"));
94   Group2->TextLabel1->setText(tr("GEOM_WPLANE_VX"));
95   Group2->TextLabel2->setText(tr("GEOM_WPLANE_VZ"));
96   Group2->PushButton1->setIcon(image0);
97   Group2->PushButton2->setIcon(image0);
98   Group2->LineEdit1->setReadOnly( true );
99   Group2->LineEdit2->setReadOnly( true );
100
101   Group3 = new Ui::DlgRef_3Check_QTD();
102   QWidget* aGroup3Widget = new QWidget(this);
103   Group3->setupUi(aGroup3Widget);
104   aGroup3Widget->setObjectName("Group3");
105
106   Group3->GroupBox1->setTitle(tr("GEOM_WPLANE_ORIGIN"));
107   Group3->RadioButton1->setText(tr("GEOM_WPLANE_OXY"));
108   Group3->RadioButton2->setText(tr("GEOM_WPLANE_OYZ"));
109   Group3->RadioButton3->setText(tr("GEOM_WPLANE_OZX"));
110
111   gridLayout1->addWidget(aGroup1Widget, 1, 0);
112   gridLayout1->addWidget(aGroup2Widget, 1, 0);
113   gridLayout1->addWidget(aGroup3Widget, 1, 0);
114   /***************************************************************/
115   QFrame* aReverseGroupBox = new QFrame(this);
116   aReverseGroupBox->setObjectName("aReverseGroupBox");
117   aReverseGroupBox->setContentsMargins(10, 10, 10, 10);
118   QHBoxLayout* aReverseGroupBoxLayout = new QHBoxLayout( aReverseGroupBox );
119     
120   myReverseCB = new QCheckBox(aReverseGroupBox);
121   myReverseCB->setObjectName("myReverseCB");
122   myReverseCB->setText(tr("GEOM_REVERSE_PLANE"));
123   aReverseGroupBoxLayout->addWidget(myReverseCB);
124     
125   gridLayout1->addWidget(aReverseGroupBox, 2, 0);
126   
127
128   setHelpFileName("working_plane.htm");
129
130   Init();
131 }
132
133 //=================================================================================
134 // function : ~BasicGUI_WorkingPlaneDlg()
135 // purpose  : Destroys the object and frees any allocated resources
136 //=================================================================================
137 BasicGUI_WorkingPlaneDlg::~BasicGUI_WorkingPlaneDlg()
138 {
139 }
140
141 //=================================================================================
142 // function : Init()
143 // purpose  :
144 //=================================================================================
145 void BasicGUI_WorkingPlaneDlg::Init()
146 {
147   /* init variables */
148   myEditCurrentArgument = Group1->LineEdit1;
149   myWPlane = myGeomGUI->GetWorkingPlane();
150
151   // myGeomGUI->SetState( 0 );
152
153   myFace = GEOM::GEOM_Object::_nil();
154   myVectX = GEOM::GEOM_Object::_nil();
155   myVectZ = GEOM::GEOM_Object::_nil();
156
157   aOriginType = 1;
158
159   /* Filter definition */
160   globalSelection( GEOM_PLANE );
161
162    /* signals and slots connections */
163   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
164   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
165   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
166   connect(GroupConstructors, SIGNAL(clicked(int)), this, SLOT(ConstructorsClicked(int)));
167
168   connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
169   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
170
171   connect(Group1->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
172   connect(Group1->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
173
174   connect(Group2->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
175   connect(Group2->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
176   connect(Group2->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
177   connect(Group2->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
178
179   connect(Group3->GroupBox1, SIGNAL(clicked(int)), this, SLOT(GroupClicked(int)));
180
181   connect(myReverseCB, SIGNAL(clicked()), this, SLOT(onReverse()));
182
183   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
184           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
185
186   initName( tr( "GEOM_WPLANE" ).toLatin1().constData() );
187   ConstructorsClicked(0);
188 }
189
190 //=================================================================================
191 // function : ConstructorsClicked()
192 // purpose  : Radio button management
193 //=================================================================================
194 void BasicGUI_WorkingPlaneDlg::ConstructorsClicked(int constructorId)
195 {
196   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
197
198   disconnect(aSelMgr, 0, this, 0);
199
200   switch (constructorId)
201     {
202     case 0:
203       {
204         //globalSelection( GEOM_PLANE );
205         TColStd_MapOfInteger aMap;
206         aMap.Add( GEOM_PLANE );
207         aMap.Add( GEOM_MARKER );
208         globalSelection( aMap );
209
210         ::qobject_cast<QWidget*>( Group2->gridLayout->parent() )->hide();
211         ::qobject_cast<QWidget*>( Group3->gridLayout->parent() )->hide();
212         resize(0, 0);
213         ::qobject_cast<QWidget*>( Group1->gridLayout->parent() )->show();
214
215         myEditCurrentArgument = Group1->LineEdit1;
216         Group1->LineEdit1->setText("");
217         myFace = GEOM::GEOM_Object::_nil();
218
219         connect(aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
220         break;
221       }
222     case 1:
223       {
224         globalSelection( GEOM_LINE );
225
226         ::qobject_cast<QWidget*>( Group1->gridLayout->parent() )->hide();
227         ::qobject_cast<QWidget*>( Group3->gridLayout->parent() )->hide();
228         resize(0, 0);
229         ::qobject_cast<QWidget*>( Group2->gridLayout->parent() )->show();
230
231         myEditCurrentArgument = Group2->LineEdit1;
232         Group2->LineEdit1->setText("");
233          Group2->LineEdit2->setText("");
234         myVectX = GEOM::GEOM_Object::_nil();
235         myVectZ = GEOM::GEOM_Object::_nil();
236
237         connect(aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
238         break;
239       }
240     case 2:
241       {
242         ::qobject_cast<QWidget*>( Group1->gridLayout->parent() )->hide();
243         ::qobject_cast<QWidget*>( Group2->gridLayout->parent() )->hide();
244         resize(0, 0);
245         ::qobject_cast<QWidget*>( Group3->gridLayout->parent() )->show();
246
247         Group3->RadioButton1->setChecked(true);
248         aOriginType = 1;
249         break;
250       }
251     }
252   
253   updateWPlane();
254 }
255
256 //=================================================================================
257 // function : GroupClicked()
258 // purpose  : Radio button management
259 //=================================================================================
260 void BasicGUI_WorkingPlaneDlg::GroupClicked(int groupId)
261 {
262   aOriginType = groupId;
263   updateWPlane();
264 }
265
266 //=================================================================================
267 // function : ClickOnOk()
268 // purpose  :
269 //=================================================================================
270 void BasicGUI_WorkingPlaneDlg::ClickOnOk()
271 {
272   if ( ClickOnApply() )
273     ClickOnCancel();
274 }
275
276 //=================================================================================
277 // function : ClickOnApply()
278 // purpose  :
279 //=================================================================================
280 bool BasicGUI_WorkingPlaneDlg::ClickOnApply()
281 {
282   buttonApply->setFocus();
283   myGeomGUI->application()->putInfo(tr(""));
284  
285   if (updateWPlane(false)){
286     myGeomGUI->SetWorkingPlane(myWPlane);
287     myGeomGUI->ActiveWorkingPlane();
288   }
289   
290   return true;
291 }
292
293 //=================================================================================
294 // function : SelectionIntoArgument()
295 // purpose  : Called when selection as changed or other case
296 //=================================================================================
297 void BasicGUI_WorkingPlaneDlg::SelectionIntoArgument()
298 {
299   myEditCurrentArgument->setText("");
300
301   const int id = getConstructorId();
302   if ( IObjectCount() != 1 ) {
303     if(id == 0)
304       myFace = GEOM::GEOM_Object::_nil();
305     else if(id == 1) {
306       if (myEditCurrentArgument == Group2->LineEdit1)
307         myVectX = GEOM::GEOM_Object::_nil();
308       else if (myEditCurrentArgument == Group2->LineEdit2)
309         myVectZ = GEOM::GEOM_Object::_nil();
310     }
311     return;
312   }
313
314   // nbSel == 1
315   Standard_Boolean aRes = Standard_False;
316   GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(firstIObject(), aRes);
317
318   if(!aRes || CORBA::is_nil( aSelectedObject ))
319     return;
320
321   if(myEditCurrentArgument == Group1->LineEdit1)
322     myFace = aSelectedObject;
323   else if(myEditCurrentArgument == Group2->LineEdit1)
324     myVectX = aSelectedObject;
325   else if(myEditCurrentArgument == Group2->LineEdit2)
326     myVectZ = aSelectedObject;
327
328   myEditCurrentArgument->setText( GEOMBase::GetName( aSelectedObject ) );
329   
330   updateWPlane();
331 }
332
333
334 //=================================================================================
335 // function : SetEditCurrentArgument()
336 // purpose  :
337 //=================================================================================
338 void BasicGUI_WorkingPlaneDlg::SetEditCurrentArgument()
339 {
340   QPushButton* send = (QPushButton*)sender();
341
342   if(send == Group1->PushButton1) {
343     myEditCurrentArgument = Group1->LineEdit1;
344     globalSelection( GEOM_PLANE );
345   }
346   else if(send == Group2->PushButton1) {
347     myEditCurrentArgument = Group2->LineEdit1;
348     globalSelection( GEOM_LINE );
349   }
350   else if(send == Group2->PushButton2) {
351     myEditCurrentArgument = Group2->LineEdit2;
352     globalSelection( GEOM_LINE );
353   }
354
355   myEditCurrentArgument->setFocus();
356   SelectionIntoArgument();
357 }
358
359
360 //=================================================================================
361 // function : LineEditReturnPressed()
362 // purpose  :
363 //=================================================================================
364 void BasicGUI_WorkingPlaneDlg::LineEditReturnPressed()
365 {
366   QLineEdit* send = (QLineEdit*)sender();
367   if(send == Group1->LineEdit1 || send == Group2->LineEdit1 || send == Group2->LineEdit2) {
368     myEditCurrentArgument = send;
369     GEOMBase_Skeleton::LineEditReturnPressed();
370   }
371 }
372
373
374 //=================================================================================
375 // function : onReverse()
376 // purpose  :
377 //=================================================================================
378 void BasicGUI_WorkingPlaneDlg::onReverse()
379 {
380   updateWPlane();
381 }
382
383
384 //=================================================================================
385 // function : ActivateThisDialog()
386 // purpose  :
387 //=================================================================================
388 void BasicGUI_WorkingPlaneDlg::ActivateThisDialog( )
389 {
390   GEOMBase_Skeleton::ActivateThisDialog();
391   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
392           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
393
394   ConstructorsClicked( getConstructorId() );
395 }
396
397
398 //=================================================================================
399 // function : DeactivateActiveDialog()
400 // purpose  : public slot to deactivate if active
401 //=================================================================================
402 void BasicGUI_WorkingPlaneDlg::DeactivateActiveDialog()
403 {
404   // myGeomGUI->SetState( -1 );
405   GEOMBase_Skeleton::DeactivateActiveDialog();
406 }
407
408 //=======================================================================
409 // function : ClickOnCancel()
410 // purpose  :
411 //=======================================================================
412 void BasicGUI_WorkingPlaneDlg::ClickOnCancel()
413 {
414   GEOMBase_Skeleton::ClickOnCancel();
415 }
416
417 //=================================================================================
418 // function : enterEvent()
419 // purpose  :
420 //=================================================================================
421 void BasicGUI_WorkingPlaneDlg::enterEvent(QEvent* e)
422 {
423   if ( !GroupConstructors->isEnabled() )
424     ActivateThisDialog();
425 }
426
427 //=================================================================================
428 // function : closeEvent
429 // purpose  :
430 //=================================================================================
431 void BasicGUI_WorkingPlaneDlg::closeEvent( QCloseEvent* e )
432 {
433   GEOMBase_Skeleton::closeEvent( e );
434 }
435
436
437 //=================================================================================
438 // function : updateWPlane
439 // purpose  :
440 //=================================================================================
441 bool BasicGUI_WorkingPlaneDlg::updateWPlane( const bool showPreview )
442 {
443   erasePreview();
444   
445   const int id = getConstructorId();
446
447   if (id == 0) { // by planar face selection
448     if (CORBA::is_nil(myFace)) {
449       if(!showPreview)
450         showError( "Face has to be selected" );
451       return false;
452     }
453
454     // PAL12781: set center of WPL to face's center of mass
455     // like it is done for LCS creation
456     CORBA::Double Ox,Oy,Oz, Zx,Zy,Zz, Xx,Xy,Xz;
457     Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
458     Zz = Xx = 1.;
459
460     GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
461       myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
462     aMeasureOp->GetPosition(myFace, Ox,Oy,Oz, Zx,Zy,Zz, Xx,Xy,Xz);
463
464     if (aMeasureOp->IsDone()) {
465       gp_Pnt aPnt (Ox,Oy,Oz);
466       gp_Dir aDirN (Zx,Zy,Zz);
467       gp_Dir aDirX (Xx,Xy,Xz);
468       myWPlane = gp_Ax3(aPnt, aDirN, aDirX);
469     } else {
470       if(!showPreview)
471         showError( "Wrong shape selected (has to be a planar face)" );
472       return false;
473     }
474
475   } else if (id == 1) { // by two vectors (Ox & Oz)
476     if ( CORBA::is_nil( myVectX ) || CORBA::is_nil( myVectZ ) ) {
477       if(!showPreview)
478         showError( "Two vectors have to be selected" );
479       return false;
480     }
481
482     TopoDS_Edge aVectX, aVectZ;
483     TopoDS_Vertex VX1, VX2, VZ1, VZ2;
484     gp_Vec aVX, aVZ;
485
486     if (!GEOMBase::GetShape( myVectX, aVectX, TopAbs_EDGE ) ||
487         !GEOMBase::GetShape( myVectZ, aVectZ, TopAbs_EDGE )) {
488       if(!showPreview)
489         showError( "Wrong shape selected (two vectors(edges) have to be selected)" );
490       return false;
491     }
492
493     TopExp::Vertices(aVectX, VX1, VX2, Standard_True);
494     TopExp::Vertices(aVectZ, VZ1, VZ2, Standard_True);
495
496     if (VX1.IsNull() || VX2.IsNull()) {
497       if(!showPreview)
498         showError( "Bad OX vector" );
499       return false;
500     }
501     if (VZ1.IsNull() || VZ2.IsNull()) {
502       if(!showPreview)
503         showError( "Bad OZ vector" );
504       return false;
505     }
506
507     aVX = gp_Vec(BRep_Tool::Pnt(VX1), BRep_Tool::Pnt(VX2));
508     aVZ = gp_Vec(BRep_Tool::Pnt(VZ1), BRep_Tool::Pnt(VZ2));
509
510     if (aVX.Magnitude() < Precision::Confusion()) {
511       if(!showPreview)
512         showError( "Bad OX vector" );
513       return false;
514     }
515     if (aVZ.Magnitude() < Precision::Confusion()) {
516       if(!showPreview)
517         showError( "Bad OZ vector" );
518       return false;
519     }
520
521     gp_Dir aDirX = gp_Dir(aVX.X(), aVX.Y(), aVX.Z());
522     gp_Dir aDirZ = gp_Dir(aVZ.X(), aVZ.Y(), aVZ.Z());
523
524     if (aDirX.IsParallel(aDirZ, Precision::Angular())) {
525       if(!showPreview)
526         showError( "Parallel vectors selected" );
527       return false;
528     }
529
530     myWPlane = gp_Ax3(BRep_Tool::Pnt(VX1), aDirZ, aDirX);
531
532   } else if (id == 2) { // by selection from standard (OXY or OYZ, or OZX)
533     gp_Ax2 anAx2;
534
535     if      (aOriginType == 1) anAx2 = gp::XOY();
536     else if (aOriginType == 2) anAx2 = gp::YOZ();
537     else if (aOriginType == 0) anAx2 = gp::ZOX();
538
539     myWPlane = gp_Ax3(anAx2);
540
541   } else {
542     return false;
543   }
544   
545   if (myReverseCB->isChecked())
546     {
547       myWPlane.YReverse();
548       myWPlane.ZReverse();
549     }
550   
551   if (showPreview)
552     {
553       GEOM::GEOM_IBasicOperations_var aBasicOp = getGeomEngine()->GetIBasicOperations( getStudyId() );
554       GEOM::GEOM_Object_var anObj = aBasicOp->MakeMarker(  myWPlane.Location().X(), myWPlane.Location().Y(), myWPlane.Location().Z(),
555                                                            myWPlane.XDirection().X(), myWPlane.XDirection().Y(), myWPlane.XDirection().Z(),
556                                                            myWPlane.YDirection().X(), myWPlane.YDirection().Y(), myWPlane.YDirection().Z() );
557       displayPreview(anObj);
558     }
559
560   return true;
561 }