Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

pymxs "guess the syntax game"

28 REPLIES 28
Reply
Message 1 of 29
Anonymous
3631 Views, 28 Replies

pymxs "guess the syntax game"

So, as with much of pymxs, you have to guess, trial and error or just give up and use Maxscript as the docs give little away due to the fact that the pymxs docs are terrible and havent improved for a while. Sure, if you have time, you can try multiple permutations to find the right way to use the undocumented code and hope it works, but why has Autodesk not updated them so that there is a proper body of reference? It cant be that you just try till it works. Im fed up of posting on multiple Autodesk forums etc and seeing nothing happen.

Trying to get medit info but maxscriopt is straightforward, yet if I want to get info using pymxs, I just get syntax errors. Below is what I have tried without success, if anyone can see a way that I have not listed, it would be appreciated. I dont want to have to use MaxPlus as its too long winded to get the same result as two lines of Maxscript.

import pymxs
rt = pymxs.runtime

mat = rt.meditMaterials[rt.activeMeditSlot]
a_mat = rt.getSubMtl(mat m) # errors, Mat is material passed and m being an index number in a loop.
a_mat = rt.getSubMtl(mat, m) # errors
a_mat = rt.getSubMtl mat m # errors
a_mat = rt.getSubMtl[mat m] # errors
a_mat = rt.getSubMtl[mat, m] # errors
a_mat = rt.getSubMtl mat[m] # errors
a_mat = rt.getSubMtl(mat[m]) #errors

So I am assuming its either not been worked out or there is a way to get what I want but I have not used the right syntax and I will have to use getmxsprop or setmxsprop but if I use

a_mat = rt.getSubMtl() -- Argument count error: getSubMtl wanted 2, got 1

Its obviously a syntax issue, but generally have found that if you include the data you want inside the brackets, you get what you need, but not in this case.

Any ideas as to what the correct syntax is for this query?

 

regards

28 REPLIES 28
Message 21 of 29
denisT.MaxDoctor
in reply to: Anonymous

what confuses me:

# you check in your code the number of cust attributes ( > 1)  but nonetheless delete from the first index

# you delete cust attributes in direct index order, which decreases the number of cust attributes in the list. so the next indexes might go over the count.  

Message 22 of 29
Anonymous
in reply to: denisT.MaxDoctor

I index through them until I find the attribute with the correct name and then delete that from the material if it has it.

However, as stated, it does what I need now, but I am due to revisit it later, so can use your feedback to see if I am over complicating it.

 

In this instance, I know its going to be the 2nd attribute, perhaps I have written it with that in mind rather than considering its use elsewhere.

 

Thanks

Message 23 of 29
denisT.MaxDoctor
in reply to: Anonymous


@Anonymous wrote:

 

In this instance, I know its going to be the 2nd attribute, perhaps I have written it with that in mind rather than considering its use elsewhere.

 


if you know for sure it might be a second attribute just check only the second one. 

 

in you code:

 

if you have this attribute in the first index it will be deleted anyway (what is not expected according your code)  

 

if you have more than one instances of the attribute definition, the next  one may not be deleted because you delete them in direct order.

 

but if it works for you .. who cares. I am talking about a general case, not a specific case.

Message 24 of 29

i don't want to mess with the python, check the mxs snippet:

my_ca = attributes my_ca attribid:#(1234,4321)
(
)

delete objects
(
	b = box()
	for k=1 to 4 do 
	(
		a = createinstance my_ca
		append b.baseobject.custattributes a
	)

	format "num attrs: %\n" b.baseobject.custattributes.count

if (b.baseobject.custattributes.count > 1) do for k=1 to b.baseobject.custattributes.count do custattributes.delete b.baseobject k format "num attrs: %\n" b.baseobject.custattributes.count )

that's what you do.

 

Message 25 of 29
Anonymous
in reply to: denisT.MaxDoctor

As I said previously, I had a maxscript version that also works and was much easier to write, but it was required to be a python function as it will be part of a larger Python tool. Had I been able to use the mxs version, I would.

 

The code should only delete attributes found that match the name provided:

 

delete_cadef_from_submats(rt.meditMaterials[mat_idx], "NAME_OF_CA_DEF")

Which may provide the insight to possible overkill or code that could be reformatted. Will look again tomorrow.

 

Thanks for the feedback, its very helpful.

Message 26 of 29
denisT.MaxDoctor
in reply to: Anonymous

you can write it on c++, c#, whatever... but i'm talking about the code logic. it's the same for all implementations, and it's wrong (IMHO)

 

here is how i would do it .. 

my_ca = attributes my_ca attribid:#(1234,4321)
(
)

delete objects
the_test_object =
(
	b = box()
	for k=1 to 4 do 
	(
		a = createinstance my_ca
		append b.baseobject.custattributes a
	)

	m = b.material = standard()
	for k=1 to 5 do 
	(
		a = createinstance my_ca
		append m.custattributes a
	)

	b
)

fn deleteCustAttrDups attr_def = 
(
	fn findAttrByAttrDef obj attr_def = 
	(
		for k=1 to obj.custattributes.count where iskindof obj.custattributes[k] attr_def collect k  
	)
	cas = custattributes.getDefInstances attr_def 
	for ca in cas collect
	(
		owner = custattributes.getowner ca
		if isvalidobj owner do
		(
			indexes = findAttrByAttrDef owner attr_def
			if indexes.count > 1 do
			(
				for k = indexes.count to 2 by -1 do custattributes.delete owner indexes[k]  
			)
		)
	)
)

(
	format "before...\n"
	format "\tobj >> num attrs: %\n" the_test_object.baseobject.custattributes.count
	format "\tmat >> num attrs: %\n" the_test_object.material.custattributes.count
)

deleteCustAttrDups my_ca
( format "after...\n" format "\tobj >> num attrs: %\n" the_test_object.baseobject.custattributes.count format "\tmat >> num attrs: %\n" the_test_object.material.custattributes.count )

if you like the pymxs just convert the 'idea' to it. this is the same thing as mxs but clumsy written inside out

Message 27 of 29
Anonymous
in reply to: denisT.MaxDoctor

But your code would remove all instances of the cadef in the scene would it not?

 

Im only interested in removing the attributes from a given materials sub materials, so while your code is well laid out, it doesnt do what I need, unless I am missing something.

 

We only work with Vray materials 

 

Message 28 of 29
denisT.MaxDoctor
in reply to: Anonymous

My code doesn't do anything for your task. It shows how to find owners with specified custom attributes and remove duplicates.

I have a scenes with hundreds of materials. Using your pipeline, do I have to find everyone, put it in the Material Editor, select the slot, and ... continue?

 

I showed in my code how to work with Custom Attributes in the scene. This is just a studying tutorial for beginners.

 

 

 

Message 29 of 29
Anonymous
in reply to: denisT.MaxDoctor

The code I have written forms part of a publishing tool that requires using the active slot as the source material to be published to a database. We often reuse the materials to form part of new materials and part of that means that any material at some level has a custom attribute and to avoid duplicating attribute data in the database, we need to remove the attributes first and then publish with new attribute data.

 

A blanket removal across the scene is not an issue, I already have tools for that, which are similar in structure to yours.

 

I probably should have said that at the start as looking back, its easy to see where the use may seem a poor choice in realation to an understanding of my codes use of the material editor. Apologies for that.

 

thanks again for the feedback.

 

regards

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report