Browse Source

ENH: Move curve/point/gradient computation into ctkTransferFunctionRepresentation

The code relative to computation of the curve, points and gradients was in
ctkTransferFunctionScene but the scene can't do it as it is supposed to
support more than 1 transfer function at a time. Use ctkTransferFunctionRepresentation
instead.
Julien Finet 15 years ago
parent
commit
967df459ac

+ 3 - 0
Libs/Core/CMakeLists.txt

@@ -47,6 +47,8 @@ SET(KIT_SRCS
   ctkSingleton.h
   ctkTransferFunction.cpp
   ctkTransferFunction.h
+  ctkTransferFunctionRepresentation.cpp
+  ctkTransferFunctionRepresentation.h
   ctkUtils.cpp
   ctkUtils.h
   )
@@ -64,6 +66,7 @@ SET(KIT_MOC_SRCS
   ctkHistogram.h
   ctkModelTester.h
   ctkTransferFunction.h
+  ctkTransferFunctionRepresentation.h
   )
 
 # UI files

+ 25 - 0
Libs/Core/ctkTransferFunction.cpp

@@ -19,6 +19,7 @@
 =========================================================================*/
 /// CTK includes
 #include "ctkTransferFunction.h"
+#include "ctkTransferFunctionRepresentation.h"
 
 //-----------------------------------------------------------------------------
 ctkControlPoint::~ctkControlPoint()
@@ -36,9 +37,26 @@ ctkNonLinearControlPoint::~ctkNonLinearControlPoint()
 }
 
 //-----------------------------------------------------------------------------
+class ctkTransferFunctionPrivate:public ctkPrivate<ctkTransferFunction>
+{
+public:
+  ctkTransferFunctionPrivate();
+  ctkTransferFunctionRepresentation* Representation;
+};
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionPrivate::ctkTransferFunctionPrivate()
+{
+  this->Representation = 0;
+}
+
+//-----------------------------------------------------------------------------
 ctkTransferFunction::ctkTransferFunction(QObject* parentObject)
   :QObject(parentObject)
 {
+  CTK_INIT_PRIVATE(ctkTransferFunction);
+  CTK_D(ctkTransferFunction);
+  d->Representation = new ctkTransferFunctionRepresentation(this);
 }
 
 //-----------------------------------------------------------------------------
@@ -51,3 +69,10 @@ ctkTransferFunction::~ctkTransferFunction()
   // this->ControlPoints->clear();
   // emit changed();
 }
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionRepresentation* ctkTransferFunction::representation()const
+{
+  CTK_D(const ctkTransferFunction);
+  return d->Representation;
+}

+ 8 - 0
Libs/Core/ctkTransferFunction.h

@@ -28,8 +28,12 @@
 #include <QVariant>
 
 /// CTK includes
+#include "ctkPimpl.h"
 #include "CTKCoreExport.h"
 
+class ctkTransferFunctionPrivate;
+class ctkTransferFunctionRepresentation;
+
 //-----------------------------------------------------------------------------
 struct CTK_CORE_EXPORT ctkPoint
 {
@@ -104,8 +108,12 @@ public:
   /// be careful with it, as changing the value might require
   /// more changes to ctkControlPoint.
   virtual void setControlPointValue(int index, const QVariant& value)=0;
+
+  ctkTransferFunctionRepresentation* representation()const;
 signals:
   void changed();
+private:
+  CTK_DECLARE_PRIVATE(ctkTransferFunction);
 };
 
 //-----------------------------------------------------------------------------

+ 510 - 0
Libs/Core/ctkTransferFunctionRepresentation.cpp

