diff --git a/README.md b/README.md
index 4198f0f..1a4f323 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,15 @@
# Blender-BakeLab2

BakeLab - A blender addon for baking images.
-Compatible with Blender 2.81 or higher.
-For blender version 2.79 go to [here](https://github.com/Shahzod114/Bakelab-Blender-addon)
+Compatible with Blender 4.0.0/5.0.0 or higher.
+For Blender version 2.79, go to [here](https://github.com/Shahzod114/Bakelab-Blender-addon)
Main Features:
-* Automatically create images, setup materials, bake objects and save/pack images in one click;
+* Automatically create images, setup materials, bake objects, and save/pack images in one click;
* Automatically generating materials;
* Anti-Aliased baking;
* Baking cycles displacement to real geometry;
-* Bake any PBR attributes of your material by its name (Metallic, Roughness, Specular and etc);
+* Bake any PBR attributes of your material by its name (Metallic, Roughness, Specular etc.);
* Adaptive image size by object's surface size;
* Unwrap and Bake Multiple Objects into one image;
diff --git a/__init__.py b/__init__.py
index 3b8ceab..89d343a 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,22 +1,9 @@
-# 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 3 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
-# MERCHANTIBILITY 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, see .
-
bl_info = {
"name" : "BakeLab",
"author" : "Shahzod Boyxonov (specoolar@gmail.com)",
"description" : "Bake textures easily",
- "blender" : (2, 81, 0),
- "version" : (2, 0, 1),
+ "blender" : (4, 0, 0),
+ "version" : (2, 0, 2),
"location" : "View3D > Properties > BakeLab",
"category" : "Baking"
}
@@ -40,8 +27,8 @@
import bpy
from bpy.types import (
- Operator,
- PropertyGroup,
+ Operator,
+ PropertyGroup,
Panel
)
from bpy.props import (
@@ -61,10 +48,6 @@ def updateAdaptiveImageMinSize(self, context):
def updateAdaptiveImageMaxSize(self, context):
self.image_max_size = max(self.image_min_size, self.image_max_size)
-def updateSavePath(self, context):
- if bpy.data.is_saved:
- self.save_path = bpy.path.abspath(self.save_path)
-
class BakeLabProperties(PropertyGroup):
bake_state: EnumProperty(
items = (
@@ -122,7 +105,7 @@ class BakeLabProperties(PropertyGroup):
update=updateAdaptiveImageMinSize
)
round_adaptive_image : BoolProperty(
- name = 'Round to power of two',
+ name = 'Round to power of two',
default = True
)
anti_alias : IntProperty(
@@ -162,7 +145,7 @@ class BakeLabProperties(PropertyGroup):
name="Create folder",
description="Automatically creates a folder named after the object(s)",
default = True
- )
+ )
folder_name : StringProperty(
name = 'Folder name',
description = 'Name of the folder',
@@ -172,12 +155,11 @@ class BakeLabProperties(PropertyGroup):
default=expanduser("~"),
name="Folder",
subtype="DIR_PATH",
- update=updateSavePath
)
show_bake_settings : BoolProperty(name = '', default = False)
show_map_settings : BoolProperty(name = '', default = False)
show_file_settings : BoolProperty(name = '', default = False)
-
+
apply_only_selected : BoolProperty(
name = 'Apply only to Selected',
description = 'Apply only to selected objects',
@@ -188,7 +170,6 @@ class BakeLabProperties(PropertyGroup):
description = 'Make data single user',
default = True
)
- # Display
baking_obj_count : IntProperty(
name = 'Baking object count',
default = 0
@@ -224,7 +205,7 @@ class BakeLabProperties(PropertyGroup):
classes = (
BakeLabProperties,
-
+
bakelab_bake.Baker,
bakelab_uv.Unwrapper,
bakelab_uv.ClearUV,
@@ -246,7 +227,7 @@ class BakeLabProperties(PropertyGroup):
def register():
for cls in classes:
bpy.utils.register_class(cls)
-
+
bpy.types.Scene.BakeLabProps = PointerProperty(type = BakeLabProperties)
bpy.types.Scene.BakeLabMaps = CollectionProperty(type = bakelab_map.BakeLabMap)
bpy.types.Scene.BakeLab_Data = CollectionProperty(type = bakelab_baked_data.BakeLab_BakedData)
@@ -255,11 +236,11 @@ def register():
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
-
+
del bpy.types.Scene.BakeLabProps
del bpy.types.Scene.BakeLabMaps
del bpy.types.Scene.BakeLab_Data
del bpy.types.Scene.BakeLabMapIndex
if __name__ == "__main__":
- register()
+ register()
\ No newline at end of file
diff --git a/bakelab_bake.py b/bakelab_bake.py
index 88cd478..96c5eea 100644
--- a/bakelab_bake.py
+++ b/bakelab_bake.py
@@ -211,7 +211,94 @@ def copy_node(self, dst_nodes, node):
if dst_input is not None:
if hasattr(src_input, 'default_value') and \
hasattr(dst_input, 'default_value'):
- dst_input.default_value = src_input.default_value
+
+ try:
+ src_val = src_input.default_value
+ dst_val = dst_input.default_value
+
+ print(
+ "COPY:",
+ node.name,
+ src_input.name,
+ src_val,
+ "->",
+ dst_input.name,
+ dst_val
+ )
+
+ if "Vector" in dst_input.bl_idname:
+ try:
+ value = tuple(src_val[:3])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ if hasattr(dst_input.default_value, "__len__"):
+ dst_len = len(dst_input.default_value)
+
+ if hasattr(src_val, "__len__"):
+ if len(src_val) > dst_len:
+ try:
+ value = src_val[:dst_len]
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ elif len(src_val) < dst_len:
+ try:
+ value = tuple(src_val) + tuple([0.0] * (dst_len - len(src_val)))
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ print(
+ "DEBUG:",
+ dst_input.name,
+ dst_input.bl_idname,
+ src_val
+ )
+ else:
+ try:
+ value = src_val
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = src_val
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = src_val
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ except:
+ pass
+
+ except Exception as e:
+ print(
+ "FAILED:",
+ node.name,
+ src_input.name,
+ src_val,
+ "->",
+ dst_input.name,
+ e
+ )
return new_node
def find_node(self, nodes, type):
@@ -251,18 +338,233 @@ def extract_nodes_rc(
from_node = link.from_node
if from_node == gr_in:
- ng_input = self.get_socket(n_group.inputs, link.from_socket.identifier)
+ ng_input = self.get_socket(
+ n_group.inputs,
+ link.from_socket.identifier
+ )
+
if ng_input is None:
continue
- dst_input.default_value = ng_input.default_value
- for ng_link in ng_input.links:
- links.new(ng_link.from_socket, dst_input)
+
+ src_val = ng_input.default_value
+
+ try:
+ dst_val = dst_input.default_value
+
+ if hasattr(dst_val, "__len__") and not isinstance(dst_val, str):
+ try:
+ dst_len = len(dst_val)
+ except:
+ dst_len = 1
+
+ if "Vector" in dst_input.bl_idname:
+ dst_len = 3
+
+ elif "Color" in dst_input.bl_idname:
+ dst_len = 4
+
+ print(
+ "SRC:", src_input.name,
+ "DST:", dst_input.name,
+ "SRC_LEN:", len(src_val) if hasattr(src_val, "__len__") else 1,
+ "DST_LEN:", dst_len,
+ "DST_SOCKET:", dst_input.bl_idname
+ )
+
+ if hasattr(src_val, "__len__"):
+ src_len = len(src_val)
+
+ if "Vector" in dst_input.bl_idname:
+ tmp = list(src_val[:3])
+ while len(tmp) < 3:
+ tmp.append(0.0)
+ print(
+ "SOCKET:",
+ dst_input.name,
+ dst_input.bl_idname,
+ "LEN:",
+ len(tmp) if 'tmp' in locals() else 'scalar'
+ )
+ try:
+ value = tuple(tmp[:dst_len])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ elif "Color" in dst_input.bl_idname:
+ tmp = list(src_val[:4])
+
+ while len(tmp) < 4:
+ tmp.append(1.0)
+
+ print(
+ "SOCKET:",
+ dst_input.name,
+ "TYPE:",
+ dst_input.bl_idname,
+ "DST_LEN:",
+ dst_len,
+ "VALUE_LEN:",
+ len(tmp)
+ )
+
+ try:
+ value = tuple(tmp[:4])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ elif src_len > dst_len:
+ if "Vector" in dst_input.bl_idname:
+ try:
+ value = tuple(src_val[:3])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ elif dst_input.bl_idname == "NodeSocketColor":
+ tmp = list(src_val[:4])
+ while len(tmp) < 4:
+ tmp.append(1.0)
+ try:
+ value = tuple(tmp[:4])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = tuple(src_val[:dst_len])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ elif src_len < dst_len:
+ tmp = list(src_val)
+ tmp.extend([src_val[-1]] * (dst_len - src_len))
+ print(
+ "SOCKET:",
+ dst_input.name,
+ dst_input.bl_idname,
+ "LEN:",
+ len(tmp) if 'tmp' in locals() else 'scalar'
+ )
+ try:
+ value = tuple(tmp[:dst_len])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ else:
+ if "Vector" in dst_input.bl_idname:
+ try:
+ value = tuple(src_val[:3])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ elif dst_input.bl_idname == "NodeSocketColor":
+ tmp = list(src_val[:4])
+ while len(tmp) < 4:
+ tmp.append(1.0)
+ print(
+ "SOCKET:",
+ dst_input.name,
+ dst_input.bl_idname,
+ "LEN:",
+ len(tmp) if 'tmp' in locals() else 'scalar'
+ )
+ try:
+ value = tuple(tmp[:dst_len])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ else:
+ if "Vector" in dst_input.bl_idname:
+ try:
+ value = tuple(src_val[:3])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ elif dst_input.bl_idname == "NodeSocketColor":
+ tmp = list(src_val[:4])
+ while len(tmp) < 4:
+ tmp.append(1.0)
+ try:
+ value = tuple(tmp[:4])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = tuple(src_val[:dst_len])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = tuple([src_val] * dst_len)
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ if hasattr(src_val, "__len__"):
+ try:
+ value = float(src_val[0])
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+ else:
+ try:
+ value = float(src_val)
+ print("ASSIGN:", dst_input.name, dst_input.bl_idname, value)
+ dst_input.default_value = value
+ except Exception as e:
+ print("FAILED:", dst_input.name, dst_input.bl_idname, value, e)
+ raise
+
+ except Exception as e:
+ print("ERROR SOCKET:", dst_input.name)
+ print("ERROR TYPE:", dst_input.bl_idname)
+ print("ERROR VALUE:", src_val)
+ print("ERROR:", e)
+
+ raise
+
else:
link_node = self.extract_nodes_rc(
from_node, gr_in, gr_out,
nodes, links, n_group, node_dict)
+
if link_node is not None:
- link_output = self.get_socket(link_node.outputs, link.from_socket.identifier)
+ link_output = self.get_socket(
+ link_node.outputs,
+ link.from_socket.identifier)
+
if link_output is not None:
links.new(link_output, dst_input)
### }
diff --git a/bakelab_baked_data.py b/bakelab_baked_data.py
index 78b8473..c10d8a5 100644
--- a/bakelab_baked_data.py
+++ b/bakelab_baked_data.py
@@ -20,9 +20,10 @@ class BakeObjData(PropertyGroup):
type=bpy.types.Object
)
class BakeMapData(PropertyGroup):
- bake_map : PointerProperty(
- type=bakelab_map.BakeLabMap
- )
+ map_type : StringProperty()
+ pass_name : StringProperty()
+ normal_space : StringProperty()
+
image : PointerProperty(
type=bpy.types.Image
)
@@ -42,8 +43,7 @@ def AddObj(self, obj):
def AddMap(self, bake_map, image):
item = self.map_list.add()
- item.bake_map.type = bake_map.type
- item.bake_map.pass_name = bake_map.pass_name
- item.bake_map.normal_space = bake_map.normal_space
-
+ item.map_type = bake_map.type
+ item.pass_name = bake_map.pass_name
+ item.normal_space = bake_map.normal_space
item.image = image