[Bf-extensions-cvs] [2cbb9e2b] master: Magic UV: Release v6.6
nutti
noreply at git.blender.org
Fri Apr 22 09:23:50 CEST 2022
Commit: 2cbb9e2b960ac343a6f5796e20d0efb443bd4a67
Author: nutti
Date: Fri Apr 22 16:21:10 2022 +0900
Branches: master
https://developer.blender.org/rBA2cbb9e2b960ac343a6f5796e20d0efb443bd4a67
Magic UV: Release v6.6
Added Features
* Copy/Paste UV Island
Updated Features
* Pack UV
* Add options "Accurate Island Copy", "Stride", "Apply Pack UV"
Other Updates
* Add 'develop' branch to the update target of updater
* Make documents official
* Fix bugs
===================================================================
M magic_uv/__init__.py
M magic_uv/common.py
M magic_uv/lib/__init__.py
M magic_uv/lib/bglx.py
M magic_uv/op/__init__.py
M magic_uv/op/align_uv.py
M magic_uv/op/align_uv_cursor.py
M magic_uv/op/clip_uv.py
M magic_uv/op/copy_paste_uv.py
M magic_uv/op/copy_paste_uv_object.py
M magic_uv/op/copy_paste_uv_uvedit.py
M magic_uv/op/flip_rotate_uv.py
M magic_uv/op/mirror_uv.py
M magic_uv/op/move_uv.py
M magic_uv/op/pack_uv.py
M magic_uv/op/preserve_uv_aspect.py
M magic_uv/op/select_uv.py
M magic_uv/op/smooth_uv.py
M magic_uv/op/texture_lock.py
M magic_uv/op/texture_projection.py
M magic_uv/op/texture_wrap.py
M magic_uv/op/transfer_uv.py
M magic_uv/op/unwrap_constraint.py
M magic_uv/op/uv_bounding_box.py
M magic_uv/op/uv_inspection.py
M magic_uv/op/uv_sculpt.py
M magic_uv/op/uvw.py
M magic_uv/op/world_scale_uv.py
M magic_uv/preferences.py
M magic_uv/properties.py
M magic_uv/ui/IMAGE_MT_uvs.py
M magic_uv/ui/VIEW3D_MT_object.py
M magic_uv/ui/VIEW3D_MT_uv_map.py
M magic_uv/ui/__init__.py
M magic_uv/ui/uvedit_copy_paste_uv.py
M magic_uv/ui/uvedit_editor_enhancement.py
M magic_uv/ui/uvedit_uv_manipulation.py
M magic_uv/ui/view3d_copy_paste_uv_editmode.py
M magic_uv/ui/view3d_copy_paste_uv_objectmode.py
M magic_uv/ui/view3d_uv_manipulation.py
M magic_uv/ui/view3d_uv_mapping.py
M magic_uv/utils/__init__.py
M magic_uv/utils/bl_class_registry.py
M magic_uv/utils/compatibility.py
A magic_uv/utils/graph.py
M magic_uv/utils/property_class_registry.py
===================================================================
diff --git a/magic_uv/__init__.py b/magic_uv/__init__.py
index dc3c9641..88385107 100644
--- a/magic_uv/__init__.py
+++ b/magic_uv/__init__.py
@@ -4,16 +4,17 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
bl_info = {
"name": "Magic UV",
- "author": "Nutti, Mifth, Jace Priester, kgeogeo, mem, imdjs"
+ "author": "Nutti, Mifth, Jace Priester, kgeogeo, mem, imdjs, "
"Keith (Wahooney) Boshoff, McBuff, MaxRobinot, "
- "Alexander Milovsky, Dusan Stevanovic, MatthiasThDs",
- "version": (6, 5, 0),
+ "Alexander Milovsky, Dusan Stevanovic, MatthiasThDs, "
+ "theCryingMan, PratikBorhade302",
+ "version": (6, 6, 0),
"blender": (2, 80, 0),
"location": "See Add-ons Preferences",
"description": "UV Toolset. See Add-ons Preferences for details",
diff --git a/magic_uv/common.py b/magic_uv/common.py
index 4e633408..034936c5 100644
--- a/magic_uv/common.py
+++ b/magic_uv/common.py
@@ -4,8 +4,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
from collections import defaultdict
from pprint import pprint
@@ -17,6 +17,7 @@ from mathutils import Vector
import bmesh
from .utils import compatibility as compat
+from .utils.graph import Graph, Node
__DEBUG_MODE = False
@@ -286,6 +287,30 @@ def get_island_info(obj, only_selected=True):
return get_island_info_from_bmesh(bm, only_selected)
+# Return island info.
+#
+# Format:
+#
+# [
+# {
+# faces: [
+# {
+# face: BMFace
+# max_uv: Vector (2D)
+# min_uv: Vector (2D)
+# ave_uv: Vector (2D)
+# },
+# ...
+# ]
+# center: Vector (2D)
+# size: Vector (2D)
+# num_uv: int
+# group: int
+# max: Vector (2D)
+# min: Vector (2D)
+# },
+# ...
+# ]
def get_island_info_from_bmesh(bm, only_selected=True):
if not bm.loops.layers.uv:
return None
@@ -1184,12 +1209,22 @@ def __is_polygon_flipped(points):
def __is_point_in_polygon(point, subject_points):
+ """Return true when point is inside of the polygon by using
+ 'Crossing number algorithm'.
+ """
+
count = 0
for i in range(len(subject_points)):
uv_start1 = subject_points.get(i)
uv_end1 = subject_points.get(i + 1)
uv_start2 = point
uv_end2 = Vector((1000000.0, point.y))
+
+ # If the point exactly matches to the point of the polygon,
+ # this point is not in polygon.
+ if uv_start1.x == uv_start2.x and uv_start1.y == uv_start2.y:
+ return False
+
intersected, _ = __is_segment_intersect(uv_start1, uv_end1,
uv_start2, uv_end2)
if intersected:
@@ -1239,7 +1274,7 @@ def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list,
overlapped_uv_layer_pairs.append([uv_layer_1, uv_layer_2])
overlapped_bm_paris.append([bm_1, bm_2])
- # next, check polygon overlapped
+ # check polygon overlapped (inter UV islands)
overlapped_uvs = []
for oip, uvlp, bmp in zip(overlapped_isl_pairs,
overlapped_uv_layer_pairs,
@@ -1272,6 +1307,41 @@ def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list,
"subject_uvs": subject_uvs,
"polygons": polygons})
+ # check polygon overlapped (intra UV island)
+ for info, uv_layer, bm in isl:
+ for i in range(len(info["faces"])):
+ clip = info["faces"][i]
+ f_clip = clip["face"]
+ clip_uvs = [l[uv_layer].uv.copy() for l in f_clip.loops]
+ for j in range(len(info["faces"])):
+ if j <= i:
+ continue
+
+ subject = info["faces"][j]
+ f_subject = subject["face"]
+
+ # fast operation, apply bounding box algorithm
+ if (clip["max_uv"].x < subject["min_uv"].x) or \
+ (subject["max_uv"].x < clip["min_uv"].x) or \
+ (clip["max_uv"].y < subject["min_uv"].y) or \
+ (subject["max_uv"].y < clip["min_uv"].y):
+ continue
+
+ subject_uvs = [l[uv_layer].uv.copy() for l in f_subject.loops]
+ # slow operation, apply Weiler-Atherton cliping algorithm
+ result, polygons = \
+ __do_weiler_atherton_cliping(clip_uvs, subject_uvs,
+ mode, same_polygon_threshold)
+ if result:
+ overlapped_uvs.append({"clip_bmesh": bm,
+ "subject_bmesh": bm,
+ "clip_face": f_clip,
+ "subject_face": f_subject,
+ "clip_uv_layer": uv_layer,
+ "subject_uv_layer": uv_layer,
+ "subject_uvs": subject_uvs,
+ "polygons": polygons})
+
return overlapped_uvs
@@ -1308,3 +1378,64 @@ def __is_polygon_same(points1, points2, threshold):
return False
return True
+
+
+def _is_uv_loop_connected(l1, l2, uv_layer):
+ uv1 = l1[uv_layer].uv
+ uv2 = l2[uv_layer].uv
+ return uv1.x == uv2.x and uv1.y == uv2.y
+
+
+def create_uv_graph(loops, uv_layer):
+ # For looking up faster.
+ loop_index_to_loop = {} # { loop index: loop }
+ for l in loops:
+ loop_index_to_loop[l.index] = l
+
+ # Setup relationship between uv_vert and loops.
+ # uv_vert is a representative of the loops which shares same
+ # UV coordinate.
+ uv_vert_to_loops = {} # { uv_vert: loops belonged to uv_vert }
+ loop_to_uv_vert = {} # { loop: uv_vert belonged to }
+ for l in loops:
+ found = False
+ for k in uv_vert_to_loops.keys():
+ if _is_uv_loop_connected(k, l, uv_layer):
+ uv_vert_to_loops[k].append(l)
+ loop_to_uv_vert[l] = k
+ found = True
+ break
+ if not found:
+ uv_vert_to_loops[l] = [l]
+ loop_to_uv_vert[l] = l
+
+ # Collect adjacent uv_vert.
+ uv_adj_verts = {} # { uv_vert: adj uv_vert list }
+ for v, vs in uv_vert_to_loops.items():
+ uv_adj_verts[v] = []
+ for ll in vs:
+ ln = ll.link_loop_next
+ lp = ll.link_loop_prev
+ uv_adj_verts[v].append(loop_to_uv_vert[ln])
+ uv_adj_verts[v].append(loop_to_uv_vert[lp])
+ uv_adj_verts[v] = list(set(uv_adj_verts[v]))
+
+ # Setup uv_vert graph.
+ graph = Graph()
+ for v in uv_adj_verts.keys():
+ graph.add_node(
+ Node(v.index, {"uv_vert": v, "loops": uv_vert_to_loops[v]})
+ )
+ edges = []
+ for v, adjs in uv_adj_verts.items():
+ n1 = graph.get_node(v.index)
+ for a in adjs:
+ n2 = graph.get_node(a.index)
+ edges.append(tuple(sorted((n1.key, n2.key))))
+ edges = list(set(edges))
+ for e in edges:
+ n1 = graph.get_node(e[0])
+ n2 = graph.get_node(e[1])
+ graph.add_edge(n1, n2)
+
+ return graph
diff --git a/magic_uv/lib/__init__.py b/magic_uv/lib/__init__.py
index 76eaf480..bccf4e17 100644
--- a/magic_uv/lib/__init__.py
+++ b/magic_uv/lib/__init__.py
@@ -4,8 +4,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
if "bpy" in locals():
import importlib
diff --git a/magic_uv/lib/bglx.py b/magic_uv/lib/bglx.py
index c1f696ab..044141b6 100644
--- a/magic_uv/lib/bglx.py
+++ b/magic_uv/lib/bglx.py
@@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+# <pep8-80 compliant>
+
from threading import Lock
import bgl
diff --git a/magic_uv/op/__init__.py b/magic_uv/op/__init__.py
index da77b17b..223ed004 100644
--- a/magic_uv/op/__init__.py
+++ b/magic_uv/op/__init__.py
@@ -4,8 +4,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
if "bpy" in locals():
import importlib
diff --git a/magic_uv/op/align_uv.py b/magic_uv/op/align_uv.py
index 9f606db9..cf5a49de 100644
--- a/magic_uv/op/align_uv.py
+++ b/magic_uv/op/align_uv.py
@@ -4,8 +4,8 @@
__author__ = "imdjs, Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
import math
from math import atan2, tan, sin, cos
@@ -28,6 +28,12 @@ from .. import common
def _is_valid_context(context):
+ # 'IMAGE_EDITOR' and 'VIEW_3D' space is allowed to execute.
+ # If 'View_3D' space is not allowed, you can't find option in Tool-Shelf
+ # after the execution
+ if not common.is_valid_space(context, ['IMAGE_EDITOR', 'VIEW_3D']):
+ return False
+
objs = common.get_uv_editable_objects(context)
if not objs:
return False
@@ -36,12 +42,6 @@ def _is_valid_context(context):
if context.object.mode != 'EDIT':
return False
- # 'IMAGE_EDITOR' and 'VIEW_3D' space is allowed to execute.
- # If 'View_3D' space is not allowed, you can't find option in Tool-Shelf
- # after the execution
- if not common.is_valid_space(context, ['IMAGE_EDITOR', 'VIEW_3D']):
- return False
-
return True
diff --git a/magic_uv/op/align_uv_cursor.py b/magic_uv/op/align_uv_cursor.py
index 2b7f1491..696b7cb8 100644
--- a/magic_uv/op/align_uv_cursor.py
+++ b/magic_uv/op/align_uv_cursor.py
@@ -4,8 +4,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.5"
-__date__ = "6 Mar 2021"
+__version__ = "6.6"
+__date__ = "22 Apr 2022"
import bpy
from mathutils import Vector
@
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list