2025-12-01
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user