Home Coding, Scripting, Shaders

maxscript assign array value to property

Hi, basically what I want to do is to assign material property to an array like 

d_standard =#("diffuseMap")

and later call it as property like

defmat = standardMaterial()
texPath = Bitmaptexture fileName:tmp
defmat.d_standard[1] = texPath << This is where I get lost

Is there any way I can achieve that with maxscript? For now my script is bloated because I have to define each slot, and I need to simplify and I already stuck in 2 days for this. Thank you and appreciate any help.


  • PolyHertz
    Offline / Send Message
    PolyHertz ngon master
    You mean like this?

    myArray = #()
    append myArray (copy meditMaterials[1].diffusemap)
    meditMaterials[1].specularmap = myArray[1]

    Or are you specifically asking about texture paths?

    myArray = #()
    append myArray (meditMaterials[1].diffusemap.filename)
    meditMaterials[1].specularmap.filename = myArray[1]

    Both of those assume you're using standard materials though. If you don't have a specific type of material in mind, and are looking for a way to get and replace texture paths universally, it becomes much more complicated.
  • vbeta
    The array has already defined with material properties texture slot, example with standard material:

    d_standard = #(""diffuseMap", "ambientMap", "displacementMap", "bumpMap")  -- and so on

    or with corona:
    d_corona = #("texmapDiffuse", <diffusewithcoronaAO>, "texmapDisplacement") -- and so on

    and I want to call that array value instead of material property ex:
    in diffuse texture slot with standard material, i will replace myMaterial.diffuseMap with  myMaterial.d_standard[1]
    or, if I use corona, i will replace myMaterial.texmapDiffuse with  myMaterial.d_corona[1]

    Problem here is .diffuseMap (or .texmapDiffuseis property name of that material, which will throw error if i replace with array index (.d_standard[1] in this example). Is there any workaround this? 

    I'm sorry if the question is not clear enough, try the best I can.

  • haiddasalami
    Online / Send Message
    haiddasalami polycounter lvl 11
    think you are looking for execute since maxscript will probably try to read d_standard[1] as a property but its really a string. Think there was a getproperty and setproperty functions for maxscript. Been a while.

    Edit: Heres the documentation for getproperty and setproperty (just search for it) https://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_879ECFAD_7928_44B3_BCD7_276D53C89B52_htm

    getproperty meditMaterials[1] "wire"
    setProperty meditMaterials[1] "wire" true

  • PolyHertz
    Offline / Send Message
    PolyHertz ngon master
    Maybe this will answer your question:

    d_standard = #("diffuseMap")
    defmat = standardMaterial()
    texPath = "C:/theTexture.png" --replace this with whatever your texture files path is
    texBit = Bitmaptexture fileName:texPath
    execute ("defmat." + d_standard[1] + " = texBit")
  • vbeta
    Hello guys, sorry for late reply. 
    @haiddasalami, thank you, it works using setProperty

    local texpath = Bitmaptexture fileName:tmp
    setProperty defmat (texSlot[slotIndex] + "Map") texpath 
    -- print defmat.diffusemap
    -- Bitmaptexture:Bitmap
    @polyhertz, execute() just doesnt work in my case.
    Bitmaptexture fileName:tmp cant be executed because it cant be converted to string. 

    execute ("defmat." + texSlot[slotIndex] + "Map=" + texpath)
    -- Unable to convert: Bitmaptexture:Bitmap to type: String

    When I tried to convert it, 

    execute ("defmat." + texSlot[slotIndex] + "Map=" + texpath as string)
    -- Error occurred during fileIn in <ReadonlyTextFileStream:0x0000a0c8>; line number: 478
    -- Syntax error: at keyword parameter, expected <factor>
    --  In line: defmat.diffuseMap=Bitmaptexture:B

    Thank you guys for your time.
  • monster
    Offline / Send Message
    monster Polycount Sponsor
    Execute always operates in global scope, even if you are in some local scope.

    So you wouldn't convert to the Bitmaptexture to a string. You would set it as a global variable, and then just use the variable as the string.

    		--set global variable in my local scope
    		global bm = Bitmaptexture()
    		--run in global scope even though I'm in a different local scope
    		execute "bm"
    ...but stick with setproperty, I try to avoid execute because it operate in global scope. Set property is mapped as well, so you can set many properties at once.

    	--array of materials
    	mats = for i = 1 to 10 collect standardmaterial()
    	bm = bitmapTexture filename:"C:/texture.png"
    	--set df for all mats in one go
    	setProperty mats #diffuseMap bm

Sign In or Register to comment.