def execute(self, context): lprint('D Export From Menu...') from io_scs_tools import exp as _export from io_scs_tools.utils import object as _object_utils filepath = os.path.dirname(self.filepath) # convert it to None, so export will ignore given menu file path and try to export to other none menu set paths if self.filepath == "": filepath = None export_scope = _get_scs_globals().export_scope init_obj_list = {} if export_scope == "selection": for obj in bpy.context.selected_objects: root = _object_utils.get_scs_root(obj) if root: if root != obj: # add only selected children init_obj_list[obj.name] = obj init_obj_list[root.name] = root else: # add every children if all are unselected children = _object_utils.get_children(obj) local_reselected_objs = [] for child_obj in children: local_reselected_objs.append(child_obj) # if some child is selected this means we won't reselect nothing in this game object if child_obj.select: local_reselected_objs = [] break for reselected_obj in local_reselected_objs: init_obj_list[reselected_obj.name] = reselected_obj init_obj_list = tuple(init_obj_list.values()) elif export_scope == "scene": init_obj_list = tuple(bpy.context.scene.objects) elif export_scope == 'scenes': init_obj_list = tuple(bpy.data.objects) # check extension for EF format and properly assign it to name suffix ef_name_suffix = "" if _get_scs_globals().export_output_type == "EF": ef_name_suffix = ".ef" try: result = _export.batch_export(self, init_obj_list, name_suffix=ef_name_suffix, menu_filepath=filepath) except Exception as e: result = {"CANCELLED"} context.window.cursor_modal_restore() trace_str = traceback.format_exc().replace("\n", "\n\t ") lprint("E Unexpected %r accured during batch export:\n\t %s", (type(e).__name__, trace_str), report_errors=1, report_warnings=1) return result
def execute(self, context): lprint('D Export From Menu...') from io_scs_tools import exp as _export from io_scs_tools.utils import object as _object_utils filepath = os.path.dirname(self.filepath) # convert it to None, so export will ignore given menu file path and try to export to other none menu set paths if self.filepath == "": filepath = None export_scope = _get_scs_globals().export_scope init_obj_list = {} if export_scope == "selection": for obj in bpy.context.selected_objects: root = _object_utils.get_scs_root(obj) if root: if root != obj: # add only selected children init_obj_list[obj.name] = obj init_obj_list[root.name] = root else: # add every children if all are unselected children = _object_utils.get_children(obj) local_reselected_objs = [] for child_obj in children: local_reselected_objs.append(child_obj) # if some child is selected this means we won't reselect nothing in this game object if child_obj.select: local_reselected_objs = [] break for reselected_obj in local_reselected_objs: init_obj_list[reselected_obj.name] = reselected_obj init_obj_list = tuple(init_obj_list.values()) elif export_scope == "scene": init_obj_list = tuple(bpy.context.scene.objects) elif export_scope == 'scenes': init_obj_list = tuple(bpy.data.objects) try: result = _export.batch_export(self, init_obj_list, menu_filepath=filepath) except Exception as e: result = {"CANCELLED"} context.window.cursor_modal_restore() import traceback traceback.print_exc() lprint("E Unexpected %r accured during batch export, see stack trace above.", (type(e).__name__,), report_errors=1, report_warnings=1) return result
def name_update(self, context): lprint("D SCS Part inventory name update: %s", (self.name, )) # convert name to game engine like name tokenized_name = _name_utils.tokenize_name( self.name, default_name=_PART_consts.default_name) if self.name != tokenized_name: self.name = tokenized_name # always get scs root because we allow editing of parts in any child scs_root_obj = _object_utils.get_scs_root(context.active_object) # if there is more of parts with same name, make postfixed name (this will cause another name update) if len( _inventory.get_indices(scs_root_obj.scs_object_part_inventory, self.name)) == 2: # duplicate i = 1 new_name = _name_utils.tokenize_name(self.name + "_" + str(i).zfill(2)) while _inventory.get_index(scs_root_obj.scs_object_part_inventory, new_name) != -1: new_name = _name_utils.tokenize_name(self.name + "_" + str(i).zfill(2)) i += 1 if new_name != self.name: self.name = new_name if "scs_part_old_name" in self: if scs_root_obj: # fix part name in all children of current root children = _object_utils.get_children(scs_root_obj) for child in children: # fix part name in child with existing old name if child.scs_props.scs_part == self["scs_part_old_name"]: child.scs_props.scs_part = self.name # rename parts in all variants also variant_inventory = scs_root_obj.scs_object_variant_inventory for variant in variant_inventory: for part in variant.parts: if part.name == self["scs_part_old_name"]: part.name = self.name break # backup current name for checking children on next renaming self["scs_part_old_name"] = self.name
def execute(self, context): lprint('D Export From Menu...') from io_scs_tools import exp as _export from io_scs_tools.utils import object as _object_utils filepath = os.path.dirname(self.filepath) export_type = _get_scs_globals().content_type init_obj_list = {} if export_type == "selection": for obj in bpy.context.selected_objects: root = _object_utils.get_scs_root(obj) if root: if root != obj: # add only selected children init_obj_list[obj.name] = obj init_obj_list[root.name] = root else: # add every children if all are unselected children = _object_utils.get_children(obj) local_reselected_objs = [] for child_obj in children: local_reselected_objs.append(child_obj) # if some child is selected this means we won't reselect nothing in this game object if child_obj.select: local_reselected_objs = [] break for reselected_obj in local_reselected_objs: init_obj_list[reselected_obj.name] = reselected_obj init_obj_list = tuple(init_obj_list.values()) elif export_type == "scene": init_obj_list = tuple(bpy.context.scene.objects) elif export_type == 'scenes': init_obj_list = tuple(bpy.data.objects) try: result = _export.batch_export(self, init_obj_list, export_type != "selection", filepath) except Exception as e: result = {"CANCELLED"} context.window.cursor_modal_restore() import traceback traceback.print_exc() lprint( "E Unexpected %r accured during batch export, see stack trace above.", (type(e).__name__, ), report_errors=1, report_warnings=1) return result
def active_scs_animation_update(self, context): """Update function for Active SCS Animation record on Objects. :param context: Blender Context :type context: bpy.types.Context :rtype: None """ active_object = context.active_object scs_root_object = _object_utils.get_scs_root(active_object) scene = context.scene # GET ARMATURE OBJECT armature = None if active_object.type == 'ARMATURE': armature = active_object else: children = _object_utils.get_children(scs_root_object) for child in children: if child.type == 'ARMATURE': armature = child break scs_object_anim_inventory = scs_root_object.scs_object_animation_inventory active_scs_anim_i = self.active_scs_animation if len(scs_object_anim_inventory) > active_scs_anim_i: active_scs_anim = scs_object_anim_inventory[active_scs_anim_i] start_frame = active_scs_anim.anim_start end_frame = active_scs_anim.anim_end length = active_scs_anim.length # set frame range properly _animation_utils.set_frame_range(scene, start_frame, end_frame) # set action to armature end properly set preview fps action = None if active_scs_anim.action in bpy.data.actions: action = bpy.data.actions[active_scs_anim.action] _animation_utils.set_fps_for_preview(scene, length, start_frame, end_frame) # ensure animation data block to be able to set action if armature.animation_data is None: armature.animation_data_create() armature.animation_data.action = action # set/reset action of current animation else: print('Wrong Animation index %i/%i!' % (active_scs_anim_i, len(scs_object_anim_inventory))) return None
def name_update(self, context): lprint("D SCS Part inventory name update: %s", (self.name,)) # convert name to game engine like name tokenized_name = _name_utils.tokenize_name(self.name, default_name=_PART_consts.default_name) if self.name != tokenized_name: self.name = tokenized_name # always get scs root because we allow editing of parts in any child scs_root_obj = _object_utils.get_scs_root(context.active_object) # if there is more of parts with same name, make postfixed name (this will cause another name update) if len(_inventory.get_indices(scs_root_obj.scs_object_part_inventory, self.name)) == 2: # duplicate i = 1 new_name = _name_utils.tokenize_name(self.name + "_" + str(i).zfill(2)) while _inventory.get_index(scs_root_obj.scs_object_part_inventory, new_name) != -1: new_name = _name_utils.tokenize_name(self.name + "_" + str(i).zfill(2)) i += 1 if new_name != self.name: self.name = new_name if "scs_part_old_name" in self: if scs_root_obj: # fix part name in all children of current root children = _object_utils.get_children(scs_root_obj) for child in children: # fix part name in child with existing old name if child.scs_props.scs_part == self["scs_part_old_name"]: child.scs_props.scs_part = self.name # rename parts in all variants also variant_inventory = scs_root_obj.scs_object_variant_inventory for variant in variant_inventory: for part in variant.parts: if part.name == self["scs_part_old_name"]: part.name = self.name break # backup current name for checking children on next renaming self["scs_part_old_name"] = self.name
def get_objects_for_export(self): """Get objects for export, list filtered and extended depending on export scope. :return: list of objects to export calculated from selection :rtype: list[bpy.types.Object] """ # if cached, just return if self.cached_objects: return self.cached_objects objs_to_export = [] export_scope = _get_scs_globals().export_scope if export_scope == "selection": for root in _object_utils.gather_scs_roots( bpy.context.selected_objects): objs_to_export.append(root) children = _object_utils.get_children(root) children_unselected = [] children_selected = [] for child_obj in children: if child_obj.select_get(): children_selected.append(child_obj) elif child_obj.users_scene: # unlinked objects shouldn't be exported children_unselected.append(child_obj) # if any children was selected make sure, to export only them if len(children_selected) > 0: objs_to_export.extend(children_selected) else: objs_to_export.extend(children_unselected) elif export_scope == "scene": objs_to_export = tuple(bpy.context.scene.objects) elif export_scope == "scenes": scenes_objs = set() for scene in bpy.data.scenes: scenes_objs.update(scene.objects) objs_to_export = tuple(scenes_objs) # cache filtered list, to be able to retrive it quickly on second call self.cached_objects = objs_to_export return self.cached_objects
def get_objects(context): if context.scene.scs_props.visibility_tools_scope == "Global": objects = context.scene.objects else: scs_root_object = _object_utils.get_scs_root(context.scene.objects.active) if scs_root_object: objects = _object_utils.get_children(scs_root_object) scs_root_object.hide = False scs_root_object.select = True bpy.context.scene.objects.active = scs_root_object else: # fallback don't do anything objects = [] return objects
def get_objects(context): if context.workspace.scs_props.visibility_tools_scope == "Global": objects = context.scene.objects else: scs_root_object = _object_utils.get_scs_root( context.view_layer.objects.active) if scs_root_object: objects = _object_utils.get_children(scs_root_object) _object_utils.hide_set(scs_root_object, False) _object_utils.select_set(scs_root_object, True) bpy.context.view_layer.objects.active = scs_root_object else: # fallback don't do anything objects = [] return objects
def get_objects(context): if context.scene.scs_props.visibility_tools_scope == "Global": objects = context.scene.objects else: scs_root_object = _object_utils.get_scs_root( context.scene.objects.active) if scs_root_object: objects = _object_utils.get_children(scs_root_object) scs_root_object.hide = False scs_root_object.select = True bpy.context.scene.objects.active = scs_root_object else: # fallback don't do anything objects = [] return objects
def __collect_materials__(root_obj): """Collect all materials on given SCS root object. :param root_obj: scs root object on which material collection will be executed :type root_obj: bpy.types.Object :return: list of materials used on objects of given SCS game object :rtype: list of bpy.types.Material """ from io_scs_tools.utils import object as _object collected_mats = {} children = _object.get_children(root_obj) for child in children: for slot in child.material_slots: if slot.material and slot.material.name not in collected_mats: collected_mats[slot.material.name] = slot.material return collected_mats.values()
def __init__(self): """Shows all layer to be able to alter selection on the whole scene and alter Blender selection the way that: 1. if only child within root is selected -> selects root too 2. if only root is selected -> select all children 3. if root and some children are selected -> don't change selection """ self.layers_visibilities = _view3d_utils.switch_layers_visibility( [], True) self.last_active_obj = bpy.context.active_object self.altered_objs = [] self.altered_objs_visibilities = [] self.not_root_objs = [] for obj in bpy.context.selected_objects: root = _object_utils.get_scs_root(obj) if root: if root != obj: if not root.select: root.select = True self.altered_objs.append(root.name) else: children = _object_utils.get_children(obj) local_reselected_objs = [] for child_obj in children: local_reselected_objs.append(child_obj.name) # if some child is selected this means we won't reselect nothing in this game objecdt if child_obj.select: local_reselected_objs = [] break self.altered_objs.extend(local_reselected_objs) else: obj.select = False self.not_root_objs.append(obj.name) for obj_name in self.altered_objs: self.altered_objs_visibilities.append( bpy.data.objects[obj_name].hide) bpy.data.objects[obj_name].hide = False bpy.data.objects[obj_name].select = True
def __init__(self): """Shows all layer to be able to alter selection on the whole scene and alter Blender selection the way that: 1. if only child within root is selected -> selects root too 2. if only root is selected -> select all children 3. if root and some children are selected -> don't change selection """ self.layers_visibilities = _view3d_utils.switch_layers_visibility([], True) self.last_active_obj = bpy.context.active_object self.altered_objs = [] self.altered_objs_visibilities = [] self.not_root_objs = [] for obj in bpy.context.selected_objects: root = _object_utils.get_scs_root(obj) if root: if root != obj: if not root.select: root.select = True self.altered_objs.append(root.name) else: children = _object_utils.get_children(obj) local_reselected_objs = [] for child_obj in children: local_reselected_objs.append(child_obj.name) # if some child is selected this means we won't reselect nothing in this game objecdt if child_obj.select: local_reselected_objs = [] break self.altered_objs.extend(local_reselected_objs) else: obj.select = False self.not_root_objs.append(obj.name) for obj_name in self.altered_objs: self.altered_objs_visibilities.append(bpy.data.objects[obj_name].hide) bpy.data.objects[obj_name].hide = False bpy.data.objects[obj_name].select = True
def active_scs_animation_update(self, context): """Update function for Active SCS Animation record on Objects. :param context: Blender Context :type context: bpy.types.Context :rtype: None """ active_object = context.active_object scs_root_object = _object_utils.get_scs_root(active_object) scene = context.scene # GET ARMATURE OBJECT armature = None if active_object.type == 'ARMATURE': armature = active_object else: children = _object_utils.get_children(scs_root_object) for child in children: if child.type == 'ARMATURE': armature = child break scs_object_animation_inventory = scs_root_object.scs_object_animation_inventory active_scs_animation = self.active_scs_animation if len(scs_object_animation_inventory) > active_scs_animation: active_animation = scs_object_animation_inventory[active_scs_animation] animation_name = active_animation.name print('Animation changed to %r [%i].' % (animation_name, active_scs_animation)) # SET ACTION STRING action = armature.animation_data.action action_names = [] for act in bpy.data.actions: action_names.append(act.name) if animation_name in action_names: action = bpy.data.actions[animation_name] armature.animation_data.action = action active_object.data.scs_props.current_action = action.name # SET PREVIEW RANGE scene.use_preview_range = True print( 'CAUTION! --- DELAYED START UPDATE ISSUE --- (see the code)') # FIXME: If the start value is other than zero, # it gets only properly updated the second time an "SCS Animation" is hit in the list. For the first time it mysteriously # always gets the old 'anim_end' value. Test is on "multiple_animations_from_one_action.blend" file. print('scene.frame_preview_start:\t%i' % scene.frame_preview_start) print('active_animation.anim_start:\t\t%i' % active_animation.anim_start) start_frame = active_animation.anim_start scene.frame_preview_start = start_frame print('scene.frame_preview_start:\t%i' % scene.frame_preview_start) end_frame = active_animation.anim_end scene.frame_preview_end = end_frame # frame_range = action.frame_range # set_fps(scene, action, frame_range) # set_fps(scene, action, (active_animation.anim_start, active_animation.anim_end)) length = active_animation.length anim_export_step = action.scs_props.anim_export_step _animation_utils.set_fps_for_preview(scene, length, anim_export_step, start_frame, end_frame) else: print('Wrong Animation index %i/%i!' % (active_scs_animation, len(scs_object_animation_inventory))) return None
def active_scs_animation_update(self, context): """Update function for Active SCS Animation record on Objects. :param context: Blender Context :type context: bpy.types.Context :rtype: None """ active_object = context.active_object scs_root_object = _object_utils.get_scs_root(active_object) scene = context.scene # GET ARMATURE OBJECT armature = None if active_object.type == 'ARMATURE': armature = active_object else: children = _object_utils.get_children(scs_root_object) for child in children: if child.type == 'ARMATURE': armature = child break scs_object_animation_inventory = scs_root_object.scs_object_animation_inventory active_scs_animation = self.active_scs_animation if len(scs_object_animation_inventory) > active_scs_animation: active_animation = scs_object_animation_inventory[ active_scs_animation] animation_name = active_animation.name print('Animation changed to %r [%i].' % (animation_name, active_scs_animation)) # SET ACTION STRING action = armature.animation_data.action action_names = [] for act in bpy.data.actions: action_names.append(act.name) if animation_name in action_names: action = bpy.data.actions[animation_name] armature.animation_data.action = action active_object.data.scs_props.current_action = action.name # SET PREVIEW RANGE scene.use_preview_range = True print('CAUTION! --- DELAYED START UPDATE ISSUE --- (see the code)' ) # FIXME: If the start value is other than zero, # it gets only properly updated the second time an "SCS Animation" is hit in the list. For the first time it mysteriously # always gets the old 'anim_end' value. Test is on "multiple_animations_from_one_action.blend" file. print('scene.frame_preview_start:\t%i' % scene.frame_preview_start) print('active_animation.anim_start:\t\t%i' % active_animation.anim_start) start_frame = active_animation.anim_start scene.frame_preview_start = start_frame print('scene.frame_preview_start:\t%i' % scene.frame_preview_start) end_frame = active_animation.anim_end scene.frame_preview_end = end_frame # frame_range = action.frame_range # set_fps(scene, action, frame_range) # set_fps(scene, action, (active_animation.anim_start, active_animation.anim_end)) length = active_animation.length anim_export_step = action.scs_props.anim_export_step _animation_utils.set_fps_for_preview(scene, length, anim_export_step, start_frame, end_frame) else: print('Wrong Animation index %i/%i!' % (active_scs_animation, len(scs_object_animation_inventory))) return None