diff options
author | Peter Kim <pk15950@gmail.com> | 2021-08-31 12:01:08 +0300 |
---|---|---|
committer | Peter Kim <pk15950@gmail.com> | 2021-08-31 12:01:08 +0300 |
commit | f02773d5eddb770a7d1e8d836d43fdcf416bd27c (patch) | |
tree | 12e47b3f67aef39857d2f739fda57f900c1e461d | |
parent | 1bbddad89934a1e18e8d22da75a78838af9e16b3 (diff) | |
parent | 4e30cfd30603c3bd8e4f7ecdea77cc65ec213d3a (diff) |
Merge branch 'master' into xr-controller-support
27 files changed, 263 insertions, 157 deletions
diff --git a/add_camera_rigs/build_rigs.py b/add_camera_rigs/build_rigs.py index 6b47fef8..e3f61632 100644 --- a/add_camera_rigs/build_rigs.py +++ b/add_camera_rigs/build_rigs.py @@ -20,7 +20,6 @@ import bpy from bpy.types import Operator from bpy_extras import object_utils from mathutils import Vector -from rna_prop_ui import rna_idprop_ui_prop_get from math import pi from .create_widgets import (create_root_widget, @@ -158,11 +157,8 @@ def setup_3d_rig(rig, cam): # Lens property pb = pose_bones['Camera'] pb["lens"] = 50.0 - prop = rna_idprop_ui_prop_get(pb, "lens", create=True) - prop["default"] = 50.0 - prop["min"] = 1.0 - prop["max"] = 1000000.0 - prop["soft_max"] = 5000.0 + ui_data = pb.id_properties_ui("lens") + ui_data.update(min=1.0, max=1000000.0, soft_max = 5000.0, default=50.0) # Build the widgets root_widget = create_root_widget("Camera_Root") @@ -327,12 +323,8 @@ def create_2d_bones(context, rig, cam): # Property to switch between rotation and switch mode pose_bones["Camera"]['rotation_shift'] = 0.0 - prop = rna_idprop_ui_prop_get(pose_bones["Camera"], 'rotation_shift', create=True) - prop["min"] = 0.0 - prop["max"] = 1.0 - prop["soft_min"] = 0.0 - prop["soft_max"] = 1.0 - prop["description"] = 'rotation_shift' + ui_data = pose_bones["Camera"].id_properties_ui('rotation_shift') + ui_data.update(min=0.0, max=1.0, soft_max = 5000.0, description="rotation_shift") # Rotation / shift switch driver driver = con.driver_add('influence').driver @@ -526,18 +518,14 @@ def build_camera_rig(context, mode): # DOF Focus Distance property pb = pose_bones['Camera'] pb["focus_distance"] = 10.0 - prop = rna_idprop_ui_prop_get(pb, "focus_distance", create=True) - prop["default"] = 10.0 - prop["min"] = 0.0 + ui_data = pb.id_properties_ui('focus_distance') + ui_data.update(min=0.0, default=10.0) # DOF F-Stop property pb = pose_bones['Camera'] pb["aperture_fstop"] = 2.8 - prop = rna_idprop_ui_prop_get(pb, "aperture_fstop", create=True) - prop["default"] = 2.8 - prop["min"] = 0.0 - prop["soft_min"] = 0.1 - prop["soft_max"] = 128.0 + ui_data = pb.id_properties_ui('aperture_fstop') + ui_data.update(min=0.0, soft_min=0.1, soft_max=128.0, default=2.8) # Add drivers to link the camera properties to the custom props # on the armature diff --git a/curve_tools/auto_loft.py b/curve_tools/auto_loft.py index c0711196..17705cc9 100644 --- a/curve_tools/auto_loft.py +++ b/curve_tools/auto_loft.py @@ -30,13 +30,10 @@ class OperatorAutoLoftCurves(Operator): context.collection.objects.link(loftobj) loftobj["autoloft"] = True - if loftobj.get('_RNA_UI') is None: - loftobj['_RNA_UI'] = {} - loftobj['_RNA_UI']["autoloft"] = { - "name": "Auto Loft", - "description": "Auto loft from %s to %s" % (curve0.name, curve1.name), - "curve0": curve0.name, - "curve1": curve1.name} + ui_data = loftobj.id_properties_ui("autoloft") + ui_data.update(description="Auto loft from %s to %s" % (curve0.name, curve1.name)) + loftobj["autoloft_curve0"] = curve0.name + loftobj["autoloft_curve1"] = curve1.name return {'FINISHED'} @@ -59,9 +56,8 @@ class AutoLoftModalOperator(Operator): #print("TIMER", lofters) for loftmesh in lofters: - rna = loftmesh['_RNA_UI']["autoloft"].to_dict() - curve0 = scene.objects.get(rna["curve0"]) - curve1 = scene.objects.get(rna["curve1"]) + curve0 = scene.objects.get(loftmesh['autoloft_curve0']) + curve1 = scene.objects.get(loftmesh['autoloft_curve1']) if curve0 and curve1: ls = surfaces.LoftedSurface(curves.Curve(curve0), curves.Curve(curve1), loftmesh.name) ls.bMesh.to_mesh(loftmesh.data) diff --git a/greasepencil_tools/__init__.py b/greasepencil_tools/__init__.py index 0a8042c9..64274c3b 100644 --- a/greasepencil_tools/__init__.py +++ b/greasepencil_tools/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "Grease Pencil Tools", "description": "Extra tools for Grease Pencil", "author": "Samuel Bernou, Antonio Vazquez, Daniel Martinez Lara, Matias Mendiola", -"version": (1, 5, 2), +"version": (1, 5, 3), "blender": (2, 91, 0), "location": "Sidebar > Grease Pencil > Grease Pencil Tools", "warning": "", diff --git a/greasepencil_tools/box_deform.py b/greasepencil_tools/box_deform.py index 6fa866ec..607d8a7d 100644 --- a/greasepencil_tools/box_deform.py +++ b/greasepencil_tools/box_deform.py @@ -333,7 +333,7 @@ def cancel_cage(self): self.gp_obj.grease_pencil_modifiers.remove(mod) else: print(f'tmp_lattice modifier not found to remove on {self.gp_obj.name}') - + for ob in self.other_gp: mod = ob.grease_pencil_modifiers.get('tmp_lattice') if mod: @@ -458,7 +458,7 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T" return {"RUNNING_MODAL"} # Valid - if event.type in {'RET', 'SPACE'}: + if event.type in {'RET', 'SPACE', 'NUMPAD_ENTER'}: if event.value == 'PRESS': context.window_manager.boxdeform_running = False self.restore_prefs(context) @@ -586,7 +586,7 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T" ## silent return return {'CANCELLED'} - + # bpy.ops.ed.undo_push(message="Box deform step")#don't work as expected (+ might be obsolete) # https://developer.blender.org/D6147 <- undo forget diff --git a/greasepencil_tools/prefs.py b/greasepencil_tools/prefs.py index 11d3d0be..929197d5 100644 --- a/greasepencil_tools/prefs.py +++ b/greasepencil_tools/prefs.py @@ -89,7 +89,7 @@ class GreasePencilAddonPrefs(bpy.types.AddonPreferences): name = "Use Hud", description = "Display angle lines and angle value as text on viewport", default = False) - + canvas_use_view_center: BoolProperty( name = "Rotate From View Center In Camera", description = "Rotate from view center in camera view, Else rotate from camera center", diff --git a/greasepencil_tools/timeline_scrub.py b/greasepencil_tools/timeline_scrub.py index 2a745f5f..9946975e 100644 --- a/greasepencil_tools/timeline_scrub.py +++ b/greasepencil_tools/timeline_scrub.py @@ -211,7 +211,7 @@ class GPTS_OT_time_scrub(bpy.types.Operator): else: self.init_index = 0 self.init_frame = self.new_frame = self.pos[0] - + # del active_pos self.index_limit = len(self.pos) - 1 @@ -311,14 +311,14 @@ class GPTS_OT_time_scrub(bpy.types.Operator): shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') # initiate shader self.batch_timeline = batch_for_shader( shader, 'LINES', {"pos": self.hud_lines}) - + if self.rolling_mode: current_id = self.pos.index(self.new_frame) # Add init_frame to "cancel" it in later UI code ui_key_pos = [i - current_id + self.init_frame for i, _f in enumerate(self.pos[:-2])] else: ui_key_pos = self.pos[:-2] - + # keyframe display if self.keyframe_aspect == 'LINE': @@ -555,6 +555,12 @@ class GPTS_timeline_settings(bpy.types.PropertyGroup): description="Alternative Gap-less timeline. No time informations to quickly roll/flip over keys\nOverride normal and 'always snap' mode", default=False) + use: BoolProperty( + name="Enable", + description="Enable/Disable timeline scrub", + default=True, + update=auto_rebind) + use_in_timeline_editor: BoolProperty( name="Shortcut in timeline editors", description="Add the same shortcut to scrub in timeline editor windows", @@ -681,6 +687,9 @@ class GPTS_timeline_settings(bpy.types.PropertyGroup): def draw_ts_pref(prefs, layout): # - General settings layout.label(text='Timeline Scrub:') + layout.prop(prefs, 'use') + if not prefs.use: + return layout.prop(prefs, 'evaluate_gp_obj_key') layout.prop(prefs, 'pixel_step') @@ -716,7 +725,7 @@ def draw_ts_pref(prefs, layout): snap_text = 'Disable keyframes snap: ' else: snap_text = 'Keyframes snap: ' - + snap_text += 'Left Mouse' if prefs.keycode == 'RIGHTMOUSE' else 'Right Mouse' if not prefs.use_ctrl: snap_text += ' or Ctrl' @@ -724,7 +733,7 @@ def draw_ts_pref(prefs, layout): snap_text += ' or Shift' if not prefs.use_alt: snap_text += ' or Alt' - + if prefs.rolling_mode: snap_text = 'Gap-less mode (always snap)' @@ -769,6 +778,9 @@ addon_keymaps = [] def register_keymaps(): prefs = get_addon_prefs().ts + if not prefs.use: + return + addon = bpy.context.window_manager.keyconfigs.addon km = addon.keymaps.new(name="Grease Pencil", space_type="EMPTY", region_type='WINDOW') diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index 71ae6ec3..01bc5421 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier", - "version": (4, 22, 0), + "version": (4, 23, 0), "blender": (2, 90, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py index bafdf1ef..3950ed5b 100644 --- a/io_scene_fbx/export_fbx_bin.py +++ b/io_scene_fbx/export_fbx_bin.py @@ -542,7 +542,7 @@ def fbx_data_element_custom_properties(props, bid): rna_properties = {prop.identifier for prop in bid.bl_rna.properties if prop.is_runtime} for k, v in items: - if k == '_RNA_UI' or k in rna_properties: + if k in rna_properties: continue list_val = getattr(v, "to_list", lambda: None)() diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index ec16b6d1..ba11757a 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -369,8 +369,10 @@ def blen_read_custom_properties(fbx_obj, blen_obj, settings): val = fbx_prop.props[4] if settings.use_custom_props_enum_as_string and fbx_prop.props[5]: enum_items = fbx_prop.props[5].decode('utf-8', 'replace').split('~') - assert(val >= 0 and val < len(enum_items)) - blen_obj[prop_name] = enum_items[val] + if val >= 0 and val < len(enum_items): + blen_obj[prop_name] = enum_items[val] + else: + print ("WARNING: User property '%s' has wrong enum value, skipped" % prop_name) else: blen_obj[prop_name] = val else: diff --git a/io_scene_gltf2/blender/com/gltf2_blender_extras.py b/io_scene_gltf2/blender/com/gltf2_blender_extras.py index 26528aa4..6c93e7b4 100644 --- a/io_scene_gltf2/blender/com/gltf2_blender_extras.py +++ b/io_scene_gltf2/blender/com/gltf2_blender_extras.py @@ -18,7 +18,7 @@ from .gltf2_blender_json import is_json_convertible # Custom properties, which are in most cases present and should not be imported/exported. -BLACK_LIST = ['cycles', 'cycles_visibility', 'cycles_curves', '_RNA_UI', 'glTF2ExportSettings'] +BLACK_LIST = ['cycles', 'cycles_visibility', 'cycles_curves', 'glTF2ExportSettings'] def generate_extras(blender_element): diff --git a/materials_library_vx/__init__.py b/materials_library_vx/__init__.py index 8df8e2b9..cc469d84 100644 --- a/materials_library_vx/__init__.py +++ b/materials_library_vx/__init__.py @@ -489,7 +489,7 @@ if mat: return "WARNING", "Select a material" def get_material(self, name, link=False): - with bpy.data.libraries.load(self.current_library.path, link, False) as (data_from, data_to): + with bpy.data.libraries.load(self.current_library.path, link=link, relative=False) as (data_from, data_to): data_to.materials = [name] if link: print(name + " linked.") @@ -523,7 +523,7 @@ if mat: return "INFO", "Please select an object" if dummy == context.object and not preview: - if (len(objects)==1 and dummy.select): + if (len(objects)==1 and dummy.select_get()): return "ERROR", "Apply is disabled for the Material Preview Object" try: last = context.scene.objects[self.last_selected] diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py index 0b1b7a15..9b93ba55 100644 --- a/mesh_snap_utilities_line/__init__.py +++ b/mesh_snap_utilities_line/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "Snap_Utilities_Line", "author": "Germano Cavalcante", - "version": (6, 9, 3), + "version": (6, 9, 4), "blender": (3, 0, 0), "location": "View3D > TOOLS > Line Tool", "description": "Extends Blender Snap controls", diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py index 611b07da..f0e2a8ed 100644 --- a/mesh_snap_utilities_line/common_classes.py +++ b/mesh_snap_utilities_line/common_classes.py @@ -471,6 +471,7 @@ class SnapUtilities: preferences = context.preferences.addons[__package__].preferences self.preferences = preferences + #Init DrawCache self.draw_cache = SnapDrawn( preferences.out_color, @@ -482,7 +483,8 @@ class SnapUtilities: preferences.constrain_shift_color, tuple(context.preferences.themes[0].user_interface.axis_x) + (1.0,), tuple(context.preferences.themes[0].user_interface.axis_y) + (1.0,), - tuple(context.preferences.themes[0].user_interface.axis_z) + (1.0,)) + tuple(context.preferences.themes[0].user_interface.axis_z) + (1.0,), + self.sctx.rv3d) self.snap_vert = self.snap_edge = snap_edge_and_vert diff --git a/mesh_snap_utilities_line/drawing_utilities.py b/mesh_snap_utilities_line/drawing_utilities.py index cf67db4b..b4e53a00 100644 --- a/mesh_snap_utilities_line/drawing_utilities.py +++ b/mesh_snap_utilities_line/drawing_utilities.py @@ -15,7 +15,7 @@ # # ##### END GPL LICENSE BLOCK ##### import gpu -from mathutils import Vector +from mathutils import Vector, Matrix class SnapDrawn(): @@ -30,6 +30,7 @@ class SnapDrawn(): 'axis_x_color', 'axis_y_color', 'axis_z_color', + 'rv3d', '_format_pos', '_format_pos_and_color', '_program_unif_col', @@ -39,7 +40,7 @@ class SnapDrawn(): def __init__(self, out_color, face_color, edge_color, vert_color, center_color, perpendicular_color, constrain_shift_color, - axis_x_color, axis_y_color, axis_z_color): + axis_x_color, axis_y_color, axis_z_color, rv3d): import gpu @@ -55,6 +56,8 @@ class SnapDrawn(): self.axis_y_color = axis_y_color self.axis_z_color = axis_z_color + self.rv3d = rv3d + self._format_pos = gpu.types.GPUVertFormat() self._format_pos.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT') @@ -62,18 +65,38 @@ class SnapDrawn(): self._format_pos_and_color.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT') self._format_pos_and_color.attr_add(id="color", comp_type='F32', len=4, fetch_mode='FLOAT') - self._program_unif_col = gpu.shader.from_builtin("3D_UNIFORM_COLOR") - self._program_smooth_col = gpu.shader.from_builtin("3D_SMOOTH_COLOR") - self._batch_point = None + def _gl_state_push(self, ob_mat=None): + clip_planes = gpu.types.Buffer('FLOAT', (6, 4), self.rv3d.clip_planes) if self.rv3d.use_clip_planes else None + + config = 'CLIPPED' if clip_planes else 'DEFAULT' + self._program_unif_col = gpu.shader.from_builtin("3D_UNIFORM_COLOR", config=config) + self._program_smooth_col = gpu.shader.from_builtin("3D_SMOOTH_COLOR", config=config) - def _gl_state_push(self): gpu.state.program_point_size_set(False) gpu.state.blend_set('ALPHA') + gpu.matrix.push() + if ob_mat: + gpu.matrix.multiply_matrix(ob_mat) + + if clip_planes: + gpu.state.clip_distances_set(4) + mat = ob_mat if ob_mat else Matrix.Identity(4) + + self._program_unif_col.bind() + self._program_unif_col.uniform_float("ModelMatrix", mat) + self._program_unif_col.uniform_vector_float(self._program_unif_col.uniform_from_name("WorldClipPlanes"), clip_planes, 4, 4) + + self._program_smooth_col.bind() + self._program_smooth_col.uniform_float("ModelMatrix", mat) + self._program_smooth_col.uniform_vector_float(self._program_smooth_col.uniform_from_name("WorldClipPlanes"), clip_planes, 4, 4) def _gl_state_restore(self): gpu.state.blend_set('NONE') + gpu.matrix.pop() + if self.rv3d.use_clip_planes: + gpu.state.clip_distances_set(0) def batch_line_strip_create(self, coords): from gpu.types import ( @@ -124,7 +147,6 @@ class SnapDrawn(): import gpu self._gl_state_push() - gpu.matrix.push() self._program_unif_col.bind() if list_verts_co: @@ -139,6 +161,7 @@ class SnapDrawn(): self._program_unif_col.bind() self._program_unif_col.uniform_float("color", (1.0, 0.8, 0.0, 0.5)) + batch.draw(self._program_unif_col) gpu.matrix.pop_projection() del batch @@ -153,6 +176,7 @@ class SnapDrawn(): self._program_unif_col.bind() self._program_unif_col.uniform_float("color", (1.0, 1.0, 1.0, 0.5)) + point_batch.draw(self._program_unif_col) gpu.matrix.translate(-prevloc) @@ -192,7 +216,6 @@ class SnapDrawn(): gpu.state.line_width_set(1.0) gpu.state.depth_test_set('LESS_EQUAL') - gpu.matrix.pop() self._gl_state_restore() def draw_elem(self, snap_obj, bm, elem): @@ -204,53 +227,48 @@ class SnapDrawn(): BMFace, ) - with gpu.matrix.push_pop(): - self._gl_state_push() - gpu.state.depth_test_set('NONE') - - gpu.matrix.multiply_matrix(snap_obj.mat) - - if isinstance(elem, BMVert): - if elem.link_edges: - import numpy as np - - color = self.vert_color - edges = np.empty((len(elem.link_edges), 2), [("pos", "f4", 3), ("color", "f4", 4)]) - edges["pos"][:, 0] = elem.co - edges["pos"][:, 1] = [e.other_vert(elem).co for e in elem.link_edges] - edges["color"][:, 0] = color - edges["color"][:, 1] = (color[0], color[1], color[2], 0.0) - edges.shape = -1 - - self._program_smooth_col.bind() - gpu.state.line_width_set(3.0) - batch = self.batch_lines_smooth_color_create(edges["pos"], edges["color"]) - batch.draw(self._program_smooth_col) - gpu.state.line_width_set(1.0) - else: + self._gl_state_push(snap_obj.mat) + gpu.state.depth_test_set('NONE') + + if isinstance(elem, BMVert): + if elem.link_edges: + import numpy as np + + color = self.vert_color + edges = np.empty((len(elem.link_edges), 2), [("pos", "f4", 3), ("color", "f4", 4)]) + edges["pos"][:, 0] = elem.co + edges["pos"][:, 1] = [e.other_vert(elem).co for e in elem.link_edges] + edges["color"][:, 0] = color + edges["color"][:, 1] = (color[0], color[1], color[2], 0.0) + edges.shape = -1 + + self._program_smooth_col.bind() + gpu.state.line_width_set(3.0) + batch = self.batch_lines_smooth_color_create(edges["pos"], edges["color"]) + batch.draw(self._program_smooth_col) + gpu.state.line_width_set(1.0) + else: + if isinstance(elem, BMEdge): self._program_unif_col.bind() + self._program_unif_col.uniform_float("color", self.edge_color) - if isinstance(elem, BMEdge): + gpu.state.line_width_set(3.0) + batch = self.batch_line_strip_create([v.co for v in elem.verts]) + batch.draw(self._program_unif_col) + gpu.state.line_width_set(1.0) + + elif isinstance(elem, BMFace): + if len(snap_obj.data) == 2: + face_color = self.face_color[0], self.face_color[1], self.face_color[2], self.face_color[3] * 0.2 self._program_unif_col.bind() - self._program_unif_col.uniform_float("color", self.edge_color) + self._program_unif_col.uniform_float("color", face_color) - gpu.state.line_width_set(3.0) - batch = self.batch_line_strip_create([v.co for v in elem.verts]) + tris = snap_obj.data[1].get_loop_tri_co_by_bmface(bm, elem) + tris.shape = (-1, 3) + batch = self.batch_triangles_create(tris) batch.draw(self._program_unif_col) - gpu.state.line_width_set(1.0) - - elif isinstance(elem, BMFace): - if len(snap_obj.data) == 2: - face_color = self.face_color[0], self.face_color[1], self.face_color[2], self.face_color[3] * 0.2 - self._program_unif_col.bind() - self._program_unif_col.uniform_float("color", face_color) - - tris = snap_obj.data[1].get_loop_tri_co_by_bmface(bm, elem) - tris.shape = (-1, 3) - batch = self.batch_triangles_create(tris) - batch.draw(self._program_unif_col) - # restore opengl defaults - gpu.state.depth_test_set('LESS_EQUAL') + # restore opengl defaults + gpu.state.depth_test_set('LESS_EQUAL') self._gl_state_restore() diff --git a/mesh_snap_utilities_line/op_line.py b/mesh_snap_utilities_line/op_line.py index aa516bfe..771c6a4b 100644 --- a/mesh_snap_utilities_line/op_line.py +++ b/mesh_snap_utilities_line/op_line.py @@ -21,7 +21,6 @@ import bmesh from mathutils import Vector from mathutils.geometry import intersect_point_line -from .drawing_utilities import SnapDrawn from .common_utilities import snap_utilities from .common_classes import ( CharMap, diff --git a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py index bd324afd..679ee932 100644 --- a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py +++ b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py @@ -336,6 +336,7 @@ class GPU_Indices_Mesh(): self.shader.bind() if GPU_Indices_Mesh.use_clip_planes: + gpu.state.clip_distances_set(4) self.shader.uniform_float("ModelMatrix", ob_mat) if self.draw_tris: @@ -374,6 +375,9 @@ class GPU_Indices_Mesh(): self.shader.uniform_int("offset", (index_offset,)) self.batch_lverts.draw(self.shader) + if GPU_Indices_Mesh.use_clip_planes: + gpu.state.clip_distances_set(0) + gpu.matrix.pop() gpu.matrix.pop_projection() @@ -436,7 +440,7 @@ def gpu_Indices_use_clip_planes(rv3d, value): if value and rv3d.use_clip_planes: GPU_Indices_Mesh.use_clip_planes = True planes = gpu.types.Buffer('FLOAT', (6, 4), rv3d.clip_planes) - shader.uniform_vector_float(shader.uniform_from_name("clip_plane"), planes, 4, 4) + shader.uniform_vector_float(shader.uniform_from_name("WorldClipPlanes"), planes, 4, 4) else: GPU_Indices_Mesh.use_clip_planes = False diff --git a/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_frag.glsl b/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_frag.glsl index 3e01f7b0..e28368be 100644 --- a/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_frag.glsl +++ b/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_frag.glsl @@ -1,24 +1,7 @@ uniform int offset; - -#ifdef USE_CLIP_PLANES -uniform bool use_clip_planes; -in vec4 clip_distance; -#endif - out uint FragColor; void main() { -#ifdef USE_CLIP_PLANES - if (use_clip_planes && - ((clip_distance[0] < 0) || - (clip_distance[1] < 0) || - (clip_distance[2] < 0) || - (clip_distance[3] < 0))) - { - discard; - } -#endif - FragColor = uint(gl_PrimitiveID + offset); } diff --git a/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_vert.glsl b/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_vert.glsl index 6fb7cbb9..747b33e9 100644 --- a/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_vert.glsl +++ b/mesh_snap_utilities_line/snap_context_l/shaders/ID_color_vert.glsl @@ -3,8 +3,7 @@ uniform mat4 ModelViewProjectionMatrix; #ifdef USE_CLIP_PLANES uniform mat4 ModelMatrix; uniform bool use_clip_planes; -uniform vec4 clip_plane[4]; -out vec4 clip_distance; +uniform vec4 WorldClipPlanes[4]; #endif in vec3 pos; @@ -15,9 +14,10 @@ void main() if (use_clip_planes) { vec4 g_pos = ModelMatrix * vec4(pos, 1.0); - for (int i = 0; i != 4; i++) { - clip_distance[i] = dot(clip_plane[i], g_pos); - } + gl_ClipDistance[0] = dot(WorldClipPlanes[0], g_pos); + gl_ClipDistance[1] = dot(WorldClipPlanes[1], g_pos); + gl_ClipDistance[2] = dot(WorldClipPlanes[2], g_pos); + gl_ClipDistance[3] = dot(WorldClipPlanes[3], g_pos); } #endif diff --git a/mesh_snap_utilities_line/widgets.py b/mesh_snap_utilities_line/widgets.py index 6c011b7a..98edf5f3 100644 --- a/mesh_snap_utilities_line/widgets.py +++ b/mesh_snap_utilities_line/widgets.py @@ -19,7 +19,6 @@ import bpy from .common_classes import SnapUtilities from .common_utilities import snap_utilities -from .drawing_utilities import SnapDrawn #def mesh_runtime_batchcache_isdirty(me): diff --git a/node_wrangler.py b/node_wrangler.py index 4b77d109..68573302 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -734,14 +734,11 @@ def autolink(node1, node2, links): def node_at_pos(nodes, context, event): - nodes_near_mouse = [] nodes_under_mouse = [] target_node = None store_mouse_cursor(context, event) x, y = context.space_data.cursor_location - x = x - y = y # Make a list of each corner (and middle of border) for each node. # Will be sorted to find nearest point and thus nearest node diff --git a/object_collection_manager/__init__.py b/object_collection_manager/__init__.py index 3936d11b..aa9211d6 100644 --- a/object_collection_manager/__init__.py +++ b/object_collection_manager/__init__.py @@ -22,7 +22,7 @@ bl_info = { "name": "Collection Manager", "description": "Manage collections and their objects", "author": "Ryan Inch", - "version": (2, 22, 3), + "version": (2, 23, 0), "blender": (2, 80, 0), "location": "View3D - Object Mode (Shortcut - M)", "warning": '', # used for warning icon and text in addons panel diff --git a/object_collection_manager/qcd_init.py b/object_collection_manager/qcd_init.py index 49951da3..ed235a63 100644 --- a/object_collection_manager/qcd_init.py +++ b/object_collection_manager/qcd_init.py @@ -59,6 +59,8 @@ qcd_classes = ( qcd_operators.MoveToQCDSlot, qcd_operators.ViewQCDSlot, qcd_operators.ViewMoveQCDSlot, + qcd_operators.UnassignedQCDSlot, + qcd_operators.CreateAllQCDSlots, qcd_operators.RenumerateQCDSlots, ui.EnableAllQCDSlotsMenu, ) diff --git a/object_collection_manager/qcd_operators.py b/object_collection_manager/qcd_operators.py index 5f465eb5..0fdf1045 100644 --- a/object_collection_manager/qcd_operators.py +++ b/object_collection_manager/qcd_operators.py @@ -759,6 +759,70 @@ class ViewQCDSlot(Operator): return {'FINISHED'} +class UnassignedQCDSlot(Operator): + bl_label = "" + bl_idname = "view3d.unassigned_qcd_slot" + bl_options = {'REGISTER', 'UNDO'} + + slot: StringProperty() + + @classmethod + def description(cls, context, properties): + slot_string = f"Unassigned QCD Slot {properties.slot}:\n" + + hotkey_string = ( + " * LMB - Create slot.\n" + " * Shift+LMB - Create and isolate slot.\n" + " * Ctrl+LMB - Create and move objects to slot.\n" + " * Ctrl+Shift+LMB - Create and add objects to slot" + ) + + return f"{slot_string}{hotkey_string}" + + def invoke(self, context, event): + modifiers = get_modifiers(event) + + new_collection = bpy.data.collections.new(f"Collection {self.slot}") + context.scene.collection.children.link(new_collection) + internals.qcd_slots.add_slot(f"{self.slot}", new_collection.name) + + # update tree view property + update_property_group(context) + + if modifiers == {"shift"}: + bpy.ops.view3d.view_qcd_slot(slot=self.slot, toggle=False) + + elif modifiers == {"ctrl"}: + bpy.ops.view3d.move_to_qcd_slot(slot=self.slot, toggle=False) + + elif modifiers == {"ctrl", "shift"}: + bpy.ops.view3d.move_to_qcd_slot(slot=self.slot, toggle=True) + + else: + pass + + return {'FINISHED'} + + +class CreateAllQCDSlots(Operator): + bl_label = "Create All QCD Slots" + bl_description = "Create any missing QCD slots so you have a full 20" + bl_idname = "view3d.create_all_qcd_slots" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + for slot_number in range(1, 21): + if not internals.qcd_slots.get_name(f"{slot_number}"): + new_collection = bpy.data.collections.new(f"Collection {slot_number}") + context.scene.collection.children.link(new_collection) + internals.qcd_slots.add_slot(f"{slot_number}", new_collection.name) + + # update tree view property + update_property_group(context) + + return {'FINISHED'} + + class RenumerateQCDSlots(Operator): bl_label = "Renumber QCD Slots" bl_description = ( diff --git a/object_collection_manager/ui.py b/object_collection_manager/ui.py index b7bc1b32..ec2c7354 100644 --- a/object_collection_manager/ui.py +++ b/object_collection_manager/ui.py @@ -1016,6 +1016,10 @@ class EnableAllQCDSlotsMenu(Menu): def draw(self, context): layout = self.layout + layout.operator("view3d.create_all_qcd_slots") + + layout.separator() + layout.operator("view3d.enable_all_qcd_slots") layout.operator("view3d.enable_all_qcd_slots_isolated") @@ -1100,7 +1104,8 @@ def view3d_header_qcd_slots(self, context): prop.slot = str(x+1) else: - row.label(text="", icon='X') + prop = row.operator("view3d.unassigned_qcd_slot", text="", icon='X', emboss=False) + prop.slot = str(x+1) if idx%5==0: diff --git a/rigify/generate.py b/rigify/generate.py index aa9a9a84..5e95bd99 100644 --- a/rigify/generate.py +++ b/rigify/generate.py @@ -21,7 +21,6 @@ import bpy import re import time -from rna_prop_ui import rna_idprop_ui_prop_get from .utils.errors import MetarigError from .utils.bones import new_bone @@ -66,6 +65,17 @@ class Generator(base_generate.BaseGenerator): return rig_module.Rig + def __switch_to_usable_collection(self, obj, fallback=False): + collections = filter_layer_collections_by_object(self.usable_collections, obj) + + if collections: + self.layer_collection = collections[0] + elif fallback: + self.layer_collection = self.view_layer.layer_collection + + self.collection = self.layer_collection.collection + + def __create_rig_object(self): scene = self.scene id_store = self.id_store @@ -80,33 +90,36 @@ class Generator(base_generate.BaseGenerator): obj = None + # Try existing object if overwriting if meta_data.rigify_generate_mode == 'overwrite': obj = meta_data.rigify_target_rig - if not obj and name in scene.objects: - obj = scene.objects[name] - if obj: self.rig_old_name = obj.name obj.name = name obj.data.name = obj.name - rig_collections = filter_layer_collections_by_object(self.usable_collections, obj) - self.layer_collection = (rig_collections + [self.layer_collection])[0] - self.collection = self.layer_collection.collection - elif name in bpy.data.objects: obj = bpy.data.objects[name] + # Create a new object if not found if not obj: obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) obj.display_type = 'WIRE' - self.collection.objects.link(obj) - elif obj.name not in self.collection.objects: # rig exists but was deleted + # If the object is already added to the scene, switch to its collection + if obj.name in self.context.scene.collection.all_objects: + self.__switch_to_usable_collection(obj) + else: + # Otherwise, add to the selected collection or the metarig collection if unusable + if (self.layer_collection not in self.usable_collections + or self.layer_collection == self.view_layer.layer_collection): + self.__switch_to_usable_collection(self.metarig, True) + self.collection.objects.link(obj) + # Configure and remember the object meta_data.rigify_target_rig = obj obj.data.pose_position = 'POSE' @@ -114,6 +127,23 @@ class Generator(base_generate.BaseGenerator): return obj + def __unhide_rig_object(self, obj): + # Ensure the object is visible and selectable + obj.hide_set(False, view_layer=self.view_layer) + obj.hide_viewport = False + + if not obj.visible_get(view_layer=self.view_layer): + raise Exception('Could not generate: Target rig is not visible') + + obj.select_set(True, view_layer=self.view_layer) + + if not obj.select_get(view_layer=self.view_layer): + raise Exception('Could not generate: Cannot select target rig') + + if self.layer_collection not in self.usable_collections: + raise Exception('Could not generate: Could not find a usable collection.') + + def __create_widget_group(self): new_group_name = "WGTS_" + self.obj.name wgts_group_name = "WGTS_" + (self.rig_old_name or self.obj.name) @@ -374,17 +404,17 @@ class Generator(base_generate.BaseGenerator): self.usable_collections = list_layer_collections(view_layer.layer_collection, selectable=True) - if self.layer_collection not in self.usable_collections: - metarig_collections = filter_layer_collections_by_object(self.usable_collections, self.metarig) - self.layer_collection = (metarig_collections + [view_layer.layer_collection])[0] - self.collection = self.layer_collection.collection - bpy.ops.object.mode_set(mode='OBJECT') #------------------------------------------ # Create/find the rig object and set it up obj = self.__create_rig_object() + self.__unhide_rig_object(obj) + + # Select the chosen working collection in case it changed + self.view_layer.active_layer_collection = self.layer_collection + # Get rid of anim data in case the rig already existed print("Clear rig animation data.") @@ -415,7 +445,6 @@ class Generator(base_generate.BaseGenerator): #------------------------------------------ # Put the rig_name in the armature custom properties - rna_idprop_ui_prop_get(obj.data, "rig_id", create=True) obj.data["rig_id"] = self.rig_id self.script = rig_ui_template.ScriptGenerator(self) diff --git a/rigify/utils/mechanism.py b/rigify/utils/mechanism.py index 92e161f6..00aef154 100644 --- a/rigify/utils/mechanism.py +++ b/rigify/utils/mechanism.py @@ -23,7 +23,7 @@ import re from bpy.types import bpy_prop_collection, Material -from rna_prop_ui import rna_idprop_ui_create, rna_idprop_ui_prop_get +from rna_prop_ui import rna_idprop_ui_create from rna_prop_ui import rna_idprop_quote_path as quote_property from .misc import force_lazy @@ -137,7 +137,7 @@ def make_property( """ # Some keyword argument defaults differ - return rna_idprop_ui_create( + rna_idprop_ui_create( owner, name, default = default, min = min, max = max, soft_min = soft_min, soft_max = soft_max, description = description or name, @@ -440,8 +440,9 @@ def deactivate_custom_properties(obj, *, reset=True): for key, value in obj.items(): valtype = type(value) if valtype in {int, float}: - info = rna_idprop_ui_prop_get(obj, key, create=False) or {} - obj[key] = valtype(info.get("default", 0)) + ui_data = obj.id_properties_ui(key) + rna_data = ui_data.as_dict() + obj[key] = valtype(rna_data.get("default", 0)) def reactivate_custom_properties(obj): @@ -462,21 +463,19 @@ def reactivate_custom_properties(obj): def copy_custom_properties(src, dest, *, prefix='', dest_prefix='', link_driver=False, overridable=True): """Copy custom properties with filtering by prefix. Optionally link using drivers.""" res = [] - exclude = {'_RNA_UI', 'rigify_parameters', 'rigify_type'} + exclude = {'rigify_parameters', 'rigify_type'} for key, value in src.items(): if key.startswith(prefix) and key not in exclude: new_key = dest_prefix + key[len(prefix):] - info = rna_idprop_ui_prop_get(src, key, create=False) + ui_data_src = src.id_properties_ui(key) + if src != dest or new_key != key: dest[new_key] = value - if info: - info2 = rna_idprop_ui_prop_get(dest, new_key, create=True) - for ki, vi in info.items(): - info2[ki] = vi + dest.id_properties_ui(new_key).update_from(ui_data_src) if link_driver: make_driver(src, quote_property(key), variables=[(dest.id_data, dest, new_key)]) @@ -484,7 +483,7 @@ def copy_custom_properties(src, dest, *, prefix='', dest_prefix='', link_driver= if overridable: dest.property_overridable_library_set(quote_property(new_key), True) - res.append((key, new_key, value, info)) + res.append((key, new_key, value)) return res @@ -500,7 +499,7 @@ def copy_custom_properties_with_ui(rig, src, dest_bone, *, ui_controls=None, **o if mapping: panel = rig.script.panel_with_selected_check(rig, ui_controls or rig.bones.flatten('ctrl')) - for key,new_key,value,info in sorted(mapping, key=lambda item: item[1]): + for key,new_key,value in sorted(mapping, key=lambda item: item[1]): name = new_key # Replace delimiters with spaces @@ -513,6 +512,7 @@ def copy_custom_properties_with_ui(rig, src, dest_bone, *, ui_controls=None, **o if name.lower() == name: name = name.title() + info = bone.id_properties_ui(new_key).as_dict() slider = type(value) is float and info and info.get("min", None) == 0 and info.get("max", None) == 1 panel.custom_prop(dest_bone, new_key, text=name, slider=slider) diff --git a/space_view3d_math_vis/utils.py b/space_view3d_math_vis/utils.py index 7910bb9c..50c8aba3 100644 --- a/space_view3d_math_vis/utils.py +++ b/space_view3d_math_vis/utils.py @@ -50,6 +50,12 @@ class VarStates: # console variables. state_props = bpy.context.window_manager.MathVisStatePropList variables = get_math_data() + + for index, state_prop in reversed(list(enumerate(state_props))): + if state_prop.name not in variables: + # Variable has been removed from console + state_props.remove(index) + for key, ktype in variables.items(): if key and key not in state_props: prop = state_props.add() |