First i will do a mathless version using a convoluted, yet pretty fast, way to get at the
global length of a curve.
This might be a little excessive, but here is a small script that you run from text editor, then in 3dview a button appears when you select a curve.
When pressed:
- it duplicates the curve as a mesh,
- applies all transforms to the duplicate (for global coordinate values)
- sums the collected the edges of this mesh
- prints the length to the terminal + copies value to clipboard
- then deletes duplicate mesh
- selects original curve again
This might be a little excessive, but here is a small script that you run from text editor, then in 3dview a button appears when you select a curve.
When pressed:
- it duplicates the curve as a mesh,
- applies all transforms to the duplicate (for global coordinate values)
- sums the collected the edges of this mesh
- prints the length to the terminal + copies value to clipboard
- then deletes duplicate mesh
- selects original curve again
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import mathutils | |
from mathutils import Vector | |
def get_length(context): | |
obj_name_original = context.active_object.name | |
bpy.ops.object.duplicate_move() | |
# the duplicate is active, apply all transforms to get global coordinates | |
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) | |
# convert to mesh | |
bpy.ops.object.convert(target='MESH', keep_original=False) | |
_data = context.active_object.data | |
edge_length = 0 | |
for edge in _data.edges: | |
vert0 = _data.vertices[edge.vertices[0]].co | |
vert1 = _data.vertices[edge.vertices[1]].co | |
edge_length += (vert0-vert1).length | |
# deal with trailing float smear | |
edge_length = '{:.6f}'.format(edge_length) | |
print(edge_length) | |
# stick into clipboard | |
context.window_manager.clipboard = edge_length | |
bpy.ops.object.delete() | |
context.scene.objects.active = context.scene.objects[obj_name_original] | |
context.object.select = True | |
class ButtonOne(bpy.types.Operator): | |
"""Defines a button""" | |
bl_idname = "scene.dostuff" | |
bl_label = "Sometype of operator" | |
def execute(self, context): | |
get_length(context) | |
return{'FINISHED'} | |
class OperatorPanel(bpy.types.Panel): | |
"""Creates a Panel in the Object properties window""" | |
bl_label = "Some Utility" | |
bl_idname = "OBJECT_PT_somefunction" | |
bl_space_type = "VIEW_3D" | |
bl_region_type = "UI" | |
bl_context = "object" | |
def draw(self, context): | |
layout = self.layout | |
obj = context.object | |
row = layout.row() | |
# display label and button | |
if not obj.type == 'Curve' and context.active_object.select: | |
row.label(text="Active object is: " + obj.name) | |
self.layout.operator("scene.dostuff", text='Print length to console') | |
classes = [OperatorPanel, ButtonOne] | |
def register(): | |
for i in classes: | |
bpy.utils.register_class(i) | |
def unregister(): | |
for i in classes: | |
bpy.utils.unregister_class(i) | |
if __name__ == "__main__": | |
register() |