[Bf-extensions-cvs] [117faa96] master: Magic UV: Release v6.5
nutti
noreply at git.blender.org
Sat Mar 6 09:56:28 CET 2021
Commit: 117faa96af35685d72e5e01f9a386d163d874133
Author: nutti
Date: Sat Mar 6 17:54:33 2021 +0900
Branches: master
https://developer.blender.org/rBA117faa96af35685d72e5e01f9a386d163d874133
Magic UV: Release v6.5
Updated Features
* Texture Projection
* Add option "Scaling", "Rotation", "Translation"
* Select UV
* Add Zoom Selected UV feature
* Add option "Same Polygon Threshold"
* Add option "Selection Method"
* Add option "Sync Mesh Selection"
* UV Inspection
* Add option "Same Polygon Threshold"
* Add option "Display View3D"
* Mirror UV
* Add option "Origin"
* UVW
* Add option "Force Axis"
Other Updates
* 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/properites.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/updater.py
M magic_uv/utils/__init__.py
M magic_uv/utils/addon_updater.py
M magic_uv/utils/bl_class_registry.py
M magic_uv/utils/compatibility.py
M magic_uv/utils/property_class_registry.py
===================================================================
diff --git a/magic_uv/__init__.py b/magic_uv/__init__.py
index e9c95f24..d0b8ae45 100644
--- a/magic_uv/__init__.py
+++ b/magic_uv/__init__.py
@@ -20,8 +20,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.4"
-__date__ = "23 Oct 2020"
+__version__ = "6.5"
+__date__ = "6 Mar 2021"
bl_info = {
@@ -29,7 +29,7 @@ bl_info = {
"author": "Nutti, Mifth, Jace Priester, kgeogeo, mem, imdjs"
"Keith (Wahooney) Boshoff, McBuff, MaxRobinot, "
"Alexander Milovsky, Dusan Stevanovic, MatthiasThDs",
- "version": (6, 4, 0),
+ "version": (6, 5, 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 3817486c..1d9d55cf 100644
--- a/magic_uv/common.py
+++ b/magic_uv/common.py
@@ -20,8 +20,8 @@
__author__ = "Nutti <nutti.metro at gmail.com>"
__status__ = "production"
-__version__ = "6.4"
-__date__ = "23 Oct 2020"
+__version__ = "6.5"
+__date__ = "6 Mar 2021"
from collections import defaultdict
from pprint import pprint
@@ -333,7 +333,7 @@ def get_uvimg_editor_board_size(area):
return (255.0, 255.0)
-def calc_polygon_2d_area(points):
+def calc_tris_2d_area(points):
area = 0.0
for i, p1 in enumerate(points):
p2 = points[(i + 1) % len(points)]
@@ -345,7 +345,7 @@ def calc_polygon_2d_area(points):
return fabs(0.5 * area)
-def calc_polygon_3d_area(points):
+def calc_tris_3d_area(points):
area = 0.0
for i, p1 in enumerate(points):
p2 = points[(i + 1) % len(points)]
@@ -395,6 +395,23 @@ def get_faces_list(bm, method, only_selected):
return faces_list
+def measure_all_faces_mesh_area(bm):
+ if compat.check_version(2, 80, 0) >= 0:
+ triangle_loops = bm.calc_loop_triangles()
+ else:
+ triangle_loops = bm.calc_tessface()
+
+ areas = {face: 0.0 for face in bm.faces}
+
+ for loops in triangle_loops:
+ face = loops[0].face
+ area = areas[face]
+ area += calc_tris_3d_area([l.vert.co for l in loops])
+ areas[face] = area
+
+ return areas
+
+
def measure_mesh_area(obj, calc_method, only_selected):
bm = bmesh.from_edit_mesh(obj.data)
if check_version(2, 73, 0) >= 0:
@@ -406,17 +423,18 @@ def measure_mesh_area(obj, calc_method, only_selected):
areas = []
for faces in faces_list:
- areas.append(measure_mesh_area_from_faces(faces))
+ areas.append(measure_mesh_area_from_faces(bm, faces))
return areas
-def measure_mesh_area_from_faces(faces):
+def measure_mesh_area_from_faces(bm, faces):
+ face_areas = measure_all_faces_mesh_area(bm)
+
mesh_area = 0.0
for f in faces:
- verts = [l.vert.co for l in f.loops]
- f_mesh_area = calc_polygon_3d_area(verts)
- mesh_area = mesh_area + f_mesh_area
+ if f in face_areas:
+ mesh_area += face_areas[f]
return mesh_area
@@ -486,12 +504,34 @@ def find_images(obj, face=None, tex_layer=None):
return images
-def measure_uv_area_from_faces(obj, faces, uv_layer, tex_layer,
+def measure_all_faces_uv_area(bm, uv_layer):
+ if compat.check_version(2, 80, 0) >= 0:
+ triangle_loops = bm.calc_loop_triangles()
+ else:
+ triangle_loops = bm.calc_tessface()
+
+ areas = {face: 0.0 for face in bm.faces}
+
+ for loops in triangle_loops:
+ face = loops[0].face
+ area = areas[face]
+ area += calc_tris_2d_area([l[uv_layer].uv for l in loops])
+ areas[face] = area
+
+ return areas
+
+
+def measure_uv_area_from_faces(obj, bm, faces, uv_layer, tex_layer,
tex_selection_method, tex_size):
+
+ face_areas = measure_all_faces_uv_area(bm, uv_layer)
+
uv_area = 0.0
for f in faces:
- uvs = [l[uv_layer].uv for l in f.loops]
- f_uv_area = calc_polygon_2d_area(uvs)
+ if f not in face_areas:
+ continue
+
+ f_uv_area = face_areas[f]
# user specified
if tex_selection_method == 'USER_SPECIFIED' and tex_size is not None:
@@ -547,8 +587,8 @@ def measure_uv_area_from_faces(obj, faces, uv_layer, tex_layer,
return uv_area
-def measure_uv_area(obj, calc_method, tex_selection_method, tex_size,
- only_selected):
+def measure_uv_area(obj, calc_method, tex_selection_method,
+ tex_size, only_selected):
bm = bmesh.from_edit_mesh(obj.data)
if check_version(2, 73, 0) >= 0:
bm.verts.ensure_lookup_table()
@@ -565,7 +605,8 @@ def measure_uv_area(obj, calc_method, tex_selection_method, tex_size,
uv_areas = []
for faces in faces_list:
uv_area = measure_uv_area_from_faces(
- obj, faces, uv_layer, tex_layer, tex_selection_method, tex_size)
+ obj, bm, faces, uv_layer, tex_layer,
+ tex_selection_method, tex_size)
if uv_area is None:
return None
uv_areas.append(uv_area)
@@ -946,7 +987,8 @@ class RingBuffer:
# clip: reference polygon
# subject: tested polygon
-def __do_weiler_atherton_cliping(clip_uvs, subject_uvs, mode):
+def __do_weiler_atherton_cliping(clip_uvs, subject_uvs, mode,
+ same_polygon_threshold):
clip_uvs = RingBuffer(clip_uvs)
if __is_polygon_flipped(clip_uvs):
@@ -961,7 +1003,7 @@ def __do_weiler_atherton_cliping(clip_uvs, subject_uvs, mode):
debug_print(subject_uvs)
# check if clip and subject is overlapped completely
- if __is_polygon_same(clip_uvs, subject_uvs):
+ if __is_polygon_same(clip_uvs, subject_uvs, same_polygon_threshold):
polygons = [subject_uvs.as_list()]
debug_print("===== Polygons Overlapped Completely =====")
debug_print(polygons)
@@ -1193,26 +1235,31 @@ def get_uv_editable_objects(context):
return objs
-def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list, mode):
+def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list,
+ mode, same_polygon_threshold=0.0000001):
# at first, check island overlapped
isl = []
for bm, uv_layer, faces in zip(bm_list, uv_layer_list, faces_list):
info = get_island_info_from_faces(bm, faces, uv_layer)
- isl.extend([(i, uv_layer) for i in info])
+ isl.extend([(i, uv_layer, bm) for i in info])
overlapped_isl_pairs = []
overlapped_uv_layer_pairs = []
- for i, (i1, uv_layer_1) in enumerate(isl):
- for i2, uv_layer_2 in isl[i + 1:]:
+ overlapped_bm_paris = []
+ for i, (i1, uv_layer_1, bm_1) in enumerate(isl):
+ for i2, uv_layer_2, bm_2 in isl[i + 1:]:
if (i1["max"].x < i2["min"].x) or (i2["max"].x < i1["min"].x) or \
(i1["max"].y < i2["min"].y) or (i2["max"].y < i1["min"].y):
continue
overlapped_isl_pairs.append([i1, i2])
overlapped_uv_layer_pairs.append([uv_layer_1, uv_layer_2])
+ overlapped_bm_paris.append([bm_1, bm_2])
# next, check polygon overlapped
overlapped_uvs = []
- for oip, uvlp in zip(overlapped_isl_pairs, overlapped_uv_layer_pairs):
+ for oip, uvlp, bmp in zip(overlapped_isl_pairs,
+ overlapped_uv_layer_pairs,
+ overlapped_bm_paris):
for clip in oip[0]["faces"]:
f_clip = clip["face"]
clip_uvs = [l[uvlp[0]].uv.copy() for l in f_clip.loops]
@@ -1228,11 +1275,13 @@ def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list, mode):
subject_uvs = [l[uvlp[1]].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)
+ result, polygons = \
+ __do_weiler_atherton_cliping(clip_uvs, subject_uvs,
+ mode, same_polygon_threshold)
if result:
- overlapped_uvs.append({"clip_face": f_clip,
+ overlapped_uvs.append({"clip_bmesh": bmp[0],
+ "subject_bmesh": bmp[1],
+ "clip_face": f_clip,
"subject_face": f_subject,
"clip_uv_layer": uvlp[0],
"subject_uv_layer": uvlp[1],
@@ -1242,14 +1291,15 @@ def get_overlapped_uv_info(bm_list, faces_list, uv_layer_list, mode):
return overlapped_uvs
-def get_flipped_uv_info(faces_list, uv_layer_list):
+def get_flipped_uv_info(bm_list, faces_list, uv_layer_list):
flipped_uvs = []
- for faces, uv_layer in zip(faces_list, uv_layer_list):
+ for bm, faces, uv_layer in zip(bm_list, faces_list, uv_layer_list):
for f in faces:
polygon = RingBuffer([l[uv_layer].uv.copy() for l in f.loops])
if __is_polygon_flipped(polygon):
uvs = [l[uv_layer].uv.copy() for l in f.loops]
- flipped_uvs.append({"face": f,
+ flipped_uvs.append({"bmesh": bm,
+ "face": f,
"uv_layer": uv_layer,
"uvs": uvs,
"polygons": [polygon.as_list()]})
@@ -1257,7 +1307,7 @@ def get_flipped_uv_info(faces_list, uv_layer_list):
return flipped_uvs
-def __is_polygon_same(points1, points2):
+def __is_polygon_same(points1, points2, threshold):
if len(points1) != len(points2):
return False
@@ -1267,7 +1317,7 @@ def __is_polygon_same(points1, points2):
for p1 in pts1:
for p2 in pts2:
diff = p2 - p1
- if diff.length < 0.0000001:
+ if diff.length < threshold:
pts2.remove(p2)
break
else:
diff --git a/magic_uv/lib/__i
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list