Skip to content

Commit bb0430d

Browse files
Merge pull request #152 from BrendanParmer/v3.4
v3.4
2 parents 997540f + e18c01a commit bb0430d

File tree

12 files changed

+96
-26
lines changed

12 files changed

+96
-26
lines changed

NodeToPython/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "Node to Python",
33
"description": "Convert Blender node groups to a Python add-on!",
44
"author": "Brendan Parmer",
5-
"version": (3, 3, 2),
5+
"version": (3, 4, 0),
66
"blender": (3, 0, 0),
77
"location": "Node",
88
"category": "Node",

NodeToPython/blender_manifest.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
schema_version = "1.0.0"
22

33
id = "node_to_python"
4-
version = "3.3.2"
4+
version = "3.4.0"
55
name = "Node To Python"
66
tagline = "Turn node groups into Python code"
77
maintainer = "Brendan Parmer <[email protected]>"
@@ -12,7 +12,7 @@ website = "https://github.com/BrendanParmer/NodeToPython"
1212
tags = ["Development", "Compositing", "Geometry Nodes", "Material", "Node"]
1313

1414
blender_version_min = "4.2.0"
15-
blender_version_max = "4.4.0"
15+
blender_version_max = "4.5.0"
1616

1717
license = [
1818
"SPDX:MIT",

NodeToPython/compositor/operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class NTPCompositorOperator(NTP_Operator):
2626
name="Is Scene",
2727
description="Blender stores compositing node trees differently for scenes and in groups")
2828

29-
def __init__(self):
30-
super().__init__()
29+
def __init__(self, *args, **kwargs):
30+
super().__init__(*args, **kwargs)
3131
self._node_infos = node_settings
3232
for name in COMP_OP_RESERVED_NAMES:
3333
self._used_vars[name] = 0

NodeToPython/compositor/ui.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ class NTPCompositorPanel(Panel):
1111
bl_context = ''
1212
bl_category = "NodeToPython"
1313

14+
def __init__(self, *args, **kwargs):
15+
super().__init__(*args, **kwargs)
16+
1417
@classmethod
1518
def poll(cls, context):
1619
return True

NodeToPython/geometry/operator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ class NTPGeoNodesOperator(NTP_Operator):
2323

2424
geo_nodes_group_name: bpy.props.StringProperty(name="Node Group")
2525

26-
def __init__(self):
27-
super().__init__()
26+
def __init__(self, *args, **kwargs):
27+
super().__init__(*args, **kwargs)
28+
2829
self._node_infos = node_settings
2930
for name in GEO_OP_RESERVED_NAMES:
3031
self._used_vars[name] = 0

NodeToPython/geometry/ui.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class NTPGeoNodesPanel(Panel):
1212
bl_context = ''
1313
bl_category = "NodeToPython"
1414

15+
def __init__(self, *args, **kwargs):
16+
super().__init__(*args, **kwargs)
17+
1518
@classmethod
1619
def poll(cls, context):
1720
return True

NodeToPython/node_settings.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ST(Enum):
3333
SIM_OUTPUT_ITEMS = auto()
3434
IMAGE = auto()
3535
IMAGE_USER = auto()
36+
COLLECTION = auto()
3637
CRYPTOMATTE_ENTRIES = auto()
3738
FILE_SLOTS = auto()
3839
FONT = auto()
@@ -51,12 +52,12 @@ class NTPNodeSetting(NamedTuple):
5152
name_: str
5253
st_: ST
5354
min_version_: tuple = (3, 0, 0)
54-
max_version_: tuple = (4, 4, 0)
55+
max_version_: tuple = (4, 5, 0)
5556

5657
class NodeInfo(NamedTuple):
5758
attributes_: list[NTPNodeSetting]
5859
min_version_: tuple = (3, 0, 0)
59-
max_version_: tuple = (4, 4, 0)
60+
max_version_: tuple = (4, 5, 0)
6061

6162
node_settings : dict[str, NodeInfo] = {
6263
'CompositorNodeAlphaOver' : NodeInfo(
@@ -378,6 +379,7 @@ class NodeInfo(NamedTuple):
378379
'CompositorNodeDenoise' : NodeInfo(
379380
[
380381
NTPNodeSetting("prefilter", ST.ENUM),
382+
NTPNodeSetting("quality", ST.ENUM, min_version_=(4, 4, 0)),
381383
NTPNodeSetting("use_hdr", ST.BOOL),
382384
]
383385
),
@@ -882,6 +884,7 @@ class NodeInfo(NamedTuple):
882884
NTPNodeSetting("center_x", ST.FLOAT, max_version_=(4, 2, 0)),
883885
NTPNodeSetting("center_y", ST.FLOAT, max_version_=(4, 2, 0)),
884886
NTPNodeSetting("tile_order", ST.ENUM, max_version_=(4, 2, 0)),
887+
NTPNodeSetting("ui_shortcut", ST.INT, min_version_=(4, 4, 0)),
885888
NTPNodeSetting("use_alpha", ST.BOOL),
886889
]
887890
),
@@ -965,6 +968,11 @@ class NodeInfo(NamedTuple):
965968
min_version_ = (4, 0, 0)
966969
),
967970

