tecorrec: Check for OpenGL and add includes/libs
[tecorrec.git] / geo / tcIlluminantDirection.cpp
blobca88d0591baa14a61a954b13ca10b2bce15c3aae
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 /**
21 * @file tcIlluminantDirection.cpp
22 * @brief Illuminant direction based calculation.
25 #include "tcIlluminantDirection.h"
26 #include "tcChannelConfigWidget.h"
27 #include "tcChannel.h"
29 #include <QObject>
30 #include <QVBoxLayout>
31 #include <QPushButton>
34 * Constructors + destructor
37 /// Primary constructor.
38 tcIlluminantDirection::tcIlluminantDirection(const QList<tcChannel*>& chromaticities,
39 int outputs, const QString& name, const QString& description)
40 : tcChannelGroup(outputs, name, description)
41 , m_chromaticities(chromaticities)
42 , m_illuminantDirection(chromaticities.size(), 1.0f)
43 , m_illuminantDirectionSamples(0)
44 , m_configWidget(0)
46 m_illuminantDirection.normalize();
49 /// Destructor.
50 tcIlluminantDirection::~tcIlluminantDirection()
52 delete m_configWidget;
56 * Accessors
59 /// Get the number of chromaticity channels.
60 int tcIlluminantDirection::numChromaticities() const
62 return m_chromaticities.size();
65 /// Get the list of chromaticitiy channels.
66 const QList<tcChannel*>& tcIlluminantDirection::chromaticities() const
68 return m_chromaticities;
71 /// Get the illuminant direction.
72 const maths::VarVector<float>& tcIlluminantDirection::illuminantDirection() const
74 return m_illuminantDirection;
78 * Main image interface
81 tcChannelConfigWidget* tcIlluminantDirection::configWidget()
83 if (0 == m_configWidget)
85 m_configWidget = new tcChannelConfigWidget();
86 m_configWidget->setWindowTitle(tr("%1 Configuration").arg(name()));
88 QVBoxLayout* layout = new QVBoxLayout(m_configWidget);
90 // Create a button which triggers an illuminant direction reset.
91 QPushButton* btnReset = new QPushButton(tr("Reset illuminant direction"), m_configWidget);
92 layout->addWidget(btnReset);
93 connect(btnReset, SIGNAL(clicked(bool)), this, SLOT(resetIlluminantDirection()));
95 // Create a button which triggers texture point request.
96 QPushButton* btnNewShadowNonShadow = new QPushButton(tr("Choose Shadow/Non-Shadow transition"), m_configWidget);
97 layout->addWidget(btnNewShadowNonShadow);
98 connect(btnNewShadowNonShadow, SIGNAL(clicked(bool)), this, SLOT(startShadowNonShadow()));
100 return m_configWidget;
104 * Private slots
107 /// Reset the illuminant direction vector.
108 void tcIlluminantDirection::resetIlluminantDirection()
110 for (int i = 0; i < m_illuminantDirection.length(); ++i)
112 m_illuminantDirection[i] = 1.0f;
114 m_illuminantDirectionSamples = 0;
115 invalidate();
116 m_configWidget->requestRedraw();
119 /// Start choosing a shadow / non shadow pair.
120 void tcIlluminantDirection::startShadowNonShadow()
122 Q_ASSERT(0 != m_configWidget);
123 m_configWidget->requestTexturePoint(this, SLOT(selectShadowPoint(const maths::Vector<2,float>&)));
126 /// New shadow point.
127 void tcIlluminantDirection::selectShadowPoint(const maths::Vector<2,float>& point)
129 Q_ASSERT(0 != m_configWidget);
130 m_shadowPoint = point;
131 m_configWidget->requestTexturePoint(this, SLOT(selectNonShadowPoint(const maths::Vector<2,float>&)));
134 /// New non-shadow point.
135 void tcIlluminantDirection::selectNonShadowPoint(const maths::Vector<2,float>& point)
137 Q_ASSERT(0 != m_configWidget);
138 // Find the direction between the log chromaticities of the two points
139 for (int i = 0; i < m_chromaticities.size(); ++i)
141 tcChannel* channel = m_chromaticities[i];
142 Reference<tcAbstractPixelData> pixelData = channel->portion();
143 if (0 != pixelData)
145 float delta = pixelData->sampleFloat(point[0], 1.0f - point[1])
146 - pixelData->sampleFloat(m_shadowPoint[0], 1.0f - m_shadowPoint[1]);
147 m_illuminantDirection[i] *= m_illuminantDirectionSamples;
148 m_illuminantDirection[i] += delta;
149 m_illuminantDirection[i] /= m_illuminantDirectionSamples+1;
152 m_illuminantDirection.normalize();
153 ++m_illuminantDirectionSamples;
154 invalidate();
155 m_configWidget->requestRedraw();
159 * Interface for derived class to implement
162 void tcIlluminantDirection::roundPortion(double* x1, double* y1, double* x2, double* y2)
164 if (!m_chromaticities.empty())
166 m_chromaticities[0]->roundPortion(x1,y1,x2,y2);
170 void tcIlluminantDirection::loadPortions(double x1, double y1, double x2, double y2, bool changed)
172 QList< Reference< tcPixelData<float> > > chromaticityData;
173 int width = 0;
174 int height = 0;
175 foreach (tcChannel* channel, m_chromaticities)
177 /// @todo Make this neater
178 double x1a = x1;
179 double y1a = y1;
180 double x2a = x2;
181 double y2a = y2;
182 Reference< tcPixelData<float> > pixelData = dynamicCast< tcPixelData<GLfloat>* >(channel->portion(&x1a,&y1a,&x2a,&y2a));
183 chromaticityData += pixelData;
184 Q_ASSERT(0 != pixelData);
185 // Ensure each channel is the same resolution
186 if (0 == width)
188 width = pixelData->width();
190 else
192 Q_ASSERT(width == pixelData->width());
194 if (0 == height)
196 height = pixelData->height();
198 else
200 Q_ASSERT(height == pixelData->height());
203 loadPortions(chromaticityData, width, height);