PDA

View Full Version : Detach by material IDs.


SergeAstahov
04-28-2005, 11:24 AM
Hi there!

I have an interesting question and i thought why not to ask here maybe it's possible indeed.

So here's the question:

It's aimed for the games, so that's why i need it.
I want to select the object and datach the polies by material IDs. I'm actualy talking about tracks and for instance you have a huge track and you have tons of textures over there but the game itself doesn't work with multisubobject material so what i need to do is detach all the different polies by IDs and that will make all the polies having their own material but only one. And i need it to be made automaticaly and not manually (selecting ID group and detaching those polies coz there migth be tons of them if you know what i mean).

So is this possible, i think it's only possible with the script help (maybe there's such one already) or there's a way of doing it in max without anything which i cannot put my finger on.

I would be glad to hear any thoughts you have.
Thanks.

galagast
04-28-2005, 12:34 PM
the_orig = $
the_polyobj = copy the_orig
the_facecount = getnumfaces the_polyobj
id_list = #()
for i in 1 to the_facecount do
(
the_faceid = the_polyobj.getfacematerial i
if not (finditem id_list the_faceid) != 0 then append id_list the_faceid
)
id_list
id_count = id_list.count
for i in 1 to id_count do
(
the_polyobj.selectbymaterial i
the_faces = getfaceselection the_polyobj
polyOp.detachFaces the_polyobj the_faces asnode:true
)
delete the_polyobj


you could try this if it would work for you.. only works on POLYGON objects though.
copy it to a blank maxscript window (MAXScript>New Script) select an object and Evaluate.

hope it helps!

SergeAstahov
04-28-2005, 04:03 PM
Thank you very much galagast and it works perfect for me. The only thing that was incorrect that after evaluating, it was leaving the original object but not deleting it, and instead of "copy" i wrote "instance" and for some reason it worked the way i wanted (i mean deleted the original object).

I really appreaciate your help but it would be very nice of you if you could help me out more.

What i need is:

