Skip to content

Instantly share code, notes, and snippets.

@tcrowson
Last active April 11, 2018 20:56
Show Gist options
  • Save tcrowson/4f86f321cb57289cef13 to your computer and use it in GitHub Desktop.
Save tcrowson/4f86f321cb57289cef13 to your computer and use it in GitHub Desktop.
Modo 901 command for freezing a morph to a new mesh.
# Command for freezing a morph to a new mesh.
# 1. Select a morph map
# 2. run morph.freezeToMesh
# 3. A new mesh bearing the name of the morph map will be created, with the frozen morph shape in it.
import lx
import lxu
import lxifc
import modo
def ensure_mesh_selection():
''' Return selected meshes, False if none '''
meshes = [x for x in modo.Scene().selected if x.type == 'mesh']
if len(meshes) == 0:
modo.dialogs.alert('FAILED',
'Please select a mesh.',
'warning')
return False
return meshes
def get_selected_vmaps(map_type):
''' Return a list of selected vmap names '''
# Get selected weight map.
# Hopefully in SP2 we'll get a wrapper for this.
selected_vmap_names = []
sel_serv = lx.service.Selection()
vmap_sel_code = sel_serv.LookupType(lx.symbol.sSELTYP_VERTEXMAP)
vmap_trans_packet = lx.object.VMapPacketTranslation(sel_serv.Allocate(lx.symbol.sSELTYP_VERTEXMAP))
map_count = sel_serv.Count(vmap_sel_code)
for i in range(map_count):
packet_pointer = sel_serv.ByIndex(vmap_sel_code, i)
if vmap_trans_packet.Type(packet_pointer) == map_type:
map_name = vmap_trans_packet.Name(packet_pointer)
selected_vmap_names.append(map_name)
return selected_vmap_names
class MorphToMesh(lxu.command.BasicCommand):
''' Command class for rigtools.morphToMesh '''
def __init__(self):
lxu.command.BasicCommand.__init__(self)
def cmd_Interact(self):
pass
def cmd_Flags(self):
return lx.symbol.fCMD_MODEL | lx.symbol.fCMD_UNDO
def basic_Execute(self, msg, flags):
# check mesh selection
mesh_selection = ensure_mesh_selection()
if mesh_selection:
# get first selected mesh
mesh = mesh_selection[0]
# get selected morph names
selected_morph_names = get_selected_vmaps(lx.symbol.i_VMAP_MORPH)
for morph_name in selected_morph_names:
# get the morph object. For now we have to avoid a direct name lookup
# via geometry.vmaps('MyMap'), due to a bug in the TD API.
morph = [m for m in mesh.geometry.vmaps.morphMaps if m.name == morph_name][0]
# deselect the morph. This seems necessary to avoid double transforms on morphs.
lx.eval("select.vertexMap name:{%s} type:{morf} mode:{remove}" %morph_name)
# store positions
abs_positions = {}
for idx, position in enumerate(morph):
abs_positions[idx] = morph.getAbsolutePosition(idx)
# duplicate the mesh
new_mesh = modo.Scene().duplicateItem(mesh, False)
# delete its morphs
new_mesh.select(True)
for x in new_mesh.geometry.vmaps.morphMaps:
lx.eval("vertmap.deleteByName type:{morf} name:{%s}" %x.name)
# rename the mesh
new_mesh.name = '%s_%s' %(mesh.name, morph_name)
# set positions stored earlier
for vert in new_mesh.geometry.vertices:
vert.position = abs_positions[vert.index]
# update geo
new_mesh.geometry.setMeshEdits()
return lx.result.OK
lx.bless(MorphToMesh, "morph.freezeToMesh")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment