Skip to content

Instantly share code, notes, and snippets.

@esnosy
Last active November 23, 2023 06:55
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save esnosy/9f2485fd3d3a3c6c5647050837648095 to your computer and use it in GitHub Desktop.
Save esnosy/9f2485fd3d3a3c6c5647050837648095 to your computer and use it in GitHub Desktop.
Example Blender script for getting/setting UV edge selection for large meshes using NumPy and foreach_get/set
# Author: Iyad Ahmed
import bpy
# importing numpy is slow for first time
import numpy as np
prev_mode = bpy.context.object.mode
bpy.ops.object.mode_set(mode="OBJECT")
bpy.context.object.update_from_editmode()
mesh = bpy.context.object.data
uv_map = mesh.uv_layers.active
nf = len(mesh.polygons)
nl = len(mesh.loops)
loop_start = np.zeros(nf, dtype=int)
mesh.polygons.foreach_get("loop_start", loop_start)
loop_total = np.zeros(nf, dtype=int)
mesh.polygons.foreach_get("loop_total", loop_total)
start_r = np.repeat(loop_start, loop_total)
total_r = np.repeat(loop_total, loop_total)
loop_indices = np.arange(nl, dtype=int)
loop_indices_next = (
(loop_indices - start_r + 1) % total_r
) + start_r # Wrap loop indices so it becomes cyclic
# Maybe there's a better way?
uv_verts = np.zeros(nl * 2)
uv_map.data.foreach_get("uv", uv_verts)
uv_verts.shape = nl, 2
a = uv_verts[loop_indices]
b = uv_verts[loop_indices_next]
v = a - b
# Original UV verts select state
o_sel = np.zeros(nl, dtype=bool)
uv_map.data.foreach_get("select", o_sel)
# Select short uv edges
sel = (v * v).sum(axis=1) < 0.005 ** 2
sel[loop_indices_next] = sel[loop_indices_next] | sel[loop_indices]
# OR-ing as edge AB is same as BA,
# we don't want a vertex that was selected to be unselected
# Untill Blender supports proper UV edge selection again
# probably after GSOC 2021
# New select state
n_sel = sel | o_sel # Select new edges and keep already selected
# n_sel = (~sel) & o_sel # Uncomment to deselct edges instead
uv_map.data.foreach_set("select", n_sel)
bpy.ops.object.mode_set(mode=prev_mode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment