From d9ffde707fe559f2cbfefb39b75f4decb42aa0a1 Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Fri, 24 May 2019 10:07:02 +1000 Subject: space_view3d_stored_views: move to contrib: T63750 --- space_view3d_stored_views/__init__.py | 138 ------------ space_view3d_stored_views/core.py | 369 -------------------------------- space_view3d_stored_views/io.py | 329 ---------------------------- space_view3d_stored_views/operators.py | 164 -------------- space_view3d_stored_views/properties.py | 120 ----------- space_view3d_stored_views/ui.py | 263 ----------------------- 6 files changed, 1383 deletions(-) delete mode 100644 space_view3d_stored_views/__init__.py delete mode 100644 space_view3d_stored_views/core.py delete mode 100644 space_view3d_stored_views/io.py delete mode 100644 space_view3d_stored_views/operators.py delete mode 100644 space_view3d_stored_views/properties.py delete mode 100644 space_view3d_stored_views/ui.py (limited to 'space_view3d_stored_views') diff --git a/space_view3d_stored_views/__init__.py b/space_view3d_stored_views/__init__.py deleted file mode 100644 index aae9add7..00000000 --- a/space_view3d_stored_views/__init__.py +++ /dev/null @@ -1,138 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -bl_info = { - "name": "Stored Views", - "description": "Save and restore User defined views, pov, layers and display configs", - "author": "nfloyd, Francesco Siddi", - "version": (0, 3, 7), - "blender": (2, 78, 0), - "location": "View3D > Properties > Stored Views", - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.5/" - "Py/Scripts/3D_interaction/stored_views", - "category": "3D View" -} - -""" -ACKNOWLEDGMENT -============== -import/export functionality is mostly based -on Bart Crouch's Theme Manager Addon - -TODO: quadview complete support : investigate. Where's the data? -TODO: lock_camera_and_layers. investigate usage -TODO: list reordering - -NOTE: logging setup has to be provided by the user in a separate config file - as Blender will not try to configure logging by default in an add-on - The Config File should be in the Blender Config folder > /scripts/startup/config_logging.py - For setting up /location of the config folder see: - https://docs.blender.org/manual/en/dev/getting_started/ - installing/configuration/directories.html - For configuring logging itself in the file, general Python documentation should work - As the logging calls are not configured, they can be kept in the other modules of this add-on - and will not have output until the logging configuration is set up -""" - -if "bpy" in locals(): - import importlib - importlib.reload(core) - importlib.reload(ui) - importlib.reload(properties) - importlib.reload(operators) - importlib.reload(io) -else: - from . import core - from . import ui - from . import properties - from . import operators - from . import io - -import bpy -from bpy.props import ( - BoolProperty, - IntProperty, - PointerProperty, -) -from bpy.types import ( - AddonPreferences, - Operator, -) - - -class VIEW3D_stored_views_initialize(Operator): - bl_idname = "view3d.stored_views_initialize" - bl_label = "Initialize" - - @classmethod - def poll(cls, context): - return not hasattr(bpy.types.Scene, 'stored_views') - - def execute(self, context): - bpy.types.Scene.stored_views = PointerProperty( - type=properties.StoredViewsData - ) - scenes = bpy.data.scenes - for scene in scenes: - core.DataStore.sanitize_data(scene) - return {'FINISHED'} - - -# Addon Preferences - -class VIEW3D_stored_views_preferences(AddonPreferences): - bl_idname = __name__ - - show_exporters: BoolProperty( - name="Enable I/O Operators", - default=False, - description="Enable Import/Export Operations in the UI:\n" - "Import Stored Views preset,\n" - "Export Stored Views preset and \n" - "Import stored views from scene", - ) - view_3d_update_rate: IntProperty( - name="3D view update", - description="Update rate of the 3D view redraw\n" - "Increse the value if the UI feels sluggish", - min=1, max=10, - default=1 - ) - - def draw(self, context): - layout = self.layout - - row = layout.row(align=True) - row.prop(self, "view_3d_update_rate", toggle=True) - row.prop(self, "show_exporters", toggle=True) - - -def register(): - bpy.utils.register_module(__name__) - - -def unregister(): - ui.VIEW3D_stored_views_draw.handle_remove(bpy.context) - bpy.utils.unregister_module(__name__) - if hasattr(bpy.types.Scene, "stored_views"): - del bpy.types.Scene.stored_views - - -if __name__ == "__main__": - register() diff --git a/space_view3d_stored_views/core.py b/space_view3d_stored_views/core.py deleted file mode 100644 index d7fb72b8..00000000 --- a/space_view3d_stored_views/core.py +++ /dev/null @@ -1,369 +0,0 @@ -# gpl authors: nfloyd, Francesco Siddi - - -import logging -module_logger = logging.getLogger(__name__) - -import hashlib -import bpy - - -# Utility function get preferences setting for exporters -def get_preferences(): - # replace the key if the add-on name changes - addon = bpy.context.preferences.addons[__package__] - show_warn = (addon.preferences.show_exporters if addon else False) - - return show_warn - - -class StoredView(): - def __init__(self, mode, index=None): - self.logger = logging.getLogger('%s.StoredView' % __name__) - self.scene = bpy.context.scene - self.view3d = bpy.context.space_data - self.index = index - self.data_store = DataStore(mode=mode) - - def save(self): - if self.index == -1: - stored_view, self.index = self.data_store.create() - else: - stored_view = self.data_store.get(self.index) - self.from_v3d(stored_view) - self.logger.debug('index: %s name: %s' % (self.data_store.current_index, stored_view.name)) - - def set(self): - stored_view = self.data_store.get(self.index) - self.update_v3d(stored_view) - self.logger.debug('index: %s name: %s' % (self.data_store.current_index, stored_view.name)) - - def from_v3d(self, stored_view): - raise NotImplementedError("Subclass must implement abstract method") - - def update_v3d(self, stored_view): - raise NotImplementedError("Subclass must implement abstract method") - - @staticmethod - def is_modified(context, stored_view): - raise NotImplementedError("Subclass must implement abstract method") - - -class POV(StoredView): - def __init__(self, index=None): - super().__init__(mode='POV', index=index) - self.logger = logging.getLogger('%s.POV' % __name__) - - def from_v3d(self, stored_view): - view3d = self.view3d - region3d = view3d.region_3d - - stored_view.distance = region3d.view_distance - stored_view.location = region3d.view_location - stored_view.rotation = region3d.view_rotation - stored_view.perspective_matrix_md5 = POV._get_perspective_matrix_md5(region3d) - stored_view.perspective = region3d.view_perspective - stored_view.lens = view3d.lens - stored_view.clip_start = view3d.clip_start - stored_view.clip_end = view3d.clip_end - - if region3d.view_perspective == 'CAMERA': - stored_view.camera_type = view3d.camera.type # type : 'CAMERA' or 'MESH' - stored_view.camera_name = view3d.camera.name # store string instead of object - if view3d.lock_object is not None: - stored_view.lock_object_name = view3d.lock_object.name # idem - else: - stored_view.lock_object_name = "" - stored_view.lock_cursor = view3d.lock_cursor - stored_view.cursor_location = view3d.cursor_location - - def update_v3d(self, stored_view): - view3d = self.view3d - region3d = view3d.region_3d - region3d.view_distance = stored_view.distance - region3d.view_location = stored_view.location - region3d.view_rotation = stored_view.rotation - region3d.view_perspective = stored_view.perspective - view3d.lens = stored_view.lens - view3d.clip_start = stored_view.clip_start - view3d.clip_end = stored_view.clip_end - view3d.lock_cursor = stored_view.lock_cursor - if stored_view.lock_cursor is True: - # update cursor only if view is locked to cursor - view3d.cursor_location = stored_view.cursor_location - - if stored_view.perspective == "CAMERA": - - lock_obj = self._get_object(stored_view.lock_object_name) - if lock_obj: - view3d.lock_object = lock_obj - else: - cam = self._get_object(stored_view.camera_name) - if cam: - view3d.camera = cam - - @staticmethod - def _get_object(name, pointer=None): - return bpy.data.objects.get(name) - - @staticmethod - def is_modified(context, stored_view): - # TODO: check for others param, currently only perspective - # and perspective_matrix are checked - POV.logger = logging.getLogger('%s.POV' % __name__) - view3d = context.space_data - region3d = view3d.region_3d - if region3d.view_perspective != stored_view.perspective: - POV.logger.debug('view_perspective') - return True - - md5 = POV._get_perspective_matrix_md5(region3d) - if (md5 != stored_view.perspective_matrix_md5 and - region3d.view_perspective != "CAMERA"): - POV.logger.debug('perspective_matrix') - return True - - return False - - @staticmethod - def _get_perspective_matrix_md5(region3d): - md5 = hashlib.md5(str(region3d.perspective_matrix).encode('utf-8')).hexdigest() - return md5 - - -class Layers(StoredView): - def __init__(self, index=None): - super().__init__(mode='LAYERS', index=index) - self.logger = logging.getLogger('%s.Layers' % __name__) - - def from_v3d(self, stored_view): - view3d = self.view3d - stored_view.view_layers = view3d.layers - stored_view.scene_layers = self.scene.layers - stored_view.lock_camera_and_layers = view3d.lock_camera_and_layers - - def update_v3d(self, stored_view): - view3d = self.view3d - view3d.lock_camera_and_layers = stored_view.lock_camera_and_layers - if stored_view.lock_camera_and_layers is True: - self.scene.layers = stored_view.scene_layers - else: - view3d.layers = stored_view.view_layers - - @staticmethod - def is_modified(context, stored_view): - Layers.logger = logging.getLogger('%s.Layers' % __name__) - if stored_view.lock_camera_and_layers != context.space_data.lock_camera_and_layers: - Layers.logger.debug('lock_camera_and_layers') - return True - if stored_view.lock_camera_and_layers is True: - for i in range(20): - if stored_view.scene_layers[i] != context.scene.layers[i]: - Layers.logger.debug('scene_layers[%s]' % (i, )) - return True - else: - for i in range(20): - if stored_view.view_layers[i] != context.space_data.view3d.layers[i]: - return True - return False - - -class Display(StoredView): - def __init__(self, index=None): - super().__init__(mode='DISPLAY', index=index) - self.logger = logging.getLogger('%s.Display' % __name__) - - def from_v3d(self, stored_view): - view3d = self.view3d - stored_view.viewport_shade = view3d.viewport_shade - stored_view.show_only_render = view3d.show_only_render - stored_view.show_outline_selected = view3d.show_outline_selected - stored_view.show_all_objects_origin = view3d.show_all_objects_origin - stored_view.show_relationship_lines = view3d.show_relationship_lines - stored_view.show_floor = view3d.show_floor - stored_view.show_axis_x = view3d.show_axis_x - stored_view.show_axis_y = view3d.show_axis_y - stored_view.show_axis_z = view3d.show_axis_z - stored_view.grid_lines = view3d.grid_lines - stored_view.grid_scale = view3d.grid_scale - stored_view.grid_subdivisions = view3d.grid_subdivisions - stored_view.material_mode = self.scene.game_settings.material_mode - stored_view.show_textured_solid = view3d.show_textured_solid - - def update_v3d(self, stored_view): - view3d = self.view3d - view3d.viewport_shade = stored_view.viewport_shade - view3d.show_only_render = stored_view.show_only_render - view3d.show_outline_selected = stored_view.show_outline_selected - view3d.show_all_objects_origin = stored_view.show_all_objects_origin - view3d.show_relationship_lines = stored_view.show_relationship_lines - view3d.show_floor = stored_view.show_floor - view3d.show_axis_x = stored_view.show_axis_x - view3d.show_axis_y = stored_view.show_axis_y - view3d.show_axis_z = stored_view.show_axis_z - view3d.grid_lines = stored_view.grid_lines - view3d.grid_scale = stored_view.grid_scale - view3d.grid_subdivisions = stored_view.grid_subdivisions - self.scene.game_settings.material_mode = stored_view.material_mode - view3d.show_textured_solid = stored_view.show_textured_solid - - @staticmethod - def is_modified(context, stored_view): - Display.logger = logging.getLogger('%s.Display' % __name__) - view3d = context.space_data - excludes = ["material_mode", "quad_view", "lock_rotation", "show_sync_view", "use_box_clip", "name"] - for k, v in stored_view.items(): - if k not in excludes: - if getattr(view3d, k) != getattr(stored_view, k): - return True - - if stored_view.material_mode != context.scene.game_settings.material_mode: - Display.logger.debug('material_mode') - return True - - -class View(StoredView): - def __init__(self, index=None): - super().__init__(mode='VIEW', index=index) - self.logger = logging.getLogger('%s.View' % __name__) - self.pov = POV() - self.layers = Layers() - self.display = Display() - - def from_v3d(self, stored_view): - self.pov.from_v3d(stored_view.pov) - self.layers.from_v3d(stored_view.layers) - self.display.from_v3d(stored_view.display) - - def update_v3d(self, stored_view): - self.pov.update_v3d(stored_view.pov) - self.layers.update_v3d(stored_view.layers) - self.display.update_v3d(stored_view.display) - - @staticmethod - def is_modified(context, stored_view): - if POV.is_modified(context, stored_view.pov) or \ - Layers.is_modified(context, stored_view.layers) or \ - Display.is_modified(context, stored_view.display): - return True - return False - - -class DataStore(): - def __init__(self, scene=None, mode=None): - if scene is None: - scene = bpy.context.scene - stored_views = scene.stored_views - self.mode = mode - - if mode is None: - self.mode = stored_views.mode - - if self.mode == 'VIEW': - self.list = stored_views.view_list - self.current_index = stored_views.current_indices[0] - elif self.mode == 'POV': - self.list = stored_views.pov_list - self.current_index = stored_views.current_indices[1] - elif self.mode == 'LAYERS': - self.list = stored_views.layers_list - self.current_index = stored_views.current_indices[2] - elif self.mode == 'DISPLAY': - self.list = stored_views.display_list - self.current_index = stored_views.current_indices[3] - - def create(self): - item = self.list.add() - item.name = self._generate_name() - index = len(self.list) - 1 - self._set_current_index(index) - return item, index - - def get(self, index): - self._set_current_index(index) - return self.list[index] - - def delete(self, index): - if self.current_index > index: - self._set_current_index(self.current_index - 1) - elif self.current_index == index: - self._set_current_index(-1) - - self.list.remove(index) - - def _set_current_index(self, index): - self.current_index = index - mode = self.mode - stored_views = bpy.context.scene.stored_views - if mode == 'VIEW': - stored_views.current_indices[0] = index - elif mode == 'POV': - stored_views.current_indices[1] = index - elif mode == 'LAYERS': - stored_views.current_indices[2] = index - elif mode == 'DISPLAY': - stored_views.current_indices[3] = index - - def _generate_name(self): - default_name = str(self.mode) - names = [] - for i in self.list: - i_name = i.name - if i_name.startswith(default_name): - names.append(i_name) - names.sort() - try: - l_name = names[-1] - post_fix = l_name.rpartition('.')[2] - if post_fix.isnumeric(): - post_fix = str(int(post_fix) + 1).zfill(3) - else: - if post_fix == default_name: - post_fix = "001" - return default_name + "." + post_fix - except: - return default_name - - @staticmethod - def sanitize_data(scene): - - def check_objects_references(mode, list): - to_remove = [] - for i, list_item in enumerate(list.items()): - key, item = list_item - if mode == 'POV' or mode == 'VIEWS': - if mode == 'VIEWS': - item = item.pov - - if item.perspective == "CAMERA": - - camera = bpy.data.objects.get(item.camera_name) - if camera is None: - try: # pick a default camera TODO: ask to pick? - camera = bpy.data.cameras[0] - item.camera_name = camera.name - except: # couldn't find a camera in the scene - pass - - obj = bpy.data.objects.get(item.lock_object_name) - if obj is None and camera is None: - to_remove.append(i) - - for i in reversed(to_remove): - list.remove(i) - - modes = ['POV', 'VIEW', 'DISPLAY', 'LAYERS'] - for mode in modes: - data = DataStore(scene=scene, mode=mode) - check_objects_references(mode, data.list) - - -def stored_view_factory(mode, *args, **kwargs): - if mode == 'POV': - return POV(*args, **kwargs) - elif mode == 'LAYERS': - return Layers(*args, **kwargs) - elif mode == 'DISPLAY': - return Display(*args, **kwargs) - elif mode == 'VIEW': - return View(*args, **kwargs) diff --git a/space_view3d_stored_views/io.py b/space_view3d_stored_views/io.py deleted file mode 100644 index a3125fcc..00000000 --- a/space_view3d_stored_views/io.py +++ /dev/null @@ -1,329 +0,0 @@ -# gpl authors: nfloyd, Francesco Siddi - -import gzip -import os -import pickle -import shutil - -import bpy -from bpy.types import Operator -from bpy.props import ( - BoolProperty, - StringProperty, -) -from bpy_extras.io_utils import ( - ExportHelper, - ImportHelper, -) -from . import bl_info -from .core import get_preferences -from .operators import DataStore - - -# TODO: reinstate filters? -class IO_Utils(): - - @staticmethod - def get_preset_path(): - # locate stored_views preset folder - paths = bpy.utils.preset_paths("stored_views") - if not paths: - # stored_views preset folder doesn't exist, so create it - paths = [os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets", - "stored_views")] - if not os.path.exists(paths[0]): - os.makedirs(paths[0]) - - return(paths) - - @staticmethod - def stored_views_apply_from_scene(scene_name, replace=True): - scene = bpy.context.scene - scene_exists = True if scene_name in bpy.data.scenes.keys() else False - - if scene_exists: - sv = bpy.context.scene.stored_views - # io_filters = sv.settings.io_filters - - structs = [sv.view_list, sv.pov_list, sv.layers_list, sv.display_list] - if replace is True: - for st in structs: # clear swap and list - while len(st) > 0: - st.remove(0) - - f_sv = bpy.data.scenes[scene_name].stored_views - # f_sv = bpy.data.scenes[scene_name].stored_views - f_structs = [f_sv.view_list, f_sv.pov_list, f_sv.layers_list, f_sv.display_list] - """ - is_filtered = [io_filters.views, io_filters.point_of_views, - io_filters.layers, io_filters.displays] - """ - for i in range(len(f_structs)): - """ - if is_filtered[i] is False: - continue - """ - for j in f_structs[i]: - item = structs[i].add() - # stored_views_copy_item(j, item) - for k, v in j.items(): - item[k] = v - DataStore.sanitize_data(scene) - return True - else: - return False - - @staticmethod - def stored_views_export_to_blsv(filepath, name='Custom Preset'): - # create dictionary with all information - dump = {"info": {}, "data": {}} - dump["info"]["script"] = bl_info['name'] - dump["info"]["script_version"] = bl_info['version'] - dump["info"]["version"] = bpy.app.version - dump["info"]["preset_name"] = name - - # get current stored views settings - scene = bpy.context.scene - sv = scene.stored_views - - def dump_view_list(dict, list): - if str(type(list)) == "": - for i, struct_dict in enumerate(list): - dict[i] = {"name": str, - "pov": {}, - "layers": {}, - "display": {}} - dict[i]["name"] = struct_dict.name - dump_item(dict[i]["pov"], struct_dict.pov) - dump_item(dict[i]["layers"], struct_dict.layers) - dump_item(dict[i]["display"], struct_dict.display) - - def dump_list(dict, list): - if str(type(list)) == "": - for i, struct in enumerate(list): - dict[i] = {} - dump_item(dict[i], struct) - - def dump_item(dict, struct): - for prop in struct.bl_rna.properties: - if prop.identifier == "rna_type": - # not a setting, so skip - continue - - val = getattr(struct, prop.identifier) - if str(type(val)) in [""]: - # array - dict[prop.identifier] = [v for v in val] - # address the pickle limitations of dealing with the Vector class - elif str(type(val)) in ["", - ""]: - dict[prop.identifier] = [v for v in val] - else: - # single value - dict[prop.identifier] = val - - # io_filters = sv.settings.io_filters - dump["data"] = {"point_of_views": {}, - "layers": {}, - "displays": {}, - "views": {}} - - others_data = [(dump["data"]["point_of_views"], sv.pov_list), # , io_filters.point_of_views), - (dump["data"]["layers"], sv.layers_list), # , io_filters.layers), - (dump["data"]["displays"], sv.display_list)] # , io_filters.displays)] - for list_data in others_data: - # if list_data[2] is True: - dump_list(list_data[0], list_data[1]) - - views_data = (dump["data"]["views"], sv.view_list) - # if io_filters.views is True: - dump_view_list(views_data[0], views_data[1]) - - # save to file - filepath = filepath - filepath = bpy.path.ensure_ext(filepath, '.blsv') - file = gzip.open(filepath, mode='wb') - pickle.dump(dump, file, protocol=pickle.HIGHEST_PROTOCOL) - file.close() - - @staticmethod - def stored_views_apply_preset(filepath, replace=True): - if not filepath: - return False - - file = gzip.open(filepath, mode='rb') - dump = pickle.load(file) - file.close() - # apply preset - scene = bpy.context.scene - sv = getattr(scene, "stored_views", None) - - if not sv: - return False - - # io_filters = sv.settings.io_filters - sv_data = { - "point_of_views": sv.pov_list, - "views": sv.view_list, - "layers": sv.layers_list, - "displays": sv.display_list - } - for sv_struct, props in dump["data"].items(): - """ - is_filtered = getattr(io_filters, sv_struct) - if is_filtered is False: - continue - """ - sv_list = sv_data[sv_struct] # .list - if replace is True: # clear swap and list - while len(sv_list) > 0: - sv_list.remove(0) - for key, prop_struct in props.items(): - sv_item = sv_list.add() - - for subprop, subval in prop_struct.items(): - if isinstance(subval, dict): # views : pov, layers, displays - v_subprop = getattr(sv_item, subprop) - for v_subkey, v_subval in subval.items(): - if isinstance(v_subval, list): # array like of pov,... - v_array_like = getattr(v_subprop, v_subkey) - for i in range(len(v_array_like)): - v_array_like[i] = v_subval[i] - else: - setattr(v_subprop, v_subkey, v_subval) # others - elif isinstance(subval, list): - array_like = getattr(sv_item, subprop) - for i in range(len(array_like)): - array_like[i] = subval[i] - else: - setattr(sv_item, subprop, subval) - - DataStore.sanitize_data(scene) - - return True - - -class VIEW3D_stored_views_import(Operator, ImportHelper): - bl_idname = "stored_views.import_blsv" - bl_label = "Import Stored Views preset" - bl_description = "Import a .blsv preset file to the current Stored Views" - - filename_ext = ".blsv" - filter_glob: StringProperty( - default="*.blsv", - options={'HIDDEN'} - ) - replace: BoolProperty( - name="Replace", - default=True, - description="Replace current stored views, otherwise append" - ) - - @classmethod - def poll(cls, context): - return get_preferences() - - def execute(self, context): - # the usual way is to not select the file in the file browser - exists = os.path.isfile(self.filepath) if self.filepath else False - if not exists: - self.report({'WARNING'}, - "No filepath specified or file could not be found. Operation Cancelled") - return {'CANCELLED'} - - # apply chosen preset - apply_preset = IO_Utils.stored_views_apply_preset( - filepath=self.filepath, replace=self.replace - ) - if not apply_preset: - self.report({'WARNING'}, - "Please Initialize Stored Views first (in the 3D View Properties Area)") - return {'CANCELLED'} - - # copy preset to presets folder - filename = os.path.basename(self.filepath) - try: - shutil.copyfile(self.filepath, - os.path.join(IO_Utils.get_preset_path()[0], filename)) - except: - self.report({'WARNING'}, - "Stored Views: preset applied, but installing failed (preset already exists?)") - return{'CANCELLED'} - - return{'FINISHED'} - - -class VIEW3D_stored_views_import_from_scene(Operator): - bl_idname = "stored_views.import_from_scene" - bl_label = "Import stored views from scene" - bl_description = "Import currently stored views from an another scene" - - scene_name: StringProperty( - name="Scene Name", - description="A current blend scene", - default="" - ) - replace: BoolProperty( - name="Replace", - default=True, - description="Replace current stored views, otherwise append" - ) - - @classmethod - def poll(cls, context): - return get_preferences() - - def draw(self, context): - layout = self.layout - - layout.prop_search(self, "scene_name", bpy.data, "scenes") - layout.prop(self, "replace") - - def invoke(self, context, event): - return context.window_manager.invoke_props_dialog(self) - - def execute(self, context): - # filepath should always be given - if not self.scene_name: - self.report({"WARNING"}, - "No scene name was given. Operation Cancelled") - return{'CANCELLED'} - - is_finished = IO_Utils.stored_views_apply_from_scene( - self.scene_name, replace=self.replace - ) - if not is_finished: - self.report({"WARNING"}, - "Could not find the specified scene. Operation Cancelled") - return {"CANCELLED"} - - return{'FINISHED'} - - -class VIEW3D_stored_views_export(Operator, ExportHelper): - bl_idname = "stored_views.export_blsv" - bl_label = "Export Stored Views preset" - bl_description = "Export the current Stored Views to a .blsv preset file" - - filename_ext = ".blsv" - filepath: StringProperty( - default=os.path.join(IO_Utils.get_preset_path()[0], "untitled") - ) - filter_glob: StringProperty( - default="*.blsv", - options={'HIDDEN'} - ) - preset_name: StringProperty( - name="Preset name", - default="", - description="Name of the stored views preset" - ) - - @classmethod - def poll(cls, context): - return get_preferences() - - def execute(self, context): - IO_Utils.stored_views_export_to_blsv(self.filepath, self.preset_name) - - return{'FINISHED'} diff --git a/space_view3d_stored_views/operators.py b/space_view3d_stored_views/operators.py deleted file mode 100644 index 5d8a4726..00000000 --- a/space_view3d_stored_views/operators.py +++ /dev/null @@ -1,164 +0,0 @@ -# gpl authors: nfloyd, Francesco Siddi - -import bpy -from bpy.props import IntProperty -from bpy.types import Operator -from .core import ( - stored_view_factory, - DataStore, - ) -from .ui import init_draw - - -class VIEW3D_stored_views_save(Operator): - bl_idname = "stored_views.save" - bl_label = "Save Current" - bl_description = "Save the view 3d current state" - - index: IntProperty() - - def execute(self, context): - mode = context.scene.stored_views.mode - sv = stored_view_factory(mode, self.index) - sv.save() - context.scene.stored_views.view_modified = False - init_draw(context) - - return {'FINISHED'} - - -class VIEW3D_stored_views_set(Operator): - bl_idname = "stored_views.set" - bl_label = "Set" - bl_description = "Update the view 3D according to this view" - - index: IntProperty() - - def execute(self, context): - mode = context.scene.stored_views.mode - sv = stored_view_factory(mode, self.index) - sv.set() - context.scene.stored_views.view_modified = False - init_draw(context) - - return {'FINISHED'} - - -class VIEW3D_stored_views_delete(Operator): - bl_idname = "stored_views.delete" - bl_label = "Delete" - bl_description = "Delete this view" - - index: IntProperty() - - def execute(self, context): - data = DataStore() - data.delete(self.index) - - return {'FINISHED'} - - -class VIEW3D_New_Camera_to_View(Operator): - bl_idname = "stored_views.newcamera" - bl_label = "New Camera To View" - bl_description = "Add a new Active Camera and align it to this view" - - @classmethod - def poll(cls, context): - return ( - context.space_data is not None and - context.space_data.type == 'VIEW_3D' and - context.space_data.region_3d.view_perspective != 'CAMERA' - ) - - def execute(self, context): - - if bpy.ops.object.mode_set.poll(): - bpy.ops.object.mode_set(mode='OBJECT') - - bpy.ops.object.camera_add() - cam = context.active_object - cam.name = "View_Camera" - # make active camera by hand - context.scene.camera = cam - - bpy.ops.view3d.camera_to_view() - return {'FINISHED'} - - -# Camera marker & switcher by Fsiddi -class SetSceneCamera(Operator): - bl_idname = "cameraselector.set_scene_camera" - bl_label = "Set Scene Camera" - bl_description = "Set chosen camera as the scene's active camera" - - hide_others = False - - def execute(self, context): - chosen_camera = context.active_object - scene = context.scene - - if self.hide_others: - for c in [o for o in scene.objects if o.type == 'CAMERA']: - c.hide = (c != chosen_camera) - scene.camera = chosen_camera - bpy.ops.object.select_all(action='DESELECT') - chosen_camera.select_set(True) - return {'FINISHED'} - - def invoke(self, context, event): - if event.ctrl: - self.hide_others = True - - return self.execute(context) - - -class PreviewSceneCamera(Operator): - bl_idname = "cameraselector.preview_scene_camera" - bl_label = "Preview Camera" - bl_description = "Preview chosen camera and make scene's active camera" - - def execute(self, context): - chosen_camera = context.active_object - bpy.ops.view3d.object_as_camera() - bpy.ops.object.select_all(action="DESELECT") - chosen_camera.select_set(True) - return {'FINISHED'} - - -class AddCameraMarker(Operator): - bl_idname = "cameraselector.add_camera_marker" - bl_label = "Add Camera Marker" - bl_description = "Add a timeline marker bound to chosen camera" - - def execute(self, context): - chosen_camera = context.active_object - scene = context.scene - - current_frame = scene.frame_current - marker = None - for m in reversed(sorted(filter(lambda m: m.frame <= current_frame, - scene.timeline_markers), - key=lambda m: m.frame)): - marker = m - break - if marker and (marker.camera == chosen_camera): - # Cancel if the last marker at or immediately before - # current frame is already bound to the camera. - return {'CANCELLED'} - - marker_name = "F_%02d_%s" % (current_frame, chosen_camera.name) - if marker and (marker.frame == current_frame): - # Reuse existing marker at current frame to avoid - # overlapping bound markers. - marker.name = marker_name - else: - marker = scene.timeline_markers.new(marker_name) - marker.frame = scene.frame_current - marker.camera = chosen_camera - marker.select = True - - for other_marker in [m for m in scene.timeline_markers if m != marker]: - other_marker.select = False - - return {'FINISHED'} diff --git a/space_view3d_stored_views/properties.py b/space_view3d_stored_views/properties.py deleted file mode 100644 index 78498f63..00000000 --- a/space_view3d_stored_views/properties.py +++ /dev/null @@ -1,120 +0,0 @@ -# gpl authors: nfloyd, Francesco Siddi - -from bpy.types import PropertyGroup -from bpy.props import ( - BoolProperty, - BoolVectorProperty, - CollectionProperty, - FloatProperty, - FloatVectorProperty, - EnumProperty, - IntProperty, - IntVectorProperty, - PointerProperty, - StringProperty, - ) - - -class POVData(PropertyGroup): - distance: FloatProperty() - location: FloatVectorProperty( - subtype='TRANSLATION' - ) - rotation: FloatVectorProperty( - subtype='QUATERNION', - size=4 - ) - name: StringProperty() - perspective: EnumProperty( - items=[('PERSP', '', ''), - ('ORTHO', '', ''), - ('CAMERA', '', '')] - ) - lens: FloatProperty() - clip_start: FloatProperty() - clip_end: FloatProperty() - lock_cursor: BoolProperty() - cursor_location: FloatVectorProperty() - perspective_matrix_md5: StringProperty() - camera_name: StringProperty() - camera_type: StringProperty() - lock_object_name: StringProperty() - - -class LayersData(PropertyGroup): - view_layers = BoolVectorProperty(size=20) - scene_layers = BoolVectorProperty(size=20) - lock_camera_and_layers: BoolProperty() - name: StringProperty() - - -class DisplayData(PropertyGroup): - name: StringProperty() - viewport_shade: EnumProperty( - items=[('BOUNDBOX', 'BOUNDBOX', 'BOUNDBOX'), - ('WIREFRAME', 'WIREFRAME', 'WIREFRAME'), - ('SOLID', 'SOLID', 'SOLID'), - ('TEXTURED', 'TEXTURED', 'TEXTURED'), - ('MATERIAL', 'MATERIAL', 'MATERIAL'), - ('RENDERED', 'RENDERED', 'RENDERED')] - ) - show_only_render: BoolProperty() - show_outline_selected: BoolProperty() - show_all_objects_origin: BoolProperty() - show_relationship_lines: BoolProperty() - show_floor: BoolProperty() - show_axis_x: BoolProperty() - show_axis_y: BoolProperty() - show_axis_z: BoolProperty() - grid_lines: IntProperty() - grid_scale: FloatProperty() - grid_subdivisions: IntProperty() - material_mode: StringProperty() - show_textured_solid: BoolProperty() - quad_view: BoolProperty() - lock_rotation: BoolProperty() - show_sync_view: BoolProperty() - use_box_clip: BoolProperty() - - -class ViewData(PropertyGroup): - pov: PointerProperty( - type=POVData - ) - layers: PointerProperty( - type=LayersData - ) - display: PointerProperty( - type=DisplayData - ) - name: StringProperty() - - -class StoredViewsData(PropertyGroup): - pov_list: CollectionProperty( - type=POVData - ) - layers_list: CollectionProperty( - type=LayersData - ) - display_list: CollectionProperty( - type=DisplayData - ) - view_list: CollectionProperty( - type=ViewData - ) - mode: EnumProperty( - name="Mode", - items=[('VIEW', "View", "3D View settings"), - ('POV', "POV", "POV settings"), - ('LAYERS', "Layers", "Layers settings"), - ('DISPLAY', "Display", "Display settings")], - default='VIEW' - ) - current_indices: IntVectorProperty( - size=4, - default=[-1, -1, -1, -1] - ) - view_modified: BoolProperty( - default=False - ) diff --git a/space_view3d_stored_views/ui.py b/space_view3d_stored_views/ui.py deleted file mode 100644 index 9388128a..00000000 --- a/space_view3d_stored_views/ui.py +++ /dev/null @@ -1,263 +0,0 @@ -# gpl authors: nfloyd, Francesco Siddi - -import logging -module_logger = logging.getLogger(__name__) - -import bpy -import blf -from . import core -from bpy.types import ( - Operator, - Panel, -) - -""" - If view name display is enabled, - it will check periodically if the view has been modified - since last set. - get_preferences_timer() is the time in seconds between these checks. - It can be increased, if the view become sluggish - It is set in the add-on preferences -""" - - -# Utility function get_preferences_timer for update of 3d view draw -def get_preferences_timer(): - # replace the key if the add-on name changes - # TODO: expose refresh rate to ui??? - addon = bpy.context.preferences.addons[__package__] - timer_update = (addon.preferences.view_3d_update_rate if addon else False) - - return timer_update - - -def init_draw(context=None): - if context is None: - context = bpy.context - - if "stored_views_osd" not in context.window_manager: - context.window_manager["stored_views_osd"] = False - - if not context.window_manager["stored_views_osd"]: - context.window_manager["stored_views_osd"] = True - bpy.ops.stored_views.draw() - - -def _draw_callback_px(self, context): - if context.area and context.area.type == 'VIEW_3D': - r_width = text_location = context.region.width - r_height = context.region.height - font_id = 0 # TODO: need to find out how best to get font_id - - blf.size(font_id, 11, context.preferences.system.dpi) - text_size = blf.dimensions(0, self.view_name) - - # compute the text location - text_location = 0 - overlap = context.preferences.system.use_region_overlap - if overlap: - for region in context.area.regions: - if region.type == "UI": - text_location = r_width - region.width - - text_x = text_location - text_size[0] - 10 - text_y = r_height - text_size[1] - 8 - blf.position(font_id, text_x, text_y, 0) - blf.draw(font_id, self.view_name) - - -class VIEW3D_stored_views_draw(Operator): - bl_idname = "stored_views.draw" - bl_label = "Show current" - bl_description = "Toggle the display current view name in the view 3D" - - _handle = None - _timer = None - - @staticmethod - def handle_add(self, context): - VIEW3D_stored_views_draw._handle = bpy.types.SpaceView3D.draw_handler_add( - _draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL') - VIEW3D_stored_views_draw._timer = \ - context.window_manager.event_timer_add(get_preferences_timer(), context.window) - - @staticmethod - def handle_remove(context): - if VIEW3D_stored_views_draw._handle is not None: - bpy.types.SpaceView3D.draw_handler_remove(VIEW3D_stored_views_draw._handle, 'WINDOW') - if VIEW3D_stored_views_draw._timer is not None: - context.window_manager.event_timer_remove(VIEW3D_stored_views_draw._timer) - VIEW3D_stored_views_draw._handle = None - VIEW3D_stored_views_draw._timer = None - - @classmethod - def poll(cls, context): - # return context.mode == 'OBJECT' - return True - - def modal(self, context, event): - if context.area: - context.area.tag_redraw() - - if not context.area or context.area.type != "VIEW_3D": - return {"PASS_THROUGH"} - - data = core.DataStore() - stored_views = context.scene.stored_views - - if len(data.list) > 0 and \ - data.current_index >= 0 and \ - not stored_views.view_modified: - - if not stored_views.view_modified: - sv = data.list[data.current_index] - self.view_name = sv.name - if event.type == 'TIMER': - is_modified = False - if data.mode == 'VIEW': - is_modified = core.View.is_modified(context, sv) - elif data.mode == 'POV': - is_modified = core.POV.is_modified(context, sv) - elif data.mode == 'LAYERS': - is_modified = core.Layers.is_modified(context, sv) - elif data.mode == 'DISPLAY': - is_modified = core.Display.is_modified(context, sv) - if is_modified: - module_logger.debug( - 'view modified - index: %s name: %s' % (data.current_index, sv.name) - ) - self.view_name = "" - stored_views.view_modified = is_modified - - return {"PASS_THROUGH"} - else: - module_logger.debug('exit') - context.window_manager["stored_views_osd"] = False - VIEW3D_stored_views_draw.handle_remove(context) - - return {'FINISHED'} - - def execute(self, context): - if context.area.type == "VIEW_3D": - self.view_name = "" - VIEW3D_stored_views_draw.handle_add(self, context) - context.window_manager.modal_handler_add(self) - - return {"RUNNING_MODAL"} - else: - self.report({"WARNING"}, "View3D not found. Operation Cancelled") - - return {"CANCELLED"} - - -class VIEW3D_PT_properties_stored_views(Panel): - bl_label = "Stored Views" - bl_space_type = "VIEW_3D" - bl_region_type = "UI" - - def draw(self, context): - self.logger = logging.getLogger('%s Properties panel' % __name__) - layout = self.layout - - if bpy.ops.view3d.stored_views_initialize.poll(): - layout.operator("view3d.stored_views_initialize") - return - - stored_views = context.scene.stored_views - - # UI : mode - col = layout.column(align=True) - col.prop_enum(stored_views, "mode", 'VIEW') - row = layout.row(align=True) - row.operator("view3d.camera_to_view", text="Camera To view") - row.operator("stored_views.newcamera") - - row = col.row(align=True) - row.prop_enum(stored_views, "mode", 'POV') - row.prop_enum(stored_views, "mode", 'LAYERS') - row.prop_enum(stored_views, "mode", 'DISPLAY') - - # UI : operators - row = layout.row() - row.operator("stored_views.save").index = -1 - - # IO Operators - if core.get_preferences(): - row = layout.row(align=True) - row.operator("stored_views.import_from_scene", text="Import from Scene") - row.operator("stored_views.import_blsv", text="", icon="IMPORT") - row.operator("stored_views.export_blsv", text="", icon="EXPORT") - - data_store = core.DataStore() - list = data_store.list - # UI : items list - if len(list) > 0: - row = layout.row() - box = row.box() - # items list - mode = stored_views.mode - for i in range(len(list)): - # associated icon - icon_string = "MESH_CUBE" # default icon - # TODO: icons for view - if mode == 'POV': - persp = list[i].perspective - if persp == 'PERSP': - icon_string = "MESH_CUBE" - elif persp == 'ORTHO': - icon_string = "MESH_PLANE" - elif persp == 'CAMERA': - if list[i].camera_type != 'CAMERA': - icon_string = 'OBJECT_DATAMODE' - else: - icon_string = "OUTLINER_DATA_CAMERA" - if mode == 'LAYERS': - if list[i].lock_camera_and_layers is True: - icon_string = 'SCENE_DATA' - else: - icon_string = 'RENDERLAYERS' - if mode == 'DISPLAY': - shade = list[i].viewport_shade - if shade == 'TEXTURED': - icon_string = 'TEXTURE_SHADED' - if shade == 'MATERIAL': - icon_string = 'MATERIAL_DATA' - elif shade == 'SOLID': - icon_string = 'SOLID' - elif shade == 'WIREFRAME': - icon_string = "WIRE" - elif shade == 'BOUNDBOX': - icon_string = 'BBOX' - elif shade == 'RENDERED': - icon_string = 'MATERIAL' - # stored view row - subrow = box.row(align=True) - # current view indicator - if data_store.current_index == i and context.scene.stored_views.view_modified is False: - subrow.label(text="", icon='SMALL_TRI_RIGHT_VEC') - subrow.operator("stored_views.set", - text="", icon=icon_string).index = i - subrow.prop(list[i], "name", text="") - subrow.operator("stored_views.save", - text="", icon="REC").index = i - subrow.operator("stored_views.delete", - text="", icon="PANEL_CLOSE").index = i - - layout = self.layout - scene = context.scene - layout.label(text="Camera Selector") - cameras = sorted([o for o in scene.objects if o.type == 'CAMERA'], - key=lambda o: o.name) - - if len(cameras) > 0: - for camera in cameras: - row = layout.row(align=True) - row.context_pointer_set("active_object", camera) - row.operator("cameraselector.set_scene_camera", - text=camera.name, icon='OUTLINER_DATA_CAMERA') - row.operator("cameraselector.preview_scene_camera", - text='', icon='RESTRICT_VIEW_OFF') - row.operator("cameraselector.add_camera_marker", - text='', icon='MARKER') - else: - layout.label(text="No cameras in this scene") -- cgit v1.2.3