@@ -0,0 +1,510 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+/// Qt includes
+#include <QGraphicsScene>
+#include <QLinearGradient>
+#include <QResizeEvent>
+#include <QDebug>
+
+/// CTK includes
+#include "ctkTransferFunction.h"
+#include "ctkTransferFunctionRepresentation.h"
+
+/// STL includes
+#include <limits>
+
+//-----------------------------------------------------------------------------
+class ctkTransferFunctionRepresentationPrivate: public ctkPrivate<ctkTransferFunctionRepresentation>
+{
+  CTK_DECLARE_PUBLIC(ctkTransferFunctionRepresentation);
+public:
+  ctkTransferFunctionRepresentationPrivate();
+
+  ctkTransferFunction* TransferFunction;
+  QColor               VerticalGradientColor;
+
+  QPainterPath         Path;
+  QLinearGradient      Gradient;
+  QList<QPointF>       Points;
+
+  QRectF       rect()const;
+  qreal        width()const;
+  qreal        height()const;
+
+  qreal        WorldRangeX[2];
+  QVariant     WorldRangeY[2];
+  qreal        RangeXDiff;
+  qreal        RangeXOffSet;
+  qreal        RangeYDiff;
+  qreal        RangeYOffSet;
+};
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionRepresentationPrivate::ctkTransferFunctionRepresentationPrivate()
+{
+  this->TransferFunction = 0;
+  this->VerticalGradientColor = QColor::fromRgbF(1., 0., 0., 1. );
+}
+
+//-----------------------------------------------------------------------------
+QRectF ctkTransferFunctionRepresentationPrivate::rect()const
+{
+  return QRectF(0.,0.,1.,1.);
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentationPrivate::width()const
+{
+  return 1.;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentationPrivate::height()const
+{
+  return 1.;
+}
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionRepresentation::ctkTransferFunctionRepresentation(QObject* parentObject)
+  :QObject(parentObject)
+{
+  CTK_INIT_PRIVATE(ctkTransferFunctionRepresentation);
+}
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionRepresentation::ctkTransferFunctionRepresentation(
+  ctkTransferFunction* transferFunction, QObject* parentObject)
+  :QObject(parentObject)
+{
+  CTK_INIT_PRIVATE(ctkTransferFunctionRepresentation);
+  this->setTransferFunction(transferFunction);
+}
+
+//-----------------------------------------------------------------------------
+ctkTransferFunctionRepresentation::~ctkTransferFunctionRepresentation()
+{
+}
+
+//-----------------------------------------------------------------------------
+QColor ctkTransferFunctionRepresentation::verticalGradientColor() const
+{
+  CTK_D( const ctkTransferFunctionRepresentation );
+  return d->VerticalGradientColor;
+}
+//-----------------------------------------------------------------------------
+void ctkTransferFunctionRepresentation::setVerticalGradientColor( QColor verticalGradientColor )
+{
+  CTK_D( ctkTransferFunctionRepresentation );
+  d->VerticalGradientColor = verticalGradientColor;
+}
+
+//-----------------------------------------------------------------------------
+void ctkTransferFunctionRepresentation::setTransferFunction(ctkTransferFunction* transferFunction)
+{
+  CTK_D(ctkTransferFunctionRepresentation);
+  if (d->TransferFunction == transferFunction)
+    {
+    return;
+    }
+  d->TransferFunction = transferFunction;
+  connect( d->TransferFunction, SIGNAL(changed()),
+           this, SLOT(onTransferFunctionChanged()),
+           Qt::UniqueConnection);
+  this->onTransferFunctionChanged();
+}
+
+//-----------------------------------------------------------------------------
+ctkTransferFunction* ctkTransferFunctionRepresentation::transferFunction()const
+{
+  return ctk_d()->TransferFunction;
+}
+
+//-----------------------------------------------------------------------------
+void ctkTransferFunctionRepresentation::onTransferFunctionChanged()
+{
+  CTK_D(ctkTransferFunctionRepresentation);
+  // delete cache here
+  d->Path = QPainterPath();
+  d->Points.clear();
+}
+
+//-----------------------------------------------------------------------------
+const QPainterPath& ctkTransferFunctionRepresentation::curve()const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  if (d->Path.isEmpty())
+    {
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeGradient();
+    }
+  return d->Path;
+}
+
+//-----------------------------------------------------------------------------
+const QList<QPointF>& ctkTransferFunctionRepresentation::points()const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  if (d->Path.isEmpty())
+    {
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeGradient();
+    }
+  return d->Points;
+}
+
+//-----------------------------------------------------------------------------
+const QGradient& ctkTransferFunctionRepresentation::gradient()const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  if (d->Path.isEmpty())
+    {
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeCurve();
+    const_cast<ctkTransferFunctionRepresentation*>(this)->computeGradient();
+    }
+  return d->Gradient;
+}
+
+//-----------------------------------------------------------------------------
+void ctkTransferFunctionRepresentation::computeCurve()
+{
+  CTK_D(ctkTransferFunctionRepresentation);
+
+  int count = d->TransferFunction ? d->TransferFunction->count() : 0;
+  if (count <= 0)
+    {
+    return;
+    }
+  qDebug() << "computeCurve" << d->rect();
+  d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
+  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
+  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
+
+  d->RangeXDiff   = this->computeRangeXDiff(d->rect(), d->WorldRangeX);
+  d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
+
+  d->RangeYDiff   = this->computeRangeYDiff(d->rect(), d->WorldRangeY);
+  d->RangeYOffSet = this->computeRangeYOffset(d->WorldRangeY);
+
+  ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
+  ctkControlPoint* nextCP = 0;
+
+  QPointF startPos = this->mapPointToScene(startCP);
+
+  d->Points.clear();
+  d->Points << startPos;
+
+  d->Path = QPainterPath();
+  d->Path.moveTo(startPos);
+  for(int i = 1; i < count; ++i)
+    {
+    nextCP = d->TransferFunction->controlPoint(i);
+    if (this->transferFunction()->isDiscrete())
+      {
+      QPointF nextPos = this->mapPointToScene(nextCP);
+      qreal midPosX = (startPos.x() + nextPos.x()) / 2.;
+
+      d->Path.lineTo(QPointF(midPosX, startPos.y()));
+      d->Path.lineTo(QPointF(midPosX, nextPos.y()));
+
+      d->Points << nextPos;
+      startPos = nextPos;
+      if (i == count -1)
+        {
+        d->Path.lineTo(nextPos);
+        }
+      }
+    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP))
+      {
+      QList<ctkPoint> points = this->nonLinearPoints(startCP, nextCP);
+      int j;
+      for (j = 1; j < points.count(); ++j)
+        {
+        d->Path.lineTo(this->mapPointToScene(points[j]));
+        }
+      j = points.count() - 1;
+      d->Points << this->mapPointToScene(points[j]);
+      }
+    else //dynamic_cast<ctkBezierControlPoint*>(startCP))
+      {
+      QList<ctkPoint> points = this->bezierParams(startCP, nextCP);
+      QList<ctkPoint>::iterator it = points.begin();
+      QList<QPointF> bezierPoints;
+      foreach(const ctkPoint& p, points)
+        {
+        bezierPoints << this->mapPointToScene(p);
+        }
+      d->Path.cubicTo(bezierPoints[1], bezierPoints[2], bezierPoints[3]);
+      d->Points << bezierPoints[3];
+      }
+    //qDebug() << i << points[0] << points[1] << points[2] << points[3];
+    delete startCP;
+    startCP = nextCP;
+    }
+  if (startCP)
+    {
+    delete startCP;
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkTransferFunctionRepresentation::computeGradient()
+{
+  CTK_D(ctkTransferFunctionRepresentation);
+
+  int count = d->TransferFunction ? d->TransferFunction->count() : 0;
+  if (count <= 0)
+    {
+    return;
+    }
+  qDebug() << "computeCurve" << d->rect();
+  d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
+  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
+  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
+
+  d->RangeXDiff   = this->computeRangeXDiff(QRectF(0.,0.,1.,1.), d->WorldRangeX);
+  d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
+
+  d->RangeYDiff   = this->computeRangeYDiff(QRectF(0.,0.,1.,1.), d->WorldRangeY);
+  d->RangeYOffSet = this->computeRangeYOffset(d->WorldRangeY);
+
+  ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
+  ctkControlPoint* nextCP = 0;
+
+  qreal startPos = this->mapXToScene(this->posX(startCP->x()));
+  qreal nextPos;
+
+  //
+  //if we have no colors in value (i.e. can't convert value to color)
+  if (! d->TransferFunction->value(0).canConvert<QColor>())
+    {
+    // create vertical gradient
+    d->Gradient = QLinearGradient(0., 0., 0., 1.);
+    // red
+    d->Gradient.setColorAt(0, d->VerticalGradientColor );
+    // to black
+    d->Gradient.setColorAt(1, QColor::fromRgbF(0., 0., 0., 1. ));
+    return;
+    }
+
+  // classic gradient if we have colors in value
+  d->Gradient = QLinearGradient(0., 0., 1., 0.);
+  d->Gradient.setColorAt(startPos, this->color(startCP));
+  for(int i = 1; i < count; ++i)
+    {
+    nextCP = d->TransferFunction->controlPoint(i);
+    nextPos = this->mapXToScene(this->posX(nextCP));
+    if (this->transferFunction()->isDiscrete())
+      {
+      qreal midPoint = (startPos + nextPos)  / 2;
+      d->Gradient.setColorAt(midPoint, this->color(startCP));
+      d->Gradient.setColorAt(midPoint + std::numeric_limits<qreal>::epsilon(), this->color(nextCP));
+      }
+    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP))
+      {
+      QList<ctkPoint> points = this->nonLinearPoints(startCP, nextCP);
+      foreach(const ctkPoint& p, points)
+        {
+        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
+        }
+      //no need, d->Gradient.setColorAt(nextPos, this->color(nextCP));
+      }
+    else //dynamic_cast<ctkBezierControlPoint*>(startCP))
+      { // TODO handle bezier points with color
+      QList<ctkPoint> points = this->bezierParams(startCP, nextCP);
+      QList<ctkPoint>::iterator it = points.begin();
+      QList<QPointF> bezierPoints;
+      foreach(const ctkPoint& p, points)
+        {
+        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
+        }
+      nextPos = this->mapXToScene(this->posX(points[points.size() - 1]));
+      }
+    //qDebug() << i << points[0] << points[1] << points[2] << points[3];
+    delete startCP;
+    startCP = nextCP;
+    startPos = nextPos;
+    }
+  d->Gradient.setColorAt(startPos, this->color(startCP));
+  if (startCP)
+    {
+    delete startCP;
+    }
+}
+
+//-----------------------------------------------------------------------------
+QList<ctkPoint> ctkTransferFunctionRepresentation::bezierParams(
+  ctkControlPoint* start, ctkControlPoint* end) const
+{
+  Q_ASSERT(start);
+  Q_ASSERT(end);
+  QList<ctkPoint> points;
+
+  ctkBezierControlPoint* bezierCP = dynamic_cast<ctkBezierControlPoint*>(start);
+  if (!bezierCP)
+    {// just duplicate start and end into p1 and p2
+    points << start->P;
+    points << start->P;
+    points << end->P;
+    points << end->P;
+    return points;
+    }
+
+  points << start->P;
+  points << bezierCP->P1;
+  points << bezierCP->P2;
+  points << end->P;
+  return points;
+}
+
+//-----------------------------------------------------------------------------
+QList<ctkPoint> ctkTransferFunctionRepresentation::nonLinearPoints(
+  ctkControlPoint* start, ctkControlPoint* end) const
+{
+  Q_ASSERT(start);
+
+  ctkNonLinearControlPoint* nonLinearCP =
+    dynamic_cast<ctkNonLinearControlPoint*>(start);
+  if (!nonLinearCP)
+    {
+    QList<ctkPoint> points;
+    points << start->P;
+    points << end->P;
+    return points;
+    }
+  return nonLinearCP->SubPoints;
+}
+
+//-----------------------------------------------------------------------------
+QColor ctkTransferFunctionRepresentation::color(const QVariant& v) const
+{
+  //Q_ASSERT(v.canConvert<QColor>());
+  if (v.canConvert<QColor>())
+    {
+    return v.value<QColor>();
+    }
+  else
+    {
+    //black background
+    QColor defaultColor(0., 0., 0.);
+    return defaultColor;
+    }
+  return QColor();
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::computeRangeXDiff(const QRectF& rect, qreal rangeX[2])
+{
+  return rect.width() / (rangeX[1] - rangeX[0]);
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::computeRangeXOffset(qreal rangeX[2])
+{
+  return rangeX[0];
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::computeRangeYDiff(const QRectF& rect, const QVariant rangeY[2])
+{
+  qreal rangeYDiff = rect.height();
+  qreal rangePosY[2];
+  rangePosY[0] = this->posY(rangeY[0]);
+  rangePosY[1] = this->posY(rangeY[1]);
+  if (rangePosY[1] == rangePosY[0])
+    {
+    rangeYDiff /= rangePosY[0];
+    return rangeYDiff;
+    }
+  rangeYDiff /= rangePosY[1] - rangePosY[0];
+  return rangeYDiff;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::computeRangeYOffset(const QVariant rangeY[2])
+{
+  qreal rangePosY[2];
+  rangePosY[0] = this->posY(rangeY[0]);
+  rangePosY[1] = this->posY(rangeY[1]);
+
+  if (rangePosY[1] == rangePosY[0])
+    {
+    return 0.;
+    }
+  return rangePosY[0];
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::posX(const qreal& x)const
+{
+  return x;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::posY(const QVariant& value)const
+{
+  Q_ASSERT(value.canConvert<qreal>() || value.canConvert<QColor>());
+  if (value.canConvert<QColor>())
+    {
+    return value.value<QColor>().alphaF();
+    }
+  return value.toReal();
+}
+
+//-----------------------------------------------------------------------------
+QPointF ctkTransferFunctionRepresentation::mapPointToScene(const ctkControlPoint* cp)const
+{
+  return QPointF(this->mapXToScene(this->posX(cp->x())),
+                 this->mapYToScene(this->posY(cp->value())));
+}
+
+//-----------------------------------------------------------------------------
+QPointF ctkTransferFunctionRepresentation::mapPointToScene(const ctkPoint& point)const
+{
+  return QPointF( this->mapXToScene(this->posX(point.X)),
+                  this->mapYToScene(this->posY(point.Value)));
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::mapXToScene(qreal xPos)const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  return (xPos - d->RangeXOffSet) * d->RangeXDiff;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::mapYToScene(qreal yPos)const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  return d->height() - (yPos - d->RangeYOffSet) * d->RangeYDiff;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::mapXFromScene(qreal scenePosX)const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  return (scenePosX / d->RangeXDiff) + d->RangeXOffSet;
+}
+
+//-----------------------------------------------------------------------------
+qreal ctkTransferFunctionRepresentation::mapYFromScene(qreal scenePosY)const
+{
+  CTK_D(const ctkTransferFunctionRepresentation);
+  return ((d->height() - scenePosY) / d->RangeYDiff) + d->RangeYOffSet ;
+}

+ 130 - 0
Libs/Core/ctkTransferFunctionRepresentation.h

@@ -0,0 +1,130 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+#ifndef __ctkTransferFunctionRepresentation_h
+#define __ctkTransferFunctionRepresentation_h
+
+/// Qt includes
+#include <QColor>
+#include <QGradient>
+#include <QObject>
+#include <QPainterPath>
+
+/// CTK includes
+#include "ctkPimpl.h"
+#include "ctkTransferFunction.h"
+#include "CTKCoreExport.h"
+
+class ctkTransferFunction;
+class ctkTransferFunctionRepresentationPrivate;
+
+//-----------------------------------------------------------------------------
+class CTK_CORE_EXPORT ctkTransferFunctionRepresentation: public QObject
+{
+  Q_OBJECT
+  Q_PROPERTY(QColor VerticalGradientColor READ verticalGradientColor WRITE setVerticalGradientColor)
+
+public:
+  ctkTransferFunctionRepresentation(QObject* parent = 0);
+  ctkTransferFunctionRepresentation(ctkTransferFunction* transferFunction, QObject* parent = 0);
+  virtual ~ctkTransferFunctionRepresentation();
+
+  void setTransferFunction(ctkTransferFunction* transferFunction);
+  ctkTransferFunction* transferFunction()const;
+
+  inline qreal posX(const ctkControlPoint* cp)const;
+  inline qreal posY(const ctkControlPoint* cp)const;
+  inline QColor color(const ctkControlPoint* cp) const;
+
+  inline qreal posX(const ctkPoint& point)const;
+  inline qreal posY(const ctkPoint& point)const;
+  inline QColor color(const ctkPoint& point) const;
+
+  qreal posX(const qreal& tfX)const;
+  qreal posY(const QVariant& tfV)const;
+  QColor color(const QVariant& tfV) const;
+
+  QPointF mapPointToScene(const ctkControlPoint* cp)const;
+  QPointF mapPointToScene(const ctkPoint& point)const;
+
+  qreal mapXToScene(qreal posX)const;
+  qreal mapYToScene(qreal posY)const;
+  qreal mapXFromScene(qreal ScenePosX)const;
+  qreal mapYFromScene(qreal ScenePosY)const;
+  inline QPointF mapPointFromScene(const QPointF& point)const;
+
+  QList<ctkPoint> bezierParams(ctkControlPoint* start, ctkControlPoint* end) const;
+  QList<ctkPoint> nonLinearPoints(ctkControlPoint* start, ctkControlPoint* end) const;
+
+  const QPainterPath& curve()const;
+  const QList<QPointF>& points()const;
+  const QGradient& gradient()const;
+
+  void computeCurve();
+  void computeGradient();
+
+  QColor verticalGradientColor()const;
+  void setVerticalGradientColor(QColor verticalGradientColor);
+
+protected slots:
+  virtual void onTransferFunctionChanged();
+
+protected:
+  qreal computeRangeXDiff(const QRectF& rect, qreal rangeX[2]);
+  qreal computeRangeXOffset(qreal rangeX[2]);
+  qreal computeRangeYDiff(const QRectF& rect, const QVariant rangeY[2]);
+  qreal computeRangeYOffset(const QVariant rangeY[2]);
+private:
+  CTK_DECLARE_PRIVATE(ctkTransferFunctionRepresentation);
+};
+
+qreal ctkTransferFunctionRepresentation::posX(const ctkControlPoint* cp)const
+{
+  return this->posX(cp->x());
+}
+qreal ctkTransferFunctionRepresentation::posY(const ctkControlPoint* cp)const
+{
+  return this->posY(cp->value());
+}
+QColor ctkTransferFunctionRepresentation::color(const ctkControlPoint* cp) const
+{
+  return this->color(cp->value());
+}
+
+qreal ctkTransferFunctionRepresentation::posX(const ctkPoint& point)const
+{
+  return this->posX(point.X);
+}
+qreal ctkTransferFunctionRepresentation::posY(const ctkPoint& point)const
+{
+  return this->posY(point.Value);
+}
+QColor ctkTransferFunctionRepresentation::color(const ctkPoint& point) const
+{
+  return this->color(point.Value);
+}
+
+QPointF ctkTransferFunctionRepresentation::mapPointFromScene(const QPointF& point)const
+{
+  return QPointF(this->mapXFromScene(point.x()),
+                 this->mapYFromScene(point.y()));
+}
+
+#endif

+ 0 - 1
Libs/Visualization/VTK/Core/ctkVTKColorTransferFunction.cpp

@@ -63,7 +63,6 @@ int ctkVTKColorTransferFunction::count()const
   CTK_D(const ctkVTKColorTransferFunction);
   if (d->ColorTransferFunction.GetPointer() == 0)
     {
-    Q_ASSERT(d->ColorTransferFunction.GetPointer());
     return -1;
     }
   return d->ColorTransferFunction->GetSize();

+ 1 - 1
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkTransferFunctionWidgetTest5.cpp

@@ -59,7 +59,7 @@ int ctkTransferFunctionWidgetTest5(int argc, char * argv [] )
   transferFunctionWidget.show();
   ctkTransferFunctionBarsItem * histogramItem = new ctkTransferFunctionBarsItem;
   histogramItem->setTransferFunction(histogram.data());
-  qobject_cast<ctkTransferFunctionScene*>(transferFunctionWidget.scene())->setTransferFunction(histogram.data());
+  //qobject_cast<ctkTransferFunctionScene*>(transferFunctionWidget.scene())->setTransferFunction(histogram.data());
   transferFunctionWidget.scene()->addItem(histogramItem);
 
   QTimer autoExit;

+ 8 - 4
Libs/Widgets/ctkTransferFunctionBarsItem.cpp

@@ -29,6 +29,7 @@
 /// CTK includes
 #include "ctkTransferFunction.h"
 #include "ctkTransferFunctionBarsItem.h"
+#include "ctkTransferFunctionRepresentation.h"
 #include "ctkTransferFunctionScene.h"
 
 // std includes
@@ -119,9 +120,11 @@ void ctkTransferFunctionBarsItem::paint(
     return;
     }
 
-  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
-  Q_ASSERT(tfScene);
-  const QList<QPointF>& points = tfScene->points();
+  ctkTransferFunctionRepresentation* tfRep = this->transferFunction()->representation();
+  //ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  //Q_ASSERT(tfScene);
+  //const QList<QPointF>& points = tfScene->points();
+  const QList<QPointF>& points = tfRep->points();
 
   QPainterPath bars;
   QPen pen( QColor(255, 255, 255, 191), 1);
@@ -152,7 +155,8 @@ void ctkTransferFunctionBarsItem::paint(
     qreal barHeight = point.y();
     if (useLog && barHeight != 1.)
       {
-      barHeight = this->rect().height() - log( tfScene->mapYFromScene(barHeight) )/log(this->transferFunction()->maxValue().toReal());// 1. - (-log(barHeight)/100.);
+      //barHeight = this->rect().height() - log( tfScene->mapYFromScene(barHeight) )/log(this->transferFunction()->maxValue().toReal());// 1. - (-log(barHeight)/100.);
+      barHeight = this->rect().height() - log( tfRep->mapYFromScene(barHeight) )/log(this->transferFunction()->maxValue().toReal());// 1. - (-log(barHeight)/100.);
       }
     bars.addRect(point.x() - barWidth/2, this->rect().height(),
                  barWidth, barHeight - this->rect().height() );

+ 15 - 10
Libs/Widgets/ctkTransferFunctionControlPointsItem.cpp

@@ -30,6 +30,7 @@
 
 /// CTK includes
 #include "ctkTransferFunctionControlPointsItem.h"
+#include "ctkTransferFunctionRepresentation.h"
 #include "ctkTransferFunctionScene.h"
 #include "ctkTransferFunctionWidget.h"
 
@@ -94,16 +95,17 @@ void ctkTransferFunctionControlPointsItem::paint(
     return;
     }
 
-  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
-  Q_ASSERT(tfScene);
+  //ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  //Q_ASSERT(tfScene);
+  ctkTransferFunctionRepresentation* tfRep = this->transferFunction()->representation();
   
-  const QPainterPath& curve = tfScene->curve();
+  const QPainterPath& curve = tfRep->curve();
   QPen pen(QColor(255, 255, 255, 191), 1);
   pen.setCosmetic(true);
   painter->setPen(pen);
   painter->drawPath(curve);
 
-  d->ControlPoints = tfScene->points();
+  d->ControlPoints = tfRep->points();
   painter->setBrush(QBrush(QColor(191, 191, 191, 127)));
   painter->save();
   QTransform transform = painter->transform();
@@ -141,11 +143,12 @@ void ctkTransferFunctionControlPointsItem::mousePressEvent(QGraphicsSceneMouseEv
     {
     return;
     }
-  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
-  Q_ASSERT(tfScene);
+  //ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  //Q_ASSERT(tfScene);
+  ctkTransferFunctionRepresentation* tfRep = this->transferFunction()->representation();
   
   // convert coordinates
-  QPointF tfPos = tfScene->mapPointFromScene(e->pos());
+  QPointF tfPos = tfRep->mapPointFromScene(e->pos());
   // add point to transfer function
   // returns index
   int index = this->transferFunction()->insertControlPoint( tfPos.x());
@@ -168,9 +171,11 @@ void ctkTransferFunctionControlPointsItem::mouseMoveEvent(QGraphicsSceneMouseEve
     return;
     }
 
-  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
-  Q_ASSERT(tfScene);
-  QPointF newPos = tfScene->mapPointFromScene(e->pos());
+  //ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  //Q_ASSERT(tfScene);
+  ctkTransferFunctionRepresentation* tfRep = this->transferFunction()->representation();
+
+  QPointF newPos = tfRep->mapPointFromScene(e->pos());
 
   // Deal with borders
   if(d->SelectedPoint == 0 || d->SelectedPoint == this->transferFunction()->count() )

+ 6 - 3
Libs/Widgets/ctkTransferFunctionGradientItem.cpp

@@ -30,6 +30,7 @@
 /// CTK includes
 #include "ctkTransferFunction.h"
 #include "ctkTransferFunctionGradientItem.h"
+#include "ctkTransferFunctionRepresentation.h"
 #include "ctkTransferFunctionScene.h"
 
 class ctkTransferFunctionGradientItemPrivate:public ctkPrivate<ctkTransferFunctionGradientItem>
@@ -68,10 +69,12 @@ void ctkTransferFunctionGradientItem::paint(
 {
   Q_UNUSED(option);
   Q_UNUSED(widget);
-  ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
-  Q_ASSERT(tfScene);
 
-  const QGradient& gradient = tfScene->gradient();
+  //ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
+  //Q_ASSERT(tfScene);
+  ctkTransferFunctionRepresentation* tfRep = this->transferFunction()->representation();
+
+  const QGradient& gradient = tfRep->gradient();
 
   if ( this->mask() )
     {

+ 20 - 1
Libs/Widgets/ctkTransferFunctionItem.cpp

@@ -30,6 +30,7 @@
 /// CTK includes
 #include "ctkTransferFunction.h"
 #include "ctkTransferFunctionItem.h"
+#include "ctkTransferFunctionScene.h"
 
 //-----------------------------------------------------------------------------
 class ctkTransferFunctionItemPrivate : 
@@ -84,6 +85,11 @@ void ctkTransferFunctionItem::setTransferFunction(ctkTransferFunction* transferF
 {
   CTK_D(ctkTransferFunctionItem);
   d->TransferFunction = transferFunction;
+  if (this->scene())
+    {
+    connect(d->TransferFunction,SIGNAL(changed()),
+            this->scene(), SLOT(update()),Qt::UniqueConnection);
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -118,7 +124,7 @@ QRectF ctkTransferFunctionItem::boundingRect()const
   CTK_D(const ctkTransferFunctionItem);
   return d->Rect;
 }
-
+/*
 //-----------------------------------------------------------------------------
 QList<ctkPoint> ctkTransferFunctionItem::bezierParams(
   ctkControlPoint* start, ctkControlPoint* end) const
@@ -310,3 +316,16 @@ QPointF ctkTransferFunctionItem::screen2TransferFunctionCoordinates( qreal x, qr
 
   return transferFunctionCoordinates;
 }
+*/
+
+//-----------------------------------------------------------------------------
+QVariant ctkTransferFunctionItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
+{
+  QVariant res = this->QGraphicsObject::itemChange(change, value);
+  if (change == QGraphicsItem::ItemSceneChange && this->scene())
+    {
+    connect(this->transferFunction(),SIGNAL(changed()),
+            this->scene(), SLOT(update()),Qt::UniqueConnection);
+    }
+  return res;
+}

+ 9 - 9
Libs/Widgets/ctkTransferFunctionItem.h

@@ -49,7 +49,7 @@ public:
   inline void setRect(qreal x, qreal y, qreal width, qreal height);
   void setRect(const QRectF& rectangle);
   QRectF rect()const;
-
+/*
   qreal rangeXDiff();
   qreal rangeXOffSet();
 
@@ -58,18 +58,18 @@ public:
 
   QPointF transferFunction2ScreenCoordinates( qreal x, qreal y);
   QPointF screen2TransferFunctionCoordinates( qreal x, qreal y);
-
+*/
   virtual QRectF boundingRect()const;
 protected:
-  qreal y(const QVariant& value)const;
-  inline qreal y(const ctkPoint& point)const;
+  //qreal y(const QVariant& value)const;
+  //inline qreal y(const ctkPoint& point)const;
 
   QColor color(const QVariant& value)const;
   inline QColor color(const ctkPoint& point)const;
 
-  QList<ctkPoint> bezierParams(ctkControlPoint* start, ctkControlPoint* end)const;
-  QList<ctkPoint> nonLinearPoints(ctkControlPoint* start, ctkControlPoint* end)const;
-
+  //QList<ctkPoint> bezierParams(ctkControlPoint* start, ctkControlPoint* end)const;
+  //QList<ctkPoint> nonLinearPoints(ctkControlPoint* start, ctkControlPoint* end)const;
+  virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value);
 private:
   CTK_DECLARE_PRIVATE(ctkTransferFunctionItem);
 };
@@ -79,7 +79,7 @@ void ctkTransferFunctionItem::setRect(qreal x, qreal y, qreal width, qreal heigh
 {
   this->setRect(QRectF(x,y,width,height));
 }
-
+/*
 //-----------------------------------------------------------------------------
 qreal ctkTransferFunctionItem::y(const ctkPoint& p)const
 {
@@ -91,5 +91,5 @@ QColor ctkTransferFunctionItem::color(const ctkPoint& p)const
 {
   return this->color(p.Value);
 }
-
+*/
 #endif

+ 1 - 428
Libs/Widgets/ctkTransferFunctionScene.cpp

@@ -36,24 +36,11 @@ class ctkTransferFunctionScenePrivate: public ctkPrivate<ctkTransferFunctionScen
   CTK_DECLARE_PUBLIC(ctkTransferFunctionScene);
 public:
   ctkTransferFunctionScenePrivate();
-  QRectF               OldRect;
-  ctkTransferFunction* TransferFunction;
-  QPainterPath   Path;
-  QLinearGradient Gradient;
-  QList<QPointF> Points;
-  qreal        WorldRangeX[2];
-  QVariant     WorldRangeY[2];
-  qreal        RangeXDiff;
-  qreal        RangeXOffSet;
-  qreal        RangeYDiff;
-  qreal        RangeYOffSet;
-  QColor       VerticalGradientColor;
 };
 
+//-----------------------------------------------------------------------------
 ctkTransferFunctionScenePrivate::ctkTransferFunctionScenePrivate()
 {
-  this->TransferFunction = 0;
-  this->VerticalGradientColor = QColor::fromRgbF(1., 0., 0., 1. );
 }
 
 //-----------------------------------------------------------------------------
@@ -63,421 +50,7 @@ ctkTransferFunctionScene::ctkTransferFunctionScene(QObject* parentObject)
   CTK_INIT_PRIVATE(ctkTransferFunctionScene);
 }
 
-//-----------------------------------------------------------------------------
-ctkTransferFunctionScene::ctkTransferFunctionScene(
-  ctkTransferFunction* transferFunction, QObject* parentObject)
-  :QGraphicsScene(parentObject)
-{
-  CTK_INIT_PRIVATE(ctkTransferFunctionScene);
-  this->setTransferFunction(transferFunction);
-}
-//-----------------------------------------------------------------------------
 ctkTransferFunctionScene::~ctkTransferFunctionScene()
 {
 }
 
-//-----------------------------------------------------------------------------
-void ctkTransferFunctionScene::setTransferFunction(ctkTransferFunction* transferFunction)
-{
-  CTK_D(ctkTransferFunctionScene);
-  if (d->TransferFunction == transferFunction)
-    {
-    return;
-    }
-  d->TransferFunction = transferFunction;
-  connect( d->TransferFunction, SIGNAL(changed()),
-           this, SLOT(onTransferFunctionChanged()),
-           Qt::UniqueConnection);
-  this->update();
-}
-
-//-----------------------------------------------------------------------------
-ctkTransferFunction* ctkTransferFunctionScene::transferFunction()const
-{
-  return ctk_d()->TransferFunction;
-}
-
-//-----------------------------------------------------------------------------
-void ctkTransferFunctionScene::onTransferFunctionChanged()
-{
-  CTK_D(ctkTransferFunctionScene);
-  // TODO delete cache here
-  d->Path = QPainterPath();
-  this->update();  
-}
-
-//-----------------------------------------------------------------------------
-const QPainterPath& ctkTransferFunctionScene::curve()const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
-    {
-    const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
-    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
-    }
-  return d->Path;
-}
-
-//-----------------------------------------------------------------------------
-const QList<QPointF>& ctkTransferFunctionScene::points()const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
-    {
-    const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
-    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
-    }
-  return d->Points;
-}
-
-//-----------------------------------------------------------------------------
-const QGradient& ctkTransferFunctionScene::gradient()const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  if (d->Path.isEmpty())// || this->sceneRect() != d->OldRect)
-    {
-    const_cast<ctkTransferFunctionScene*>(this)->computeCurve();
-    const_cast<ctkTransferFunctionScene*>(this)->computeGradient();
-    }
-  return d->Gradient;
-}
-
-//-----------------------------------------------------------------------------
-void ctkTransferFunctionScene::computeCurve()
-{
-  CTK_D(ctkTransferFunctionScene);
-
-  int count = d->TransferFunction ? d->TransferFunction->count() : 0;
-  if (count <= 0)
-    {
-    return;
-    }
-  qDebug() << "computeCurve" << this->sceneRect();
-  d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
-  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
-  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
-
-  d->RangeXDiff   = this->computeRangeXDiff(this->sceneRect(), d->WorldRangeX);
-  d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
-
-  d->RangeYDiff   = this->computeRangeYDiff(this->sceneRect(), d->WorldRangeY);
-  d->RangeYOffSet = this->computeRangeYOffset(d->WorldRangeY);
-
-  ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
-  ctkControlPoint* nextCP = 0;
-
-  QPointF startPos = this->mapPointToScene(startCP);
-  
-  d->Points.clear();
-  d->Points << startPos;
-
-  d->Path = QPainterPath();
-  d->Path.moveTo(startPos);
-  for(int i = 1; i < count; ++i)
-    {
-    nextCP = d->TransferFunction->controlPoint(i);
-    if (this->transferFunction()->isDiscrete())
-      {
-      QPointF nextPos = this->mapPointToScene(nextCP);
-      qreal midPosX = (startPos.x() + nextPos.x()) / 2.;
-      
-      d->Path.lineTo(QPointF(midPosX, startPos.y()));
-      d->Path.lineTo(QPointF(midPosX, nextPos.y()));
-      
-      d->Points << nextPos;
-      startPos = nextPos;
-      if (i == count -1)
-        {
-        d->Path.lineTo(nextPos);
-        }
-      }
-    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP))
-      {
-      QList<ctkPoint> points = this->nonLinearPoints(startCP, nextCP);
-      int j;
-      for (j = 1; j < points.count(); ++j)
-        {
-        d->Path.lineTo(this->mapPointToScene(points[j]));
-        }
-      j = points.count() - 1;
-      d->Points << this->mapPointToScene(points[j]);
-      }
-    else //dynamic_cast<ctkBezierControlPoint*>(startCP))
-      {
-      QList<ctkPoint> points = this->bezierParams(startCP, nextCP);
-      QList<ctkPoint>::iterator it = points.begin();
-      QList<QPointF> bezierPoints;
-      foreach(const ctkPoint& p, points)
-        {
-        bezierPoints << this->mapPointToScene(p);
-        }
-      d->Path.cubicTo(bezierPoints[1], bezierPoints[2], bezierPoints[3]);
-      d->Points << bezierPoints[3];
-      }
-    //qDebug() << i << points[0] << points[1] << points[2] << points[3];
-    delete startCP;
-    startCP = nextCP;
-    }
-  if (startCP)
-    {
-    delete startCP;
-    }
-}
-
-//-----------------------------------------------------------------------------
-void ctkTransferFunctionScene::computeGradient()
-{
-  CTK_D(ctkTransferFunctionScene);
-
-  int count = d->TransferFunction ? d->TransferFunction->count() : 0;
-  if (count <= 0)
-    {
-    return;
-    }
-  qDebug() << "computeCurve" << this->sceneRect();
-  d->TransferFunction->range(d->WorldRangeX[0], d->WorldRangeX[1]);
-  d->WorldRangeY[0] = this->posY(d->TransferFunction->minValue());
-  d->WorldRangeY[1] = this->posY(d->TransferFunction->maxValue());
-
-  d->RangeXDiff   = this->computeRangeXDiff(QRectF(0.,0.,1.,1.), d->WorldRangeX);
-  d->RangeXOffSet = this->computeRangeXOffset(d->WorldRangeX);
-
-  d->RangeYDiff   = this->computeRangeYDiff(QRectF(0.,0.,1.,1.), d->WorldRangeY);
-  d->RangeYOffSet = this->computeRangeYOffset(d->WorldRangeY);
-
-  ctkControlPoint* startCP = d->TransferFunction->controlPoint(0);
-  ctkControlPoint* nextCP = 0;
-
-  qreal startPos = this->mapXToScene(this->posX(startCP->x()));
-  qreal nextPos;
-  
-  //
-  //if we have no colors in value (i.e. can't convert value to color)
-  if (! d->TransferFunction->value(0).canConvert<QColor>())
-    {
-    // create vertical gradient
-    d->Gradient = QLinearGradient(0., 0., 0., 1.);
-    // red
-    d->Gradient.setColorAt(0, d->VerticalGradientColor );
-    // to black
-    d->Gradient.setColorAt(1, QColor::fromRgbF(0., 0., 0., 1. ));
-    return;
-    }
-
-  // classic gradient if we have colors in value
-  d->Gradient = QLinearGradient(0., 0., 1., 0.);
-  d->Gradient.setColorAt(startPos, this->color(startCP));
-  for(int i = 1; i < count; ++i)
-    {
-    nextCP = d->TransferFunction->controlPoint(i);
-    nextPos = this->mapXToScene(this->posX(nextCP));
-    if (this->transferFunction()->isDiscrete())
-      {
-      qreal midPoint = (startPos + nextPos)  / 2;
-      d->Gradient.setColorAt(midPoint, this->color(startCP));
-      d->Gradient.setColorAt(midPoint + std::numeric_limits<qreal>::epsilon(), this->color(nextCP));
-      }
-    else if (dynamic_cast<ctkNonLinearControlPoint*>(startCP))
-      {
-      QList<ctkPoint> points = this->nonLinearPoints(startCP, nextCP);
-      foreach(const ctkPoint& p, points)
-        {
-        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
-        }
-      //no need, d->Gradient.setColorAt(nextPos, this->color(nextCP));
-      }
-    else //dynamic_cast<ctkBezierControlPoint*>(startCP))
-      { // TODO handle bezier points with color
-      QList<ctkPoint> points = this->bezierParams(startCP, nextCP);
-      QList<ctkPoint>::iterator it = points.begin();
-      QList<QPointF> bezierPoints;
-      foreach(const ctkPoint& p, points)
-        {
-        d->Gradient.setColorAt(this->mapXToScene(this->posX(p)), this->color(p));
-        }
-      nextPos = this->mapXToScene(this->posX(points[points.size() - 1]));
-      }
-    //qDebug() << i << points[0] << points[1] << points[2] << points[3];
-    delete startCP;
-    startCP = nextCP;
-    startPos = nextPos;
-    }
-  d->Gradient.setColorAt(startPos, this->color(startCP));
-  if (startCP)
-    {
-    delete startCP;
-    }
-}
-
-//-----------------------------------------------------------------------------
-QList<ctkPoint> ctkTransferFunctionScene::bezierParams(
-  ctkControlPoint* start, ctkControlPoint* end) const
-{
-  Q_ASSERT(start);
-  Q_ASSERT(end);
-  QList<ctkPoint> points; 
-  
-  ctkBezierControlPoint* bezierCP = dynamic_cast<ctkBezierControlPoint*>(start);
-  if (!bezierCP)
-    {// just duplicate start and end into p1 and p2
-    points << start->P;
-    points << start->P;
-    points << end->P;
-    points << end->P;
-    return points;
-    }
-  
-  points << start->P;
-  points << bezierCP->P1;
-  points << bezierCP->P2;
-  points << end->P;
-  return points;
-}
-
-//-----------------------------------------------------------------------------
-QList<ctkPoint> ctkTransferFunctionScene::nonLinearPoints(
-  ctkControlPoint* start, ctkControlPoint* end) const
-{
-  Q_ASSERT(start);
-    
-  ctkNonLinearControlPoint* nonLinearCP = 
-    dynamic_cast<ctkNonLinearControlPoint*>(start);
-  if (!nonLinearCP)
-    {
-    QList<ctkPoint> points; 
-    points << start->P;
-    points << end->P;
-    return points;
-    }
-  return nonLinearCP->SubPoints;
-}
-
-//-----------------------------------------------------------------------------
-QColor ctkTransferFunctionScene::color(const QVariant& v) const
-{ 
-  //Q_ASSERT(v.canConvert<QColor>());
-  if (v.canConvert<QColor>())
-    {
-    return v.value<QColor>();
-    }
-  else
-    {
-    //black background
-    QColor defaultColor(0., 0., 0.);
-    return defaultColor;
-    }
-  return QColor();
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::computeRangeXDiff(const QRectF& rect, qreal rangeX[2])
-{
-  return rect.width() / (rangeX[1] - rangeX[0]);
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::computeRangeXOffset(qreal rangeX[2])
-{
-  return rangeX[0];
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::computeRangeYDiff(const QRectF& rect, const QVariant rangeY[2])
-{
-  qreal rangeYDiff = rect.height();
-  qreal rangePosY[2];
-  rangePosY[0] = this->posY(rangeY[0]);
-  rangePosY[1] = this->posY(rangeY[1]);
-  if (rangePosY[1] == rangePosY[0])
-    {
-    rangeYDiff /= rangePosY[0];
-    return rangeYDiff;
-    }
-  rangeYDiff /= rangePosY[1] - rangePosY[0];
-  return rangeYDiff;
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::computeRangeYOffset(const QVariant rangeY[2])
-{
-  qreal rangePosY[2];
-  rangePosY[0] = this->posY(rangeY[0]);
-  rangePosY[1] = this->posY(rangeY[1]);
-
-  if (rangePosY[1] == rangePosY[0])
-    {
-    return 0.;
-    }
-  return rangePosY[0];
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::posX(const qreal& x)const
-{
-  return x;
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::posY(const QVariant& value)const
-{
-  Q_ASSERT(value.canConvert<qreal>() || value.canConvert<QColor>());
-  if (value.canConvert<QColor>())
-    {
-    return value.value<QColor>().alphaF();
-    }
-  return value.toReal();
-}
-
-//-----------------------------------------------------------------------------
-QPointF ctkTransferFunctionScene::mapPointToScene(const ctkControlPoint* cp)const
-{
-  return QPointF(this->mapXToScene(this->posX(cp->x())),
-                 this->mapYToScene(this->posY(cp->value())));
-}
-
-//-----------------------------------------------------------------------------
-QPointF ctkTransferFunctionScene::mapPointToScene(const ctkPoint& point)const
-{
-  return QPointF( this->mapXToScene(this->posX(point.X)),
-                  this->mapYToScene(this->posY(point.Value)));
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapXToScene(qreal xPos)const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  return (xPos - d->RangeXOffSet) * d->RangeXDiff;
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapYToScene(qreal yPos)const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  return this->height() - (yPos - d->RangeYOffSet) * d->RangeYDiff;
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapXFromScene(qreal scenePosX)const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  return (scenePosX / d->RangeXDiff) + d->RangeXOffSet;
-}
-
-//-----------------------------------------------------------------------------
-qreal ctkTransferFunctionScene::mapYFromScene(qreal scenePosY)const
-{
-  CTK_D(const ctkTransferFunctionScene);
-  return ((this->height() - scenePosY) / d->RangeYDiff) + d->RangeYOffSet ;
-}
-//-----------------------------------------------------------------------------
-QColor ctkTransferFunctionScene::verticalGradientColor() const
-{
-  CTK_D( const ctkTransferFunctionScene );
-  return d->VerticalGradientColor;
-}
-//-----------------------------------------------------------------------------
-void ctkTransferFunctionScene::setVerticalGradientColor( QColor verticalGradientColor )
-{
-  CTK_D( ctkTransferFunctionScene );
-  d->VerticalGradientColor = verticalGradientColor;
-}

+ 0 - 80
Libs/Widgets/ctkTransferFunctionScene.h

@@ -38,93 +38,13 @@ class ctkTransferFunctionScenePrivate;
 class CTK_WIDGETS_EXPORT ctkTransferFunctionScene: public QGraphicsScene
 {
   Q_OBJECT
-  Q_PROPERTY(QColor VerticalGradientColor READ verticalGradientColor WRITE setVerticalGradientColor)
 
 public:
   ctkTransferFunctionScene(QObject* parent = 0);
-  ctkTransferFunctionScene(ctkTransferFunction* transferFunction, QObject* parent = 0);
   virtual ~ctkTransferFunctionScene();
 
-  void setTransferFunction(ctkTransferFunction* transferFunction);
-  ctkTransferFunction* transferFunction()const;
-
-  inline qreal posX(const ctkControlPoint* cp)const;
-  inline qreal posY(const ctkControlPoint* cp)const;
-  inline QColor color(const ctkControlPoint* cp) const;
-
-  inline qreal posX(const ctkPoint& point)const;
-  inline qreal posY(const ctkPoint& point)const;
-  inline QColor color(const ctkPoint& point) const;
-
-  qreal posX(const qreal& tfX)const;
-  qreal posY(const QVariant& tfV)const;
-  QColor color(const QVariant& tfV) const;
-  
-  QPointF mapPointToScene(const ctkControlPoint* cp)const;
-  QPointF mapPointToScene(const ctkPoint& point)const;
-  
- 
-  qreal mapXToScene(qreal posX)const;
-  qreal mapYToScene(qreal posY)const;
-  qreal mapXFromScene(qreal ScenePosX)const;
-  qreal mapYFromScene(qreal ScenePosY)const;
-  inline QPointF mapPointFromScene(const QPointF& point)const;
-
-  QList<ctkPoint> bezierParams(ctkControlPoint* start, ctkControlPoint* end) const;
-  QList<ctkPoint> nonLinearPoints(ctkControlPoint* start, ctkControlPoint* end) const;
-
-  const QPainterPath& curve()const;
-  const QList<QPointF>& points()const;
-  const QGradient& gradient()const;
-
-  void computeCurve();
-  void computeGradient();
-
-  QColor verticalGradientColor()const;
-  void setVerticalGradientColor(QColor verticalGradientColor);
-
-protected slots:
-  virtual void onTransferFunctionChanged();
-
-protected:
-  qreal computeRangeXDiff(const QRectF& rect, qreal rangeX[2]);
-  qreal computeRangeXOffset(qreal rangeX[2]);
-  qreal computeRangeYDiff(const QRectF& rect, const QVariant rangeY[2]);
-  qreal computeRangeYOffset(const QVariant rangeY[2]);
 private:
   CTK_DECLARE_PRIVATE(ctkTransferFunctionScene);
 };
 
-qreal ctkTransferFunctionScene::posX(const ctkControlPoint* cp)const
-{
-  return this->posX(cp->x());
-}
-qreal ctkTransferFunctionScene::posY(const ctkControlPoint* cp)const
-{
-  return this->posY(cp->value());
-}
-QColor ctkTransferFunctionScene::color(const ctkControlPoint* cp) const
-{
-  return this->color(cp->value());
-}
-
-qreal ctkTransferFunctionScene::posX(const ctkPoint& point)const
-{
-  return this->posX(point.X);
-}
-qreal ctkTransferFunctionScene::posY(const ctkPoint& point)const
-{
-  return this->posY(point.Value);
-}
-QColor ctkTransferFunctionScene::color(const ctkPoint& point) const
-{
-  return this->color(point.Value);
-}
-
-QPointF ctkTransferFunctionScene::mapPointFromScene(const QPointF& point)const
-{
-  return QPointF(this->mapXFromScene(point.x()),
-                 this->mapYFromScene(point.y()));
-}
-
 #endif

+ 1 - 1
Libs/Widgets/ctkTransferFunctionWidget.cpp

@@ -89,7 +89,7 @@ void ctkTransferFunctionWidget::setTransferFunction(ctkTransferFunction* transfe
   ctkTransferFunctionScene* tfScene = dynamic_cast<ctkTransferFunctionScene*>(this->scene());
   Q_ASSERT(tfScene);
   tfScene->clear();
-  tfScene->setTransferFunction(transferFunction);
+  //tfScene->setTransferFunction(transferFunction);
 
   ctkTransferFunctionGradientItem* gradient = 
     new ctkTransferFunctionGradientItem(transferFunction);