33
44import bpy
55import bmesh
6- import mathutils
76import pathlib
87import platform
98import shutil
109import subprocess
10+ import numpy
1111from ..manager import manager
1212from ..unwrap import Unwrap
1313from ..utils import (
2020 set_bmesh ,
2121 get_linux_path ,
2222 calc_center ,
23+ apply_transforms ,
24+ cut ,
2325)
2426from ..ui .panels import expand
2527from ..job import Preserve , Join , Cleanup , Symmetrise
@@ -37,6 +39,7 @@ def execute(self, context):
3739 try :
3840 logger .new_info ()
3941 prefs = get_preferences ()
42+ props = context .scene .uvgami
4043 engine_path = pathlib .Path (prefs .engine_path )
4144 if prefs .autosave :
4245 if bpy .data .is_saved :
@@ -149,6 +152,43 @@ def execute(self, context):
149152 # if the modifier is disabled, don't apply
150153 pass
151154
155+ # cuts
156+ if props .use_cuts and not props .use_symmetry :
157+ bm = new_bmesh (copy_object )
158+
159+ if props .cut_type == "EVEN" :
160+ # make even cuts on axes
161+ apply_transforms (copy_object )
162+ props = context .scene .uvgami
163+ axes = props .cut_axes
164+ cuts = props .cuts
165+
166+ a_length = len (axes ) if len (axes ) != 0 else 3
167+ d = cuts // a_length
168+ r = cuts % a_length
169+
170+ # distribute cuts
171+ x_num = d if r == 0 else d + 1
172+ y_num = d if r != 2 else d + 1
173+ z_num = d
174+
175+ center = calc_center (obj )
176+ if not axes or "X" in axes :
177+ cut (x_num , center , copy_object .dimensions .x , 0 , bm )
178+ if not axes or "Y" in axes :
179+ cut (y_num , center , copy_object .dimensions .y , 1 , bm )
180+ if not axes or "Z" in axes :
181+ cut (z_num , center , copy_object .dimensions .z , 2 , bm )
182+
183+ else :
184+ # cut on seams
185+ seams = numpy .zeros (len (bm .edges ), dtype = numpy .bool )
186+ obj .data .edges .foreach_get ("use_seam" , seams )
187+ bm_seams = numpy .array (bm .edges )[seams ]
188+ bmesh .ops .split_edges (bm , edges = bm_seams )
189+
190+ set_bmesh (bm , copy_object )
191+
152192 # save name, format: input name, unwrap name
153193 names [copy_object .name ] = [obj .name , obj .name ]
154194 objects .append (copy_object )
@@ -166,7 +206,6 @@ def execute(self, context):
166206 self .report ({"ERROR" }, report_msg )
167207 return {"CANCELLED" }
168208 else :
169- props = context .scene .uvgami
170209 input_path = get_dir_path () / "input"
171210 input_path .mkdir (exist_ok = True )
172211 output_path = input_path .parent / "output"
@@ -194,17 +233,7 @@ def execute(self, context):
194233 # bisect if symmetry on
195234 axes = props .sym_axes
196235 if props .use_symmetry :
197- # apply all transforms
198- location , _ , scale = obj .matrix_basis .decompose ()
199- actual = (
200- mathutils .Matrix .Translation (location )
201- @ obj .matrix_basis .to_3x3 ().normalized ().to_4x4 ()
202- @ mathutils .Matrix .Diagonal (scale ).to_4x4 ()
203- )
204- obj .data .transform (actual )
205- for c in obj .children :
206- c .matrix_local = actual @ c .matrix_local
207- obj .matrix_basis = mathutils .Matrix ()
236+ apply_transforms (obj )
208237
209238 bm = new_bmesh (obj )
210239 obj_center = calc_center (obj )
@@ -227,8 +256,9 @@ def execute(self, context):
227256 plane_no = direction ,
228257 clear_inner = True ,
229258 )
230- # if the object already had vertices down it's center plane, there will be duplicates
231- bmesh .ops .remove_doubles (bm , verts = bm .verts , dist = 0.0001 )
259+ # if the object already had vertices down it's center plane
260+ # there will be duplicates
261+ bmesh .ops .remove_doubles (bm , verts = bm .verts , dist = 1e-7 )
232262 set_bmesh (bm , obj )
233263
234264 # separate objects
@@ -240,11 +270,11 @@ def execute(self, context):
240270 join_job = Join (len (s ))
241271 cleanup_job = None
242272
243- # the delete job can come after join because it doesn't depend on
244- # the unwrapped objects
273+ # the delete job can come after join because it doesn't depend
274+ # on the unwrapped objects
245275 if prefs .cleanup == "HIDE" or prefs .cleanup == "DELETE" :
246- # the count is > 1 because all the separated objs need to finish
247- # before deleting the original
276+ # the count is > 1 because all the separated objs need to
277+ # finish before deleting the original
248278 cleanup_job = Cleanup (len (s ), prefs .cleanup )
249279 manager .input [cleanup_job ] = input [object_idx ]
250280
@@ -444,6 +474,7 @@ def execute(self, context):
444474 len (obj .data .vertices ),
445475 shade_smooth ,
446476 angle ,
477+ props .use_cuts and not props .use_symmetry ,
447478 )
448479 manager .active .append (unwrap )
449480
0 commit comments