Skip to content

Instantly share code, notes, and snippets.

@cpinter
Created July 11, 2019 15:56
Show Gist options
  • Save cpinter/ba47dd9075a5afa5aae012b08c31e927 to your computer and use it in GitHub Desktop.
Save cpinter/ba47dd9075a5afa5aae012b08c31e927 to your computer and use it in GitHub Desktop.
Python wrapping of static constant string
/*==============================================================================
Program: 3D Slicer
Portions (c) Copyright Brigham and Women's Hospital (BWH) All Rights Reserved.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
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.
==============================================================================*/
// MRML includes
#include "vtkMRMLInteractionEventData.h"
#include "vtkMRMLMarkupsDisplayNode.h"
#include <vtkMRMLProceduralColorNode.h>
// VTK includes
#include <vtkCommand.h>
#include <vtkDiscretizableColorTransferFunction.h>
#include <vtkIntArray.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkPiecewiseFunction.h>
// STL includes
#include <sstream>
const char* vtkMRMLMarkupsDisplayNode::LineColorNodeReferenceRole = "lineColor";
const char* vtkMRMLMarkupsDisplayNode::LineColorNodeReferenceMRMLAttributeName = "lineColorNodeRef";
const std::string vtkMRMLMarkupsDisplayNode::DEFAULT_CONTEXT_NAME = "";
//----------------------------------------------------------------------------
vtkMRMLNodeNewMacro(vtkMRMLMarkupsDisplayNode);
//----------------------------------------------------------------------------
vtkMRMLMarkupsDisplayNode::vtkMRMLMarkupsDisplayNode()
{
// Markups display node settings
this->Visibility = 1;
this->Visibility2D = 1;
this->VectorVisibility = 0;
this->ScalarVisibility = 0;
this->TensorVisibility = 0;
this->Color[0] = 0.4;
this->Color[1] = 1.0;
this->Color[2] = 1.0;
this->SelectedColor[0] = 1.0;
this->SelectedColor[1] = 0.5;
this->SelectedColor[2] = 0.5;
this->SetName("");
this->Opacity = 1.0;
this->Ambient = 0;
this->Diffuse = 1.0;
this->Specular = 0;
this->Power = 1;
// markup display node settings
this->TextScale = 3;
this->GlyphType = vtkMRMLMarkupsDisplayNode::Sphere3D;
this->GlyphScale = 1.0; // size as percent in screen size
this->GlyphSize = 5.0; // size in world coordinate system (mm)
this->UseGlyphScale = true; // relative size by default
// projection settings
this->SliceProjection = false;
this->SliceProjectionUseFiducialColor = true;
this->SliceProjectionOutlinedBehindSlicePlane = false;
this->SliceProjectionColor[0] = 1.0;
this->SliceProjectionColor[1] = 1.0;
this->SliceProjectionColor[2] = 1.0;
this->SliceProjectionOpacity = 0.6;
this->PropertiesLabelVisibility = true;
this->PointLabelsVisibility = false;
// Set active component defaults for mouse (identified by empty string)
this->ActiveComponents[DEFAULT_CONTEXT_NAME] = ComponentInfo();
this->LineThickness = 0.2;
// Line color variables
this->LineColorFadingStart = 1.;
this->LineColorFadingEnd = 10.;
this->LineColorFadingSaturation = 1.;
this->LineColorFadingHueOffset = 0.;
// Line color node
vtkNew<vtkIntArray> events;
events->InsertNextValue(vtkCommand::ModifiedEvent);
this->AddNodeReferenceRole(this->GetLineColorNodeReferenceRole(),
this->GetLineColorNodeReferenceMRMLAttributeName(),
events.GetPointer());
}
//----------------------------------------------------------------------------
vtkMRMLMarkupsDisplayNode::~vtkMRMLMarkupsDisplayNode()
= default;
//----------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::WriteXML(ostream& of, int nIndent)
{
Superclass::WriteXML(of, nIndent);
vtkMRMLWriteXMLBeginMacro(of);
vtkMRMLWriteXMLBooleanMacro(propertiesLabelVisibility, PropertiesLabelVisibility);
vtkMRMLWriteXMLBooleanMacro(pointLabelsVisibility, PointLabelsVisibility);
vtkMRMLWriteXMLFloatMacro(textScale, TextScale);
vtkMRMLWriteXMLFloatMacro(glyphScale, GlyphScale);
vtkMRMLWriteXMLFloatMacro(glyphSize, GlyphSize);
vtkMRMLWriteXMLBooleanMacro(useGlyphScale, UseGlyphScale);
vtkMRMLWriteXMLEnumMacro(glyphType, GlyphType);
vtkMRMLWriteXMLBooleanMacro(sliceProjection, SliceProjection);
vtkMRMLWriteXMLBooleanMacro(sliceProjectionUseFiducialColor, SliceProjectionUseFiducialColor);
vtkMRMLWriteXMLBooleanMacro(sliceProjectionOutlinedBehindSlicePlane, SliceProjectionOutlinedBehindSlicePlane);
vtkMRMLWriteXMLVectorMacro(sliceProjectionColor, SliceProjectionColor, double, 3);
vtkMRMLWriteXMLFloatMacro(sliceProjectionOpacity, SliceProjectionOpacity);
vtkMRMLWriteXMLFloatMacro(lineThickness, LineThickness);
vtkMRMLWriteXMLFloatMacro(lineColorFadingStart, LineColorFadingStart);
vtkMRMLWriteXMLFloatMacro(lineColorFadingEnd, LineColorFadingEnd);
vtkMRMLWriteXMLFloatMacro(lineColorFadingSaturation, LineColorFadingSaturation);
vtkMRMLWriteXMLFloatMacro(lineColorFadingHueOffset, LineColorFadingHueOffset);
vtkMRMLWriteXMLEndMacro();
}
//----------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::ReadXMLAttributes(const char** atts)
{
int disabledModify = this->StartModify();
Superclass::ReadXMLAttributes(atts);
vtkMRMLReadXMLBeginMacro(atts);
vtkMRMLReadXMLBooleanMacro(propertiesLabelVisibility, PropertiesLabelVisibility);
vtkMRMLReadXMLBooleanMacro(pointLabelsVisibility, PointLabelsVisibility);
vtkMRMLReadXMLFloatMacro(textScale, TextScale);
vtkMRMLReadXMLFloatMacro(glyphScale, GlyphScale);
vtkMRMLReadXMLFloatMacro(glyphSize, GlyphSize);
vtkMRMLReadXMLBooleanMacro(useGlyphScale, UseGlyphScale);
vtkMRMLReadXMLEnumMacro(glyphType, GlyphType);
vtkMRMLReadXMLBooleanMacro(sliceProjection, SliceProjection);
vtkMRMLReadXMLBooleanMacro(sliceProjectionUseFiducialColor, SliceProjectionUseFiducialColor);
vtkMRMLReadXMLBooleanMacro(sliceProjectionOutlinedBehindSlicePlane, SliceProjectionOutlinedBehindSlicePlane);
vtkMRMLReadXMLVectorMacro(sliceProjectionColor, SliceProjectionColor, double, 3);
vtkMRMLReadXMLFloatMacro(sliceProjectionOpacity, SliceProjectionOpacity);
vtkMRMLReadXMLFloatMacro(lineThickness, LineThickness);
vtkMRMLReadXMLFloatMacro(lineColorFadingStart, LineColorFadingStart);
vtkMRMLReadXMLFloatMacro(lineColorFadingEnd, LineColorFadingEnd);
vtkMRMLReadXMLFloatMacro(lineColorFadingSaturation, LineColorFadingSaturation);
vtkMRMLReadXMLFloatMacro(lineColorFadingHueOffset, LineColorFadingHueOffset);
vtkMRMLReadXMLEndMacro();
// Fix up legacy markups fiducial nodes
const char* attName;
const char* attValue;
while (*atts != nullptr)
{
attName = *(atts++);
attValue = *(atts++);
// Glyph type used to be saved as an integer (not as a string enum as it is done now),
// therefore we can use it to detect legacy scenes.
if (!strcmp(attName, "glyphType"))
{
std::stringstream ss;
int val = 0;
ss << attValue;
ss >> val;
if (val > 0)
{
// Se glyph type from integer
this->SetGlyphType(val);
// Point label visibility attribute was not present in legacy scenes,
// therefore we need to set it here.
this->SetPointLabelsVisibility(true);
}
}
}
this->EndModify(disabledModify);
}
//----------------------------------------------------------------------------
// Copy the node's attributes to this object.
// Does NOT copy: ID, FilePrefix, Name, ID
void vtkMRMLMarkupsDisplayNode::Copy(vtkMRMLNode *anode)
{
int disabledModify = this->StartModify();
Superclass::Copy(anode);
vtkMRMLCopyBeginMacro(anode);
vtkMRMLCopyBooleanMacro(PropertiesLabelVisibility);
vtkMRMLCopyBooleanMacro(PointLabelsVisibility);
vtkMRMLCopyFloatMacro(TextScale);
vtkMRMLCopyFloatMacro(GlyphScale);
vtkMRMLCopyFloatMacro(GlyphSize);
vtkMRMLCopyBooleanMacro(UseGlyphScale);
vtkMRMLCopyEnumMacro(GlyphType);
vtkMRMLCopyBooleanMacro(SliceProjection);
vtkMRMLCopyBooleanMacro(SliceProjectionUseFiducialColor);
vtkMRMLCopyBooleanMacro(SliceProjectionOutlinedBehindSlicePlane);
vtkMRMLCopyVectorMacro(SliceProjectionColor, double, 3);
vtkMRMLCopyFloatMacro(SliceProjectionOpacity);
vtkMRMLCopyFloatMacro(LineThickness);
vtkMRMLCopyFloatMacro(LineColorFadingStart);
vtkMRMLCopyFloatMacro(LineColorFadingEnd);
vtkMRMLCopyFloatMacro(LineColorFadingSaturation);
vtkMRMLCopyFloatMacro(LineColorFadingHueOffset);
vtkMRMLCopyEndMacro();
this->EndModify(disabledModify);
}
//----------------------------------------------------------------------------
const char* vtkMRMLMarkupsDisplayNode::GetGlyphTypeAsString()
{
return vtkMRMLMarkupsDisplayNode::GetGlyphTypeAsString(this->GlyphType);
}
//----------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::SetGlyphTypeFromString(const char *glyphString)
{
this->SetGlyphType(vtkMRMLMarkupsDisplayNode::GetGlyphTypeFromString(glyphString));
}
//-----------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::GetGlyphTypeFromString(const char* name)
{
if (name == nullptr)
{
// invalid name
return 0;
}
for (int ii = 0; ii < GlyphType_Last; ii++)
{
if (strcmp(name, GetGlyphTypeAsString(ii)) == 0)
{
// found a matching name
return ii;
}
}
// unknown name
return GlyphTypeInvalid;
}
//---------------------------------------------------------------------------
const char* vtkMRMLMarkupsDisplayNode::GetGlyphTypeAsString(int id)
{
switch (id)
{
case Vertex2D: return "Vertex2D";
case Dash2D: return "Dash2D";
case Cross2D: return "Cross2D";
case ThickCross2D: return "ThickCross2D";
case Triangle2D: return "Triangle2D";
case Square2D: return "Square2D";
case Circle2D: return "Circle2D";
case Diamond2D: return "Diamond2D";
case Arrow2D: return "Arrow2D";
case ThickArrow2D: return "ThickArrow2D";
case HookedArrow2D: return "HookedArrow2D";
case StarBurst2D: return "StarBurst2D";
case Sphere3D: return "Sphere3D";
case Diamond3D: return "Diamond3D";
case GlyphTypeInvalid:
default:
// invalid id
return "Invalid";
}
}
//----------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::PrintSelf(ostream& os, vtkIndent indent)
{
Superclass::PrintSelf(os,indent);
vtkMRMLPrintBeginMacro(os,indent);
vtkMRMLPrintBooleanMacro(PropertiesLabelVisibility);
vtkMRMLPrintBooleanMacro(PointLabelsVisibility);
vtkMRMLPrintFloatMacro(TextScale);
vtkMRMLPrintFloatMacro(GlyphScale);
vtkMRMLPrintFloatMacro(GlyphSize);
vtkMRMLPrintBooleanMacro(UseGlyphScale);
vtkMRMLPrintEnumMacro(GlyphType);
vtkMRMLPrintBooleanMacro(SliceProjection);
vtkMRMLPrintBooleanMacro(SliceProjectionUseFiducialColor);
vtkMRMLPrintBooleanMacro(SliceProjectionOutlinedBehindSlicePlane);
vtkMRMLPrintVectorMacro(SliceProjectionColor, double, 3);
vtkMRMLPrintFloatMacro(SliceProjectionOpacity);
{
os << indent << "ActiveComponents: ";
for (std::map<std::string, ComponentInfo>::iterator it = this->ActiveComponents.begin(); it != this->ActiveComponents.end(); ++it)
{
os << it->first << ": " << it->second.Type << ", " << it->second.Index;
}
os << "\n";
}
vtkMRMLPrintFloatMacro(LineThickness);
vtkMRMLPrintFloatMacro(LineColorFadingStart);
vtkMRMLPrintFloatMacro(LineColorFadingEnd);
vtkMRMLPrintFloatMacro(LineColorFadingSaturation);
vtkMRMLPrintFloatMacro(LineColorFadingHueOffset);
vtkMRMLPrintEndMacro();
}
//---------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::ProcessMRMLEvents(vtkObject *caller,
unsigned long event,
void *callData)
{
Superclass::ProcessMRMLEvents(caller, event, callData);
return;
}
//-----------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::UpdateScene(vtkMRMLScene *scene)
{
Superclass::UpdateScene(scene);
}
//---------------------------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::GlyphTypeIs3D(int glyphType)
{
if (glyphType >= vtkMRMLMarkupsDisplayNode::Sphere3D)
{
return 1;
}
else
{
return 0;
}
}
//---------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::SetLineColorNodeID(const char *lineColorNodeID)
{
this->SetNodeReferenceID(this->GetLineColorNodeReferenceRole(), lineColorNodeID);
}
//---------------------------------------------------------------------------
const char *vtkMRMLMarkupsDisplayNode::GetLineColorNodeID()
{
return this->GetNodeReferenceID(this->GetLineColorNodeReferenceRole());
}
//---------------------------------------------------------------------------
vtkMRMLProceduralColorNode *vtkMRMLMarkupsDisplayNode::GetLineColorNode()
{
return vtkMRMLProceduralColorNode::SafeDownCast(this->GetNodeReference(this->GetLineColorNodeReferenceRole()));
}
//---------------------------------------------------------------------------
const char *vtkMRMLMarkupsDisplayNode::GetLineColorNodeReferenceRole()
{
return vtkMRMLMarkupsDisplayNode::LineColorNodeReferenceRole;
}
//----------------------------------------------------------------------------
const char *vtkMRMLMarkupsDisplayNode::GetLineColorNodeReferenceMRMLAttributeName()
{
return vtkMRMLMarkupsDisplayNode::LineColorNodeReferenceMRMLAttributeName;
}
//---------------------------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::GetActiveComponentType(std::string context/*=DEFAULT_CONTEXT_NAME*/)
{
if (this->ActiveComponents.find(context) == this->ActiveComponents.end())
{
vtkErrorMacro("GetActiveComponentType: No interaction context with identifier '" << context << "' was found");
return ComponentNone;
}
return this->ActiveComponents[context].Type;
}
//---------------------------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::GetActiveComponentIndex(std::string context/*=DEFAULT_CONTEXT_NAME*/)
{
if (this->ActiveComponents.find(context) == this->ActiveComponents.end())
{
vtkErrorMacro("GetActiveComponentIndex: No interaction context with identifier '" << context << "' was found");
return -1;
}
return this->ActiveComponents[context].Index;
}
//---------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::SetActiveComponent(int componentType, int componentIndex, std::string context/*=DEFAULT_CONTEXT_NAME*/)
{
if ( this->ActiveComponents.find(context) != this->ActiveComponents.end()
&& this->ActiveComponents[context].Type == componentType
&& this->ActiveComponents[context].Index == componentIndex )
{
// no change
return;
}
this->ActiveComponents[context].Index = componentIndex;
this->ActiveComponents[context].Type = componentType;
this->Modified();
}
//---------------------------------------------------------------------------
bool vtkMRMLMarkupsDisplayNode::HasActiveComponent()
{
for (std::map<std::string, ComponentInfo>::iterator it = this->ActiveComponents.begin(); it != this->ActiveComponents.end(); ++it)
{
if (it->second.Type != ComponentNone)
{
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
std::vector<std::string> vtkMRMLMarkupsDisplayNode::GetActiveComponentInteractionContexts()
{
std::vector<std::string> interactionContextVector;
for (std::map<std::string, ComponentInfo>::iterator it = this->ActiveComponents.begin(); it != this->ActiveComponents.end(); ++it)
{
if (it->second.Type != ComponentNone)
{
interactionContextVector.push_back(it->first);
}
}
return interactionContextVector;
}
//---------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::SetActiveControlPoint(int controlPointIndex)
{
this->SetActiveComponent(ComponentControlPoint, controlPointIndex);
}
//---------------------------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::UpdateActiveControlPointWorld(
int controlPointIndex, vtkMRMLInteractionEventData* eventData,
double orientationMatrixWorld[9], const char* viewNodeID,
const char* associatedNodeID, int positionStatus)
{
vtkMRMLMarkupsNode* markupsNode = this->GetMarkupsNode();
if (!markupsNode || !eventData)
{
return -1;
}
bool addNewControlPoint = false;
if (controlPointIndex < 0 || controlPointIndex >= markupsNode->GetNumberOfControlPoints())
{
// Determine new control point index. Now we assume that new point is added to the end,
// but in the future we may place existing points.
controlPointIndex = markupsNode->GetNumberOfControlPoints();
addNewControlPoint = true;
}
// Update active component but not yet fire modified event because the control
// point is not created/updated yet in the markups node.
//TODO: Allow other interaction contexts to place markups
bool activeComponentChanged = false;
std::string interactionContext = eventData->GetInteractionContextName();
if ( this->ActiveComponents[interactionContext].Index != controlPointIndex
|| this->ActiveComponents[interactionContext].Type != ComponentControlPoint )
{
this->ActiveComponents[interactionContext].Type = ComponentControlPoint;
this->ActiveComponents[interactionContext].Index = controlPointIndex;
activeComponentChanged = true;
}
// AddControlPoint will fire modified events anyway, so we temporarily disable events
// to add a new point with a minimum number of events.
bool wasDisabled = markupsNode->GetDisableModifiedEvent();
markupsNode->DisableModifiedEventOn();
if (positionStatus == vtkMRMLMarkupsNode::PositionPreview)
{
markupsNode->SetAttribute("Markups.MovingInSliceView", viewNodeID);
std::ostringstream controlPointIndexStr;
controlPointIndexStr << controlPointIndex;
markupsNode->SetAttribute("Markups.MovingMarkupIndex", controlPointIndexStr.str().c_str());
}
else
{
markupsNode->SetAttribute("Markups.MovingInSliceView", "");
markupsNode->SetAttribute("Markups.MovingMarkupIndex", "");
}
markupsNode->SetDisableModifiedEvent(wasDisabled);
double pointWorld[3] = { 0.0 };
eventData->GetWorldPosition(pointWorld);
if (addNewControlPoint)
{
// Add new control point
vtkMRMLMarkupsNode::ControlPoint* controlPoint = new vtkMRMLMarkupsNode::ControlPoint;
markupsNode->TransformPointFromWorld(pointWorld, controlPoint->Position);
// TODO: transform orientation to world before copying
std::copy_n(orientationMatrixWorld, 9, controlPoint->OrientationMatrix);
if (associatedNodeID)
{
controlPoint->AssociatedNodeID = associatedNodeID;
}
controlPoint->PositionStatus = positionStatus;
markupsNode->AddControlPoint(controlPoint);
}
else
{
// Update existing control point
markupsNode->SetNthControlPointPositionOrientationWorldFromArray(controlPointIndex,
pointWorld, orientationMatrixWorld, associatedNodeID, positionStatus);
}
if (activeComponentChanged)
{
this->Modified();
}
return controlPointIndex;
}
//---------------------------------------------------------------------------
void vtkMRMLMarkupsDisplayNode::GetActiveControlPoints(std::vector<int>& controlPointIndices)
{
controlPointIndices.clear();
for (std::map<std::string, ComponentInfo>::iterator it = this->ActiveComponents.begin(); it != this->ActiveComponents.end(); ++it)
{
if (it->second.Type == ComponentControlPoint)
{
controlPointIndices.push_back(it->second.Index);
}
}
}
//---------------------------------------------------------------------------
int vtkMRMLMarkupsDisplayNode::GetActiveControlPointForContext(std::string context)
{
if ( this->ActiveComponents.find(context) != this->ActiveComponents.end()
&& this->ActiveComponents[context].Type == ComponentControlPoint )
{
return this->ActiveComponents[context].Index;
}
else
{
return -1;
}
}
//---------------------------------------------------------------------------
vtkMRMLMarkupsNode* vtkMRMLMarkupsDisplayNode::GetMarkupsNode()
{
return vtkMRMLMarkupsNode::SafeDownCast(this->GetDisplayableNode());
}
/*==============================================================================
Program: 3D Slicer
Portions (c) Copyright Brigham and Women's Hospital (BWH) All Rights Reserved.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
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.
==============================================================================*/
// .NAME vtkMRMLMarkupsDisplayNode - MRML node to represent display properties for markups
// .SECTION Description
// vtkMRMLMarkupsDisplayNode nodes store display properties of markups,
// keeping elements that are applicable to all parts of the markups in this superclass
//
#ifndef __vtkMRMLMarkupsDisplayNode_h
#define __vtkMRMLMarkupsDisplayNode_h
#include "vtkSlicerMarkupsModuleMRMLExport.h"
#include "vtkMRMLDisplayNode.h"
#include "vtkMRMLMarkupsNode.h"
// STD includes
#include <map>
class vtkMRMLInteractionEventData;
class vtkMRMLProceduralColorNode;
/// \ingroup Slicer_QtModules_Markups
class VTK_SLICER_MARKUPS_MODULE_MRML_EXPORT vtkMRMLMarkupsDisplayNode : public vtkMRMLDisplayNode
{
public:
/// Name of the default context (typically the mouse)
static const std::string DEFAULT_CONTEXT_NAME;
static vtkMRMLMarkupsDisplayNode *New();
vtkTypeMacro ( vtkMRMLMarkupsDisplayNode,vtkMRMLDisplayNode );
void PrintSelf ( ostream& os, vtkIndent indent ) override;
//--------------------------------------------------------------------------
// MRMLNode methods
//--------------------------------------------------------------------------
vtkMRMLNode* CreateNodeInstance ( ) override;
/// Read node attributes from XML (MRML) file
void ReadXMLAttributes ( const char** atts ) override;
/// Write this node's information to a MRML file in XML format.
void WriteXML ( ostream& of, int indent ) override;
/// Copy the node's attributes to this object
void Copy ( vtkMRMLNode *node ) override;
/// Get node XML tag name (like Volume, Markups)
const char* GetNodeTagName() override {return "MarkupsDisplay";};
/// Finds the storage node and read the data
void UpdateScene(vtkMRMLScene *scene) override;
/// Alternative method to propagate events generated in Display nodes
void ProcessMRMLEvents ( vtkObject * /*caller*/,
unsigned long /*event*/,
void * /*callData*/ ) override;
/// Convenience function for getting the displayable markups node
vtkMRMLMarkupsNode* GetMarkupsNode();
/// Active component (that the mouse or other interaction context is hovered over).
/// This property is computed on-the-fly and saved to file.
/// \param context Name of the interaction context. By default it is empty string, meaning mouse
int GetActiveComponentType(std::string context=DEFAULT_CONTEXT_NAME);
enum ComponentType
{
ComponentNone = 0,
ComponentControlPoint,
ComponentCenterPoint,
ComponentLine
};
struct ComponentInfo
{
ComponentInfo()
{
this->Type = ComponentNone;
this->Index = -1;
}
int Type;
int Index;
};
/// Index of active component (that the mouse or other interaction context is hovered over).
/// This property is computed on-the-fly and saved to file.
/// \param context Name of the interaction context. By default it is empty string, meaning mouse
int GetActiveComponentIndex(std::string context=DEFAULT_CONTEXT_NAME);
/// Set active component type and index for interaction context (empty by default, meaning mouse)
void SetActiveComponent(int componentType, int componentIndex, std::string context=DEFAULT_CONTEXT_NAME);
/// Query if there is an active component for any interaction context
bool HasActiveComponent();
/// Get list of interaction context names that have active components
/// \return List of interaction context names that have active components
std::vector<std::string> GetActiveComponentInteractionContexts();
/// Set active component index to the provided value and component type to ComponentControlPoint.
void SetActiveControlPoint(int controlPointIndex);
/// Convenience method to perform several update operations at once, with minimum number of modified events.
/// It updates the active control point index (if controlPointIndex<0 then it creates a new point) and
/// updates its position and orientation.
/// Returns the control point index (different from the input if the input was < 0).
int UpdateActiveControlPointWorld(int controlPointIndex, vtkMRMLInteractionEventData* eventData,
double accurateWorldOrientationMatrix[9], const char* viewNodeID,
const char* associatedNodeID, int positionStatus);
/// Returns index of active control point for all interaction contexts if active component type is
/// ComponentControlPoint.
void GetActiveControlPoints(std::vector<int>& controlPointIndices);
/// Returns index of active control point for interaction context if active component type is
/// ComponentControlPoint, -1 otherwise.
/// \param context Name of the interaction context. By default it is empty string, meaning mouse
int GetActiveControlPointForContext(std::string context=DEFAULT_CONTEXT_NAME);
/// Set the text scale of the associated text.
vtkGetMacro(TextScale,double);
vtkSetMacro(TextScale,double);
//@{
/**
* Control visibility of control point labels.
*/
vtkSetMacro(PointLabelsVisibility, bool);
vtkGetMacro(PointLabelsVisibility, bool);
vtkBooleanMacro(PointLabelsVisibility, bool);
//@}
//@{
/**
* Control visibility of information box.
*/
vtkSetMacro(PropertiesLabelVisibility, bool);
vtkGetMacro(PropertiesLabelVisibility, bool);
vtkBooleanMacro(PropertiesLabelVisibility, bool);
//@}
/// Which kind of glyph should be used to display this markup?
/// Vertex2D is supposed to start at 1
enum GlyphShapes
{
GlyphTypeInvalid = 0,
Vertex2D,
Dash2D,
Cross2D,
ThickCross2D,
Triangle2D,
Square2D,
Circle2D,
Diamond2D,
Arrow2D,
ThickArrow2D,
HookedArrow2D,
StarBurst2D,
Sphere3D,
Diamond3D,
GlyphType_Last // insert new types above this line
};
/// Return the min/max glyph types, for iterating over them in tcl
static int GetMinimumGlyphType() { return 1; };
static int GetMaximumGlyphType() { return vtkMRMLMarkupsDisplayNode::GlyphType_Last-1; };
/// The glyph type used to display this fiducial
vtkSetMacro(GlyphType, int);
vtkGetMacro(GlyphType, int);
/// Returns 1 if the type is a 3d one, 0 else
int GlyphTypeIs3D(int glyphType);
int GlyphTypeIs3D() { return this->GlyphTypeIs3D(this->GlyphType); };
/// Return a string representing the glyph type, set it from a string
const char* GetGlyphTypeAsString();
void SetGlyphTypeFromString(const char *glyphString);
static const char* GetGlyphTypeAsString(int g);
static int GetGlyphTypeFromString(const char*);
/// Get/Set markup point size relative to the window size.
/// This value is only used in slice views and only if SliceUseGlyphScale is set to true.
/// Diameter of the point is defined as "scale" percentage of diagonal size of the window.
vtkSetMacro(GlyphScale,double);
vtkGetMacro(GlyphScale,double);
/// Get/Set absolute markup point size.
/// This value is used in 3D views. This value is used in slice views if SliceUseGlyphScale is set to false.
/// Diameter of the point is defined as "scale" percentage of diagonal size of the window.
vtkSetMacro(GlyphSize,double);
vtkGetMacro(GlyphSize,double);
/// This flag controls if GlyphScale relative or GlyphSize absolute size is used
/// to determine size of point glyphs.
/// On by default (GlyphScale is used for point sizing in 2D views).
/// \sa SetGlyphScale, SetGlyphSize
vtkSetMacro(UseGlyphScale, bool);
vtkGetMacro(UseGlyphScale, bool);
vtkBooleanMacro(UseGlyphScale, bool);
enum
{
ResetToDefaultsEvent = 19001, //< reset this node to the default values, request completed by markups logic
JumpToPointEvent, /**< request jump to a selected control point, request completed by markups logic,
event data is vtkMRMLInteractionEventData*/
MenuEvent, /**< display of context menu is requested (mapped to right-click by default),
event data is vtkMRMLInteractionEventData */
ActionEvent, /**< default action on the point is requested (mapped to double-click by default),
event data is vtkMRMLInteractionEventData */
};
/// Set SliceProjection flag that controls if the projection of markups
/// is visible or not in 2D viewers on slices on which it is normally
/// not visible.
/// Off by default
/// \sa SliceIntersectionVisibilty, SliceProjectionColor
vtkSetMacro(SliceProjection, bool);
vtkGetMacro(SliceProjection, bool);
vtkBooleanMacro(SliceProjection, bool);
/// Set projection color to be the same as the fiducial color
/// On by default
vtkSetMacro(SliceProjectionUseFiducialColor, bool);
vtkGetMacro(SliceProjectionUseFiducialColor, bool);
vtkBooleanMacro(SliceProjectionUseFiducialColor, bool);
/// Set projection's view different if under/over/in the plane
/// Off by default
vtkSetMacro(SliceProjectionOutlinedBehindSlicePlane, bool);
vtkGetMacro(SliceProjectionOutlinedBehindSlicePlane, bool);
vtkBooleanMacro(SliceProjectionOutlinedBehindSlicePlane, bool);
/// Set color of the projection on the 2D viewers
/// White (1.0, 1.0, 1.0) by default.
vtkSetVector3Macro(SliceProjectionColor, double);
vtkGetVector3Macro(SliceProjectionColor, double);
/// Set opacity of projection on the 2D viewers
/// 0.6 by default
vtkSetClampMacro(SliceProjectionOpacity, double, 0.0, 1.0);
vtkGetMacro(SliceProjectionOpacity, double);
/// Configures line thickness.
/// Thickness is specified relative to markup point size
/// (1.0 means line diameter is the same as diameter of point glyphs).
vtkGetMacro(LineThickness, double);
vtkSetMacro(LineThickness, double);
/// Configures the line color fading appearance
/// Default value = 1.0
vtkGetMacro (LineColorFadingStart, double);
vtkSetMacro (LineColorFadingStart, double);
/// Configures the line color fading appearance
/// Default value = 10.0
vtkGetMacro (LineColorFadingEnd, double);
vtkSetMacro (LineColorFadingEnd, double);
/// Configures the line color fading appearance
/// Default value = 1.0
vtkSetClampMacro (LineColorFadingSaturation, double, 0.0, 1.0);
vtkGetMacro (LineColorFadingSaturation, double);
/// Configures the line color fading appearance
/// Default value = 0.0
vtkSetClampMacro (LineColorFadingHueOffset, double, 0.0, 1.0);
vtkGetMacro (LineColorFadingHueOffset, double);
/// Set the line color node ID used for the projection on the line actors on the 2D viewers.
/// Setting a line color node allows to define any arbitrary color mapping.
/// Setting a line color node will overwrite the settings given by the
/// color, opacity and LineColorFading variables of the displayNode.
virtual void SetLineColorNodeID(const char *lineColorNodeID);
/// Get the line color node ID used for the projection on the line actors on the 2D viewers.
const char* GetLineColorNodeID();
/// Get the line color node used for the projection on the line actors on the 2D viewers.
vtkMRMLProceduralColorNode* GetLineColorNode();
virtual const char* GetLineColorNodeReferenceRole();
protected:
vtkMRMLMarkupsDisplayNode();
~vtkMRMLMarkupsDisplayNode() override;
vtkMRMLMarkupsDisplayNode( const vtkMRMLMarkupsDisplayNode& );
void operator= ( const vtkMRMLMarkupsDisplayNode& );
/// Current active point or widget component type and index (hovered by the mouse or other interaction context)
/// Map interaction context identifier (empty string for mouse) to component type enum
std::map<std::string, ComponentInfo> ActiveComponents;
bool PropertiesLabelVisibility;
bool PointLabelsVisibility;
double TextScale;
int GlyphType;
double GlyphScale;
double GlyphSize;
bool UseGlyphScale;
bool SliceProjection;
bool SliceProjectionUseFiducialColor;
bool SliceProjectionOutlinedBehindSlicePlane;
double SliceProjectionColor[3];
double SliceProjectionOpacity;
virtual const char* GetLineColorNodeReferenceMRMLAttributeName();
static const char* LineColorNodeReferenceRole;
static const char* LineColorNodeReferenceMRMLAttributeName;
double LineThickness;
double LineColorFadingStart;
double LineColorFadingEnd;
double LineColorFadingSaturation;
double LineColorFadingHueOffset;
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment