OpenWalnut  1.5.0dev
WTransferFunctionHistogram.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <iostream>
27 #include <cmath>
28 #include <vector>
29 
30 #include "WTransferFunctionHistogram.h"
31 #include "WTransferFunctionWidget.h"
32 
33 #include "QPainter"
34 #include "QStyleOption"
35 #include "QGraphicsSceneMouseEvent"
36 
37 
39 {
40  setOpacity( 0.4 );
41  setZValue( 2 );
42 }
43 
45 {
46 }
47 
49 {
50  return scene()->sceneRect();
51 }
52 
53 void WTransferFunctionHistogram::paint( QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget* )
54 {
55  const int steps = m_data.size();
56  if( steps > 0 )
57  {
58  double maxval = *std::max_element( m_data.begin(), m_data.end() );
59  if( maxval > 0.0 )
60  {
61  QRadialGradient gradient( 0.0, 0.0, 10 );
62  painter->setBrush( gradient );
63  gradient.setColorAt( 0, Qt::white );
64  gradient.setColorAt( 1, Qt::black );
65 
66  painter->setBrush( gradient );
67 
68  // polygon for logarithmic mapping ( background )
69  {
70  QPolygon histogram;
71  QRectF bb( this->scene()->sceneRect() );
72  histogram << QPoint( bb.right(), bb.bottom() );
73  histogram << QPoint( bb.left(), bb.bottom() );
74 
75  for( int i = 0; i < steps; ++i )
76  {
77  // logarithmic mapping of histogram to values
78  // the added 0.001 is to avoid numerical problems but should work for most data sets
79  // when changing this value, keep in mind that the value has to work for a wide range of
80  // numbers ( i.e. maxval close to 0 and maxval close to infty )
81  histogram << QPoint( bb.left()+ ( double )bb.width()*( double )i/( double )steps,
82  bb.bottom() - ( double )bb.height() * std::log( m_data[ i ]+1 )/std::log( maxval+1+0.001 ) );
83  }
84  painter->drawPolygon( histogram );
85  }
86  // The paper "Multi-Dimensional Transfer Functions for Interactive Volume Rendering"
87  // by Joe Kniss, Gordon Kindlmann and Charles Hansen
88  // brought the idea of overlaying the logarithmic plot with a non-logarithmic plot
89  // which may help to understand the data a bit better. Maybe this should be a config option,
90  // but for now it is there for whoever likes to see it.
91  //
92  // polygon for non-logarithmic mapping
93  {
94  QPolygon histogram;
95  QRectF bb( this->scene()->sceneRect() );
96  histogram << QPoint( bb.right(), bb.bottom() );
97  histogram << QPoint( bb.left(), bb.bottom() );
98 
99  for( int i = 0; i < steps; ++i )
100  {
101  // linear mapping of histogram to values
102  histogram << QPoint( bb.left()+ ( double )bb.width()*( double )i/( double )steps,
103  bb.bottom() - ( double )bb.height() * m_data[ i ]/maxval );
104  }
105  painter->drawPolygon( histogram );
106  }
107  }
108  }
109 }
110 
111 const std::vector< double >& WTransferFunctionHistogram::getData() const
112 {
113  return m_data;
114 }
115 
116 std::vector< double >& WTransferFunctionHistogram::getData()
117 {
118  return m_data;
119 }
120 
WTransferFunctionHistogram(WTransferFunctionWidget *parent=0x0)
Default constructor.
virtual ~WTransferFunctionHistogram()
Default destructor.
QRectF boundingRect() const
Get the bounding rect of the histogram.
std::vector< double > m_data
the histogram data
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
Paint a semi-transparent histogram on top of the transfer function but below the input handles.
const std::vector< double > & getData() const
Get histogram data.
A widget that holds a scene to display and modify the transfer function.