Finding current texture using python

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Cave_Dweller
Posts: 4
Joined: Wed Nov 28, 2012 6:20 pm

Finding current texture using python

Postby Cave_Dweller » Wed Nov 28, 2012 6:36 pm

Hello All,
I should first mention that while I have been working with 3d software for a long time I have just been introduced to blender recently and have begun poking around trying to get a feel for how blender is constructed. So after tinkering around and creating some windows/panels using python I thought I would take a crack at converting a script I had from another software package into something I could use in blender. Unfortunately, I have run into a small problem. Part of the script requires that I get the name of the current texture I am working with. I have found several examples of being able to loop through all the textures in a scene and getting all of the names which is helpful. However, what I would like to do is determine which texture is active in the texture panel and be able to grab its name. The ultimate goal being to replace the image being used in my current texture. Any ideas on how I can make this happen?

CoDEmanX
Posts: 894
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Postby CoDEmanX » Wed Nov 28, 2012 9:06 pm

you can get the active material like:

Code: Select all

bpy.context.object.active_material
bpy.data.materials['Material.002']


or for the slot index:

Code: Select all

bpy.context.object.active_material_index
3


for the material name:

Code: Select all

bpy.context.object.active_material.name


note that active_material can be None when there's a slot added, but no material associated, or no material slot at all.

active_material_index is 0 if the first slot is selected, but also 0 if there's no slot in stack! So always check for material first!

Code: Select all

if bpy.context.active_material:
    print("Active Material Name:", bpy.context.active_material.name)
    print("Active Material Index:", bpy.context.active_material_index)
else:
    print("No Material in stack!")



For material of active polygon you can do:

Code: Select all

ob = bpy.context.object

if ob.mode == 'EDIT':
    # Force mesh update to get up-to-date material assignment
    bpy.ops.object.editmode_toggle()
    bpy.ops.object.editmode_toggle()

p = ob.data.polygons
mat = ob.data.materials[p[p.active].material_index]

print("Material of active polygon:", mat.name)
I'm sitting, waiting, wishing, building Blender in superstition...

Cave_Dweller
Posts: 4
Joined: Wed Nov 28, 2012 6:20 pm

Postby Cave_Dweller » Wed Nov 28, 2012 11:04 pm

Thanks CoDEmanX that does answer some other questions that I had. However, what I am trying to do is manipulate the texture (not material) itself. In other words, if I have a empty scene I can click on the checkered texture icon and create a new texture, change the type to image and then load an image. My question is how can I change its source or other attributes later on via python. The reason for my first question was that my thinking was that if I could find a way to grab the name of the texture somehow then I could later us it to go in and swap out its source later on if I wanted to. My thinking initially was that I could just grab the texture name when I created the texture but it would be nice if I could simply add a button to the texture panel that I could use to grab it later if I needed to since in some cases the textures would have already been created.

CoDEmanX
Posts: 894
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Postby CoDEmanX » Thu Nov 29, 2012 12:24 am

First you need the material to access the texture, it's like

Material Slot -> Material -> Texture Slot -> Texture

For active texture, you can do:

Code: Select all

C.object.active_material.active_texture.name


Change type to Image / Movie and set image to an already loaded image:

Code: Select all

Texture.type = 'IMAGE'
Texture.image = bpy.data.images['loaded_before.jpg']
I'm sitting, waiting, wishing, building Blender in superstition...

Cave_Dweller
Posts: 4
Joined: Wed Nov 28, 2012 6:20 pm

Postby Cave_Dweller » Thu Nov 29, 2012 4:09 am

Thanks again CoDEmanX. I think the biggest hurdle for me was understanding the relationship between materials and textures. The only question I have left is the case where there is no shader linked to a texture. For example, if I have an empty scene with just the camera, I can create a texture using the checkered icon. Is there a way to access the name of the new texture as well?

CoDEmanX
Posts: 894
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Postby CoDEmanX » Thu Nov 29, 2012 8:18 am

there are a lot checkered icons in texture tab, which one do you mean?

and how could you create a texture with a checkered icon? I don't know a way to do that, it's required to click the "+ New" button
I'm sitting, waiting, wishing, building Blender in superstition...

Cave_Dweller
Posts: 4
Joined: Wed Nov 28, 2012 6:20 pm

Postby Cave_Dweller » Fri Nov 30, 2012 3:14 am

Ok so after poking around a bit more I think I am starting to get a better understanding some of the relationships that blender textures have to the overall scene. As CoDEmanX eluded to its all about context. From what I can tell there are three different contexts that a texture can be in. They are Material, World, and TexDraw. They are represented by icons in the texture panel that look like a checkered sphere, a globe and a paintbrush respectively. The fist two are pretty similar in how you retrieve the active textures name. The third however, is still eluding me. A quick search of the word TexDraw in the API docs and Google resulted in next to no additional information, which makes me wonder if I should be looking for it by a different name. Of course all of this has raised the larger question of how to determine the context dynamically. In other words if I am working on a texture in the world context I would like my script to know that I am in working in a world context and grab the correct name instead of say using a material context and grabbing one from there. Anyway, as I continue my search I will continue to post what I find along with any relevant code snippets I run across. Here is what I have so far

Code for Material Context:

Code: Select all

 bpy.context.object.active_material.active_texture.name


Code for World Context:

Code: Select all

 bpy.context.scene.world.active_texture.name


Code for TexDraw Context:

Code: Select all

 # Still trying to figure this one out

CoDEmanX
Posts: 894
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Postby CoDEmanX » Fri Nov 30, 2012 11:22 am

have a look at:

Blender\2.64\scripts\startup\bl_ui\properties_texture.py

it's the texture panel code.

the problem about context is, that there can be multiple Properties editors in current screen layout. Therefore, you gotta be careful when getting the context - you could use the first Properties editor only for instance (the texture_context is independent!)

Code: Select all

for area in bpy.context.screen.areas:
    if area.type == 'PROPERTIES':
        print("Current texture_context:", area.spaces[0].texture_context)
        break


not sure about the brush, but this seems to work:

Code: Select all

bpy.data.brushes['TexDraw'].texture
I'm sitting, waiting, wishing, building Blender in superstition...


Return to “Python”

Who is online

Users browsing this forum: No registered users and 0 guests