Replacing Objects


Good afternoon everyone.
I have a question regarding replacing objects in a scene.
I’d like to make this as specific and easy to understand as possible so I would first like to say that I have downloaded more than 20 different object replacement scripts which have not really improved my speed at all. I have scoured tutorials, books and dvds and still have yet to find the one method I am lacking.

The premise of my script is to import an ASCII file exported from a bit of software that my office is producing. The file format outputted from the program is .dae (if it matters). What I need to do is open the file in max and replace every geometry instance with a reference file on our server. Meaning that if there are 350 objects exported in the file I am going to be replacing each individual object with its own reference file.

Object 1 would be replaced with Reference Z1
Object 2 - Reference z2 and so on and so forth.
There will commonly be times where I will have 35 object1’s - in which case I am turning them into instances.

What my script does right now is selects all like furniture (Object 1) and then brings up the default max replace window where you navigate to your file.
I have roughly figured out how max opens a file and how I can read and write data to and from them however I cannot figure out how to do a replace.

As it stands right now I have 65 different objects that need replacing at most (this number grows by the month though) so having to select 65 different files via 65 different replace windows is still mighty frustrating.

If someone could suggest how to implement the replace feature without having a user select the files (say in the quiet dialog mode) or a better method to do what I am trying to do could you please help me out?

If you are going to post a link to another script please indicate why you think it would be useful. As I mentioned before, I have tried a ton of scripts and just can’t get the usability and time saving I need out of them.

Thank you very much for reading to this point and thank you for replying and helping me!


Check the Maxscript Help File > MAX File Loading and Saving. You can use mergemaxfile with #deleteOldDups which according to the help file is equivalent to replace from the UI. There are other commands for handling of parenting, materials, etc.



I’d tried that before and have tried it again as you’ve mentioned.
The problem I had before and am having again with this method is that my objects are scattered around the scene. The reference objects are located at 0,0,0 and when merged the originals are deleted from their scattered location and are replaced by a model at 0,0,0.
Which with multiples leaves quite the cluster at 0,0,0.

Any ideas?


I’d probably do something along the lines of merge/import -> move to old object’s location -> delete old object – on merge you have the option of selecting the imported object (at least when they are max files) so after merge you can get the new objects, and then move / rotate them into the position of the old objects

Side thought here: Since these are all ascii files, I’m not sure how it works with importing (don’t have max open to test) if it will select the objects after merge and such, but you could also easy make a script that in a clean scene, imports a file, saves as a max file, and then does that for X number of files if it would make it easier.


How do you identify what object should be replaced with what file? are there any constants that you can start from? What i mean is: is object1 always refering to object1.max?
wouldnt something like this work?

