How to get material by name?


16-11-2005 04:25:22

I have a submesh and I want to mess with its texture passes. This is the closest I got so far:


That returns a ResourcePtr, which I suppose is handy in C++, but how do I get to the actual Material in Python? Is there any way to do this currently, or is this an area that needs some SWIG love? :)

In the later case, I'm willing to try my hand at solving this. I just thought I'd make sure that this is indeed a shortcoming of PyOgre.

Also, if this is a problem do you have any ideas about what would be the preferred way to fix it?

I can think of extending MaterialManager to return the actual Material (then do the same for other managers), but I'm not sure whether someone else would actually want the ResourcePtr instead. Can you think of any scenario where this could happen? In general, what use are SharedPtrs for PyOgre users?

As an interim solution for other cases like this, I can think of utility cast functions. This introduces concepts that are extraneous to Python, but at least it would let PyOgre users continue with their work while more proper solutions are being implemented for each similar problem.




16-11-2005 06:53:06

This should work like this:
But after checking it just now, it doesn't seem to be working. =/

We never got shared pointers working as I want them to. (IE this function should just return either a Material or a MaterialPtr (assuming the MaterialPtr can do what it needs to).

Maybe I'll put this on the todo list. Obviously something needs to be done because this code isn't working.


16-11-2005 19:34:44

Oops, I figured it out. I forgot the Ptr name ogre uses conflicts with swig's interal *Ptr classes, so we renamed it as Pointer:

mp = ogre.MaterialPointer(ogre.MaterialManager.getSingleton().getByName(submesh.materialName))
And this works.

Be careful though, the dir on this object will only return the SharedPointer's class members, but you can call them even though they aren't in dir:

(Pdb) dir(mp)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'get', 'this', 'thisown', 'unique', 'useCount']
(Pdb) mp.origin

You can also use the get method to retrieve the original Material object too, but since MaterialPointers are reference counted you may want to hold onto a copy of it just incase the useCount drops too low.


16-11-2005 22:53:17

Hmm, that sounds weird. I thought dir() basically looked through the object/module to find all its methods. How can it miss some of them? (if it's too advanced to get into, that's ok :))


17-11-2005 00:42:25

It's a little python magic. Basically the SharedPointer class has overridden the __getattr__ method, and this is called whenever you try to access a method of the class that doesn't exist:

class Test:
def __getattr__(self, attr):
print attr
return None

t = Test()

t.x # prints x
t.y # prints y
t.z # prints z

Basically whenever you try to access a member of SharedPointer which doesn't exist, it automatically calls the get method (which returns what the pointer points to, like Material) and tries to access it that way.


17-11-2005 14:38:57

Ah, cool. :) Makes sense.


18-11-2005 04:20:23

OK, MaterialPointer and .get() are what I needed. Thank you very much!