From 64eeb14bf27dd64074cedaae02c00a2227849152 Mon Sep 17 00:00:00 2001 From: jim man Date: Thu, 26 Aug 2021 12:55:56 +0200 Subject: Node Wrangler: remove unnecessary code Differential Revision: https://developer.blender.org/D12076 --- node_wrangler.py | 3 --- 1 file changed, 3 deletions(-) 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 -- cgit v1.2.3 From 5b76cb1d313cb2ca72c477a62b59e6718481b00b Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 26 Aug 2021 10:25:55 -0300 Subject: Snap_Utilities_Line: update clip distance API --- mesh_snap_utilities_line/__init__.py | 2 +- mesh_snap_utilities_line/common_classes.py | 4 +- mesh_snap_utilities_line/drawing_utilities.py | 118 ++++++++++++--------- .../snap_context_l/mesh_drawing.py | 6 +- .../snap_context_l/shaders/ID_color_frag.glsl | 17 --- .../snap_context_l/shaders/ID_color_vert.glsl | 10 +- 6 files changed, 82 insertions(+), 75 deletions(-) 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/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 -- cgit v1.2.3 From 53c7859c9135eeb5274008d4d6caa8364ea0c308 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 26 Aug 2021 13:07:25 -0300 Subject: Cleanup: redundant imports --- mesh_snap_utilities_line/op_line.py | 1 - mesh_snap_utilities_line/widgets.py | 1 - 2 files changed, 2 deletions(-) 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/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): -- cgit v1.2.3 From 104ba1c5682016a55b8a8ed06be52e0c05e913e9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Aug 2021 08:29:15 -0500 Subject: Update addons for D9697 "_RNA_UI" removal This is a followup patch for D9697 which applies the changes to the addon reporistory. Almost all of the changes are in rigify, but there is one change in "curve_tools" and two trivial changes in IO addons. Differential Revision: https://developer.blender.org/D9919 --- add_camera_rigs/build_rigs.py | 28 +++++++--------------- curve_tools/auto_loft.py | 16 +++++-------- io_scene_fbx/export_fbx_bin.py | 2 +- io_scene_gltf2/blender/com/gltf2_blender_extras.py | 2 +- rigify/generate.py | 2 -- rigify/utils/mechanism.py | 24 +++++++++---------- 6 files changed, 28 insertions(+), 46 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/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_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/rigify/generate.py b/rigify/generate.py index aa9a9a84..caff2633 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 @@ -415,7 +414,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) -- cgit v1.2.3 From 326e03a597cfe32db0ea234807ada69b9971e76b Mon Sep 17 00:00:00 2001 From: Pullusb Date: Sun, 29 Aug 2021 18:23:52 +0200 Subject: GPencil Tools: Fix T90976 Timeline-scrub toggle Add a checkbox in preference to Disable timeline-scrub feature. Following task https://developer.blender.org/T90976 required for industry standard keymap conflict. Also Add {key Numpad Enter} to valid Box-deform (following user request https://github.com/Pullusb/greasepencil-addon/issues/8) --- greasepencil_tools/__init__.py | 2 +- greasepencil_tools/box_deform.py | 6 +++--- greasepencil_tools/prefs.py | 2 +- greasepencil_tools/timeline_scrub.py | 22 +++++++++++++++++----- 4 files changed, 22 insertions(+), 10 deletions(-) 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') -- cgit v1.2.3 From 65e477d88426d14f3ac24d054b132ebdeeab0867 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 29 Aug 2021 23:02:25 +0300 Subject: Rigify: unhide the rig before generation if it is hidden. Rig generation fails if the target rig that is to be overwritten is hidden, either directly or via collections. To improve usability, try unhiding the object, and fail with an appropriate message if it doesn't work. In addition, slightly refactor code that selects a suitable unhidden collection to use for generation. This started as D11355 by @Mets, but was somewhat refactored. --- rigify/generate.py | 59 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/rigify/generate.py b/rigify/generate.py index caff2633..5e95bd99 100644 --- a/rigify/generate.py +++ b/rigify/generate.py @@ -65,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 @@ -79,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' @@ -113,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) @@ -373,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.") -- cgit v1.2.3 From f583ecf0ad14d969c8b53f8a4234c1b5df9a0703 Mon Sep 17 00:00:00 2001 From: Ryan Inch Date: Sun, 29 Aug 2021 22:15:39 -0400 Subject: Collection Manager: Improve UI for adding QCD slots. Task: T69577 Replace the X labels in the QCD header widget with operators that generate the corresponding slot when clicked, allows for moving objects to the new slot by pressing hotkeys when clicking. Each unassigned slot operator has a tooltip specifying it's an unassigned slot, which slot number it corresponds to, and lists the hotkeys that can be used with it and their functions. Adds a menu item to the QVT menu (the eye icon beside the QCD header widget) to add any missing QCD slots so that you end up with a full 20 slots. --- object_collection_manager/__init__.py | 2 +- object_collection_manager/qcd_init.py | 2 + object_collection_manager/qcd_operators.py | 64 ++++++++++++++++++++++++++++++ object_collection_manager/ui.py | 7 +++- 4 files changed, 73 insertions(+), 2 deletions(-) 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: -- cgit v1.2.3 From 36edc11a436d73e3e503396ffe1c14136e37db8d Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 28 Aug 2021 14:55:47 +0200 Subject: When deleting a variable from the console, the MathVis data is not updated. When later trying to remove the data from MathVis we see a stack trace. This patch takes care to update the MathVis list instantly via the VarStates:store_states() hook --- space_view3d_math_vis/utils.py | 6 ++++++ 1 file changed, 6 insertions(+) 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() -- cgit v1.2.3 From 36671a4e21b2e2ad7fd381a0529cde2a63505097 Mon Sep 17 00:00:00 2001 From: Iyad Ahmed Date: Tue, 31 Aug 2021 10:12:52 +0200 Subject: Fix: Material Library VX add-on cannot apply library materials to selected object Fix https://developer.blender.org/T90483, https://developer.blender.org/T89680 Reviewed By: mont29, dfelinto, campbellbarton Maniphest Tasks: T89740, T90483, T89680 Differential Revision: https://developer.blender.org/D12214 --- materials_library_vx/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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] -- cgit v1.2.3 From 4e30cfd30603c3bd8e4f7ecdea77cc65ec213d3a Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 31 Aug 2021 09:43:04 +0200 Subject: FBX Import: skip invalid custom enum properties This was (correctly) asserting before, now handle this more gracefully and just skip (and warn about this) a custom property that has an invalid value set. Seems there are a couple of exporters out there that do this wrong, I think this tradeoff can be made though. Fixes T91062, T81657, T83501, T86595 Maniphest Tasks: T91062, T86595, T83501, T81657 Differential Revision: https://developer.blender.org/D12354 --- io_scene_fbx/__init__.py | 2 +- io_scene_fbx/import_fbx.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) 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/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: -- cgit v1.2.3