GEMC  2.3
Geant4 Monte-Carlo Framework
camera_control.cc
Go to the documentation of this file.
1 // Qt headers
2 #include <QtWidgets>
3 
4 // windows.h and gl.h in windows
5 #ifdef _MSC_VER
6  #include <windows.h>
7  #include <gl.h>
8 #endif
9 
10 
11 // gemc headers
12 #include "camera_control.h"
13 #include "string_utilities.h"
14 
15 // C++ headers
16 
18 {
19  gemcOpt = Opts;
20  UImanager = G4UImanager::GetUIpointer();
21 
22 
23  QGroupBox *anglesGroup = new QGroupBox(tr("Camera Control"));
24  anglesGroup->setMinimumWidth(450);
25 
26  // move camera or detector
27  QLabel *moveLabel = new QLabel(tr("Move:"));
28  moveCombo = new QComboBox;
29  moveCombo->addItem(tr("Light"));
30  moveCombo->addItem(tr("Detector"));
31 
32 
33  // projection: Orthogonal / Perspective
34  QLabel *projLabel = new QLabel(tr("Projection:"));
35  projCombo = new QComboBox;
36  projCombo->addItem(tr("Orthogonal"));
37  projCombo->addItem(tr("Perspective 30"));
38  projCombo->addItem(tr("Perspective 45"));
39  projCombo->addItem(tr("Perspective 60"));
40  connect ( projCombo , SIGNAL( currentIndexChanged (int) ), this, SLOT( set_perspective(int) ) );
41 
42  QHBoxLayout *mpLayout = new QHBoxLayout;
43  mpLayout->addWidget(moveLabel);
44  mpLayout->addWidget(moveCombo);
45  mpLayout->addSpacing(100);
46  mpLayout->addWidget(projLabel);
47  mpLayout->addWidget(projCombo);
48 
49  theta_hall = phi_hall = 0; // initial angles
50 
51  // Theta Controls
52  QLabel *thetaLabel = new QLabel(tr("theta"));
53  theta_slider = new QSlider(Qt::Horizontal);
54  theta_slider->setTickInterval(1);
55  theta_slider->setRange(0, 180);
56 
57  QLCDNumber *Theta_LCD = new QLCDNumber(this);
58  Theta_LCD->setFont(QFont("Helvetica", 32, QFont::Bold));
59  Theta_LCD->setMaximumSize(45, 45);
60  Theta_LCD->setSegmentStyle(QLCDNumber::Flat);
61  for(int t=0; t<=180; t+=30)
62  {
63  char tmp[100];
64  sprintf(tmp, "%d", t);
65  ThetaSet.push_back(tmp);
66  }
67 
68  QComboBox *ThetaCombo = new QComboBox;
69  for(unsigned int i=0; i<ThetaSet.size(); i++) ThetaCombo->addItem(tr(ThetaSet[i].c_str()));
70  ThetaCombo->setMaximumSize(60, 45);
71  QHBoxLayout *thetaLayout = new QHBoxLayout;
72  thetaLayout->addWidget(thetaLabel);
73  thetaLayout->addWidget(theta_slider);
74  thetaLayout->addWidget(Theta_LCD);
75  thetaLayout->addWidget(ThetaCombo);
76 
77  connect ( theta_slider , SIGNAL( valueChanged (int) ), this, SLOT( change_theta(int) ) );
78  connect ( theta_slider , SIGNAL( valueChanged (int) ), Theta_LCD, SLOT( display(int) ) );
79  connect ( ThetaCombo , SIGNAL( currentIndexChanged (int) ), this, SLOT( set_theta(int) ) );
80  connect ( ThetaCombo , SIGNAL( currentIndexChanged (int) ), this, SLOT( change_theta_s(int) ) );
81 
82  // Phi Controls
83  QLabel *phiLabel = new QLabel(tr("phi"));
84  phi_slider = new QSlider(Qt::Horizontal);
85  phi_slider->setTickInterval(1);
86  phi_slider->setRange(0, 360);
87  QLCDNumber *Phi_LCD = new QLCDNumber(this);
88  Phi_LCD->setFont(QFont("Helvetica", 32, QFont::Bold));
89  Phi_LCD->setMaximumSize(45, 45);
90  Phi_LCD->setSegmentStyle(QLCDNumber::Flat);
91  for(int t=0; t<=360; t+=30)
92  {
93  char tmp[100];
94  sprintf(tmp, "%d", t);
95  PhiSet.push_back(tmp);
96  }
97  QComboBox *PhiCombo = new QComboBox;
98  for(unsigned int i=0; i<PhiSet.size(); i++) PhiCombo->addItem(tr(PhiSet[i].c_str()));
99  PhiCombo->setMaximumSize(60, 45);
100  QHBoxLayout *phiLayout = new QHBoxLayout;
101  phiLayout->addWidget(phiLabel);
102  phiLayout->addWidget(phi_slider);
103  phiLayout->addWidget(Phi_LCD);
104  phiLayout->addWidget(PhiCombo);
105 
106  connect ( phi_slider , SIGNAL( valueChanged (int) ), this, SLOT( change_phi(int) ) );
107  connect ( phi_slider , SIGNAL( valueChanged (int) ), Phi_LCD, SLOT( display(int) ) );
108  connect ( PhiCombo , SIGNAL( currentIndexChanged (int) ), this, SLOT( set_phi(int) ) );
109  connect ( PhiCombo , SIGNAL( currentIndexChanged (int) ), this, SLOT( change_phi_s(int) ) );
110 
111  QVBoxLayout *anglesLayout = new QVBoxLayout;
112  anglesLayout->addLayout(mpLayout);
113  anglesLayout->addSpacing(12);
114  anglesLayout->addLayout(thetaLayout);
115  anglesLayout->addSpacing(2);
116  anglesLayout->addLayout(phiLayout);
117  anglesGroup->setLayout(anglesLayout);
118 
119 
120 
121 
122 
123  // x slice
124  sliceXEdit = new QLineEdit(tr("0"));
125  sliceXEdit->setMaximumWidth(100);
126 
127  sliceXActi = new QCheckBox(tr("&Active: "));
128  sliceXActi->setChecked(false);
129 
130  sliceXInve = new QCheckBox(tr("&Invert: "));
131  sliceXInve->setChecked(false);
132 
133  QHBoxLayout *sliceXLayout = new QHBoxLayout;
134  sliceXLayout->addWidget(new QLabel(tr("X: ")));
135  sliceXLayout->addWidget(sliceXEdit);
136  sliceXLayout->addStretch(1);
137  sliceXLayout->addWidget(sliceXActi);
138  sliceXLayout->addWidget(sliceXInve);
139  sliceXLayout->addStretch(1);
140 
141 
142  // y slice
143  sliceYEdit = new QLineEdit(tr("0"));
144  sliceYEdit->setMaximumWidth(100);
145 
146  sliceYActi = new QCheckBox(tr("&Active: "));
147  sliceYActi->setChecked(false);
148 
149  sliceYInve = new QCheckBox(tr("&Invert: "));
150  sliceYInve->setChecked(false);
151 
152  QHBoxLayout *sliceYLayout = new QHBoxLayout;
153  sliceYLayout->addWidget(new QLabel(tr("Y: ")));
154  sliceYLayout->addWidget(sliceYEdit);
155  sliceYLayout->addStretch(1);
156  sliceYLayout->addWidget(sliceYActi);
157  sliceYLayout->addWidget(sliceYInve);
158  sliceYLayout->addStretch(1);
159 
160 
161 
162  // z slice
163  sliceZEdit = new QLineEdit(tr("0"));
164  sliceZEdit->setMaximumWidth(100);
165 
166  sliceZActi = new QCheckBox(tr("&Active: "));
167  sliceZActi->setChecked(false);
168 
169  sliceZInve = new QCheckBox(tr("&Invert: "));
170  sliceZInve->setChecked(false);
171 
172  QHBoxLayout *sliceZLayout = new QHBoxLayout;
173  sliceZLayout->addWidget(new QLabel(tr("Z: ")));
174  sliceZLayout->addWidget(sliceZEdit);
175  sliceZLayout->addStretch(1);
176  sliceZLayout->addWidget(sliceZActi);
177  sliceZLayout->addWidget(sliceZInve);
178  sliceZLayout->addStretch(1);
179 
180 
181  connect ( sliceXEdit , SIGNAL( textChanged(const QString &) ), this, SLOT( slice() ) );
182  connect ( sliceYEdit , SIGNAL( textChanged(const QString &) ), this, SLOT( slice() ) );
183  connect ( sliceZEdit , SIGNAL( textChanged(const QString &) ), this, SLOT( slice() ) );
184 
185  connect ( sliceXActi , SIGNAL( stateChanged(int) ), this, SLOT( slice() ) );
186  connect ( sliceYActi , SIGNAL( stateChanged(int) ), this, SLOT( slice() ) );
187  connect ( sliceZActi , SIGNAL( stateChanged(int) ), this, SLOT( slice() ) );
188 
189 
190  QPushButton *clearSliceButton = new QPushButton(tr("Clear Slices"));
191  clearSliceButton->setToolTip("Clear Slice Planes");
192  clearSliceButton->setIcon(style()->standardIcon(QStyle::SP_DialogResetButton));
193  connect ( clearSliceButton , SIGNAL(clicked()), this, SLOT( clearSlice() ) );
194 
195 
196  // slices layout
197  QVBoxLayout *sliceLayout = new QVBoxLayout;
198  sliceLayout->addLayout(sliceXLayout);
199  sliceLayout->addLayout(sliceYLayout);
200  sliceLayout->addLayout(sliceZLayout);
201  sliceLayout->addWidget(clearSliceButton);
202 
203  // slices group
204  QGroupBox *sliceGroup = new QGroupBox(tr("Slices [mm]"));
205  sliceGroup->setLayout(sliceLayout);
206 
207 
208 
209  QLabel *antialiasingLabel = new QLabel(tr("Anti-Aliasing"));
210  aliasing = new QComboBox;
211  aliasing->addItem(tr("OFF"));
212  aliasing->addItem(tr("ON"));
213  QHBoxLayout *aliasingLayout = new QHBoxLayout;
214  aliasingLayout->addWidget(antialiasingLabel);
215  aliasingLayout->addWidget(aliasing);
216  connect ( aliasing , SIGNAL( currentIndexChanged (int) ), this, SLOT( switch_antialiasing(int) ) );
217 
218  QLabel *sides_per_circlesLabel = new QLabel(tr("Sides per circle"));
219  sides_per_circle = new QComboBox;
220  sides_per_circle->addItem(tr("25"));
221  sides_per_circle->addItem(tr("50"));
222  sides_per_circle->addItem(tr("100"));
223  sides_per_circle->addItem(tr("200"));
224  sides_per_circle->setCurrentIndex(0);
225  QHBoxLayout *sides_per_circleLayout = new QHBoxLayout;
226  sides_per_circleLayout->addWidget(sides_per_circlesLabel);
227  sides_per_circleLayout->addWidget(sides_per_circle);
228  connect ( sides_per_circle , SIGNAL( currentIndexChanged (int) ), this, SLOT( switch_sides_per_circle(int) ) );
229 
230  QLabel *auxiliaryEdgesLabel = new QLabel(tr("Auxiliary Edges"));
231  auxiliary = new QComboBox;
232  auxiliary->addItem(tr("OFF"));
233  auxiliary->addItem(tr("ON"));
234  QHBoxLayout *auxedgesLayout = new QHBoxLayout;
235  auxedgesLayout->addWidget(auxiliaryEdgesLabel);
236  auxedgesLayout->addWidget(auxiliary);
237  connect ( auxiliary , SIGNAL( currentIndexChanged (int) ), this, SLOT( switch_auxiliary_edges(int) ) );
238 
239  QVBoxLayout *voptionsLayout = new QVBoxLayout;
240  voptionsLayout->addLayout(aliasingLayout);
241  voptionsLayout->addLayout(sides_per_circleLayout);
242  voptionsLayout->addLayout(auxedgesLayout);
243 
244  // options group
245  QGroupBox *vOptionsGroup = new QGroupBox(tr("Visualization Options"));
246  vOptionsGroup->setLayout(voptionsLayout);
247 
248 
249  QHBoxLayout *sliceOptionsLayout = new QHBoxLayout;
250  sliceOptionsLayout->addWidget(sliceGroup);
251  sliceOptionsLayout->addWidget(vOptionsGroup);
252 
253 
254  // Explode Controls
255  // slider is from 1 to 2.5 in intervals of 0.05 (30 total)
256  explodeSlider = new QSlider(Qt::Horizontal);
257  explodeSlider->setTickInterval(1);
258  explodeSlider->setRange(0, 30);
259  connect ( explodeSlider , SIGNAL( valueChanged(int) ), this, SLOT( explode(int) ) );
260 
261  QPushButton *screenShotPNG = new QPushButton(tr("PNG"));
262  screenShotPNG->setToolTip("Print a screenshot to a PNG file");
263  screenShotPNG->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
264  connect ( screenShotPNG , SIGNAL(clicked()), this, SLOT( printPNG() ));
265 
266  QPushButton *screenShotEPS = new QPushButton(tr("EPS"));
267  screenShotEPS->setToolTip("Print a screenshot to a encapsulated poscript file");
268  screenShotEPS->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
269  connect ( screenShotEPS , SIGNAL(clicked()), this, SLOT( printEPS() ));
270 
271  QPushButton *screenShotPDF = new QPushButton(tr("PDF"));
272  screenShotPDF->setToolTip("Print a screenshot to PDF");
273  screenShotPDF->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
274  connect ( screenShotPDF , SIGNAL(clicked()), this, SLOT( printPDF() ));
275 
276 
277  QHBoxLayout *explodeLayout = new QHBoxLayout;
278  explodeLayout->addWidget(explodeSlider);
279  explodeLayout->addWidget(screenShotPNG);
280  explodeLayout->addWidget(screenShotPDF);
281  explodeLayout->addWidget(screenShotEPS);
282 
283  QGroupBox *explodeGroup = new QGroupBox(tr("Explode"));
284  explodeGroup->setLayout(explodeLayout);
285 
286 
287 
288  // All together
289  QVBoxLayout *mainLayout = new QVBoxLayout;
290  mainLayout->addWidget(anglesGroup);
291  mainLayout->addLayout(sliceOptionsLayout);
292  mainLayout->addSpacing(6);
293  mainLayout->addWidget(explodeGroup);
294  mainLayout->addStretch(1);
295  setLayout(mainLayout);
296 
297 
298 
299 }
300 
301 
302 void camera_control::printPNG()
303 {
304  char command[100];
305  sprintf(command, "/vis/ogl/export gemc.png");
306  UImanager->ApplyCommand(command);
307 }
308 
309 
310 void camera_control::printEPS()
311 {
312  char command[100];
313  sprintf(command, "/vis/ogl/set/printMode vectored");
314  UImanager->ApplyCommand(command);
315  sprintf(command, "/vis/ogl/printEPS");
316  UImanager->ApplyCommand(command);
317 }
318 
319 void camera_control::printPDF()
320 {
321  char command[100];
322  sprintf(command, "/vis/ogl/export gemc.pdf");
323  UImanager->ApplyCommand(command);
324 }
325 
326 
327 
328 void camera_control::slice()
329 {
330  // can't have a mix of wireframe / solid when doing a slice.
331  // forcing all to be solid
332  UImanager->ApplyCommand("/vis/geometry/set/forceSolid all -1 1");
333 
334 
335  UImanager->ApplyCommand("/vis/viewer/clearCutawayPlanes");
336 
337  UImanager->ApplyCommand("/vis/viewer/set/cutawayMode intersection");
338 
339  char command[200] = "";
340 
341  if(sliceXActi->isChecked() )
342  {
343  sprintf(command, "/vis/viewer/addCutawayPlane %d 0 0 mm %d 0 0 ", (int) qs_toDouble(sliceXEdit->text()), sliceXInve->isChecked() ? -1 : 1 );
344  UImanager->ApplyCommand(command);
345  }
346  if(sliceYActi->isChecked() )
347  {
348  sprintf(command, "/vis/viewer/addCutawayPlane 0 %d 0 mm 0 %d 0 ", (int) qs_toDouble(sliceYEdit->text()), sliceYInve->isChecked() ? -1 : 1);
349  UImanager->ApplyCommand(command);
350  }
351  if(sliceZActi->isChecked() )
352  {
353  sprintf(command, "/vis/viewer/addCutawayPlane 0 0 %d mm 0 0 %d ", (int) qs_toDouble(sliceZEdit->text()), sliceZInve->isChecked() ? -1 : 1);
354  UImanager->ApplyCommand(command);
355  }
356 
357 
358 
359 }
360 
361 
362 
363 
364 void camera_control::clearSlice()
365 {
366  UImanager->ApplyCommand("/vis/viewer/clearCutawayPlanes");
367 
368  sliceXActi->setChecked(false);
369  sliceYActi->setChecked(false);
370  sliceZActi->setChecked(false);
371 
372 
373 }
374 
375 
376 void camera_control::change_theta(int theta)
377 {
378  char command[100];
379  theta_hall = theta - 1;
380 
381  if(qs_tostring(moveCombo->currentText()) == "Detector")
382  sprintf(command,"/vis/viewer/set/viewpointThetaPhi %d %d.", theta_hall, phi_hall);
383 
384  if(qs_tostring(moveCombo->currentText()) == "Light")
385  sprintf(command,"/vis/viewer/set/lightsThetaPhi %d %d.", theta_hall, phi_hall);
386 
387  UImanager->ApplyCommand(command);
388 }
389 
390 void camera_control::set_theta(int index)
391 {
392  char command[100];
393  theta_hall = atoi(ThetaSet[index].c_str());
394  sprintf(command,"/vis/viewer/set/viewpointThetaPhi %d %d.", theta_hall, phi_hall);
395  UImanager->ApplyCommand(command);
396 }
397 
398 void camera_control::change_theta_s(int theta)
399 {
400  theta_slider->setSliderPosition(atoi(ThetaSet[theta].c_str()));
401 }
402 
403 void camera_control::change_phi(int phi)
404 {
405  char command[100];
406  phi_hall = phi - 1;
407 
408 
409  if(qs_tostring(moveCombo->currentText()) == "Detector")
410  sprintf(command,"/vis/viewer/set/viewpointThetaPhi %d %d", theta_hall, phi_hall);
411 
412  if(qs_tostring(moveCombo->currentText()) == "Light")
413  sprintf(command,"/vis/viewer/set/lightsThetaPhi %d %d.", theta_hall, phi_hall);
414 
415  UImanager->ApplyCommand(command);
416 }
417 
418 void camera_control::change_phi_s(int phi)
419 {
420  phi_slider->setSliderPosition(atoi(PhiSet[phi].c_str()));
421 }
422 
423 void camera_control::set_phi(int index)
424 {
425  char command[100];
426  phi_hall = atoi(PhiSet[index].c_str());
427  sprintf(command,"/vis/viewer/set/viewpointThetaPhi %d %d.", theta_hall, phi_hall);
428  UImanager->ApplyCommand(command);
429 }
430 
431 
432 void camera_control::explode(int boom)
433 {
434  char command[100];
435 
436  double xf = 1 + ((double) boom)/15.0;
437 
438  sprintf(command,"/vis/viewer/set/explodeFactor %3.2f", xf);
439 
440  UImanager->ApplyCommand(command);
441 }
442 
443 void camera_control::set_perspective(int index)
444 {
445  char command[100];
446  double angles[4] = { 0, 30, 45, 60};
447  string which[4] = {"o", "p", "p", "p"};
448 
449  sprintf(command,"/vis/viewer/set/projection %s %4.2f ",which[index].c_str(), angles[index]);
450  UImanager->ApplyCommand(command);
451 }
452 
453 void camera_control::switch_antialiasing(int index)
454 {
455  if(index == 0)
456  {
457  glDisable (GL_LINE_SMOOTH);
458  glDisable (GL_POLYGON_SMOOTH);
459  }
460  else
461  {
462  glEnable (GL_LINE_SMOOTH);
463  glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
464  glEnable (GL_POLYGON_SMOOTH);
465  glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
466  }
467  UImanager->ApplyCommand("/vis/viewer/flush");
468 }
469 
470 void camera_control::switch_auxiliary_edges(int index)
471 {
472  if(index == 0)
473  {
474  UImanager->ApplyCommand("/vis/viewer/set/auxiliaryEdge 0");
475  UImanager->ApplyCommand("/vis/viewer/set/hiddenEdge 0");
476  }
477  else
478  {
479  UImanager->ApplyCommand("/vis/viewer/set/auxiliaryEdge 1");
480  UImanager->ApplyCommand("/vis/viewer/set/hiddenEdge 1");
481  }
482  UImanager->ApplyCommand("/vis/viewer/flush");
483 }
484 
485 void camera_control::switch_sides_per_circle(int index)
486 {
487  char command[100];
488  int sides[4] = { 25, 50, 100, 200};
489 
490  sprintf(command,"/vis/viewer/set/lineSegmentsPerCircle %d ", sides[index]);
491  UImanager->ApplyCommand(command);
492  UImanager->ApplyCommand("/vis/viewer/flush");
493 }
494 
495 
496 void camera_control::update_angles()
497 {
498 // G4VViewer* currentViewer = visManager->GetCurrentViewer();
499 // theta_hall = (int) floor(currentViewer->GetViewParameters().GetViewpointDirection().getTheta()/deg);
500 // phi_hall = (int) floor(currentViewer->GetViewParameters().GetViewpointDirection().getPhi()/deg );
501 // TransfSli[0]->setSliderPosition ( theta_hall + 1);
502 // TransfSli[1]->setSliderPosition ( phi_hall + 1);
503 }
504 
505 
507 {
508  string hd_msg = gemcOpt->optMap["LOG_MSG"].args ;
509  double VERB = gemcOpt->optMap["GEO_VERBOSITY"].arg ;
510  if(VERB>2)
511  cout << hd_msg << " Camera Control Widget Deleted." << endl;
512 
513 }
514 
515 
G4UImanager * UImanager
goptions * gemcOpt
double qs_toDouble(QString input)
map< string, aopt > optMap
Options map.
Definition: options.h:75
string qs_tostring(QString input)
camera_control(QWidget *parent, goptions *)