971+
'FunctionNodeFindInString' : NodeInfo(
972+
[],
973+
min_version_ = (4, 4, 0)
974+
),
975+
968976
'FunctionNodeFloatToInt' : NodeInfo(
969977
[
970978
NTPNodeSetting("rounding_mode", ST.ENUM),
@@ -1581,6 +1589,13 @@ class NodeInfo(NamedTuple):
15811589
min_version_ = (4, 1, 0)
15821590
),
15831591

1592+
'GeometryNodeInputCollection' : NodeInfo(
1593+
[
1594+
NTPNodeSetting("collection", ST.COLLECTION),
1595+
],
1596+
min_version_ = (4, 4, 0)
1597+
),
1598+
15841599
'GeometryNodeInputCurveHandlePositions' : NodeInfo(
15851600
[]
15861601
),
@@ -1682,7 +1697,16 @@ class NodeInfo(NamedTuple):
16821697
),
16831698

16841699
'GeometryNodeInputNormal' : NodeInfo(
1685-
[]
1700+
[
1701+
NTPNodeSetting("legacy_corner_normals", ST.BOOL, min_version_=(4, 4, 0)),
1702+
]
1703+
),
1704+
1705+
'GeometryNodeInputObject' : NodeInfo(
1706+
[
1707+
NTPNodeSetting("object", ST.OBJECT),
1708+
],
1709+
min_version_ = (4, 4, 0)
16861710
),
16871711

16881712
'GeometryNodeInputPosition' : NodeInfo(
@@ -2282,6 +2306,7 @@ class NodeInfo(NamedTuple):
22822306

22832307
'GeometryNodeResampleCurve' : NodeInfo(
22842308
[
2309+
NTPNodeSetting("keep_last_segment", ST.BOOL, min_version_=(4, 4, 0)),
22852310
NTPNodeSetting("mode", ST.ENUM),
22862311
]
22872312
),

NodeToPython/ntp_operator.py

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class NTP_Operator(Operator):
6464
bpy.types.NodeTreeInterfaceSocketTexture
6565
}
6666

67-
def __init__(self):
68-
super().__init__()
67+
def __init__(self, *args, **kwargs):
68+
super().__init__(*args, **kwargs)
6969

