source: trunk/FACT++/gui/BasicGlCamera.cc@ 19983

Last change on this file since 19983 was 19978, checked in by tbretz, 4 years ago
These are some workarounds to make it compile with Qt5
File size: 42.5 KB
Line 
1#include "BasicGlCamera.h"
2
3#include <math.h>
4
5#include <fstream>
6#include <iostream>
7#include <string>
8#include <sstream>
9#include <algorithm>
10
11#include <QLabel>
12#include <QRadioButton>
13#include <QButtonGroup>
14
15#include <GL/glu.h>
16
17#include "src/Time.h"
18#include "src/tools.h"
19
20using namespace std;;
21
22//static variables
23PixelMap BasicGlCamera::fPixelMap;
24GLfloat BasicGlCamera::pixelsCoords[MAX_NUM_PIXELS][3];
25PixelsNeighbors BasicGlCamera::neighbors[MAX_NUM_PIXELS];
26int BasicGlCamera::hardwareMapping[NPIX];
27GLfloat BasicGlCamera::verticesList[NPIX*6][2];
28vector<edge> BasicGlCamera::patchesIndices[160];
29int BasicGlCamera::verticesIndices[NPIX][6];
30int BasicGlCamera::pixelsPatch[NPIX];
31int BasicGlCamera::softwareMapping[NPIX];
32
33static const float _coord = 1/sqrt(3.);
34
35//Coordinates of an hexagon of radius 1 and center 0
36GLfloat hexcoords[6][2] = {{-1*_coord, 1},
37 { 1*_coord, 1},
38 { 2*_coord, 0},
39 { 1*_coord, -1},
40 {-1*_coord, -1},
41 {-2*_coord, 0}};
42
43
44
45 BasicGlCamera::BasicGlCamera(QWidget* cParent)
46 : QGLWidget(QGLFormat(QGL::DoubleBuffer |
47 QGL::DepthBuffer),cParent)
48 {
49#ifdef HAVE_QT4
50 QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
51#endif
52 fWhite = -1;
53 fWhitePatch = -1;
54 fMin = -1;
55 fMax = -1;
56 fScaleLimit = -0.5;
57 fTextSize = 0;
58 autoRefresh = false;
59 logScale = false;
60 cameraRotation = +90;
61 fTextEnabled = true;
62 unitsText = "";
63 titleText = "";
64 dataText = "";
65 pixelContourColour[0] = 0.1f;
66 pixelContourColour[1] = 0.1f;
67 pixelContourColour[2] = 0.1f;
68 patchesCoulour[0] = 0.1f;
69 patchesCoulour[1] = 0.1f;
70 patchesCoulour[2] = 0.1f;
71 highlightedPatchesCoulour[0] = 0.6f;
72 highlightedPatchesCoulour[1] = 0.6f;
73 highlightedPatchesCoulour[2] = 0.6f;
74 highlightedPixelsCoulour[0] = 0.8f;
75 highlightedPixelsCoulour[1] = 0.8f;
76 highlightedPixelsCoulour[2] = 0.8f;
77
78 regularPalettePlease(true);
79
80
81 viewSize = 1.0f;
82/*
83 ifstream fin1("Trigger-Patches.txt");
84 if (!fin1.is_open())
85 {
86 cout << "Error: file \"Trigger-Patches.txt\" missing. Aborting." << endl;
87 exit(-1);
88 }
89 l=0;
90 while (getline(fin1, buf, '\n'))
91 {
92 buf = Tools::Trim(buf);
93 if (buf[0]=='#')
94 continue;
95
96 stringstream str(buf);
97 for (int i=0; i<9; i++)
98 {
99 unsigned int n;
100 str >> n;
101
102 if (n>=1440)
103 continue;
104
105 patches[l][i] = hardwareMapping[n];
106 }
107 l++;
108 }
109
110 //now construct the correspondance between pixels and patches
111 for (int i=0;i<NTMARK;i++)
112 for (int j=0;j<9;j++)
113 pixelsPatch[softwareMapping[patches[i][j]]] = i;
114
115 for (int i=0;i<1440;i++)
116 updateNeighbors(i);
117
118 buildPatchesIndices();
119*/////////////////////////////////
120 regularPalettePlease(true);
121// ss[0] = 0; ss[1] = 0.25f; ss[2] = 0.5f; ss[3] = 0.75f; ss[4] = 1.0f;
122// rr[0] = 0.15; rr[1] = 0; rr[2] = 0; rr[3] = 1.0f; rr[4] = 0.85f;
123// gg[0] = 0.15; gg[1] = 0; gg[2] = 1; gg[3] = 0; gg[4] = 0.85f;
124// bb[0] = 0.15; bb[1] = 1; bb[2] = 0; bb[3] = 0; bb[4] = 0.85f;
125
126 fPixelStride = 1;
127 fcSlice = 0;
128 fData.resize(1440);
129 for (int i=0;i<NPIX;i++)
130 fData[i] = (double)i;///1.44;//(double)(i)/(double)(ACTUAL_NUM_PIXELS);
131
132// setFont(QFont("Arial", 8));
133 int buttonShift=0;
134 scaleLabel = new QLabel("Scale", this);
135// buttonShift += scaleLabel->height();
136
137 linearButton = new QRadioButton("Linear", this);
138 linearButton->move(scaleLabel->width(), buttonShift);
139 buttonShift += linearButton->height();
140
141 logButton = new QRadioButton("Log", this);
142 logButton->move(scaleLabel->width(), buttonShift);
143 buttonShift += logButton->height()*1.1f;
144
145 colorPaletteLabel = new QLabel("Colour\nPalette", this);
146 colorPaletteLabel->move(0, buttonShift);
147 // buttonShift += colorPaletteLabel->height();
148
149 regularPaletteButton = new QRadioButton("Regular", this);
150 regularPaletteButton->move(colorPaletteLabel->width(), buttonShift);
151 buttonShift += regularPaletteButton->height();
152
153 prettyPaletteButton = new QRadioButton("Pretty", this);
154 prettyPaletteButton->move(colorPaletteLabel->width(), buttonShift);
155 buttonShift += prettyPaletteButton->height();
156
157 greyScalePaletteButton = new QRadioButton("Grey Scale", this);
158 greyScalePaletteButton->move(colorPaletteLabel->width(), buttonShift);
159 buttonShift += greyScalePaletteButton->height();
160
161 glowingPaletteButton = new QRadioButton("Glowing", this);
162 glowingPaletteButton->move(colorPaletteLabel->width(), buttonShift);
163 buttonShift += glowingPaletteButton->height()*1.1f;
164
165 rotationLabel = new QLabel("Camera\nRotation", this);
166 rotationLabel->move(0, buttonShift);
167 // buttonShift += rotationLabel->height();
168
169 unsigned short utf16Array;
170 utf16Array = 0x00b0;
171 QString degreeSymbol(QString::fromUtf16(&utf16Array, 1));
172 QString zerostr("0" + degreeSymbol);
173 zeroRotationButton = new QRadioButton(zerostr, this);
174 zeroRotationButton->move(rotationLabel->width(), buttonShift);
175 buttonShift += zeroRotationButton->height();
176 QString minus90str("+90" + degreeSymbol);
177 minus90RotationButton = new QRadioButton(minus90str, this);
178 minus90RotationButton->move(rotationLabel->width(), buttonShift);
179 buttonShift += minus90RotationButton->height();
180 QString plus90str("-90"+degreeSymbol);
181 plus90Rotationbutton = new QRadioButton(plus90str, this);
182 plus90Rotationbutton->move(rotationLabel->width(), buttonShift);
183
184
185 scaleGroup = new QButtonGroup(this);
186 colorGroup = new QButtonGroup(this);
187 rotationGroup = new QButtonGroup(this);
188 scaleGroup->addButton(linearButton);
189 scaleGroup->addButton(logButton);
190 colorGroup->addButton(regularPaletteButton);
191 colorGroup->addButton(prettyPaletteButton);
192 colorGroup->addButton(greyScalePaletteButton);
193 colorGroup->addButton(glowingPaletteButton);
194 rotationGroup->addButton(zeroRotationButton);
195 rotationGroup->addButton(minus90RotationButton);
196 rotationGroup->addButton(plus90Rotationbutton);
197
198 linearButton->setChecked(true);
199 regularPaletteButton->setChecked(true);
200// zeroRotationButton->setChecked(true);
201 minus90RotationButton->setChecked(true);
202// linearButton->palette.setColor();
203
204 linearButton->setAutoFillBackground(true);
205 logButton->setAutoFillBackground(true);
206 regularPaletteButton->setAutoFillBackground(true);
207 prettyPaletteButton->setAutoFillBackground(true);
208 greyScalePaletteButton->setAutoFillBackground(true);
209 glowingPaletteButton->setAutoFillBackground(true);
210 zeroRotationButton->setAutoFillBackground(true);
211 minus90RotationButton->setAutoFillBackground(true);
212 plus90Rotationbutton->setAutoFillBackground(true);
213 scaleLabel->setAutoFillBackground(true);
214 colorPaletteLabel->setAutoFillBackground(true);
215 rotationLabel->setAutoFillBackground(true);
216
217 linearButton->hide();
218 logButton->hide();
219 regularPaletteButton->hide();
220 prettyPaletteButton->hide();
221 greyScalePaletteButton->hide();
222 glowingPaletteButton->hide();
223 zeroRotationButton->hide();
224 minus90RotationButton->hide();
225 plus90Rotationbutton->hide();
226 scaleLabel->hide();
227 colorPaletteLabel->hide();
228 rotationLabel->hide();
229
230 connect(linearButton, SIGNAL(toggled(bool)),
231 this, SLOT(linearScalePlease(bool)));
232 connect(logButton, SIGNAL(toggled(bool)),
233 this, SLOT(logScalePlease(bool)));
234 connect(regularPaletteButton, SIGNAL(toggled(bool)),
235 this, SLOT(regularPalettePlease(bool)));
236 connect(prettyPaletteButton, SIGNAL(toggled(bool)),
237 this, SLOT(prettyPalettePlease(bool)));
238 connect(greyScalePaletteButton, SIGNAL(toggled(bool)),
239 this, SLOT(greyScalePalettePlease(bool)));
240 connect(glowingPaletteButton, SIGNAL(toggled(bool)),
241 this, SLOT(glowingPalettePlease(bool)));
242 connect(zeroRotationButton, SIGNAL(toggled(bool)),
243 this, SLOT(zeroRotationPlease(bool)));
244 connect(minus90RotationButton, SIGNAL(toggled(bool)),
245 this, SLOT(plus90RotationPlease(bool)));
246 connect(plus90Rotationbutton, SIGNAL(toggled(bool)),
247 this, SLOT(minus90RotationPlease(bool)));
248
249 connect(this, SIGNAL(signalUpdateCamera()),
250 this, SLOT(timedUpdate()));
251 }
252 BasicGlCamera::~BasicGlCamera()
253 {
254 }
255 bool BasicGlCamera::isFACT() const
256 {
257 return hexRadius<0.02;
258 }
259 void BasicGlCamera::assignPixelMap(const PixelMap& map)
260 {
261 fPixelMap = map;
262
263 int cnt = 0;
264 for (auto it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
265 {
266 hardwareMapping[it->index] = it->hw();
267 softwareMapping[it->hw()] = it->index;
268 if (it->gapd>0)
269 cnt++;
270 }
271
272 if (cnt==64)
273 {
274 cout << "INFO: 64 SiPMs found in mapping file -- assuming HAWC's Eye geometry." << endl;
275 hexRadius = 0.060f;
276 }
277 else
278 hexRadius = 0.015f;
279
280 //now construct the correspondance between pixels and patches
281 for (int i=0;i<NTMARK;i++)
282 for (int j=0;j<9;j++)
283 pixelsPatch[softwareMapping[i*9+j]] = i;
284
285 calculatePixelsCoords();
286
287 for (int i=0;i<1440;i++)
288 {
289 for (int j=0;j<6;j++)
290 neighbors[i][j] = -1;
291 updateNeighbors(i);
292 }
293
294 buildVerticesList();
295
296 buildPatchesIndices();
297
298 }
299 void BasicGlCamera::enableText(bool on)
300 {
301 fTextEnabled = on;
302 }
303 void BasicGlCamera::setPatchColor(int id, float color[3])
304 {
305 for (int i=0;i<9;i++)
306 for (int j=0;j<3;j++)
307 pixelsColor[softwareMapping[id*9+i]][j] = color[j];
308 }
309 void BasicGlCamera::setUnits(const string& units)
310 {
311 unitsText = units;
312 pixelColorUpToDate = false;
313 if (isVisible() && autoRefresh)
314 updateGL();
315 }
316 void BasicGlCamera::setTitle(const string& title)
317 {
318 titleText = title;
319 pixelColorUpToDate = false;
320 if (isVisible() && autoRefresh)
321 updateGL();
322 }
323 void BasicGlCamera::SetWhite(int idx)
324 {
325 fWhite = idx;
326 fWhitePatch = pixelsPatch[fWhite];
327 if (isVisible() && autoRefresh)
328 updateGL();
329// CalculatePatchColor();
330 }
331 void BasicGlCamera::SetMin(int64_t min)
332 {
333// cout << "min: " << min << endl;
334 fMin = min;
335 pixelColorUpToDate = false;
336 if (isVisible() && autoRefresh)
337 updateGL();
338 }
339 void BasicGlCamera::setAutoscaleLowerLimit(float val)
340 {
341 fScaleLimit = val;
342 if (isVisible() && autoRefresh)
343 updateGL();
344 }
345
346 void BasicGlCamera::SetMax(int64_t max)
347 {
348// cout << "max: " << max << endl;
349 fMax = max;
350 pixelColorUpToDate = false;
351 if (isVisible() && autoRefresh)
352 updateGL();
353 }
354 void BasicGlCamera::linearScalePlease(bool checked)
355 {
356 if (!checked) return;
357 logScale = false;
358 pixelColorUpToDate = false;
359 emit colorPaletteHasChanged();
360 if (isVisible() && autoRefresh)
361 updateGL();
362 }
363 void BasicGlCamera::UpdateText()
364 {
365 ostringstream str;
366 float min, max, median;
367 int ii=0;
368 for (;ii<ACTUAL_NUM_PIXELS;ii++)
369 {
370 if (finite(fData[ii]))
371 {
372 min = max = fData[ii];
373 break;
374 }
375 }
376 double mean = 0;
377 double rms = 0;
378 median = 0;
379 if (ii==ACTUAL_NUM_PIXELS)
380 {
381 fmin = fmax = fmean = frms = fmedian = 0;
382 return;
383 }
384
385 vector<double> medianVec;
386 medianVec.resize(ACTUAL_NUM_PIXELS);
387 auto it = medianVec.begin();
388 int numSamples = 0;
389 for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
390 {
391 if (!finite(fData[i]))
392 continue;
393 if (fData[i] < min)
394 min = fData[i];
395 if (fData[i] > max)
396 max = fData[i];
397 mean += fData[i];
398 rms += fData[i]*fData[i];
399 //medianSet.insert(fData[i]);
400 *it = fData[i];
401 it++;
402 numSamples++;
403 }
404
405// vector<double> medianVec;
406// medianVec.resize(ACTUAL_NUM_PIXELS);
407// int iii=0;
408// for (auto it=medianVec.begin(); it != medianVec.end(); it++) {
409// *it = fData[iii];
410// iii++;
411// }
412 sort(medianVec.begin(), medianVec.begin()+numSamples);
413
414
415 mean /= numSamples;
416 rms = sqrt((rms/numSamples) - (mean * mean));
417
418// multiset<double>::iterator it = medianSet.begin();
419 auto jt = medianVec.begin();
420 for (int i=0;i<(numSamples/2)-1;i++)
421 {
422// it++;
423 jt++;
424 }
425 median = *jt;
426 // cout << *it << " " << *jt << endl;
427 if (numSamples%2==0){
428 jt++;
429 median += *jt;
430 median /= 2;}
431
432 str << "Min: " << min << endl << " Max: " << max << " Mean: " << mean << " RMS: " << rms << " Median: " << median;
433 str << " Units: " << unitsText;
434 dataText = str.str();
435
436 fmin = min;
437 fmax = max;
438 fmean = mean;
439 frms = rms;
440 fmedian = median;
441 }
442 void BasicGlCamera::DrawCameraText()
443 {
444 if (!fTextEnabled)
445 return;
446 glPushMatrix();
447 glLoadIdentity();
448// cout << width() << " " << height() << endl;
449 int textSize = (int)(height()*14/600);
450// setFont(QFont("Times", textSize));
451 qglColor(QColor(255,223,127));
452 float shiftx = 0.01f;//0.55f;
453 float shifty = 0.01f;//0.65f;
454 renderText(-shownSizex/2.f + shiftx, 0.f, 0.f, QString(dataText.c_str()));//-shownSizey/2.f + shifty, 0.f, QString(dataText.c_str()));
455
456
457// int textLength = titleText.size();
458 renderText(-shownSizex/2.f + shiftx, shownSizey/2.f - textSize*pixelSize - shifty, 0.f, QString(titleText.c_str()));
459
460 glPopMatrix();
461
462 // textSize = (int)(600*14/600);
463// setFont(QFont("Times", textSize));
464 }
465 void BasicGlCamera::DrawScale()
466 {
467 glPushMatrix();
468 glLoadIdentity();
469 glPushAttrib(GL_POLYGON_BIT);
470 glShadeModel(GL_SMOOTH);
471 glBegin(GL_QUADS);
472 float oneX = shownSizex/2.f - shownSizex/50.f;
473 float twoX = shownSizex/2.f;
474 float oneY = -shownSizey/2.f;
475 float twoY = -shownSizey/4.f;
476 float threeY = 0;
477 float fourY = shownSizey/4.f;
478 float fiveY = shownSizey/2.f;
479 glColor3f(rr[0], gg[0], bb[0]);
480 glVertex2f(oneX, oneY);
481 glVertex2f(twoX, oneY);
482 glColor3f(rr[1], gg[1], bb[1]);
483 glVertex2f(twoX, twoY);
484 glVertex2f(oneX, twoY);
485
486 glVertex2f(oneX, twoY);
487 glVertex2f(twoX, twoY);
488 glColor3f(rr[2], gg[2], bb[2]);
489 glVertex2f(twoX, threeY);
490 glVertex2f(oneX, threeY);
491
492 glVertex2f(oneX, threeY);
493 glVertex2f(twoX, threeY);
494 glColor3f(rr[3], gg[3], bb[3]);
495 glVertex2f(twoX, fourY);
496 glVertex2f(oneX, fourY);
497
498 glVertex2f(oneX, fourY);
499 glVertex2f(twoX, fourY);
500 glColor3f(rr[4], gg[4], bb[4]);
501 glVertex2f(twoX, fiveY);
502 glVertex2f(oneX, fiveY);
503 float zeroX = oneX - shownSizex/50.f;
504 float zeroY = fiveY - shownSizey/50.f;
505 glColor3fv(tooHighValueCoulour);
506 glVertex2f(zeroX, fiveY);
507 glVertex2f(oneX, fiveY);
508 glVertex2f(oneX, zeroY);
509 glVertex2f(zeroX, zeroY);
510 glColor3fv(tooLowValueCoulour);
511 glVertex2f(zeroX, -fiveY);
512 glVertex2f(oneX, -fiveY);
513 glVertex2f(oneX, -zeroY);
514 glVertex2f(zeroX, -zeroY);
515 glEnd();
516 glTranslatef(0,0,0.1f);
517
518 //draw linear/log tick marks
519 glColor3f(0.f,0.f,0.f);
520 glBegin(GL_LINES);
521 float value;
522 for (int i=1;i<10;i++)
523 {
524 if (logScale)
525 value = log10(i);
526 else
527 value = (float)(i)/10.f;
528 float yy = -shownSizey/2.f + value*shownSizey;
529 glVertex2f(oneX, yy);
530 glVertex2f(twoX, yy);
531 }
532 glEnd();
533 glPopAttrib();
534 glPopMatrix();
535 }
536 void BasicGlCamera::logScalePlease(bool checked)
537 {
538 if (!checked) return;
539 logScale = true;
540 pixelColorUpToDate = false;
541 emit colorPaletteHasChanged();
542 if (isVisible() && autoRefresh)
543 updateGL();
544 }
545 void BasicGlCamera::regularPalettePlease(bool checked)
546 {
547 if (!checked) return;
548 ss[0] = 0; ss[1] = 0.25f; ss[2] = 0.5f; ss[3] = 0.75f; ss[4] = 1.0f;
549 rr[0] = 0; rr[1] = 0; rr[2] = 0; rr[3] = 1.0f; rr[4] = 1;
550 gg[0] = 0; gg[1] = 1; gg[2] = 1; gg[3] = 1; gg[4] = 0;
551 bb[0] = 0.5f; bb[1] = 1; bb[2] = 0; bb[3] = 0; bb[4] = 0;
552 tooHighValueCoulour[0] = 1.f;
553 tooHighValueCoulour[1] = 1.f;
554 tooHighValueCoulour[2] = 1.f;
555 tooLowValueCoulour[0] = 0.f;
556 tooLowValueCoulour[1] = 0.f;
557 tooLowValueCoulour[2] = 0.f;
558 pixelColorUpToDate = false;
559
560 emit colorPaletteHasChanged();
561
562 if (isVisible() && autoRefresh)
563 updateGL();
564 }
565 void BasicGlCamera::prettyPalettePlease(bool checked)
566 {
567 if (!checked) return;
568 ss[0] = 0.f; ss[1] = 0.25f; ss[2] = 0.5f; ss[3] = 0.75f; ss[4] = 1.0f;
569 rr[0] = 0.f; rr[1] = 0.35f; rr[2] = 0.85f; rr[3] = 1.0f; rr[4] = 1.f;
570 gg[0] = 0.f; gg[1] = 0.10f; gg[2] = 0.20f; gg[3] = 0.73f; gg[4] = 1.f;
571 bb[0] = 0.f; bb[1] = 0.03f; bb[2] = 0.06f; bb[3] = 0.00f; bb[4] = 1.f;
572 tooHighValueCoulour[0] = 0.f;
573 tooHighValueCoulour[1] = 1.f;
574 tooHighValueCoulour[2] = 0.f;
575 tooLowValueCoulour[0] = 0.f;
576 tooLowValueCoulour[1] = 0.f;
577 tooLowValueCoulour[2] = 1.f;
578 pixelColorUpToDate = false;
579
580 emit colorPaletteHasChanged();
581
582 if (isVisible() && autoRefresh)
583 updateGL();
584 }
585 void BasicGlCamera::greyScalePalettePlease(bool checked)
586 {
587 if (!checked) return;
588 ss[0] = 0; ss[1] = 0.25f; ss[2] = 0.5f; ss[3] = 0.75f; ss[4] = 1.0f;
589 rr[0] = 0; rr[1] = 0.25f; rr[2] = 0.5f; rr[3] = 0.75f; rr[4] = 1.0f;
590 gg[0] = 0; gg[1] = 0.25f; gg[2] = 0.5f; gg[3] = 0.75f; gg[4] = 1.0f;
591 bb[0] = 0; bb[1] = 0.25f; bb[2] = 0.5f; bb[3] = 0.75f; bb[4] = 1.0f;
592 tooHighValueCoulour[0] = 0.f;
593 tooHighValueCoulour[1] = 1.f;
594 tooHighValueCoulour[2] = 0.f;
595 tooLowValueCoulour[0] = 0.f;
596 tooLowValueCoulour[1] = 0.f;
597 tooLowValueCoulour[2] = 1.f;
598 pixelColorUpToDate = false;
599
600 emit colorPaletteHasChanged();
601
602 if (isVisible() && autoRefresh)
603 updateGL();
604 }
605 void BasicGlCamera::glowingPalettePlease(bool checked)
606 {
607 if (!checked) return;
608 ss[0] = 0; ss[1] = 0.25f; ss[2] = 0.5f; ss[3] = 0.75f; ss[4] = 1.0f;
609 rr[0] = 0.15; rr[1] = 0.5; rr[2] = 1.f; rr[3] = 0.0f; rr[4] = 1.f;
610 gg[0] = 0.15; gg[1] = 0.5; gg[2] = 1.f; gg[3] = 0.5f; gg[4] = 0.5f;
611 bb[0] = 0.15; bb[1] = 0.5; bb[2] = 1; bb[3] = 1.f; bb[4] = 0.f;
612 tooHighValueCoulour[0] = 1.f;
613 tooHighValueCoulour[1] = 0.f;
614 tooHighValueCoulour[2] = 0.f;
615 tooLowValueCoulour[0] = 0.f;
616 tooLowValueCoulour[1] = 1.f;
617 tooLowValueCoulour[2] = 0.f;
618 pixelColorUpToDate = false;
619
620 emit colorPaletteHasChanged();
621
622 if (isVisible() && autoRefresh)
623 updateGL();
624 }
625 void BasicGlCamera::SetAutoRefresh(bool on)
626 {
627 autoRefresh = on;
628 if (isVisible() && autoRefresh)
629 updateGL();
630 }
631 void BasicGlCamera::zeroRotationPlease(bool checked)
632 {
633 if (!checked) return;
634 cameraRotation = 0;
635 pixelColorUpToDate = false;
636 if (isVisible() && autoRefresh)
637 updateGL();
638 }
639 void BasicGlCamera::plus90RotationPlease(bool checked)
640 {
641 if (!checked) return;
642 cameraRotation = 90;
643 pixelColorUpToDate = false;
644 if (isVisible() && autoRefresh)
645 updateGL();
646 }
647 void BasicGlCamera::minus90RotationPlease(bool checked)
648 {
649 if (!checked) return;
650 cameraRotation = -90;
651 pixelColorUpToDate = false;
652 if (isVisible() && autoRefresh)
653 updateGL();
654 }
655
656 void BasicGlCamera::initializeGL()
657 {
658 qglClearColor(QColor(212,208,200));//25,25,38));
659 glShadeModel(GL_FLAT);
660 glEnable(GL_DEPTH_TEST);
661 glDisable(GL_CULL_FACE);
662
663 // glEnable (GL_LINE_SMOOTH);
664 // glEnable (GL_BLEND);
665 // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
666 // glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
667
668 }
669 void BasicGlCamera::resizeGL(int cWidth, int cHeight)
670 {
671 glViewport(0, 0, cWidth, cHeight);
672 glMatrixMode(GL_PROJECTION);
673 glLoadIdentity();
674 GLfloat windowRatio = (float)cWidth/(float)cHeight;
675 if (windowRatio < 1)
676 {
677 windowRatio = 1.0f/windowRatio;
678 gluOrtho2D(-viewSize, viewSize, -viewSize*windowRatio, viewSize*windowRatio);
679 pixelSize = 2*viewSize/(float)cWidth;
680 shownSizex = 2*viewSize;
681 shownSizey = 2*viewSize*windowRatio;
682 }
683 else
684 {
685 gluOrtho2D(-viewSize*windowRatio, viewSize*windowRatio, -viewSize, viewSize);
686 pixelSize = 2*viewSize/(float)cHeight;
687 shownSizex = 2*viewSize*windowRatio;
688 shownSizey = 2*viewSize;
689 }
690 glMatrixMode(GL_MODELVIEW);
691
692 fTextSize = (int)(cWidth*12/600); //want a sized 12 font for a window of 600 pixels width
693 setFont(QFont("Monospace", fTextSize));
694 }
695 void BasicGlCamera::paintGL()
696 {
697 glClear(GL_COLOR_BUFFER_BIT);
698 glLoadIdentity();
699
700 glTranslatef(0,-0.44,0);
701 glScalef(1.5, 1.5, 1.5);
702
703 drawCamera(true);
704
705 drawPatches();
706 }
707 void BasicGlCamera::toggleInterfaceDisplay()
708 {
709 if (linearButton->isVisible())
710 {
711 linearButton->hide();
712 logButton->hide();
713 regularPaletteButton->hide();
714 prettyPaletteButton->hide();
715 greyScalePaletteButton->hide();
716 glowingPaletteButton->hide();
717 zeroRotationButton->hide();
718 minus90RotationButton->hide();
719 plus90Rotationbutton->hide();
720 scaleLabel->hide();
721 colorPaletteLabel->hide();
722 rotationLabel->hide();
723 }
724 else
725 {
726 linearButton->show();
727 logButton->show();
728 regularPaletteButton->show();
729 prettyPaletteButton->show();
730 greyScalePaletteButton->show();
731 glowingPaletteButton->show();
732 zeroRotationButton->show();
733 minus90RotationButton->show();
734 plus90Rotationbutton->show();
735 scaleLabel->show();
736 colorPaletteLabel->show();
737 rotationLabel->show();
738 }
739 }
740
741 void BasicGlCamera::mousePressEvent(QMouseEvent *)
742 {
743
744 }
745 void BasicGlCamera::mouseMoveEvent(QMouseEvent *)
746 {
747
748 }
749 void BasicGlCamera::mouseDoubleClickEvent(QMouseEvent *)
750 {
751
752 }
753 void BasicGlCamera::timedUpdate()
754 {
755 if (isVisible())
756 updateGL();
757 }
758 void BasicGlCamera::updateCamera()
759 {
760 emit signalUpdateCamera();
761 }
762 void BasicGlCamera::drawCamera(bool alsoWire)
763 {
764// cout << "Super PaintGL" << endl;
765 glColor3f(0.5,0.5,0.5);
766 glLineWidth(1.0);
767 float color;
768
769 for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
770 {
771 color = float(fData[i*fPixelStride+fcSlice]);// + ]eventData[nRoi*i + whichSlice]+(VALUES_SPAN/2))/(float)(VALUES_SPAN-1);
772 int index = 0;
773 while (ss[index] < color)
774 index++;
775 index--;
776 float weight0 = (color-ss[index]) / (ss[index+1]-ss[index]);
777 float weight1 = 1.0f-weight0;
778 pixelsColor[i][0] = weight1*rr[index] + weight0*rr[index+1];
779 pixelsColor[i][1] = weight1*gg[index] + weight0*gg[index+1];
780 pixelsColor[i][2] = weight1*bb[index] + weight0*bb[index+1];
781 }
782
783 for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
784 {
785 // if (i == 690 ||
786 // i == 70)
787 // continue;
788 glColor3fv(pixelsColor[i]);
789 glLoadName(i);
790
791 drawHexagon(i,true);
792
793 }
794 if (!alsoWire)
795 return;
796 glColor3f(0.0f,0.0f,0.0f);
797 for (int i=0;i<ACTUAL_NUM_PIXELS;i++)
798 {
799// if (i == 690 ||
800// i == 70)
801// continue;
802 drawHexagon(i, false);
803 }
804 }
805 void BasicGlCamera::drawPatches()
806 {
807 glLineWidth(2.0f);
808 float backupRadius = hexRadius;
809 hexRadius *= 0.95;
810 glColor3f(0.5f, 0.5f, 0.3f);
811 glBegin(GL_LINES);
812 for (int i=0;i<NTMARK;i++)
813 {
814 for (unsigned int j=0;j<patchesIndices[i].size();j++)
815 {
816 glVertex2fv(verticesList[patchesIndices[i][j].first]);
817 glVertex2fv(verticesList[patchesIndices[i][j].second]);
818 }
819 }
820 glEnd();
821 hexRadius = backupRadius;
822 }
823 int BasicGlCamera::PixelAtPosition(const QPoint &cPos)
824 {
825 const int MaxSize = 512;
826 GLuint buffer[MaxSize];
827 GLint viewport[4];
828
829 makeCurrent();
830
831 glGetIntegerv(GL_VIEWPORT, viewport);
832 glSelectBuffer(MaxSize, buffer);
833 glRenderMode(GL_SELECT);
834
835 glInitNames();
836 glPushName(0);
837
838 glMatrixMode(GL_PROJECTION);
839 glPushMatrix();
840 glLoadIdentity();
841 GLfloat windowRatio = GLfloat(width()) / GLfloat(height());
842 gluPickMatrix(GLdouble(cPos.x()), GLdouble(viewport[3] - cPos.y()),
843 1.0, 1.0, viewport);
844
845 if (windowRatio < 1)
846 {
847 windowRatio = 1.0f/windowRatio;
848 gluOrtho2D(-viewSize, viewSize, -viewSize*windowRatio, viewSize*windowRatio);
849 }
850 else
851 {
852 gluOrtho2D(-viewSize*windowRatio, viewSize*windowRatio, -viewSize, viewSize);
853 }
854
855 glMatrixMode(GL_MODELVIEW);
856 drawCamera(false);
857 glMatrixMode(GL_PROJECTION);
858 glPopMatrix();
859
860 //for some reason that I cannot understand, the push/pop matrix doesn't do the trick here... bizarre
861 //ok, so re-do the resizeGL thing.
862 resizeGL(width(), height());
863
864 if (!glRenderMode(GL_RENDER))
865 return -1;
866
867 return buffer[3];
868 }
869 void BasicGlCamera::drawHexagon(int index, bool solid)
870 {
871/* float minX, maxX, minY, maxY;
872 minX = minY = 1e10;
873 maxX = maxY = -1e10;
874 for (int i=0;i<1438;i++)
875 {
876 for (int j=0;j<6;j++)
877 {
878 if (verticesList[verticesIndices[i][j]][0] > maxX)
879 maxX = verticesList[verticesIndices[i][j]][0];
880 if (verticesList[verticesIndices[i][j]][0] < minX)
881 minX = verticesList[verticesIndices[i][j]][0];
882 if (verticesList[verticesIndices[i][j]][1] > maxY)
883 maxY = verticesList[verticesIndices[i][j]][1];
884 if (verticesList[verticesIndices[i][j]][1] < minY)
885 minY = verticesList[verticesIndices[i][j]][1];
886 }
887 }
888 cout << "Min, Max X: " << minX << " " << maxX << endl;
889 cout << "Min, Max Y: " << minY << " " << maxY << endl;
890 exit(0);*/
891 if (solid)
892 glBegin(GL_POLYGON);
893 else
894 glBegin(GL_LINE_LOOP);
895
896 glVertex2fv(verticesList[verticesIndices[index][0]]);
897 glVertex2fv(verticesList[verticesIndices[index][1]]);
898 glVertex2fv(verticesList[verticesIndices[index][2]]);
899 glVertex2fv(verticesList[verticesIndices[index][3]]);
900 glVertex2fv(verticesList[verticesIndices[index][4]]);
901 glVertex2fv(verticesList[verticesIndices[index][5]]);
902 if (solid)
903 glVertex2fv(verticesList[verticesIndices[index][0]]);
904
905 glEnd();
906 }
907
908 void BasicGlCamera::updateNeighbors(int currentPixel)
909 {
910 hexTolerance = hexRadius/100.0f;
911
912 float squaredDistance = 0;
913 for (int i=0;i<currentPixel;i++)
914 {
915 squaredDistance = (pixelsCoords[i][0] - pixelsCoords[currentPixel][0])*
916 (pixelsCoords[i][0] - pixelsCoords[currentPixel][0]) +
917 (pixelsCoords[i][1] - pixelsCoords[currentPixel][1])*
918 (pixelsCoords[i][1] - pixelsCoords[currentPixel][1]);
919 if (squaredDistance < 4*hexRadius*hexRadius*(1.0f+hexTolerance))//neighbor !
920 {//ok, but which one ?
921 if (fabs(pixelsCoords[i][0] - pixelsCoords[currentPixel][0]) < hexTolerance &&
922 pixelsCoords[i][1] < pixelsCoords[currentPixel][1]){//top
923 neighbors[i][0] = currentPixel;
924 neighbors[currentPixel][3] = i;
925 continue;}
926 if (fabs(pixelsCoords[i][0] - pixelsCoords[currentPixel][0]) < hexTolerance &&
927 pixelsCoords[i][1] > pixelsCoords[currentPixel][1]){//bottom
928 neighbors[i][3] = currentPixel;
929 neighbors[currentPixel][0] = i;
930 continue;}
931 if (pixelsCoords[i][0] > pixelsCoords[currentPixel][0] &&
932 pixelsCoords[i][1] > pixelsCoords[currentPixel][1]){//top right
933 neighbors[i][4] = currentPixel;
934 neighbors[currentPixel][1] = i;
935 continue;}
936 if (pixelsCoords[i][0] > pixelsCoords[currentPixel][0] &&
937 pixelsCoords[i][1] < pixelsCoords[currentPixel][1]){//bottom right
938 neighbors[i][5] = currentPixel;
939 neighbors[currentPixel][2] = i;
940 continue;}
941 if (pixelsCoords[i][0] < pixelsCoords[currentPixel][0] &&
942 pixelsCoords[i][1] > pixelsCoords[currentPixel][1]){//top left
943 neighbors[i][2] = currentPixel;
944 neighbors[currentPixel][5] = i;
945 continue;}
946 if (pixelsCoords[i][0] < pixelsCoords[currentPixel][0] &&
947 pixelsCoords[i][1] < pixelsCoords[currentPixel][1]){//bottom left
948 neighbors[i][1] = currentPixel;
949 neighbors[currentPixel][4] = i;
950 continue;}
951 }
952 }
953 }
954 void BasicGlCamera::skipPixels(int start, int howMany)
955 {
956 for (int i=start;i<MAX_NUM_PIXELS-howMany;i++)
957 {
958 pixelsCoords[i][0] = pixelsCoords[i+howMany][0];
959 pixelsCoords[i][1] = pixelsCoords[i+howMany][1];
960 }
961 }
962 void BasicGlCamera::calculatePixelsCoords()
963 {
964 if (fabs(pixelsCoords[0][1])>0.000001)
965 return;
966
967 /****************** HAWC's Eye camera layout **************************/
968 if (!isFACT())
969 {
970 static const double gsSin60 = sqrt(3.)/2;
971
972 pixelsCoords[0][0] = 0;
973 pixelsCoords[0][1] = 0;
974
975 uint32_t cnt = 1;
976 for (int32_t ring=1; ring<=4; ring++)
977 {
978 for (int32_t s=0; s<6; s++)
979 {
980 for (int i=1; i<=ring; i++)
981 {
982 switch (s)
983 {
984 case 0: // Direction South East
985 pixelsCoords[cnt][0] = ring-i;
986 pixelsCoords[cnt][1] = (ring+i)*0.5;
987 break;
988
989 case 1: // Direction North East
990 pixelsCoords[cnt][0] = -i;
991 pixelsCoords[cnt][1] = ring-i*0.5;
992 break;
993
994 case 2: // Direction North
995 pixelsCoords[cnt][0] = -ring;
996 pixelsCoords[cnt][1] = ring*0.5-i;
997 break;
998
999 case 3: // Direction North West
1000 pixelsCoords[cnt][0] = -(ring-i);
1001 pixelsCoords[cnt][1] = -(ring+i)*0.5;
1002 break;
1003
1004 case 4: // Direction South West
1005 pixelsCoords[cnt][0] = i;
1006 pixelsCoords[cnt][1] = 0.5*i-ring;
1007 break;
1008
1009 case 5: // Direction South
1010 pixelsCoords[cnt][0] = ring;
1011 pixelsCoords[cnt][1] = i-ring*0.5;
1012 break;
1013
1014 }
1015 cnt++;
1016 }
1017 }
1018 }
1019
1020 pixelsCoords[cnt][0] = -4;
1021 pixelsCoords[cnt][1] = -4;
1022
1023 cnt++;
1024
1025 pixelsCoords[cnt][0] = 4;
1026 pixelsCoords[cnt][1] = -4;
1027
1028 cnt++;
1029
1030 pixelsCoords[cnt][0] = 4;
1031 pixelsCoords[cnt][1] = 4;
1032
1033 cnt++;
1034
1035 for (int i=0; i<8; i++)
1036 {
1037 pixelsCoords[cnt+i][0] = i-3.5;
1038 pixelsCoords[cnt+i][1] = 7.25 + (i%2)*0.75;
1039 }
1040
1041 cnt += 8;
1042
1043 for (;cnt<MAX_NUM_PIXELS; cnt++)
1044 {
1045 pixelsCoords[cnt][0] = 1000;
1046 pixelsCoords[cnt][1] = 1000;
1047 }
1048
1049 for (int i=0; i<MAX_NUM_PIXELS; i++)
1050 {
1051 if (i<64)
1052 {
1053 pixelsCoords[i][1] += 1.5;
1054 pixelsCoords[i][0] *= gsSin60;
1055 }
1056
1057 pixelsCoords[i][0] *= 2*hexRadius;
1058 pixelsCoords[i][1] *= 2*hexRadius;
1059 pixelsCoords[i][2] = 0;
1060 }
1061 }
1062 else
1063 {
1064 /************************ FACT Camera layout **************************/
1065 pixelsCoords[0][0] = 0;
1066 pixelsCoords[0][1] = 0.3 - hexRadius;
1067 pixelsCoords[0][2] = 0;
1068 pixelsCoords[1][0] = 0;
1069 pixelsCoords[1][1] = 0.3+hexRadius;
1070 pixelsCoords[1][2] = 0;
1071 neighbors[0][0] = 1;
1072 neighbors[1][3] = 0;
1073 //from which side of the previous hexagon are we coming from ?
1074 int fromSide = 3;
1075 //to which side are we heading to ?
1076 int toSide = 0;
1077 for (int i=2;i<MAX_NUM_PIXELS;i++)
1078 {
1079 toSide = fromSide-1;
1080 if (toSide < 0)
1081 toSide =5;
1082 while (neighbors[i-1][toSide] >= 0)
1083 {
1084 toSide--;
1085 if (toSide < 0)
1086 toSide = 5;
1087 }
1088 fromSide = toSide + 3;
1089 if (fromSide > 5)
1090 fromSide -= 6;
1091 //ok. now we now in which direction we're heading
1092 pixelsCoords[i][0] = pixelsCoords[i-1][0];
1093 pixelsCoords[i][1] = pixelsCoords[i-1][1];
1094 pixelsCoords[i][2] = pixelsCoords[i-1][2];
1095 switch (toSide)
1096 {
1097 case 0:
1098 pixelsCoords[i][1] += 2*hexRadius;
1099 break;
1100 case 1:
1101 pixelsCoords[i][0] += (2*hexRadius)*sin(M_PI/3.0);
1102 pixelsCoords[i][1] += (2*hexRadius)*cos(M_PI/3.0);
1103 break;
1104 case 2:
1105 pixelsCoords[i][0] += (2*hexRadius)*sin(M_PI/3.0);
1106 pixelsCoords[i][1] -= (2*hexRadius)*cos(M_PI/3.0);
1107 break;
1108 case 3:
1109 pixelsCoords[i][1] -= 2*hexRadius;
1110 break;
1111 case 4:
1112 pixelsCoords[i][0] -= (2*hexRadius)*sin(M_PI/3.0);
1113 pixelsCoords[i][1] -= (2*hexRadius)*cos(M_PI/3.0);
1114 break;
1115 case 5:
1116 pixelsCoords[i][0] -= (2*hexRadius)*sin(M_PI/3.0);
1117 pixelsCoords[i][1] += (2*hexRadius)*cos(M_PI/3.0);
1118 break;
1119 };
1120 // pixelsCoords[i][1] -= hexRadius;
1121
1122 updateNeighbors(i);
1123 }
1124 //Ok. So now we've circled around all the way to MAX_NUM_PIXELS
1125 //do the required shifts so that it matches the fact camera up to ACTUAL_NUM_PIXELS pixels
1126 //remember the location pixels 1438 and 1439, and re-assign them later on
1127 GLfloat backupCoords[4];
1128 skipPixels(1200, 1);
1129 skipPixels(1218, 3);
1130 skipPixels(1236, 1);
1131 skipPixels(1256, 1);
1132 skipPixels(1274, 3);
1133 skipPixels(1292, 3);
1134 skipPixels(1309, 6);
1135 skipPixels(1323, 7);
1136 skipPixels(1337, 6);
1137 skipPixels(1354, 6);
1138 skipPixels(1368, 7);
1139 //la c'est dans 1390 qu'il y a 1439
1140 backupCoords[0] = pixelsCoords[1390][0];
1141 backupCoords[1] = pixelsCoords[1390][1];
1142 skipPixels(1382, 9);
1143 skipPixels(1394, 12);
1144 skipPixels(1402, 15);
1145 skipPixels(1410, 12);
1146 //la c'est dans 1422 qu'il y a 1438
1147 backupCoords[2] = pixelsCoords[1422][0];
1148 backupCoords[3] = pixelsCoords[1422][1];
1149 skipPixels(1422, 12);
1150 skipPixels(1430, 15);
1151
1152 pixelsCoords[1438][0] = backupCoords[2];
1153 pixelsCoords[1438][1] = backupCoords[3];
1154 pixelsCoords[1439][0] = backupCoords[0];
1155 pixelsCoords[1439][1] = backupCoords[1];
1156 }
1157 }
1158
1159 void BasicGlCamera::buildVerticesList()
1160 {
1161 hexTolerance = hexRadius/100.0f;
1162
1163 numVertices = 0;
1164 GLfloat cVertex[2];
1165 for (int i=0;i<NPIX;i++)
1166 {
1167 for (int j=0;j<6;j++)
1168 {
1169 for (int k=0;k<2;k++)
1170 cVertex[k] = hexcoords[j][k]*hexRadius + pixelsCoords[i][k];
1171
1172 bool found = false;
1173 for (int k=0;k<numVertices;k++)
1174 {
1175 if ((cVertex[0] - verticesList[k][0])*
1176 (cVertex[0] - verticesList[k][0]) +
1177 (cVertex[1] - verticesList[k][1])*
1178 (cVertex[1] - verticesList[k][1]) < hexTolerance*hexTolerance)
1179 {
1180 found = true;
1181 break;
1182 }
1183 }
1184 if (!found)
1185 {
1186 for (int k=0;k<2;k++)
1187 verticesList[numVertices][k] = cVertex[k];
1188 numVertices++;
1189 }
1190 }
1191 }
1192//cout << "numVertices: " << numVertices << endl;
1193 for (int i=0;i<NPIX;i++)
1194 {
1195 for (int j=0;j<6;j++)
1196 {
1197 for (int k=0;k<2;k++)
1198 cVertex[k] = hexcoords[j][k]*hexRadius + pixelsCoords[i][k];
1199
1200 for (int k=0;k<numVertices;k++)
1201 {
1202 if ((cVertex[0] - verticesList[k][0])*
1203 (cVertex[0] - verticesList[k][0]) +
1204 (cVertex[1] - verticesList[k][1])*
1205 (cVertex[1] - verticesList[k][1]) < hexTolerance*hexTolerance)
1206 {
1207 verticesIndices[i][j] = k;
1208 break;
1209 }
1210 }
1211 }
1212 }
1213 }
1214 void BasicGlCamera::buildPatchesIndices()
1215 {
1216 vector<edge>::iterator it;
1217 bool erased = false;
1218// patchesIndices.resize(NTMARK);
1219 for (int i=0;i<NTMARK;i++)//for all patches
1220 {
1221 patchesIndices[i].clear();
1222 for (int j=0;j<9;j++)//for all cells of the current patch
1223 {
1224 if (softwareMapping[i*9+j] >= ACTUAL_NUM_PIXELS)
1225 continue;
1226 for (int k=0;k<6;k++)//for all sides of the current cell
1227 {
1228 int first = k-1;
1229 int second = k;
1230 if (first < 0)
1231 first = 5;
1232 erased = false;
1233 for (it=(patchesIndices[i]).begin(); it != (patchesIndices[i]).end(); it++)//check if this side is here already or not
1234 {
1235 const int idx = i*9+j;
1236
1237 if ((it->first == verticesIndices[softwareMapping[idx]][first] &&
1238 it->second == verticesIndices[softwareMapping[idx]][second]) ||
1239 (it->first == verticesIndices[softwareMapping[idx]][second] &&
1240 it->second == verticesIndices[softwareMapping[idx]][first]))
1241 {
1242 patchesIndices[i].erase(it);
1243 erased = true;
1244 break;
1245 }
1246 }
1247 if (!erased)
1248 {
1249 edge temp;
1250 temp.first = verticesIndices[softwareMapping[i*9+j]][first];
1251 temp.second = verticesIndices[softwareMapping[i*9+j]][second];
1252 patchesIndices[i].push_back(temp);
1253 }
1254 }
1255 }
1256 }
1257// for (int i=0;i<NTMARK;i++)
1258// {
1259// cout << ".....................patch " << i << " size: " << patchesIndices[i].size() << endl;
1260// for (unsigned int j=0;j<patchesIndices[i].size();j++)
1261// {
1262// if (patchesIndices[i][j].first < 0 || patchesIndices[i][j].first > 3013)
1263// cout << patchesIndices[i][j].first << " and " << patchesIndices[i][j].second << " and " << j << endl;
1264// }
1265// }
1266 }
1267
Note: See TracBrowser for help on using the repository browser.