Skip to content

Commit 824aea9

Browse files
Merge pull request #92 from BrendanParmer/Blender-4-1
Blender 4 1
2 parents f9a2ca0 + 41fba00 commit 824aea9

File tree

8 files changed

+149
-21
lines changed

8 files changed

+149
-21
lines changed

__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, 0, 1),
5+
"version": (3, 1, 0),
66
"blender": (3, 0, 0),
77
"location": "Node",
88
"category": "Node",

compositor/node_settings.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,19 @@
261261
],
262262

263263
'CompositorNodeKuwahara' : [
264-
NTPNodeSetting("eccentricity", ST.FLOAT, min_version = (4, 0, 0)),
265-
NTPNodeSetting("sharpness", ST.FLOAT, min_version = (4, 0, 0)),
266-
NTPNodeSetting("size", ST.INT, min_version = (4, 0, 0)),
267-
NTPNodeSetting("uniformity", ST.INT, min_version = (4, 0, 0)),
268-
NTPNodeSetting("variation", ST.ENUM, min_version = (4, 0, 0))
264+
NTPNodeSetting("eccentricity", ST.FLOAT, min_version = (4, 0, 0)),
265+
NTPNodeSetting("sharpness", ST.FLOAT, min_version = (4, 0, 0)),
266+
NTPNodeSetting("size", ST.INT, min_version = (4, 0, 0),
267+
max_version = (4, 1, 0)),
268+
NTPNodeSetting("uniformity", ST.INT, min_version = (4, 0, 0)),
269+
NTPNodeSetting("variation", ST.ENUM, min_version = (4, 0, 0)),
270+
NTPNodeSetting("use_high_precision", ST.BOOL, min_version = (4, 1, 0))
269271
],
270272

271-
'CompositorNodePixelate' : [],
273+
'CompositorNodePixelate' : [
274+
NTPNodeSetting("pixel_size", ST.INT, min_version = (4, 1, 0))
275+
],
276+
272277
'CompositorNodePosterize' : [],
273278

274279
'CompositorNodeSunBeams' : [
@@ -324,7 +329,7 @@
324329
NTPNodeSetting("distance", ST.FLOAT),
325330
NTPNodeSetting("iterations", ST.INT),
326331
NTPNodeSetting("spin", ST.FLOAT),
327-
NTPNodeSetting("use_wrap", ST.BOOL, max_version = (3, 4, 0)),
332+
NTPNodeSetting("use_wrap", ST.BOOL, max_version = (3, 5, 0)),
328333
NTPNodeSetting("zoom", ST.FLOAT)
329334
],
330335

@@ -571,6 +576,10 @@
571576

572577
'CompositorNodeNormalize' : [],
573578

579+
'CompositorNodeSplit' : [
580+
NTPNodeSetting("axis", ST.ENUM, min_version=(4, 1, 0)),
581+
NTPNodeSetting("factor", ST.INT, min_version=(4, 1, 0))
582+
],
574583

575584
'CompositorNodeSwitch' : [
576585
NTPNodeSetting("check", ST.BOOL)

compositor/operator.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,27 @@ def _initialize_compositor_node_tree(self, ntp_nt, nt_name):
7878
f"name = {str_to_py_str(nt_name)})"))
7979
self._write("")
8080

