Last active
April 11, 2018 20:56
-
-
Save tcrowson/4f86f321cb57289cef13 to your computer and use it in GitHub Desktop.
Modo 901 command for freezing a morph to a new mesh.
This file contains 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
# 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