1
$\begingroup$

I'm very new to Blender and its Python API so bear with me. I'm trying to create a cube and put an image texture (unwrapped, so that the entire image can be seen on the cube face) on each of its faces. I have everything but the unwrapping part working - the images show on the cube faces but they are cropped. Here's what I have, thanks in advance for the help!

def make_cube_with_material(size, x, y, z):
    bpy.ops.mesh.primitive_cube_add(size=size, enter_editmode=False, align='WORLD', location=(x, y, z))
    obj = bpy.context.active_object
    obj.data.materials.append(random.choice(mats))
    me = obj.data
    for edge in me.edges:
        edge.use_seam = True
    
    bm = bmesh.new()   # create an empty BMesh
    bm.from_mesh(me)   # fill it in from a Mesh
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE', action='ENABLE')
    for face in bm.faces:
        face.material_index = 0
        face.select = True
        bpy.ops.uv.unwrap()
    bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE', action='DISABLE')
    bpy.ops.object.mode_set(mode='OBJECT')
    
    # Finish up, write the bmesh back to the mesh
    bm.to_mesh(me)
    bm.free()  # free and prevent further access
$\endgroup$
2
  • $\begingroup$ May I assume that outside of this code you have created the materials that involve an image texture as color input to a shader node and that mats is a collection of those materials? $\endgroup$ Dec 27, 2021 at 20:36
  • $\begingroup$ yep thats correct! the image displays on the side of the cube, but the edges of the image don't match up with the edges of the cube which is what I'm trying to achieve. $\endgroup$
    – me163
    Dec 27, 2021 at 20:49

1 Answer 1

0
$\begingroup$

You have a couple of problems in your logic. Some are from the way you're mixing mesh ops with bmesh ops and some are in the way you're using bmesh.

Bmesh requires that you validate the faces or edges lookup tables before you use the data with a line like this. Replace faces with edges for the edge data.

bm.faces.ensure_lookup_table()

As long as you're doing things with bmesh, may as well use bemsh for the seams, so I changed that loop.

The mesh select and unselect mode calls don't affect the bmesh so I replaced them with a loop to deselect all of the bmesh faces before unwrapping.

In your unwrap loop, you don't update the mesh from the bmesh before calling unwrap. Unwrap works on the mesh data not the bmesh data.

The cube primitive now comes with a UV map. You need to reset the map before you unwrap. The following script will do the unwrapping properly but you'll have to verify the code necessary for the materials yourself, as I didn't validate whether you're using face.material_index correctly:

import bpy
import bmesh

def make_cube_with_material(size, x, y, z):
    bpy.ops.mesh.primitive_cube_add(size=size, enter_editmode=False, align='WORLD', location=(x, y, z))
    obj = bpy.context.active_object
    #obj.data.materials.append(random.choice(mats))
    mesh = obj.data

    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.uv.reset()

    bm = bmesh.from_edit_mesh(mesh)

    bm.edges.ensure_lookup_table()
    for edge in bm.edges:
        edge.seam = True

    bm.faces.ensure_lookup_table()
    for face in bm.faces:
        face.select_set(False)


    for face in bm.faces:
        face.material_index = 0
        face.select_set(True)
        bmesh.update_edit_mesh(mesh)
        bpy.ops.uv.unwrap()
        face.select_set(False)

    bpy.ops.object.mode_set(mode='OBJECT')

$\endgroup$
2
  • $\begingroup$ This worked perfectly! Thank you so much! Still trying to wrap my head around these APIs :) $\endgroup$
    – me163
    Dec 27, 2021 at 23:11
  • $\begingroup$ You're welcome. I'm glad it worked. The thing to remember about bmesh is that a bmesh is a separate copy of the original mesh so you must copy it back for the changes to affect the original and that bpy.ops almost always operate on the original mesh. $\endgroup$ Dec 27, 2021 at 23:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .