ctkVTKColorTransferFunction.cpp

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Library:   CTK
00004  
00005   Copyright (c) 2010  Kitware Inc.
00006 
00007   Licensed under the Apache License, Version 2.0 (the "License");
00008   you may not use this file except in compliance with the License.
00009   You may obtain a copy of the License at
00010 
00011       http://www.commontk.org/LICENSE
00012 
00013   Unless required by applicable law or agreed to in writing, software
00014   distributed under the License is distributed on an "AS IS" BASIS,
00015   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016   See the License for the specific language governing permissions and
00017   limitations under the License.
00018  
00019 =========================================================================*/
00020 
00022 #include <QColor>
00023 #include <QDebug>
00024 
00026 #include "ctkVTKColorTransferFunction.h"
00027 
00029 #include <vtkColorTransferFunction.h>
00030 #include <vtkSmartPointer.h>
00031 
00032 //-----------------------------------------------------------------------------
00033 class ctkVTKColorTransferFunctionPrivate: public ctkPrivate<ctkVTKColorTransferFunction>
00034 {
00035 public:
00036   vtkSmartPointer<vtkColorTransferFunction> ColorTransferFunction;
00037 };
00038 
00039 //-----------------------------------------------------------------------------
00040 ctkVTKColorTransferFunction::ctkVTKColorTransferFunction(QObject* parentObject)
00041   :ctkTransferFunction(parentObject)
00042 {
00043   CTK_INIT_PRIVATE(ctkVTKColorTransferFunction);
00044 }
00045 
00046 //-----------------------------------------------------------------------------
00047 ctkVTKColorTransferFunction::ctkVTKColorTransferFunction(vtkColorTransferFunction* colorTransferFunction, 
00048                                                          QObject* parentObject)
00049   :ctkTransferFunction(parentObject)
00050 {
00051   CTK_INIT_PRIVATE(ctkVTKColorTransferFunction);
00052   this->setColorTransferFunction(colorTransferFunction);
00053 }
00054 
00055 //-----------------------------------------------------------------------------
00056 ctkVTKColorTransferFunction::~ctkVTKColorTransferFunction()
00057 {
00058 }
00059 
00060 //-----------------------------------------------------------------------------
00061 int ctkVTKColorTransferFunction::count()const
00062 {
00063   CTK_D(const ctkVTKColorTransferFunction);
00064   if (d->ColorTransferFunction.GetPointer() == 0)
00065     {
00066     Q_ASSERT(d->ColorTransferFunction.GetPointer());
00067     return -1;
00068     }
00069   return d->ColorTransferFunction->GetSize();
00070 }
00071 
00072 //-----------------------------------------------------------------------------
00073 bool ctkVTKColorTransferFunction::isDiscrete()const
00074 {
00075   return false;
00076 }
00077 
00078 //-----------------------------------------------------------------------------
00079 bool ctkVTKColorTransferFunction::isEditable()const
00080 {
00081   return true;
00082 }
00083 
00084 //-----------------------------------------------------------------------------
00085 void ctkVTKColorTransferFunction::range(qreal& minRange, qreal& maxRange)const
00086 {
00087   CTK_D(const ctkVTKColorTransferFunction);
00088   if (d->ColorTransferFunction.GetPointer() == 0)
00089     {
00090     Q_ASSERT(d->ColorTransferFunction.GetPointer());
00091     minRange = 1.;
00092     maxRange = 0.;
00093     return;
00094     }
00095   double rangeValues[2];
00096   d->ColorTransferFunction->GetRange(rangeValues);
00097   minRange = rangeValues[0];
00098   maxRange = rangeValues[1];
00099 }
00100 
00101 //-----------------------------------------------------------------------------
00102 QVariant ctkVTKColorTransferFunction::minValue()const
00103 {
00104   CTK_D(const ctkVTKColorTransferFunction);
00105   if (d->ColorTransferFunction.GetPointer() == 0)
00106     {
00107     Q_ASSERT(d->ColorTransferFunction.GetPointer());
00108     return -1;
00109     }
00110   double rgb[3];
00111   QColor minValue = QColor::fromRgbF(1.,1.,1.);
00112   for (int i = 0; i < this->count(); ++i)
00113     {
00114     d->ColorTransferFunction->GetColor(i, rgb);
00115     Q_ASSERT(rgb[0] >= 0. && rgb[0] <= 1. &&
00116              rgb[1] >= 0. && rgb[1] <= 1. &&
00117              rgb[2] >= 0. && rgb[2] <= 1.);
00118     QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
00119     if ( qGray(color.red(), color.green(), color.blue()) <
00120          qGray(minValue.red(), minValue.green(), minValue.blue()))
00121       {
00122       minValue = color;
00123       }
00124     }
00125   return minValue;
00126 }
00127 
00128 //-----------------------------------------------------------------------------
00129 QVariant ctkVTKColorTransferFunction::maxValue()const
00130 {
00131   CTK_D(const ctkVTKColorTransferFunction);
00132   if (d->ColorTransferFunction.GetPointer() == 0)
00133     {
00134     Q_ASSERT(d->ColorTransferFunction.GetPointer());
00135     return -1;
00136     }
00137   double rgb[3];
00138   QColor minValue = QColor::fromRgbF(0.,0.,0.);
00139   for (int i = 0; i < this->count(); ++i)
00140     {
00141     d->ColorTransferFunction->GetColor(i, rgb);
00142     Q_ASSERT(rgb[0] >= 0. && rgb[0] <= 1. &&
00143              rgb[1] >= 0. && rgb[1] <= 1. &&
00144              rgb[2] >= 0. && rgb[2] <= 1.);
00145     QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
00146     if ( qGray(color.red(), color.green(), color.blue()) >
00147          qGray(minValue.red(), minValue.green(), minValue.blue()))
00148       {
00149       minValue = color;
00150       }
00151     }
00152   return minValue;
00153 }
00154 
00155 //-----------------------------------------------------------------------------
00156 ctkControlPoint* ctkVTKColorTransferFunction::controlPoint(int index)const
00157 {
00158   CTK_D(const ctkVTKColorTransferFunction);
00159   Q_ASSERT(index >= 0 && index < this->count());
00160   double values[6];
00161   d->ColorTransferFunction->GetNodeValue(index, values);
00162   Q_ASSERT(values[0] >= d->ColorTransferFunction->GetRange()[0] &&
00163            values[0] <= d->ColorTransferFunction->GetRange()[1] &&
00164            values[1] >= 0. && values[1] <= 1. &&  // Red
00165            values[2] >= 0. && values[2] <= 1. &&  // Green
00166            values[3] >= 0. && values[3] <= 1. &&  // Blue
00167            values[4] >= 0. && values[4] <= 1. &&  // MidPoint
00168            values[5] >= 0. && values[5] <= 1.);   // Sharpness
00169   QColor rgb = QColor::fromRgbF(values[1], values[2], values[3]);
00170   if (index + 1 >= this->count())
00171     {
00172     ctkControlPoint* cp = new ctkControlPoint();
00173     cp->P.X = values[0];
00174     cp->P.Value = rgb;
00175     return cp;
00176     }
00177   ctkNonLinearControlPoint* cp = new ctkNonLinearControlPoint();
00178   cp->P.X = values[0];
00179   cp->P.Value = rgb;
00180   double nextValues[6];
00181   d->ColorTransferFunction->GetNodeValue(index + 1, nextValues);
00182   Q_ASSERT(nextValues[0] >= d->ColorTransferFunction->GetRange()[0] &&
00183            nextValues[0] <= d->ColorTransferFunction->GetRange()[1] &&
00184            nextValues[1] >= 0. && nextValues[1] <= 1. &&  // Red
00185            nextValues[2] >= 0. && nextValues[2] <= 1. &&  // Green
00186            nextValues[3] >= 0. && nextValues[3] <= 1. &&  // Blue
00187            nextValues[4] >= 0. && nextValues[4] <= 1. &&  // MidPoint
00188            nextValues[5] >= 0. && nextValues[5] <= 1.);   // Sharpness
00189   // Optimization: don't use SubPoints when the sharpness is 0.
00190   if (values[5] == 0.)
00191     {
00192     cp->SubPoints << ctkPoint(values[0], rgb);
00193     rgb = QColor::fromRgbF(nextValues[1], nextValues[2], nextValues[3]);
00194     cp->SubPoints << ctkPoint(nextValues[0], rgb);
00195     return cp;
00196     } 
00197   double subPoints[30];
00198   d->ColorTransferFunction->GetTable(cp->x(), values[0], 10, subPoints);
00199   qreal interval = (values[0] - cp->x()) / 9.;
00200   for(int i = 0; i < 10; ++i)
00201     {
00202     rgb = QColor::fromRgbF(subPoints[3*i], 
00203                            subPoints[3*i+1],
00204                            subPoints[3*i+2]);
00205     cp->SubPoints << ctkPoint(cp->x() + interval*i, rgb);
00206     }
00207   return cp;
00208 }
00209 
00210 //-----------------------------------------------------------------------------
00211 QVariant ctkVTKColorTransferFunction::value(qreal pos)const
00212 {
00213   CTK_D(const ctkVTKColorTransferFunction);
00214   Q_ASSERT(d->ColorTransferFunction.GetPointer());
00215   double rgb[3];
00216   d->ColorTransferFunction->GetColor(pos, rgb);
00217   QColor color = QColor::fromRgbF(rgb[0], rgb[1], rgb[2]);
00218   return color;
00219 }
00220 
00221 //-----------------------------------------------------------------------------
00222 int ctkVTKColorTransferFunction::insertControlPoint(const ctkControlPoint& cp)
00223 {
00224   CTK_D(ctkVTKColorTransferFunction);
00225   int index = -1;
00226   if (d->ColorTransferFunction.GetPointer() == 0)
00227     {
00228     return index;
00229     }
00230   QColor rgb = cp.value().value<QColor>();
00231   const ctkNonLinearControlPoint* nonLinearCp = dynamic_cast<const ctkNonLinearControlPoint*>(&cp);
00232   if (nonLinearCp)
00233     {
00234     // TODO retrieve midpoint & sharpness
00235     index = d->ColorTransferFunction->AddRGBPoint(
00236       cp.x(), rgb.redF(), rgb.greenF(), rgb.blueF());
00237     }
00238   else
00239     {
00240     index = d->ColorTransferFunction->AddRGBPoint(
00241       cp.x(), rgb.redF(), rgb.greenF(), rgb.blueF());
00242     }
00243   return index;
00244 }
00245 //-----------------------------------------------------------------------------
00246 // insert point with value = 0
00247 int ctkVTKColorTransferFunction::insertControlPoint(qreal pos)
00248 {
00249   // nothing
00250   int index = 0;
00251 
00252   return index;
00253 }
00254 //-----------------------------------------------------------------------------
00255 void ctkVTKColorTransferFunction::setControlPointPos(int index, qreal pos)
00256 {
00257   CTK_D(ctkVTKColorTransferFunction);
00258   double values[6];
00259   d->ColorTransferFunction->GetNodeValue(index, values);
00260   values[0] = pos;
00261   // warning, a possible new range is not supported
00262   // SetNodeValue eventually fire the signal changed()
00263   d->ColorTransferFunction->SetNodeValue(index, values);
00264 }
00265 
00266 //-----------------------------------------------------------------------------
00267 void ctkVTKColorTransferFunction::setControlPointValue(int index, const QVariant& value)
00268 {
00269   CTK_D(ctkVTKColorTransferFunction);
00270   Q_ASSERT(value.value<QColor>().isValid());
00271   QColor rgb = value.value<QColor>();
00272   double values[6];
00273   d->ColorTransferFunction->GetNodeValue(index, values);
00274   values[1] = rgb.redF();
00275   values[2] = rgb.greenF();
00276   values[3] = rgb.blueF();
00277   // setNodeValue should eventually fired the signal changed()
00278   d->ColorTransferFunction->SetNodeValue(index, values);
00279 }
00280 
00281 //-----------------------------------------------------------------------------
00282 void ctkVTKColorTransferFunction::setColorTransferFunction(vtkColorTransferFunction* colorTransferFunction)
00283 {
00284   CTK_D(ctkVTKColorTransferFunction);
00285   d->ColorTransferFunction = colorTransferFunction;
00286   this->qvtkReconnect(d->ColorTransferFunction,vtkCommand::ModifiedEvent,
00287                       this, SIGNAL(changed()));
00288   emit changed();
00289 }
00290 
00291 //-----------------------------------------------------------------------------
00292 vtkColorTransferFunction* ctkVTKColorTransferFunction::colorTransferFunction()const
00293 {
00294   CTK_D(const ctkVTKColorTransferFunction);
00295   return d->ColorTransferFunction;
00296 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated on 21 May 2010 for CTK by  doxygen 1.6.1