7070
# Write functions after nodes are mostly initialized and linked up
7171
self._write_after_links: list[Callable] = []
@@ -229,6 +229,9 @@ def _init_operator(self, idname: str, label: str) -> None:
229229
"""
230230
self._idname = idname
231231
self._write(f"class {self._class_name}(bpy.types.Operator):", 0)
232+
self._write("def __init__(self, *args, **kwargs):", 1)
233+
self._write("super().__init__(*args, **kwargs)\n", 2)
234+
232235
self._write(f"bl_idname = \"node.{idname}\"", 1)
233236
self._write(f"bl_label = {str_to_py_str(label)}", 1)
234237
self._write("bl_options = {\'REGISTER\', \'UNDO\'}\n", 1)
@@ -408,26 +411,27 @@ def _set_settings_defaults(self, node: Node) -> None:
408411
elif st == ST.COLOR:
409412
self._write(f"{setting_str} = {color_to_py_str(attr)}")
410413
elif st == ST.MATERIAL:
411-
name = str_to_py_str(attr.name)
412-
self._write(f"if {name} in bpy.data.materials:")
413-
self._write(f"{setting_str} = bpy.data.materials[{name}]",
414-
self._inner_indent_level + 1)
414+
self._set_if_in_blend_file(attr, setting_str, "materials")
415415
elif st == ST.OBJECT:
416-
name = str_to_py_str(attr.name)
417-
self._write(f"if {name} in bpy.data.objects:")
418-
self._write(f"{setting_str} = bpy.data.objects[{name}]",
419-
self._inner_indent_level + 1)
416+
self._set_if_in_blend_file(attr, setting_str, "objects")
417+
elif st == ST.COLLECTION:
418+
self._set_if_in_blend_file(attr, setting_str, "collections")
420419
elif st == ST.COLOR_RAMP:
421420
self._color_ramp_settings(node, attr_name)
422421
elif st == ST.CURVE_MAPPING:
423422
self._curve_mapping_settings(node, attr_name)
424423
elif st == ST.NODE_TREE:
425424
self._node_tree_settings(node, attr_name)
426425
elif st == ST.IMAGE:
427-
if self._addon_dir is not None and attr is not None:
426+
if attr is None:
427+
continue
428+
if self._addon_dir is not None:
428429
if attr.source in {'FILE', 'GENERATED', 'TILED'}:
429430
if self._save_image(attr):
430431
self._load_image(attr, f"{node_var}.{attr_name}")
432+
else:
433+
self._set_if_in_blend_file(attr, setting_str, "images")
434+
431435
elif st == ST.IMAGE_USER:
432436
self._image_user_settings(attr, f"{node_var}.{attr_name}")
433437
elif st == ST.SIM_OUTPUT_ITEMS:
@@ -755,6 +759,7 @@ def _process_items(self, parent: NodeTreeInterfacePanel,
755759
processed items, so none are done twice
756760
ntp_nt (NTP_NodeTree): owner of the socket
757761
"""
762+
758763
if parent is None:
759764
items = ntp_nt.node_tree.interface.items_tree
760765
else:
@@ -774,6 +779,14 @@ def _process_items(self, parent: NodeTreeInterfacePanel,
774779
elif item.item_type == 'PANEL':
775780
self._create_panel(item, panel_dict, items_processed,
776781
parent, ntp_nt)
782+
if bpy.app.version >= (4, 4, 0) and parent is not None:
783+
nt_var = self._node_tree_vars[ntp_nt.node_tree]
784+
interface_var = f"{nt_var}.interface"
785+
panel_var = panel_dict[item]
786+
parent_var = panel_dict[parent]
787+
self._write(f"{interface_var}.move_to_parent("
788+
f"{panel_var}, {parent_var}, {item.index})")
789+
777790

778791
def _tree_interface_settings(self, ntp_nt: NTP_NodeTree) -> None:
779792
"""
@@ -837,9 +850,12 @@ def _set_input_defaults(self, node: Node) -> None:
837850
# images
838851
elif input.bl_idname == 'NodeSocketImage':
839852
img = input.default_value
840-
if img is not None and self._addon_dir != None: # write in a better way
841-
if self._save_image(img):
842-
self._load_image(img, f"{socket_var}.default_value")
853+
if img is not None:
854+
if self._addon_dir != None: # write in a better way
855+
if self._save_image(img):
856+
self._load_image(img, f"{socket_var}.default_value")
857+
else:
858+
self._in_file_inputs(input, socket_var, "images")
843859
default_val = None
844860

845861
# materials
@@ -921,6 +937,16 @@ def _set_socket_defaults(self, node: Node):
921937
self._set_input_defaults(node)
922938
self._set_output_defaults(node)
923939

940+
def _set_if_in_blend_file(self, attr, setting_str: str, data_type: str
941+
) -> None:
942+
"""
943+
Attempts to grab referenced thing from blend file
944+
"""
945+
name = str_to_py_str(attr.name)
946+
self._write(f"if {name} in bpy.data.{data_type}:")
947+
self._write(f"{setting_str} = bpy.data.{data_type}[{name}]",
948+
self._inner_indent_level + 1)
949+
924950
def _color_ramp_settings(self, node: Node, color_ramp_name: str) -> None:
925951
"""
926952
Replicate a color ramp node

NodeToPython/options.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ class NTPOptions(bpy.types.PropertyGroup):
44
"""
55
Property group used during conversion of node group to python
66
"""
7+
8+
def __init__(self, *args, **kwargs):
9+
super().__init__(*args, **kwargs)
10+
711
# General properties
812
mode: bpy.props.EnumProperty(
913
name = "Mode",
@@ -170,6 +174,9 @@ class NTPOptionsPanel(bpy.types.Panel):
170174
bl_context = ''
171175
bl_category = "NodeToPython"
172176

177+
def __init__(self, *args, **kwargs):
178+
super().__init__(*args, **kwargs)
179+
173180
@classmethod
174181
def poll(cls, context):
175182
return True

NodeToPython/shader/operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class NTPShaderOperator(NTP_Operator):
2121
#TODO: add option for general shader node groups
2222
material_name: bpy.props.StringProperty(name="Node Group")
2323

24-
def __init__(self):
25-
super().__init__()
24+
def __init__(self, *args, **kwargs):
25+
super().__init__(*args, **kwargs)
2626
self._node_infos = node_settings
2727
for name in SHADER_OP_RESERVED_NAMES:
2828
self._used_vars[name] = 0

NodeToPython/shader/ui.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ class NTPShaderPanel(Panel):
1111
bl_context = ''
1212
bl_category = "NodeToPython"
1313

14+
def __init__(self, *args, **kwargs):
15+
super().__init__(*args, **kwargs)
16+
1417
@classmethod
1518
def poll(cls, context):
1619
return True

tools/node_settings_generator/types_utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class ST(Enum):
3939
IMAGE_USER = auto() #needs refactor
4040

4141
# Currently unimplemented
42+
COLLECTION = auto()
4243
CRYPTOMATTE_ENTRIES = auto()
4344
FILE_SLOTS = auto()
4445
FONT = auto()
@@ -78,6 +79,7 @@ class ST(Enum):
7879
"" : "",
7980
"bpy_prop_collection of CryptomatteEntry": ST.CRYPTOMATTE_ENTRIES,
8081
"boolean" : ST.BOOL,
82+
"Collection" : ST.COLLECTION,
8183
"ColorMapping" : None, # Always read-only
8284
"ColorRamp" : ST.COLOR_RAMP,
8385
"CompositorNodeOutputFileFileSlots" : ST.FILE_SLOTS,

0 commit comments

Comments
 (0)