81+
# Compositor node tree settings
82+
#TODO: might be good to make this optional
83+
enum_settings = ["chunk_size", "edit_quality", "execution_mode",
84+
"precision", "render_quality"]
85+
for enum in enum_settings:
86+
if not hasattr(ntp_nt.node_tree, enum):
87+
continue
88+
setting = getattr(ntp_nt.node_tree, enum)
89+
if setting is not None and setting is not "":
90+
py_str = enum_to_py_str(setting)
91+
self._write(f"{ntp_nt.var}.{enum} = {py_str}")
92+
93+
bool_settings = ["use_groupnode_buffer", "use_opencl", "use_two_pass",
94+
"use_viewer_border"]
95+
for bool_setting in bool_settings:
96+
if not hasattr(ntp_nt.node_tree, bool_setting):
97+
continue
98+
if getattr(ntp_nt.node_tree, bool_setting) is True:
99+
self._write(f"{ntp_nt.var}.{bool_setting} = True")
100+
101+
81102
def _set_color_balance_settings(self, node: CompositorNodeColorBalance
82103
) -> None:
83104
"""

geometry/node_settings.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
# Input > Scene
7272
'GeometryNodeTool3DCursor' : [],
7373

74+
'GeometryNodeInputActiveCamera' : [],
75+
7476
'GeometryNodeCollectionInfo' : [
7577
NTPNodeSetting("transform_space", ST.ENUM)
7678
],
@@ -138,6 +140,10 @@
138140
'GeometryNodeToolSetSelection' : [],
139141

140142
# Geometry > Operations
143+
'GeometryNodeBake' : [
144+
NTPNodeSetting("bake_items", ST.BAKE_ITEMS, min_version = (4, 1, 0))
145+
],
146+
141147
'GeometryNodeBoundBox' : [],
142148
'GeometryNodeConvexHull' : [],
143149

@@ -154,6 +160,10 @@
154160
NTPNodeSetting("mode", ST.ENUM, min_version = (3, 1, 0))
155161
],
156162

163+
'GeometryNodeSortElements' : [
164+
NTPNodeSetting("domain", ST.ENUM, min_version = (4, 1, 0))
165+
],
166+
157167
'GeometryNodeTransform' : [],
158168
'GeometryNodeSeparateComponents' : [],
159169

@@ -279,7 +289,7 @@
279289

280290
'GeometryNodeRealizeInstances' : [
281291
NTPNodeSetting("legacy_behavior", ST.BOOL, min_version = (3, 1, 0),
282-
max_version = (3, 6, 0))
292+
max_version = (4, 0, 0))
283293
],
284294

285295
'GeometryNodeRotateInstances' : [],
@@ -472,12 +482,14 @@
472482
],
473483

474484
'ShaderNodeTexMusgrave' : [
475-
NTPNodeSetting("musgrave_dimensions", ST.ENUM),
476-
NTPNodeSetting("musgrave_type", ST.ENUM)
485+
NTPNodeSetting("musgrave_dimensions", ST.ENUM, max_version = (4, 1, 0)),
486+
NTPNodeSetting("musgrave_type", ST.ENUM, max_version = (4, 1, 0))
477487
],
478488

479489
'ShaderNodeTexNoise' : [
480-
NTPNodeSetting("noise_dimensions", ST.ENUM)
490+
NTPNodeSetting("noise_dimensions", ST.ENUM),
491+
NTPNodeSetting("noise_type", ST.ENUM, min_version=(4, 1, 0)),
492+
NTPNodeSetting("normalize", ST.BOOL, min_version=(4, 0, 0)),
481493
],
482494

483495
'ShaderNodeTexVoronoi' : [
@@ -499,6 +511,16 @@
499511

500512

501513
# UTILITIES
514+
'GeometryNodeIndexSwitch' : [
515+
NTPNodeSetting("data_type", ST.ENUM, min_version = (4, 1, 0)),
516+
NTPNodeSetting("index_switch_items", ST.INDEX_SWITCH_ITEMS, min_version = (4, 1, 0))
517+
],
518+
519+
'GeometryNodeMenuSwitch' : [
520+
NTPNodeSetting("data_type", ST.ENUM, min_version = (4, 1, 0)),
521+
NTPNodeSetting("enum_definition", ST.ENUM_DEFINITION, min_version = (4, 1, 0))
522+
],
523+
502524
'ShaderNodeMix' : [
503525
NTPNodeSetting("blend_type", ST.ENUM, min_version = (3, 4, 0)),
504526
NTPNodeSetting("clamp_factor", ST.BOOL, min_version = (3, 4, 0)),
@@ -610,7 +632,7 @@
610632
],
611633

612634
'FunctionNodeCompareFloats' : [
613-
NTPNodeSetting("operation", ST.ENUM, max_version = (3, 0, 0))
635+
NTPNodeSetting("operation", ST.ENUM, max_version = (3, 2, 0))
614636
],
615637

616638
'ShaderNodeFloatCurve' : [
@@ -641,7 +663,11 @@
641663
'FunctionNodeAxisAngleToRotation' : [],
642664
'FunctionNodeEulerToRotation' : [],
643665
'FunctionNodeInvertRotation' : [],
644-
666+
667+
'FunctionNodeRotateRotation' : [
668+
NTPNodeSetting("rotation_space", ST.ENUM, min_version = (4, 1, 0))
669+
],
670+
645671
'FunctionNodeRotateEuler' : [
646672
NTPNodeSetting("space", ST.ENUM),
647673
NTPNodeSetting("type", ST.ENUM)

geometry/operator.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,16 @@ def _set_geo_tree_properties(self, node_tree: GeometryNodeTree) -> None:
139139
if is_tool:
140140
self._write(f"{nt_var}.is_tool = True")
141141

142-
tool_flags = ["is_mode_edit",
142+
tool_flags = ["is_mode_object",
143+
"is_mode_edit",
143144
"is_mode_sculpt",
144145
"is_type_curve",
145146
"is_type_mesh",
146147
"is_type_point_cloud"]
147148

148149
for flag in tool_flags:
149-
self._write(f"{nt_var}.{flag} = {getattr(node_tree, flag)}")
150+
if hasattr(node_tree, flag) is True:
151+
self._write(f"{nt_var}.{flag} = {getattr(node_tree, flag)}")
150152
self._write("")
151153

152154
def _process_node_tree(self, node_tree: GeometryNodeTree) -> None:

material/node_settings.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,14 @@
194194
],
195195

196196
'ShaderNodeTexMusgrave' : [
197-
NTPNodeSetting("musgrave_dimensions", ST.ENUM),
198-
NTPNodeSetting("musgrave_type", ST.ENUM)
197+
NTPNodeSetting("musgrave_dimensions", ST.ENUM, max_version = (4, 1, 0)),
198+
NTPNodeSetting("musgrave_type", ST.ENUM, max_version = (4, 1, 0))
199199
],
200200

201201
'ShaderNodeTexNoise' : [
202202
NTPNodeSetting("noise_dimensions", ST.ENUM),
203-
NTPNodeSetting("normalize", ST.BOOL, min_version = (4, 0, 0))
203+
NTPNodeSetting("noise_type", ST.ENUM, min_version=(4, 1, 0)),
204+
NTPNodeSetting("normalize", ST.BOOL, min_version=(4, 0, 0)),
204205
],
205206

206207
'ShaderNodeTexPointDensity' : [

ntp_operator.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ def _set_settings_defaults(self, node: Node) -> None:
294294

295295
if not hasattr(node, attr_name):
296296
if (bpy.app.version >= setting.min_version and
297-
bpy.app.version <= setting.max_version):
297+
bpy.app.version < setting.max_version):
298298
self.report({'WARNING'},
299299
f"NodeToPython: Couldn't find attribute "
300300
f"\"{attr_name}\" for node {node.name} of type "
@@ -345,6 +345,12 @@ def _set_settings_defaults(self, node: Node) -> None:
345345
self._load_image(attr, f"{node_var}.{attr_name}")
346346
elif st == ST.IMAGE_USER:
347347
self._image_user_settings(attr, f"{node_var}.{attr_name}")
348+
elif st == ST.INDEX_SWITCH_ITEMS:
349+
self._index_switch_items(attr, f"{node_var}.{attr_name}")
350+
elif st == ST.ENUM_DEFINITION:
351+
self._enum_definition(attr, f"{node_var}.{attr_name}")
352+
elif st == ST.BAKE_ITEMS:
353+
self._bake_items(attr, f"{node_var}.{attr_name}")
348354

349355
if bpy.app.version < (4, 0, 0):
350356
def _set_group_socket_defaults(self, socket_interface: NodeSocketInterface,
@@ -703,6 +709,10 @@ def _set_input_defaults(self, node: Node) -> None:
703709
elif input.bl_idname == 'NodeSocketString':
704710
default_val = str_to_py_str(input.default_value)
705711

712+
#menu
713+
elif input.bl_idname == 'NodeSocketMenu':
714+
default_val = enum_to_py_str(input.default_value)
715+
706716
# images
707717
elif input.bl_idname == 'NodeSocketImage':
708718
img = input.default_value
@@ -1043,6 +1053,61 @@ def _image_user_settings(self, img_user: bpy.types.ImageUser,
10431053
self._write(f"{img_user_var}.{img_usr_attr} = "
10441054
f"{getattr(img_user, img_usr_attr)}")
10451055

1056+
if bpy.app.version >= (4, 1, 0):
1057+
def _index_switch_items(self, switch_items: bpy.types.NodeIndexSwitchItems,
1058+
items_str: str) -> None:
1059+
"""
1060+
Set the proper amount of index switch items
1061+
1062+
Parameters:
1063+
switch_items (bpy.types.NodeIndexSwitchItems): switch items to copy
1064+
items_str (str): string for the generated switch items attribute
1065+
"""
1066+
num_items = len(switch_items)
1067+
self._write(f"{items_str}.clear()")
1068+
for i in range(num_items):
1069+
self._write(f"{items_str}.new()")
1070+
1071+
def _enum_definition(self, enum_def: bpy.types.NodeEnumDefinition,
1072+
enum_def_str: str) -> None:
1073+
"""
1074+
Set enum definition item for a node
1075+
1076+
Parameters:
1077+
enum_def (bpy.types.NodeEnumDefinition): enum definition to replicate
1078+
enum_def_str (str): string for the generated enum definition
1079+
"""
1080+
self._write(f"{enum_def_str}.enum_items.clear()")
1081+
for i, enum_item in enumerate(enum_def.enum_items):
1082+
name = str_to_py_str(enum_item.name)
1083+
self._write(f"{enum_def_str}.enum_items.new({name})")
1084+
if enum_item.description != "":
1085+
self._write(f"{enum_def_str}.enum_items[{i}].description = "
1086+
f"{str_to_py_str(enum_item.description)}")
1087+
1088+
def _bake_items(self, bake_items: bpy.types.NodeGeometryBakeItems,
1089+
bake_items_str: str) -> None:
1090+
"""
1091+
Set bake items for a node
1092+
1093+
Parameters:
1094+
bake_items (bpy.types.NodeGeometryBakeItems): bake items to replicate
1095+
bake_items_str (str): string for the generated bake items
1096+
"""
1097+
self._write(f"{bake_items_str}.clear()")
1098+
for i, bake_item in enumerate(bake_items):
1099+
socket_type = enum_to_py_str(bake_item.socket_type)
1100+
name = str_to_py_str(bake_item.name)
1101+
self._write(f"{bake_items_str}.new({socket_type}, {name})")
1102+
1103+
ad = enum_to_py_str(bake_item.attribute_domain)
1104+
self._write(f"{bake_items_str}[{i}].attribute_domain = {ad}")
1105+
1106+
if bake_item.is_attribute:
1107+
self._write(f"{bake_items_str}[{i}].is_attribute = True")
1108+
1109+
1110+
10461111
def _set_parents(self, node_tree: NodeTree) -> None:
10471112
"""
10481113
Sets parents for all nodes, mostly used to put nodes in frames

utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class ST(Enum):
2929
CURVE_MAPPING = auto()
3030
NODE_TREE = auto()
3131

32+
ENUM_DEFINITION = auto()
33+
INDEX_SWITCH_ITEMS = auto()
34+
BAKE_ITEMS = auto()
35+
3236
# Asset Library
3337
MATERIAL = auto() # Handle with asset library
3438
OBJECT = auto() # Handle with asset library
@@ -53,7 +57,7 @@ class NTPNodeSetting(NamedTuple):
5357
name: str
5458
st: ST
5559
min_version: tuple = (3, 0, 0)
56-
max_version: tuple = (4, 1, 0)
60+
max_version: tuple = (4, 2, 0) #first version where a setting is invalid
5761

5862

5963
def clean_string(string: str, lower: bool = True) -> str:

0 commit comments

Comments
 (0)