To be able to select all objects all together and evalute them but not evaluate every single object. Coz now when i select all the objects and evaluate them, it makes the copy of them (using copy or instance doesn't matter).

And it only works with editable poly now but i need it to work with editable mesh as well if it's possible, coz some things are still made in 3ds max 3 (becasue of some plug-ins which are only there) and there isn't any edit poly over there.

And the last but not the least.
After evaluating the object it would be great to have the names of the textures on those new created objects (made from mat. IDs). Here's a little explanation - let's take a plane for instance. The name of the plane is plane01 (by default). After collapsing it i made two polygons and assigned twodifferent textures for them. One polygon of this plane has texture brick01.jpg and other polygon of the same plane has brick02.jpg texture and after evaluating the plane, it names the parts like so: object01 and object 03, but would it be possible to have the names of textures for these detached polies. So after evaluating the plane it should have objects: brick01 and brick02, of course without an extension.

If i haven't explained good enough plz let me know about it and i will explain better :D.

If some of that is possible then it would be simply great. Thank you very much in advance for any help you can provide.

galagast
04-28-2005, 04:58 PM
Thank you very much galagast and it works perfect for me. The only thing that was incorrect that after evaluating, it was leaving the original object but not deleting it, and instead of "copy" i wrote "instance" and for some reason it worked the way i wanted (i mean deleted the original object).

I really appreaciate your help but it would be very nice of you if you could help me out more.

What i need is:

To be able to select all objects all together and evalute them but not evaluate every single object. Coz now when i select all the objects and evaluate them, it makes the copy of them (using copy or instance doesn't matter).

And it only works with editable poly now but i need it to work with editable mesh as well if it's possible, coz some things are still made in 3ds max 3 (becasue of some plug-ins which are only there) and there isn't any edit poly over there.

And the last but not the least.
After evaluating the object it would be great to have the names of the textures on those new created objects (made from mat. IDs). Here's a little explanation - let's take a plane for instance. The name of the plane is plane01 (by default). After collapsing it i made two polygons and assigned twodifferent textures for them. One polygon of this plane has texture brick01.jpg and other polygon of the same plane has brick02.jpg texture and after evaluating the plane, it names the parts like so: object01 and object 03, but would it be possible to have the names of textures for these detached polies. So after evaluating the plane it should have objects: brick01 and brick02, of course without an extension.

If i haven't explained good enough plz let me know about it and i will explain better :D.

If some of that is possible then it would be simply great. Thank you very much in advance for any help you can provide.

yup, these are quite possible, I'll try to work on it after my work tomorrow. :thumbsup:

galagast
04-29-2005, 02:53 PM
rollout detachByID "Detach by ID" width:120 height:120
(
local name_type = true
local the_name = "Element_"
local the_mats = #()
local id_list = #()
button detach_bot "DETACH" pos:[5,95] width:110 height:21
checkbox del_bot "Delete Original" pos:[5,75] width:110 height:15 checked:true
edittext name_edt "" pos:[10,50] width:100 height:15 visible:false text:"Element_"
radiobuttons name_rd "" pos:[10,15] width:74 height:32 labels:#("Material", "Prefix") default:1 columns:1
GroupBox name_grp "Naming: " pos:[5,0] width:110 height:70
label name_lbl "- Texture Name -" pos:[10,50] width:100 height:15 visible:true

on name_edt entered txt do
(
the_name = txt
)

on name_rd changed val do
(
case val of
(
1:
(
name_edt.visible = false
name_lbl.visible = true
name_type = true
)
2:
(
name_edt.visible = true
name_lbl.visible = false
name_type = false
)
)
)

on detach_bot pressed do
undo "Detach by ID" on
(
the_sel = selection as array
if the_sel != undefined do
(
for obj in the_sel where superclassof obj == GeometryClass do
(
try(convertToPoly obj)catch()
the_orig = obj
the_polyobj = copy the_orig
the_facecount = getnumfaces the_polyobj
for i in 1 to the_facecount do
(
the_faceid = the_polyobj.getfacematerial i
if not (finditem id_list the_faceid) != 0 then append id_list the_faceid
)

for i in id_list do
(
try (
if obj.material != undefined then
(
if getnumsubmtls obj.material != 0 then
(
the_objmat = obj.material[i]
the_mapfile = the_objmat.diffusemap.bitmap.filename
the_filename = getfilenamefile the_mapfile
append the_mats (uniquename the_filename)
)
else (append the_mats (uniquename obj.material.name))
)
else (append the_mats obj.name)
)
catch (append the_mats obj.name)
)
the_index = 0
for i in id_list do
(
the_index += 1
the_polyobj.selectbymaterial i
the_faces = getfaceselection the_polyobj
if name_type do try(the_name = the_mats[the_index])
catch (the_name = (uniquename obj.name))
polyOp.detachFaces the_polyobj the_faces asnode:true name:the_name
)
the_index = 0
if del_bot.checked do delete the_orig
delete the_polyobj
)
the_mats = #()
id_list = #()
)
)
)
createdialog detachByID



ok, i just made a not so fancy UI, with it includes a couple of obvious options. hehe
just make a selection and press the "detach" button.
this would, internally, collapse everything selected to editable_poly, thus detach each by ID.

hope this helps!

SergeAstahov
05-02-2005, 07:53 AM
Thanks galagast for your time and help, it's a very useful thing for me. Though it doesn't name the polies as textures and i don't know whether it's possible or not but still thanks a lot man, really appreaciate it.

galagast
05-02-2005, 11:35 AM
hmmm... thats weird... wait... i assume you're using multi-subobj materials on your objects? and each submaterial has a standard material with a bitmap diffusemap in it?

the naming works this way...
it will check to see if it has a multisubobject material, look for the corresponding ID's, get the diffuse bitmap filename to name the detached part.
if the object has no multisubmaterial, it will name it using the name if the material...
if the object has no material at all, it will name it uniquely based on its original name... (not so useful though, hehe)

(it wont bother me if you could also give me a sample scene where when i apply the script, naming doesnt work. :) :) :) )

