Salome HOME
0020327: EDF 1018 GEOM : Missing MakeTangentPlaneOnFace in geompy
[modules/geom.git] / src / TransformationGUI / TransformationGUI_RotationDlg.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  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 //  GEOM GEOMGUI : GUI for Geometry component
23 //  File   : TransformationGUI_RotationDlg.cxx
24 //  Author : Lucien PIGNOLONI
25 //  Module : GEOM
26 //  $Header$
27 //
28 #include "TransformationGUI_RotationDlg.h"
29
30 #include "SUIT_Desktop.h"
31 #include "SUIT_Session.h"
32 #include "SalomeApp_Application.h"
33 #include "LightApp_SelectionMgr.h"
34
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS.hxx>
38 #include <TopExp.hxx>
39 #include <TColStd_IndexedMapOfInteger.hxx>
40 #include <TopTools_IndexedMapOfShape.hxx>
41
42 #include <qcheckbox.h>
43 #include <qlabel.h>
44
45 #include "GEOMImpl_Types.hxx"
46
47 #include "utilities.h"
48
49 using namespace std;
50
51 //=================================================================================
52 // class    : TransformationGUI_RotationDlg()
53 // purpose  : Constructs a TransformationGUI_RotationDlg which is a child of 'parent', with the
54 //            name 'name' and widget flags set to 'f'.
55 //            The dialog will by default be modeless, unless you set 'modal' to
56 //            TRUE to construct a modal dialog.
57 //=================================================================================
58 TransformationGUI_RotationDlg::TransformationGUI_RotationDlg
59   (GeometryGUI* theGeometryGUI, QWidget* parent,  const char* name, bool modal, WFlags fl)
60   :GEOMBase_Skeleton(theGeometryGUI, parent, name, modal, WStyle_Customize |
61                      WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
62 {
63   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
64   QPixmap image0 (aResMgr->loadPixmap("GEOM",tr("ICON_DLG_ROTATION")));
65   QPixmap image1 (aResMgr->loadPixmap("GEOM",tr("ICON_SELECT")));
66   QPixmap image2 (aResMgr->loadPixmap("GEOM",tr("ICON_DLG_ROTATION_THREE_POINTS")));
67
68   setCaption(tr("GEOM_ROTATION_TITLE"));
69
70   /***************************************************************/
71   GroupConstructors->setTitle(tr("GEOM_ROTATION"));
72   RadioButton1->setPixmap(image0);
73   RadioButton2->setPixmap(image2);
74   RadioButton3->close(TRUE);
75
76   GroupPoints = new DlgRef_4Sel1Spin2Check(this, "GroupPoints");
77   GroupPoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
78   GroupPoints->TextLabel1->setText(tr("GEOM_OBJECTS"));
79   GroupPoints->TextLabel2->setText(tr("GEOM_AXIS"));
80   GroupPoints->TextLabel3->setText(tr("GEOM_ANGLE"));
81   GroupPoints->TextLabel4->setText(tr("GEOM_POINT_I").arg("1"));
82   GroupPoints->TextLabel5->setText(tr("GEOM_POINT_I").arg("2"));
83
84   GroupPoints->LineEdit1->setReadOnly(true);
85   GroupPoints->LineEdit2->setReadOnly(true);
86   GroupPoints->LineEdit4->setReadOnly(true);
87   GroupPoints->LineEdit5->setReadOnly(true);
88   GroupPoints->PushButton1->setPixmap(image1);
89   GroupPoints->PushButton2->setPixmap(image1);
90   GroupPoints->PushButton4->setPixmap(image1);
91   GroupPoints->PushButton5->setPixmap(image1);
92   GroupPoints->CheckButton1->setText(tr("GEOM_CREATE_COPY"));
93   GroupPoints->CheckButton2->setText(tr("GEOM_REVERSE"));
94
95   Layout1->addWidget(GroupPoints, 2, 0);
96   /***************************************************************/
97
98   double anAngle = 0;
99   double SpecificStep = 5;
100   /* min, max, step and decimals for spin boxes & initial values */
101   GroupPoints->SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, SpecificStep, DBL_DIGITS_DISPLAY);
102   GroupPoints->SpinBox_DX->SetValue(anAngle);
103
104   // Activate Create a Copy mode
105   GroupPoints->CheckButton1->setChecked(true);
106   CreateCopyModeChanged(true);
107
108   GroupBoxPublish->show();
109
110   /* signals and slots connections */
111   connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
112   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
113   connect(GroupConstructors, SIGNAL(clicked(int)), SLOT(ConstructorsClicked(int)));
114
115   connect(GroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
116   connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
117   connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
118   connect(GroupPoints->PushButton5, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
119
120   connect(GroupPoints->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
121   connect(GroupPoints->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
122
123   connect(GroupPoints->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
124   connect(GroupPoints->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(CreateCopyModeChanged(bool)));
125   connect(GroupPoints->CheckButton2, SIGNAL(toggled(bool)), this, SLOT(onReverse()));
126
127   connect(myGeomGUI->getApp()->selectionMgr(),
128           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
129
130   setHelpFileName("rotation_operation_page.html");
131
132   Init();
133 }
134
135
136 //=================================================================================
137 // function : ~TransformationGUI_RotationDlg()
138 // purpose  : Destroys the object and frees any allocated resources
139 //=================================================================================
140 TransformationGUI_RotationDlg::~TransformationGUI_RotationDlg()
141 {
142   // no need to delete child widgets, Qt does it all for us
143 }
144
145
146 //=================================================================================
147 // function : Init()
148 // purpose  :
149 //=================================================================================
150 void TransformationGUI_RotationDlg::Init()
151 {
152   /* init variables */
153   myEditCurrentArgument = GroupPoints->LineEdit1;
154   GroupPoints->LineEdit2->clear();
155
156   myAxis = myCentPoint = myPoint1 = myPoint2 = GEOM::GEOM_Object::_nil();
157
158   initName( tr( "GEOM_ROTATION" ) );
159   ConstructorsClicked( 0 );
160 }
161
162 //=================================================================================
163 // function : ConstructorsClicked()
164 // purpose  : Radio button management
165 //=================================================================================
166 void TransformationGUI_RotationDlg::ConstructorsClicked(int constructorId)
167 {
168   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
169
170   myEditCurrentArgument = GroupPoints->LineEdit1;
171   globalSelection();
172
173   switch (constructorId)
174     {
175     case 0: /* rotation an object angle and axis */
176       {
177         GroupPoints->ShowRows(2,3,false);
178         resize(0,0);
179         GroupPoints->TextLabel2->setText(tr("GEOM_AXIS"));
180         GroupPoints->LineEdit2->clear();
181         GroupPoints->ShowRows(4,4,true);
182         myAxis = GEOM::GEOM_Object::_nil();
183         break;
184       }
185     case 1: /* rotation an object by 3 points */
186       {
187         GroupPoints->ShowRows(4,4,false);
188         resize(0,0);
189         GroupPoints->ShowRows(2,3,true);
190         GroupPoints->TextLabel2->setText(tr("GEOM_CENTRAL_POINT"));
191         GroupPoints->TextLabel4->setText(tr("GEOM_POINT_I").arg("1"));
192         GroupPoints->TextLabel5->setText(tr("GEOM_POINT_I").arg("2"));
193         GroupPoints->LineEdit2->clear();
194         GroupPoints->LineEdit4->clear();
195         GroupPoints->LineEdit5->clear();
196         myCentPoint = myPoint1 = myPoint2 = GEOM::GEOM_Object::_nil();
197         break;
198       }
199     }
200
201   myEditCurrentArgument->setFocus();
202   connect(myGeomGUI->getApp()->selectionMgr(),
203           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
204 }
205
206 //=================================================================================
207 // function : ClickOnOk()
208 // purpose  :
209 //=================================================================================
210 void TransformationGUI_RotationDlg::ClickOnOk()
211 {
212   if ( ClickOnApply() )
213     ClickOnCancel();
214 }
215
216
217 //=================================================================================
218 // function : ClickOnApply()
219 // purpose  :
220 //=================================================================================
221 bool TransformationGUI_RotationDlg::ClickOnApply()
222 {
223   if ( !onAccept( GroupPoints->CheckButton1->isChecked()) )
224     return false;
225
226   initName();
227   ConstructorsClicked( getConstructorId() );
228   return true;
229 }
230
231
232 //=================================================================================
233 // function : SelectionIntoArgument()
234 // purpose  : Called when selection as changed or other case
235 //=================================================================================
236 void TransformationGUI_RotationDlg::SelectionIntoArgument()
237 {
238   myEditCurrentArgument->setText("");
239   QString aName;
240
241   if(myEditCurrentArgument == GroupPoints->LineEdit1)
242     {
243       int aNbSel = GEOMBase::GetNameOfSelectedIObjects(selectedIO(), aName);
244       if(aNbSel < 1)
245         {
246           myObjects.length(0);
247           return;
248         }
249       GEOMBase::ConvertListOfIOInListOfGO(selectedIO(), myObjects);
250       if (!myObjects.length())
251         return;
252     }
253   else
254     {
255       if(IObjectCount() != 1)
256         {
257           if(myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0)
258             myAxis = GEOM::GEOM_Object::_nil();
259           else if(myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 1)
260             myCentPoint  = GEOM::GEOM_Object::_nil();
261           else if(myEditCurrentArgument == GroupPoints->LineEdit4)
262             myPoint1 = GEOM::GEOM_Object::_nil();
263           else if(myEditCurrentArgument == GroupPoints->LineEdit5)
264             myPoint2 = GEOM::GEOM_Object::_nil();
265           return;
266         }
267
268       Standard_Boolean testResult = Standard_False;
269       GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(firstIObject(), testResult );
270       if(!testResult || CORBA::is_nil( aSelectedObject ))
271         return;
272
273       aName = GEOMBase::GetName( aSelectedObject );
274       TopoDS_Shape aShape;
275       if ( GEOMBase::GetShape( aSelectedObject, aShape, TopAbs_SHAPE ) && !aShape.IsNull() )
276         {
277           TopAbs_ShapeEnum aNeedType = TopAbs_VERTEX;
278           if (myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0)
279             aNeedType = TopAbs_EDGE;
280
281           LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
282           TColStd_IndexedMapOfInteger aMap;
283           aSelMgr->GetIndexes( firstIObject(), aMap );
284           if ( aMap.Extent() == 1 )
285             {
286               int anIndex = aMap( 1 );
287               if (aNeedType == TopAbs_EDGE)
288                 aName += QString(":edge_%1").arg(anIndex);
289               else
290                 aName += QString(":vertex_%1").arg(anIndex);
291
292               //Find SubShape Object in Father
293               GEOM::GEOM_Object_var aFindedObject = findObjectInFather(aSelectedObject, aName);
294
295               if ( aFindedObject == GEOM::GEOM_Object::_nil() ) { // Object not found in study
296                 GEOM::GEOM_IShapesOperations_var aShapesOp =
297                   getGeomEngine()->GetIShapesOperations( getStudyId() );
298                 aSelectedObject = aShapesOp->GetSubShape(aSelectedObject, anIndex);
299               }
300               else
301                 aSelectedObject = aFindedObject; // get Object from study
302             }
303           else {
304             if (aShape.ShapeType() != aNeedType) {
305               aSelectedObject = GEOM::GEOM_Object::_nil();
306               aName = "";
307             }
308           }
309         }
310
311       if(myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0)
312         myAxis = aSelectedObject;
313       else if(myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 1)
314         myCentPoint = aSelectedObject;
315       else if(myEditCurrentArgument == GroupPoints->LineEdit4)
316         myPoint1 = aSelectedObject;
317       else if(myEditCurrentArgument == GroupPoints->LineEdit5)
318         myPoint2 = aSelectedObject;
319
320     }
321   myEditCurrentArgument->setText( aName );
322
323   displayPreview();
324 }
325
326
327 //=================================================================================
328 // function : SetEditCurrentArgument()
329 // purpose  :
330 //=================================================================================
331 void TransformationGUI_RotationDlg::SetEditCurrentArgument()
332 {
333   QPushButton* send = (QPushButton*)sender();
334   globalSelection();
335
336   if(send == GroupPoints->PushButton1) {
337     myEditCurrentArgument = GroupPoints->LineEdit1;
338   }
339   else if(send == GroupPoints->PushButton2) {
340     myEditCurrentArgument = GroupPoints->LineEdit2;
341     if (getConstructorId() == 0)
342       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE );
343     else
344       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
345   }
346   else if (send == GroupPoints->PushButton4)
347     {
348       myEditCurrentArgument = GroupPoints->LineEdit4;
349       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
350     }
351   else if (send == GroupPoints->PushButton5)
352     {
353       myEditCurrentArgument = GroupPoints->LineEdit5;
354       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
355     }
356
357   myEditCurrentArgument->setFocus();
358   SelectionIntoArgument();
359 }
360
361
362 //=================================================================================
363 // function : LineEditReturnPressed()
364 // purpose  :
365 //=================================================================================
366 void TransformationGUI_RotationDlg::LineEditReturnPressed()
367 {
368   QLineEdit* send = (QLineEdit*)sender();
369   if(send == GroupPoints->LineEdit1 ||
370      send == GroupPoints->LineEdit2)
371     {
372       myEditCurrentArgument = send;
373       GEOMBase_Skeleton::LineEditReturnPressed();
374     }
375 }
376
377
378 //=================================================================================
379 // function : ActivateThisDialog()
380 // purpose  :
381 //=================================================================================
382 void TransformationGUI_RotationDlg::ActivateThisDialog()
383 {
384   GEOMBase_Skeleton::ActivateThisDialog();
385   connect(myGeomGUI->getApp()->selectionMgr(),
386           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
387
388   ConstructorsClicked( getConstructorId() );
389 }
390
391
392 //=================================================================================
393 // function : enterEvent()
394 // purpose  :
395 //=================================================================================
396 void TransformationGUI_RotationDlg::enterEvent(QEvent* e)
397 {
398   if (!GroupConstructors->isEnabled())
399     ActivateThisDialog();
400 }
401
402
403 //=================================================================================
404 // function : ValueChangedInSpinBox()
405 // purpose  :
406 //=================================================================================
407 void TransformationGUI_RotationDlg::ValueChangedInSpinBox()
408 {
409   displayPreview();
410 }
411
412
413 //=================================================================================
414 // function : createOperation
415 // purpose  :
416 //=================================================================================
417 GEOM::GEOM_IOperations_ptr TransformationGUI_RotationDlg::createOperation()
418 {
419   return getGeomEngine()->GetITransformOperations( getStudyId() );
420 }
421
422
423 //=================================================================================
424 // function : isValid
425 // purpose  :
426 //=================================================================================
427 bool TransformationGUI_RotationDlg::isValid( QString& msg )
428 {
429   switch (getConstructorId())
430     {
431     case 0:
432       {
433         return !(myObjects.length() == 0 || myAxis->_is_nil());
434         break;
435       }
436     case 1:
437       {
438         return !(myObjects.length() == 0 || myCentPoint->_is_nil() || myPoint1->_is_nil() || myPoint2->_is_nil() );
439         break;
440       }
441     default: return false;
442     }
443 }
444
445
446 //=================================================================================
447 // function : execute
448 // purpose  :
449 //=================================================================================
450 bool TransformationGUI_RotationDlg::execute( ObjectList& objects )
451 {
452   bool res = false;
453   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
454
455   GEOM::GEOM_Object_var anObj;
456
457   switch ( getConstructorId() )
458     {
459     case 0 :
460       {
461         if (toCreateCopy)
462           for (int i = 0; i < myObjects.length(); i++)
463             {
464               myCurrObject = myObjects[i];
465               anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
466                 RotateCopy( myObjects[i], myAxis, GetAngle() * PI180 );
467               if ( !anObj->_is_nil() )
468                 objects.push_back( anObj._retn() );
469             }
470         else
471           for (int i = 0; i < myObjects.length(); i++)
472             {
473               myCurrObject = myObjects[i];
474               anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
475                 Rotate( myObjects[i], myAxis, GetAngle() * PI180 );
476               if ( !anObj->_is_nil() )
477                 objects.push_back( anObj._retn() );
478             }
479         res = true;
480         break;
481       }
482     case 1 :
483       {
484         if (toCreateCopy)
485           for (int i = 0; i < myObjects.length(); i++)
486             {
487               myCurrObject = myObjects[i];
488               anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
489                 RotateThreePointsCopy( myObjects[i], myCentPoint, myPoint1, myPoint2 );
490               if ( !anObj->_is_nil() )
491                 objects.push_back( anObj._retn() );
492             }
493         else
494           for (int i = 0; i < myObjects.length(); i++)
495             {
496               myCurrObject = myObjects[i];
497               anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
498                 RotateThreePoints( myObjects[i], myCentPoint, myPoint1, myPoint2 );     
499               if ( !anObj->_is_nil() )
500                 objects.push_back( anObj._retn() );
501             }
502         res = true;
503         break;
504       }
505     }
506
507   return res;
508 }
509
510 //=================================================================================
511 // function : restoreSubShapes
512 // purpose  :
513 //=================================================================================
514 void TransformationGUI_RotationDlg::restoreSubShapes (SALOMEDS::Study_ptr   theStudy,
515                                                       SALOMEDS::SObject_ptr theSObject)
516 {
517   if (CheckBoxRestoreSS->isChecked()) {
518     // we pass here the first operation argument (object) through the list of arguments
519     // because the rotation operation place its arguments in the data structure in another order,
520     // and we need to point the first argument directly
521     GEOM::ListOfGO_var anArgs = new GEOM::ListOfGO;
522     anArgs->length(1);
523     anArgs[0] = myCurrObject;
524     getGeomEngine()->RestoreSubShapesSO(theStudy, theSObject, anArgs,
525                                         /*theFindMethod=*/GEOM::FSM_Transformed,
526                                         /*theInheritFirstArg=*/true);
527   }
528 }
529
530 //=================================================================================
531 // function : GetAngle()
532 // purpose  :
533 //=================================================================================
534 double TransformationGUI_RotationDlg::GetAngle() const
535 {
536   return GroupPoints->SpinBox_DX->GetValue();
537 }
538
539
540 //=================================================================================
541 // function :  CreateCopyModeChanged()
542 // purpose  :
543 //=================================================================================
544 void TransformationGUI_RotationDlg::CreateCopyModeChanged(bool isCreateCopy)
545 {
546   this->GroupBoxName->setEnabled(isCreateCopy);
547 }
548
549
550 //=================================================================================
551 // function :  onReverse()
552 // purpose  :
553 //=================================================================================
554 void TransformationGUI_RotationDlg::onReverse()
555 {
556   double anOldValue = GroupPoints->SpinBox_DX->GetValue();
557   GroupPoints->SpinBox_DX->SetValue( -anOldValue );
558 }
559
560 //=================================================================================
561 // function : addSubshapeToStudy
562 // purpose  : virtual method to add new SubObjects if local selection
563 //=================================================================================
564 void TransformationGUI_RotationDlg::addSubshapesToStudy()
565 {
566   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
567   if (toCreateCopy) {
568   QMap<QString, GEOM::GEOM_Object_var> objMap;
569   switch (getConstructorId())
570     {
571     case 0:
572       objMap[GroupPoints->LineEdit2->text()] = myAxis;
573       break;
574     case 1:
575       objMap[GroupPoints->LineEdit2->text()] = myCentPoint;
576       objMap[GroupPoints->LineEdit4->text()] = myPoint1;
577       objMap[GroupPoints->LineEdit5->text()] = myPoint2;
578       break;
579     }
580   addSubshapesToFather( objMap );
581   }
582 }