Notifications
Clear all

[Closed] how to use the "collect "command?

thanks all for your replies.

so It seems like I can use collect to do this:

	
fn getNonBodyMeshList = (
		local list =#()
		local meshes=$*mesh_*
		for each in meshes do
		(
			if (each.name != "mesh_body") then
			(
				append list each.name
			)
		)
		return list
	)

with this:

	
fn getNonBodyMeshList=(
		for obj in $mesh_*  where obj.name != "mesh_body" collect obj.name
	)

is this a faster method as well?
my code is full of the former style of object gathering

does collect have an anlaogue in C#?

the fastest way in your case is


 $'mesh_body' as array
 

Dennis, i think you misread the intent of my code :
return an array of names (strings) for all objects named “mesh_*” excluding “mesh_body”

4 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

Maybe this aproch. I don’t know is it fast but at least you can try


arrNames = #()
mapped fn collectObjNames arr &names =
(
	append names arr.name
)
collectObjNames selection arrNames
arrNames

(@denist)
Joined: 11 months ago

Posts: 0

my bad… well. let me improve myself:


for node in $mesh_* where stricmp node.name "mesh_body" != 0 collect node.name

the stricmp compares strings not case sensitive.

(@mambo4)
Joined: 11 months ago

Posts: 0

Is using node instead of a variable like obj also an optimization?
I guess nodes restricts the possibilities searched to scene nodes and excludes any maxscript objects / variables …

(@denist)
Joined: 11 months ago

Posts: 0

in any loop case node is a local variable. you can use any other

that’s nice Denis, i’d always used matchpattern with ignorecase set as true for that sort of thing.

Thanks for the replies on dontcollect. I can see where you would use it now. I’ve even used it this morning! This was to collect any materials from the selection with a material ID applied. The extra check in this is vray materials have an ID override property that you need to look for too.

mats = for i in (selection as array) where i.material != undefined collect
(
	-- check for vray mat ID override
	if hasproperty i.material #override_effect_id and i.material.override_effect_id then i.material
		else if i.material.effectsChannel > 0 then i.material 
				else dontcollect
)

if you dont use dontcollect, you’d get a lot of undefined values in the array. Thanks for the clarification.

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Similar way using mapped fn


  vrMtls = #()
  mapped fn collectVRayMatsByID arr &mtls = 
  (
  	if isKindOf arr.material VRayMtl and arr.material.override_effect_id and \
  	arr.material.effect_id != 0 do append mtls arr.material
  )
  collectVRayMatsByID selection vrMtls
  vrMtls
  

Also, I did some tests to wrap my head around dontcollect
Some psuedo code to illustrate my understanding:


list1=for [exp1] collect --values passing [exp1] are collected
list2=for [exp1] collect [ if [exp2] then (value)] --values failing [exp2] collected as undefined
list3= for [exp] collect  [ if [exp2] then (value) else don't collect] --values failing [exp2] are skipped

does that seem correct?

absolutely correct

so, now I’m trying to think if any of this collect/dontcollect can help me solve this task:

gather all meshes whose diffuse texture is either unique or is the first instance of a shared texture.

that is, for each unique diffuse texture in scene, return a single mesh that uses it.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

are you talking about TextureMap or Bitmap?

I speak of the external file Path of the bitmap value of the mesh’s diffuse map (in our case each mesh has a single diffuse map bitmap file)

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

what material do you use? why am i asking? because i might be much easier way to find objects in some specific case

well… do you want to find the first object that uses a specified bitmap texture (file)?

here is a possible solution:


fn findObjectsByTextureUse textureFilename list: firstOnly:on =
(
	if list == unsupplied do list = objects
	local found = off
	local nodes = for node in list while not found or not firstOnly where node.mat != undefined and finditem (usedMaps node.mat) textureFilename != 0 collect
	(
		found = on
		node
	)
	if firstOnly then nodes[1] else nodes
)	

there are some another…

Page 2 / 3