BlenderKit: replace asset command, present in right-click menu.
This commit is contained in:
parent
1760af58fc
commit
a1b29d179a
|
@ -19,7 +19,7 @@
|
|||
bl_info = {
|
||||
"name": "BlenderKit Asset Library",
|
||||
"author": "Vilem Duha, Petr Dlouhy",
|
||||
"version": (1, 0, 27),
|
||||
"version": (1, 0, 28),
|
||||
"blender": (2, 80, 0),
|
||||
"location": "View3D > Properties > BlenderKit",
|
||||
"description": "Online BlenderKit library (materials, models, brushes and more)",
|
||||
|
|
|
@ -21,8 +21,9 @@ if "bpy" in locals():
|
|||
from importlib import reload
|
||||
|
||||
utils = reload(utils)
|
||||
ui = reload(ui)
|
||||
else:
|
||||
from blenderkit import utils
|
||||
from blenderkit import utils, ui
|
||||
|
||||
import bpy
|
||||
import uuid
|
||||
|
@ -84,7 +85,7 @@ def append_scene(file_name, scenename=None, link=False, fake_user=False):
|
|||
return scene
|
||||
|
||||
|
||||
def link_group(file_name, obnames=[], location=(0, 0, 0), link=False, **kwargs):
|
||||
def link_group(file_name, obnames=[], location=(0, 0, 0), link=False, parent = None, **kwargs):
|
||||
'''link an instanced group - model type asset'''
|
||||
sel = utils.selection_get()
|
||||
|
||||
|
@ -95,14 +96,17 @@ def link_group(file_name, obnames=[], location=(0, 0, 0), link=False, **kwargs):
|
|||
if col == kwargs['name']:
|
||||
data_to.collections = [col]
|
||||
|
||||
rotation = (0,0,0)
|
||||
rotation = (0, 0, 0)
|
||||
if kwargs.get('rotation') is not None:
|
||||
rotation = kwargs['rotation']
|
||||
|
||||
|
||||
bpy.ops.object.empty_add(type='PLAIN_AXES', location=location, rotation = rotation)
|
||||
bpy.ops.object.empty_add(type='PLAIN_AXES', location=location, rotation=rotation)
|
||||
main_object = bpy.context.view_layer.objects.active
|
||||
main_object.instance_type = 'COLLECTION'
|
||||
|
||||
main_object.parent = parent
|
||||
main_object.matrix_world.translation = location
|
||||
|
||||
for col in bpy.data.collections:
|
||||
if col.library is not None:
|
||||
fp = bpy.path.abspath(col.library.filepath)
|
||||
|
@ -111,6 +115,7 @@ def link_group(file_name, obnames=[], location=(0, 0, 0), link=False, **kwargs):
|
|||
main_object.instance_collection = col
|
||||
break;
|
||||
|
||||
main_object.name = main_object.instance_collection.name
|
||||
|
||||
# bpy.ops.wm.link(directory=file_name + "/Collection/", filename=kwargs['name'], link=link, instance_collections=True,
|
||||
# autoselect=True)
|
||||
|
@ -176,6 +181,7 @@ def append_particle_system(file_name, obnames=[], location=(0, 0, 0), link=False
|
|||
|
||||
def append_objects(file_name, obnames=[], location=(0, 0, 0), link=False, **kwargs):
|
||||
'''append objects into scene individually'''
|
||||
|
||||
with bpy.data.libraries.load(file_name, link=link, relative=True) as (data_from, data_to):
|
||||
sobs = []
|
||||
for ob in data_from.objects:
|
||||
|
@ -207,7 +213,6 @@ def append_objects(file_name, obnames=[], location=(0, 0, 0), link=False, **kwar
|
|||
hidden_objects.append(obj)
|
||||
obj.hide_viewport = False
|
||||
return_obs.append(obj)
|
||||
|
||||
# Only after all objects are in scene! Otherwise gets broken relationships
|
||||
if link == True:
|
||||
bpy.ops.object.make_local(type='SELECT_OBJECT')
|
||||
|
@ -216,7 +221,14 @@ def append_objects(file_name, obnames=[], location=(0, 0, 0), link=False, **kwar
|
|||
|
||||
if kwargs.get('rotation') is not None:
|
||||
main_object.rotation_euler = kwargs['rotation']
|
||||
|
||||
if kwargs.get('parent') is not None:
|
||||
main_object.parent = bpy.data.objects[kwargs['parent']]
|
||||
main_object.matrix_world.translation = location
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
utils.selection_set(sel)
|
||||
|
||||
|
||||
return main_object, return_obs
|
||||
|
|
|
@ -343,14 +343,16 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
|
|||
location=downloader['location'],
|
||||
rotation=downloader['rotation'],
|
||||
link=link,
|
||||
name=asset_data['name'])
|
||||
name=asset_data['name'],
|
||||
parent=kwargs.get('parent'))
|
||||
|
||||
else:
|
||||
parent, newobs = append_link.append_objects(file_names[-1],
|
||||
location=downloader['location'],
|
||||
rotation=downloader['rotation'],
|
||||
link=link,
|
||||
name=asset_data['name'])
|
||||
name=asset_data['name'],
|
||||
parent=kwargs.get('parent'))
|
||||
if parent.type == 'EMPTY' and link:
|
||||
bmin = asset_data['bbox_min']
|
||||
bmax = asset_data['bbox_max']
|
||||
|
@ -363,12 +365,14 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
|
|||
location=kwargs['model_location'],
|
||||
rotation=kwargs['model_rotation'],
|
||||
link=link,
|
||||
name=asset_data['name'])
|
||||
name=asset_data['name'],
|
||||
parent=kwargs.get('parent'))
|
||||
else:
|
||||
parent, newobs = append_link.append_objects(file_names[-1],
|
||||
location=kwargs['model_location'],
|
||||
rotation=kwargs['model_rotation'],
|
||||
link=link)
|
||||
link=link,
|
||||
parent=kwargs.get('parent'))
|
||||
if parent.type == 'EMPTY' and link:
|
||||
bmin = asset_data['bbox_min']
|
||||
bmax = asset_data['bbox_max']
|
||||
|
@ -839,13 +843,16 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
|
|||
asset_index: IntProperty(name="Asset Index", description='asset index in search results', default=-1)
|
||||
|
||||
target_object: StringProperty(
|
||||
name="Material Target Object",
|
||||
description="",
|
||||
name="Target Object",
|
||||
description="Material or object target for replacement",
|
||||
default="")
|
||||
|
||||
material_target_slot: IntProperty(name="Asset Index", description='asset index in search results', default=0)
|
||||
model_location: FloatVectorProperty(name='Asset Location', default=(0, 0, 0))
|
||||
model_rotation: FloatVectorProperty(name='Asset Rotation', default=(0, 0, 0))
|
||||
|
||||
replace: BoolProperty(name='Replace', description='replace selection with the asset', default=False)
|
||||
|
||||
cast_parent: StringProperty(
|
||||
name="Particles Target Object",
|
||||
description="",
|
||||
|
@ -865,19 +872,38 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
|
|||
s['assets used'] = {}
|
||||
if asset_data['asset_base_id'] in s.get('assets used'):
|
||||
asset_data = s['assets used'][asset_data['asset_base_id']].to_dict()
|
||||
|
||||
atype = asset_data['asset_type']
|
||||
if bpy.context.mode != 'OBJECT' and (
|
||||
atype == 'model' or atype == 'material') and bpy.context.active_object is not None:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
kwargs = {
|
||||
'cast_parent': self.cast_parent,
|
||||
'target_object': self.target_object,
|
||||
'material_target_slot': self.material_target_slot,
|
||||
'model_location': tuple(self.model_location),
|
||||
'model_rotation': tuple(self.model_rotation)
|
||||
}
|
||||
|
||||
start_download(asset_data, **kwargs)
|
||||
if self.replace: # cleanup first, assign later.
|
||||
obs = utils.get_selected_models()
|
||||
|
||||
for ob in obs:
|
||||
kwargs = {
|
||||
'cast_parent': self.cast_parent,
|
||||
'target_object': ob.name,
|
||||
'material_target_slot': ob.active_material_index,
|
||||
'model_location': tuple(ob.matrix_world.translation),
|
||||
'model_rotation': tuple(ob.matrix_world.to_euler()),
|
||||
'replace': False,
|
||||
'parent': ob.parent
|
||||
}
|
||||
utils.delete_hierarchy(ob)
|
||||
start_download(asset_data, **kwargs)
|
||||
else:
|
||||
kwargs = {
|
||||
'cast_parent': self.cast_parent,
|
||||
'target_object': self.target_object,
|
||||
'material_target_slot': self.material_target_slot,
|
||||
'model_location': tuple(self.model_location),
|
||||
'model_rotation': tuple(self.model_rotation),
|
||||
'replace': False
|
||||
}
|
||||
|
||||
start_download(asset_data, **kwargs)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
|
@ -886,7 +912,7 @@ def register_download():
|
|||
bpy.utils.register_class(BlenderkitKillDownloadOperator)
|
||||
bpy.app.handlers.load_post.append(scene_load)
|
||||
bpy.app.handlers.save_pre.append(scene_save)
|
||||
bpy.app.timers.register(timer_update, persistent = True)
|
||||
bpy.app.timers.register(timer_update, persistent=True)
|
||||
|
||||
|
||||
def unregister_download():
|
||||
|
|
|
@ -733,19 +733,34 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
|
|||
sr = bpy.context.scene['search results orig']['results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
author_id = str(asset_data['author']['id'])
|
||||
a = bpy.context.window_manager['bkit authors'].get(author_id)
|
||||
if a is not None:
|
||||
# utils.p('author:', a)
|
||||
if a.get('aboutMeUrl') is not None:
|
||||
op = layout.operator('wm.url_open', text="Open author's website")
|
||||
op.url = a['aboutMeUrl']
|
||||
op = layout.operator('view3d.blenderkit_search', text='search assets by same author')
|
||||
op.author_id = author_id
|
||||
|
||||
wm = bpy.context.window_manager
|
||||
if wm.get('bkit authors') is not None:
|
||||
a = bpy.context.window_manager['bkit authors'].get(author_id)
|
||||
if a is not None:
|
||||
# utils.p('author:', a)
|
||||
if a.get('aboutMeUrl') is not None:
|
||||
op = layout.operator('wm.url_open', text="Open author's website")
|
||||
op.url = a['aboutMeUrl']
|
||||
|
||||
op = layout.operator('view3d.blenderkit_search', text='search assets by same author')
|
||||
op.author_id = author_id
|
||||
|
||||
op = layout.operator('view3d.blenderkit_search', text='search similar')
|
||||
print(dir(asset_data))
|
||||
op.keywords = asset_data['name'] + ' ' + asset_data['description'] + ' ' + ''.join(asset_data['tags'])
|
||||
|
||||
if bpy.context.active_object is not None and ui_props.asset_type == 'MODEL':
|
||||
aob = bpy.context.active_object
|
||||
op = layout.operator('scene.blenderkit_download', text='replace active ' + ui_props.asset_type.lower())
|
||||
op.asset_type = ui_props.asset_type
|
||||
op.asset_index = ui_props.active_index
|
||||
op.model_location = aob.location
|
||||
op.model_rotation = aob.rotation_euler
|
||||
op.target_object = aob.name
|
||||
op.material_target_slot = aob.active_material_index
|
||||
op.replace = True
|
||||
|
||||
wm = bpy.context.window_manager
|
||||
profile = wm.get('bkit profile')
|
||||
if profile is not None:
|
||||
|
@ -808,7 +823,6 @@ def draw_panel_categories(self, context):
|
|||
# row.prop(ui_props, 'asset_type', expand=True, icon_only=True)
|
||||
layout.separator()
|
||||
|
||||
|
||||
layout.label(text='Categories')
|
||||
wm = bpy.context.window_manager
|
||||
if wm.get('bkit_categories') == None:
|
||||
|
|
|
@ -65,14 +65,18 @@ def get_selected_models():
|
|||
parents = []
|
||||
for ob in obs:
|
||||
if ob not in done:
|
||||
while ob.parent is not None and ob not in done:
|
||||
while ob.parent is not None and ob not in done and ob.blenderkit.asset_base_id != '' and ob.instance_collection is not None:
|
||||
done[ob] = True
|
||||
ob = ob.parent
|
||||
|
||||
if ob not in parents and ob not in done:
|
||||
if ob.blenderkit.name != '':
|
||||
if ob.blenderkit.name != '' or ob.instance_collection is not None:
|
||||
parents.append(ob)
|
||||
done[ob] = True
|
||||
|
||||
#if no blenderkit - like objects were found, use the original selection.
|
||||
if len(parents) == 0:
|
||||
parents = obs
|
||||
return parents
|
||||
|
||||
|
||||
|
@ -282,6 +286,15 @@ def get_hierarchy(ob):
|
|||
obs.append(o)
|
||||
return obs
|
||||
|
||||
def select_hierarchy(ob, state = True):
|
||||
obs = get_hierarchy(ob)
|
||||
for ob in obs:
|
||||
ob.select_set(state)
|
||||
return obs
|
||||
|
||||
def delete_hierarchy(ob):
|
||||
obs = get_hierarchy(ob)
|
||||
bpy.ops.object.delete({"selected_objects": obs})
|
||||
|
||||
def get_bounds_snappable(obs, use_modifiers=False):
|
||||
# progress('getting bounds of object(s)')
|
||||
|
|
Loading…
Reference in New Issue