Last active
November 23, 2023 06:55
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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