f-- *** clone & place***
-- *** maxScript  ***
-- clones source object multiple times and aligns with selected target objects.
-- Jeff Brown, Fire Mist Media
-- for 3ds Max 2010 (and above, probably)
-- ver. 1.3 2017-August

-- Has some (minimal) error-checking. As always: use at your own risk.

-- Thanks to all the good Max-folks that have helped me over the years. 
--  Particular thanks to Bobo & Larry M. for their work on MaxScript!!

-- Please modify, adapt, & distribute this script as you need. 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------


-- comment ( uncomment ) the following line to disable ( enable ) as a Macro Script :

-- macroScript  CloneAndPlace category:"Fire Mist Media"

(
	--variables
	global ro_fmm_clonePlace
	
	local i = 1					-- index
	local source				-- object to be cloned
	local newSource			-- clone of object
	local targetArray=#()	-- objects to be aligned to
	local objArray=#()		-- used in deleteObj function
	
	local bt_selectSource 	-- UI objects
	local bt_cloneGo
	local cb_deleteOld
	
	local collectTargets 			-- functions
	local alignLocal
	local makeSuffix
	local cloneAndPlace				
	local deleteObj
	
	--functions ****************

	function collectTargets = (
		targetArray = #()
		targetArray = for obj in selection collect obj
	)
	
	function makeSuffix numeral = (		-- numeral input returns zero-padded string
		suffix = numeral as String
		for z = 2 to suffix.count by -1 do (
			suffix = "0" + suffix
		)
		suffix
	)
	
	function alignLocal newSource target = (
		source.rotation = target.rotation
		source.position = target.position
	)
	
	function cloneAndPlace = (
		if (targetArray.count>0 AND targetArray!=undefined) then (
			print("targetArray.count:" +(targetArray.count as String))
			if (source!=undefined) then (
				for i =1 to targetArray.count do (
					if (ro_fmm_clonePlace.cb_cloneHierarchy.checked) then (
						newSource = maxOps.CloneNodes source offset:[0,0,0] expandHierarchy:true cloneType:#instance actualNodeList:&actual newNodes:&newObj
						print("newSource[" +(i as string) +"] = " +(newObj as string))
						print("target[" +(i as string) +"] = " +(targetArray[i] as string))
						alignLocal newObj[1] targetArray[i]
					)
					else (
						newSource = maxOps.CloneNodes source offset:[0,0,0] expandHierarchy:false cloneType:#instance actualNodeList:&actual newNodes:&newObj
						print("newSource[" +(i as string) +"] = " +(newObj as string))
						print("target[" +(i as string) +"] = " +(targetArray[i] as string))
						alignLocal newObj[1] targetArray[i]
					)
				)
			)
			else (
				print "error in sourceObj"
			)
		)
		else (
			print "error in targetArray"
		)
	)
	
	function deleteObj objArray = (
		if (targetArray.count>0 AND targetArray!=undefined) then (
			print("targetArray.count:" +(targetArray.count as String))
			if queryBox "Are you sure you want to DELETE ALL TARGET OBJECTS?" beep:true do (
				for i =1 to objArray.count do (
					delete objArray[i]
				)
			)
		)
	)
	-- UI interaction - get stuff

	-- interface ************************
	try(destroyDialog ro_fmm_clonePlace) catch() 		--kill any existing instances of rollout to start fresh		

	rollout ro_fmm_clonePlace"Clone & Place" width:210 height:120
	(
		pickbutton bt_selectSource "pick source/parent object" pos:[10,8] width:198 height:21
		checkbox cb_cloneHierarchy "clone full hierarchy" pos:[12,30] width:198 height:21
		button bt_cloneGo " ---- clone & place ----" pos:[10,58] width:198 height:21
		checkbox cb_deleteOld "delete target objects (NO UNDO!!!)" pos:[12,80] width:198 height:21
		on bt_selectSource picked obj do (
			source = obj
		)

		on bt_cloneGo pressed do (
				collectTargets()
				cloneAndPlace()
				if (cb_deleteOld.checked) do (
					deleteObj targetArray
				)
		)
		
	)--end rollout
	
	createDialog ro_fmm_clonePlace width:220 height:120 pos:[860,130] style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing , #style_minimizebox) lockHeight:false	
	
)-- end prog