[Bf-extensions-cvs] [7de962e] master: Copy and Paste UV =================== - Upload script Support new feature, and some optimization about this script. 1. Support copy/paste between UV maps. 2. Support copy/paste by selection sequence. - Wiki update
Nutti
noreply at git.blender.org
Wed Dec 31 06:36:05 CET 2014
Commit: 7de962e146c619d708c2bd60bcfd802510b7b263
Author: Nutti
Date: Wed Dec 31 14:30:25 2014 +0900
Branches: master
https://developer.blender.org/rBAC7de962e146c619d708c2bd60bcfd802510b7b263
Copy and Paste UV
===================
- Upload script
Support new feature, and some optimization about this script.
1. Support copy/paste between UV maps.
2. Support copy/paste by selection sequence.
- Wiki update
The wiki page is ready, see here:
http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/UV/Copy_Paste_UV
Modified Paths:
-------------------
blender-addons-contrib/uv_copy_and_paste_uv.py
===================================================================
M uv_copy_and_paste_uv.py
===================================================================
diff --git a/uv_copy_and_paste_uv.py b/uv_copy_and_paste_uv.py
index 84a74bf..9cb41cd 100644
--- a/uv_copy_and_paste_uv.py
+++ b/uv_copy_and_paste_uv.py
@@ -19,12 +19,21 @@
# ##### END GPL LICENSE BLOCK #####
import bpy
+import bmesh
+import math
+from collections import namedtuple
+from bpy.props import *
+
+__author__ = "Nutti <nutti.metro at gmail.com>"
+__status__ = "production"
+__version__ = "2.0"
+__date__ = "20 December 2014"
bl_info = {
"name" : "Copy and Paste UV",
"author" : "Nutti",
- "version" : (1,1),
- "blender" : (2, 6, 5),
+ "version" : (2,0),
+ "blender" : (2, 7, 2),
"location" : "UV Mapping > Copy and Paste UV",
"description" : "Copy and Paste UV data",
"warning" : "",
@@ -33,9 +42,26 @@ bl_info = {
"category" : "UV"
}
-src_indices = None # source indices
-dest_indices = None # destination indices
+SelectedFaceInfo = namedtuple('SelectedFaceInfo', 'normal indices')
+
+src_uv_map = None # source uv map
src_obj = None # source object
+src_sel_face_info = None # source selected faces information
+dest_sel_face_info = None # destination selected faces information
+
+# master menu
+class CopyAndPasteUVMenu(bpy.types.Menu):
+ bl_idname = "uv.copy_and_paste_uv_menu"
+ bl_label = "Copy/Paste UV"
+ bl_description = "Copy and Paste UV Menu"
+
+ def draw(self, context):
+ self.layout.operator(CopyAndPasteUVCopyUV.bl_idname)
+ self.layout.operator(CopyAndPasteUVPasteUV.bl_idname)
+ self.layout.operator(CopyAndPasteUVCopyUVBySelSeq.bl_idname)
+ self.layout.operator(CopyAndPasteUVPasteUVBySelSeq.bl_idname)
+ self.layout.menu(CopyAndPasteUVCopyUVMap.bl_idname)
+ self.layout.menu(CopyAndPasteUVPasteUVMap.bl_idname)
# copy UV
@@ -48,40 +74,25 @@ class CopyAndPasteUVCopyUV(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
-
- # global variables
- global src_indices
- global dest_indices
+ global src_sel_face_info
+ global src_uv_map
global src_obj
+
+ self.report({'INFO'}, "Copy UV coordinate.")
- # get active (source) object to be copied from
- active_obj = bpy.context.active_object;
-
- # change to 'OBJECT' mode, in order to access internal data
- mode_orig = bpy.context.object.mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # create source indices list
- src_indices = []
- for i in range(len(active_obj.data.polygons)):
- # get selected faces
- poly = active_obj.data.polygons[i]
- if poly.select:
- src_indices.extend(poly.loop_indices)
-
- # check if any faces are selected
- if len(src_indices) == 0:
- self.report({'WARNING'}, "No faces are not selected.")
- bpy.ops.object.mode_set(mode=mode_orig)
+ # prepare for coping
+ ret, src_obj, mode_orig = prep_copy()
+ if ret != 0:
return {'CANCELLED'}
- else:
- self.report(
- {'INFO'},
- "%d indices are selected." % len(src_indices))
- src_obj = active_obj
- # revert to original mode
- bpy.ops.object.mode_set(mode=mode_orig)
+ # copy
+ src_sel_face_info = get_selected_faces(src_obj)
+ ret, src_uv_map = copy_opt(self, "", src_obj, src_sel_face_info)
+
+ # finish coping
+ fini_copy(mode_orig)
+ if ret != 0:
+ return {'CANCELLED'}
return {'FINISHED'}
@@ -96,65 +107,420 @@ class CopyAndPasteUVPasteUV(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
+ global src_sel_face_info
+ global dest_sel_face_info
+ global src_uv_map
+ global src_obj
+
+ self.report({'INFO'}, "Paste UV coordinate.")
+
+ # prepare for pasting
+ ret, dest_obj, mode_orig = prep_paste(src_obj, src_sel_face_info)
+ if ret != 0:
+ return {'CANCELLED'}
+
+ # paste
+ dest_sel_face_info = get_selected_faces(dest_obj)
+ ret = paste_opt(
+ self, "", src_obj, src_sel_face_info,
+ src_uv_map, dest_obj, dest_sel_face_info)
+
+ # finish pasting
+ fini_paste(mode_orig)
+ if ret != 0:
+ return {'CANCELLED'}
- # global variables
- global src_indices
- global dest_indices
+ return {'FINISHED'}
+
+
+# copy UV (by selection sequence)
+class CopyAndPasteUVCopyUVBySelSeq(bpy.types.Operator):
+ """Copying UV coordinate on selected object by selection sequence."""
+
+ bl_idname = "uv.copy_uv_sel_seq"
+ bl_label = "Copy UV (Selection Sequence)"
+ bl_description = "Copy UV data by selection sequence."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ global src_sel_face_info
+ global src_uv_map
global src_obj
+
+ self.report({'INFO'}, "Copy UV coordinate. (sequence)")
- # check if copying operation was executed
- if src_indices is None or src_obj is None:
- self.report({'WARNING'}, "Do copy operation at first.")
- return {'CANCELLED'}
-
- # get active (source) object to be pasted to
- active_obj = bpy.context.active_object
-
- # change to 'OBJECT' mode, in order to access internal data
- mode_orig = bpy.context.object.mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # create source indices list
- dest_indices = []
- for i in range(len(active_obj.data.polygons)):
- # get selected faces
- poly = active_obj.data.polygons[i]
- if poly.select:
- dest_indices.extend(poly.loop_indices)
-
- if len(dest_indices) != len(src_indices):
- self.report(
- {'WARNING'},
- "Number of selected faces is different from copied faces." +
- "(src:%d, dest:%d)" % (len(src_indices), len(dest_indices)))
- bpy.ops.object.mode_set(mode=mode_orig)
+ # prepare for coping
+ ret, src_obj, mode_orig = prep_copy()
+ if ret != 0:
return {'CANCELLED'}
- else:
- dest_obj = active_obj
-
- # update UV data
- src_uv = src_obj.data.uv_layers.active # source UV data
- dest_uv = dest_obj.data.uv_layers.active # destination UV data
- for i in range(len(dest_indices)):
- dest_data = dest_uv.data[dest_indices[i]]
- src_data = src_uv.data[src_indices[i]]
- dest_data.uv = src_data.uv
+ # copy
+ src_sel_face_info = get_selected_faces_by_sel_seq(src_obj)
+ ret, src_uv_map = copy_opt(self, "", src_obj, src_sel_face_info)
+
+ # finish coping
+ fini_copy(mode_orig)
+ if ret != 0:
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+# paste UV (by selection sequence)
+class CopyAndPasteUVPasteUVBySelSeq(bpy.types.Operator):
+ """Paste UV coordinate which is copied by selection sequence."""
+
+ bl_idname = "uv.paste_uv_sel_seq"
+ bl_label = "Paste UV (Selection Sequence)"
+ bl_description = "Paste UV data by selection sequence."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ flip_copied_uv = BoolProperty(
+ name = "flip_copied_uv",
+ description = "flip_copied_uv...",
+ default = False )
+
+ rotate_copied_uv = IntProperty(
+ default = 0,
+ min = 0,
+ max = 30 )
+
+ def execute(self, context):
+ global src_sel_face_info
+ global dest_sel_face_info
+ global src_uv_map
+ global src_obj
+
+ self.report({'INFO'}, "Paste UV coordinate. (sequence)")
+
+ # prepare for pasting
+ ret, dest_obj, mode_orig = prep_paste(src_obj, src_sel_face_info)
+ if ret != 0:
+ return {'CANCELLED'}
+
+ # paste
+ dest_sel_face_info = get_selected_faces_by_sel_seq(dest_obj)
+ ret = paste_opt(
+ self, "", src_obj, src_sel_face_info,
+ src_uv_map, dest_obj, dest_sel_face_info)
+
+ # finish pasting
+ fini_paste(mode_orig)
+ if ret != 0:
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+# copy UV map (sub menu operator)
+class CopyAndPasteUVCopyUVMapSubOpt(bpy.types.Operator):
+ bl_idname = "uv.copy_uv_map_sub_opt"
+ bl_label = "Copy UV Map (Sub Menu Operator)"
+ uv_map = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global src_sel_face_info
+ global src_uv_map
+ global src_obj
+
self.report(
{'INFO'},
- "%d indices are copied." % len(dest_indices))
+ "Copy UV coordinate. (UV map:" + self.uv_map + ")")
+
+ # prepare for coping
+ ret, src_obj, mode_orig = prep_copy()
+ if ret != 0:
+ return {'CANCELLED'}
+
+ # copy
+ src_sel_face_info = get_selected_faces(src_obj)
+ ret, src_uv_map = copy_opt(
+ self, self.uv_map, src_obj,
+ src_sel_face_info)
+
+ # finish coping
+ fini_copy(mode_orig)
+ if ret != 0:
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+# copy UV map
+class CopyAndPasteUVCopyUVMap(bpy.types.Menu):
+ """Copying UV map coordinate on selected object."""
+
+ bl_idname = "uv.copy_uv_map"
+ bl_label = "Copy UV Map"
+ bl_description = "Copy UV map data"
+ bl_options = {'REGISTER', 'UNDO'}
- # revert to original mode
- bpy.ops.object.mode_set(mode=mode_orig)
+ def draw(self, context):
+ global menu_count
+
+ layout = self.layout
+
+ # create sub menu
+ uv_maps = bpy.context.active_object.data.uv_textures.keys()
+ for m in uv_maps:
+ layout.operator(
+ CopyAndPasteUVCopyUVMapSubOpt.bl_idname,
+ text=m).uv_map = m
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list