'//Instances2DupesNullsOrClones vbs //mail2004@grahamdclark.com
'//December 02nd 2003
'//modified March 21st 2004 rewritten to be iterate thru a hierarchy instead of per selection
'//modified Thursday April 29th 2004 rewritten to corrct issue with recursive sometimes not working with instances inside of instances
'//modfied Sunday May 2nd to fix flatten hierarchy with children other than instances
'//Directions:
'//select model or parent containing instances,run script,select options,OK
'//options: 
'//-KeepHierarchy false will flatten hierarchy and remove all models and instances
'//-RemoveNullsIfNoHierarchy will remove all nulls if KeepHierarchy is set to false
'//-delete instances false, will leave them but hidden, regardless of setting they will be deleted if hierarchy is flattened
'//-KeepAnim will KeepAnim of each instance on the duplicate but not will not add up the animation if hierarchy is flattened
'//-duplicateOrClone will make instances into models with duplicates or clones 
'//(which means for example if an object containing is instanced again in a hierarchy then it will share the original clone source) 

Main()
'//////////////////////////////////
function Main()
'//////////////////////////////////
	GetValues oPPGCancelled,KeepHierarchy,DeleteInstances,KeepAnim,duplicateOrClone,RemoveNullsIfNoHierarchy,InstancedModels2NullsIfHierarchy,AllModels2NullsIfHierarchy
	if oPPGCancelled <> True then
		Set oColly = CreateObject("XSI.Collection")

		for each selected in selection
			oColly.Add selected
		next

		for i = 0 to oColly.count -1
			RecursiveInstance2Models oColly(i),oColly(i).children,DeleteInstances,KeepAnim,duplicateOrClone,InstancedModels2NullsIfHierarchy ,KeepHierarchy
			if KeepHierarchy = False then 
				FlattenHierarchy oColly(i),True,RemoveNullsIfNoHierarchy
			else
				if AllModels2NullsIfHierarchy then models2nulls(oColly(i))
			end if			
		next
	end if
end function


'////////////////////////////////////////////////////////
sub RecursiveInstance2Models(oCollyi,InputObj,DeleteInstances,KeepAnim,duplicateOrClone,InstancedModels2NullsIfHierarchy,KeepHierarchy)
'////////////////////////////////////////////////////////
'converts instance to model and keeps hierarchy and children(of the instances, not that anyone should be doing that) and new model is named same as instance was
'keeps name of instances on objects, (or NOTE2SELF: offer option to name according to master (with instance number if possible))
	dim list, msg, elem, name
	
	Set oColl = CreateObject("XSI.Collection")
	oColl.RemoveAll
	if Inputobj.count = 0 then
		exit sub
	end if	
	for each child in InputObj
			oColl.Add child
	next

	for i = 0 to oColl.count - 1
		set master = GetMaster(oColl.item(i))
		if typename(master) <> "Nothing" then
			name = master.name
			logmessage name
			oColl.item(i).name = name&"old"
			if duplicateOrClone then
				set dupe = duplicate("B:"&master)
			else
				set dupe = Clone("B:"&master,,,,,,,,0)
			end if
			
			'dupe(0).name = name
			ParentObj oColl.item(i), dupe
			ResetTransform dupe(0), siObj, siSRT, siXYZ
			ParentObj oColl.item(i).parent, dupe
			
			if KeepHierarchy And InstancedModels2NullsIfHierarchy then
				set oNull = oColl.item(i).addnull
				ResetTransform oNull, siObj, siSRT, siXYZ					
				ParentObj oColl.item(i).parent, oNull
				ParentObj oNull, dupe(0).children
				deleteObj dupe(0)
			else
				set oNull = dupe(0)				 
			end if
			
			oNull.name = name
			if oColl.item(i).children.count > 0 then ParentObj oNull,oColl.item(i).children
				
			if KeepAnim then
				if oColl.item(i).IsAnimated( siAnySource ) = True then
					CopyAllAnimation2 oColl.item(i), siAnySource, siAllParam, False
					PasteAllAnimation oNull
				end if
			end if
			if DeleteInstances then
				 DeleteObj "B:"&oColl.item(i)
			else
				 SetValue oColl.item(i)&".visibility.viewvis", False
			end if
			
			RecursiveInstance2Models oCollyi,oNull.children,DeleteInstances,KeepAnim,duplicateOrClone,InstancedModels2NullsIfHierarchy,KeepHierarchy			
		else
			RecursiveInstance2Models oCollyi,oColl.item(i).children,DeleteInstances,KeepAnim,duplicateOrClone,InstancedModels2NullsIfHierarchy,KeepHierarchy
		end if
		'logmessage 
		'if oColl.item(i) <>"nothing" then
		'end if
	next
