[Closed] 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.
Example:
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.
-Eric
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.
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!
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)
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?
-Eric
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.
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 obj.name 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
(
clearSelection()
-- 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
)
)
act
)
-- call this function
objectReplace "Classic Office Chair"
if isvalidnode (node = selection[1]) do
Interesting. I didn’t know you could initialize a variable right in the ‘if’ line like that.
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.
change my code to:
-- replace all old instances with new one
for obj in nodes do
(
instancereplace obj node
obj.mat = node.mat
)