3
$\begingroup$

I'm creating an addon for browsing for an image and creating a texture from it.

I could get Image path from the user but I stuck in how to apply the image to the object as a texture.

In original Blender The images disappear from the preview if it's misplaced, renamed, or deleted after texturing the object. See image one. After browsing to that image, Once again its come back in Blender. See image two.
Here is my code:

bpy.types.Scene.MyPath = StringProperty(name="Browse Image:",
   attr="custompath",# this a variable that will set or get from the scene
   description="simple file path",
   maxlen= 1024,
   subtype='FILE_PATH',
   default= "")#this set the text

class TexturePanel(Panel):
   .
   .
   .
   .
   self.layout.prop(context.scene, 'MyPath') # creates Browser in panel
   .
   .
   .
   .

See the Image two left side of the blender marked in blue color for browsing to the image.

How to apply this? Or how can we texture in Python?

one

enter image description here

two

enter image description here

$\endgroup$
3
$\begingroup$

You could use a callback to detect changes to the filepath field:

def update_texture(self, context):
    print("New image:", self.MyPath)

bpy.types.Scene.MyPath = StringProperty(name="Browse Image:",
   attr="custompath",# this a variable that will set or get from the scene
   description="simple file path",
   maxlen= 1024,
   subtype='FILE_PATH',
   default= "",
   update=update_texture) # callback

In that callback, you would texture the mesh. It really depends on your situation how to go from here, since there could be UV mapping or Cycles textures.

In case of a mesh with UV mapping, note the difference between

  • bpy.context.object.data.polygons[#].material_index, which tells you the # of the material (ob.data.materials[#])
  • and the image assigned to a face for UV mapping (ob.data.uv_textures.active.data[poly#].image).

You may wanna add a new material to the mesh object: ob.data.materials.append(mat), which you need to create beforehand: mat = bpy.data.materials.new(...)

Or use an existing material?

Active material slot's material: ob.active_material

First slot's material (if there is one):

try:
    slot1 = ob.material_slots[0]
except KeyError:
    return
mat = slot1.material
if mat is not None:
    # there is a mat in first slow and it has a material

You can load your image from filepath as image datablock and assign it for UV mapped meshes to uv_textures...image, or figure out the index and assign to Polygon.material_index (or both).

Find the index e.g. like:

def material_index(me, material):
    for i, mat in enumerate(me.materials):
        if mat == material:
            return i
    else:
        return None # or -1 or 0??

You may wanna look at the code of the Material Utils addon, which transfers material assignments from Polygon.material_index to UV editor (uv_textures...image) or the other way around.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.