Asset Pipeline v2 #145
@ -101,9 +101,9 @@ class AssetTransferMapping:
|
|||||||
coll_map: Dict[bpy.types.Collection, bpy.types.Collection] = {}
|
coll_map: Dict[bpy.types.Collection, bpy.types.Collection] = {}
|
||||||
|
|
||||||
local_tl_names = [
|
local_tl_names = [
|
||||||
core.get_name_with_asset_prefix(tl_type[1])
|
core.get_name_with_asset_prefix(tl_ui_name)
|
||||||
for tl_type in constants.TASK_LAYER_TYPES
|
for tl_key, tl_ui_name in constants.TASK_LAYER_TYPES.items()
|
||||||
if tl_type[0] in self._local_tls
|
if tl_key in self._local_tls
|
||||||
]
|
]
|
||||||
|
|
||||||
for local_task_layer_col in self._local_col.children:
|
for local_task_layer_col in self._local_col.children:
|
||||||
|
@ -1,49 +1,54 @@
|
|||||||
# TODO Tie this into props and generate based on JSON file instead
|
# TODO Tie this into props and generate based on JSON file instead
|
||||||
|
|
||||||
TASK_LAYER_TYPES = [
|
# Information about the list of task layers.
|
||||||
("NONE", "None", ""),
|
# There is no behaviour that is specific to a particular task layer.
|
||||||
("MODEL", "Modeling", ""),
|
# You could even choose to name your task layers after artists in your team.
|
||||||
("RIG", "Rigging", ""),
|
# {Task Layer Key: Collection/UI name}
|
||||||
("SHADE", "Shading", ""),
|
TASK_LAYER_TYPES = {
|
||||||
|
"NONE": "None",
|
||||||
|
"MODEL": "Modeling",
|
||||||
|
"RIG": "Rigging",
|
||||||
|
"SHADE": "Shading"
|
||||||
|
}
|
||||||
|
|
||||||
|
# When creating a new asset, start in this task layer's file.
|
||||||
|
STARTING_FILE = 'MODEL'
|
||||||
|
|
||||||
|
# Convert it to the format that EnumProperty.items wants:
|
||||||
|
# List of 3-tuples, re-use name as description at 3rd element.
|
||||||
|
TASK_LAYER_TYPES_ENUM_ITEMS = [
|
||||||
|
(key, value, value) for key, value in TASK_LAYER_TYPES.items()
|
||||||
]
|
]
|
||||||
|
|
||||||
TASK_LAYER_KEYS = [task_layer[0] for task_layer in TASK_LAYER_TYPES]
|
NONE_KEY = "NONE"
|
||||||
TASK_LAYER_NAMES = [task_layer[1] for task_layer in TASK_LAYER_TYPES]
|
VERTEX_GROUP_KEY = "GROUP_VERTEX"
|
||||||
|
VERTEX_COLOR_KEY = "COLOR_ATTRIBUTE"
|
||||||
|
MODIFIER_KEY = "MODIFIER"
|
||||||
|
CONSTRAINT_KEY = "CONSTRAINT"
|
||||||
|
MATERIAL_SLOT_KEY = "MATERIAL"
|
||||||
|
UV_LAYERS_KEY = "UV_MAP"
|
||||||
|
SHAPE_KEY_KEY = "SHAPE_KEY"
|
||||||
|
ATTRIBUTE_KEY = "ATTRIBUTE"
|
||||||
|
|
||||||
# KEYS FOR TRANSFER DATA TYPE MATCH NAME OF ICON
|
# Information about supported transferable data.
|
||||||
TRANSFER_DATA_TYPES = [
|
# {Key string : ("UI Name", 'ICON')}
|
||||||
("NONE", "None", ""),
|
TRANSFER_DATA_TYPES = {
|
||||||
("GROUP_VERTEX", "Vertex Group", ""),
|
NONE_KEY: ("None", "BLANK1"),
|
||||||
("COLOR_ATTRIBUTE", "Color Attribute", ""),
|
VERTEX_GROUP_KEY: ("Vertex Group", 'GROUP_VERTEX'),
|
||||||
("MODIFIER", "Modifier", ""),
|
VERTEX_COLOR_KEY: ("Color Attribute", 'GROUP_VCOL'),
|
||||||
("CONSTRAINT", "Constraint", ""),
|
MODIFIER_KEY: ("Modifier", 'MODIFIER'),
|
||||||
("MATERIAL", "Material Slot", ""),
|
CONSTRAINT_KEY: ("Constraint", 'CONSTRAINT'),
|
||||||
("UV_MAP", "UV Maps", ""),
|
MATERIAL_SLOT_KEY: ("Material Slot", 'MATERIAL'),
|
||||||
("SHAPE_KEY", "Shape Key", ""),
|
UV_LAYERS_KEY: ("UV Maps", 'GROUP_UVS'),
|
||||||
("ATTRIBUTE", "Attribute", ""),
|
SHAPE_KEY_KEY: ("Shape Key", 'SHAPEKEY_DATA'),
|
||||||
]
|
ATTRIBUTE_KEY: ("Attribute", 'EVENT_A'),
|
||||||
|
}
|
||||||
|
|
||||||
TRANSFER_DATA_KEYS = [transfer_data[0] for transfer_data in TRANSFER_DATA_TYPES]
|
# Convert it to the format that EnumProperty.items wants:
|
||||||
|
# List of 5-tuples; Re-use name as description at 3rd element, add index at 5th.
|
||||||
VERTEX_GROUP_KEY = TRANSFER_DATA_KEYS[1]
|
TRANSFER_DATA_TYPES_ENUM_ITEMS = [
|
||||||
VERTEX_COLOR_KEY = TRANSFER_DATA_KEYS[2]
|
(tup[0], tup[1][0], tup[1][0], tup[1][1], i)
|
||||||
MODIFIER_KEY = TRANSFER_DATA_KEYS[3]
|
for i, tup in enumerate(TRANSFER_DATA_TYPES.items())
|
||||||
CONSTRAINT_KEY = TRANSFER_DATA_KEYS[4]
|
|
||||||
MATERIAL_SLOT_KEY = TRANSFER_DATA_KEYS[5]
|
|
||||||
UV_LAYERS_KEY = TRANSFER_DATA_KEYS[6]
|
|
||||||
SHAPE_KEY_KEY = TRANSFER_DATA_KEYS[7]
|
|
||||||
ATTRIBUTE_KEY = TRANSFER_DATA_KEYS[8]
|
|
||||||
|
|
||||||
TRANSFER_DATA_ICONS = [
|
|
||||||
("None", "NONE", ""),
|
|
||||||
(VERTEX_GROUP_KEY, "GROUP_VERTEX", ""),
|
|
||||||
(VERTEX_COLOR_KEY, "GROUP_VCOL", ""),
|
|
||||||
(MODIFIER_KEY, "MODIFIER", ""),
|
|
||||||
(CONSTRAINT_KEY, "CONSTRAINT", ""),
|
|
||||||
(MATERIAL_SLOT_KEY, "MATERIAL", ""),
|
|
||||||
(UV_LAYERS_KEY, "GROUP_UVS", ""),
|
|
||||||
(SHAPE_KEY_KEY, "SHAPEKEY_DATA", ""),
|
|
||||||
(ATTRIBUTE_KEY, "EVENT_A", ""),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MATERIAL_TRANSFER_INFO_NAME = "All Material Slots"
|
MATERIAL_TRANSFER_INFO_NAME = "All Material Slots"
|
||||||
|
@ -21,7 +21,7 @@ def ownership_transfer_data_cleanup(
|
|||||||
transfer_data = obj.transfer_data_ownership
|
transfer_data = obj.transfer_data_ownership
|
||||||
to_remove = []
|
to_remove = []
|
||||||
for transfer_info in transfer_data:
|
for transfer_info in transfer_data:
|
||||||
if constants.TASK_LAYER_KEYS[transfer_info["owner"]] == task_layer_name:
|
if transfer_info.owner == task_layer_name:
|
||||||
if transfer_core.transfer_data_is_missing(transfer_info):
|
if transfer_core.transfer_data_is_missing(transfer_info):
|
||||||
to_remove.append(transfer_info.name)
|
to_remove.append(transfer_info.name)
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ def get_invalid_objects(
|
|||||||
|
|
||||||
def get_task_layer_col_name(task_layer_key):
|
def get_task_layer_col_name(task_layer_key):
|
||||||
# TODO Docstring and return types
|
# TODO Docstring and return types
|
||||||
task_layer_name = get_dict_tuple_item(constants.TASK_LAYER_TYPES, task_layer_key)[1]
|
task_layer_name = constants.TASK_LAYER_TYPES[task_layer_key]
|
||||||
return get_name_with_asset_prefix(task_layer_name)
|
return get_name_with_asset_prefix(task_layer_name)
|
||||||
|
|
||||||
|
|
||||||
@ -339,10 +339,3 @@ def import_data_from_lib(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return eval(f"bpy.data.{data_category}['{data_name}']")
|
return eval(f"bpy.data.{data_category}['{data_name}']")
|
||||||
|
|
||||||
|
|
||||||
def get_dict_tuple_item(dict: dict, key: str) -> tuple:
|
|
||||||
"""For a dict of tuples, returns a dict item based on it's key"""
|
|
||||||
for item in dict:
|
|
||||||
if item[0] == key:
|
|
||||||
return item
|
|
||||||
|
@ -64,28 +64,34 @@ class ASSETPIPE_OT_create_new_asset(bpy.types.Operator):
|
|||||||
asset_pipe.name = self._name
|
asset_pipe.name = self._name
|
||||||
asset_pipe.prefix = self._prefix
|
asset_pipe.prefix = self._prefix
|
||||||
|
|
||||||
for task_layer_key in constants.TASK_LAYER_KEYS:
|
# Create the collections for each task layer.
|
||||||
|
for task_layer_key in constants.TASK_LAYER_TYPES.keys():
|
||||||
if task_layer_key == "NONE":
|
if task_layer_key == "NONE":
|
||||||
continue
|
continue
|
||||||
col_name = core.get_task_layer_col_name(task_layer_key)
|
col_name = core.get_task_layer_col_name(task_layer_key)
|
||||||
bpy.data.collections.new(col_name)
|
bpy.data.collections.new(col_name)
|
||||||
asset_col.children.link(bpy.data.collections.get(col_name))
|
asset_col.children.link(bpy.data.collections.get(col_name))
|
||||||
|
|
||||||
for task_layer_key in reversed(constants.TASK_LAYER_KEYS):
|
starting_file = ""
|
||||||
|
# Create the file for each task layer.
|
||||||
|
for task_layer_key in constants.TASK_LAYER_TYPES.keys():
|
||||||
if task_layer_key == "NONE":
|
if task_layer_key == "NONE":
|
||||||
continue
|
continue
|
||||||
name = self._name + "." + task_layer_key + ".blend"
|
name = self._name + "." + task_layer_key + ".blend"
|
||||||
task_layer_file = os.path.join(asset_path, name)
|
task_layer_file = os.path.join(asset_path, name)
|
||||||
asset_pipe.task_layer_name = task_layer_key
|
asset_pipe.task_layer_name = task_layer_key
|
||||||
|
if task_layer_key == constants.STARTING_FILE:
|
||||||
|
starting_file = task_layer_file
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=task_layer_file, copy=True)
|
bpy.ops.wm.save_as_mainfile(filepath=task_layer_file, copy=True)
|
||||||
|
|
||||||
# Creata intial publish based on task layers
|
# Create intial publish based on task layers.
|
||||||
asset_pipe.task_layer_name = "NONE"
|
asset_pipe.task_layer_name = "NONE"
|
||||||
publish_path = os.path.join(asset_path, constants.ACTIVE_PUBLISH_KEY)
|
publish_path = os.path.join(asset_path, constants.ACTIVE_PUBLISH_KEY)
|
||||||
name = self._name + "." + "v001" + ".blend"
|
name = self._name + "." + "v001" + ".blend"
|
||||||
publish_file = os.path.join(publish_path, name)
|
publish_file = os.path.join(publish_path, name)
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=publish_file, copy=True)
|
bpy.ops.wm.save_as_mainfile(filepath=publish_file, copy=True)
|
||||||
bpy.ops.wm.open_mainfile(filepath=task_layer_file)
|
if starting_file:
|
||||||
|
bpy.ops.wm.open_mainfile(filepath=starting_file)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -236,7 +242,7 @@ class ASSETPIPE_OT_sync_with_publish(bpy.types.Operator):
|
|||||||
|
|
||||||
local_tls = [
|
local_tls = [
|
||||||
task_layer
|
task_layer
|
||||||
for task_layer in constants.TASK_LAYER_KEYS
|
for task_layer in constants.TASK_LAYER_TYPES.keys()
|
||||||
if task_layer != task_layer_key
|
if task_layer != task_layer_key
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -11,11 +11,11 @@ class AssetTransferData(bpy.types.PropertyGroup):
|
|||||||
|
|
||||||
owner: bpy.props.EnumProperty(
|
owner: bpy.props.EnumProperty(
|
||||||
name="Transfer Data Owner",
|
name="Transfer Data Owner",
|
||||||
items=constants.TASK_LAYER_TYPES,
|
items=constants.TASK_LAYER_TYPES_ENUM_ITEMS,
|
||||||
)
|
)
|
||||||
type: bpy.props.EnumProperty(
|
type: bpy.props.EnumProperty(
|
||||||
name="Transfer Data Type",
|
name="Transfer Data Type",
|
||||||
items=constants.TRANSFER_DATA_TYPES,
|
items=constants.TRANSFER_DATA_TYPES_ENUM_ITEMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -25,11 +25,11 @@ class AssetTransferDataTemp(bpy.types.PropertyGroup):
|
|||||||
|
|
||||||
owner: bpy.props.EnumProperty(
|
owner: bpy.props.EnumProperty(
|
||||||
name="Transfer Data Owner",
|
name="Transfer Data Owner",
|
||||||
items=constants.TASK_LAYER_TYPES,
|
items=constants.TASK_LAYER_TYPES_ENUM_ITEMS,
|
||||||
)
|
)
|
||||||
type: bpy.props.EnumProperty(
|
type: bpy.props.EnumProperty(
|
||||||
name="Transfer Data Type",
|
name="Transfer Data Type",
|
||||||
items=constants.TRANSFER_DATA_TYPES,
|
items=constants.TRANSFER_DATA_TYPES_ENUM_ITEMS,
|
||||||
)
|
)
|
||||||
obj: bpy.props.PointerProperty(type=bpy.types.Object)
|
obj: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ class AssetPipeline(bpy.types.PropertyGroup):
|
|||||||
|
|
||||||
# TODO Rename to Current_Task_Layer
|
# TODO Rename to Current_Task_Layer
|
||||||
task_layer_name: bpy.props.EnumProperty(
|
task_layer_name: bpy.props.EnumProperty(
|
||||||
name="Task Layer Name", items=constants.TASK_LAYER_TYPES
|
name="Task Layer Name", items=constants.TASK_LAYER_TYPES_ENUM_ITEMS
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_temp_trasnfer_data(self, name, owner, type, obj):
|
def add_temp_trasnfer_data(self, name, owner, type, obj):
|
||||||
@ -94,7 +94,7 @@ def register():
|
|||||||
bpy.types.Scene.asset_pipeline = bpy.props.PointerProperty(type=AssetPipeline)
|
bpy.types.Scene.asset_pipeline = bpy.props.PointerProperty(type=AssetPipeline)
|
||||||
bpy.types.Object.asset_id_owner = bpy.props.EnumProperty(
|
bpy.types.Object.asset_id_owner = bpy.props.EnumProperty(
|
||||||
name="ID Owner",
|
name="ID Owner",
|
||||||
items=constants.TASK_LAYER_TYPES,
|
items=constants.TASK_LAYER_TYPES_ENUM_ITEMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ def init_transfer_data(
|
|||||||
transfer_functions.init_constraints(scene, obj)
|
transfer_functions.init_constraints(scene, obj)
|
||||||
# transfer_functions.init_vertex_colors(scene, obj)
|
# transfer_functions.init_vertex_colors(scene, obj)
|
||||||
# transfer_functions.init_uv_layers(scene, obj)
|
# transfer_functions.init_uv_layers(scene, obj)
|
||||||
transfer_functions.init_shap_keys(scene, obj)
|
transfer_functions.init_shape_keys(scene, obj)
|
||||||
transfer_functions.init_attributes(scene, obj)
|
transfer_functions.init_attributes(scene, obj)
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,7 +296,8 @@ def material_slots_clean(obj):
|
|||||||
if transfer_data_list != []:
|
if transfer_data_list != []:
|
||||||
return
|
return
|
||||||
|
|
||||||
obj.data.materials.clear()
|
if obj.data and hasattr(obj.data, 'materials'):
|
||||||
|
obj.data.materials.clear()
|
||||||
|
|
||||||
|
|
||||||
def material_slots_is_missing(transfer_info):
|
def material_slots_is_missing(transfer_info):
|
||||||
@ -357,13 +358,6 @@ def shape_key_set_active(obj, shape_key_name):
|
|||||||
obj.active_shape_key_index = index
|
obj.active_shape_key_index = index
|
||||||
|
|
||||||
|
|
||||||
def shape_key_move(context, obj, shape_key_name, top=True):
|
|
||||||
move_type = "TOP" if top else "BOTTOM"
|
|
||||||
shape_key_set_active(obj, shape_key_name)
|
|
||||||
with context.temp_override(object=obj):
|
|
||||||
bpy.ops.object.shape_key_move(type=move_type)
|
|
||||||
|
|
||||||
|
|
||||||
def shape_key_closest_face_to_point(bm_source, p_target, bvh_tree=None):
|
def shape_key_closest_face_to_point(bm_source, p_target, bvh_tree=None):
|
||||||
if not bvh_tree:
|
if not bvh_tree:
|
||||||
bvh_tree = mathutils.bvhtree.BVHTree.FromBMesh(bm_source)
|
bvh_tree = mathutils.bvhtree.BVHTree.FromBMesh(bm_source)
|
||||||
@ -408,18 +402,18 @@ def shape_keys_clean(obj):
|
|||||||
obj.transfer_data_ownership, constants.SHAPE_KEY_KEY
|
obj.transfer_data_ownership, constants.SHAPE_KEY_KEY
|
||||||
)
|
)
|
||||||
for shape_key in obj.data.shape_keys.key_blocks:
|
for shape_key in obj.data.shape_keys.key_blocks:
|
||||||
# Move Shape Keys relative to themselves to the top (usually basis key)
|
|
||||||
if shape_key.relative_key == shape_key:
|
|
||||||
shape_key_move(context, obj, shape_key.name)
|
|
||||||
|
|
||||||
if not asset_suffix.get_basename(shape_key.name) in transfer_data_list:
|
if not asset_suffix.get_basename(shape_key.name) in transfer_data_list:
|
||||||
obj.shape_key_remove(shape_key)
|
obj.shape_key_remove(shape_key)
|
||||||
|
|
||||||
|
|
||||||
def shape_key_is_missing(transfer_info):
|
def shape_key_is_missing(transfer_info):
|
||||||
obj = transfer_info.id_data
|
if not transfer_info.type == constants.SHAPE_KEY_KEY:
|
||||||
if obj.type != "MESH" or obj.data.shape_keys is None:
|
|
||||||
return
|
return
|
||||||
|
obj = transfer_info.id_data
|
||||||
|
if obj.type != 'MESH':
|
||||||
|
return
|
||||||
|
if not obj.data.shape_keys:
|
||||||
|
return True
|
||||||
return transfer_core.transfer_info_is_missing(
|
return transfer_core.transfer_info_is_missing(
|
||||||
transfer_info,
|
transfer_info,
|
||||||
constants.SHAPE_KEY_KEY,
|
constants.SHAPE_KEY_KEY,
|
||||||
@ -427,9 +421,18 @@ def shape_key_is_missing(transfer_info):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def init_shap_keys(scene, obj):
|
def init_shape_keys(scene, obj):
|
||||||
if obj.type != "MESH" or obj.data.shape_keys is None:
|
if obj.type != "MESH" or obj.data.shape_keys is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Check that the order is legal.
|
||||||
|
# Key Blocks must be ordered after the key they are Relative To.
|
||||||
|
for i, kb in enumerate(obj.data.shape_keys.key_blocks):
|
||||||
|
if kb.relative_key:
|
||||||
|
base_shape_idx = obj.data.shape_keys.key_blocks.find(kb.relative_key.name)
|
||||||
|
if base_shape_idx > i:
|
||||||
|
raise Exception(f'Shape Key "{kb.name}" must be ordered after its base shape "{kb.relative_key.name}" on object "{obj.name}".')
|
||||||
|
|
||||||
transfer_core.transfer_info_init(
|
transfer_core.transfer_info_init(
|
||||||
scene, obj, obj.data.shape_keys.key_blocks, constants.SHAPE_KEY_KEY
|
scene, obj, obj.data.shape_keys.key_blocks, constants.SHAPE_KEY_KEY
|
||||||
)
|
)
|
||||||
@ -441,42 +444,48 @@ def transfer_shape_key(
|
|||||||
target_obj: bpy.types.Object,
|
target_obj: bpy.types.Object,
|
||||||
source_obj: bpy.types.Object,
|
source_obj: bpy.types.Object,
|
||||||
):
|
):
|
||||||
# BASIS SHAPE KEY MUST BE PASSED FIRST OTHERWISE THIS WILL ERROR OUT
|
if not source_obj.data.shape_keys:
|
||||||
|
return
|
||||||
sk_source = source_obj.data.shape_keys.key_blocks.get(shape_key_name)
|
sk_source = source_obj.data.shape_keys.key_blocks.get(shape_key_name)
|
||||||
print(f"Moving shape key: {shape_key_name}")
|
assert sk_source
|
||||||
|
|
||||||
# If key is relative to another key that doesn't exist yet
|
sk_target = None
|
||||||
if sk_source.relative_key != sk_source:
|
if not target_obj.data.shape_keys:
|
||||||
relative_key = target_obj.data.shape_keys.key_blocks.get(
|
sk_target = target_obj.shape_key_add()
|
||||||
sk_source.relative_key.name
|
if not sk_target:
|
||||||
)
|
sk_target = target_obj.data.shape_keys.key_blocks.get(shape_key_name)
|
||||||
if not relative_key:
|
if not sk_target:
|
||||||
print(
|
sk_target = target_obj.shape_key_add()
|
||||||
f"Shape Key '{sk_source.name}' failed to find Relative Key '{sk_source.relative_key.name}' on Object '{target_obj.name}'"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Remove existing shape keys that match name
|
|
||||||
if target_obj.data.shape_keys is not None:
|
|
||||||
old_sk = target_obj.data.shape_keys.key_blocks.get(shape_key_name)
|
|
||||||
if old_sk:
|
|
||||||
target_obj.shape_key_remove(old_sk)
|
|
||||||
|
|
||||||
sk_target = target_obj.shape_key_add()
|
|
||||||
sk_target.name = sk_source.name
|
sk_target.name = sk_source.name
|
||||||
sk_target.vertex_group = sk_source.vertex_group
|
sk_target.vertex_group = sk_source.vertex_group
|
||||||
sk_target.relative_key = target_obj.data.shape_keys.key_blocks[
|
if sk_source.relative_key != sk_source:
|
||||||
sk_source.relative_key.name
|
relative_key = None
|
||||||
]
|
if target_obj.data.shape_keys:
|
||||||
|
relative_key = target_obj.data.shape_keys.key_blocks.get(
|
||||||
|
sk_source.relative_key.name
|
||||||
|
)
|
||||||
|
if relative_key:
|
||||||
|
sk_target.relative_key = relative_key
|
||||||
|
else:
|
||||||
|
# If the base shape of one of our shapes was removed by another task layer,
|
||||||
|
# the result will probably be pretty bad, but it's not a catastrophic failure.
|
||||||
|
# Proceed with a warning.
|
||||||
|
print(
|
||||||
|
f'Warning: Base shape "{sk_source.relative_key.name}" of Key "{sk_source.name}" was removed from "{target_obj.name}"'
|
||||||
|
)
|
||||||
|
|
||||||
|
sk_target.slider_min = sk_source.slider_min
|
||||||
|
sk_target.slider_max = sk_source.slider_max
|
||||||
|
sk_target.value = sk_source.value
|
||||||
|
sk_target.mute = sk_source.mute
|
||||||
|
|
||||||
bm_source = bmesh.new()
|
bm_source = bmesh.new()
|
||||||
bm_source.from_mesh(source_obj.data)
|
bm_source.from_mesh(source_obj.data)
|
||||||
bm_source.faces.ensure_lookup_table()
|
bm_source.faces.ensure_lookup_table()
|
||||||
|
|
||||||
bvh_tree = mathutils.bvhtree.BVHTree.FromBMesh(bm_source)
|
bvh_tree = mathutils.bvhtree.BVHTree.FromBMesh(bm_source)
|
||||||
|
|
||||||
tris_dict = shape_key_tris_per_face(bm_source)
|
tris_dict = shape_key_tris_per_face(bm_source)
|
||||||
|
|
||||||
for i, vert in enumerate(target_obj.data.vertices):
|
for i, vert in enumerate(target_obj.data.vertices):
|
||||||
p = vert.co
|
p = vert.co
|
||||||
face = shape_key_closest_face_to_point(bm_source, p, bvh_tree)
|
face = shape_key_closest_face_to_point(bm_source, p, bvh_tree)
|
||||||
@ -576,7 +585,7 @@ def transfer_attribute(
|
|||||||
type=source_attribute.data_type,
|
type=source_attribute.data_type,
|
||||||
domain=source_attribute.domain,
|
domain=source_attribute.domain,
|
||||||
)
|
)
|
||||||
print(f"Transferring Attribute{attribute_name}")
|
# print(f"Transfering Attribute {attribute_name}")
|
||||||
for source_data_item in source_attribute.data.items():
|
for source_data_item in source_attribute.data.items():
|
||||||
index = source_data_item[0]
|
index = source_data_item[0]
|
||||||
source_data = source_data_item[1]
|
source_data = source_data_item[1]
|
||||||
|
@ -8,19 +8,12 @@ def draw_transfer_data_type(
|
|||||||
"""Draw UI Element for items of a transfer data type"""
|
"""Draw UI Element for items of a transfer data type"""
|
||||||
if transfer_data == []:
|
if transfer_data == []:
|
||||||
return
|
return
|
||||||
name = core.get_dict_tuple_item(
|
name, icon = constants.TRANSFER_DATA_TYPES[transfer_data[0].type]
|
||||||
constants.TRANSFER_DATA_TYPES, transfer_data[0].type
|
|
||||||
)[1]
|
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
icon = core.get_dict_tuple_item(
|
|
||||||
constants.TRANSFER_DATA_ICONS, transfer_data[0].type
|
|
||||||
)[1]
|
|
||||||
box.label(text=name, icon=icon)
|
box.label(text=name, icon=icon)
|
||||||
for transfer_info in transfer_data:
|
for transfer_info in transfer_data:
|
||||||
owner = core.get_dict_tuple_item(
|
owner_tl_ui_name = constants.TASK_LAYER_TYPES[transfer_info.owner]
|
||||||
constants.TASK_LAYER_TYPES, transfer_info.owner
|
box.label(text=f"{transfer_info.name}: '{owner_tl_ui_name}'")
|
||||||
)[1]
|
|
||||||
box.label(text=f"{transfer_info.name}: '{owner}'")
|
|
||||||
|
|
||||||
|
|
||||||
def draw_transfer_data(
|
def draw_transfer_data(
|
||||||
|
@ -65,10 +65,8 @@ class ASSETPIPE_ownership_inspector(bpy.types.Panel):
|
|||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
transfer_data = obj.transfer_data_ownership
|
transfer_data = obj.transfer_data_ownership
|
||||||
layout = layout.box()
|
layout = layout.box()
|
||||||
owner = core.get_dict_tuple_item(
|
owner_tl_ui_name = constants.TASK_LAYER_TYPES[obj.asset_id_owner]
|
||||||
constants.TASK_LAYER_TYPES, obj.asset_id_owner
|
layout.label(text=f"{obj.name}: '{owner_tl_ui_name}'", icon="OBJECT_DATA")
|
||||||
)[1]
|
|
||||||
layout.label(text=f"{obj.name}: '{owner}'", icon="OBJECT_DATA")
|
|
||||||
transfer_ui.draw_transfer_data(transfer_data, layout)
|
transfer_ui.draw_transfer_data(transfer_data, layout)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user