I'm looking at writing a script that will take the selected bitmap textures in the slate editor, and then automatically connect the nodes to the correct slots on the objects material. I've chosen to do it based on bitmap name as part of the script will make the name of the bitmap node the same name as the image filename.
I can then connect the diffuse texture map to the base color map slot of a physical material by searching the selected nodes for bitmap textures with "_Diffuse" in its name, and then doing the same for the other selected nodes in the array ("_Roughness", "_Normal", etc etc).
However I'm having trouble search through the array and separately get each selected node to connect to their intended slots, currently this version of the script works but it will just connect the last node in the array and connect it to the base color map slot on the material:
on btn5 pressed do
(
if sme.IsOpen() do
(
v = sme.GetView sme.activeView
pm = physicalMaterial()
if (node = (v.GetSelectedNodes())[1]) != undefined do
map = node.reference
(
if iskindof map Bitmaptexture do $.material.base_color_map = map
)
)
)
I've tried a few different things to separate objects in selected nodes based on name including using matchpattern() but I cannot figure it out, I think at the very least I am ruining the syntax when I try to do anything too complex.
Any help please?
This is a very typical mistake related to the use of "$".
If multiple nodes are selected, "$" means a collection of nodes, if only one node is selected, it means a node.
Therefore, when you apply:
$.prop = x
in the multiple case, it will assign the value "x" to all nodes at the same time.
So never use "$" in the code. You only need it for "dirty scripting" in the MAXScript listener or for quick tests.
Use, for example, "selection" which is always collection.
fn mapPhysicalMaterial mat texmaps =
(
name_mapper =
#(
#("*_diffuse", #base_color_map),
#("*_normal", #bump_map),
#("*_roughness", #roughness_map),
#("*_metalness", #metalness_map),
-- or for example:
#("*_D", #base_color_map),
#("*_N", #bump_map),
#("*_R", #roughness_map),
#("*_M", #metalness_map)
/*
... and so on
*/
)
if iskindof mat PhysicalMaterial do
(
tex_set = #()
for tx in texmaps where iskindof tx BitmapTexture do
(
if tx.filename != undefined do
(
file = getFilenameFile tx.filename
for k=1 to name_mapper.count where matchpattern file pattern:name_mapper[k][1] do
(
setproperty mat name_mapper[k][2] tx
append tex_set #(tx, name_mapper[k][2])
)
)
)
tex_set
)
)
/********* USING:
xx = getfiles (pathConfig.appendPath DOWNLOAD_DIR_ "* _*.jpg") -- these are my test bitmap files
txs = for x in xx collect (bitmaptexture filename:x)
mat = PhysicalMaterial name:#test_mat
obj = box name:#test_obj material:mat
mapPhysicalMaterial obj.mat txs
*/
I believe you can easily adapt it to your needs. Feel free to ask questions, if any...
Wow awesome thank you!
I've played with some parts of it and got it working well and am managing to feed the grabbed texture files from a seperate getSavePath function on another button.
However, how would I go about ignoring the creation of the test obj box and instead just apply the newly created material to the currently selected object? Changing the line:
obj = box name:#test_obj material:mat
to anything relating to $, when I later call the function 'mapPhysicalMaterial' it doesn't like it.
Additionally, I can't figure out how to get the new material to immediately show in the current sme view. I've done it before with createnode function and a getView but I can't work it out in this instance.
fn mapPhysicalMaterial mat texmaps = if iskindof mat PhysicalMaterial do
(
name_mapper =
#(
#("*_diffuse", #base_color_map),
#("*_normal", #bump_map),
#("*_roughness", #roughness_map),
#("*_metalness", #metalness_map),
-- or for example:
#("*_D", #base_color_map),
#("*_N", #bump_map),
#("*_R", #roughness_map),
#("*_M", #metalness_map)
/*
... and so on
*/
)
tex_set = #()
for tx in texmaps where iskindof tx BitmapTexture do
(
if tx.filename != undefined do
(
file = getFilenameFile tx.filename
for k=1 to name_mapper.count where matchpattern file pattern:name_mapper[k][1] do
(
setproperty mat name_mapper[k][2] tx
append tex_set #(tx, name_mapper[k][2])
)
)
)
tex_set
)
mapped fn applyMappedPhysicalMaterial node texmaps force:off = if isvalidnode node do
(
if not iskindof node.mat PhysicalMaterial and force do node.mat = PhysicalMaterial()
mapPhysicalMaterial node.mat texmaps
)
/********* USING:
applyMappedPhysicalMaterial selection texmaps -- all selected nodes
applyMapppedPhysicalMaterial selection[1] texmaps -- first selected node
*/
Can't find what you're looking for? Ask the community or share your knowledge.