GetAllTextures from materials only
-
Hi all,
Following this post: https://developers.maxon.net/forum/topic/10645/14093_getalltextures-not-working
Where if we want to get the textures from specific objects (in my case just the material objects), you need to add them to an AtomArray. Unfortunately, I cannot understand how to append this list to it, so I can can pass it to GetAlltextures. So I'm missing something here.
BaseDocument.GetAllTextures(isNet=True, ar=None)
ar (List[c4d.C4DAtom]) – An atom array to get the textures for. If None (default), all used textures in the document will be returned.Thank you in advance!
Andre
-
Hi,
AtomArrays
are soley (although sometimes mentioned in the Python docs) a C++ thing. C4d expects you to pass a list of type symbols forar
, which will define the filter for the objects that will be returned.I never used this method, but something like the following should do what you want. But you might have to fine tune the type symbols, depending on what you want to do.
my_types = [c4d.Mmaterial, c4d.Xbase] tex_filenames = my_document.GetAllTextures(ar=my_types)
Cheers
zipit -
Hi @zipit ,
Cheers for your help!
@zipit said in GetAllTextures from materials only:
AtomArrays are soley (although sometimes mentioned in the Python docs) a C++ thing.
Thank you for clarifying! I was suspecting that it may be the case.
It gives me the following TypeError:
BaseDocument.GetAllTextures expected c4d.C4DAtom, not int
Does it work fine on your end?
I mean I can get all textures per material but it would take longer to process.
Thanks again!
Andre
-
Hi,
oh, then you have actually to pass the types not the smybols.
my_types = [c4d.BaseMaterial, c4d.BaseShader]
Cheers
zipit -
Hi,
@zipit said in GetAllTextures from materials only:
oh, then you have actually to pass the types not the smybols.
my_types = [c4d.BaseMaterial, c4d.BaseShader]Yes, I tried that as well before, it still looks for c4d.C4DAtom
It's a weird one, but like you said it may only work with C++. I can't see what objects to pass if types or symbols don't work.That's ok! I appreciate your time and help with this!
Andre
-
Hi,
sorry for all the confusion. You have to pass actual instances of objects. The following code does what you want (and this time I actually tried it myself ;)).
import c4d def main(): """ """ bc = doc.GetAllTextures(ar=doc.GetMaterials()) for cid, value in bc: print cid, value if __name__=='__main__': main()
Cheers,
zipit -
Hi @zipit ,
No need to apologise!
Thank you for figuring it out! It's actually clear, now that you explained.Do you have access to other render engines? Just to confirm I'm not being stupid (again ). It seems to return a list with texture paths from only Cinema materials.
As a summary:
- If I do not pass the Object Instances to
doc.GetAllTextures()
I will have a basecontainer with all of the textures paths from every scene object including materials that are Cinema and other type. - If we pass specific Object Instances list
doc.GetAllTextures(ar=doc.GetMaterials())
I will have a basecontainer with all of the texture paths from Cinema materials.
If this is correct it's a great workflow if only using Cinema materials, but rest not as much, still need to filter a lot of stuff out.
Either way, you answer my questions!
Thank you very much once again!
Andre
- If I do not pass the Object Instances to
-
Hi,
no, I do not have any external render engines here. But you can filter stuff, you just have to compose
ar
of objects you want to include.my_filter = [obj for obj in doc.GetMaterials() if obj.CheckType(c4d.Mterrain)] for _, path in doc.GetAllTextures(ar=my_filter): print path, "is a texture path in a terrain material."
You can throw everything that is a
c4d.C4DAtom
intoar
. You could try some of theBaseObjects
for example that have a texture path.For external renderer materials: have you confirmed that they are actually included in
doc.GetMaterials()
?Also writing a little script, that extracts all bitmap path attributes from a
GeListNode
(i.e. a shader tree) tree is not too hard either. I think someone asked a similar question in combination with Octane just recently.Cheers
zipit -
Hi,
@zipit said in GetAllTextures from materials only:
Hi,
no, I do not have any external render engines here. But you can filter stuff, you just have to compose
ar
of objects you want to include.my_filter = [obj for obj in doc.GetMaterials() if obj.CheckType(c4d.Mterrain)] for _, path in doc.GetAllTextures(ar=my_filter): print path, "is a texture path in a terrain material."
You can throw everything that is a c4d.C4DAtom into ar. You could try some of the BaseObjects for example that have a texture path.
That's a great example! Thank you!
For external renderer materials: have you confirmed that they are actually included in doc.GetMaterials()?
Yep, I've tried it and can confirm that the materials are included. Following your example:
OCTANE_MAT_ID = 1029501 my_filter = [obj for obj in doc.GetMaterials() if obj.CheckType(OCTANE_MAT_ID)] for _, path in doc.GetAllTextures(ar=my_filter): print path, "is a texture path in an Octane material."
Does not print anything.
Also writing a little script, that extracts all bitmap path attributes from a
GeListNode
(i.e. a shader tree) tree is not too hard either. I think someone asked a similar question in combination with Octane just recently.It may have been me! I do have the script but was curious to understand the GetAllTextures function, which you explained to me really well.
Thanks again!
-
Hi,
the function is most likely just looking for
c4d.Xbitmap
nodes (the shader type cinema uses to wrap around a texture file). If Octane does use its own bitmap shader, the function will not work.Cheers
zipit -
Just to add some information GetAllTexture call the message MSG_GETALLASSETS to all passed BaseList2D.
So even 3rd party BaseList2D are supported as long as the 3rd party developer supported MSG_GETALLASSETS.
Cheers,
Maxime. -