mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
433 lines
14 KiB
C++
433 lines
14 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkCompositeControlPointsItem.cxx
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
|
|
#include "vtkBrush.h"
|
|
#include "vtkCallbackCommand.h"
|
|
#include "vtkContext2D.h"
|
|
#include "vtkIdTypeArray.h"
|
|
#include "vtkColorTransferFunction.h"
|
|
#include "vtkCompositeControlPointsItem.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPen.h"
|
|
#include "vtkPiecewiseFunction.h"
|
|
#include "vtkPoints2D.h"
|
|
#include "vtkContextScene.h"
|
|
#include "vtkPiecewisePointHandleItem.h"
|
|
|
|
// to handle mouse.GetButton
|
|
#include "vtkContextMouseEvent.h"
|
|
|
|
#include <cassert>
|
|
#include <limits>
|
|
#include <algorithm>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkStandardNewMacro(vtkCompositeControlPointsItem);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkCompositeControlPointsItem::vtkCompositeControlPointsItem()
|
|
{
|
|
this->PointsFunction = ColorAndOpacityPointsFunction;
|
|
this->OpacityFunction = 0;
|
|
this->ColorFill = true;
|
|
this->OpacityPointHandle = NULL;
|
|
this->UseOpacityPointHandles = false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkCompositeControlPointsItem::~vtkCompositeControlPointsItem()
|
|
{
|
|
if (this->OpacityFunction)
|
|
{
|
|
this->OpacityFunction->RemoveObserver(this->Callback);
|
|
this->OpacityFunction->Delete();
|
|
this->OpacityFunction = 0;
|
|
}
|
|
if (this->OpacityPointHandle)
|
|
{
|
|
this->OpacityPointHandle->Delete();
|
|
this->OpacityPointHandle = 0;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
os << indent << "OpacityFunction: ";
|
|
if (this->OpacityFunction)
|
|
{
|
|
os << endl;
|
|
this->OpacityFunction->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
os << indent << "OpacityFunction: ";
|
|
if (this->OpacityPointHandle)
|
|
{
|
|
os << endl;
|
|
this->OpacityPointHandle->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
os << indent << "UseOpacityPointHandles: " << this->UseOpacityPointHandles << endl;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::emitEvent(unsigned long event, void* params)
|
|
{
|
|
if (this->OpacityFunction)
|
|
{
|
|
this->OpacityFunction->InvokeEvent(event, params);
|
|
}
|
|
this->Superclass::emitEvent(event, params);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
unsigned long int vtkCompositeControlPointsItem::GetControlPointsMTime()
|
|
{
|
|
unsigned long int mTime = this->Superclass::GetControlPointsMTime();
|
|
if (this->OpacityFunction)
|
|
{
|
|
mTime = std::max(mTime, this->OpacityFunction->GetMTime());
|
|
}
|
|
return mTime;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::SetOpacityFunction(vtkPiecewiseFunction* function)
|
|
{
|
|
if (function == this->OpacityFunction)
|
|
{
|
|
return;
|
|
}
|
|
if (this->OpacityFunction)
|
|
{
|
|
this->OpacityFunction->RemoveObserver(this->Callback);
|
|
}
|
|
vtkSetObjectBodyMacro(OpacityFunction, vtkPiecewiseFunction, function);
|
|
if (this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
this->SilentMergeTransferFunctions();
|
|
}
|
|
if (this->OpacityFunction)
|
|
{
|
|
this->OpacityFunction->AddObserver(vtkCommand::StartEvent, this->Callback);
|
|
this->OpacityFunction->AddObserver(vtkCommand::ModifiedEvent, this->Callback);
|
|
this->OpacityFunction->AddObserver(vtkCommand::EndEvent, this->Callback);
|
|
}
|
|
this->ResetBounds();
|
|
this->ComputePoints();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::SetColorTransferFunction(vtkColorTransferFunction* c)
|
|
{
|
|
if (c == this->ColorTransferFunction)
|
|
{
|
|
return;
|
|
}
|
|
// We need to set the color transfer function here (before
|
|
// Superclass::SetPiecewiseFunction) to be able to have a valid
|
|
// color transfer function for MergeColorTransferFunction().
|
|
vtkSetObjectBodyMacro(ColorTransferFunction, vtkColorTransferFunction, c);
|
|
if (this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
this->SilentMergeTransferFunctions();
|
|
}
|
|
this->Superclass::SetColorTransferFunction(c);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkCompositeControlPointsItem::UsingLogScale()
|
|
{
|
|
return (this->PointsFunction != OpacityPointsFunction &&
|
|
this->ColorTransferFunction &&
|
|
this->ColorTransferFunction->UsingLogScale());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::DrawPoint(vtkContext2D* painter, vtkIdType index)
|
|
{
|
|
if (this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
this->Superclass::DrawPoint(painter, index);
|
|
return;
|
|
}
|
|
if (this->PointsFunction == OpacityPointsFunction &&
|
|
this->ColorFill && this->ColorTransferFunction)
|
|
{
|
|
double xvms[4];
|
|
this->OpacityFunction->GetNodeValue(index, xvms);
|
|
unsigned char* rgb = this->ColorTransferFunction->MapValue(xvms[0]);
|
|
painter->GetBrush()->SetColorF(
|
|
rgb[0] / 255., rgb[1] / 255., rgb[2] / 255., 0.55);
|
|
}
|
|
this->vtkControlPointsItem::DrawPoint(painter, index);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkIdType vtkCompositeControlPointsItem::GetNumberOfPoints()const
|
|
{
|
|
if (this->ColorTransferFunction &&
|
|
(this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
return this->Superclass::GetNumberOfPoints();
|
|
}
|
|
if (this->OpacityFunction &&
|
|
(this->PointsFunction == OpacityPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
return static_cast<vtkIdType>(this->OpacityFunction->GetSize());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::SetControlPoint(vtkIdType index, double* newPos)
|
|
{
|
|
if (this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
this->Superclass::SetControlPoint(index, newPos);
|
|
}
|
|
if (this->OpacityFunction &&
|
|
(this->PointsFunction == OpacityPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
this->StartChanges();
|
|
this->OpacityFunction->SetNodeValue(index, newPos);
|
|
this->EndChanges();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::GetControlPoint(vtkIdType index, double* pos)const
|
|
{
|
|
if (!this->OpacityFunction ||
|
|
this->PointsFunction == ColorPointsFunction)
|
|
{
|
|
this->Superclass::GetControlPoint(index, pos);
|
|
if (this->OpacityFunction)
|
|
{
|
|
pos[1] = const_cast<vtkPiecewiseFunction*>(this->OpacityFunction)
|
|
->GetValue(pos[0]);
|
|
}
|
|
return;
|
|
}
|
|
const_cast<vtkPiecewiseFunction*>(this->OpacityFunction)
|
|
->GetNodeValue(index, pos);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::EditPoint(float tX, float tY)
|
|
{
|
|
if (this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
this->Superclass::EditPoint(tX, tY);
|
|
}
|
|
if (this->OpacityFunction &&
|
|
(this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
this->StartChanges();
|
|
double xvms[4];
|
|
this->OpacityFunction->GetNodeValue(this->CurrentPoint, xvms);
|
|
xvms[2] += tX;
|
|
xvms[3] += tY;
|
|
this->OpacityFunction->SetNodeValue(this->CurrentPoint, xvms);
|
|
// Not sure why we move the point before too
|
|
if (this->CurrentPoint > 0)
|
|
{
|
|
this->OpacityFunction->GetNodeValue(this->CurrentPoint - 1, xvms);
|
|
xvms[2] += tX;
|
|
xvms[3] += tY;
|
|
this->OpacityFunction->SetNodeValue(this->CurrentPoint - 1, xvms);
|
|
}
|
|
this->EndChanges();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkIdType vtkCompositeControlPointsItem::AddPoint(double* newPos)
|
|
{
|
|
vtkIdType addedPoint = -1;
|
|
this->StartChanges();
|
|
if (this->OpacityFunction &&
|
|
(this->PointsFunction == OpacityPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
addedPoint = this->OpacityFunction->AddPoint(newPos[0], newPos[1]);
|
|
if (this->PointsFunction == OpacityPointsFunction)
|
|
{
|
|
this->vtkControlPointsItem::AddPointId(addedPoint);
|
|
}
|
|
}
|
|
if (this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
addedPoint = this->Superclass::AddPoint(newPos);
|
|
}
|
|
this->EndChanges();
|
|
return addedPoint;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkIdType vtkCompositeControlPointsItem::RemovePoint(double* currentPoint)
|
|
{
|
|
vtkIdType removedPoint = -1;
|
|
if (!this->IsPointRemovable(this->GetControlPointId(currentPoint)))
|
|
{
|
|
return removedPoint;
|
|
}
|
|
|
|
this->StartChanges();
|
|
if (this->PointsFunction == ColorPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction)
|
|
{
|
|
removedPoint = this->Superclass::RemovePoint(currentPoint);
|
|
}
|
|
if (this->OpacityFunction &&
|
|
(this->PointsFunction == OpacityPointsFunction ||
|
|
this->PointsFunction == ColorAndOpacityPointsFunction))
|
|
{
|
|
removedPoint = this->OpacityFunction->RemovePoint(currentPoint[0]);
|
|
}
|
|
this->EndChanges();
|
|
return removedPoint;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::MergeTransferFunctions()
|
|
{
|
|
if (!this->ColorTransferFunction || !this->OpacityFunction)
|
|
{
|
|
return;
|
|
}
|
|
// Naive implementation that does the work but can be a bit slow
|
|
// Copy OpacityFunction points into the ColorTransferFunction
|
|
const int piecewiseFunctionCount = this->OpacityFunction->GetSize();
|
|
for (int i = 0; i < piecewiseFunctionCount; ++i)
|
|
{
|
|
double piecewisePoint[4];
|
|
this->OpacityFunction->GetNodeValue(i, piecewisePoint);
|
|
double rgb[3];
|
|
this->ColorTransferFunction->GetColor(piecewisePoint[0], rgb);
|
|
// note that we might lose the midpoint/sharpness of the point if any
|
|
this->ColorTransferFunction->RemovePoint(piecewisePoint[0]);
|
|
this->ColorTransferFunction->AddRGBPoint(piecewisePoint[0], rgb[0], rgb[1], rgb[2], piecewisePoint[2], piecewisePoint[3]);
|
|
}
|
|
// Copy ColorTransferFunction points into the OpacityFunction
|
|
const int colorFunctionCount = this->ColorTransferFunction->GetSize();
|
|
for (int i = 0; i < colorFunctionCount; ++i)
|
|
{
|
|
double xrgbms[6];
|
|
this->ColorTransferFunction->GetNodeValue(i, xrgbms);
|
|
double value = this->OpacityFunction->GetValue(xrgbms[0]);
|
|
// note that we might lose the midpoint/sharpness of the point if any
|
|
this->OpacityFunction->RemovePoint(xrgbms[0]);
|
|
this->OpacityFunction->AddPoint(xrgbms[0], value, xrgbms[4], xrgbms[5]);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::SilentMergeTransferFunctions()
|
|
{
|
|
this->StartChanges();
|
|
this->MergeTransferFunctions();
|
|
this->EndChanges();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkCompositeControlPointsItem::MouseButtonPressEvent(const vtkContextMouseEvent &mouse)
|
|
{
|
|
bool result=false;
|
|
if(this->OpacityPointHandle && this->OpacityPointHandle->GetVisible())
|
|
{
|
|
result = this->OpacityPointHandle->MouseButtonPressEvent(mouse);
|
|
}
|
|
if(!result)
|
|
{
|
|
result = this->Superclass::MouseButtonPressEvent(mouse);
|
|
if(result && this->OpacityPointHandle &&
|
|
this->OpacityPointHandle->GetVisible() &&
|
|
this->OpacityPointHandle->GetCurrentPointIndex() !=
|
|
this->GetCurrentPoint())
|
|
{
|
|
this->OpacityPointHandle->SetVisible(false);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkCompositeControlPointsItem::MouseDoubleClickEvent(const vtkContextMouseEvent &mouse)
|
|
{
|
|
bool superRes = this->Superclass::MouseDoubleClickEvent(mouse);
|
|
if(superRes)
|
|
{
|
|
vtkIdType curIdx = this->GetCurrentPoint();
|
|
this->EditPointCurve(curIdx);
|
|
}
|
|
return superRes;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkCompositeControlPointsItem::MouseMoveEvent(const vtkContextMouseEvent &mouse)
|
|
{
|
|
bool result=false;
|
|
if(this->OpacityPointHandle && this->OpacityPointHandle->GetVisible())
|
|
{
|
|
result = this->OpacityPointHandle->MouseMoveEvent(mouse);
|
|
}
|
|
if(!result)
|
|
{
|
|
result = this->Superclass::MouseMoveEvent(mouse);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkCompositeControlPointsItem::EditPointCurve(vtkIdType index)
|
|
{
|
|
if(index<0 || index>=this->GetNumberOfPoints())
|
|
{
|
|
return;
|
|
}
|
|
if(this->GetUseOpacityPointHandles())
|
|
{
|
|
if(!this->OpacityPointHandle)
|
|
{
|
|
this->OpacityPointHandle = vtkPiecewisePointHandleItem::New();
|
|
this->AddItem(this->OpacityPointHandle);
|
|
this->OpacityPointHandle->SetPiecewiseFunction(
|
|
this->GetOpacityFunction());
|
|
}
|
|
else
|
|
{
|
|
this->OpacityPointHandle->SetVisible(
|
|
!this->OpacityPointHandle->GetVisible());
|
|
this->GetScene()->SetDirty(true);
|
|
}
|
|
}
|
|
}
|