Commit 1509669d authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Cleaning up transfer function widgets.

Cleaning up issues with the context-items related to tranfer function editor.

+ Added support for log-mapped color-transfer function. We ensure that when
  using log-scale, the color transfer function widget also enter log-space.

+ vtkPiecewiseControlPointsItem had a bug resulting it deleting of end points
  even when told otherwise. Fixed that.

+ Added new event vtkControlPointsItem::PointsModifiedEvent which if fired when
  control points are changed making it easier for application to do something
  when the points are changed.

+ Improved the usability by adding ability to label control points.

Change-Id: If02bc1139f6ccb3d7c2198b07d10491f902bafda
parent 90b9cca7
c3b8ad563805adbd17676dcfc6b9c488
cb1c16066e465328005012e8db8254d9
......@@ -46,6 +46,7 @@ vtkColorTransferControlPointsItem::~vtkColorTransferControlPointsItem()
{
if (this->ColorTransferFunction)
{
this->ColorTransferFunction->RemoveObserver(this->Callback);
this->ColorTransferFunction->Delete();
this->ColorTransferFunction = 0;
}
......@@ -134,7 +135,8 @@ void vtkColorTransferControlPointsItem::GetControlPoint(vtkIdType index, double*
double xrgbms[6];
vtkColorTransferFunction* thisTF = const_cast<vtkColorTransferFunction*>(
this->ColorTransferFunction);
if(thisTF)
if (thisTF)
{
thisTF->GetNodeValue(index, xrgbms);
pos[0] = xrgbms[0];
......@@ -157,6 +159,7 @@ void vtkColorTransferControlPointsItem::SetControlPoint(vtkIdType index, double*
xrgbms[4] = newPos[2];
xrgbms[5] = newPos[3];
this->ColorTransferFunction->SetNodeValue(index, xrgbms);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
}
}
......@@ -178,6 +181,7 @@ void vtkColorTransferControlPointsItem::EditPoint(float tX, float tY)
xrgbms[4] += tX;
xrgbms[5] += tY;
this->ColorTransferFunction->SetNodeValue(this->CurrentPoint - 1, xrgbms);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
}
}
......@@ -188,11 +192,14 @@ vtkIdType vtkColorTransferControlPointsItem::AddPoint(double* newPos)
{
return -1;
}
double posX = newPos[0];
double rgb[3] = {0., 0., 0.};
this->ColorTransferFunction->GetColor(newPos[0], rgb);
this->ColorTransferFunction->GetColor(posX, rgb);
vtkIdType addedPoint =
this->ColorTransferFunction->AddRGBPoint(newPos[0], rgb[0], rgb[1], rgb[2]);
this->ColorTransferFunction->AddRGBPoint(posX, rgb[0], rgb[1], rgb[2]);
this->vtkControlPointsItem::AddPointId(addedPoint);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
return addedPoint;
}
......@@ -211,5 +218,30 @@ vtkIdType vtkColorTransferControlPointsItem::RemovePoint(double* currentPoint)
vtkIdType removedPoint =
this->ColorTransferFunction->RemovePoint(currentPoint[0]);
assert(removedPoint == expectedPoint);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
return removedPoint;
}
//-----------------------------------------------------------------------------
void vtkColorTransferControlPointsItem::ComputeBounds(double* bounds)
{
if (this->ColorTransferFunction)
{
const double* range = this->ColorTransferFunction->GetRange();
bounds[0] = range[0];
bounds[1] = range[1];
bounds[2] = 0.5;
bounds[3] = 0.5;
}
else
{
this->Superclass::ComputeBounds(bounds);
}
}
//-----------------------------------------------------------------------------
bool vtkColorTransferControlPointsItem::UsingLogScale()
{
return (this->ColorTransferFunction?
(this->ColorTransferFunction->UsingLogScale() != 0) : false);
}
......@@ -86,6 +86,12 @@ protected:
vtkColorTransferControlPointsItem();
virtual ~vtkColorTransferControlPointsItem();
// Description:
// Returns true if control points are to be rendered in log-space. This is
// true when vtkScalarsToColors is using log-scale, for example. Default
// implementation always return false.
virtual bool UsingLogScale();
virtual void emitEvent(unsigned long event, void* params);
virtual unsigned long int GetControlPointsMTime();
......@@ -93,6 +99,11 @@ protected:
virtual void DrawPoint(vtkContext2D* painter, vtkIdType index);
virtual void EditPoint(float tX, float tY);
// Description:
// Compute the bounds for this item. Overridden to use the
// vtkColorTransferFunction range.
virtual void ComputeBounds(double* bounds);
vtkColorTransferFunction* ColorTransferFunction;
bool ColorFill;
......
......@@ -12,7 +12,6 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkBrush.h"
#include "vtkCallbackCommand.h"
#include "vtkContext2D.h"
......@@ -25,6 +24,7 @@
#include "vtkPoints2D.h"
#include <cassert>
#include <math.h>
//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkColorTransferFunctionItem);
......@@ -40,6 +40,7 @@ vtkColorTransferFunctionItem::~vtkColorTransferFunctionItem()
{
if (this->ColorTransferFunction)
{
this->ColorTransferFunction->RemoveObserver(this->Callback);
this->ColorTransferFunction->Delete();
this->ColorTransferFunction = 0;
}
......@@ -115,10 +116,22 @@ void vtkColorTransferFunctionItem::ComputeTexture()
0, 0,
0, 0);
this->Texture->AllocateScalars(VTK_UNSIGNED_CHAR, 4);
bool isLogTable = this->UsingLogScale();
double logBoundsMin = bounds[0] > 0.0 ? log10(bounds[0]) : 0.0;
double logBoundsDelta = (bounds[0] > 0.0 && bounds[1] > 0.0)?
(log10(bounds[1])-log10(bounds[0])) : 0.0;
for (int i = 0; i < dimension; ++i)
{
values[i] = bounds[0] + i * (bounds[1] - bounds[0]) / (dimension - 1);
if (isLogTable)
{
double normVal = i/(dimension-1.0);
double lval = logBoundsMin + normVal*logBoundsDelta;
values[i] = pow(10.0, lval);
}
else
{
values[i] = bounds[0] + i * (bounds[1] - bounds[0]) / (dimension - 1);
}
}
unsigned char* ptr =
reinterpret_cast<unsigned char*>(this->Texture->GetScalarPointer(0,0,0));
......@@ -135,3 +148,10 @@ void vtkColorTransferFunctionItem::ComputeTexture()
delete [] values;
return;
}
//-----------------------------------------------------------------------------
bool vtkColorTransferFunctionItem::UsingLogScale()
{
return this->ColorTransferFunction?
(this->ColorTransferFunction->UsingLogScale() != 0) : false;
}
......@@ -39,6 +39,11 @@ protected:
vtkColorTransferFunctionItem();
virtual ~vtkColorTransferFunctionItem();
// Description:
// Returns true if we are rendering in log space.
virtual bool UsingLogScale();
// Description:
// Reimplemented to return the range of the lookup table
virtual void ComputeBounds(double bounds[4]);
......
......@@ -51,6 +51,7 @@ vtkCompositeControlPointsItem::~vtkCompositeControlPointsItem()
{
if (this->OpacityFunction)
{
this->OpacityFunction->RemoveObserver(this->Callback);
this->OpacityFunction->Delete();
this->OpacityFunction = 0;
}
......@@ -153,6 +154,13 @@ void vtkCompositeControlPointsItem::SetColorTransferFunction(vtkColorTransferFun
this->Superclass::SetColorTransferFunction(c);
}
//-----------------------------------------------------------------------------
bool vtkCompositeControlPointsItem::UsingLogScale()
{
return (this->ColorTransferFunction &&
this->ColorTransferFunction->UsingLogScale());
}
//-----------------------------------------------------------------------------
void vtkCompositeControlPointsItem::DrawPoint(vtkContext2D* painter, vtkIdType index)
{
......
......@@ -103,6 +103,11 @@ protected:
vtkCompositeControlPointsItem();
virtual ~vtkCompositeControlPointsItem();
// Description:
// Returns true if control points are to be rendered in log-space. This is
// true when vtkScalarsToColors is using log-scale, for example.
virtual bool UsingLogScale();
virtual void emitEvent(unsigned long event, void* params);
virtual unsigned long int GetControlPointsMTime();
......
......@@ -43,6 +43,7 @@ vtkCompositeTransferFunctionItem::~vtkCompositeTransferFunctionItem()
{
if (this->OpacityFunction)
{
this->OpacityFunction->RemoveObserver(this->Callback);
this->OpacityFunction->Delete();
this->OpacityFunction = 0;
}
......
......@@ -37,6 +37,12 @@ protected:
vtkCompositeTransferFunctionItem();
virtual ~vtkCompositeTransferFunctionItem();
// Description:
// Returns true if we are rendering in log space.
// Since vtkPiecewiseFunction doesn't support log, we show this transfer
// function in non-log space always.
virtual bool UsingLogScale() { return false; }
// Description:
// Reimplemented to return the range of the piecewise function
virtual void ComputeBounds(double bounds[4]);
......
This diff is collapsed.
......@@ -43,7 +43,9 @@ public:
enum {
CurrentPointChangedEvent = vtkCommand::UserEvent,
CurrentPointEditEvent
CurrentPointEditEvent,
PointsModifiedEvent // fired when the control points are changed by
// user-interaction.
};
// Description:
......@@ -175,6 +177,17 @@ public:
vtkSetMacro(EndPointsRemovable, bool);
vtkGetMacro(EndPointsRemovable, bool);
// Description:
// When set to true, labels are shown on the current control point and the end
// points. Default is false.
vtkSetMacro(ShowLabels, bool);
vtkGetMacro(ShowLabels, bool);
// Description:
// Get/Set the label format. Default is "%.4f, %.4f".
vtkSetStringMacro(LabelFormat);
vtkGetStringMacro(LabelFormat);
// Description:
// Add a point to the function. Returns the index of the point (0 based),
// or -1 on error.
......@@ -301,6 +314,12 @@ protected:
// Returns true if the supplied x, y coordinate is on a control point.
virtual bool Hit(const vtkContextMouseEvent &mouse);
// Description:
// Transform the mouse event in the control-points space. This is needed when
// ColorTransferFunction is using log-scale.
virtual void TransformScreenToData(const vtkVector2f& in, vtkVector2f& out);
virtual void TransformDataToScreen(const vtkVector2f& in, vtkVector2f& out);
// Description:
// Clamp the given 2D pos into the bounds of the function.
// Return true if the pos has been clamped, false otherwise.
......@@ -328,6 +347,10 @@ protected:
// Mouse button release event.
virtual bool MouseButtonReleaseEvent(const vtkContextMouseEvent &mouse);
// Description:
// Generate label for a control point.
virtual vtkStdString GetControlPointLabel(vtkIdType index);
void AddPointId(vtkIdType addedPointId);
// Description:
......@@ -339,6 +362,19 @@ protected:
// Return true if the point is removable
bool IsPointRemovable(vtkIdType pointId);
// Description:
// Compute the bounds for this item. Typically, the bounds should be aligned
// to the range of the vtkScalarsToColors or vtkPiecewiseFunction that is
// being controlled by the subclasses.
// Default implementation uses the range of the control points themselves.
virtual void ComputeBounds(double* bounds);
// Description:
// Returns true if control points are to be rendered in log-space. This is
// true when vtkScalarsToColors is using log-scale, for example. Default
// implementation always return false.
virtual bool UsingLogScale() { return false; }
vtkCallbackCommand* Callback;
vtkPen* SelectedPointPen;
vtkBrush* SelectedPointBrush;
......@@ -365,12 +401,13 @@ protected:
bool EndPointsXMovable;
bool EndPointsYMovable;
bool EndPointsRemovable;
bool ShowLabels;
char* LabelFormat;
private:
vtkControlPointsItem(const vtkControlPointsItem &); // Not implemented.
void operator=(const vtkControlPointsItem &); // Not implemented.
void ComputeBounds();
void ComputeBounds(double* bounds);
vtkIdType RemovePointId(vtkIdType removedPointId);
};
......
......@@ -45,6 +45,7 @@ vtkPiecewiseControlPointsItem::~vtkPiecewiseControlPointsItem()
{
if (this->PiecewiseFunction)
{
this->PiecewiseFunction->RemoveObserver(this->Callback);
this->PiecewiseFunction->Delete();
this->PiecewiseFunction = 0;
}
......@@ -130,6 +131,7 @@ void vtkPiecewiseControlPointsItem::SetControlPoint(vtkIdType index, double* new
newPos[2] != oldPos[2])
{
this->PiecewiseFunction->SetNodeValue(index, newPos);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
}
}
......@@ -151,6 +153,7 @@ void vtkPiecewiseControlPointsItem::EditPoint(float tX, float tY)
xvms[2] += tX;
xvms[3] += tY;
this->PiecewiseFunction->SetNodeValue(this->CurrentPoint - 1, xvms);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
}
}
......@@ -163,6 +166,7 @@ vtkIdType vtkPiecewiseControlPointsItem::AddPoint(double* newPos)
}
vtkIdType addedPoint = this->PiecewiseFunction->AddPoint(newPos[0], newPos[1]);
this->Superclass::AddPointId(addedPoint);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
return addedPoint;
}
......@@ -173,6 +177,10 @@ vtkIdType vtkPiecewiseControlPointsItem::RemovePoint(double* currentPoint)
{
return -1;
}
if (!this->IsPointRemovable(this->GetControlPointId(currentPoint)))
{
return -1;
}
#ifndef NDEBUG
vtkIdType expectedPoint =
#endif
......@@ -180,5 +188,6 @@ vtkIdType vtkPiecewiseControlPointsItem::RemovePoint(double* currentPoint)
vtkIdType removedPoint =
this->PiecewiseFunction->RemovePoint(currentPoint[0]);
assert(removedPoint == expectedPoint);
this->InvokeEvent(vtkControlPointsItem::PointsModifiedEvent);
return removedPoint;
}
......@@ -42,6 +42,7 @@ vtkPiecewiseFunctionItem::~vtkPiecewiseFunctionItem()
{
if (this->PiecewiseFunction)
{
this->PiecewiseFunction->RemoveObserver(this->Callback);
this->PiecewiseFunction->Delete();
this->PiecewiseFunction = 0;
}
......
......@@ -50,8 +50,8 @@ vtkScalarsToColorsItem::vtkScalarsToColorsItem()
this->MaskAboveCurve = false;
this->UserBounds[0] = this->UserBounds[1] = this->UserBounds[2] =
this->UserBounds[3] = 0.0;
this->UserBounds[0] = this->UserBounds[2] = 0.0;
this->UserBounds[1] = this->UserBounds[3] = -1.0;
}
//-----------------------------------------------------------------------------
......
......@@ -53,7 +53,7 @@ public:
// Description:
// Paint the children of the item, should be called whenever the children
// need to be rendered.
bool PaintChildren(vtkContext2D *painter);
virtual bool PaintChildren(vtkContext2D *painter);
// Description:
// Release graphics resources hold by the item. The default implementation
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment