PDA

View Full Version : Sorting sub materials in multisub based on their slot name


abyjoe
07-22-2007, 04:52 PM
hi all,
i have this block of code here

myfragmaterial = getMeditMaterial 3 -- selects the 3rd material which is a multisub material in my scene
myfragmaterial.names -- this will give me the slot names of the sub material...

i want to sort the myfragmaterial.names but if i use
sort myfragmaterial.names it says the sort func does not exist for this

please anyone ??? i am only 1 day old to scripting :)

_______________________________________________

another thing.... like seen above
myfragmaterial = getMeditMaterial 3

this will select the 3rd material in the mat editor... i have to specify this in my code right now but i want the user to select the material (or more than a material) store that selection and then run my script for those materials...

how to do that... a combo box or list box will be nice but i have no idea how to do it...!!!

ofer_z
07-22-2007, 09:31 PM
Hi,

Here's a small function that will sort a multi-sub material by the sub-materials' names:

(

fn sortMatByName m =
(
-- Create a struct to hold all the relevant sub-material info. This will help
-- with the sort function.
struct s_Mat (id, name, material, mapEnabled)

-- Create an array of s_Mat structs, one for each sub-material.
local mats = for i = 1 to m.numSubs collect s_Mat m.materialIDList[i] m.names[i] m.materialList[i] m.mapEnabled[i]

-- Define the sort function to use in qsort. This function takes 2 s_Mat structs and compares
-- them by name (the name property of the struct).
fn sortFN s1 s2 =
(
if s1.name > s2.name then 1
else if s1.name < s2.name then -1
else 0
)
-- Sort the mats array using the sort function that was just defined.
-- qsort sort an array using a sort function, for full details see the
-- maxscript help.
qsort mats sortFN

-- Now that we have the mats array sorted, all we need to do is assign the sorted
-- parts back to the multi-sub material.
-- We go through each of the s_Mat strcut's properties, collect them in the right
-- order and assign to the appropriate list in the multi-sub material.
m.materialIDList = for i in mats collect i.id
m.names = for i in mats collect i.name
m.materialList = for i in mats collect i.material
m.mapEnabled = for i in mats collect i.mapEnabled
)

sortMatByName meditMaterials[2]
)



hOpe this helps,
o

abyjoe
07-22-2007, 09:48 PM
thanks a lot.. ur function works like a treat... i have made a few changes to fit in my script and its all cool... thanks again..

could you shed some light on how to take the material name as input from user.

ofer_z
07-22-2007, 09:54 PM
thanks a lot.. ur function works like a treat... i have made a few changes to fit in my script and its all cool... thanks again..

could you shed some light on how to take the material name as input from user.

Do you want the use to enter a new material name or to select a material by name?

abyjoe
07-22-2007, 10:09 PM
suppose i have 10 different materials -- 3 multi sub and 7 standard
i only want to use 2 different materials to perform my action so i was thinking of a rollout where user selects his choice (say 2 materials out of all the scenematerials) and then i run my function for those 2

like ur function specifies meditMaterials[2] but i want the choice to select any material and not make the script absolute to second material

cgtalk rep added for your first post. really helpful

abyjoe
07-22-2007, 10:39 PM
how did u know there is something like the m.numSubs property.i cant find it in the showproperties listing and neither in its superclass... i was accessing the m.materialList.count property to do the same

--- sorry found it after I checked in the help file... using the numSubs property has its disadvantage... materialList.count property is more accurate.

ofer_z
07-22-2007, 10:53 PM
Try this one. It would probably need some foolproofing before it's completely usable, but that should get you started:



try(destroyDialog ro_SortMultiMaterial)catch()

rollout ro_SortMultiMaterial "Sort Multi-Material"
(

-- Local Variable Declerations
--------------------------------
local multiMatArray = #()


-- User Interface
-----------------------------
multiListBox mlbMaterials "Scene Multi-Materials: " height:20
button bnSort "Sort" width:140


-- Functions
-----------------------------
fn sortMatByName m =
(
-- Create a struct to hold all the relevant sub-material info. This will help
-- with the sort function.
struct s_Mat (id, name, material, mapEnabled)

-- Create an array of s_Mat structs, one for each sub-material.
local mats = for i = 1 to m.numSubs collect s_Mat m.materialIDList[i] m.names[i] m.materialList[i] m.mapEnabled[i]

-- Define the sort function to use in qsort. This function takes 2 s_Mat structs and compares
-- them by name (the name property of the struct).
fn sortFN s1 s2 =
(
if s1.name > s2.name then 1
else if s1.name < s2.name then -1
else 0
)
-- Sort the mats array using the sort function that was just defined.
-- qsort sort an array using a sort function, for full details see the
-- maxscript help.
qsort mats sortFN

-- Now that we have the mats array sorted, all we need to do is assign the sorted
-- parts back to the multi-sub material.
-- We go through each of the s_Mat strcut's properties, collect them in the right
-- order and assign to the appropriate list in the multi-sub material.
m.materialIDList = for i in mats collect i.id
m.names = for i in mats collect i.name
m.materialList = for i in mats collect i.material
m.mapEnabled = for i in mats collect i.mapEnabled
)


fn init =
(
-- get all the multimaterial instances into the multiMatArray
multiMatArray = getClassInstances Multimaterial

-- update the multiListBox
mlbMaterials.items = for m in multiMatArray collect m.name
)

-- Event Handlers
------------------------
on bnSort pressed do (
for i in mlbMaterials.selection do
sortMatByName multiMatArray[i]
)



on ro_SortMultiMaterial open do init()

)-- end of ro_SortMultiMaterial rollout

createDialog ro_SortMultiMaterial



hOpe this helps,
o

abyjoe
07-22-2007, 11:05 PM
thanks u so much.. u have made my day :) cgtalk rules
will update on how things work...

edit: i am trying to add an ignorecase function to ur script as it ignores case senstivity so Camera and camera are not treated as one... i am trying to use matchpattern for this. is that right or there is a better way?

CGTalk Moderation
07-22-2007, 11:05 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.