What I have:
select two points then click “First” (get length between), then other two points - click “Second” (get length between), and then click “Scale” and get value “Second / First”.
Am I right with code, or somewhere it can be simplified?

import bpy
import bmesh
from bpy.types import Operator, Panel, PropertyGroup
def get_float1(self):
return self["l1"]
def set_float1(self, value):
self["l1"] = value
def get_float2(self):
return self["l2"]
def set_float2(self, value):
self["l2"] = value
def length_first():
obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
elem_list1 = []
for g in bm.select_history:
elem_list1.append(g)
lf1 = elem_list1[0].co
lf2 = elem_list1[1].co
length1 = (lf2 - lf1).length
print("First value =", length1)
return length1
def length_second():
obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
elem_list2 = []
for g in bm.select_history:
elem_list2.append(g)
ls1 = elem_list2[0].co
ls2 = elem_list2[1].co
length2 = (ls2 - ls1).length
print("Second value =", length2)
return length2
class VERTS_OT_length (Operator):
bl_idname = "verts.length"
bl_label = "l"
bl_description = ""
action: bpy.props.EnumProperty (
items=[('first','first',''),
('second','second',''),
('scale','scale','')])
def execute(self, context):
props = context.scene.LENGTH_PG_main
if self.action == "first":
props.l1 = length_first()
if self.action == "second":
props.l2 = length_second()
if self.action == "scale":
scale = props.l2 / props.l1
print("----------------------")
#print(props.l1)
#print(props.l2)
print("Scale =", scale)
return {'FINISHED'}
class LENGTH_PG_main (PropertyGroup):
l1: bpy.props.FloatProperty(
name="Get",
subtype="DISTANCE",
get=get_float1,
set=set_float1
)
l2: bpy.props.FloatProperty(
name="Set",
subtype="DISTANCE",
get=get_float2,
set=set_float2
)
class TEST_PT_main(Panel):
bl_label = "TEST"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'TEST'
def draw(self, context):
layout = self.layout
col = layout.column(align = True)
row1 = col.row(align = True)
props = context.scene.LENGTH_PG_main
row1.prop(props, "l1", text="")
row1.operator("verts.length", text="First").action = "first"
col = layout.column(align = True)
row2 = col.row(align = True)
props = context.scene.LENGTH_PG_main
row2.prop(props, "l2", text="")
row2.operator("verts.length", text="Second").action = "second"
col = layout.column()
col.operator("verts.length", text="Scale").action = "scale"
classes = (
VERTS_OT_length,
LENGTH_PG_main,
TEST_PT_main,
)
register, unregister = bpy.utils.register_classes_factory(classes)
def register():
for c in classes:
bpy.utils.register_class(c)
bpy.types.Scene.LENGTH_PG_main = bpy.props.PointerProperty(type = LENGTH_PG_main)
def unregister():
for c in classes:
bpy.utils.unregister_class(c)
del bpy.types.Scene.LENGTH_PG_main
if name == "main":
register()