1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkViewNodeFactory.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkViewNodeFactory.h"
16 #include "vtkObjectFactory.h"
17 #include "vtkViewNode.h"
18 
19 #include <map>
20 #include <string>
21 
22 //============================================================================
23 class vtkViewNodeFactory::vtkInternals
24 {
25 public:
26   std::map<std::string, vtkViewNode* (*)()> Overrides;
27 
28   vtkInternals() = default;
29 
~vtkInternals()30   ~vtkInternals() { this->Overrides.clear(); }
31 };
32 
33 //============================================================================
34 vtkStandardNewMacro(vtkViewNodeFactory);
35 
36 //------------------------------------------------------------------------------
vtkViewNodeFactory()37 vtkViewNodeFactory::vtkViewNodeFactory()
38 {
39   this->Internals = new vtkInternals;
40 }
41 
42 //------------------------------------------------------------------------------
~vtkViewNodeFactory()43 vtkViewNodeFactory::~vtkViewNodeFactory()
44 {
45   delete this->Internals;
46 }
47 
48 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)49 void vtkViewNodeFactory::PrintSelf(ostream& os, vtkIndent indent)
50 {
51   this->Superclass::PrintSelf(os, indent);
52 }
53 
54 //------------------------------------------------------------------------------
CreateNode(vtkObject * who)55 vtkViewNode* vtkViewNodeFactory::CreateNode(vtkObject* who)
56 {
57   if (!who)
58   {
59     return nullptr;
60   }
61 
62   vtkViewNode* (*func)() = nullptr;
63 
64   // First, check if there is an exact match for override functions for this
65   // object type.
66   {
67     auto fnOverrideIt = this->Internals->Overrides.find(who->GetClassName());
68     if (fnOverrideIt != this->Internals->Overrides.end())
69     {
70       func = fnOverrideIt->second;
71     }
72   }
73 
74   // Next, check if there is an indirect match (one of the parents of this
75   // object type has an override). If there is more than one override for
76   // types in this object's hierarchy, choose the most derived one.
77   if (func == nullptr)
78   {
79     vtkIdType closest = VTK_ID_MAX;
80     for (auto it = this->Internals->Overrides.begin(); it != this->Internals->Overrides.end(); ++it)
81     {
82       vtkIdType numberOfGenerations = who->GetNumberOfGenerationsFromBase(it->first.c_str());
83       if (numberOfGenerations >= 0 && numberOfGenerations < closest)
84       {
85         closest = numberOfGenerations;
86         func = it->second;
87       }
88     }
89   }
90 
91   // If neither are available, do not create a node for this object.
92   if (func == nullptr)
93   {
94     return nullptr;
95   }
96 
97   // Otherwise, create a node and initialize it.
98   vtkViewNode* vn = func();
99   vn->SetMyFactory(this);
100   if (vn)
101   {
102     vn->SetRenderable(who);
103   }
104 
105   return vn;
106 }
107 
108 //------------------------------------------------------------------------------
RegisterOverride(const char * name,vtkViewNode * (* func)())109 void vtkViewNodeFactory::RegisterOverride(const char* name, vtkViewNode* (*func)())
110 {
111   this->Internals->Overrides[name] = func;
112 }
113