00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "GradientEditor.h"
00040 #include "HoverPoints.h"
00041 #include <fstream>
00042 #include <QWidget>
00043
00044 static int start = 0;
00045
00046 GradientEditor::GradientEditor(QWidget *parent, Qt::WindowFlags flags)
00047 : QWidget(parent, flags)
00048 {
00049 printf("creating GradientEditor\n");
00050
00051 setWindowTitle("Transferfunktion");
00052 m_parent = parent;
00053
00054 vbox = new QVBoxLayout(this);
00055 vbox->setSpacing(1);
00056 vbox->setMargin(1);
00057
00058 m_red_shade = new ShadeWidget(ShadeWidget::RedShade, this, "red" );
00059 m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this, "green" );
00060 m_blue_shade = new ShadeWidget(ShadeWidget::BlueShade, this, "blue" );
00061 m_alpha_shade = new ShadeWidget(ShadeWidget::ARGBShade, this, "alpha" );
00062
00063 vbox->addWidget( m_red_shade );
00064 vbox->addWidget( m_green_shade );
00065 vbox->addWidget( m_blue_shade );
00066 vbox->addWidget( m_alpha_shade, 3 );
00067
00068 connect(m_red_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00069 connect(m_green_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00070 connect(m_blue_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00071 connect(m_alpha_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00072
00073 if(start++)
00074 show();
00075 }
00076
00077
00078
00079
00080
00081
00082 inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
00083 {
00084 return p1.x() < p2.x();
00085 }
00086
00087
00088
00089 void GradientEditor::pointsUpdated()
00090 {
00091 double w = m_alpha_shade->width();
00092
00093 QGradientStops stops;
00094
00095 QPolygonF points;
00096
00097 points += m_red_shade->points();
00098 points += m_green_shade->points();
00099 points += m_blue_shade->points();
00100 points += m_alpha_shade->points();
00101
00102 qSort(points.begin(), points.end(), x_less_than);
00103
00104 for (int i=0; i<points.size(); ++i)
00105 {
00106 double x = int( points.at(i).x() );
00107
00108 if ( i < points.size()-1 && x == points.at(i+1).x() )
00109 continue;
00110
00111
00112 QColor color((0x00ff0000 & m_red_shade->colorAt(int(x))) >> 16,
00113 (0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8,
00114 (0x000000ff & m_blue_shade->colorAt(int(x))),
00115 (0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24);
00116
00117
00118
00119
00120
00121
00122
00123
00124 if (x / w > 1)
00125 return;
00126
00127 stops << QGradientStop(x / w, color);
00128 }
00129
00130 m_alpha_shade->setGradientStops(stops);
00131
00132 emit gradientStopsChanged(stops);
00133 }
00134
00135 void GradientEditor::showHistogram(const int *density)
00136 {
00137 m_alpha_shade->setHistogram(density);
00138 this->update();
00139 }
00140
00141 void GradientEditor::clearHistogram()
00142 {
00143 m_alpha_shade->clearHistogram();
00144 this->update();
00145
00146 }
00147
00148
00149 static void set_shade_points(const QPolygonF &points, ShadeWidget *shade)
00150 {
00151 shade->hoverPoints()->setPoints(points);
00152 shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft);
00153 shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight);
00154 shade->update();
00155 }
00156
00157 void GradientEditor::setGradientStops(const QGradientStops &stops)
00158 {
00159 QPolygonF pts_red, pts_green, pts_blue, pts_alpha;
00160
00161 double h_red = m_red_shade->height();
00162 double h_green = m_green_shade->height();
00163 double h_blue = m_blue_shade->height();
00164 double h_alpha = m_alpha_shade->height();
00165
00166 for (int i=0; i<stops.size(); ++i) {
00167 double pos = stops.at(i).first;
00168 QRgb color = stops.at(i).second.rgba();
00169 pts_red << QPointF(pos * m_red_shade->width(), h_red - qRed(color) * h_red / 255);
00170 pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255);
00171 pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255);
00172 pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255);
00173 }
00174
00175 set_shade_points(pts_red, m_red_shade);
00176 set_shade_points(pts_green, m_green_shade);
00177 set_shade_points(pts_blue, m_blue_shade);
00178 set_shade_points(pts_alpha, m_alpha_shade);
00179 }
00180
00181 void GradientEditor::loadTransferFunction( std::string filename )
00182 {
00183 ShadeWidget* shades[SHADES_COUNT] = { m_red_shade, m_green_shade, m_blue_shade, m_alpha_shade };
00184 QPolygonF pts;
00185 QGradientStops stops;
00186 int shadeIndex = -1;
00187 float px, py;
00188 std::string line, num;
00189
00190
00191 std::ifstream in(filename.c_str());
00192
00193 if(!in)
00194 std::cerr << "- Error opening file!" << std::endl << std::endl;
00195
00196 while(std::getline(in, line))
00197 {
00198
00199 for(int s = 0; s < SHADES_COUNT; s++)
00200 {
00201 if(!line.compare(shades[s]->getName()))
00202 {
00203 if(shadeIndex != -1)
00204 {
00205 shades[shadeIndex]->setPoints(pts);
00206 shades[shadeIndex]->update();
00207 pts.clear();
00208 }
00209
00210
00211 shadeIndex = s;
00212 break;
00213 }
00214 }
00215
00216 if(isdigit(line.at(0)))
00217 {
00218 sscanf_s(line.c_str(), "%f %f\n", &px, &py);
00219 pts << QPointF(px, py);
00220 }
00221
00222 }
00223
00224
00225 shades[ALPHA]->setPoints(pts);
00226 pointsUpdated();
00227 }
00228
00229 void GradientEditor::saveTransferFunction( std::string filename )
00230 {
00231 ShadeWidget* shades[SHADES_COUNT] = { m_red_shade, m_green_shade, m_blue_shade, m_alpha_shade };
00232 QGradientStops stops;
00233 QPolygonF pts;
00234 int px, py;
00235
00236 FILE *fp = NULL;
00237 fopen_s( &fp, filename.c_str(), "w" );
00238
00239 if(!fp)
00240 std::cerr << "- Error saving file!" << std::endl << std::endl;
00241
00242
00243 for( int s = 0; s < SHADES_COUNT; s++ )
00244 {
00245
00246 fprintf(fp, "%s\n", shades[s]->getName().c_str());
00247
00248 pts = shades[s]->points();
00249 stops = shades[s]->getGradientStops();
00250
00251
00252 for( int i = 0; i < pts.size(); i++ )
00253 {
00254 px = (int) pts.at(i).x();
00255 py = (int) pts.at(i).y();
00256 fprintf(fp, "%d %d\n", px, py);
00257 }
00258 }
00259
00260 fclose(fp);
00261 }