Skip to content

Instantly share code, notes, and snippets.

@Volantk
Last active March 6, 2022 15:38
Show Gist options
  • Save Volantk/034959717c88baac5c4f554292c0c979 to your computer and use it in GitHub Desktop.
Save Volantk/034959717c88baac5c4f554292c0c979 to your computer and use it in GitHub Desktop.
With 2 objects selected, will merge children of first selected into last selected. Geo will be replaced in objects found in both hierarchies. New objects will be added. Objects no longer found in first selected will be removed from last selected.
import pymxs
def delete_hidden_children_of(obj):
print("Deleting hidden children of " + obj.name)
hidden = [c for c in obj.children if c.isNodeHidden]
for i in range(len(hidden)):
pymxs.runtime.delete(hidden[i])
def delete(single_obj):
print("Deleting " + single_obj.name)
pymxs.runtime.delete(single_obj)
def delete_list(obj_list):
for i in range(len(obj_list)):
delete(obj_list[i])
def setparent(obj, newparent):
print("Parenting " + obj.name + " to " + newparent.name)
obj.parent = newparent
def setparent_list(obj_list, newparent):
for i in range(len(obj_list)):
setparent(obj_list[i], newparent)
def delete_all_verts(obj):
print("Deleting all verts in " + obj.name)
numverts = obj.numverts
to_delete = []
# probably nicer ways to get the index list, but eh, it works.
for i in range(numverts):
to_delete.append(i+1) # starts at 1...
pymxs.runtime.polyop.deleteVerts(obj,to_delete)
def attach(to_merge, destination):
print("Attaching: " + destination.name + " <- " + to_merge.name)
pymxs.runtime.polyop.attach(destination, to_merge)
def merge_with_other_hierarchy(firstSelected, lastSelected):
print("\nSTARTING UP\n")
print("New objects: " + firstSelected.name)
print("Old hierarchy to be reused: " + lastSelected.name)
# stupid but effective safeguard
if "baked" not in lastSelected.name.lower():
print("'baked' not found in lastSelected name... Wrong selection order? Select BAKED object last.")
return
# clean starting point
delete_hidden_children_of(firstSelected)
newNames = [c.name for c in firstSelected.children]
oldNames = [c.name for c in lastSelected.children]
# simple delete or copy
oldToDelete = [c for c in lastSelected.children if c.name not in newNames]
newToCopy = [c for c in firstSelected.children if c.name not in oldNames]
# which meshes to attach
oldToReplace = [c for c in lastSelected.children if c.name in newNames]
newToMerge = [c for c in firstSelected.children if c.name in oldNames]
# create dictionary for attaching
attachmap = {}
for b in oldToReplace:
a = None
for oa in newToMerge:
if oa.name == b.name:
a = oa
break
attachmap[b] = a
# replace with new geo (remove verts, then attach)
for old, new in attachmap.items():
delete_all_verts(old)
attach(new, old)
# delete and reparent
delete_list(oldToDelete)
setparent_list(newToCopy, lastSelected)
# remove parent that no longer has any children :'(
delete(firstSelected)
print("DONE")
if(len(selected) == 2):
merge_with_other_hierarchy(selected[0], selected[1])
else:
print("Wrong amount of objects selected " + "(" + str(len(selected)) + ")")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment