2025-12-01

This commit is contained in:
2026-03-17 14:58:51 -06:00
parent 183e865f8b
commit 4b82b57113
6846 changed files with 954887 additions and 162606 deletions
+88 -29
View File
@@ -304,6 +304,11 @@ def get_search_props():
if not hasattr(wm, "blenderkit_nodegroup"):
return
props = wm.blenderkit_nodegroup
if uiprops.asset_type == "ADDON":
if not hasattr(wm, "blenderkit_addon"):
return
props = wm.blenderkit_addon
return props
@@ -357,6 +362,8 @@ def get_active_asset():
return get_active_brush()
elif ui_props.asset_type == "NODEGROUP":
return get_active_nodegroup()
elif ui_props.asset_type == "ADDON":
return None # Addons don't have an active asset concept
return None
@@ -394,6 +401,8 @@ def get_upload_props():
b = get_active_nodegroup()
if b is not None:
return b.blenderkit
elif ui_props.asset_type == "ADDON":
return None # Addons don't have upload props
return None
@@ -449,7 +458,7 @@ def get_preferences_as_dict():
# GUI
"show_on_start": user_preferences.show_on_start,
"thumb_size": user_preferences.thumb_size,
"max_assetbar_rows": user_preferences.max_assetbar_rows,
"maximized_assetbar_rows": user_preferences.maximized_assetbar_rows,
"search_field_width": user_preferences.search_field_width,
"search_in_header": user_preferences.search_in_header,
"tips_on_start": user_preferences.tips_on_start,
@@ -500,7 +509,7 @@ def get_preferences() -> datas.Prefs:
# GUI
show_on_start=user_preferences.show_on_start, # type: ignore[union-attr]
thumb_size=user_preferences.thumb_size, # type: ignore[union-attr]
max_assetbar_rows=user_preferences.max_assetbar_rows, # type: ignore[union-attr]
maximized_assetbar_rows=user_preferences.maximized_assetbar_rows, # type: ignore[union-attr]
search_field_width=user_preferences.search_field_width, # type: ignore[union-attr]
search_in_header=user_preferences.search_in_header, # type: ignore[union-attr]
tips_on_start=user_preferences.tips_on_start, # type: ignore[union-attr]
@@ -530,8 +539,8 @@ def save_prefs_without_save_userpref(user_preferences, context):
def save_prefs(user_preferences, context, **kwargs):
# first check context, so we don't do this on registration or blender startup
if bpy.app.background is True:
# first check context, so we don't do this on registration, blender startup, or blender factory startup
if bpy.app.background is True or bpy.app.factory_startup is True:
return
global_vars.PREFS = get_preferences_as_dict()
@@ -647,10 +656,11 @@ def img_to_preview(img, copy_original=False):
def get_hidden_image(
tpath, bdata_name, force_reload: bool = False, colorspace: str = ""
):
"""Get hidden image by name. If not found, load it from tpath."""
if bdata_name[0] == ".":
hidden_name = bdata_name
else:
hidden_name = ".%s" % bdata_name
hidden_name = f".{bdata_name}"
img = bpy.data.images.get(hidden_name) # type: ignore[union-attr]
if tpath.startswith("//"):
@@ -687,14 +697,14 @@ def get_hidden_image(
def get_thumbnail(name):
"""Get addon thumbnail image by name."""
p = paths.get_addon_thumbnail_path(name)
name = ".%s" % name
name = f".{name}"
img = bpy.data.images.get(name)
if img == None:
if img is None:
img = bpy.data.images.load(p, check_existing=True)
image_utils.set_colorspace(img)
img.name = name
img.name = name
return img
@@ -836,6 +846,7 @@ def get_bounds_snappable(obs, use_modifiers=False):
obcount = 0 # calculates the mesh obs. Good for non-mesh objects
matrix_parent = parent.matrix_world
depsgraph = bpy.context.evaluated_depsgraph_get()
for ob in obs:
# bb=ob.bound_box
mw = ob.matrix_world
@@ -846,7 +857,6 @@ def get_bounds_snappable(obs, use_modifiers=False):
if ob.type == "MESH" or ob.type == "CURVE":
# If to_mesh() works we can use it on curves and any other ob type almost.
# disabled to_mesh for 2.8 by now, not wanting to use dependency graph yet.
depsgraph = bpy.context.evaluated_depsgraph_get()
object_eval = ob.evaluated_get(depsgraph)
if ob.type == "CURVE":
@@ -873,6 +883,36 @@ def get_bounds_snappable(obs, use_modifiers=False):
# bpy.data.meshes.remove(mesh)
if ob.type == "CURVE":
object_eval.to_mesh_clear()
elif ob.type == "VOLUME":
# Ensure evaluated bound box (so grids/sequences are loaded)
object_eval = ob.evaluated_get(depsgraph)
bb = object_eval.bound_box
obcount += 1
for c in bb:
coord = c
parent_coord = (
matrix_parent.inverted()
@ mw
@ Vector((coord[0], coord[1], coord[2]))
)
minx = min(minx, parent_coord.x)
miny = min(miny, parent_coord.y)
minz = min(minz, parent_coord.z)
maxx = max(maxx, parent_coord.x)
maxy = max(maxy, parent_coord.y)
maxz = max(maxz, parent_coord.z)
elif ob.type in ["LIGHT", "CAMERA"]:
# From these we only need center point for bounds
coord = ob.location
parent_coord = (
matrix_parent.inverted() @ mw @ Vector((coord[0], coord[1], coord[2]))
)
minx = min(minx, parent_coord.x)
miny = min(miny, parent_coord.y)
minz = min(minz, parent_coord.z)
maxx = max(maxx, parent_coord.x)
maxy = max(maxy, parent_coord.y)
maxz = max(maxz, parent_coord.z)
if obcount == 0:
minx, miny, minz, maxx, maxy, maxz = 0, 0, 0, 0, 0, 0
@@ -1062,9 +1102,7 @@ def name_update(props, context=None):
Checks for name change, because it decides if whole asset has to be re-uploaded. Name is stored in the blend file
and that's the reason.
"""
scene = bpy.context.scene
ui_props = bpy.context.window_manager.blenderkitUI
# props = get_upload_props()
if props.name_old != props.name:
props.name_changed = True
@@ -1074,16 +1112,23 @@ def name_update(props, context=None):
if nname.isupper():
nname = nname.lower()
nname = nname[0].upper() + nname[1:]
props.name = nname
if nname != "":
nname = nname[0].upper() + nname[1:]
props.name = (
nname # this recursively triggers the name_update() again, so we return
)
return
# here we need to fix the name for blender data = ' or " give problems in path evaluation down the road.
fname = props.name
fname = fname.replace("'", "")
fname = fname.replace('"', "")
asset = get_active_asset()
if ui_props.asset_type != "HDR":
# Here we actually rename assets datablocks, but don't do that with HDR's and possibly with others
asset.name = fname
if ui_props.asset_type == "HDR" or fname == "":
bk_logger.info(f"Skiping the rename")
return # don't rename HDR's or with empty name
else:
asset = get_active_asset()
if asset.name != fname: # Here we actually rename assets datablocks
asset.name = fname # change name of active object to upload Name
def fmt_dimensions(p):
@@ -1189,6 +1234,9 @@ def user_is_owner(asset_data: Optional[dict] = None) -> bool:
def asset_from_newer_blender_version(asset_data, blender_version=None):
"""Check if asset is from a newer blender version, to avoid incompatibility. Give info if difference is in major, minor or patch version."""
# addons don't have a blender version, so we return False
if asset_data["assetType"] == "addon":
return False, ""
asset_ver = asset_data["sourceAppVersion"].split(".")
if blender_version is None:
blender_version = bpy.app.version
@@ -1231,27 +1279,38 @@ def guard_from_crash():
def get_largest_area(context=None, area_type="VIEW_3D"):
"""Get the largest area of the given type."""
maxsurf = 0
maxa = None
maxw = None
region = None
if context is None:
windows = bpy.data.window_managers[0].windows
if bpy.context.window is not None:
windows = [bpy.context.window]
else:
windows = bpy.data.window_managers.windows
else:
windows = context.window_manager.windows
for w in windows:
for a in w.screen.areas:
if a.type == area_type:
asurf = a.width * a.height
if asurf > maxsurf:
maxa = a
maxw = w
maxsurf = asurf
if bpy.context.area is not None and bpy.context.area.type == area_type:
maxa = bpy.context.area
maxw = bpy.context.window
maxsurf = maxa.width * maxa.height
region = maxa.regions[-1]
else:
areas = w.screen.areas
for a in w.screen.areas:
if a.type == area_type:
asurf = a.width * a.height
if asurf > maxsurf:
maxa = a
maxw = w
maxsurf = asurf
region = a.regions[-1]
# for r in a.regions:
# if r.type == 'WINDOW':
# region = r
region = a.regions[-1]
# for r in a.regions:
# if r.type == 'WINDOW':
# region = r
if maxw is None or maxa is None:
return None, None, None