Commit 4fd51eea authored by Utkarsh Ayachit's avatar Utkarsh Ayachit
Browse files

Added slice annotations to OrthographicSliceView.

Also set vtkSMOrthographicSliceViewProxy and vtkSMMultiSliceViewProxy to
show Slices by default and also initialize view properties when a
representation is added.

Change-Id: I02f10e797427a09c5e6414306b46137deff77ca3
parent fd01c29c
......@@ -28,8 +28,12 @@
#include "vtkRenderer.h"
#include "vtkRenderViewBase.h"
#include "vtkRenderWindow.h"
#include "vtkTextActor.h"
#include "vtkTextProperty.h"
#include "vtkTextRepresentation.h"
#include <cassert>
#include <sstream>
class vtkPVOrthographicSliceViewInteractorStyle : public vtkPVInteractorStyle
{
......@@ -82,7 +86,9 @@ vtkPVOrthographicSliceView::vtkPVOrthographicSliceView()
: Renderers(),
OrthographicInteractorStyle(),
SlicePositionAxes2D(),
SlicePositionAxes3D()
SlicePositionAxes3D(),
SliceAnnotations(),
SliceAnnotationsVisibility(false)
{
this->CenterAxes->SetVisibility(0);
this->SliceIncrements[0] = this->SliceIncrements[1] = this->SliceIncrements[2] = 1.0;
......@@ -94,11 +100,21 @@ vtkPVOrthographicSliceView::vtkPVOrthographicSliceView()
this->Renderers[cc]->SetBackground(0.5, 0.5, 0.5);
this->Renderers[cc]->GetActiveCamera()->SetParallelProjection(1);
window->AddRenderer(this->Renderers[cc].GetPointer());
this->SlicePositionAxes2D[cc]->SetComputeNormals(0);
this->SlicePositionAxes2D[cc]->SetPickable(0);
this->SlicePositionAxes2D[cc]->SetUseBounds(1);
this->SlicePositionAxes2D[cc]->SetScale(10, 10, 10);
this->Renderers[cc]->AddActor(this->SlicePositionAxes2D[cc].GetPointer());
this->SliceAnnotations[cc]->SetRenderer(this->Renderers[cc].GetPointer());
this->SliceAnnotations[cc]->SetText("Slice Annotation");
this->SliceAnnotations[cc]->BuildRepresentation();
this->SliceAnnotations[cc]->SetWindowLocation(vtkTextRepresentation::AnyLocation);
this->SliceAnnotations[cc]->GetTextActor()->SetTextScaleModeToNone();
this->SliceAnnotations[cc]->GetTextActor()->GetTextProperty()->SetJustificationToLeft();
this->SliceAnnotations[cc]->SetVisibility(0);
this->Renderers[cc]->AddActor(this->SliceAnnotations[cc].GetPointer());
}
this->SlicePositionAxes3D->SetComputeNormals(0);
......@@ -165,14 +181,28 @@ void vtkPVOrthographicSliceView::SetInteractionMode(int mode)
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::ResetCamera()
{
this->Superclass::ResetCamera();
double bounds[6];
this->GeometryBounds.GetBounds(bounds);
for (int cc=0; cc < 3; cc++)
{
this->SlicePositionAxes2D[cc]->SetUseBounds(0);
this->Renderers[cc]->ResetCamera();
this->SlicePositionAxes2D[cc]->SetUseBounds(1);
this->Renderers[cc]->ResetCamera(bounds);
// do this explicitly to ensure the SlicePositionAxes2D doesn't get clipped.
this->Renderers[cc]->ResetCameraClippingRange();
}
}
//----------------------------------------------------------------------------
// Note this is called on all processes.
void vtkPVOrthographicSliceView::ResetCamera(double bounds[6])
{
this->Superclass::ResetCamera(bounds);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->ResetCamera(bounds);
// do this explicitly to ensure the SlicePositionAxes2D doesn't get clipped.
this->Renderers[cc]->ResetCameraClippingRange();
}
this->Superclass::ResetCamera();
}
//----------------------------------------------------------------------------
vtkRenderer* vtkPVOrthographicSliceView::GetRenderer(int index)
......@@ -210,6 +240,16 @@ void vtkPVOrthographicSliceView::Initialize(unsigned int id)
double lowerLeft[]={0, 0, 0.5, 0.5};
this->Renderers[FRONT_VIEW]->SetViewport(lowerLeft);
this->SynchronizedWindows->AddRenderer(id, this->Renderers[FRONT_VIEW].GetPointer(), lowerLeft);
for (int cc=0; cc < 3; cc++)
{
double viewport[4];
this->Renderers[cc]->GetViewport(viewport);
// BUG: one would think x coordinate should be viewport[0]. But there's
// something funny with vtkTextRepresentation. We x coordinate relative to
// the renderer's viewport, but y coordinate relative to the window!
this->SliceAnnotations[cc]->SetPosition(0+0.01, viewport[1] + 0.01);
}
}
//----------------------------------------------------------------------------
......@@ -248,12 +288,6 @@ void vtkPVOrthographicSliceView::UpdateCenterAxes()
this->SlicePositionAxes3D->SetScale(widths);
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::ResetCameraClippingRange()
{
this->Superclass::ResetCameraClippingRange();
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::AboutToRenderOnLocalProcess(bool interactive)
{
......@@ -285,6 +319,28 @@ void vtkPVOrthographicSliceView::AboutToRenderOnLocalProcess(bool interactive)
fp[1] + axis[cc].GetData()[1] * focaldistance,
fp[2] + axis[cc].GetData()[2] * focaldistance);
}
// Setup slice annotations.
// const char* axis_names[] = {"Sagittal", "Axial", "Coronal" };
const char* view_names[] = {"Right Side", "Top", "Front" };
const char* axis_names[] = {"X", "Y", "Z" };
for (int cc=0; cc <3; cc++)
{
if (const char* label = this->GetAxisLabel(cc))
{
axis_names[cc] = label;
view_names[cc] = label;
}
}
for (int cc=0; cc < 3; cc++)
{
this->SliceAnnotations[cc]->SetVisibility(this->SliceAnnotationsVisibility? 1 : 0);
std::ostringstream stream;
stream << view_names[cc] << " View ( " << axis_names[cc] << "=" << this->SlicePosition[cc] << ")\n";
stream << axis_names[(cc+1)%3] << "=" << this->SlicePosition[(cc+1)%3] << ",";
stream << axis_names[(cc+2)%3] << "=" << this->SlicePosition[(cc+2)%3];
this->SliceAnnotations[cc]->SetText(stream.str().c_str());
}
this->Superclass::AboutToRenderOnLocalProcess(interactive);
}
......@@ -334,6 +390,56 @@ void vtkPVOrthographicSliceView::OnMouseWheelBackwardEvent()
this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, pos);
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::SetBackground(double r, double g, double b)
{
this->Superclass::SetBackground(r, g, b);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->SetBackground(r, g, b);
}
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::SetBackground2(double r, double g, double b)
{
this->Superclass::SetBackground2(r, g, b);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->SetBackground2(r, g, b);
}
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::SetBackgroundTexture(vtkTexture* val)
{
this->Superclass::SetBackgroundTexture(val);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->SetBackgroundTexture(val);
}
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::SetGradientBackground(int val)
{
this->Superclass::SetGradientBackground(val);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->SetGradientBackground(val);
}
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::SetTexturedBackground(int val)
{
this->Superclass::SetTexturedBackground(val);
for (int cc=0; cc < 3; cc++)
{
this->Renderers[cc]->SetTexturedBackground(val);
}
}
//----------------------------------------------------------------------------
void vtkPVOrthographicSliceView::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -63,6 +63,7 @@ public:
using Superclass::GetRenderer;
virtual void ResetCamera();
virtual void ResetCamera(double bounds[6]);
virtual void SetInteractionMode(int mode);
// Description:
......@@ -74,10 +75,24 @@ public:
// Set slice increments.
vtkSetVector3Macro(SliceIncrements, double);
// Description:
// Get/Set whether to show slice annotations.
vtkSetMacro(SliceAnnotationsVisibility, bool);
vtkGetMacro(SliceAnnotationsVisibility, bool);
// Description:
// To avoid confusion, we don't show the center axes at all in this view.
virtual void SetCenterAxesVisibility(bool){}
//*****************************************************************
virtual void SetBackground(double r, double g, double b);
virtual void SetBackground2(double r, double g, double b);
virtual void SetBackgroundTexture(vtkTexture* val);
virtual void SetGradientBackground(int val);
virtual void SetTexturedBackground(int val);
//BTX
protected:
vtkPVOrthographicSliceView();
......@@ -85,14 +100,16 @@ protected:
virtual void AboutToRenderOnLocalProcess(bool interactive);
virtual void UpdateCenterAxes();
virtual void ResetCameraClippingRange();
vtkNew<vtkRenderer> Renderers[3];
vtkNew<vtkPVOrthographicSliceViewInteractorStyle> OrthographicInteractorStyle;
vtkNew<vtkPVCenterAxesActor> SlicePositionAxes2D[3];
vtkNew<vtkPVCenterAxesActor> SlicePositionAxes3D;
vtkNew<vtkTextRepresentation> SliceAnnotations[3];
double SliceIncrements[3];
double SlicePosition[3];
bool SliceAnnotationsVisibility;
private:
vtkPVOrthographicSliceView(const vtkPVOrthographicSliceView&); // Not implemented
void operator=(const vtkPVOrthographicSliceView&); // Not implemented
......
......@@ -363,6 +363,7 @@ public:
// manager XML. Returns the XML element for the hints associated with
// this property, if any, otherwise returns NULL.
vtkGetObjectMacro(Hints, vtkPVXMLElement);
void SetHints(vtkPVXMLElement* hints);
// Description:
// Overridden to support blocking of modified events.
......@@ -480,7 +481,6 @@ protected:
// Updates state from an XML element. Returns 0 on failure.
virtual int LoadState(vtkPVXMLElement* element, vtkSMProxyLocator* loader);
void SetHints(vtkPVXMLElement* hints);
vtkPVXMLElement* Hints;
char* Command;
......
......@@ -16,10 +16,14 @@
#include "vtkBoundingBox.h"
#include "vtkClientServerStream.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
#include "vtkPVDataSetAttributesInformation.h"
#include "vtkPVMultiSliceView.h"
#include "vtkPVSession.h"
#include "vtkPVXMLElement.h"
#include "vtkSMInputProperty.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMProxyManager.h"
......@@ -153,60 +157,103 @@ vtkSMRepresentationProxy* vtkSMMultiSliceViewProxy::CreateDefaultRepresentation(
{
vtkSMRepresentationProxy* repr = this->Superclass::CreateDefaultRepresentation(
proxy,outputPort);
if (repr)
if (repr && strcmp(repr->GetXMLName(), "CompositeMultiSliceRepresentation") == 0)
{
this->InitDefaultSlices(vtkSMSourceProxy::SafeDownCast(proxy), outputPort, repr);
return repr;
}
// Currently only images can be shown
// vtkErrorMacro("This view only supports Multi-Slice representation.");
return 0;
return repr;
}
//-----------------------------------------------------------------------------
void vtkSMMultiSliceViewProxy::InitDefaultSlices(
vtkSMSourceProxy* source, int opport, vtkSMRepresentationProxy*)
// HACK: method to force representation type to "Slices".
void vtkSMMultiSliceViewProxy::ForceRepresentationType(
vtkSMProxy* repr, const char* type)
{
if (!source)
// HACK: to set default representation type to Slices.
vtkSMPropertyHelper reprProp(repr, "Representation");
reprProp.Set(type);
vtkNew<vtkPVXMLElement> nodefault;
nodefault->SetName("NoDefault");
if (vtkPVXMLElement* hints = repr->GetProperty("Representation")->GetHints())
{
return;
hints->AddNestedElement(nodefault.GetPointer());
}
// FIXME:UDA
return;
double bounds[6] = { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN,
VTK_DOUBLE_MAX, VTK_DOUBLE_MIN,
VTK_DOUBLE_MAX, VTK_DOUBLE_MIN};
vtkPVDataInformation* info = source->GetDataInformation(opport);
if(info)
else
{
info->GetBounds(bounds);
if(vtkBoundingBox::IsValid(bounds))
vtkNew<vtkPVXMLElement> hints2;
hints2->SetName("Hints");
hints2->AddNestedElement(nodefault.GetPointer());
repr->GetProperty("Representation")->SetHints(hints2.GetPointer());
}
}
//-----------------------------------------------------------------------------
// HACK: Get representation's input data bounds.
bool vtkSMMultiSliceViewProxy::GetDataBounds(
vtkSMSourceProxy* source, int opport, double bounds[6])
{
vtkPVDataInformation* info = source? source->GetDataInformation(opport) : NULL;
if (info)
{
if (vtkPVArrayInformation* ainfo =
info->GetFieldDataInformation()->GetArrayInformation("BoundingBoxInModelCoordinates"))
{
double center[3];
for(int i=0;i<3;i++)
// use "original basis" bounds, if present.
if (ainfo->GetNumberOfTuples() == 1 && ainfo->GetNumberOfComponents() == 6)
{
center[i] = (bounds[2*i] + bounds[2*i+1])/2.0;
for (int cc=0; cc < 6; cc++)
{
bounds[cc] = ainfo->GetComponentRange(cc)[0];
}
return true;
}
// Add orthogonal X,Y,Z slices based on center position.
std::vector<double> xSlices =
vtkSMPropertyHelper(this, "XSlicesValues").GetDoubleArray();
std::vector<double> ySlices =
vtkSMPropertyHelper(this, "YSlicesValues").GetDoubleArray();
std::vector<double> zSlices =
vtkSMPropertyHelper(this, "ZSlicesValues").GetDoubleArray();
}
info->GetBounds(bounds);
return vtkBoundingBox::IsValid(bounds);
}
return false;
}
//-----------------------------------------------------------------------------
void vtkSMMultiSliceViewProxy::InitDefaultSlices(
vtkSMSourceProxy* source, int opport, vtkSMRepresentationProxy* repr)
{
if (!source)
{
return;
}
vtkSMMultiSliceViewProxy::ForceRepresentationType(repr, "Slices");
double bounds[6];
if (vtkSMMultiSliceViewProxy::GetDataBounds(source, opport, bounds))
{
vtkBoundingBox bbox(bounds);
double center[3];
bbox.GetCenter(center);
// Add orthogonal X,Y,Z slices based on center position.
std::vector<double> xSlices =
vtkSMPropertyHelper(this, "XSlicesValues").GetDoubleArray();
std::vector<double> ySlices =
vtkSMPropertyHelper(this, "YSlicesValues").GetDoubleArray();
std::vector<double> zSlices =
vtkSMPropertyHelper(this, "ZSlicesValues").GetDoubleArray();
if (xSlices.size() == 0 && ySlices.size() == 0 && zSlices.size() == 0)
{
xSlices.push_back(center[0]);
ySlices.push_back(center[1]);
zSlices.push_back(center[2]);
vtkSMPropertyHelper(this, "XSlicesValues").Set(&xSlices[0],
static_cast<unsigned int>(xSlices.size()));
static_cast<unsigned int>(xSlices.size()));
vtkSMPropertyHelper(this, "YSlicesValues").Set(&ySlices[0],
static_cast<unsigned int>(ySlices.size()));
static_cast<unsigned int>(ySlices.size()));
vtkSMPropertyHelper(this, "ZSlicesValues").Set(&zSlices[0],
static_cast<unsigned int>(ySlices.size()));
static_cast<unsigned int>(ySlices.size()));
}
this->UpdateVTKObjects();
}
}
......
......@@ -60,6 +60,14 @@ public:
// synced among all ranks in Update().
void GetDataBounds(double bounds[6]);
// Description:
// HACK: method to force representation type to "Slices".
static void ForceRepresentationType(vtkSMProxy* reprProxy, const char* type);
// Description:
// HACK: Get source's input data bounds (or BoundingBoxInModelCoordinates if
// present).
static bool GetDataBounds(vtkSMSourceProxy* source, int opport, double bounds[6]);
//BTX
protected:
vtkSMMultiSliceViewProxy();
......
......@@ -14,11 +14,14 @@
=========================================================================*/
#include "vtkSMOrthographicSliceViewProxy.h"
#include "vtkBoundingBox.h"
#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkPVOrthographicSliceView.h"
#include "vtkSMInputProperty.h"
#include "vtkSMMultiSliceViewProxy.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMRepresentationProxy.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSourceProxy.h"
......@@ -83,6 +86,47 @@ const char* vtkSMOrthographicSliceViewProxy::GetRepresentationType(
this->Superclass::GetRepresentationType(producer, outputPort);
}
//----------------------------------------------------------------------------
vtkSMRepresentationProxy* vtkSMOrthographicSliceViewProxy::CreateDefaultRepresentation(
vtkSMProxy* proxy, int outputPort)
{
vtkSMRepresentationProxy* repr = this->Superclass::CreateDefaultRepresentation(
proxy,outputPort);
if (repr && strcmp(repr->GetXMLName(), "CompositeOrthographicSliceRepresentation") == 0)
{
this->InitDefaultSlices(vtkSMSourceProxy::SafeDownCast(proxy), outputPort, repr);
}
return repr;
}
//-----------------------------------------------------------------------------
void vtkSMOrthographicSliceViewProxy::InitDefaultSlices(
vtkSMSourceProxy* source, int opport, vtkSMRepresentationProxy* repr)
{
if (!source)
{
return;
}
// HACK: to set default representation type to Slices.
vtkSMMultiSliceViewProxy::ForceRepresentationType(repr, "Slices");
double bounds[6];
if (vtkSMMultiSliceViewProxy::GetDataBounds(source, opport, bounds))
{
vtkBoundingBox bbox(bounds);
double center[3];
bbox.GetCenter(center);
vtkSMPropertyHelper(this, "SlicePosition").Set(center, 3);
double lengths[3];
bbox.Scale(0.1, 0.1, 0.1);
bbox.GetLengths(lengths);
vtkSMPropertyHelper(this, "SliceIncrements").Set(lengths, 3);
this->UpdateVTKObjects();
}
}
//----------------------------------------------------------------------------
void vtkSMOrthographicSliceViewProxy::OnMouseWheelBackwardEvent(
vtkObject*, unsigned long, void* calldata)
......
......@@ -20,6 +20,7 @@
#define __vtkSMOrthographicSliceViewProxy_h
#include "vtkSMRenderViewProxy.h"
class vtkSMRepresentationProxy;
class VTKPVSERVERMANAGERRENDERING_EXPORT vtkSMOrthographicSliceViewProxy : public vtkSMRenderViewProxy
{
......@@ -33,11 +34,22 @@ public:
virtual const char* GetRepresentationType(
vtkSMSourceProxy* producer, int outputPort);
// Description:
// Overridden to set initial default slices when a representation is created.
// Not sure that's the best way to do this, but leaving the logic unchanged in
// this pass.
virtual vtkSMRepresentationProxy* CreateDefaultRepresentation(
vtkSMProxy* proxy, int outputPort);
//BTX
protected:
vtkSMOrthographicSliceViewProxy();
~vtkSMOrthographicSliceViewProxy();
// Description:
void InitDefaultSlices(vtkSMSourceProxy* source, int opport,
vtkSMRepresentationProxy* repr);
virtual void CreateVTKObjects();
void OnMouseWheelBackwardEvent(vtkObject*, unsigned long, void* calldata);
void OnMouseWheelForwardEvent(vtkObject*, unsigned long, void* calldata);
......
......@@ -2256,12 +2256,25 @@
</Documentation>
<DoubleRangeDomain name="range" />
</DoubleVectorProperty>
<DoubleVectorProperty name="SliceIncrements"
command="SetSliceIncrements"
number_of_elements="3"
default_values="1 1 1">
<DoubleRangeDomain name="range" />
</DoubleVectorProperty>
<Documentation>
When interacting using the thumb wheel, set the increments to use
to change the slice position.
</Documentation>
</DoubleVectorProperty>
<IntVectorProperty name="ShowSliceAnnotations"
command="SetSliceAnnotationsVisibility"
number_of_elements="1"
default_values="1">
<BooleanDomain name="bool" />
</IntVectorProperty>
</OrthographicSliceViewProxy>
<!-- ================================================================== -->
......
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