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