Program Listing for File vtkSlicerLayerDMLogic.h

Return to documentation for file (Logic/vtkSlicerLayerDMLogic.h)

#pragma once

#include "vtkSlicerLayerDMModuleLogicExport.h"

// Slicer includes
#include <vtkMRMLDisplayableNode.h>
#include <vtkMRMLScene.h>
#include <vtkSlicerModuleLogic.h>

class vtkMRMLLayerDMWidgetEventTranslationNode;

class VTK_SLICER_LAYERDM_MODULE_LOGIC_EXPORT vtkSlicerLayerDMLogic : public vtkSlicerModuleLogic
{
public:
  static vtkSlicerLayerDMLogic* New();
  vtkTypeMacro(vtkSlicerLayerDMLogic, vtkSlicerModuleLogic);

  vtkSlicerLayerDMLogic(const vtkSlicerLayerDMLogic&) = delete;
  void operator=(const vtkSlicerLayerDMLogic&) = delete;

  void RegisterNodes() override;

  static int GetVersionMajor();
  static int GetVersionMinor();
  static int GetVersionPatch();
  static std::string GetVersion();

  static void SetWidgetEventTranslationNode(vtkMRMLNode* node, vtkMRMLLayerDMWidgetEventTranslationNode* translationNode);

  static vtkMRMLLayerDMWidgetEventTranslationNode* GetWidgetEventTranslationNode(vtkMRMLNode* node);

  static vtkMRMLLayerDMWidgetEventTranslationNode* GetWidgetEventTranslationSingleton(vtkMRMLScene* scene, const std::string& singletonId);

  static vtkMRMLLayerDMWidgetEventTranslationNode* GetWidgetEventTranslationSingleton(vtkMRMLScene* scene,
                                                                                      const std::string& singletonId,
                                                                                      const std::function<void(vtkMRMLLayerDMWidgetEventTranslationNode*)>& configureF);

  static vtkMRMLLayerDMWidgetEventTranslationNode* CreateWidgetEventTranslationSingleton(vtkMRMLScene* scene, const std::string& singletonId);

  static void CreateDefaultEventTranslation(vtkMRMLNode* node, const std::string& singletonId, const std::function<void(vtkMRMLLayerDMWidgetEventTranslationNode*)>& configureF);

  static std::string GetEventTranslationRole();

  static std::string GetDisplayRole();

  template <typename T>
  static void RegisterNodeIfNeeded(vtkMRMLScene* scene);

  template <typename T>
  static T* GetDisplayNode(vtkMRMLNode* node);

  template <typename T>
  static T* GetReferenceNode(vtkMRMLNode* node, const char* role);

  template <typename T>
  static T* GetReferenceNode(vtkMRMLNode* node);

  template <typename T>
  static std::vector<T*> GetReferenceNodes(vtkMRMLNode* node, const char* role);

  template <typename T>
  static std::vector<T*> GetReferenceNodes(vtkMRMLNode* node);

  template <typename T>
  static T* CreateDisplayNode(vtkMRMLNode* node, bool allowMultiple = false);

  template <typename T>
  static T* CreateReferenceNode(vtkMRMLNode* node, const char* role, bool allowMultiple = false);

  template <typename T>
  static T* CreateReferenceNode(vtkMRMLNode* node, bool allowMultiple = false);

  template <typename T>
  static T* AddReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role);

  template <typename T>
  static T* SetReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role);

  template <typename T>
  static T* SetNthReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role, int nthRef);

protected:
  vtkSlicerLayerDMLogic() = default;
  ~vtkSlicerLayerDMLogic() override = default;

private:
  template <typename T>
  static T* ModifyNodeReference(vtkMRMLNode* node, vtkMRMLNode* nodeRef, const std::function<void()>& modifyF)
  {
    if (!node || !nodeRef)
    {
      return nullptr;
    }

    modifyF();
    return T::SafeDownCast(nodeRef);
  }

  static constexpr auto EventTranslationRole{ "widgetEventTranslation" };
  static constexpr auto DisplayRole{ "display" }; // copied from vtkMRMLDisplayableNode
};