undo on (
import_object = mergemaxfile "replacement.max"
for obj in selection do
new_object = maxops.clonenodes new_object clonetype:#instance
new_object.pos = import_object.pos
new_object.rotation = import_object.rotation
delete selection

(no got max open, so written from memory…badly :p)


As much as I wish I were that proficient with MAXScript, I currently am not. However I will definitely be doing some looking at implementing that kind of system just as soon as I can get all the code correct. The reason why I’ve got ASCII files is because that is the open source file format we are dealing with. I hope it doesn’t cause too much grief. I just thought that merging files would be much more efficient on a large quantity as I can easily select a bunch of object and instance them as the replacement file and hit merge. But doing this with buttons and dialogue boxes would take a long time in a scene with 300 different types of objects.

Dutch, looking at your code seems to be exactly what I would have been trying to figure out based on the previous post and it looks pretty well like it’d work.
When I import the file I get very good naming conventions, as weird as it may sound, I am the one creating the models being used in the file I am importing… Long story there but I essentially distribute low levels of detail for clients to use in a proprietary piece of software which at the moment supports only .3ds and .dae files. But it only exports their scenes as .dae. So I can select all 300 instances of one object by searching for its filename. However what I have been doing as a pre-cursor is searching for and selecting Object1 which might be named Object1.3ds in the file now and I instance them as Object1.
Thats why I have found the merge function works so perfectly.
I will have a go at your code snippet and let you know how it goes. Thanks for the help thus far guys!


Dutch, the code supplied as copied and pasted gives the following errors:

-- Error occurred in new_object loop
--  Frame:
--   new_object: true
--   called in anonymous codeblock
--  Frame:
--   import_object: true
-- Unknown property: "pos" in true

I am currently troubleshooting.


Are you using any of the reparenting arguments? Can you post a sample file and scene where you want the object replaced? How are the objects scattered?



I currently am not doing a whole lot of anything beyond replace. Not successfully anyways.
I am not a very experienced maxscripter and started with forum trolling and a book. I also have some of the tutorials done by Bobo.

As such most ideas thrown at me I then research as best as possible and then learn to implement them.
I have attached a zip with 2 max files one “Classic Office Chair” which is the replacement object and “cgsociety example” which has a few scattered instances of some objects that need replacing. The Chairs - well chair pieces - have already been re-named to match my successful although slow replacement technique.

Objects replace

here is 100% working code:

fn objectReplace name all:on makeunique:off = 
	act = off
	pattern = if all then (name + "*") else name
	-- collect all nodes with the name or which name match the pattern <name>* (name_01, name 02, etc. )  
	nodes = for obj in objects where matchpattern pattern:pattern collect obj
	-- replace file has to be in the same directory and has the name of object to replace
	file = maxfilepath + name + ".max"
	if nodes.count > 0 and doesfileexist file do
		-- merge only object with the name
		mergeMaxFile file #(name) #select #mergeDups #neverReparent #useMergedMtlDups quiet:on
		if isvalidnode (node = selection[1]) do
			-- replace all old instances with new one
			for obj in nodes do instancereplace obj node
			-- make them unique if necessary
			if makeunique do InstanceMgr.MakeObjectsUnique nodes #individual
			delete node
			act = on
-- call this function
objectReplace "Classic Office Chair"

Objects replace

DenisT, thank you so VERY much.
This problem has been quite puzzling to me and my lack of maxscript skills.
You have provided me with much more than I was expecting from the forum. That works perfectly and frankly much more efficiently than my script before and I am very appreciative of the comments provided to help explain what each bit is doing and how.

Once again, thank you VERY VERY much.


Minor note, in my instance the materials are not coming over as well. Not too sure why at the moment, but if anyone has any idea please let me know.
I am using max2009 if it matters.

Objects replace

change my code to:

			-- replace all old instances with new one
			for obj in nodes do 
				instancereplace obj node
				obj.mat = node.mat


Spot on! Thank you very much Denis


Sorry if this question seems stupid with all the information received so far,
if I wanted to do the same as above with a few objects but instead of simpling merging and replacing what if I replaced the object with an xref?

i’ve tried the following with the resulting xref being placed at 0,0,0

xrefs.addNewXRefObject file #(name) #proxy #merge #merge #useMergedMtlDups quiet:on

Any ideas, or should I be writing a different looking function specifically for the xrefs?

Thank you in advance!

I’ve realized I had an issue with my xref object code as it is - in that I wasn’t specifying an object or node to xref. so I have the done just fine however I can’t get rid of the duplicate material popup which sucks nor can I figure out any way to move/rotate each xref to the original objects location. I’ve got it to the point where I can get the correct number of xrefs but just can’t figure out how to manipulate each one. Any ideas?

EDIT2: I have figured out how to do what I want… I think. Everything seems to be ok, still the issue of the popup for duplicate materials so if anyone has an idea about that I’d love to hear it. anywho, my code for it.

xrefs.addNewXRefObject "C:\\Users\\ahosking\\Desktop\\13 - Furniture Catalogue 2.0\\Rendering Furniture\\2x2 Reception Table.max" "2x2 Reception Table" #xref #xref #useMergedMtlDups quiet:on
for o in originalA do (
i = instance $'xref furniture' pos: o.pos
delete o


if you are working with max 2010 you can call xrefs.addNewXRefObject with dupMtlNameAction:#useXRefed option (see MXS help XRefObject : Node)

with this option the function will not pop up material replace dialog.

if your max’s version is lower then max 2010 you can use objXRefMgr.AddXRefItemsFromFile with option xrefOptions:#(#mergeMaterials)
(see MXS help Interface: objXRefMgr)

to set origin transforms
you can use[color=Yellow] instanceReplace [color=Yellow]the same way as in my previous sample for the merged object[/color][/color]


Ah Denis, thank you once again!
Your knowledge is fantastic. I’ve scoured that damn MaxScript reference and didn’t ever come upon objxrefmgr so thank you for that. Things make a whole lot more sense for xref management now.
Thanks a tonne!


if isvalidnode (node = selection[1]) do

Interesting. I didn’t know you could initialize a variable right in the ‘if’ line like that.


This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.