g4display
Loading...
Searching...
No Matches
g4displayview.cc
Go to the documentation of this file.
1#include "g4displayview.h"
2#include "g4display_options.h"
3#include "gutilities.h"
4
5using namespace g4display;
6
7#include <iostream>
8#include <string>
9
10using namespace std;
11using namespace gutilities;
12
24G4DisplayView::G4DisplayView(const std::shared_ptr<GOptions>& gopts, std::shared_ptr<GLogger> logger, QWidget* parent) : QWidget(parent), log(logger) {
25 log->debug(CONSTRUCTOR, "G4DisplayView");
26
27 G4Camera jcamera = getG4Camera(gopts);
28
29 double thetaValue = getG4Number(jcamera.theta);
30 double phiValue = getG4Number(jcamera.phi);
31
32 vector<string> toggle_button_titles;
33 toggle_button_titles.emplace_back("Hidden\nLines");
34 toggle_button_titles.emplace_back("Anti\nAliasing");
35 toggle_button_titles.emplace_back("Auxiliary\nEdges");
36 toggle_button_titles.emplace_back("Field\nLines");
37
38
39 buttons_set1 = new GQTToggleButtonWidget(80, 80, 20, toggle_button_titles, false, this);
40 connect(buttons_set1, &GQTToggleButtonWidget::buttonPressedIndexChanged, this, &G4DisplayView::apply_buttons_set1);
41
42 // Camera sliders
43 cameraTheta = new QSlider(Qt::Horizontal);
44 cameraTheta->setRange(0, 180);
45 cameraTheta->setSingleStep(1);
46 cameraTheta->setValue(thetaValue);
47 auto cameraThetaLabel = new QLabel(tr("θ"));
48
49 auto cameraThetaLayout = new QHBoxLayout;
50 cameraThetaLayout->addWidget(cameraThetaLabel);
51 cameraThetaLayout->addWidget(cameraTheta);
52
53 cameraPhi = new QSlider(Qt::Horizontal);
54 cameraPhi->setRange(0, 360);
55 cameraPhi->setSingleStep(1);
56 cameraPhi->setValue(phiValue);
57 auto cameraPhiLabel = new QLabel(tr("ɸ"));
58
59 auto cameraPhiLayout = new QHBoxLayout;
60 cameraPhiLayout->addWidget(cameraPhiLabel);
61 cameraPhiLayout->addWidget(cameraPhi);
62
63 QVBoxLayout* cameraDirectionLayout = new QVBoxLayout;
64 cameraDirectionLayout->addLayout(cameraThetaLayout);
65 cameraDirectionLayout->addSpacing(12);
66 cameraDirectionLayout->addLayout(cameraPhiLayout);
67
68 QGroupBox* cameraAnglesGroup = new QGroupBox(tr("Camera Direction"));
69 cameraAnglesGroup->setLayout(cameraDirectionLayout);
70
71 connect(cameraTheta, &QSlider::valueChanged, this, &G4DisplayView::changeCameraDirection);
72 connect(cameraPhi, &QSlider::valueChanged, this, &G4DisplayView::changeCameraDirection);
73
74 // Light Direction
75 lightTheta = new QSlider(Qt::Horizontal);
76 lightTheta->setRange(0, 180);
77 lightTheta->setSingleStep(1);
78 lightTheta->setValue(thetaValue);
79 auto lightThetaLabel = new QLabel(tr("θ"));
80
81 auto lightThetaLayout = new QHBoxLayout;
82 lightThetaLayout->addWidget(lightThetaLabel);
83 lightThetaLayout->addWidget(lightTheta);
84
85 lightPhi = new QSlider(Qt::Horizontal);
86 lightPhi->setRange(0, 360);
87 lightPhi->setSingleStep(1);
88 lightPhi->setValue(phiValue);
89 auto lightPhiLabel = new QLabel(tr("ɸ"));
90
91 auto lightPhiLayout = new QHBoxLayout;
92 lightPhiLayout->addWidget(lightPhiLabel);
93 lightPhiLayout->addWidget(lightPhi);
94
95 auto lightDirectionLayout = new QVBoxLayout;
96 lightDirectionLayout->addLayout(lightThetaLayout);
97 lightDirectionLayout->addSpacing(12);
98 lightDirectionLayout->addLayout(lightPhiLayout);
99
100 QGroupBox* lightAnglesGroup = new QGroupBox(tr("Light Direction"));
101 lightAnglesGroup->setLayout(lightDirectionLayout);
102
103 connect(lightTheta, &QSlider::valueChanged, this, &G4DisplayView::changeLightDirection);
104 connect(lightPhi, &QSlider::valueChanged, this, &G4DisplayView::changeLightDirection);
105
106 // x slice
107 sliceXEdit = new QLineEdit(tr("0"));
108 sliceXEdit->setMaximumWidth(100);
109 sliceXActi = new QCheckBox(tr("&On"));
110 sliceXActi->setChecked(false);
111 sliceXInve = new QCheckBox(tr("&Flip"));
112 sliceXInve->setChecked(false);
113 auto sliceXLayout = new QHBoxLayout;
114 sliceXLayout->addWidget(new QLabel(tr("X: ")));
115 sliceXLayout->addWidget(sliceXEdit);
116 sliceXLayout->addStretch(1);
117 sliceXLayout->addWidget(sliceXActi);
118 sliceXLayout->addWidget(sliceXInve);
119 sliceXLayout->addStretch(1);
120
121
122 // y slice
123 sliceYEdit = new QLineEdit(tr("0"));
124 sliceYEdit->setMaximumWidth(100);
125 sliceYActi = new QCheckBox(tr("&On"));
126 sliceYActi->setChecked(false);
127 sliceYInve = new QCheckBox(tr("&Flip"));
128 sliceYInve->setChecked(false);
129 auto sliceYLayout = new QHBoxLayout;
130 sliceYLayout->addWidget(new QLabel(tr("Y: ")));
131 sliceYLayout->addWidget(sliceYEdit);
132 sliceYLayout->addStretch(1);
133 sliceYLayout->addWidget(sliceYActi);
134 sliceYLayout->addWidget(sliceYInve);
135 sliceYLayout->addStretch(1);
136
137 // z slice
138 sliceZEdit = new QLineEdit(tr("0"));
139 sliceZEdit->setMaximumWidth(100);
140 sliceZActi = new QCheckBox(tr("&On"));
141 sliceZActi->setChecked(false);
142 sliceZInve = new QCheckBox(tr("&Flip"));
143 sliceZInve->setChecked(false);
144 auto sliceZLayout = new QHBoxLayout;
145 sliceZLayout->addWidget(new QLabel(tr("Z: ")));
146 sliceZLayout->addWidget(sliceZEdit);
147 sliceZLayout->addStretch(1);
148 sliceZLayout->addWidget(sliceZActi);
149 sliceZLayout->addWidget(sliceZInve);
150 sliceZLayout->addStretch(1);
151
152 // clear sice button
153 QPushButton* clearSliceButton = new QPushButton(tr("Clear Slices"));
154 clearSliceButton->setToolTip("Clear Slice Planes");
155 clearSliceButton->setIcon(QIcon::fromTheme("edit-clear"));
156 clearSliceButton->setIconSize(QSize(16, 16)); // Adjust as necessary
157
158 connect(clearSliceButton, &QPushButton::clicked, this, &G4DisplayView::clearSlices);
159
160 // slice style: Intersection or Union
161 QGroupBox* sliceChoiceBox = new QGroupBox(tr("Slices Style"));
162 sliceSectn = new QRadioButton(tr("&Intersection"), sliceChoiceBox);
163 sliceUnion = new QRadioButton(tr("&Union"), sliceChoiceBox);
164 sliceSectn->setChecked(true);
165
166 connect(sliceSectn, &QRadioButton::toggled, this, &G4DisplayView::slice);
167 connect(sliceUnion, &QRadioButton::toggled, this, &G4DisplayView::slice);
168
169 auto sliceChoiceLayout = new QHBoxLayout;
170 sliceChoiceLayout->addWidget(sliceSectn);
171 sliceChoiceLayout->addWidget(sliceUnion);
172 sliceChoiceBox->setLayout(sliceChoiceLayout);
173
174
175 // slices layout
176 auto sliceLayout = new QVBoxLayout;
177 sliceLayout->addLayout(sliceXLayout);
178 sliceLayout->addLayout(sliceYLayout);
179 sliceLayout->addLayout(sliceZLayout);
180 sliceLayout->addWidget(sliceChoiceBox);
181 sliceLayout->addWidget(clearSliceButton);
182
183
184 // connecting widgets to slice
185 connect(sliceXEdit, &QLineEdit::returnPressed, this, &G4DisplayView::slice);
186 connect(sliceYEdit, &QLineEdit::returnPressed, this, &G4DisplayView::slice);
187 connect(sliceZEdit, &QLineEdit::returnPressed, this, &G4DisplayView::slice);
188
189
190#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0) // Qt ≤6.6
191 connect(sliceXActi, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
192 connect(sliceYActi, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
193 connect(sliceZActi, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
194 connect(sliceXInve, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
195 connect(sliceYInve, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
196 connect(sliceZInve, &QCheckBox::stateChanged, this, &G4DisplayView::slice);
197#else // Qt≥6.7
198 connect(sliceXActi, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
199 connect(sliceYActi, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
200 connect(sliceZActi, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
201 connect(sliceXInve, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
202 connect(sliceYInve, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
203 connect(sliceZInve, &QCheckBox::checkStateChanged, this, &G4DisplayView::slice);
204#endif
205
206
207 QGroupBox* fieldPrecisionBox = new QGroupBox(tr("Number of Field Points"));
208 field_npoints = new QLineEdit(QString::number(field_NPOINTS), this);
209 field_npoints->setMaximumWidth(40);
210
211 QFont font = field_npoints->font();
212 font.setPointSize(24);
213 field_npoints->setFont(font);
214 connect(field_npoints, &QLineEdit::returnPressed, this, &G4DisplayView::field_precision_changed);
215
216 // buttons + field line number
217 auto fieldPointsHBox = new QHBoxLayout;
218 fieldPointsHBox->addWidget(field_npoints);
219 fieldPrecisionBox->setLayout(fieldPointsHBox);
220
221 auto buttons_field_HBox = new QHBoxLayout;
222 buttons_field_HBox->addWidget(buttons_set1);
223 buttons_field_HBox->addWidget(fieldPrecisionBox);
224 fieldPrecisionBox->setMaximumHeight(3 * buttons_set1->height());
225 fieldPrecisionBox->setMaximumWidth(140);
226
227
228 // All layouts together
229 auto mainLayout = new QVBoxLayout;
230 mainLayout->addLayout(buttons_field_HBox);
231 mainLayout->addWidget(cameraAnglesGroup);
232 mainLayout->addWidget(lightAnglesGroup);
233 mainLayout->addLayout(sliceLayout);
234 setLayout(mainLayout);
235}
236
243void G4DisplayView::changeCameraDirection() {
244 // Construct the command using the current slider values.
245 string command = "/vis/viewer/set/viewpointThetaPhi " +
246 to_string(cameraTheta->value()) + " " +
247 to_string(cameraPhi->value());
248 // Send the command to the Geant4 UImanager.
249 G4UImanager::GetUIpointer()->ApplyCommand(command);
250}
251
258void G4DisplayView::changeLightDirection() {
259 string command = "/vis/viewer/set/lightsThetaPhi " +
260 to_string(lightTheta->value()) + " " +
261 to_string(lightPhi->value());
262 G4UImanager::GetUIpointer()->ApplyCommand(command);
263}
264
265
273void G4DisplayView::slice() {
274 G4UImanager* g4uim = G4UImanager::GetUIpointer();
275 if (g4uim == nullptr) { return; }
276
277 // can't have a mix of wireframe / solid when doing a slice.
278 // forcing all to be solid
279 // if(!solidVis) {
280 // g4uim->ApplyCommand("/vis/geometry/set/forceSolid all -1 1");
281 // }
282
283 g4uim->ApplyCommand("/vis/viewer/clearCutawayPlanes");
284
285 if (sliceSectn->isChecked()) { g4uim->ApplyCommand("/vis/viewer/set/cutawayMode intersection"); }
286 else if (sliceUnion->isChecked()) { g4uim->ApplyCommand("/vis/viewer/set/cutawayMode union"); }
287
288 g4uim->ApplyCommand("/vis/viewer/clearCutawayPlanes");
289
290 if (sliceXActi->isChecked()) {
291 string command = "/vis/viewer/addCutawayPlane " + sliceXEdit->text().toStdString() + " 0 0 mm " +
292 to_string(sliceXInve->isChecked() ? -1 : 1) + " 0 0 ";
293 cout << "X " << command << endl;
294 g4uim->ApplyCommand(command);
295 }
296
297 if (sliceYActi->isChecked()) {
298 string command = "/vis/viewer/addCutawayPlane 0 " + sliceYEdit->text().toStdString() + " 0 mm 0 " +
299 to_string(sliceYInve->isChecked() ? -1 : 1) + " 0 ";
300 cout << "Y " << command << endl;
301 g4uim->ApplyCommand(command);
302 }
303
304 if (sliceZActi->isChecked()) {
305 string command = "/vis/viewer/addCutawayPlane 0 0 " + sliceZEdit->text().toStdString() + " mm 0 0 " +
306 to_string(sliceZInve->isChecked() ? -1 : 1);
307 cout << "Z " << command << endl;
308 g4uim->ApplyCommand(command);
309 }
310
311 //solidVis = true;
312}
313
314
320void G4DisplayView::clearSlices() {
321 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/clearCutawayPlanes");
322 sliceXActi->setChecked(false);
323}
324
334void G4DisplayView::apply_buttons_set1(int index) {
335 G4UImanager* g4uim = G4UImanager::GetUIpointer();
336 if (g4uim == nullptr) { return; }
337
338 bool button_state = buttons_set1->lastButtonState();
339
340 if (index == 0) {
341 string command = string("/vis/viewer/set/hiddenEdge") + (button_state ? " 1" : " 0");
342 g4uim->ApplyCommand(command);
343 g4uim->ApplyCommand("/vis/viewer/flush");
344 }
345 else if (index == 1) {
346 if (button_state == 0) {
347 glDisable(GL_LINE_SMOOTH);
348 glDisable(GL_POLYGON_SMOOTH);
349 }
350 else {
351 glEnable(GL_LINE_SMOOTH);
352 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
353 glEnable(GL_POLYGON_SMOOTH);
354 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
355 }
356 }
357 else if (index == 2) {
358 string command = string("/vis/viewer/set/auxiliaryEdge") + (button_state ? " 1" : " 0");
359 g4uim->ApplyCommand(command);
360 command = string("/vis/viewer/set/hiddenEdge") + (button_state ? " 1" : " 0");
361 g4uim->ApplyCommand(command);
362 if (buttons_set1->buttonStatus(0) != button_state) { buttons_set1->toggleButton(0); }
363 }
364 else if (index == 3) {
365 if (button_state == 0) {
366 string command = string("vis/scene/activateModel Field 0");
367 g4uim->ApplyCommand(command);
368 g4uim->ApplyCommand("/vis/scene/removeModel Field");
369 }
370 else {
371 string npoints = to_string(field_NPOINTS);
372 string command = string("/vis/scene/add/magneticField ") + npoints;
373 g4uim->ApplyCommand(command);
374 }
375 }
376}
377
384void G4DisplayView::field_precision_changed() {
385 G4UImanager* g4uim = G4UImanager::GetUIpointer();
386 if (g4uim == nullptr) { return; }
387 field_NPOINTS = field_npoints->text().toInt();
388 if (buttons_set1->buttonStatus(3) == 1) {
389 string command = string("vis/scene/activateModel Field 0");
390 g4uim->ApplyCommand(command);
391 g4uim->ApplyCommand("/vis/scene/removeModel Field");
392
393 string npoints = to_string(field_NPOINTS);
394 command = string("/vis/scene/add/magneticField ") + npoints;
395 G4UImanager::GetUIpointer()->ApplyCommand(command);
396 }
397}
G4DisplayView(const std::shared_ptr< GOptions > &gopts, std::shared_ptr< GLogger > logger, QWidget *parent=nullptr)
Constructs the G4DisplayView widget.
G4Camera getG4Camera(const std::shared_ptr< GOptions > &gopts)