0
$\begingroup$

I have an object with several faces, and I want to loop over the faces, adjust the view for each differently and then UV unwrap the face from the chosen view.

I managed to do it using Blender GUI but how can I automate it via a python script?

This is the code I was trying with... I keep getting either a context error or an error saying that BMFace has been removed :s

import bpy, bmesh
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bm = bmesh.from_edit_mesh(bpy.data.objects['my_obj'].data)
for face in bm.faces:
    face.select = True
    if [...] : # Condition chosen to know which face this is
        q = Quaternion([...]) # Set desired corresponding view for this face
    for area in bpy.context.screen.areas:
        if area.type == 'VIEW_3D':
            break
    for region in area.regions:
        if region.type == 'WINDOW':
            break
    space = area.spaces[0]
    context = bpy.context.copy()
    context['area'] = area
    context['region'] = region
    context['space_data'] = space
    r3d = space.region_3d
    r3d.view_perspective = 'ORTHO'
    r3d.view_rotation = q

    for window in bpy.context.window_manager.windows:
        screen = window.screen
        for area in screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        for region in area.regions:
                            if region.type == 'WINDOW':
                                override = {'window': window, 'screen': screen, 'area': area, 'region': region}
                                bpy.ops.uv.project_from_view(override, orthographic=False, correct_aspect=True, clip_to_bounds=False, scale_to_bounds=True)
    face.select = False

Please help!

$\endgroup$
2
$\begingroup$

Manipulating UV coordinates in python is usually done via the bmesh interface.

I include an example from barber-pole.py

def spiralUVs(mesh, xPlus):
    # add a UV layer called "spiral" and make it slanted.
    mesh.uv_textures.new("spiral")
    bm = bmesh.new()
    bm.from_mesh(mesh)

    bm.faces.ensure_lookup_table()

    uv_layer = bm.loops.layers.uv[0]

    nFaces = len(bm.faces)
    for fi in range(nFaces):
        x0 = fi*2/nFaces
        x1 = (fi+1)*2/nFaces
        bm.faces[fi].loops[0][uv_layer].uv = (x0, 0)
        bm.faces[fi].loops[1][uv_layer].uv = (x1, 0)
        bm.faces[fi].loops[2][uv_layer].uv = (xPlus+x1, 1)
        bm.faces[fi].loops[3][uv_layer].uv = (xPlus+x0, 1)
    bm.to_mesh(mesh)

Some other examples that set UV texture coordinates include

$\endgroup$
  • $\begingroup$ Thanks a lot! I just got rid of this project_from_view function and set the values of the uv coordinates directly as desired :) $\endgroup$ – Beginner Jan 25 '16 at 8:28
1
$\begingroup$

You could try to create an operator that is executed in the correct context, then you don't need to search for the right one.

Something like this:

import bpy
import mathutils

def main(context):
    # Your code without context searching
    bpy.ops.uv.project_from_view()
    context.space_data.region_3d.view_rotation = mathutils.Quaternion((1,1,1))

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.mode == 'EDIT_MESH'

    def execute(self, context):
        main(context)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(SimpleOperator)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()

You can then execute the operator in your 3d-window (Space -> Simple Object Operator).

$\endgroup$
  • $\begingroup$ I am not used to bpy operators, but I don't see how this operator manages to be called in the correct context. Note that I need the whole thing to be fully automated in my case... no GUI at all. $\endgroup$ – Beginner Jan 25 '16 at 8:33
  • $\begingroup$ @Beginner any update if it worked for you without GUI using this? $\endgroup$ – gonephishing Mar 27 '18 at 9:52
0
$\begingroup$

This is not a script, but it may get what you want.

Select all faces (a) then unwrap (u). In the unwrap menu, select 'reset'. This will make every face fill up the whole uv grid. Each face will be a square, and fit your texture.

Hope this helps.

$\endgroup$
  • $\begingroup$ Thanks for the advice :) but it is not applicable in my case $\endgroup$ – Beginner Jan 25 '16 at 8:35

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.