//----------------------------------------------------------------------------
template <typename T>
void vtkSlicerLayerDMLogic::RegisterNodeIfNeeded(vtkMRMLScene* scene)
{
  if (!scene)
  {
    return;
  }

  vtkNew<T> node;
  if (!scene->IsNodeClassRegistered(node.Get()->GetClassName()))
  {
    scene->RegisterNodeClass(node.Get());
  }
}

template <typename T>
T* vtkSlicerLayerDMLogic::GetDisplayNode(vtkMRMLNode* node)
{
  if (!node)
  {
    return {};
  }

  return GetReferenceNode<T>(node, DisplayRole);
}

template <typename T>
T* vtkSlicerLayerDMLogic::GetReferenceNode(vtkMRMLNode* node, const char* role)
{
  const auto referenceNodes = GetReferenceNodes<T>(node, role);
  return referenceNodes.empty() ? nullptr : referenceNodes[0];
}

template <typename T>
T* vtkSlicerLayerDMLogic::GetReferenceNode(vtkMRMLNode* node)
{
  return GetReferenceNode<T>(node, T::GetReferenceRole());
}

template <typename T>
std::vector<T*> vtkSlicerLayerDMLogic::GetReferenceNodes(vtkMRMLNode* node, const char* role)
{
  if (!node)
  {
    return {};
  }

  std::vector<T*> referenceNodes;
  for (int i_node = 0; i_node < node->GetNumberOfNodeReferences(role); i_node++)
  {
    if (auto refNode = T::SafeDownCast(node->GetNthNodeReference(role, i_node)))
    {
      referenceNodes.emplace_back(refNode);
    }
  }
  return referenceNodes;
}

template <typename T>
std::vector<T*> vtkSlicerLayerDMLogic::GetReferenceNodes(vtkMRMLNode* node)
{
  return GetReferenceNodes<T>(node, T::GetReferenceRole());
}

template <typename T>
T* vtkSlicerLayerDMLogic::CreateDisplayNode(vtkMRMLNode* node, bool allowMultiple)
{
  if (!node)
  {
    return {};
  }

  return CreateReferenceNode<T>(node, DisplayRole, allowMultiple);
}

template <typename T>
T* vtkSlicerLayerDMLogic::CreateReferenceNode(vtkMRMLNode* node, const char* role, bool allowMultiple)
{
  auto scene = node ? node->GetScene() : nullptr;
  if (!node || !scene)
  {
    return {};
  }

  auto nodeRef = GetReferenceNode<T>(node, role);
  if (nodeRef && !allowMultiple)
  {
    return nodeRef;
  }

  nodeRef = T::SafeDownCast(scene->AddNewNodeByClass(vtkSmartPointer<T>::New()->GetClassName()));
  return AddReferenceNode<T>(node, nodeRef, role);
}

template <typename T>
T* vtkSlicerLayerDMLogic::CreateReferenceNode(vtkMRMLNode* node, bool allowMultiple)
{
  return CreateReferenceNode<T>(node, T::GetReferenceRole(), allowMultiple);
}

template <typename T>
T* vtkSlicerLayerDMLogic::AddReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role)
{
  return ModifyNodeReference<T>(node, nodeRef, [=] { node->AddAndObserveNodeReferenceID(role, nodeRef->GetID()); });
}

template <typename T>
T* vtkSlicerLayerDMLogic::SetReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role)
{
  return ModifyNodeReference<T>(node, nodeRef, [=] { node->SetAndObserveNodeReferenceID(role, nodeRef->GetID()); });
}

template <typename T>
T* vtkSlicerLayerDMLogic::SetNthReferenceNode(vtkMRMLNode* node, T* nodeRef, const char* role, int nthRef)
{
  return ModifyNodeReference<T>(node, nodeRef, [=] { node->SetAndObserveNthNodeReferenceID(role, nthRef, nodeRef->GetID()); });
}