object picker
This commit is contained in:
parent
606df32fcb
commit
209197e4aa
61
__init__.py
61
__init__.py
@ -101,7 +101,6 @@ def add_capped_frustum(bm: bmesh.types.BMesh,
|
|||||||
hr = [bm.verts.new(p) for p in _apply(head_mat, _ring_positions(head_radius, tables))]
|
hr = [bm.verts.new(p) for p in _apply(head_mat, _ring_positions(head_radius, tables))]
|
||||||
tr = [bm.verts.new(p) for p in _apply(tail_mat, _ring_positions(tail_radius, tables))]
|
tr = [bm.verts.new(p) for p in _apply(tail_mat, _ring_positions(tail_radius, tables))]
|
||||||
|
|
||||||
# Side quads
|
|
||||||
for i in range(segs):
|
for i in range(segs):
|
||||||
nxt = (i + 1) % segs
|
nxt = (i + 1) % segs
|
||||||
try:
|
try:
|
||||||
@ -109,7 +108,6 @@ def add_capped_frustum(bm: bmesh.types.BMesh,
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Head cap
|
|
||||||
hcv = bm.verts.new(head_pos)
|
hcv = bm.verts.new(head_pos)
|
||||||
for i in range(segs):
|
for i in range(segs):
|
||||||
try:
|
try:
|
||||||
@ -117,7 +115,6 @@ def add_capped_frustum(bm: bmesh.types.BMesh,
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Tail cap
|
|
||||||
tcv = bm.verts.new(tail_pos)
|
tcv = bm.verts.new(tail_pos)
|
||||||
for i in range(segs):
|
for i in range(segs):
|
||||||
try:
|
try:
|
||||||
@ -148,7 +145,7 @@ def _end_matrices(world_mat: Matrix, bone_matrix: Matrix, bone_length: float):
|
|||||||
our Z = bone Y (ring normal → along bone)
|
our Z = bone Y (ring normal → along bone)
|
||||||
"""
|
"""
|
||||||
bx = bone_matrix.col[0].to_3d()
|
bx = bone_matrix.col[0].to_3d()
|
||||||
by = bone_matrix.col[1].to_3d() # along bone
|
by = bone_matrix.col[1].to_3d()
|
||||||
bz = bone_matrix.col[2].to_3d()
|
bz = bone_matrix.col[2].to_3d()
|
||||||
|
|
||||||
orient = Matrix((
|
orient = Matrix((
|
||||||
@ -177,7 +174,8 @@ class ARMATURE_OT_build_envelope_mesh(bpy.types.Operator):
|
|||||||
bl_label = "Build Envelope Mesh"
|
bl_label = "Build Envelope Mesh"
|
||||||
bl_description = (
|
bl_description = (
|
||||||
"Convert the selected armature into an envelope-style mesh. "
|
"Convert the selected armature into an envelope-style mesh. "
|
||||||
"Object/Pose mode = posed bones | Edit mode = edit bones."
|
"If a target object is set in the panel, its mesh is replaced in place. "
|
||||||
|
"Otherwise a new object is created and assigned as the target."
|
||||||
)
|
)
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
@ -219,17 +217,44 @@ class ARMATURE_OT_build_envelope_mesh(bpy.types.Operator):
|
|||||||
bone.bone.head_radius, bone.bone.tail_radius,
|
bone.bone.head_radius, bone.bone.tail_radius,
|
||||||
bone.parent is None)
|
bone.parent is None)
|
||||||
|
|
||||||
mesh = bpy.data.meshes.new(arm_obj.name + "_envelope_mesh")
|
panel_props = context.scene.envelope_mesher
|
||||||
bm.to_mesh(mesh)
|
target = panel_props.target
|
||||||
bm.free()
|
|
||||||
mesh.update()
|
|
||||||
|
|
||||||
result_obj = bpy.data.objects.new(arm_obj.name + "_envelope", mesh)
|
if target is not None:
|
||||||
context.collection.objects.link(result_obj)
|
# Destructively replace the target's mesh data.
|
||||||
|
old_mesh = target.data
|
||||||
|
new_mesh = bpy.data.meshes.new(old_mesh.name)
|
||||||
|
bm.to_mesh(new_mesh)
|
||||||
|
bm.free()
|
||||||
|
new_mesh.update()
|
||||||
|
target.data = new_mesh
|
||||||
|
bpy.data.meshes.remove(old_mesh)
|
||||||
|
else:
|
||||||
|
# Create a new object and hand it back to the panel picker.
|
||||||
|
new_mesh = bpy.data.meshes.new(arm_obj.name + "_envelope_mesh")
|
||||||
|
bm.to_mesh(new_mesh)
|
||||||
|
bm.free()
|
||||||
|
new_mesh.update()
|
||||||
|
result_obj = bpy.data.objects.new(arm_obj.name + "_envelope", new_mesh)
|
||||||
|
context.collection.objects.link(result_obj)
|
||||||
|
panel_props.target = result_obj
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Panel properties
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class EnvelopeMesherProperties(bpy.types.PropertyGroup):
|
||||||
|
target: bpy.props.PointerProperty(
|
||||||
|
name="Target",
|
||||||
|
description="Object whose mesh will be replaced on each run. "
|
||||||
|
"Leave empty to create a new object on first run.",
|
||||||
|
type=bpy.types.Object,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Panel
|
# Panel
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -243,6 +268,10 @@ class VIEW3D_PT_armature_mesher(bpy.types.Panel):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
props = context.scene.envelope_mesher
|
||||||
|
|
||||||
|
layout.prop(props, "target")
|
||||||
|
|
||||||
op = layout.operator(
|
op = layout.operator(
|
||||||
ARMATURE_OT_build_envelope_mesh.bl_idname,
|
ARMATURE_OT_build_envelope_mesh.bl_idname,
|
||||||
text="Build Envelope Mesh",
|
text="Build Envelope Mesh",
|
||||||
@ -255,13 +284,21 @@ class VIEW3D_PT_armature_mesher(bpy.types.Panel):
|
|||||||
# Registration
|
# Registration
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
classes = (ARMATURE_OT_build_envelope_mesh, VIEW3D_PT_armature_mesher)
|
classes = (
|
||||||
|
EnvelopeMesherProperties,
|
||||||
|
ARMATURE_OT_build_envelope_mesh,
|
||||||
|
VIEW3D_PT_armature_mesher,
|
||||||
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.register_class(cls)
|
bpy.utils.register_class(cls)
|
||||||
|
bpy.types.Scene.envelope_mesher = bpy.props.PointerProperty(
|
||||||
|
type=EnvelopeMesherProperties,
|
||||||
|
)
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
del bpy.types.Scene.envelope_mesher
|
||||||
for cls in reversed(classes):
|
for cls in reversed(classes):
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user