Salome HOME
8e264045e925c4f0c7acf0503ec0d9b126d2dc60
[modules/geom.git] / src / GenerationGUI / GenerationGUI_PipeDlg.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : GenerationGUI_PipeDlg.cxx
25 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
26 //
27 #include "GenerationGUI_PipeDlg.h"
28
29 #include <DlgRef.h>
30 #include <GeometryGUI.h>
31 #include <GEOMBase.h>
32
33 #include <SUIT_Session.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SalomeApp_Application.h>
36 #include <LightApp_SelectionMgr.h>
37
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS.hxx>
40 #include <TopExp.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42 #include <TColStd_IndexedMapOfInteger.hxx>
43 #include <TColStd_MapOfInteger.hxx>
44
45 #include <GEOMImpl_Types.hxx>
46
47 //=================================================================================
48 // class    : GenerationGUI_PipeDlg()
49 // purpose  : Constructs a GenerationGUI_PipeDlg which is a child of 'parent', with the
50 //            name 'name' and widget flags set to 'f'.
51 //            The dialog will by default be modeless, unless you set 'modal' to
52 //            TRUE to construct a modal dialog.
53 //=================================================================================
54 GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
55                                               bool modal, Qt::WindowFlags fl)
56   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl)
57 {
58   QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_PIPE")));
59   QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
60   QPixmap image2 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_PIPE_BINORMAL")));
61   QPixmap image3 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_PIPE_SECTION")));
62
63   setWindowTitle(tr("GEOM_PIPE_TITLE"));
64
65   /***************************************************************/
66   mainFrame()->GroupConstructors->setTitle(tr("GEOM_PIPE"));
67   mainFrame()->RadioButton1->setIcon(image0);
68   mainFrame()->RadioButton2->setIcon(image2);
69   mainFrame()->RadioButton3->setIcon(image3);
70   // mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
71   // mainFrame()->RadioButton3->close();
72
73   GroupPoints = new DlgRef_3Sel1Check(centralWidget());
74
75   GroupPoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
76   GroupPoints->TextLabel1->setText(tr("GEOM_BASE_OBJECT"));
77   GroupPoints->TextLabel2->setText(tr("GEOM_PATH_OBJECT"));
78   GroupPoints->TextLabel3->setText(tr("GEOM_BINORMAL"));
79   GroupPoints->PushButton1->setIcon(image1);
80   GroupPoints->PushButton2->setIcon(image1);
81   GroupPoints->PushButton3->setIcon(image1);
82   GroupPoints->CheckButton1->setText(tr("GEOM_SELECT_UNPUBLISHED_EDGES"));
83
84   GroupMakePoints = new DlgRef_3Sel2Check3Spin(centralWidget());
85
86   GroupMakePoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
87   GroupMakePoints->TextLabel1->setText(tr("GEOM_BASE_OBJECT"));
88   GroupMakePoints->TextLabel2->setText(tr("GEOM_LOCATIONS"));
89   GroupMakePoints->TextLabel3->setText(tr("GEOM_PATH_OBJECT"));
90   GroupMakePoints->PushButton1->setIcon(image1);
91   GroupMakePoints->PushButton2->setIcon(image1);
92   GroupMakePoints->PushButton3->setIcon(image1);
93   GroupMakePoints->CheckBox1->setText(tr("GEOM_WITH_CONTACT"));
94   GroupMakePoints->CheckBox2->setText(tr("GEOM_WITH_CORRECTION"));
95   GroupMakePoints->SpinBox1->close();
96   GroupMakePoints->SpinBox2->close();
97   GroupMakePoints->SpinBox3->close();
98   GroupMakePoints->TextLabel4->close();
99   GroupMakePoints->TextLabel5->close();
100   GroupMakePoints->TextLabel6->close();
101
102   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
103   layout->setMargin(0); layout->setSpacing(6);
104   layout->addWidget(GroupPoints);
105   layout->addWidget(GroupMakePoints);
106   /***************************************************************/
107
108   setHelpFileName("create_extrusion_alongpath_page.html");
109
110   // Initialisation
111   Init();
112 }
113
114 //=================================================================================
115 // function : ~GenerationGUI_PipeDlg()
116 // purpose  : Destroys the object and frees any allocated resources
117 //=================================================================================
118 GenerationGUI_PipeDlg::~GenerationGUI_PipeDlg()
119 {
120   // no need to delete child widgets, Qt does it all for us
121 }
122
123 //=================================================================================
124 // function : Init()
125 // purpose  :
126 //=================================================================================
127 void GenerationGUI_PipeDlg::Init()
128 {
129   // init variables
130   GroupPoints->LineEdit1->setReadOnly(true);
131   GroupPoints->LineEdit2->setReadOnly(true);
132   GroupPoints->LineEdit3->setReadOnly(true);
133
134   GroupPoints->LineEdit1->setText("");
135   GroupPoints->LineEdit2->setText("");
136   GroupPoints->LineEdit3->setText("");
137   myPath.nullify();
138   myVec.nullify();
139
140   GroupPoints->CheckButton1->setEnabled(false);
141
142   GroupMakePoints->LineEdit1->setReadOnly(true);
143   GroupMakePoints->LineEdit2->setReadOnly(true);
144   GroupMakePoints->LineEdit3->setReadOnly(true);
145
146   GroupMakePoints->LineEdit1->setText("");
147   GroupMakePoints->LineEdit2->setText("");
148   GroupMakePoints->LineEdit3->setText("");
149
150   showOnlyPreviewControl();
151
152   // signals and slots connections
153   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
154   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
155
156   connect(this,          SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
157
158   connect(GroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
159   connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
160   connect(GroupPoints->PushButton3, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
161
162   connect(GroupPoints->CheckButton1,   SIGNAL(toggled(bool)), this, SLOT(SelectionTypeButtonClicked()));
163
164   connect(GroupMakePoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
165   connect(GroupMakePoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
166   connect(GroupMakePoints->PushButton3, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
167   connect(GroupMakePoints->CheckBox1, SIGNAL(clicked()), this, SLOT(processPreview()));
168   connect(GroupMakePoints->CheckBox2, SIGNAL(clicked()), this, SLOT(processPreview()));
169
170   initName(tr("GEOM_PIPE"));
171   resize(100,100);
172
173   GroupPoints->TextLabel3->hide();
174   GroupPoints->PushButton3->hide();
175   GroupPoints->LineEdit3->hide();
176   ConstructorsClicked(0);
177
178   GroupPoints->PushButton1->click();
179   SelectionIntoArgument();
180 }
181
182 //=================================================================================
183 // function : ConstructorsClicked()
184 // purpose  : Radio button management
185 //=================================================================================
186 void GenerationGUI_PipeDlg::ConstructorsClicked( int constructorId )
187 {
188   erasePreview();
189
190   switch (constructorId) {
191   case 0:
192     GroupMakePoints->hide();
193     GroupPoints->show();
194     GroupPoints->TextLabel3->hide();
195     GroupPoints->PushButton3->hide();
196     GroupPoints->LineEdit3->hide();
197     GroupPoints->PushButton1->click();
198     break;
199   case 1:
200     GroupMakePoints->hide();
201     GroupPoints->show();
202     GroupPoints->TextLabel3->show();
203     GroupPoints->PushButton3->show();
204     GroupPoints->LineEdit3->show();
205     GroupPoints->PushButton1->click();
206     break;
207   case 2:
208     GroupPoints->hide();
209     GroupMakePoints->show();
210     GroupMakePoints->PushButton1->click();
211     break;
212   default:
213     break;
214   }
215
216   qApp->processEvents();
217   updateGeometry();
218   resize(100,100);
219
220   SelectionIntoArgument();
221   processPreview();
222 }
223
224 //=================================================================================
225 // function : SelectionBittonClicked()
226 // purpose  : Selection type Radio button management
227 //=================================================================================
228 void GenerationGUI_PipeDlg::SelectionTypeButtonClicked()
229 {
230   globalSelection();
231   if ( GroupPoints->CheckButton1->isChecked() ) {
232     localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE );
233   } else {
234     TColStd_MapOfInteger aMap;
235     aMap.Add(GEOM_COMPOUND);
236     aMap.Add(GEOM_WIRE);
237     aMap.Add(GEOM_LINE);
238     globalSelection(aMap);
239   }
240   if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) {
241     myEditCurrentArgument->setText("");
242     myPath.nullify();
243   }
244   processPreview();
245 }
246
247 //=================================================================================
248 // function : ClickOnOk()
249 // purpose  :
250 //=================================================================================
251 void GenerationGUI_PipeDlg::ClickOnOk()
252 {
253   setIsApplyAndClose( true );
254   if (ClickOnApply())
255     ClickOnCancel();
256 }
257
258 //=================================================================================
259 // function : ClickOnApply()
260 // purpose  :
261 //=================================================================================
262 bool GenerationGUI_PipeDlg::ClickOnApply()
263 {
264   if (!onAccept())
265     return false;
266
267   initName();
268
269   return true;
270 }
271
272 //=================================================================================
273 // function : SelectionIntoArgument()
274 // purpose  : Called when selection is changed or on dialog initialization or activation
275 //=================================================================================
276 void GenerationGUI_PipeDlg::SelectionIntoArgument()
277 {
278   erasePreview();
279   myEditCurrentArgument->setText("");
280
281   if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) {
282     myBaseObjects.clear();
283     QList<GEOM::GeomObjPtr> objects = getSelected( TopAbs_SHAPE, -1 );
284     for ( int i = 0; i < objects.count(); i++ ) {
285       GEOM::shape_type stype = objects[i]->GetMaxShapeType();
286       GEOM::shape_type maxallowed = getConstructorId() == 1 ? GEOM::FACE : GEOM::SHELL;
287       GEOM::shape_type minallowed = getConstructorId() == 1 ? GEOM::EDGE : GEOM::VERTEX;
288       if ( stype < maxallowed || stype > minallowed )
289         continue;
290       myBaseObjects << objects[i];
291     }
292     if ( !myBaseObjects.isEmpty() ) {
293       QString aName = myBaseObjects.count() > 1 ? QString( "%1_objects").arg( myBaseObjects.count() ) : GEOMBase::GetName( myBaseObjects[0].get() );
294       myEditCurrentArgument->setText( aName );
295     }
296   }
297   else if (myEditCurrentArgument == GroupPoints->LineEdit2) {
298     QList<TopAbs_ShapeEnum> types;
299     types << TopAbs_EDGE << TopAbs_WIRE;
300     myPath = getSelected( types );
301     if ( myPath ) {
302       QString aName = GEOMBase::GetName( myPath.get() );
303       myEditCurrentArgument->setText( aName );
304       if ( getConstructorId() == 1 && !myVec )
305         GroupPoints->PushButton3->click();
306       else if ( myBaseObjects.isEmpty() )
307         GroupPoints->PushButton1->click();
308     }
309   }
310   else if (myEditCurrentArgument == GroupPoints->LineEdit3) {
311     myVec = getSelected( TopAbs_EDGE );
312     if ( myVec ) {
313       QString aName = GEOMBase::GetName( myVec.get() );
314       myEditCurrentArgument->setText( aName );
315       if ( myBaseObjects.isEmpty() )
316         GroupPoints->PushButton1->click();
317       else if ( !myPath )
318         GroupPoints->PushButton2->click();
319     }
320   }
321   else if ( myEditCurrentArgument == GroupMakePoints->LineEdit1 ) {
322     myBaseObjects.clear();
323     QList<TopAbs_ShapeEnum> types;
324     types << TopAbs_EDGE << TopAbs_WIRE << TopAbs_FACE << TopAbs_SHELL;
325     QList<GEOM::GeomObjPtr> objects = getSelected( types, -1 );
326     GEOMBase::Synchronize( myBaseObjects, objects );
327     if ( !myBaseObjects.isEmpty() ) {
328       QString aName = myBaseObjects.count() > 1 ? QString( "%1_objects").arg( myBaseObjects.count() ) : GEOMBase::GetName( myBaseObjects[0].get() );
329       myEditCurrentArgument->setText( aName );
330     }
331   }
332   else if ( myEditCurrentArgument == GroupMakePoints->LineEdit2 ) {
333     myLocations.clear();
334     localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
335     QList<GEOM::GeomObjPtr> objects = getSelected( TopAbs_VERTEX, -1 );
336     GEOMBase::Synchronize( myLocations, objects );
337     if ( !myLocations.isEmpty() ) {
338       QString aName = myLocations.count() > 1 ? QString( "%1_objects").arg( myLocations.count() ) : GEOMBase::GetName( myLocations[0].get() );
339       myEditCurrentArgument->setText( aName );
340     }
341   }
342   else if ( myEditCurrentArgument == GroupMakePoints->LineEdit3 ) {
343     QList<TopAbs_ShapeEnum> types;
344     types << TopAbs_EDGE << TopAbs_WIRE;
345     myPath = getSelected( types );
346     if ( myPath ) {
347       QString aName = GEOMBase::GetName( myPath.get() );
348       myEditCurrentArgument->setText( aName );
349     }
350   }
351
352   processPreview();
353 }
354
355 //=================================================================================
356 // function : SetEditCurrentArgument()
357 // purpose  :
358 //=================================================================================
359 void GenerationGUI_PipeDlg::SetEditCurrentArgument()
360 {
361   QPushButton* send = (QPushButton*)sender();
362
363   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
364   globalSelection(GEOM_ALLSHAPES);
365   GroupPoints->PushButton1->setDown(false);
366   GroupPoints->PushButton2->setDown(false);
367   GroupPoints->PushButton3->setDown(false);
368   GroupPoints->LineEdit1->setEnabled(false);
369   GroupPoints->LineEdit2->setEnabled(false);
370   GroupPoints->LineEdit3->setEnabled(false);
371   if (send == GroupPoints->PushButton1) {
372     myEditCurrentArgument = GroupPoints->LineEdit1;
373     GroupPoints->CheckButton1->setEnabled(false);
374   }
375   else if (send == GroupPoints->PushButton2) {
376     myEditCurrentArgument = GroupPoints->LineEdit2;
377
378     if ( GroupPoints->CheckButton1->isChecked() ) {
379       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE );
380     } else {
381       TColStd_MapOfInteger aMap;
382       aMap.Add(GEOM_COMPOUND);
383       aMap.Add(GEOM_WIRE);
384       aMap.Add(GEOM_LINE);
385       globalSelection(aMap);
386     }
387     GroupPoints->CheckButton1->setEnabled(true);
388   }
389   else if(send == GroupPoints->PushButton3) {
390     myEditCurrentArgument = GroupPoints->LineEdit3;
391     GroupPoints->CheckButton1->setEnabled(false);
392     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE);
393   }
394
395   GroupMakePoints->PushButton1->setDown(false);
396   GroupMakePoints->PushButton2->setDown(false);
397   GroupMakePoints->PushButton3->setDown(false);
398   GroupMakePoints->LineEdit1->setEnabled(false);
399   GroupMakePoints->LineEdit2->setEnabled(false);
400   GroupMakePoints->LineEdit3->setEnabled(false);
401   if (send == GroupMakePoints->PushButton1) {
402     myEditCurrentArgument = GroupMakePoints->LineEdit1;
403   }
404   else if(send == GroupMakePoints->PushButton2) {
405     myEditCurrentArgument = GroupMakePoints->LineEdit2;
406   }
407   else if (send == GroupMakePoints->PushButton3) {
408     myEditCurrentArgument = GroupMakePoints->LineEdit3;
409   }
410
411   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
412           this, SLOT(SelectionIntoArgument()));
413
414   // enable line edit
415   myEditCurrentArgument->setEnabled(true);
416   myEditCurrentArgument->setFocus();
417   // after setFocus(), because it will be setDown(false) when loses focus
418   send->setDown(true);
419
420   // seems we need it only to avoid preview disappearing, caused by selection mode change
421   processPreview();
422 }
423
424 //=================================================================================
425 // function : ActivateThisDialog()
426 // purpose  :
427 //=================================================================================
428 void GenerationGUI_PipeDlg::ActivateThisDialog()
429 {
430   GEOMBase_Skeleton::ActivateThisDialog();
431   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
432            this, SLOT( SelectionIntoArgument() ) );
433
434   ConstructorsClicked(getConstructorId());
435 }
436
437 //=================================================================================
438 // function : enterEvent()
439 // purpose  : when mouse enter onto the QWidget
440 //=================================================================================
441 void GenerationGUI_PipeDlg::enterEvent (QEvent*)
442 {
443   if (!mainFrame()->GroupConstructors->isEnabled())
444     ActivateThisDialog();
445 }
446
447 //=================================================================================
448 // function : createOperation
449 // purpose  :
450 //=================================================================================
451 GEOM::GEOM_IOperations_ptr GenerationGUI_PipeDlg::createOperation()
452 {
453   return getGeomEngine()->GetI3DPrimOperations(getStudyId());
454 }
455
456 //=================================================================================
457 // function : isValid
458 // purpose  :
459 //=================================================================================
460 bool GenerationGUI_PipeDlg::isValid (QString&)
461 {
462   bool ok = false;
463   switch ( getConstructorId() ) {
464   case 0 :
465     ok = !myBaseObjects.isEmpty() && myPath;
466     break;
467   case 1 :
468     ok = !myBaseObjects.isEmpty() && myPath && myVec;
469     break;
470   case 2 :
471     ok = !myBaseObjects.isEmpty() && ( myLocations.isEmpty() || myBaseObjects.count() == myLocations.count() ) && myPath;
472     break;
473   default:
474     break;
475   }
476   return ok;
477 }
478
479 //=================================================================================
480 // function : execute
481 // purpose  :
482 //=================================================================================
483 bool GenerationGUI_PipeDlg::execute (ObjectList& objects)
484 {
485   GEOM::GEOM_Object_var anObj;
486
487   GEOM::GEOM_I3DPrimOperations_var anOper = GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
488   switch( getConstructorId() ) {
489   case 0:
490   case 1:
491     for (int i = 0; i < myBaseObjects.count(); i++) {
492       switch ( getConstructorId() ) {
493       case 0 :
494         anObj = anOper->MakePipe(myBaseObjects[i].get(), myPath.get());
495         break;
496       case 1 :
497         anObj = anOper->MakePipeBiNormalAlongVector(myBaseObjects[i].get(), myPath.get(), myVec.get());
498         break;
499       }
500     
501       if (!anObj->_is_nil())
502         objects.push_back(anObj._retn());
503     }
504     break;
505   case 2:
506     {
507       GEOM::ListOfGO_var myBaseGO = new GEOM::ListOfGO();
508       GEOM::ListOfGO_var myLocationsGO = new GEOM::ListOfGO();
509       myBaseGO->length( myBaseObjects.count() );
510       myLocationsGO->length( myLocations.count() );
511       for (int i = 0; i < myBaseObjects.count(); i++) {
512         myBaseGO[i] = myBaseObjects[i].copy();
513       }
514       for (int i = 0; i < myLocations.count(); i++) {
515         myLocationsGO[i] = myLocations[i].copy();
516       }
517       
518       anObj = anOper->MakePipeWithDifferentSections(myBaseGO.in(), myLocationsGO.in(), myPath.get(), 
519                                                     GroupMakePoints->CheckBox1->isChecked(), 
520                                                     GroupMakePoints->CheckBox2->isChecked());
521       if (!anObj->_is_nil())
522         objects.push_back(anObj._retn());
523     }
524     break;
525   default:
526     break;
527   }
528   return true;
529 }
530
531 //=================================================================================
532 // function : addSubshapeToStudy
533 // purpose  : virtual method to add new SubObjects if local selection
534 //=================================================================================
535 void GenerationGUI_PipeDlg::addSubshapesToStudy()
536 {
537   GEOMBase::PublishSubObject( myPath.get() );
538   GEOMBase::PublishSubObject( myVec.get() );
539 }
540
541 //=================================================================================
542 // function : extractPrefix
543 // purpose  : redefined from GEOMBase_Helper class
544 //=================================================================================
545 bool GenerationGUI_PipeDlg::extractPrefix() const
546 {
547   return myBaseObjects.count() > 1;
548 }