-
Notifications
You must be signed in to change notification settings - Fork 235
/
Copy path__init__.py
148 lines (119 loc) · 4.6 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import os
import importlib
import inspect
from typing import Union
import bpy
from sverchok.utils.sv_oldnodes_parser import get_old_node_bl_idnames
from sverchok.utils.sv_logging import sv_logger
from sverchok.utils.handle_blender_data import BlTrees
class LazyDist:
def __init__(self):
self.__data: dict = None
@property
def _data(self):
if self.__data is None:
self.__data = get_old_node_bl_idnames(path=os.path.dirname(__file__))
return self.__data
def __contains__(self, item):
return item in self._data
def __getitem__(self, item):
return self._data[item]
def __iter__(self):
return iter(self._data)
imported_mods = {}
old_bl_idnames = LazyDist() # to save some time during initialization
def is_old(node_info: Union[str, bpy.types.Node]):
"""
Check if node or node.bl_idname is among
the old nodes
"""
if isinstance(node_info, str):
# assumes bl_idname
return node_info in old_bl_idnames
elif isinstance(node_info, bpy.types.Node):
return node_info.bl_idname in old_bl_idnames
raise TypeError(f"String or Node is expected, {node_info} is given")
def mark_old(node, text="Deprecated node!"):
"""Create a frame node around given one with deprecated label"""
if node.parent and node.parent.label == text:
return
ng = node.id_data
frame = ng.nodes.new("NodeFrame")
if node.parent:
frame.parent = node.parent
node.parent = frame
frame.label = text
frame.use_custom_color = True
frame.color = (.8, 0, 0)
frame.shrink = True
def mark_all():
"""Add frames with deprecated label to all deprecated nodes if necessary"""
for node in (n for t in BlTrees().sv_trees for n in t.nodes):
if node.bl_idname in old_bl_idnames:
mark_old(node)
def has_old_nodes(tree) -> bool:
"""Recursive search of deprecated nodes"""
for n in tree.nodes:
if n.bl_idname in old_bl_idnames:
return True
elif hasattr(n, 'node_tree') and has_old_nodes(n.node_tree):
return True
return False
# mark group nodes if they have deprecated nodes inside
for node in (n for t in BlTrees().sv_main_trees for n in t.nodes):
if not hasattr(node, 'node_tree'):
continue
if has_old_nodes(node.node_tree):
mark_old(node, text="Has deprecated nodes!")
def register_old(bl_id):
"""Register old node class"""
if bl_id in old_bl_idnames:
mod = importlib.import_module(".{}".format(old_bl_idnames[bl_id]), __name__)
res = inspect.getmembers(mod)
for name, cls in res:
if inspect.isclass(cls):
if issubclass(cls, bpy.types.Node) and cls.bl_idname == bl_id:
if bl_id not in imported_mods:
mod.register()
imported_mods[bl_id] = mod
else:
raise LookupError(f"Cannot find {bl_id} among old nodes")
def register_all():
"""Register all old node classes"""
for bl_id in old_bl_idnames:
try:
register_old(bl_id)
except Exception as e:
# when a code of an old node is copied to old folder
# it can be copied with other classes (property groups)
# which does not change it version to MK2, so we have the error
sv_logger.error(e)
def register():
import sverchok
# This part is called upon scrip.reload (F8), because old nodes will be unregistered again
# There is no way to say which old node classes should be registered without registering them all
if sverchok.reload_event:
register_all()
def unregister():
for mod in imported_mods.values():
try:
mod.unregister()
except Exception as e:
sv_logger.error(e)