Skip to content

Commit

Permalink
Merge pull request #965 from lassoan/fix-gradient-opacity-shift
Browse files Browse the repository at this point in the history
ENH: Make gradient opacity transfer function shift independently from opacity and color transfer functions
  • Loading branch information
pieper authored May 3, 2021
2 parents 88d954f + ebaf50a commit adacea2
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 27 deletions.
109 changes: 86 additions & 23 deletions Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ctkVTKVolumePropertyWidgetPrivate:
public:
ctkVTKVolumePropertyWidgetPrivate(ctkVTKVolumePropertyWidget& object);
void setupUi(QWidget* widget);
void computeRange(double* range);
void computeIntensityRange(double* range);
void updateThresholdSlider(vtkPiecewiseFunction* opacityFunction);
void setThreshold(double min, double max, double opacity);

Expand Down Expand Up @@ -87,7 +87,10 @@ void ctkVTKVolumePropertyWidgetPrivate::setupUi(QWidget* widget)
double validBounds[4] = {VTK_DOUBLE_MIN, VTK_DOUBLE_MAX, 0., 1.};
this->ScalarOpacityWidget->view()->setValidBounds(validBounds);
this->ScalarColorWidget->view()->setValidBounds(validBounds);
this->GradientWidget->view()->setValidBounds(validBounds);

// Gradient magnitude is always positive
double validPositiveBounds[4] = { 0, VTK_DOUBLE_MAX, 0., 1. };
this->GradientWidget->view()->setValidBounds(validPositiveBounds);

QObject::connect(this->ScalarOpacityWidget->view(), SIGNAL(extentChanged()),
q, SIGNAL(chartsExtentChanged()));
Expand Down Expand Up @@ -141,7 +144,7 @@ void ctkVTKVolumePropertyWidgetPrivate::setupUi(QWidget* widget)
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidgetPrivate::computeRange(double* range)
void ctkVTKVolumePropertyWidgetPrivate::computeIntensityRange(double* range)
{
if (!this->VolumeProperty)
{
Expand All @@ -165,11 +168,6 @@ void ctkVTKVolumePropertyWidgetPrivate::computeRange(double* range)
this->VolumeProperty->GetScalarOpacity(this->CurrentComponent)->GetRange(opacityRange);
range[0] = qMin(range[0], opacityRange[0]);
range[1] = qMax(range[1], opacityRange[1]);

double gradientRange[2] = {0., 1.};
this->VolumeProperty->GetGradientOpacity(this->CurrentComponent)->GetRange(gradientRange);
range[0] = qMin(range[0], gradientRange[0]);
range[1] = qMax(range[1], gradientRange[1]);
}

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -275,7 +273,7 @@ void ctkVTKVolumePropertyWidget::updateRange()
Q_D(ctkVTKVolumePropertyWidget);

double range[2] = {0.0};
d->computeRange(range);
d->computeIntensityRange(range);
d->ScalarOpacityThresholdWidget->setRange(range[0], range[1]);

// Elements: {leftMin, leftMax, bottomMin, bottomMax, rightMin, rightMax, topMin, topMax}
Expand All @@ -292,12 +290,6 @@ void ctkVTKVolumePropertyWidget::updateRange()
chartBounds[3] = range[1];
d->ScalarColorWidget->view()->setChartUserBounds(chartBounds);
d->ScalarColorWidget->view()->update();

d->GradientWidget->view()->chartBounds(chartBounds);
chartBounds[2] = range[0];
chartBounds[3] = range[1];
d->GradientWidget->view()->setChartUserBounds(chartBounds);
d->GradientWidget->view()->update();
}

// ----------------------------------------------------------------------------
Expand All @@ -314,12 +306,15 @@ void ctkVTKVolumePropertyWidget::chartsBounds(double bounds[4])const
bounds[1] = qMax(bounds[1], chartBounds[1]);
bounds[2] = qMin(bounds[2], chartBounds[2]);
bounds[3] = qMax(bounds[3], chartBounds[3]);
}

