Merge branch 'master' into xr-controller-support
This commit is contained in:
commit
f02773d5ed
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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": "",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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')
|
||||
self._gl_state_push(snap_obj.mat)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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._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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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 = (
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'
|
||||
|
||||
# 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)
|
||||
|
||||
elif obj.name not in self.collection.objects: # rig exists but was deleted
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue