Node Wrangler: do not add reroutes to unavailable outputs
[blender-addons.git] / magic_uv / op / copy_paste_uv.py
blob780b08e8db1392acd4b85ca31f2e668a11dfa908
1 # SPDX-FileCopyrightText: 2017-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 __author__ = "Nutti <nutti.metro@gmail.com>, Jace Priester"
6 __status__ = "production"
7 __version__ = "6.6"
8 __date__ = "22 Apr 2022"
10 import bmesh
11 import bpy.utils
12 from bpy.props import (
13 StringProperty,
14 BoolProperty,
15 IntProperty,
16 EnumProperty,
19 from .. import common
20 from ..utils.bl_class_registry import BlClassRegistry
21 from ..utils.property_class_registry import PropertyClassRegistry
22 from ..utils import compatibility as compat
25 def _is_valid_context(context):
26 # only 'VIEW_3D' space is allowed to execute
27 if not common.is_valid_space(context, ['VIEW_3D']):
28 return False
30 # Multiple objects editing mode is not supported in this feature.
31 objs = common.get_uv_editable_objects(context)
32 if len(objs) != 1:
33 return False
35 # only edit mode is allowed to execute
36 if context.object.mode != 'EDIT':
37 return False
39 return True
42 def get_copy_uv_layers(ops_obj, bm, uv_map):
43 uv_layers = []
44 if uv_map == "__default":
45 if not bm.loops.layers.uv:
46 ops_obj.report(
47 {'WARNING'}, "Object must have more than one UV map")
48 return None
49 uv_layers.append(bm.loops.layers.uv.verify())
50 ops_obj.report({'INFO'}, "Copy UV coordinate")
51 elif uv_map == "__all":
52 for uv in bm.loops.layers.uv.keys():
53 uv_layers.append(bm.loops.layers.uv[uv])
54 ops_obj.report({'INFO'}, "Copy UV coordinate (UV map: ALL)")
55 else:
56 uv_layers.append(bm.loops.layers.uv[uv_map])
57 ops_obj.report(
58 {'INFO'}, "Copy UV coordinate (UV map: {})".format(uv_map))
60 return uv_layers
63 def get_paste_uv_layers(ops_obj, obj, bm, src_info, uv_map):
64 uv_layers = []
65 if uv_map == "__default":
66 if not bm.loops.layers.uv:
67 ops_obj.report(
68 {'WARNING'}, "Object must have more than one UV map")
69 return None
70 uv_layers.append(bm.loops.layers.uv.verify())
71 ops_obj.report({'INFO'}, "Paste UV coordinate")
72 elif uv_map == "__new":
73 new_uv_map = common.create_new_uv_map(obj)
74 if not new_uv_map:
75 ops_obj.report({'WARNING'},
76 "Reached to the maximum number of UV map")
77 return None
78 uv_layers.append(bm.loops.layers.uv[new_uv_map.name])
79 ops_obj.report(
80 {'INFO'},
81 "Paste UV coordinate (UV map: {})".format(new_uv_map.name))
82 elif uv_map == "__all":
83 for src_layer in src_info.keys():
84 if src_layer not in bm.loops.layers.uv.keys():
85 new_uv_map = common.create_new_uv_map(obj, src_layer)
86 if not new_uv_map:
87 ops_obj.report({'WARNING'},
88 "Reached to the maximum number of UV map")
89 return None
90 uv_layers.append(bm.loops.layers.uv[src_layer])
91 ops_obj.report({'INFO'}, "Paste UV coordinate (UV map: ALL)")
92 else:
93 uv_layers.append(bm.loops.layers.uv[uv_map])
94 ops_obj.report(
95 {'INFO'}, "Paste UV coordinate (UV map: {})".format(uv_map))
97 return uv_layers
100 def get_src_face_info(ops_obj, bm, uv_layers, only_select=False):
101 src_info = {}
102 for layer in uv_layers:
103 face_info = []
104 for face in bm.faces:
105 if not only_select or face.select:
106 info = {
107 "index": face.index,
108 "uvs": [l[layer].uv.copy() for l in face.loops],
109 "pin_uvs": [l[layer].pin_uv for l in face.loops],
110 "seams": [l.edge.seam for l in face.loops],
112 face_info.append(info)
113 if not face_info:
114 ops_obj.report({'WARNING'}, "No faces are selected")
115 return None
116 src_info[layer.name] = face_info
118 return src_info
121 def get_dest_face_info(ops_obj, bm, uv_layers, src_info, strategy,
122 only_select=False):
123 dest_info = {}
124 for layer in uv_layers:
125 face_info = []
126 for face in bm.faces:
127 if not only_select or face.select:
128 info = {
129 "index": face.index,
130 "uvs": [l[layer].uv.copy() for l in face.loops],
132 face_info.append(info)
133 if not face_info:
134 ops_obj.report({'WARNING'}, "No faces are selected")
135 return None
136 key = list(src_info.keys())[0]
137 src_face_count = len(src_info[key])
138 dest_face_count = len(face_info)
139 if strategy == 'N_N' and src_face_count != dest_face_count:
140 ops_obj.report(
141 {'WARNING'},
142 "Number of selected faces is different from copied" +
143 "(src:{}, dest:{})"
144 .format(src_face_count, dest_face_count))
145 return None
146 dest_info[layer.name] = face_info
148 return dest_info
151 def _get_select_history_src_face_info(ops_obj, bm, uv_layers):
152 src_info = {}
153 for layer in uv_layers:
154 face_info = []
155 for hist in bm.select_history:
156 if isinstance(hist, bmesh.types.BMFace) and hist.select:
157 info = {
158 "index": hist.index,
159 "uvs": [l[layer].uv.copy() for l in hist.loops],
160 "pin_uvs": [l[layer].pin_uv for l in hist.loops],
161 "seams": [l.edge.seam for l in hist.loops],
163 face_info.append(info)
164 if not face_info:
165 ops_obj.report({'WARNING'}, "No faces are selected")
166 return None
167 src_info[layer.name] = face_info
169 return src_info
172 def _get_select_history_dest_face_info(ops_obj, bm, uv_layers, src_info,
173 strategy):
174 dest_info = {}
175 for layer in uv_layers:
176 face_info = []
177 for hist in bm.select_history:
178 if isinstance(hist, bmesh.types.BMFace) and hist.select:
179 info = {
180 "index": hist.index,
181 "uvs": [l[layer].uv.copy() for l in hist.loops],
183 face_info.append(info)
184 if not face_info:
185 ops_obj.report({'WARNING'}, "No faces are selected")
186 return None
187 key = list(src_info.keys())[0]
188 src_face_count = len(src_info[key])
189 dest_face_count = len(face_info)
190 if strategy == 'N_N' and src_face_count != dest_face_count:
191 ops_obj.report(
192 {'WARNING'},
193 "Number of selected faces is different from copied" +
194 "(src:{}, dest:{})"
195 .format(src_face_count, dest_face_count))
196 return None
197 dest_info[layer.name] = face_info
199 return dest_info
202 def paste_uv(ops_obj, bm, src_info, dest_info, uv_layers, strategy, flip,
203 rotate, copy_seams):
204 for slayer_name, dlayer in zip(src_info.keys(), uv_layers):
205 src_faces = src_info[slayer_name]
206 dest_faces = dest_info[dlayer.name]
208 for idx, dinfo in enumerate(dest_faces):
209 sinfo = None
210 if strategy == 'N_N':
211 sinfo = src_faces[idx]
212 elif strategy == 'N_M':
213 sinfo = src_faces[idx % len(src_faces)]
215 suv = sinfo["uvs"]
216 spuv = sinfo["pin_uvs"]
217 ss = sinfo["seams"]
218 if len(sinfo["uvs"]) != len(dinfo["uvs"]):
219 ops_obj.report({'WARNING'}, "Some faces are different size")
220 return -1
222 suvs_fr = [uv for uv in suv]
223 spuvs_fr = [pin_uv for pin_uv in spuv]
224 ss_fr = [s for s in ss]
226 # flip UVs
227 if flip is True:
228 suvs_fr.reverse()
229 spuvs_fr.reverse()
230 ss_fr.reverse()
232 # rotate UVs
233 for _ in range(rotate):
234 uv = suvs_fr.pop()
235 pin_uv = spuvs_fr.pop()
236 s = ss_fr.pop()
237 suvs_fr.insert(0, uv)
238 spuvs_fr.insert(0, pin_uv)
239 ss_fr.insert(0, s)
241 # paste UVs
242 for l, suv, spuv, ss in zip(bm.faces[dinfo["index"]].loops,
243 suvs_fr, spuvs_fr, ss_fr):
244 l[dlayer].uv = suv
245 l[dlayer].pin_uv = spuv
246 if copy_seams is True:
247 l.edge.seam = ss
249 return 0
252 @PropertyClassRegistry()
253 class _Properties:
254 idname = "copy_paste_uv"
256 @classmethod
257 def init_props(cls, scene):
258 class Props():
259 src_info = None
261 scene.muv_props.copy_paste_uv = Props()
262 scene.muv_props.copy_paste_uv_selseq = Props()
264 scene.muv_copy_paste_uv_enabled = BoolProperty(
265 name="Copy/Paste UV Enabled",
266 description="Copy/Paste UV is enabled",
267 default=False
269 scene.muv_copy_paste_uv_copy_seams = BoolProperty(
270 name="Seams",
271 description="Copy Seams",
272 default=True
274 scene.muv_copy_paste_uv_mode = EnumProperty(
275 items=[
276 ('DEFAULT', "Default", "Default Mode"),
277 ('SEL_SEQ', "Selection Sequence", "Selection Sequence Mode")
279 name="Copy/Paste UV Mode",
280 description="Copy/Paste UV Mode",
281 default='DEFAULT'
283 scene.muv_copy_paste_uv_strategy = EnumProperty(
284 name="Strategy",
285 description="Paste Strategy",
286 items=[
287 ('N_N', 'N:N', 'Number of faces must be equal to source'),
288 ('N_M', 'N:M', 'Number of faces must not be equal to source')
290 default='N_M'
293 @classmethod
294 def del_props(cls, scene):
295 del scene.muv_props.copy_paste_uv
296 del scene.muv_props.copy_paste_uv_selseq
297 del scene.muv_copy_paste_uv_enabled
298 del scene.muv_copy_paste_uv_copy_seams
299 del scene.muv_copy_paste_uv_mode
300 del scene.muv_copy_paste_uv_strategy
303 @BlClassRegistry()
304 @compat.make_annotations
305 class MUV_OT_CopyPasteUV_CopyUV(bpy.types.Operator):
307 Operation class: Copy UV coordinate
310 bl_idname = "uv.muv_copy_paste_uv_copy_uv"
311 bl_label = "Copy UV"
312 bl_description = "Copy UV coordinate"
313 bl_options = {'REGISTER', 'UNDO'}
315 uv_map = StringProperty(default="__default", options={'HIDDEN'})
317 @classmethod
318 def poll(cls, context):
319 # we can not get area/space/region from console
320 if common.is_console_mode():
321 return True
322 return _is_valid_context(context)
324 def execute(self, context):
325 props = context.scene.muv_props.copy_paste_uv
327 objs = common.get_uv_editable_objects(context)
328 # poll() method ensures that only one object is selected.
329 obj = objs[0]
330 bm = common.create_bmesh(obj)
332 # get UV layer
333 uv_layers = get_copy_uv_layers(self, bm, self.uv_map)
334 if not uv_layers:
335 return {'CANCELLED'}
337 # get selected face
338 src_info = get_src_face_info(self, bm, uv_layers, True)
339 if src_info is None:
340 return {'CANCELLED'}
341 props.src_info = src_info
343 face_count = len(props.src_info[list(props.src_info.keys())[0]])
344 self.report({'INFO'}, "{} face(s) are copied".format(face_count))
346 return {'FINISHED'}
349 @BlClassRegistry()
350 class MUV_MT_CopyPasteUV_CopyUV(bpy.types.Menu):
352 Menu class: Copy UV coordinate
355 bl_idname = "MUV_MT_CopyPasteUV_CopyUV"
356 bl_label = "Copy UV (Menu)"
357 bl_description = "Menu of Copy UV coordinate"
359 @classmethod
360 def poll(cls, context):
361 return _is_valid_context(context)
363 def draw(self, context):
364 layout = self.layout
365 objs = common.get_uv_editable_objects(context)
366 # poll() method ensures that only one object is selected.
367 obj = objs[0]
369 # create sub menu
370 bm = common.create_bmesh(obj)
371 uv_maps = bm.loops.layers.uv.keys()
373 ops = layout.operator(MUV_OT_CopyPasteUV_CopyUV.bl_idname,
374 text="[Default]")
375 ops.uv_map = "__default"
377 ops = layout.operator(MUV_OT_CopyPasteUV_CopyUV.bl_idname,
378 text="[All]")
379 ops.uv_map = "__all"
381 for m in uv_maps:
382 ops = layout.operator(MUV_OT_CopyPasteUV_CopyUV.bl_idname, text=m)
383 ops.uv_map = m
386 @BlClassRegistry()
387 @compat.make_annotations
388 class MUV_OT_CopyPasteUV_PasteUV(bpy.types.Operator):
390 Operation class: Paste UV coordinate
393 bl_idname = "uv.muv_copy_paste_uv_paste_uv"
394 bl_label = "Paste UV"
395 bl_description = "Paste UV coordinate"
396 bl_options = {'REGISTER', 'UNDO'}
398 uv_map = StringProperty(default="__default", options={'HIDDEN'})
399 strategy = EnumProperty(
400 name="Strategy",
401 description="Paste Strategy",
402 items=[
403 ('N_N', 'N:N', 'Number of faces must be equal to source'),
404 ('N_M', 'N:M', 'Number of faces must not be equal to source')
406 default="N_M"
408 flip_copied_uv = BoolProperty(
409 name="Flip Copied UV",
410 description="Flip Copied UV...",
411 default=False
413 rotate_copied_uv = IntProperty(
414 default=0,
415 name="Rotate Copied UV",
416 min=0,
417 max=30
419 copy_seams = BoolProperty(
420 name="Seams",
421 description="Copy Seams",
422 default=True
425 @classmethod
426 def poll(cls, context):
427 # we can not get area/space/region from console
428 if common.is_console_mode():
429 return True
430 sc = context.scene
431 props = sc.muv_props.copy_paste_uv
432 if not props.src_info:
433 return False
434 return _is_valid_context(context)
436 def execute(self, context):
437 props = context.scene.muv_props.copy_paste_uv
438 if not props.src_info:
439 self.report({'WARNING'}, "Need copy UV at first")
440 return {'CANCELLED'}
442 objs = common.get_uv_editable_objects(context)
443 # poll() method ensures that only one object is selected.
444 obj = objs[0]
445 bm = common.create_bmesh(obj)
447 # get UV layer
448 uv_layers = get_paste_uv_layers(self, obj, bm, props.src_info,
449 self.uv_map)
450 if not uv_layers:
451 return {'CANCELLED'}
453 # get selected face
454 dest_info = get_dest_face_info(self, bm, uv_layers,
455 props.src_info, self.strategy, True)
456 if dest_info is None:
457 return {'CANCELLED'}
459 # paste
460 ret = paste_uv(self, bm, props.src_info, dest_info, uv_layers,
461 self.strategy, self.flip_copied_uv,
462 self.rotate_copied_uv, self.copy_seams)
463 if ret:
464 return {'CANCELLED'}
466 face_count = len(props.src_info[list(dest_info.keys())[0]])
467 self.report({'INFO'}, "{} face(s) are pasted".format(face_count))
469 bmesh.update_edit_mesh(obj.data)
471 if compat.check_version(2, 80, 0) < 0:
472 if self.copy_seams is True:
473 obj.data.show_edge_seams = True
475 return {'FINISHED'}
478 @BlClassRegistry()
479 class MUV_MT_CopyPasteUV_PasteUV(bpy.types.Menu):
481 Menu class: Paste UV coordinate
484 bl_idname = "MUV_MT_CopyPasteUV_PasteUV"
485 bl_label = "Paste UV (Menu)"
486 bl_description = "Menu of Paste UV coordinate"
488 @classmethod
489 def poll(cls, context):
490 sc = context.scene
491 props = sc.muv_props.copy_paste_uv
492 if not props.src_info:
493 return False
494 return _is_valid_context(context)
496 def draw(self, context):
497 sc = context.scene
498 layout = self.layout
499 objs = common.get_uv_editable_objects(context)
500 # poll() method ensures that only one object is selected.
501 obj = objs[0]
503 # create sub menu
504 bm = common.create_bmesh(obj)
505 uv_maps = bm.loops.layers.uv.keys()
507 ops = layout.operator(MUV_OT_CopyPasteUV_PasteUV.bl_idname,
508 text="[Default]")
509 ops.uv_map = "__default"
510 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
511 ops.strategy = sc.muv_copy_paste_uv_strategy
513 ops = layout.operator(MUV_OT_CopyPasteUV_PasteUV.bl_idname,
514 text="[New]")
515 ops.uv_map = "__new"
516 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
517 ops.strategy = sc.muv_copy_paste_uv_strategy
519 ops = layout.operator(MUV_OT_CopyPasteUV_PasteUV.bl_idname,
520 text="[All]")
521 ops.uv_map = "__all"
522 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
523 ops.strategy = sc.muv_copy_paste_uv_strategy
525 for m in uv_maps:
526 ops = layout.operator(MUV_OT_CopyPasteUV_PasteUV.bl_idname, text=m)
527 ops.uv_map = m
528 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
529 ops.strategy = sc.muv_copy_paste_uv_strategy
532 @BlClassRegistry()
533 @compat.make_annotations
534 class MUV_OT_CopyPasteUV_SelSeqCopyUV(bpy.types.Operator):
536 Operation class: Copy UV coordinate by selection sequence
539 bl_idname = "uv.muv_copy_paste_uv_selseq_copy_uv"
540 bl_label = "Copy UV (Selection Sequence)"
541 bl_description = "Copy UV data by selection sequence"
542 bl_options = {'REGISTER', 'UNDO'}
544 uv_map = StringProperty(default="__default", options={'HIDDEN'})
546 @classmethod
547 def poll(cls, context):
548 # we can not get area/space/region from console
549 if common.is_console_mode():
550 return True
551 return _is_valid_context(context)
553 def execute(self, context):
554 props = context.scene.muv_props.copy_paste_uv_selseq
556 objs = common.get_uv_editable_objects(context)
557 # poll() method ensures that only one object is selected.
558 obj = objs[0]
559 bm = common.create_bmesh(obj)
561 # get UV layer
562 uv_layers = get_copy_uv_layers(self, bm, self.uv_map)
563 if not uv_layers:
564 return {'CANCELLED'}
566 # get selected face
567 src_info = _get_select_history_src_face_info(self, bm, uv_layers)
568 if src_info is None:
569 return {'CANCELLED'}
570 props.src_info = src_info
572 face_count = len(props.src_info[list(props.src_info.keys())[0]])
573 self.report({'INFO'}, "{} face(s) are selected".format(face_count))
575 return {'FINISHED'}
578 @BlClassRegistry()
579 class MUV_MT_CopyPasteUV_SelSeqCopyUV(bpy.types.Menu):
581 Menu class: Copy UV coordinate by selection sequence
584 bl_idname = "MUV_MT_CopyPasteUV_SelSeqCopyUV"
585 bl_label = "Copy UV (Selection Sequence) (Menu)"
586 bl_description = "Menu of Copy UV coordinate by selection sequence"
588 @classmethod
589 def poll(cls, context):
590 return _is_valid_context(context)
592 def draw(self, context):
593 layout = self.layout
594 objs = common.get_uv_editable_objects(context)
595 # poll() method ensures that only one object is selected.
596 obj = objs[0]
598 bm = common.create_bmesh(obj)
599 uv_maps = bm.loops.layers.uv.keys()
601 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqCopyUV.bl_idname,
602 text="[Default]")
603 ops.uv_map = "__default"
605 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqCopyUV.bl_idname,
606 text="[All]")
607 ops.uv_map = "__all"
609 for m in uv_maps:
610 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqCopyUV.bl_idname,
611 text=m)
612 ops.uv_map = m
615 @BlClassRegistry()
616 @compat.make_annotations
617 class MUV_OT_CopyPasteUV_SelSeqPasteUV(bpy.types.Operator):
619 Operation class: Paste UV coordinate by selection sequence
622 bl_idname = "uv.muv_copy_paste_uv_selseq_paste_uv"
623 bl_label = "Paste UV (Selection Sequence)"
624 bl_description = "Paste UV coordinate by selection sequence"
625 bl_options = {'REGISTER', 'UNDO'}
627 uv_map = StringProperty(default="__default", options={'HIDDEN'})
628 strategy = EnumProperty(
629 name="Strategy",
630 description="Paste Strategy",
631 items=[
632 ('N_N', 'N:N', 'Number of faces must be equal to source'),
633 ('N_M', 'N:M', 'Number of faces must not be equal to source')
635 default="N_M"
637 flip_copied_uv = BoolProperty(
638 name="Flip Copied UV",
639 description="Flip Copied UV...",
640 default=False
642 rotate_copied_uv = IntProperty(
643 default=0,
644 name="Rotate Copied UV",
645 min=0,
646 max=30
648 copy_seams = BoolProperty(
649 name="Seams",
650 description="Copy Seams",
651 default=True
654 @classmethod
655 def poll(cls, context):
656 # we can not get area/space/region from console
657 if common.is_console_mode():
658 return True
659 sc = context.scene
660 props = sc.muv_props.copy_paste_uv_selseq
661 if not props.src_info:
662 return False
663 return _is_valid_context(context)
665 def execute(self, context):
666 props = context.scene.muv_props.copy_paste_uv_selseq
667 if not props.src_info:
668 self.report({'WARNING'}, "Need copy UV at first")
669 return {'CANCELLED'}
671 objs = common.get_uv_editable_objects(context)
672 # poll() method ensures that only one object is selected.
673 obj = objs[0]
674 bm = common.create_bmesh(obj)
676 # get UV layer
677 uv_layers = get_paste_uv_layers(self, obj, bm, props.src_info,
678 self.uv_map)
679 if not uv_layers:
680 return {'CANCELLED'}
682 # get selected face
683 dest_info = _get_select_history_dest_face_info(self, bm, uv_layers,
684 props.src_info,
685 self.strategy)
686 if dest_info is None:
687 return {'CANCELLED'}
689 # paste
690 ret = paste_uv(self, bm, props.src_info, dest_info, uv_layers,
691 self.strategy, self.flip_copied_uv,
692 self.rotate_copied_uv, self.copy_seams)
693 if ret:
694 return {'CANCELLED'}
696 face_count = len(props.src_info[list(dest_info.keys())[0]])
697 self.report({'INFO'}, "{} face(s) are pasted".format(face_count))
699 bmesh.update_edit_mesh(obj.data)
701 if compat.check_version(2, 80, 0) < 0:
702 if self.copy_seams is True:
703 obj.data.show_edge_seams = True
705 return {'FINISHED'}
708 @BlClassRegistry()
709 class MUV_MT_CopyPasteUV_SelSeqPasteUV(bpy.types.Menu):
711 Menu class: Paste UV coordinate by selection sequence
714 bl_idname = "MUV_MT_CopyPasteUV_SelSeqPasteUV"
715 bl_label = "Paste UV (Selection Sequence) (Menu)"
716 bl_description = "Menu of Paste UV coordinate by selection sequence"
718 @classmethod
719 def poll(cls, context):
720 sc = context.scene
721 props = sc.muv_props.copy_paste_uv_selseq
722 if not props.src_info:
723 return False
724 return _is_valid_context(context)
726 def draw(self, context):
727 sc = context.scene
728 layout = self.layout
729 objs = common.get_uv_editable_objects(context)
730 # poll() method ensures that only one object is selected.
731 obj = objs[0]
733 # create sub menu
734 bm = common.create_bmesh(obj)
735 uv_maps = bm.loops.layers.uv.keys()
737 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqPasteUV.bl_idname,
738 text="[Default]")
739 ops.uv_map = "__default"
740 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
741 ops.strategy = sc.muv_copy_paste_uv_strategy
743 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqPasteUV.bl_idname,
744 text="[New]")
745 ops.uv_map = "__new"
746 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
747 ops.strategy = sc.muv_copy_paste_uv_strategy
749 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqPasteUV.bl_idname,
750 text="[All]")
751 ops.uv_map = "__all"
752 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
753 ops.strategy = sc.muv_copy_paste_uv_strategy
755 for m in uv_maps:
756 ops = layout.operator(MUV_OT_CopyPasteUV_SelSeqPasteUV.bl_idname,
757 text=m)
758 ops.uv_map = m
759 ops.copy_seams = sc.muv_copy_paste_uv_copy_seams
760 ops.strategy = sc.muv_copy_paste_uv_strategy