Salome HOME
d527eee7fa8d4566cafb0bc075f1c10222a29a21
[modules/geom.git] / src / MeasureGUI / MeasureGUI_DistanceDlg.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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : MeasureGUI_DistanceDlg.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : GEOM
27 //  $Header$
28
29 using namespace std;
30 #include "MeasureGUI_DistanceDlg.h"
31
32 #include "QAD_RightFrame.h"
33 #include "OCCViewer_Viewer3d.h"
34
35 #include <Geom_Plane.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <BRepExtrema_DistShapeShape.hxx>
38 #include <AIS_LengthDimension.hxx>
39 #include <BRepBuilderAPI_MakeEdge.hxx>
40 #include <BRepBuilderAPI_MakeVertex.hxx>
41 #include <AIS_ListIteratorOfListOfInteractive.hxx>
42 #include <gce_MakePln.hxx>
43 #include <Precision.hxx>
44
45 //=================================================================================
46 // class    : MeasureGUI_DistanceDlg()
47 // purpose  : Constructs a MeasureGUI_DistanceDlg which is a child of 'parent', with the 
48 //            name 'name' and widget flags set to 'f'.
49 //            The dialog will by default be modeless, unless you set 'modal' to
50 //            TRUE to construct a modal dialog.
51 //=================================================================================
52 MeasureGUI_DistanceDlg::MeasureGUI_DistanceDlg(QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl)
53   :MeasureGUI_Skeleton(parent, name, Sel, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
54 {
55   QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap("GEOM",tr("ICON_DLG_MINDIST")));
56   QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap("GEOM",tr("ICON_SELECT")));
57
58   setCaption(tr("GEOM_MINDIST_TITLE"));
59
60   /***************************************************************/
61   GroupConstructors->setTitle(tr("GEOM_DISTANCE"));
62   RadioButton1->setPixmap(image0);
63
64   GroupC1 = new MeasureGUI_2Sel1LineEdit_QTD(this, "GroupC1");
65   GroupC1->GroupBox1->setTitle(tr("GEOM_MINDIST_OBJ"));
66   GroupC1->TextLabel1->setText(tr("GEOM_OBJECT_I").arg("1"));
67   GroupC1->TextLabel2->setText(tr("GEOM_OBJECT_I").arg("2"));
68   GroupC1->TextLabel3->setText(tr("GEOM_LENGTH"));
69   GroupC1->LineEdit3->setReadOnly(TRUE);
70   GroupC1->PushButton1->setPixmap(image1);
71   GroupC1->PushButton2->setPixmap(image1);
72
73   Layout1->addWidget(GroupC1, 1, 0);
74   /***************************************************************/
75
76   /* Initialisation */
77   Init();
78 }
79
80
81 //=================================================================================
82 // function : ~MeasureGUI_DistanceDlg()
83 // purpose  : Destroys the object and frees any allocated resources
84 //=================================================================================
85 MeasureGUI_DistanceDlg::~MeasureGUI_DistanceDlg()
86 {  
87   /* no need to delete child widgets, Qt does it all for us */
88 }
89
90
91 //=================================================================================
92 // function : Init()
93 // purpose  :
94 //=================================================================================
95 void MeasureGUI_DistanceDlg::Init()
96 {
97   /* init variables */
98   myEditCurrentArgument = GroupC1->LineEdit1;
99
100   myOkShape1 = myOkShape2 = false;
101
102    /* signals and slots connections */
103   connect(buttonClose, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
104   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
105   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
106
107   connect(GroupC1->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
108   connect(GroupC1->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
109
110   connect(GroupC1->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
111   connect(GroupC1->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
112
113   connect(mySelection, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
114
115   /* displays Dialog */
116   GroupC1->show();
117   this->show();
118
119   return;
120 }
121
122
123 //=================================================================================
124 // function : ClickOnCancel()
125 // purpose  :
126 //=================================================================================
127 void MeasureGUI_DistanceDlg::ClickOnCancel()
128 {
129   this->EraseDistance();
130   MeasureGUI_Skeleton::ClickOnCancel();
131   return;
132 }
133
134
135 //=================================================================================
136 // function : SelectionIntoArgument()
137 // purpose  : Called when selection has changed
138 //=================================================================================
139 void MeasureGUI_DistanceDlg::SelectionIntoArgument()
140 {
141   myGeomBase->EraseSimulationShape();
142   mySimulationTopoDs.Nullify();
143   this->EraseDistance();
144   myEditCurrentArgument->setText("");
145   QString aString = "";
146
147   GroupC1->LineEdit3->setText("");
148
149   int nbSel = myGeomBase->GetNameOfSelectedIObjects(mySelection, aString);
150   if(nbSel != 1) {
151     if(myEditCurrentArgument == GroupC1->LineEdit1)
152       myOkShape1 = false;
153     else if(myEditCurrentArgument == GroupC1->LineEdit2)
154       myOkShape2 = false;
155     return;
156   }
157
158   /*  nbSel == 1  */
159   TopoDS_Shape S;
160   if(!myGeomBase->GetTopoFromSelection(mySelection, S))
161     return;
162
163   Standard_Boolean testResult;
164   Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject();
165   
166   if(myEditCurrentArgument == GroupC1->LineEdit1) {
167     myGeomShape1 = myGeomBase->ConvertIOinGEOMShape(IO, testResult);
168     if(!testResult)
169       return;
170     myShape1 = S;
171     myEditCurrentArgument->setText(aString);
172     myOkShape1 = true;
173   }    
174   else if(myEditCurrentArgument == GroupC1->LineEdit2) {
175     myGeomShape2 = myGeomBase->ConvertIOinGEOMShape(IO, testResult);
176     if(!testResult)
177       return;
178     myShape2 = S;
179     myEditCurrentArgument->setText(aString);
180     myOkShape2 = true;
181   }
182
183   if(myOkShape1 && myOkShape2)
184     this->MakeDistanceSimulationAndDisplay(myShape1 ,myShape2);
185   return; 
186 }
187
188
189 //=================================================================================
190 // function : SetEditCurrentArgument()
191 // purpose  :
192 //=================================================================================
193 void MeasureGUI_DistanceDlg::SetEditCurrentArgument()
194 {
195   QPushButton* send = (QPushButton*)sender();
196
197   if(send == GroupC1->PushButton1) {
198     GroupC1->LineEdit1->setFocus();
199     myEditCurrentArgument = GroupC1->LineEdit1;
200   }
201   else if(send == GroupC1->PushButton2) {
202     GroupC1->LineEdit2->setFocus();
203     myEditCurrentArgument = GroupC1->LineEdit2;
204   }
205
206   this->SelectionIntoArgument();
207   return;
208 }
209
210
211 //=================================================================================
212 // function : LineEditReturnPressed()
213 // purpose  :
214 //=================================================================================
215 void MeasureGUI_DistanceDlg::LineEditReturnPressed()
216 {
217   QLineEdit* send = (QLineEdit*)sender();
218   if(send == GroupC1->LineEdit1)
219     myEditCurrentArgument = GroupC1->LineEdit1;
220   else if(send == GroupC1->LineEdit2)
221     myEditCurrentArgument = GroupC1->LineEdit2;
222   else
223     return;
224
225   MeasureGUI_Skeleton::LineEditReturnPressed();
226   return;
227 }
228
229
230 //=================================================================================
231 // function : ActivateThisDialog()
232 // purpose  :
233 //=================================================================================
234 void MeasureGUI_DistanceDlg::ActivateThisDialog()
235 {
236   MeasureGUI_Skeleton::ActivateThisDialog();
237   connect(mySelection, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
238   if(!mySimulationTopoDs.IsNull())
239     myGeomBase->DisplaySimulationShape(mySimulationTopoDs);
240   return;
241 }
242
243
244 //=================================================================================
245 // function : enterEvent()
246 // purpose  : when mouse enter onto the QWidget
247 //=================================================================================
248 void MeasureGUI_DistanceDlg::enterEvent(QEvent* e)
249 {
250   if(GroupConstructors->isEnabled())
251     return;
252   this->ActivateThisDialog();
253   return;
254 }
255
256
257 //=================================================================================
258 // function : closeEvent()
259 // purpose  :
260 //=================================================================================
261 void MeasureGUI_DistanceDlg::closeEvent(QCloseEvent* e)
262 {
263   /* same than click on cancel button */
264   this->ClickOnCancel();
265   return;
266 }
267
268
269 //=================================================================================
270 // function : MakeDistanceSimulationAndDisplay()
271 // purpose  :
272 //=================================================================================
273 void MeasureGUI_DistanceDlg::MakeDistanceSimulationAndDisplay(const TopoDS_Shape& S1, const TopoDS_Shape& S2) 
274 {
275   myGeomBase->EraseSimulationShape();
276   mySimulationTopoDs.Nullify();
277   GroupC1->LineEdit3->setText("");
278   
279   BRepExtrema_DistShapeShape dst(S1, S2);
280
281   try {
282     if(dst.IsDone()) {
283       gp_Pnt P1, P2;
284       Standard_Real Dist = 1.e9;
285       for(int i = 1; i <= dst.NbSolution(); i++) {
286         P1 = (dst.PointOnShape1(i));
287         P2 = (dst.PointOnShape2(i));
288
289         Standard_Real MinDist = P1.Distance(P2);
290         if(Dist > MinDist)
291           Dist = MinDist;
292       }
293
294       if(Dist <= 1.e-9) {
295         BRepBuilderAPI_MakeVertex MakeVertex(P1);
296         mySimulationTopoDs = MakeVertex.Vertex();
297         myGeomBase->DisplaySimulationShape(mySimulationTopoDs);
298
299         GroupC1->LineEdit3->setText("0.0");
300       } 
301       else {
302         BRepBuilderAPI_MakeEdge MakeEdge(P1, P2);
303         mySimulationTopoDs = MakeEdge.Edge();
304
305         TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(P1);
306         TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(P2);
307
308         QString S;
309         S.sprintf("%.1f", Dist);
310
311         gp_Pnt P3;
312         P3.SetX((P1.X() + P2.X()) / 2);
313         P3.SetY((P1.Y() + P2.Y()) / 2);
314         P3.SetZ(((P1.Z() + P2.Z()) / 2) + 100);
315         gp_Vec va(P3, P1);
316         gp_Vec vb(P3, P2);
317         if(va.IsParallel(vb, Precision::Angular())) {
318           P3.SetY(((P1.Y() + P2.Y()) / 2) + 100);
319           P3.SetZ(((P1.Z() + P2.Z()) / 2));
320         }
321         gce_MakePln gce_MP(P1, P2, P3);
322         gp_Pln gp_P = gce_MP.Value();
323         Handle(Geom_Plane) P = new Geom_Plane(gp_P);
324
325         Handle(AIS_LengthDimension) Distance = new AIS_LengthDimension(V1, V2, P, Dist, TCollection_ExtendedString(strdup(S)));
326
327         GroupC1->LineEdit3->setText(S);
328
329         if(QAD_Application::getDesktop()->getActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_OCC) {
330           OCCViewer_Viewer3d* v3d = ((OCCViewer_ViewFrame*)QAD_Application::getDesktop()->getActiveStudy()->getActiveStudyFrame()->getRightFrame()->getViewFrame())->getViewer();
331           Handle (AIS_InteractiveContext) ic = v3d->getAISContext();
332           ic->Display(Distance);
333           ic->UpdateCurrentViewer();
334         }
335       }
336     }
337   }
338   catch(Standard_Failure) {
339     MESSAGE("Catch intercepted in MakeDistanceSimulationAndDisplay()");
340   }
341   return;
342 }
343
344
345 //=================================================================================
346 // function : EraseDistance()
347 // purpose  :
348 //=================================================================================
349 void MeasureGUI_DistanceDlg::EraseDistance()
350 {
351   int count = QAD_Application::getDesktop()->getActiveStudy()->getStudyFramesCount();
352   for(int i = 0; i < count; i++) {
353     if (QAD_Application::getDesktop()->getActiveStudy()->getStudyFrame(i)->getTypeView() == VIEW_OCC ) {
354       OCCViewer_Viewer3d* v3d = ((OCCViewer_ViewFrame*)QAD_Application::getDesktop()->getActiveStudy()->getStudyFrame(i)->getRightFrame()->getViewFrame())->getViewer();
355       Handle (AIS_InteractiveContext) ic = v3d->getAISContext();
356
357       AIS_ListOfInteractive L;
358       ic->DisplayedObjects(AIS_KOI_Relation, -1, L);
359       AIS_ListIteratorOfListOfInteractive ite(L);
360       while (ite.More()) {
361         ic->Remove(ite.Value());
362         ic->UpdateCurrentViewer();
363         ite.Next();
364       }
365     }
366   }
367   return;
368 }