OK, so who else hates Material datablock links?

General discussion about the development of the open source Blender

Moderators: jesterKing, stiv

Post Reply
osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

OK, so who else hates Material datablock links?

Post by osxrules »

I've been trying to get some Python working (again) and I keep coming across the problem where some functions don't return what I expect. Turns out the problem was again because Blender has two separate links per object - a datablock link and an object link. In the materials panel, you can see the OB and ME buttons.

This is a pain when it comes to materials because Blender's defaults are set to use datablocks (this can be changed in the user prefs thankfully). So in a Python script, you have to analyse each object for its type, then access it's data contents in order to get the material link.

It's far easier to use object links because no matter what object you are referencing, the function calls are the same:

object = Blender.Object.Get("somethin")
materials = object.getMaterials()

Using datablocks, you have to do something like this for each object type:

object = Blender.Object.Get("somethin")
if (object.getType() == "Mesh"):
name = object.getName
mesh = Blender.NMesh.GetRawFromObject(name)
if(mesh.materials):
try:
materials = mesh.materials
except:
pass

Would it be possible in future versions of Blender to remove the ability to link materials to datablocks and default it to objects or is there some reason why it might be better using datablocks?

On a related note, I also find the setup a little confusing with having the Mesh class and NMesh class and none of them are subclasses of Object. Why not have all object types descend from the object class and then just have a method getData that lets you access the raw data?

z3r0_d
Posts: 289
Joined: Wed Oct 16, 2002 2:38 am
Contact:

Post by z3r0_d »

changing getData() to return a Mesh object instead of NMesh would break existing scripts

Mesh and NMesh don't relate to blender OBJECTS at all, they both relate to the mesh datablock.

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

z3r0_d wrote:changing getData() to return a Mesh object instead of NMesh would break existing scripts
But why are there two of them - can't one mesh class handle all the stuff needed? Breaking existing scripts is not a major problem because commercial apps do it all the time and the amount of code change would be pretty small. It would make the API cleaner.
z3r0_d wrote:Mesh and NMesh don't relate to blender OBJECTS at all, they both relate to the mesh datablock.
Yeah it seems an object is used as a link to a datablock and material blocks link to either one of those but why link the material to the datablock? Ok if you want to change one object's datablock then the material follows but does anyone ever manually change the datablock link?

I think it would be better hiding the datablock access from the user at all times and just handle it internally while linking everything to the object and make everything accessible via the object class. It simplifies the GUI by getting rid of some buttons and simplifies the Python API.

z3r0_d
Posts: 289
Joined: Wed Oct 16, 2002 2:38 am
Contact:

Post by z3r0_d »

osxrules wrote:But why are there two of them - can't one mesh class handle all the stuff needed? Breaking existing scripts is not a major problem because commercial apps do it all the time and the amount of code change would be pretty small. It would make the API cleaner.
NMesh has always been in blender.. Unlike NMesh newer APIs in blender give direct access to the datablock, they don't copy it, are easier to extend and maintain and such.