SergeAstahov
05-02-2005, 06:05 PM
sorry, I should have tested it on several versions of 3dsmax before posting that it didn't work. The thing is, I tested it in 3dsmax 3 where the UI didn't even load, and in 3dsmax 5 it named the polies by their original name along with a number.

But I've just tried it in 3dsmax 7 and it worked :) But there's a little but. It *only* works well (correct) for those objects which have Multi/Sub-Object material, but for those which don't, it names polies as "Material #xx", although it does have a texture but only *one* assigned to it.

So, the way I have it now, is, for example, a thousand of separate individual objects, where some of them do have Multi/Sub-Object meterial and some don't. I don't know which of them do and which of them don't (because I imported the scene from another modeling program...), unless of course I select each of them one by one and check if it has Multi/Sub-Object material or not. What I need to do is select everything on the screen, and apply your script, which would
1) "find" among all selected objects those which do have Multi/Sub-Object meterial;
2) Broke those into pieces (polies) (Detached by IDs);
3) Named the pieces by their assigned texture the way I explained above;
4) and for those objects which do *not* have Multi/Sub-Object material but do have only *one* texture assigned, simply named that object by its texture name.

:)

Right now, your code works correctly in the following cases:
1. if I select just *one* object with Multi/Sub-Object material
2. if I select *several* objects all of which have Multi/Sub-Object material

by "working correctly" I imply detaching objects by IDs and naming them by their own texture file name.

does not work correctly in the following cases:
1) if I select at least one object *without* Multi/Sub-Object material but _with_ one texture assigned (in this case it will name the object as "Material #xx")
2) if I select a group of objects where there are both objects with Multi/Sub-Object material *and* without. It will not only name incorrectly those without Multi/Sub-Object material, but it will also name half of the "pieces" of one single object which has Multi/Sub-Object material correctly, and the other half as "Material #xx" << Note that selecting each object which has Multi/Sub-Object material separately and applying your script will work correctly, it's just that it doesn't work when the "group" is selected.

I'd like it to work correctly in the case "2)", that's the goal.

By "group" I mean objects:
a) which do have Multi/Sub-Object material
b) and those which don't

phew, I hope I haven't confused you :D Was trying to be very detailed :)

Anyway I think you see where the problem is, it just seems that it doesn't like objects without Multi/Sub-Object material... and I want it to like them :)

Thanks again for your time and patience, you're a great help to me, really :thumbsup: Much appreciated.

[edit] here's an example of such a scene (in fact it's a very small part of it).
I included the textures as well because the script works only if all needed textures are found:

http://hawk.sitesled.com/files/TheTrack.rar

(right click + "Save Target As...")

galagast
05-24-2005, 03:19 AM
ok, it now works... (i hope)

-- it will loop through all your selected objects
-- check if it has a multimaterial, thus get the submaterials' diffuse bitmap to name the detached part
-- or, if it only has a standard material, it will get the diffuse bitmap thus name the detached part
-- if it has no material assigned to it, it will just name it using the the original name
-- if it didnt find the corresponding material id in the multimaterial, will also name it using the objects' original name

oh, i forgot to mention that i wasnt able to open up your attached max file, coz im only using ver6.0...

Here (http://www.geocities.com/jepoy20/files/detachbyID.zip) is the file, zipped it with a sample max (6.0) file...

:)

SergeAstahov
05-25-2005, 12:44 PM
Woohoo!! You got it, galagast! Works perfectly :eek: :thumbsup: Brilliant job, exactly what I needed, spot on, bingo, don't know what else to say :D You da man! Thank you *very* much! :) This is an invaluable tool for me :) I appreciate all the time you spent on it!

Cheers and best regards!

CGTalk Moderation
05-25-2005, 12:44 PM
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.