Skip to content

Instantly share code, notes, and snippets.

@Eterea
Last active August 12, 2020 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eterea/8896a727d490f75d5204df97f8580b28 to your computer and use it in GitHub Desktop.
Save Eterea/8896a727d490f75d5204df97f8580b28 to your computer and use it in GitHub Desktop.
#python
# ------------------------------------------------------------------------------------------------
# NAME: etr_super_edgeLength_calculator.py
# VERS: 1.0
# DATE: August 11, 2020
#
# MADE: Cristobal Vila, etereaestudios.com, with snippets kindly shared by
# Shawn Frueh, shawnfrueh.com/me/ and also 'robberyman'
# ------------------------------------------------------------------------------------------------
"""
SUPER EDGE LENGTH CALCULATOR
------------------------------------------------------------------------------------------------
Next pure Python API snippet is a mix between the one shared by Shawn Frueh:
https://foundry-modo.slack.com/archives/C6F918JEB/p1596930293212700
And also this one shared by 'robberyman':
https://foundry-modo.slack.com/archives/C6F918JEB/p1597076342264900
With this we can calculate the total accumulated length for all selected edges, no matter
these ones belong to different item meshes, procedural, deformed, animated... ALL!
"""
import lxu, lx
import math
TOTAL_LENGTH = 0
# Initialize the selection service
SELECTION_SERVICE = lxu.service.Selection()
# Get the edge selection int type
edge_selection_type = SELECTION_SERVICE.LookupType(lx.symbol.sSELTYP_EDGE)
# Get the selection object: lxu.object.SelectionType
edge_selection_object = SELECTION_SERVICE.Allocate(lx.symbol.sSELTYP_EDGE)
# Convert that type into a packet so that we can access the selection data
edge_translation_packet = lx.object.EdgePacketTranslation(edge_selection_object)
# Get the total count of selected points
selected_edge_count = SELECTION_SERVICE.Count(edge_selection_type)
# Iterate over each edge and get some data. These edges could be coming from multiple meshes
# and so you will need to check the item they be
for edge_index in range(selected_edge_count):
# Get a pointer to the vertex data in the given index.
edge_pointer = SELECTION_SERVICE.ByIndex(edge_selection_type, edge_index)
# If we don't get a pointer, skip to the next index in the loop.
# This is necessary to prevent any crashes.
if not edge_pointer:
continue
# Get the item the edge belongs to: lxu.object.Item
selection_item = edge_translation_packet.Item(edge_pointer)
item = lx.object.Item(selection_item)
# Get the matrix channel index
matrix_index = selection_item.ChannelLookup("worldMatrix")
# Prep the selection item to be read at the current time. You want those animated points!
selection_item.ReadEvaluated(SELECTION_SERVICE.GetTime())
# Get the matrix from the channel as a COM object and convert it to a matrix object.
item_world_matrix = lx.object.Matrix(selection_item.ChannelValue(matrix_index))
# Get the mesh item the edge belongs to: lxu.object.Mesh
selection_mesh = edge_translation_packet.Mesh(edge_pointer)
mesh = lx.object.Mesh(selection_mesh)
# IDs for the edge endpoints,
aPoint, bPoint = edge_translation_packet.Vertices(edge_pointer)
point = mesh.PointAccessor()
# Select and get the position of boths points. This will be relative to the mesh
# So if the mesh is not zero you will need to multiply this position by the transform data
# of the item it belongs to. We do this by multiplying it by the world matrix of it's item.
point.Select(aPoint)
posA = item_world_matrix.MultiplyVector(point.Pos())
point.Select(bPoint)
posB = item_world_matrix.MultiplyVector(point.Pos())
ABX = posA[0] - posB[0]
ABY = posA[1] - posB[1]
ABZ = posA[2] - posB[2]
AB_distance = math.sqrt(ABX**2 + ABY**2 + ABZ**2) # Pythagoras Theorem
TOTAL_LENGTH += AB_distance
print 'TOTAL_LENGTH:', TOTAL_LENGTH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment