def bpy_data_ctor_lights(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) name = proxy.data("name") light_type = proxy.data("type") light = collection.new(name, light_type) return light
def bpy_data_ctor_sounds(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) filepath = proxy.data("filepath") # TODO what about "check_existing" ? id_ = collection.load(filepath) # we may have received an ID named xxx.001 although filepath is xxx, so fix it now id_.name = proxy.data("name") return id_
def pre_save_datablock(proxy: DatablockProxy, target: T.ID, context: Context) -> T.ID: """Process attributes that must be saved first and return a possibly updated reference to the target""" # WARNING this is called from save() and from apply() # When called from save, the proxy has all the synchronized properties # WHen called from apply, the proxy only contains the updated properties if target.library: return target # animation_data is handled in StructProxy (parent class of DatablockProxy) if isinstance(target, T.Mesh): from mixer.blender_data.mesh_proxy import MeshProxy assert isinstance(proxy, MeshProxy) if proxy.requires_clear_geometry(target): target.clear_geometry() elif isinstance(target, T.Material): is_grease_pencil = proxy.data("is_grease_pencil") # will be None for a DeltaUpdate that does not modify "is_grease_pencil" if is_grease_pencil is not None: # Seems to be write once as no depsgraph update is fired if is_grease_pencil and not target.grease_pencil: bpy.data.materials.create_gpencil_data(target) elif not is_grease_pencil and target.grease_pencil: bpy.data.materials.remove_gpencil_data(target) elif isinstance(target, T.Scene): from mixer.blender_data.misc_proxies import NonePtrProxy sequence_editor = proxy.data("sequence_editor") if sequence_editor is not None: # NonePtrProxy or StructProxy if not isinstance(sequence_editor, NonePtrProxy) and target.sequence_editor is None: target.sequence_editor_create() elif isinstance( sequence_editor, NonePtrProxy) and target.sequence_editor is not None: target.sequence_editor_clear() elif isinstance(target, _morphable_types): # required first to have access to new datablock attributes type_ = proxy.data("type") if type_ is not None and type_ != target.type: target.type = type_ # must reload the reference target = target.type_recast() uuid = proxy.mixer_uuid context.proxy_state.remove_datablock(uuid) context.proxy_state.add_datablock(uuid, target) elif isinstance(target, T.Action): groups = proxy.data("groups") if groups: groups.save(target.groups, target, "groups", context) return target
def _(collection_name: str, proxy: DatablockProxy, context: Context) -> T.VectorFont: name = proxy.data("name") filepath = proxy.data("filepath") if filepath != "<builtin>": raise NotImplementedError(f"non builtin font: {name}") dummy_text = bpy.data.curves.new("_mixer_tmp_text", "FONT") font = dummy_text.font bpy.data.curves.remove(dummy_text) return font
def pre_save_datablock(proxy: DatablockProxy, target: T.ID, context: Context) -> T.ID: """Process attributes that must be saved first and return a possibly updated reference to the target""" # WARNING this is called from save() and from apply() # When called from save, the proxy has all the synchronized properties # WHen called from apply, the proxy only contains the updated properties if target.library: return target if isinstance(target, T.Mesh) and proxy.requires_clear_geometry(target): target.clear_geometry() elif isinstance(target, T.Material): is_grease_pencil = proxy.data("is_grease_pencil") # will be None for a DeltaUpdate that does not modify "is_grease_pencil" if is_grease_pencil is not None: # Seems to be write once as no depsgraph update is fired if is_grease_pencil and not target.grease_pencil: bpy.data.materials.create_gpencil_data(target) elif not is_grease_pencil and target.grease_pencil: bpy.data.materials.remove_gpencil_data(target) elif isinstance(target, T.Scene): from mixer.blender_data.misc_proxies import NonePtrProxy sequence_editor = proxy.data("sequence_editor") if sequence_editor is not None: # NonePtrProxy or StructProxy if not isinstance(sequence_editor, NonePtrProxy) and target.sequence_editor is None: target.sequence_editor_create() elif isinstance( sequence_editor, NonePtrProxy) and target.sequence_editor is not None: target.sequence_editor_clear() elif isinstance(target, T.Light): # required first to have access to new light type attributes light_type = proxy.data("type") if light_type is not None and light_type != target.type: target.type = light_type # must reload the reference target = proxy.target(context) return target
def _(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) media = None media_name = proxy.data("name") filepath = proxy.data("filepath") resolved_filepath = proxy.resolved_filepath(context) if resolved_filepath is None: return None packed_files = proxy.data("packed_files") if packed_files is not None and packed_files.length: if collection_name == "images": width, height = proxy.data("size") try: with open(resolved_filepath, "rb") as file_: buffer = file_.read() media = collection.new(media_name, width, height) media.pack(data=buffer, data_len=len(buffer)) except RuntimeError as e: logger.warning( f'Cannot load packed file original "{filepath}"", resolved "{resolved_filepath}". Exception: ' ) logger.warning(f"... {e}") raise ExternalFileFailed from e else: try: media = collection.load(resolved_filepath) media.name = media_name except RuntimeError as e: logger.warning( f'Cannot load file original "{filepath}"", resolved "{resolved_filepath}". Exception: ' ) logger.warning(f"... {e}") raise ExternalFileFailed from e # prevent filepath to be overwritten by the incoming proxy value as it would attempt to reload the file # from the incoming path that may not exist proxy._data["filepath"] = resolved_filepath proxy._data["filepath_raw"] = resolved_filepath return media
def _(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy from mixer.blender_data.misc_proxies import NonePtrProxy collection = getattr(bpy.data, collection_name) name = proxy.data("name") data_datablock = None data_proxy = proxy.data("data") if isinstance(data_proxy, DatablockRefProxy): data_datablock = data_proxy.target(context) elif isinstance(data_proxy, NonePtrProxy): data_datablock = None else: # error on the sender side logger.warning( f"bpy.data.objects[{name}].data proxy is a {data_proxy.__class__}." ) logger.warning("... loaded as Empty") data_datablock = None return collection.new(name, data_datablock)
def bpy_data_ctor(collection_name: str, proxy: DatablockProxy, context: Any) -> Optional[T.ID]: """ Create an element in a bpy.data collection. Contains collection-specific code is the mathod to add an element is not new(name: str) """ collection = getattr(bpy.data, collection_name) name = proxy.data("name") try: id_ = collection.new(name) except Exception as e: logger.error( f"Exception while calling : bpy.data.{collection_name}.new({name})" ) logger.error(f"... {e!r}") return None return id_
def bpy_data_ctor(collection_name: str, proxy: DatablockProxy, context: Any) -> Optional[T.ID]: """ Create an element in a bpy.data collection. Contains collection-specific code is the mathod to add an element is not new(name: str) """ collection = getattr(bpy.data, collection_name) if collection_name == "images": image = None image_name = proxy.data("name") filepath = proxy.data("filepath") resolved_filepath = get_resolved_file_path(filepath) packed_files = proxy.data("packed_files") if packed_files is not None and packed_files.length: name = proxy.data("name") width, height = proxy.data("size") try: with open(resolved_filepath, "rb") as image_file: buffer = image_file.read() image = collection.new(name, width, height) image.pack(data=buffer, data_len=len(buffer)) except RuntimeError as e: logger.warning( f'Cannot load packed image original "{filepath}"", resolved "{resolved_filepath}". Exception: ' ) logger.warning(f"... {e}") return None else: try: image = collection.load(resolved_filepath) image.name = image_name except RuntimeError as e: logger.warning( f'Cannot load image original "{filepath}"", resolved "{resolved_filepath}". Exception: ' ) logger.warning(f"... {e}") return None # prevent filepath to be overwritten by the incoming proxy value as it would attempt to reload the file # from the incoming path that may not exist proxy._data["filepath"] = resolved_filepath proxy._data["filepath_raw"] = resolved_filepath return image if collection_name == "objects": from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy from mixer.blender_data.misc_proxies import NonePtrProxy name = proxy.data("name") target = None target_proxy = proxy.data("data") if isinstance(target_proxy, DatablockRefProxy): target = target_proxy.target(context) elif isinstance(target_proxy, NonePtrProxy): target = None else: # error on the sender side logger.warning( f"bpy.data.objects[{name}].data proxy is a {target_proxy.__class__}." ) logger.warning("... loaded as Empty") target = None object_ = collection.new(name, target) return object_ if collection_name == "lights": name = proxy.data("name") light_type = proxy.data("type") light = collection.new(name, light_type) return light if collection_name == "node_groups": name = proxy.data("name") type_ = node_tree_type[proxy.data("type")] return collection.new(name, type_) if collection_name == "sounds": filepath = proxy.data("filepath") # TODO what about "check_existing" ? id_ = collection.load(filepath) # we may have received an ID named xxx.001 although filepath is xxx, so fix it now id_.name = proxy.data("name") return id_ if collection_name == "curves": name = proxy.data("name") return bpy.data.curves.new(name, "CURVE") name = proxy.data("name") try: id_ = collection.new(name) except TypeError as e: logger.error( f"Exception while calling : bpy.data.{collection_name}.new({name})" ) logger.error(f"TypeError : {e!r}") return None return id_
def _(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) name = proxy.data("name") curve_type = proxy._type_name return collection.new(name, _curve_ids[curve_type])
def _(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) name = proxy.data("name") type_ = proxy.data("type") return collection.new(name, type_)
def bpy_data_ctor_curves(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) name = proxy.data("name") return collection.new(name, "CURVE")
def bpy_data_ctor_node_groups(collection_name: str, proxy: DatablockProxy, context: Context) -> Optional[T.ID]: collection = getattr(bpy.data, collection_name) name = proxy.data("name") type_ = node_tree_type[proxy.data("type")] return collection.new(name, type_)