Notifications
Clear all

[Closed] composite texture map, script?

hi there,
I’ve been trying in maxscript to do a little script with no luck and i was wondering if anyone could help with it?

the idea is that given a folder that contains some tif images, the script should create a composite map with one layer per file in the folder. I managed to get max reading the folder and getting the number of files, creating an array with the files and creating a cmposite map, but I couldn’t get to work how to add the layers in the composite map…any help really appreciated!

cheers

29 Replies
3 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

I recently optimize the code of MultimapLoader script by Hani Tiby.

(@pixel_monkey)
Joined: 11 months ago

Posts: 0

What exactly is your problem? You should create a new bitmap texture, supply the desired file as the map path, then create a map array of bitmap textures, finally set the compositeTextureMap.mapList to the array.

mapArr = (getfiles ((getdir #maxroot)+"\\maps\\*.jpg"))
BaseMap = bitmapTexture filename:mapArr[1]
for val in 2 to mapArr.count do
(
	strVal = (val as string)
	txt = "map"+strVal+" = bitmapTexture filename:mapArr["+strVal+"]
"
	txt += "cmap"+strVal+" = CompositeTextureMap mapList:#(BaseMap,map"+strVal+")"
	execute txt
	if sme.activeView != 0 do
	(
		actView = sme.getView sme.activeView
		newPos = [0,(val*200)]
		execute ("actView.CreateNode cmap"+strVal+" &newPos")
	)
)

This should do what you want. The sme.activeView stuff is simply used to add the results to an SME view. You will need to have opened SME at least once and have a View available in it.

-Eric

(@gazybara)
Joined: 11 months ago

Posts: 0

Hi Eric,
Nice snippet you post here.
One question: why do you need to create map(node) in SME? is it not better to use Compact ME because SME limitations.

that’s great, thanks for the reply!

however…what i intend to do is more complex than that, but thanks anyway, I will have a look to it!

:bowdown:

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Your top question to me is not like a complex task. This tool needs more polish but for now works as expected. You can use it freely, and these functions a lot more if you like

yeah agreed that my top question is probably fairly basic one, ok so here is the big picture

what im trying to achieve is a script that reads the content of a folder, take those images, and for each one of those images , let’s say A , B , C an so on, it creates a composite map for each
this composite map would be something like this:

compositeMap1 : layer2: A
layer1:BaseMap

compositeMap2: layer2: B
layer1:BaseMap

compositeMap3: layer2:C
layer1:BaseMap

Where baseMap is another map that I would get to chose from a folder too.

then, this 3 compositeMaps would be inside one big compositeMap, called in this example “finalComposite” , so you end up with this:

finalComposite: layer4:compositeMap3
layer3:compositeMap2
layer2:compositeMap1
layer1:BaseMap

that’s why i was suggesting that is going to get more complicated… I just wanted to start with something to see how I can start scripting a tool to do that!

thanks again for the reply

I suggest you to attach folder with theses maps and *.max file with manually created composite map in the material editor to see how map looks and for later testing.

Because I rarely use CME, and it is hard to tell what is instanced in CME as you have to dig through the material/map setups to see it. In SME it is easy to see that the code creates an Instance of the BaseMap for all base inputs.

-Eric

EDIT:Similar code using CME instead.

mapArr = (getfiles ((getdir #maxroot)+"\\maps\\*.jpg"))
BaseMap = bitmapTexture filename:mapArr[1]
for val in 2 to mapArr.count do
(
	strVal = ((val-1) as string)
	txt = "map"+strVal+" = bitmapTexture filename:mapArr["+strVal+"]
"
	txt += "cmap"+strVal+" = CompositeTextureMap mapList:#(BaseMap,map"+strVal+")
"
	txt += "meditmaterials["+strVal+"] = cmap"+strVal
	execute txt
)
1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Yes, for that you are 100% right, i also prefer to use SME for large scale scene when i need to create a bunch of materials.
Yesterday, I tried using the maxscript to assign mtl to selection from SME to selection but without luck. Do you have any solution for that problem?

there is a way how probably I would code it:


 -- make sample texture folder:
 temp_dir = getdir #temp + @"\colors\"
 makedir temp_dir all:on
 for c in #("red", "green", "blue", "yellow", "orange", "brown", "gray", "white") do
 (
 	b = bitmap 4 4 color:(execute c)
 	b.filename = temp_dir + c + ".tga"
 	save b quiet:on
 )
 (
 	b = bitmap 4 4 color:black
 	b.filename = temp_dir + "master" + ".tga"
 	save b quiet:on
 )
 
 -- create composite texture:
 (
 	global master
 	files = getfiles (temp_dir + "*.tga")
 	fn sortbyname f1 f2 = (stricmp (getfilenamefile f1) (getfilenamefile f2))
 		
 	for f in files where getfilenamefile f == "master" do exit with master = f
 	if master != undefined do
 	(
 		master = bitmaptexture name:"master" filename:master 
 		qsort files sortbyname
 		cc = for f in files where f != "master" collect
 		(
 			name = getfilenamefile f
 			ct = compositeTexture()
 			ct.name = "comp_" + name
 			ct.layerName = #(name, "master") 
 			ct.mapList = #(bitmaptexture name:name filename:f, master)
 			ct
 		)
 		global ct = compositeTexture()
 		ct.name = "final_" + "master"
 		ct.layerName = append (for c in cc collect c.name) "master"
 		ct.mapList = append cc master
 		ct
 	)
 )
 meditmaterials[1] = ct
 
 -- PS. All globals are used for easier debugging.
 

nothing fancy. i’ve just followed the way of compositeTexture creation shown in the mxs help.

i don’t understand the problem. can you not assign or you not collect selected materials?

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

The problem is how to collect all sme-view nodes in active or any other sme-view as material, and then assigne one of theses mtls to scene objects. I know how to create mtl and place it to SME but how to assigne material from SME to newly created object, that is question.
edit:
or even better: How to collect all “unused” nodes as materials like in the CME?

SME from the mxs scripter position is one of the silliest interface that I know. I found whole SME interfaces is absolutely useless in my development.
The only function that I like is .DeleteView.
But we have to live in this screwed world and find a workaround where it’s possible.
So. Forget about SME interface. And use trackViewNodes


trackViewNodes[#sme] -- the editor
trackViewNodes[#sme].numsubs -- num views
trackViewNodes[#sme][v] -- v's view
trackViewNodes[#sme][v].numsubs -- num nodes
trackViewNodes[#sme][v][n] -- n's node
trackViewNodes[#sme][v][n].reference -- the node's reference

3 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

Denis this is very funny.
Last couple timse on other threats you give me answer in one line , and now is the same, answer in one line trackViewNodes[#sme][v][n].reference.
I already try all theses stuff but, the last line is what I’m looking for
Thanks again and I really appreciate your effort.

(@pixel_monkey)
Joined: 11 months ago

Posts: 0

Where is the .reference stuff documented? I was trying that, but couldn’t find a way to get the actual object from the trackview info.

-Eric

(@denist)
Joined: 11 months ago

Posts: 0

it’s not documented. i found it looking in trackview heirarchy:

And thanks to denisT here is exampe how to add and then assigne mtl to newly created objects from SME

--create 10 random mtl's to SME
  ActiveSMEView = sme.GetView (sme.activeView)
  tempObj = TargetObject isHidden:on
  mtlpos = [0,0]
  for m in 1 to 10 do
  (
  	 tempObj.material = Standard name:("StdMtl_"+m as string) diffuse:(random black white)
  	 ActiveSMEView.CreateNode tempObj.material &mtlpos
  	 mtlpos.x = 180*m
  ) 
  delete tempObj
  --create 10 teapots
  teapotsArr = for i in 1 to 10 collect Teapot radius:10 pos:[0, 20*i, 0]
  
  fn assigneMtltoSelection selArr mtlName: = if selArr.count != 0 and mtlName != unsupplied do
  (
  	local numViews = trackViewNodes[#sme].numsubs
  	local mtlArr = #()
  	if numViews > 0 do
  	(
  		
  		for v in 1 to numViews where (numNodes = trackViewNodes[#sme][v].numsubs) > 0 do
  		( 
  			for n in 1 to numNodes do append mtlArr trackViewNodes[#sme][v][n].reference
  		)
  	)
  	if (mtlArr.count) != 0 do
  	(
  		mtlArr = for m in mtlArr where m.name == mtlName collect m
  		if (mtlArr.count) != 0 do for o in selection do o.material = mtlArr[1]
  	)
  )
  assigneMtltoSelection teapotsArr mtlName:"StdMtl_5"
2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

use the fact that selection is a nodes set, and you can set any node’s common property to whole set:


  fn assigneMtlToSelection name view: = 
  (
  	if view == unsupplied do view = sme.activeview
  	local vnode = trackViewNodes[#sme][view]
  	local mat, done = off
  	for k=1 to vnode.numsubs while not done where done = (iskindof (mat = vnode[k].reference) material and stricmp mat.name name == 0) do [b]selection.mat = mat[/b]
  	mat
  )
  
(@gazybara)
Joined: 11 months ago

Posts: 0

:bowdown:no comment

hey, sorry to reply so late on this,

thanks a lot for the help on this one, I will study it carefully and see what if i manage to understand what’s going on…

thanks again, appreciated!
Alex

Page 1 / 2