Deleting Objects *Safely

MotionBuilder is really great at a lot of things. However, deleting objects is not one of those things. Piggy backing off of this blog post by Marcus Krautwurst, deleting often requires custom/order of operation sensitive scripting.

With more complicated scenes and constraints, sometimes even using the map( FBComponent.FBDelete, list_of_objects ) crashes mobu. To solve this, I wrote a method to handle deletion with a little more caution…and called it safe_delete_object. This method is shown below, along with a few simple convenience methods, use’m as you please.

def get_all_src( obj ):
	return [ obj.GetSrc( i ) for i in range( 0, obj.GetSrcCount( ) ) ]

def get_all_dst( obj ):
	return [ obj.GetDst( i ) for i in range( 0, obj.GetDstCount( ) ) ]

def safe_delete_object( objects ):
	# Convert the object to a list if the object isn't a list or tuple
	if not isinstance( objects, ( set, tuple, list ) ):
		objects = [ objects ]

	# Iterate through the list and disconnect/delete
	for obj in objects:
		assert isinstance( obj, pyfbsdk.FBPlug )

		obj.BeginChange()
		dst_objects = [ ]
		# Disconnect all Dst objects except for the Scene component.
		for i in range( 0, obj.GetDstCount( ) - 1 ):
			dst_objects.append( obj.GetDst( i ) )
		for dst_object in dst_objects:
			if not isinstance( dst_object, pyfbsdk.FBScene ):
				obj.DisconnectDst( dst_object )

		obj.DisconnectAllSrc( )
		obj.EndChange()
		obj.FBDelete( )


	pyfbsdk.FBSystem().Scene.Evaluate( )

	return True

Basically, all objects in mobu which derive from the FBComponent are connected to each other through Src & Dst’s ( just like inputs and outputs in Maya/Max etc. ). What I’ve written is a method  that runs through all the connections of a component and unplugs them. However, one of the destinations of each object is the FBScene ( like in fbxsdk ) and we don’t want to unplug an object from that. If you do, the object is left in purgatory where you can select the object in the viewer, but it doesn’t show up in the navigator. It also exists between scenes, but is not actually saved with the scene. This is why we stop when the obj.GetDstCount() is 1.

So long story short, if you’re trying to delete all or a lot of interconnected objects in your scene, this method alone won’t likely do the trick. It’s meant to be used as part of another larger method you’d use to delete objects from your scene in a specific order, like the one outlined in Marcus’ post linked above.

Live long and evaluate <3

Leave a Reply

Your email address will not be published. Required fields are marked *