3
$\begingroup$

I want to be able to display the UV coordinates of a selected face (or vert but if I can get one to work I assume the other will too).

I cobbled together a rough script that'll show the UV coordinates of the first vertex of the active face, in 2.93 it worked but in 3.0 it breaks and crashes often. In 3.0 it does show the first vertex (of the face) coordinates but you can't see your selection in the 3d view and X-ray mode makes Blender crash. Having it running while trying to move the face breaks a lot of stuff since its opening and closing the bmesh (each frame?)

import bpy
import bmesh


def getFaceUV(context):

    if len(context.edit_object.data.uv_layers) < 1:
        return " Incompatible", " Incompatible"

    main_element = context.edit_object.data
    bm = bmesh.from_edit_mesh(main_element)
    uv_layer = bm.loops.layers.uv[0]

    currentX, currentY = bm.faces.active.loops[0][uv_layer].uv

    currentObj = context.edit_object
    bm.faces.index_update()

    bmesh.update_edit_mesh(main_element, loop_triangles=False, destructive=False)
    return currentX, currentY



class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the 3d viewport"""
    bl_label = "UV coords in view_3d"
    bl_idname = "OBJECT_PT_3dpanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Face UV"

    def draw(self, context):
        layout = self.layout
        
        uvAccessible = False
        if context.mode == 'EDIT_MESH':
            if context.tool_settings.mesh_select_mode[:] == (False, False, True):
                try:
                    currentX, currentY = getFaceUV(context)
                except:
                    currentX, currentY = " Unexpected", " Error"
                    
                uvAccessible = True
            if not uvAccessible:
                currentX, currentY = " Only works in face mode", " Only works in face mode"
            row = layout.row()
            row.label(text=f"X: {currentX}")
            row = layout.row()
            row.label(text=f"Y: {currentY}")
        else:
            row = layout.row()
            row.label(text=f"Only works in edit mode with a face selected")


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


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


if __name__ == "__main__":
    register()

Is there a way to get the selected faces UV coordinates and display them in the UI without using bmesh each frame?

$\endgroup$

1 Answer 1

4
$\begingroup$

Have a look into Text Editor -> Templates -> Python. Quickly combined Operator Mesh UV and UI Panel Simple templates. You can never be sure, but no crashes while testing...

enter image description here

import bpy
import bmesh

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_context = "mesh_edit"
    
    def draw(self, context):
        layout = self.layout
        obj = context.object
        me = obj.data
        bm = bmesh.from_edit_mesh(me)

        uv_layer = bm.loops.layers.uv.verify()
        coords = []
        for face in [f for f in bm.faces if f.select]:
            for loop in face.loops:
                coords.append(loop[uv_layer].uv)
        #bmesh.update_edit_mesh(me)
        for n, item in enumerate(coords):
            row = layout.row()
            row.label(text="Vert {}: {:.2f}, {:.2f}".format(n, item.x, item.y))

def register():
    bpy.utils.register_class(HelloWorldPanel)
def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ @CybranM Blender 3.0, no performance issues $\endgroup$
    – pyCod3R
    Jan 20, 2022 at 22:29

You must log in to answer this question.

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