void ctkVTKVolumePropertyWidget::chartsGradientBounds(double bounds[4])const
{
Q_D(const ctkVTKVolumePropertyWidget);

double chartBounds[8] = { 0.0 };
d->GradientWidget->view()->chartBounds(chartBounds);
bounds[0] = qMin(bounds[0], chartBounds[0]);
bounds[1] = qMax(bounds[1], chartBounds[1]);
bounds[2] = qMin(bounds[2], chartBounds[2]);
bounds[3] = qMax(bounds[3], chartBounds[3]);
memcpy(bounds, chartBounds, 4 * sizeof(double));
}

// ----------------------------------------------------------------------------
Expand All @@ -333,12 +328,29 @@ QList<double> ctkVTKVolumePropertyWidget::chartsBounds()const
return bounds;
}

// ----------------------------------------------------------------------------
QList<double> ctkVTKVolumePropertyWidget::chartsGradientBounds()const
{
double boundsArray[4] = { 0.0 };
this->chartsGradientBounds(boundsArray);

QList<double> bounds;
bounds << boundsArray[0] << boundsArray[1] << boundsArray[2] << boundsArray[3];
return bounds;
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::setChartsExtent(double extent[2])
{
this->setChartsExtent(extent[0], extent[1]);
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::setChartsGradientExtent(double extent[2])
{
this->setChartsGradientExtent(extent[0], extent[1]);
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::setChartsExtent(double min, double max)
{
Expand All @@ -356,7 +368,14 @@ void ctkVTKVolumePropertyWidget::setChartsExtent(double min, double max)
chartExtent[1] = max;
d->ScalarColorWidget->view()->setChartUserExtent(chartExtent);
d->ScalarColorWidget->view()->update();
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::setChartsGradientExtent(double min, double max)
{
Q_D(ctkVTKVolumePropertyWidget);

double chartExtent[8] = { 0.0 };
d->GradientWidget->view()->chartExtent(chartExtent);
chartExtent[0] = min;
chartExtent[1] = max;
Expand All @@ -378,12 +397,15 @@ void ctkVTKVolumePropertyWidget::chartsExtent(double extent[4])const
extent[1] = qMax(extent[1], chartExtent[1]);
extent[2] = qMin(extent[2], chartExtent[2]);
extent[3] = qMax(extent[3], chartExtent[3]);
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::chartsGradientExtent(double extent[4])const
{
Q_D(const ctkVTKVolumePropertyWidget);
double chartExtent[8] = { 0.0 };
d->GradientWidget->view()->chartExtent(chartExtent);
extent[0] = qMin(extent[0], chartExtent[0]);
extent[1] = qMax(extent[1], chartExtent[1]);
extent[2] = qMin(extent[2], chartExtent[2]);
extent[3] = qMax(extent[3], chartExtent[3]);
memcpy(extent, chartExtent, 4 * sizeof(double));
}

// ----------------------------------------------------------------------------
Expand All @@ -397,6 +419,17 @@ QList<double> ctkVTKVolumePropertyWidget::chartsExtent()const
return extent;
}

// ----------------------------------------------------------------------------
QList<double> ctkVTKVolumePropertyWidget::chartsGradientExtent()const
{
double extentArray[4] = { 0.0 };
this->chartsGradientExtent(extentArray);

QList<double> extent;
extent << extentArray[0] << extentArray[1] << extentArray[2] << extentArray[3];
return extent;
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::setInterpolationMode(int mode)
{
Expand Down Expand Up @@ -544,6 +577,21 @@ void ctkVTKVolumePropertyWidget::moveAllPoints(double xOffset, double yOffset,
->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
d->ScalarColorWidget->view()
->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
if (d->VolumeProperty)
{
d->VolumeProperty->InvokeEvent(vtkCommand::EndEvent);
}
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::moveAllGradientPoints(double xOffset, double yOffset,
bool dontMoveFirstAndLast)
{
Q_D(ctkVTKVolumePropertyWidget);
if (d->VolumeProperty)
{
d->VolumeProperty->InvokeEvent(vtkCommand::StartEvent);
}
d->GradientWidget->view()
->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
if (d->VolumeProperty)
Expand All @@ -565,6 +613,21 @@ void ctkVTKVolumePropertyWidget::spreadAllPoints(double factor,
->spreadAllPoints(factor, dontSpreadFirstAndLast);
d->ScalarColorWidget->view()
->spreadAllPoints(factor, dontSpreadFirstAndLast);
if (d->VolumeProperty)
{
d->VolumeProperty->InvokeEvent(vtkCommand::EndEvent);
}
}

// ----------------------------------------------------------------------------
void ctkVTKVolumePropertyWidget::spreadAllGradientPoints(double factor,
bool dontSpreadFirstAndLast)
{
Q_D(ctkVTKVolumePropertyWidget);
if (d->VolumeProperty)
{
d->VolumeProperty->InvokeEvent(vtkCommand::StartEvent);
}
d->GradientWidget->view()
->spreadAllPoints(factor, dontSpreadFirstAndLast);
if (d->VolumeProperty)
Expand Down
39 changes: 35 additions & 4 deletions Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,34 +59,65 @@ class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKVolumePropertyWidget
bool isThresholdToggleVisible()const;
void setThresholdToggleVisible(bool showToggle);

/// Get intensity bounds of the chart.
void chartsBounds(double bounds[4])const;
/// Get intensity bounds of the chart.
Q_INVOKABLE QList<double> chartsBounds()const;
/// Get intensity extents of the chart.
void chartsExtent(double extent[4])const;
/// Get intensity extents of the chart.
Q_INVOKABLE QList<double> chartsExtent()const;

/// Get gradient bounds of the chart.
void chartsGradientBounds(double bounds[4])const;
/// Get gradient bounds of the chart.
Q_INVOKABLE QList<double> chartsGradientBounds()const;
/// Get gradient extents of the chart.
void chartsGradientExtent(double extent[4])const;
/// Get gradient extents of the chart.
Q_INVOKABLE QList<double> chartsGradientExtent()const;

public Q_SLOTS:
void setVolumeProperty(vtkVolumeProperty* volumeProperty);

/// Move all the control points of the opacity, colors and gradient
/// of a give offset.
/// Move all the control points of the opacity and colors
/// by a given offset.
/// \sa vtkControlPoints::movePoints()
void moveAllPoints(double xOffset, double yOffset = 0.,
bool dontSpreadFirstAndLast = false);

/// Spread all the control points of the opacity, colors and gradient
/// Move all the control points of the gradient opacity transfer function
/// by a given offset.
/// \sa vtkControlPoints::movePoints()
void moveAllGradientPoints(double xOffset, double yOffset = 0.,
bool dontSpreadFirstAndLast = false);

/// Spread all the control points of the opacity and colors
/// by a given offset.
/// A value >0 will space the control points, a value <0. will contract
/// them.
/// \sa vtkControlPoints::spreadPoints()
void spreadAllPoints(double factor = 1.,
bool dontSpreadFirstAndLast = false);

/// Spread all the control points of the gradient opacity transfer function
/// by a given offset.
/// A value >0 will space the control points, a value <0. will contract
/// them.
/// \sa vtkControlPoints::spreadPoints()
void spreadAllGradientPoints(double factor = 1.,
bool dontSpreadFirstAndLast = false);

void setThresholdEnabled(bool enable);

/// Set chart extent
/// Set charts intensity extent
void setChartsExtent(double extent[2]);
void setChartsExtent(double min, double max);

/// Set charts gradient extent
void setChartsGradientExtent(double extent[2]);
void setChartsGradientExtent(double min, double max);

Q_SIGNALS:
void thresholdEnabledChanged(bool enable);
void chartsExtentChanged();
Expand Down

0 comments on commit adacea2

Please sign in to comment.