So, the Mesh module was created to work that way. The NMesh module still exists for older scripts... but probably will go away
osxrules wrote:Yeah it seems an object is used as a link to a datablock and material blocks link to either one of those but why link the material to the datablock? Ok if you want to change one object's datablock then the material follows but does anyone ever manually change the datablock link?
of course they do [it's in the link menu, control+L]
osxrules wrote:I think it would be better hiding the datablock access from the user at all times and just handle it internally while linking everything to the object and make everything accessible via the object class. It simplifies the GUI by getting rid of some buttons and simplifies the Python API.
I disagree

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

z3r0_d wrote:So, the Mesh module was created to work that way. The NMesh module still exists for older scripts... but probably will go away.
I don't think it will. The reason being that materials are linked to datablocks and not objects by default. This means the only way to access an object's material properties through Python is via the NMesh class. That's why I think the default should be changed so NMesh can be removed.
z3r0_d wrote:of course they do [it's in the link menu, control+L]
I've never felt the need to access that menu and I've never heard people mention it on the BlenderArtists site but I guess it might come in handy some time.
z3r0_d wrote:
osxrules wrote:I think it would be better hiding the datablock access from the user at all times and just handle it internally while linking everything to the object and make everything accessible via the object class. It simplifies the GUI by getting rid of some buttons and simplifies the Python API.
I disagree
Ok but what about the original point. Do you think that materials should link to objects by default and remove the option to link to datablocks? The point being that because it's a user preference now, if someone writes a script that deals with materials, it will work for some users and not for others.

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

Another thing seems to be that the two links can exist simultaneously. I think that maybe explained some odd behaviour I saw when using multiple materials - the material preview doesn't update when you switch them.

You can assign a material to an object and to the datablock the object is linked to and depending on whether you press ME or OB, that is the one Blender uses. I assumed there was one material object that was being linked to either the object or the datablock.

That means that for a single object you can get this output:

obj get [[Material "Material.001"]]
obj getdata [[Material "Material"]]
nmesh get [[Material "Material"]]

obj.getMaterials returns that the object is linked to Material.001 and obj.getData().getMaterials() return the same as the NMesh class that the material linked to the datablock is called Material. Oh well, at least I can access the datablock material links via the object class and I can cut out all the NMesh calls and I don't need a try/except block any more.

If I can use the same code to get the material for all object types then that will be great but I think object.getData() is returning NoneType for anything other than mesh. Object.getMaterials() seems to work for all object types.

joeri
Posts: 96
Joined: Fri Jan 10, 2003 6:41 pm
Contact:

Post by joeri »

ctrl-L is the hart of blender. ( not only ctrl-L, the popups to (re)link other data blocks are everywhere in blender, what are you thinking? )

"...think it would be better hiding the datablock access from the user at all times..."

I think it's time you move on to another program.

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

joeri wrote:ctrl-L is the hart of blender. ( not only ctrl-L, the popups to (re)link other data blocks are everywhere in blender, what are you thinking? )
Y'know, I've been using Blender for nearly two years and I've never used ctrl-L other than for selecting linked verts on a model in editmode.
joeri wrote:"...think it would be better hiding the datablock access from the user at all times..."

I think it's time you move on to another program.
Ok, I said before that I could see uses for some datablock access - the main one I can see is if you have animated an object's position but want to change the mesh. My main problem still remains about the material links though.

I actually thought I had it using the object class but the problem is this:

When you access a material linked to a datablock via either NMesh or object.getData, the performance is terrible for big meshes.

However, materials linked to objects can be accessed very quickly.

I just want a quick way to get the list of materials applied to an object. Since accessing materials linked to objects is much faster, maybe Blender could default to linking materials to objects instead of datablocks and remove the option. By all means leave the other datablock stuff since it seems two Blender users need it ;).

Out of interest, has anyone changed the user preference to use objects before I made the thread? I'm guessing this affects Python people most but it affects the performance of export scripts quite dramatically for large scenes (by that I mean scenes containing high poly models).

edit: I just did a test and I didn't expect there to be so much of a difference though I knew something was slowing my script down. I replaced all of the calls to get materials via the NMesh class with ones that use the object.getMaterials class, leaving only one NMesh call to export each actual object and the results are as follows:

50 cubes with 6146 verts each = 307300 verts
20 frames exported
time using NMesh: 3min30s

same scene exported using getMaterials() for material export and one call to NMesh for object mesh reading
export time: 34 seconds

That's a 6x speed increase.
Last edited by osxrules on Mon May 15, 2006 5:15 pm, edited 1 time in total.

z3r0_d
Posts: 289
Joined: Wed Oct 16, 2002 2:38 am
Contact:

Post by z3r0_d »

osxrules wrote:When you access a material linked to a datablock via either NMesh or object.getData, the performance is terrible for big meshes.

However, materials linked to objects can be accessed very quickly.
we've already discussed this. That is the reason the Mesh api was created

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

z3r0_d wrote:
osxrules wrote:When you access a material linked to a datablock via either NMesh or object.getData, the performance is terrible for big meshes.

However, materials linked to objects can be accessed very quickly.
we've already discussed this. That is the reason the Mesh api was created
Newbies in the house say hoooooo

hoooooo[/just me]

Ok, I get it now :roll:

I remember I tried that before but I called the Mesh class using the name of the object instead of the name of the datablock.

Now, are there equivalent classes for all object types like curve data or are they just as fast as the mesh class? For example, is getting a material from a curve just as fast as getting one for a mesh via the Mesh class?

If not, then I might just go the route of using object material links after all. Not just for speed either but the code is the same for all objects.

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

Ok, it seems that for some other object types, using object.getData() is fast enough. For meshes, I could do object.getData(True) to return the datablock name and then use that to get the Mesh.

The trouble is that object.getData() is returning None for things like meta objects and nurbs curves and a blank for text objects. Since obj.getMaterials works for all the objects I've just decided I'll go that way. It shouldn't be much trouble for people to change material links to OB anyway and I can maybe write a script to do it automatically.

Then I will use each object class for exporting objects individually using the Mesh class instead of NMesh for meshes.

Thanks for the help.

joeri
Posts: 96
Joined: Fri Jan 10, 2003 6:41 pm
Contact:

Post by joeri »

By all means leave the other datablock stuff since it seems two Blender users need it Wink.
:) ... And nobody else seems to hate the object blocks might be a reason to.

stiv
Posts: 0
Joined: Tue Aug 05, 2003 7:58 am
Location: 45N 86W

Post by stiv »

Heh, joeri!

I have tried to stay out of this thread because the whole rant was based on not understanding Blender. However, due to my poor impulse control, I have to ask:

I know it is in the User Prefs, but Materials linked to ObData has been the Blender default pretty much since day one, right?

osxrules
Posts: 0
Joined: Wed Jun 02, 2004 6:34 pm

Post by osxrules »

stiv wrote:I have tried to stay out of this thread because the whole rant was based on not understanding Blender.
The rant was based on the choice to link materials to datablocks instead of object blocks by default, which is still my complaint. The part that I didn't get was the need to have access to the datablocks at all but now I see uses for it.

Post Reply