end sub	

'/////////////////////////////////
function FlattenHierarchy(oInObj,RemoveModels,RemoveNulls)
'/////////////////////////////////

	set children = SelectChildNodes("B:"&oInObj,True,True)
	children.remove children.item(0)
	ParentObj oInObj, children
	if RemoveNulls then RemoveModels = False
	if RemoveModels then deleteObj oInObj.models
	set filteredCollection = oInObj.FindChildren(,,siNullPrimitiveFamily)
	if RemoveNulls then deleteObj filteredCollection
end function


'/////////////////////////////////
function models2nulls(inputObject)
'/////////////////////////////////
	'GetValues oPPGCancelled,RecursiveChildren
	'if RecursiveChildren then
		set cModel = inputObject.FindChildren(,"#model")
	'else
	'	set cModel = inputObject.models(false)
	'end if
	if inputObject.type = "#model" then 
		ival = 1
	else
		ival = 0
	end if
	for i = ival to cModel.count -1
		set master = GetMaster(cModel.item(i))
		if typename(master) = "Nothing" then
			sname = cModel.item(i).name
			set oNull = cModel.item(i).addnull
			ResetTransform oNull, siObj, siSRT, siXYZ
			ParentObj cModel.item(i).parent, oNull
			for each child in cModel.item(i).children
				'ParentObj oNull, cModel.item(i).children 'noworkie
				ParentObj oNull, child
			next
			deleteObj cModel.item(i)
			oNull.name = sname&"null"
		end if
	next
end function

'//////////////////////////////////
Function GetValues(oPPGCancelled,KeepHierarchy,DeleteInstances,KeepAnim,duplicateOrClone,RemoveNullsIfNoHierarchy,InstancedModels2NullsIfHierarchy,AllModels2NullsIfHierarchy)
'//////////////////////////////////
	set oRoot = application.activeproject.activescene.root
	set oPPG = oRoot.AddProperty("Custom_parameter_list",,"instance2model options")
	SIAddCustomParameter oPPG, "KeepHierarchy", siBool, True,0,1,0,4,,,, "KeepHierarchy"
	SIAddCustomParameter oPPG, "RemoveNullsIfNoHierarchy", siBool, True,0,1,0,4,,,, "RemoveNullsIfNoHierarchy"
	SIAddCustomParameter oPPG, "InstancedModels2NullsIfHierarchy", siBool, True,0,1,0,4,,,, "InstancedModels2NullsIfHierarchy"
	SIAddCustomParameter oPPG, "AllModels2NullsIfHierarchy", siBool, False,0,1,0,4,,,, "AllModels2NullsIfHierarchy"
	SIAddCustomParameter oPPG, "DeleteInstances", siBool, True,0,1,0,4,,,, "DeleteInstances"
	SIAddCustomParameter oPPG, "KeepAnim", siBool, True,0,1,0,4,,,, "KeepAnim"
	SIAddCustomParameter oPPG, "duplicateOrClone", siBool, True,0,1,0,4,,,, "duplicateOrClone"
	
	On Error Resume Next
	InspectObj oPPG ,,"instance2model options",SIModal
	'oPPGCancelled = Err.Number
	If Err.Number <> 0 Then
		LogMessage "cancelled", siError
		oPPGCancelled = True
		DeleteObj oPPG
		Exit Function
	End If
	
	KeepHierarchy = oPPG.KeepHierarchy.value
	DeleteInstances = oPPG.DeleteInstances.value
	KeepAnim = oPPG.KeepAnim.value
	duplicateOrClone  = oPPG.duplicateOrClone.value
	RemoveNullsIfNoHierarchy  = oPPG.RemoveNullsIfNoHierarchy.value
	InstancedModels2NullsIfHierarchy  = oPPG.InstancedModels2NullsIfHierarchy.value
	AllModels2NullsIfHierarchy  = oPPG.AllModels2NullsIfHierarchy.value
	LogMessage "options selected"
	DeleteObj oPPG
End Function