Developer documentation | Axl-2.5.1

axlVolumeDiscreteEditor.cpp
Go to the documentation of this file.
1 /* axlVolumeDiscreteEditor.cpp ---
2  *
3  * Author: Julien Wintz
4  * Created: Thu Sep 26 14:09:18 2013 (+0200)
5  * Version:
6  * Last-Updated: Wed Oct 9 19:53:34 2013 (+0200)
7  * By: Julien Wintz
8  * Update #: 1681
9  */
10 
11 /* Change Log:
12  *
13  */
14 
17 
18 #include "axlVtkView.h"
19 #include "axlVolumeDiscrete.h"
20 #include "axlActorVolumeDiscrete.h"
21 
22 #include <vtkColorTransferFunction.h>
23 #include <vtkImageAccumulate.h>
24 #include <vtkImageData.h>
25 #include <vtkPiecewiseFunction.h>
26 #include <vtkVolume.h>
27 #include <vtkVolumeProperty.h>
28 
29 #include <ctime>
30 
31 // ///////////////////////////////////////////////////////////////////
32 // Definitions
33 // ///////////////////////////////////////////////////////////////////
34 
35 #define axl_BIN_WIDTH 8
36 
37 // ///////////////////////////////////////////////////////////////////
38 // axlVolumeDiscreteEditorMapper
39 // ///////////////////////////////////////////////////////////////////
40 
42 {
43 public:
44  void setSceneRect(const QRectF& rect);
45  void setHistgRect(const QRectF& rect);
46  void setTableRect(const QRectF& rect);
47 
48 public:
49  QPointF mapFromSceneToHistg(const QPointF& point);
50  QPointF mapFromSceneToTable(const QPointF& point);
51 
52 public:
53  QPointF mapFromHistgToScene(const QPointF& point);
54  QPointF mapFromTableToScene(const QPointF& point);
55 
56 public:
57  QRectF scene_rect;
58  QRectF histg_rect;
59  QRectF table_rect;
60 
61 public:
62  bool use_log;
63  bool use_scl;
64 };
65 
66 // ///////////////////////////////////////////////////////////////////
67 // axlVolumeDiscreteEditorVertex
68 // ///////////////////////////////////////////////////////////////////
69 
70 class axlVolumeDiscreteEditorVertex : public QGraphicsItem
71 {
72 public:
73  axlVolumeDiscreteEditorVertex(QGraphicsItem *parent = 0);
75 
76 public:
77  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
78 
79 public:
80  QRectF boundingRect(void) const;
81 
82 protected:
83  void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
84  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
85 
86 public:
89 };
90 
91 // ///////////////////////////////////////////////////////////////////
92 // axlVolumeDiscreteEditorTable
93 // ///////////////////////////////////////////////////////////////////
94 
95 class axlVolumeDiscreteEditorTable : public QGraphicsItem
96 {
97 public:
98  axlVolumeDiscreteEditorTable(QGraphicsItem *parent = 0);
100 
101 public:
103 
104 public:
105  void update(void);
106 
107 public:
108  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
109 
110 public:
111  QRectF boundingRect(void) const;
112 
113 public:
114  QList<axlVolumeDiscreteEditorVertex *> vertices;
115 
116 public:
120 
121 private:
122  QPointF *points;
123  int point_count;
124 
125 private:
126  QBrush brush;
127 };
128 
129 // ///////////////////////////////////////////////////////////////////
130 // axlVolumeDiscreteEditorScene
131 // ///////////////////////////////////////////////////////////////////
132 
133 class axlVolumeDiscreteEditorScene : public QGraphicsScene
134 {
135 public:
136  axlVolumeDiscreteEditorScene(QObject *parent = 0);
138 
139 public:
140  void setActor(axlActorVolumeDiscrete *actor);
141  void setSceneRect(const QRectF& rect);
142  void setUseLog(bool use);
143  void setUseScl(bool use);
144 
145 public:
146  void drawBackground(QPainter *painter, const QRectF& rect);
147 
148 public:
149  void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
150 
151 public:
154 
155 public:
156  int *bins;
159 
160 private:
161  bool use_log;
162  bool use_scl;
163 
164 private:
165  qreal fct_scl;
166 };
167 
168 // ///////////////////////////////////////////////////////////////////
169 // axlVolumeDiscreteEditorView
170 // ///////////////////////////////////////////////////////////////////
171 
172 class axlVolumeDiscreteEditorView : public QGraphicsView
173 {
174 public:
175  axlVolumeDiscreteEditorView(QWidget *parent = 0);
177 
178 public:
180 
181 public:
182  void resize(const QSize& size);
183  void resizeEvent(QResizeEvent *event);
184 
185 protected:
186  void mouseMoveEvent(QMouseEvent *event);
187 
188 public:
190 };
191 
192 // ///////////////////////////////////////////////////////////////////
193 // axlVolumeDiscreteEditorPrivate
194 // ///////////////////////////////////////////////////////////////////
195 
196 class axlVolumeDiscreteEditorPrivate
197 {
198 public:
199  axlAbstractView *view;
200  axlVolumeDiscrete *volume;
201  axlVolumeDiscreteEditorView *volume_view;
202  axlVolumeDiscreteEditorScene *volume_scene;
203 
204 public:
205  QLineEdit *dim_x;
206  QLineEdit *dim_y;
207  QLineEdit *dim_z;
208 
209 public:
210  QLineEdit *sca_min;
211  QLineEdit *sca_max;
212 
213 public:
214  QRadioButton *log_radio;
215  QRadioButton *scl_radio;
216  QRadioButton *shd_radio;
217 };
218 
219 // ///////////////////////////////////////////////////////////////////
220 // axlVolumeDiscreteEditorMapper
221 // ///////////////////////////////////////////////////////////////////
222 
224 {
225  this->scene_rect = rect;
226 }
227 
229 {
230  this->histg_rect = rect;
231 }
232 
234 {
235  this->table_rect = rect;
236 }
237 
239 {
240  qreal x = point.x();
241  qreal y = point.y();
242 
243  qreal s_x = this->scene_rect.x();
244  qreal s_y = this->scene_rect.y();
245  qreal s_w = this->scene_rect.width();
246  qreal s_h = this->scene_rect.height();
247 
248  qreal h_x = this->histg_rect.x();
249  qreal h_y = this->histg_rect.y();
250  qreal h_w = this->histg_rect.width();
251  qreal h_h = this->histg_rect.height();
252 
253  if(this->use_log) {
254  if (y > 0)
255  y = log(y);
256  h_y = log(h_y);
257  h_h = log(h_h);
258  }
259 
260  qreal a_x = +h_w/s_w;
261  qreal a_y = -h_h/s_h;
262  qreal b_x = h_x-(h_w/s_w)*s_x;
263  qreal b_y = (s_h*(h_y+h_h)+h_h*s_y)/s_h;
264 
265  return QPointF(a_x*x+b_x, a_y*y+b_y);
266 }
267 
269 {
270  qreal x = point.x();
271  qreal y = point.y();
272 
273  qreal s_x = this->scene_rect.x();
274  qreal s_y = this->scene_rect.y();
275  qreal s_w = this->scene_rect.width();
276  qreal s_h = this->scene_rect.height();
277 
278  qreal h_x = this->table_rect.x();
279  qreal h_y = this->table_rect.y();
280  qreal h_w = this->table_rect.width();
281  qreal h_h = this->table_rect.height();
282 
283  qreal a_x = +h_w/s_w;
284  qreal a_y = -h_h/s_h;
285  qreal b_x = h_x-(h_w/s_w)*s_x;
286  qreal b_y = (s_h*(h_y+h_h)+h_h*s_y)/s_h;
287 
288  return QPointF(a_x*x+b_x, a_y*y+b_y);
289 }
290 
292 {
293  qreal x = point.x();
294  qreal y = point.y();
295 
296  qreal s_x = this->scene_rect.x();
297  qreal s_y = this->scene_rect.y();
298  qreal s_w = this->scene_rect.width();
299  qreal s_h = this->scene_rect.height();
300 
301  qreal h_x = this->histg_rect.x();
302  qreal h_y = this->histg_rect.y();
303  qreal h_w = this->histg_rect.width();
304  qreal h_h = this->histg_rect.height();
305 
306  if(this->use_log) {
307  if (y > 0)
308  y = log(y);
309  h_y = log(h_y);
310  h_h = log(h_h);
311  }
312 
313  qreal a_x = +s_w/h_w;
314  qreal a_y = -s_h/h_h;
315  qreal b_x = s_x-(s_w/h_w)*h_x;
316  qreal b_y = (s_h*(h_y+h_h)+h_h*s_y)/h_h;
317 
318  return QPointF(a_x*x+b_x, a_y*y+b_y);
319 }
320 
322 {
323  qreal x = point.x();
324  qreal y = point.y();
325 
326  qreal s_x = this->scene_rect.x();
327  qreal s_y = this->scene_rect.y();
328  qreal s_w = this->scene_rect.width();
329  qreal s_h = this->scene_rect.height();
330 
331  qreal h_x = this->table_rect.x();
332  qreal h_y = this->table_rect.y();
333  qreal h_w = this->table_rect.width();
334  qreal h_h = this->table_rect.height();
335 
336  qreal a_x = +s_w/h_w;
337  qreal a_y = -s_h/h_h;
338  qreal b_x = s_x-(s_w/h_w)*h_x;
339  qreal b_y = (s_h*(h_y+h_h)+h_h*s_y)/h_h;
340 
341  return QPointF(a_x*x+b_x, a_y*y+b_y);
342 }
343 
344 // ///////////////////////////////////////////////////////////////////
345 // axlVolumeDiscreteEditorVertex
346 // ///////////////////////////////////////////////////////////////////
347 
348 axlVolumeDiscreteEditorVertex::axlVolumeDiscreteEditorVertex(QGraphicsItem *parent) : QGraphicsItem(parent)
349 {
350  this->foreground_color = QColor(0x00, 0x00, 0xff);
351  this->background_color = QColor(0x33, 0x33, 0x33);
352 
353  this->setPos(0, 0);
354 
355  this->setFlag(QGraphicsItem::ItemIsMovable, true);
356  this->setFlag(QGraphicsItem::ItemIsSelectable, true);
357 
358  this->setCursor(Qt::ArrowCursor);
359 }
360 
362 {
363 
364 }
365 
366 void axlVolumeDiscreteEditorVertex::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
367 {
368  Q_UNUSED(option);
369  Q_UNUSED(widget);
370 
371  painter->setRenderHints(QPainter::Antialiasing, true);
372 
373  if(this->isSelected())
374  painter->setPen(Qt::magenta);
375  else
376  painter->setPen(QColor(0x55, 0x55, 0x55));
377 
378  painter->setBrush(this->background_color); painter->drawEllipse(-10.0, -10.0, 20.0, 20.0);
379  painter->setBrush(this->foreground_color); painter->drawEllipse(-05.0, -05.0, 10.0, 10.0);
380 }
381 
383 {
384  return QRectF(-10.0, -10.0, 20.0, 20.0);
385 }
386 
387 void axlVolumeDiscreteEditorVertex::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
388 {
389  Q_UNUSED(event);
390 
391  this->foreground_color = QColorDialog::getColor(this->foreground_color, 0, "Choose vertex color");
392  this->update();
393 
394  if(axlVolumeDiscreteEditorTable *table = dynamic_cast<axlVolumeDiscreteEditorTable *>(this->parentItem()))
395  table->update();
396 }
397 
398 void axlVolumeDiscreteEditorVertex::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
399 {
400  QGraphicsItem::mouseMoveEvent(event);
401 
402  axlVolumeDiscreteEditorTable *table = dynamic_cast<axlVolumeDiscreteEditorTable *>(this->parentItem());
403 
404  if (table)
405  table->update();
406 }
407 
408 // ///////////////////////////////////////////////////////////////////
409 // axlVolumeDiscreteEditorTable
410 // ///////////////////////////////////////////////////////////////////
411 
412 axlVolumeDiscreteEditorTable::axlVolumeDiscreteEditorTable(QGraphicsItem *parent) : QGraphicsItem(parent)
413 {
414  this->view = NULL;
415  this->actor = NULL;
416  this->brush = QColor::fromRgb(255, 0, 0, 128);
417 
418  this->points = NULL;
419  this->point_count = 0;
420 }
421 
423 {
424 
425 }
426 
427 static QColor axlVolumeDiscreteEditorTableColor(axlVolumeDiscreteEditorVertex *vertex)
428 {
429  qreal h = vertex->scene()->sceneRect().height();
430  qreal y = vertex->scenePos().y();
431  qreal r = 1.0 - y/h;
432 
433  if (r > 1.0)
434  r = 1.0;
435 
436  if (r < 0.0)
437  r = 0.0;
438 
439  QColor c = vertex->foreground_color; c.setAlphaF(r);
440 
441  return c;
442 }
443 
444 static bool axlVolumeDiscreteEditorTableSort(const axlVolumeDiscreteEditorVertex *v1, const axlVolumeDiscreteEditorVertex *v2) {
445  return (v1->pos().x() < v2->pos().x());
446 }
447 
449 {
450  this->vertices << vertex;
451 
452  vertex->setParentItem(this);
453 
454  this->update();
455 }
456 
457 QPointF axlVolumeDiscreteEditorTableClamp(const QPointF& point, const QRectF& rect)
458 {
459  QPointF value = point;
460 
461  if (value.y() < rect.y())
462  value.setY(rect.y());
463 
464  if(value.y() > rect.height())
465  value.setY(rect.height());
466 
467  return value;
468 }
469 
471 {
472  // ///////////////////////////////////////////////////////////////////
473  // vtk side
474  // ///////////////////////////////////////////////////////////////////
475 
476  vtkColorTransferFunction *color = static_cast<vtkColorTransferFunction *>(this->actor->colorTransferFunction());
477  color->RemoveAllPoints();
478 
479  vtkPiecewiseFunction *opacity = static_cast<vtkPiecewiseFunction *>(this->actor->opacityTransferFunction());
480  opacity->RemoveAllPoints();
481 
482  // ///////////////////////////////////////////////////////////////////
483 
484  if(this->vertices.isEmpty())
485  return;
486 
487  if(this->points)
488  delete [] this->points;
489 
490  qSort(vertices.begin(), vertices.end(), axlVolumeDiscreteEditorTableSort);
491 
492  this->point_count = this->vertices.size()+4;
493  this->points = new QPointF[this->point_count];
494 
495  points[0] = QPointF(0, this->scene()->sceneRect().height());
496  points[1] = QPointF(0, this->vertices.first()->pos().y());
497 
498  QLinearGradient gradient(0, 0, this->scene()->sceneRect().width(), 0.0);
499  gradient.setColorAt(0, axlVolumeDiscreteEditorTableColor(this->vertices.first()));
500 
501  for(int i = 0 ; i < this->vertices.count() ; i++) {
502 
503  points[i+2] = this->vertices.at(i)->pos();
504 
505  qreal x = this->vertices.at(i)->pos().x();
506  qreal w = this->scene()->sceneRect().width();
507  qreal r = x/w;
508 
509  if (r < 0.0)
510  r = 0.0;
511 
512  if (r > 1.0)
513  r = 1.0;
514 
515  gradient.setColorAt(r, axlVolumeDiscreteEditorTableColor(this->vertices.at(i)));
516 
517  // ///////////////////////////////////////////////////////////////////
518  // vtk side
519  // ///////////////////////////////////////////////////////////////////
520 
521  QPointF value = this->mapper->mapFromSceneToTable(axlVolumeDiscreteEditorTableClamp(this->vertices.at(i)->scenePos(), this->scene()->sceneRect()));
522 
523  color->AddRGBPoint(value.x(),
524  this->vertices.at(i)->foreground_color.redF(),
525  this->vertices.at(i)->foreground_color.greenF(),
526  this->vertices.at(i)->foreground_color.blueF());
527 
528  opacity->AddPoint(value.x(), value.y());
529 
530  // ///////////////////////////////////////////////////////////////////
531  }
532 
533  points[this->vertices.count()+2] = QPointF(this->scene()->sceneRect().width(), this->vertices.last()->pos().y());
534  points[this->vertices.count()+3] = QPointF(this->scene()->sceneRect().width(), this->scene()->sceneRect().height());
535 
536  gradient.setColorAt(1.0, axlVolumeDiscreteEditorTableColor(this->vertices.last()));
537 
538  this->brush = QBrush(gradient);
539 
540  QGraphicsItem::update();
541 
542  // ///////////////////////////////////////////////////////////////////
543  // vtk side
544  // ///////////////////////////////////////////////////////////////////
545 
546  static_cast<vtkVolumeProperty *>(this->actor->volumeProperty())->Modified();
547  static_cast<vtkVolume *>(this->actor->vol())->Update();
548 
549  // ///////////////////////////////////////////////////////////////////
550 
551  if (view)
552  view->update();
553 }
554 
555 void axlVolumeDiscreteEditorTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
556 {
557  Q_UNUSED(option);
558  Q_UNUSED(widget);
559 
560  if(this->vertices.isEmpty())
561  return;
562 
563  painter->setPen(Qt::NoPen);
564  painter->setBrush(this->brush);
565  painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
566  painter->setRenderHints(QPainter::Antialiasing, true);
567  painter->drawPolygon(this->points, this->point_count);
568 }
569 
571 {
572  if(!this->point_count)
573  return QRectF();
574 
575  return QRectF(this->points[0].x(), 0.0, this->points[this->point_count-1].x(), this->scene()->sceneRect().height());
576 }
577 
578 // ///////////////////////////////////////////////////////////////////
579 // axlVolumeDiscreteEditorScene
580 // ///////////////////////////////////////////////////////////////////
581 
582 axlVolumeDiscreteEditorScene::axlVolumeDiscreteEditorScene(QObject *parent) : QGraphicsScene(parent)
583 {
584  this->bins = NULL;
585  this->bin_min = 0;
586  this->bin_max = 0;
587  this->use_log = true;
588  this->use_scl = false;
590  this->mapper->use_log = true;
591  this->mapper->use_scl = false;
593  this->table->mapper = this->mapper;
594 
595  this->addItem(this->table);
596  this->setBackgroundBrush(QColor(0x00, 0x00, 0x00));
597 }
598 
600 {
601  delete this->mapper;
602 }
603 
605 {
606  vtkImageData *image = static_cast<vtkImageData *>(actor->image());
607 
608  // this->bin_min = image->GetScalarRange()[0];
609  // this->bin_max = image->GetScalarRange()[1];
610  this->bin_min = dynamic_cast<axlVolumeDiscrete *>(actor->data())->minValue();
611  this->bin_max = dynamic_cast<axlVolumeDiscrete *>(actor->data())->maxValue();
612 
613  vtkImageAccumulate *histogram = vtkImageAccumulate::New();
614  histogram->SetComponentExtent(this->bin_min, this->bin_max, 0, 0, 0, 0);
615 #if (VTK_MAJOR_VERSION <= 5)
616  histogram->SetInput(image);
617 #else
618  histogram->SetInputData(image);
619 #endif
620  histogram->SetIgnoreZero(true);
621  histogram->Update();
622 
623  this->bins = static_cast<int*>(histogram->GetOutput()->GetScalarPointer());
624 
625  this->hst_min = INT_MAX;
626  this->hst_max = INT_MIN;
627 
628  for(int i = this->bin_min; i < this->bin_max; i++) {
629  this->hst_min = qMin(this->hst_min, this->bins[i-bin_min]);
630  this->hst_max = qMax(this->hst_max, this->bins[i-bin_min]);
631  }
632 
633 
634  this->mapper->setHistgRect(QRectF(this->bin_min, this->hst_min, this->bin_max-this->bin_min, this->hst_max-this->hst_min));
635  this->mapper->setTableRect(QRectF(this->bin_min, 0, this->bin_max-this->bin_min, 1.0));
636 
637  this->table->actor = actor;
638 }
639 
641 {
642  QRectF scene_rect = rect;
643 
644  QPointF blc = mapper->mapFromHistgToScene(QPointF(0, 0));
645  QPointF brc = mapper->mapFromHistgToScene(QPointF(1, 0));
646 
647  if(this->use_scl)
648  scene_rect.setWidth(rect.width() * this->fct_scl);
649 
650  this->mapper->use_log = this->use_log;
651  this->mapper->use_scl = this->use_scl;
652  this->mapper->setSceneRect(scene_rect);
653 
654  QGraphicsScene::setSceneRect(scene_rect);
655 
656  if(!this->table->vertices.empty())
657  return;
658 
659  qreal min_x = this->bin_min;
660  qreal mid_x = (this->bin_max-this->bin_min)/2.0;
661  qreal max_x = this->bin_max-this->bin_min;
662 
664  min->foreground_color = Qt::blue;
665  min->setPos(mapper->mapFromHistgToScene(QPointF(min_x, 0.0)));
666  min->setPos(min->scenePos().x(), rect.height()/2.0);
667 
669  mid->foreground_color = Qt::green;
670  mid->setPos(mapper->mapFromHistgToScene(QPointF(mid_x, 0.0)));
671  mid->setPos(mid->scenePos().x(), rect.height()/2.0);
672 
674  max->foreground_color = Qt::red;
675  max->setPos(mapper->mapFromHistgToScene(QPointF(max_x, 0.0)));
676  max->setPos(max->scenePos().x(), rect.height()/2.0);
677 
678  this->table->append(min);
679  this->table->append(mid);
680  this->table->append(max);
681 }
683 {
684  this->use_log = use;
685  this->mapper->use_log = use;
686 }
687 
689 {
690  this->use_scl = use;
691  this->mapper->use_scl = use;
692 
693  if (use) {
694  QPointF blc = mapper->mapFromHistgToScene(QPointF(0, 0));
695  QPointF brc = mapper->mapFromHistgToScene(QPointF(1, 0));
696  this->fct_scl = axl_BIN_WIDTH / (brc.x() - blc.x());
697  } else {
698  this->fct_scl = 1 / this->fct_scl;
699  }
700 
701  foreach(axlVolumeDiscreteEditorVertex *vertex, this->table->vertices)
702  vertex->setPos(vertex->pos().x()*this->fct_scl, vertex->pos().y());
703 }
704 
705 void axlVolumeDiscreteEditorScene::drawBackground(QPainter *painter, const QRectF& rect)
706 {
707  QGraphicsScene::drawBackground(painter, rect);
708 
709  qreal h_x = this->mapper->histg_rect.x();
710  // qreal h_y = this->mapper->histg_rect.y();
711  qreal h_w = this->mapper->histg_rect.width();
712  // qreal h_h = this->mapper->histg_rect.height();
713 
714  if (this->use_scl)
715  painter->setPen(QColor(0x35, 0x35, 0x35));
716  else
717  painter->setPen(Qt::NoPen);
718 
719  painter->setBrush(QColor(0x77, 0x77, 0xf7));
720 
721  for(int i = h_x; i < h_x+h_w; i++) {
722  QPointF b_l = mapper->mapFromHistgToScene(QPointF(i+0, 0));
723  QPointF t_r = mapper->mapFromHistgToScene(QPointF(i+1, bins[i-int(h_x)]));
724  painter->drawRect(QRectF(b_l, t_r));
725  }
726 }
727 
728 void axlVolumeDiscreteEditorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
729 {
730  QGraphicsItem *item = this->items(event->scenePos()).first();
731 
732  if(item && dynamic_cast<axlVolumeDiscreteEditorVertex *>(item)) {
733  QGraphicsScene::mouseDoubleClickEvent(event);
734  return;
735  }
736 
738  vertex->setPos(event->scenePos());
739  vertex->setSelected(true);
740 
741  this->table->append(vertex);
742 }
743 
744 // ///////////////////////////////////////////////////////////////////
745 // axlVolumeDiscreteEditorView
746 // ///////////////////////////////////////////////////////////////////
747 
748 axlVolumeDiscreteEditorView::axlVolumeDiscreteEditorView(QWidget *parent) : QGraphicsView(parent)
749 {
750  this->scene = NULL;
751 
752  this->setAttribute(Qt::WA_MacShowFocusRect, false);
753  this->setCursor(Qt::CrossCursor);
754  this->setFrameShape(QFrame::NoFrame);
755  this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
756  this->setMouseTracking(true);
757  this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
758  this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
759 
760  this->setMinimumHeight(300);
761 }
762 
764 {
765 
766 }
767 
769 {
770  QGraphicsView::setScene(scene);
771 
772  this->scene = scene;
773 }
774 
776 {
777  QGraphicsView::mouseMoveEvent(event);
778 
779  QPointF point = scene->mapper->mapFromSceneToTable(this->mapToScene(event->pos()));
780 
781  QString x = QString::number(point.x(), 'f', 2);
782  QString y = QString::number(point.y(), 'f', 2);
783 
784  this->setToolTip(QString("(%1, %2)").arg(x).arg(y));
785 }
786 
787 void axlVolumeDiscreteEditorView::resize(const QSize& size)
788 {
789  QGraphicsView::resize(size);
790 
791  this->scene->setSceneRect(QRectF(QPointF(0, 0), size));
792  this->scene->update();
793 }
794 
796 {
797  QGraphicsView::resizeEvent(event);
798 
799  this->scene->setSceneRect(QRectF(QPointF(0, 0), event->size()));
800 }
801 
802 // ///////////////////////////////////////////////////////////////////
803 // axlVolumeDiscreteEditor
804 // ///////////////////////////////////////////////////////////////////
805 
806 axlVolumeDiscreteEditor::axlVolumeDiscreteEditor(QWidget *parent) : axlAbstractVolumeDiscreteEditor(parent), d(new axlVolumeDiscreteEditorPrivate)
807 {
808  d->volume = NULL;
809  d->view = NULL;
810 
811  d->volume_scene = new axlVolumeDiscreteEditorScene(this);
812 
813  d->volume_view = new axlVolumeDiscreteEditorView(this);
814  d->volume_view->setScene(d->volume_scene);
815  d->volume_view->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
816 
817  d->dim_x = new QLineEdit(this);
818  d->dim_x->setReadOnly(true);
819 
820  d->dim_y = new QLineEdit(this);
821  d->dim_y->setReadOnly(true);
822 
823  d->dim_z = new QLineEdit(this);
824  d->dim_z->setReadOnly(true);
825 
826  d->sca_min = new QLineEdit(this);
827  d->sca_min->setReadOnly(true);
828 
829  d->sca_max = new QLineEdit(this);
830  d->sca_max->setReadOnly(true);
831 
832  d->log_radio = new QRadioButton(this);
833  d->log_radio->setAutoExclusive(false);
834  d->log_radio->setChecked(true);
835 
836  d->scl_radio = new QRadioButton(this);
837  d->scl_radio->setAutoExclusive(false);
838  d->scl_radio->setChecked(false);
839 
840  d->shd_radio = new QRadioButton(this);
841  d->shd_radio->setAutoExclusive(false);
842  d->shd_radio->setChecked(false);
843 
844  QPushButton *outline_none = new QPushButton("None", this);
845  outline_none->setCheckable(true);
846  outline_none->setChecked(true);
847  outline_none->setObjectName("left");
848 
849  QPushButton *outline_corners = new QPushButton("Corners", this);
850  outline_corners->setCheckable(true);
851  outline_corners->setChecked(false);
852  outline_corners->setObjectName("middle");
853 
854  QPushButton *outline_box = new QPushButton("Box", this);
855  outline_box->setCheckable(true);
856  outline_box->setChecked(false);
857  outline_box->setObjectName("middle");
858 
859  QPushButton *outline_contour = new QPushButton("Contour", this);
860  outline_contour->setCheckable(true);
861  outline_contour->setChecked(false);
862  outline_contour->setObjectName("right");
863 
864  QButtonGroup *outline_group = new QButtonGroup(this);
865  outline_group->addButton(outline_none);
866  outline_group->addButton(outline_corners);
867  outline_group->addButton(outline_box);
868  outline_group->addButton(outline_contour);
869 
870  QHBoxLayout *outline_layout = new QHBoxLayout;
871  outline_layout->setSpacing(0);
872  outline_layout->addWidget(outline_none);
873  outline_layout->addWidget(outline_corners);
874  outline_layout->addWidget(outline_box);
875  outline_layout->addWidget(outline_contour);
876 
877  QHBoxLayout *dim_l = new QHBoxLayout;
878  dim_l->addWidget(d->dim_x);
879  dim_l->addWidget(d->dim_y);
880  dim_l->addWidget(d->dim_z);
881 
882  QHBoxLayout *sca_l = new QHBoxLayout;
883  sca_l->addWidget(d->sca_min);
884  sca_l->addWidget(d->sca_max);
885 
886  QFormLayout *b_layout = new QFormLayout;
887  b_layout->setContentsMargins(10, 10, 10, 10);
888  b_layout->setSpacing(10);
889  b_layout->addRow("Dimensions", dim_l);
890  b_layout->addRow("Scalar range", sca_l);
891  b_layout->addRow("Logarithmic count", d->log_radio);
892  b_layout->addRow("Scaled values", d->scl_radio);
893  b_layout->addRow("Shaded rendering", d->shd_radio);
894 
895  QVBoxLayout *layout = new QVBoxLayout(this);
896  layout->setContentsMargins(0, 0, 0, 0);
897  layout->setSpacing(0);
898  layout->addWidget(d->volume_view);
899  layout->addWidget(new axlInspectorSeparator(this));
900  layout->addLayout(b_layout);
901  layout->addLayout(outline_layout);
902 
903  connect(d->log_radio, SIGNAL(toggled(bool)), this, SLOT(onLogChecked(bool)));
904  connect(d->scl_radio, SIGNAL(toggled(bool)), this, SLOT(onSclChecked(bool)));
905  connect(d->shd_radio, SIGNAL(toggled(bool)), this, SLOT(onShdChecked(bool)));
906 
907  connect(outline_none, SIGNAL(clicked()), this, SLOT(outlineNone()));
908  connect(outline_corners, SIGNAL(clicked()), this, SLOT(outlineCorners()));
909  connect(outline_box, SIGNAL(clicked()), this, SLOT(outlineBox()));
910  connect(outline_contour, SIGNAL(clicked()), this, SLOT(outlineContour()));
911 }
912 
914 {
915  delete d;
916 }
917 
918 
920 {
922 }
923 
925 {
926  return new axlVolumeDiscreteEditor;
927 }
928 
929 
930 
932 {
933  if(!(d->volume = dynamic_cast<axlVolumeDiscrete *>(volume)))
934  return;
935 
936  d->dim_x->setText(QString::number(d->volume->xDimension()));
937  d->dim_y->setText(QString::number(d->volume->yDimension()));
938  d->dim_z->setText(QString::number(d->volume->zDimension()));
939 
940  if(!d->view){
941  qDebug() << Q_FUNC_INFO << "no view selected";
942  }
943  if(!d->view->actor(d->volume)){
944  qDebug() << Q_FUNC_INFO << "no actor found";
945  }
946  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
947 
948  if (actor)
949  d->volume_scene->setActor(actor);
950 
951  d->sca_min->setText(QString::number(d->volume_scene->bin_min));
952  d->sca_max->setText(QString::number(d->volume_scene->bin_max));
953 }
954 
956 {
957  d->view = view;
958  d->volume_scene->table->view = view;
959 }
960 
962 {
963  d->volume_scene->setUseLog(checked);
964  d->volume_scene->mapper->use_log = checked;
965  d->volume_scene->update();
966 }
967 
969 {
970  d->volume_scene->setUseScl(checked);
971  d->volume_view->resize(d->volume_view->size());
972  d->volume_scene->table->update();
973  d->volume_scene->update();
974 }
975 
977 {
978  if(!d->view)
979  return;
980 
981  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
982 
983  vtkVolumeProperty *property = static_cast<vtkVolumeProperty *>(actor->volumeProperty());
984  property->SetShade(checked);
985  property->Modified();
986 
987  vtkVolume *volume = static_cast<vtkVolume *>(actor->vol());
988  volume->Update();
989 
990  d->view->update();
991 }
992 
994 {
995  if(!d->view)
996  return;
997 
998  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
999 
1000  actor->outlineNone();
1001 
1002  d->view->update();
1003 }
1004 
1006 {
1007  if(!d->view)
1008  return;
1009 
1010  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
1011 
1012  actor->outlineCorners();
1013 
1014  d->view->update();
1015 }
1016 
1018 {
1019  if(!d->view)
1020  return;
1021 
1022  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
1023 
1024  actor->outlineBox();
1025 
1026  d->view->update();
1027 }
1028 
1030 {
1031  if(!d->view)
1032  return;
1033 
1034  axlActorVolumeDiscrete *actor = dynamic_cast<axlActorVolumeDiscrete *>(d->view->actor(d->volume));
1035 
1036  actor->outlineContour();
1037 
1038  d->view->update();
1039 }
bool registerInspectorObject(const QString &interface_name, axlInspectorObjectCreator func)
dtkAbstractData * data(void)
axlInspectorObjectInterface * createaxlVolumeDiscreteEditor(void)
QList< axlVolumeDiscreteEditorVertex * > vertices
QPointF mapFromHistgToScene(const QPointF &point)
void resizeEvent(QResizeEvent *event)
axlVolumeDiscreteEditor(QWidget *parent=0)
void setSceneRect(const QRectF &rect)
void setActor(axlActorVolumeDiscrete *actor)
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
void setVolume(axlAbstractVolumeDiscrete *volume)
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
#define axl_BIN_WIDTH
QPointF axlVolumeDiscreteEditorTableClamp(const QPointF &point, const QRectF &rect)
axlVolumeDiscreteEditorScene * scene
static axlInspectorObjectFactory * instance(void)
axlVolumeDiscreteEditorView(QWidget *parent=0)
virtual void update(void)
void append(axlVolumeDiscreteEditorVertex *vertex)
QPointF mapFromSceneToTable(const QPointF &point)
QPointF mapFromTableToScene(const QPointF &point)
axlVolumeDiscreteEditorTable * table
axlVolumeDiscreteEditorMapper * mapper
axlVolumeDiscreteEditorTable(QGraphicsItem *parent=0)
void mouseMoveEvent(QMouseEvent *event)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
axlVolumeDiscreteEditorVertex(QGraphicsItem *parent=0)
void drawBackground(QPainter *painter, const QRectF &rect)
void setScene(axlVolumeDiscreteEditorScene *scene)
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
QPointF mapFromSceneToHistg(const QPointF &point)
void setView(axlAbstractView *view)
axlVolumeDiscreteEditorMapper * mapper