Преглед на файлове

COMP: Transfer function composite missing files added

Nicolas Rannou преди 15 години
родител
ревизия
7393aed1c2

+ 385 - 0
Libs/Visualization/VTK/Core/ctkVTKCompositeFunction.cpp

@@ -0,0 +1,385 @@
+/*=========================================================================
+
+  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 <QColor>
+#include <QDebug>
+
+/// CTK includes
+#include "ctkVTKCompositeFunction.h"
+
+/// VTK includes
+#include <vtkPiecewiseFunction.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkSmartPointer.h>
+
+class ctkVTKCompositeFunctionPrivate: public ctkPrivate<ctkVTKCompositeFunction>
+{
+public:
+  vtkSmartPointer<vtkPiecewiseFunction>     PiecewiseFunction;
+  vtkSmartPointer<vtkColorTransferFunction> ColorTransferFunction;
+};
+
+//-----------------------------------------------------------------------------
+ctkVTKCompositeFunction::ctkVTKCompositeFunction(vtkPiecewiseFunction* piecewiseFunction,
+                                                 vtkColorTransferFunction* colorTransferFunction,
+                                                 QObject* parentObject)
+  :ctkTransferFunction(parentObject)
+{
+  CTK_INIT_PRIVATE(ctkVTKCompositeFunction);
+  this->setPiecewiseFunction(piecewiseFunction);
+  this->setColorTransferFunction(colorTransferFunction);
+}
+
+//-----------------------------------------------------------------------------
+ctkVTKCompositeFunction::~ctkVTKCompositeFunction()
+{
+}
+
+//-----------------------------------------------------------------------------
+int ctkVTKCompositeFunction::count()const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  // count points from piecewise
+  // could be from color transfer function
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    Q_ASSERT(d->PiecewiseFunction.GetPointer());
+    return -1;
+    }
+
+  if (d->ColorTransferFunction.GetPointer() == 0)
+    {
+    Q_ASSERT(d->ColorTransferFunction.GetPointer());
+    return -1;
+    }
+  //qDebug() << "Piecewise: " << d->PiecewiseFunction->GetSize();
+  //qDebug() << "Color Transfer: " << d->ColorTransferFunction->GetSize();
+
+  // check if 2 tranfer function have same size
+  Q_ASSERT( d->PiecewiseFunction->GetSize() == d->ColorTransferFunction->GetSize());
+
+  return d->PiecewiseFunction->GetSize();
+}
+
+//-----------------------------------------------------------------------------
+bool ctkVTKCompositeFunction::isDiscrete()const
+{
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+bool ctkVTKCompositeFunction::isEditable()const
+{
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKCompositeFunction::range(qreal& minRange, qreal& maxRange)const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    Q_ASSERT(d->PiecewiseFunction.GetPointer());
+    minRange = 1.;
+    maxRange = 0.;
+    return;
+    }
+  double rangeValues[2];
+  d->PiecewiseFunction->GetRange(rangeValues);
+  minRange = rangeValues[0];
+  maxRange = rangeValues[1];
+}
+
+//-----------------------------------------------------------------------------
+QVariant ctkVTKCompositeFunction::minValue()const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    Q_ASSERT(d->PiecewiseFunction.GetPointer());
+    return -1;
+    }
+  //Initialize to max value
+  double minValue = VTK_DOUBLE_MAX;
+  for (int i = 0; i < this->count(); ++i)
+    {
+    double value[4];
+    d->PiecewiseFunction->GetNodeValue(i, value);
+    minValue = qMin(value[1], minValue);
+    }
+  return minValue;
+}
+
+//-----------------------------------------------------------------------------
+QVariant ctkVTKCompositeFunction::maxValue()const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    Q_ASSERT(d->PiecewiseFunction.GetPointer());
+    return -1;
+    }
+  //Initialize to min value
+  double maxValue = VTK_DOUBLE_MIN;
+  for (int i = 0; i < this->count(); ++i)
+    {
+    double value[4];
+    d->PiecewiseFunction->GetNodeValue(i, value);
+    maxValue = qMax(maxValue, value[1]);
+    }
+  return maxValue;
+}
+
+//-----------------------------------------------------------------------------
+ctkControlPoint* ctkVTKCompositeFunction::controlPoint(int index)const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  Q_ASSERT(index >= 0 && index < this->count());
+
+  double valuesPWF[4];
+  double valuesCTF[6];
+  double* range = d->PiecewiseFunction->GetRange();
+  d->PiecewiseFunction->GetNodeValue(index, valuesPWF);
+  d->ColorTransferFunction->GetNodeValue(index, valuesCTF);
+
+  QVariant rangeY[2];
+  rangeY[0] = this->minValue();
+  rangeY[1] = this->maxValue();
+
+// test piecewise
+  Q_ASSERT(valuesPWF[0] >= range[0] && valuesPWF[0] <= range [1] &&  // X
+    valuesPWF[1] >= rangeY[0].toDouble() && valuesPWF[1] <= rangeY[1].toDouble()  &&  // Y
+    valuesPWF[2] >= 0. && valuesPWF[2] <= 1. &&                // Midpoint
+    valuesPWF[3] >= 0. && valuesPWF[3] <= 1. );                // Sharpness
+
+  // test color transfer
+  Q_ASSERT(valuesCTF[0] >= d->ColorTransferFunction->GetRange()[0] &&
+    valuesCTF[0] <= d->ColorTransferFunction->GetRange()[1] &&
+    valuesCTF[1] >= 0. && valuesCTF[1] <= 1. &&  // Red
+    valuesCTF[2] >= 0. && valuesCTF[2] <= 1. &&  // Green
+    valuesCTF[3] >= 0. && valuesCTF[3] <= 1. &&  // Blue
+    valuesCTF[4] >= 0. && valuesCTF[4] <= 1. &&  // MidPoint
+    valuesCTF[5] >= 0. && valuesCTF[5] <= 1.);   // Sharpness
+
+  // if only 2 points -> linear
+  if (index + 1 >= this->count())
+    {
+    ctkControlPoint* cp = new ctkControlPoint();
+    cp->P.X = valuesPWF[0];
+    // update value of QVariant
+    QColor compositeValue(valuesCTF[1], valuesCTF[2], valuesCTF[3], valuesPWF[1]);
+    cp->P.Value = compositeValue;
+    return cp;
+    }
+
+  //else
+
+  ctkNonLinearControlPoint* cp = new ctkNonLinearControlPoint();
+  cp->P.X = valuesPWF[0];
+  // update value of QVariant
+  QColor compositeValue(valuesCTF[1], valuesCTF[2], valuesCTF[3], valuesPWF[1]);
+  cp->P.Value = compositeValue;
+
+  d->PiecewiseFunction->GetNodeValue(index + 1, valuesPWF);
+  d->ColorTransferFunction->GetNodeValue(index +1, valuesCTF);
+
+  Q_ASSERT(valuesPWF[0] >= range[0] && valuesPWF[0] <= range[1]  &&  // X
+    valuesPWF[1] >= rangeY[0].toDouble() && valuesPWF[1] <= rangeY[1].toDouble()  &&  // Y
+    valuesPWF[2] >= 0. && valuesPWF[2] <= 1. &&                // Midpoint
+    valuesPWF[3] >= 0. && valuesPWF[3] <= 1. );                // Sharpness
+
+  Q_ASSERT(valuesCTF[0] >= d->ColorTransferFunction->GetRange()[0] &&
+    valuesCTF[0] <= d->ColorTransferFunction->GetRange()[1] &&
+    valuesCTF[1] >= 0. && valuesCTF[1] <= 1. &&  // Red
+    valuesCTF[2] >= 0. && valuesCTF[2] <= 1. &&  // Green
+    valuesCTF[3] >= 0. && valuesCTF[3] <= 1. &&  // Blue
+    valuesCTF[4] >= 0. && valuesCTF[4] <= 1. &&  // MidPoint
+    valuesCTF[5] >= 0. && valuesCTF[5] <= 1.);   // Sharpness
+
+  double subPointsCTF[30];
+  double subPointsPWF[30];
+  d->ColorTransferFunction->GetTable(cp->x(), valuesCTF[0], 10, subPointsCTF);
+  d->PiecewiseFunction->GetTable(cp->x(), valuesCTF[0], 10, subPointsPWF);
+  qreal interval = (valuesCTF[0] - cp->x()) / 9.;
+
+  for(int i = 0; i < 10; ++i)
+  {
+	  qreal red =  subPointsCTF[3*i];
+	  qreal green =  subPointsCTF[3*i+1];
+	  qreal blue =  subPointsCTF[3*i+2];
+	  qreal alpha = subPointsPWF[i];
+	  QColor compositeValue;
+	  compositeValue.setRgb(red*255, green*255, blue*255, alpha*255 );
+	  //compositeValue. (red, green, blue, alpha);
+    cp->SubPoints << ctkPoint(cp->x() + interval*i, compositeValue);
+  }
+  return cp;
+}
+
+//-----------------------------------------------------------------------------
+QVariant ctkVTKCompositeFunction::value(qreal pos)const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  Q_ASSERT(d->PiecewiseFunction.GetPointer());
+  Q_ASSERT(d->ColorTransferFunction.GetPointer());
+
+  // Get color
+  double rgb[3];
+  d->ColorTransferFunction->GetColor(pos, rgb);
+
+  // Get Alpha
+  qreal alpha;
+  alpha = d->PiecewiseFunction->GetValue( pos );
+
+  // returns RGBA
+  QColor compositeValue(rgb[0], rgb[1], rgb[2], alpha);
+  return compositeValue;
+}
+
+//-----------------------------------------------------------------------------
+int ctkVTKCompositeFunction::insertControlPoint(const ctkControlPoint& cp)
+{
+  CTK_D(ctkVTKCompositeFunction);
+  int index = -1;
+  // check piecewise
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    return index;
+    }
+  // cp: x
+  // value = rgba
+  /*
+  // check color tf
+  qreal value = cp.value().value<qreal>();
+  const ctkNonLinearControlPoint* nonLinearCp = dynamic_cast<const ctkNonLinearControlPoint*>(&cp);
+  if (nonLinearCp)
+    {
+    // TODO retrieve midpoint & sharpness
+    index = d->PiecewiseFunction->AddPoint(
+      cp.x(), value);
+    }
+  else
+    {
+    index = d->PiecewiseFunction->AddPoint(
+      cp.x(), value);
+    }*/
+  return index;
+}
+//-----------------------------------------------------------------------------
+int ctkVTKCompositeFunction::insertControlPoint(qreal pos)
+{
+  CTK_D(ctkVTKCompositeFunction);
+  int index = -1;
+  // check piecewise
+  if (d->PiecewiseFunction.GetPointer() == 0)
+    {
+    return index;
+    }
+  //check color tf
+  if (d->ColorTransferFunction.GetPointer() == 0)
+    {
+    return index;
+    }
+
+  // Add color to CTF
+  double color[3];
+  d->ColorTransferFunction->GetColor( pos, color );
+  int indexColor =
+      d->ColorTransferFunction->AddRGBPoint( pos, color[0], color[1], color[2] );
+
+  // Add point to piecewise
+  int indexPiecewise =
+      d->PiecewiseFunction->AddPoint( pos, 0);
+
+  // check index
+  Q_ASSERT(indexColor == indexPiecewise);
+
+  index = indexColor;
+
+  return index;
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKCompositeFunction::setControlPointPos(int index, qreal pos)
+{
+  CTK_D(ctkVTKCompositeFunction);
+
+  // update X pos in the CTF
+  double valuesColor[6];
+  d->ColorTransferFunction->GetNodeValue(index, valuesColor);
+  valuesColor[0] = pos;
+  // warning, a possible new range is not supported
+  // SetNodeValue eventually fire the signal changed()
+  d->ColorTransferFunction->SetNodeValue(index, valuesColor);
+
+  // Update X pos in the PWF
+  double valuesPiecewise[4];
+  d->PiecewiseFunction->GetNodeValue(index, valuesPiecewise);
+  // warning, a possible new range is not supported
+  // SetNodeValue eventually fire the signal changed()
+  valuesPiecewise[0] = pos;
+  d->PiecewiseFunction->SetNodeValue(index, valuesPiecewise);
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKCompositeFunction::setControlPointValue(int index, const QVariant& value)
+{
+  CTK_D(ctkVTKCompositeFunction);
+  // QVariant = RGBA
+
+  double values[4];
+  d->PiecewiseFunction->GetNodeValue(index, values);
+  values[1] = value.toDouble();
+  // setNodeValue should eventually fired the signal changed()
+  d->PiecewiseFunction->SetNodeValue(index, values);
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKCompositeFunction::setPiecewiseFunction(vtkPiecewiseFunction* piecewiseFunction)
+{
+  CTK_D(ctkVTKCompositeFunction);
+  d->PiecewiseFunction = piecewiseFunction;
+  this->qvtkReconnect(d->PiecewiseFunction,vtkCommand::ModifiedEvent,
+                      this, SIGNAL(changed()));
+  emit changed();
+}
+//-----------------------------------------------------------------------------
+void ctkVTKCompositeFunction::setColorTransferFunction(vtkColorTransferFunction* colorTransferFunction)
+{
+  CTK_D(ctkVTKCompositeFunction);
+  d->ColorTransferFunction = colorTransferFunction;
+  this->qvtkReconnect(d->ColorTransferFunction,vtkCommand::ModifiedEvent,
+                      this, SIGNAL(changed()));
+  emit changed();
+}
+
+//-----------------------------------------------------------------------------
+vtkPiecewiseFunction* ctkVTKCompositeFunction::piecewiseFunction()const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  return d->PiecewiseFunction;
+}
+//-----------------------------------------------------------------------------
+vtkColorTransferFunction* ctkVTKCompositeFunction::colorTransferFunction()const
+{
+  CTK_D(const ctkVTKCompositeFunction);
+  return d->ColorTransferFunction;
+}

+ 74 - 0
Libs/Visualization/VTK/Core/ctkVTKCompositeFunction.h

@@ -0,0 +1,74 @@
+/*=========================================================================
+
+  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 __ctkVTKCompositeFunction_h
+#define __ctkVTKCompositeFunction_h
+
+// CTK includes
+#include "ctkTransferFunction.h"
+#include "ctkPimpl.h"
+#include "CTKVisualizationVTKCoreExport.h"
+#include "ctkVTKObject.h"
+
+class vtkPiecewiseFunction;
+class vtkColorTransferFunction;
+class ctkVTKCompositeFunctionPrivate;
+
+///
+/// Transfer function for a vtkPiecewiseFunction
+
+class CTK_VISUALIZATION_VTK_CORE_EXPORT ctkVTKCompositeFunction: public ctkTransferFunction
+{
+  Q_OBJECT;
+  QVTK_OBJECT;
+public:
+  ctkVTKCompositeFunction(vtkPiecewiseFunction*     piecewiserFunction,
+                          vtkColorTransferFunction* colorTransferFunction,
+                          QObject* parent = 0);
+  virtual ~ctkVTKCompositeFunction();
+
+  virtual ctkControlPoint* controlPoint(int index)const;
+  virtual QVariant value(qreal pos)const;
+  // ADD color here
+  // value = color in piecewise and colortransfer
+  virtual int count()const;
+  virtual bool isDiscrete()const;
+  virtual bool isEditable()const;
+
+  virtual void range(qreal& minRange, qreal& maxRange)const;
+  virtual QVariant minValue()const;
+  virtual QVariant maxValue()const;
+
+  virtual int insertControlPoint(const ctkControlPoint& cp);
+  virtual int insertControlPoint(qreal pos);
+
+  virtual void setControlPointPos(int index, qreal pos);
+  virtual void setControlPointValue(int index, const QVariant& value);
+
+  void setPiecewiseFunction(vtkPiecewiseFunction* piecewiseFunction);
+  void setColorTransferFunction(vtkColorTransferFunction* colorTansferFunction);
+
+  vtkPiecewiseFunction*     piecewiseFunction()const;
+  vtkColorTransferFunction* colorTransferFunction()const;
+private:
+  CTK_DECLARE_PRIVATE(ctkVTKCompositeFunction);
+};
+
+#endif

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

@@ -58,7 +58,7 @@ int ctkTransferFunctionWidgetTest2(int argc, char * argv [] )
 
   QTimer autoExit;
   QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-  autoExit.start(100000);
+  autoExit.start(1000);
 
   return app.exec();
 }

+ 72 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkTransferFunctionWidgetTest4.cpp

@@ -0,0 +1,72 @@
+/*=========================================================================
+
+  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 <QApplication>
+#include <QSharedPointer>
+#include <QTimer>
+
+// CTK includes
+#include "ctkTransferFunction.h"
+#include "ctkTransferFunctionWidget.h"
+#include "ctkVTKCompositeFunction.h"
+
+// VTK includes
+#include <vtkPiecewiseFunction.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkTransferFunctionWidgetTest4(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  // Points have to be between 0 and 1
+
+  vtkSmartPointer<vtkPiecewiseFunction> pwf =
+    vtkSmartPointer<vtkPiecewiseFunction>::New();
+  //
+  pwf->AddPoint(0., 0.1);
+  pwf->AddPoint(0.2,.2);
+  pwf->AddPoint(0.3, .5);
+  pwf->AddPoint(0.9, .5);
+
+  vtkSmartPointer<vtkColorTransferFunction> ctf =
+    vtkSmartPointer<vtkColorTransferFunction>::New();
+  //
+  ctf->AddRGBPoint(0., 1.,0.,0., 0., 0.);
+  ctf->AddRGBPoint(0.2, 0.,1.,0., 0.5, 0.);
+  ctf->AddRGBPoint(0.3, 1.,0.,0.6, 0.5, 0.);
+  ctf->AddRGBPoint(0.9, 0.,0.,1., 0.5, 0.);
+
+  QSharedPointer<ctkTransferFunction> transferFunction =
+    QSharedPointer<ctkTransferFunction>(new ctkVTKCompositeFunction(pwf, ctf));
+  ctkTransferFunctionWidget transferFunctionWidget(transferFunction.data(), 0);
+  // the widget is not really shown here, only when app.exec() is called
+  transferFunctionWidget.show();
+
+  QTimer autoExit;
+  QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
+  autoExit.start(1000);
+  return app.exec();
+}

+ 1 - 0
Libs/Widgets/ctkTransferFunctionWidget.cpp

@@ -89,6 +89,7 @@ void ctkTransferFunctionWidget::setTransferFunction(ctkTransferFunction* transfe
   tfScene->clear();
   tfScene->setTransferFunction(transferFunction);
 
+  bool useMask = true;
   ctkTransferFunctionGradientItem* gradient = 
     new ctkTransferFunctionGradientItem(transferFunction);
   //gradient->setRect(tfScene->sceneRect());