Use separate root objects to gather the sample visualization and the
[blender-addons-contrib.git] / uv_copy_and_paste_uv.py
1 # <pep8-80 compliant>
2
3 # ##### BEGIN GPL LICENSE BLOCK #####
4 #
5 #  This program is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU General Public License
7 #  as published by the Free Software Foundation; either version 2
8 #  of the License, or (at your option) any later version.
9 #
10 #  This program is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU General Public License for more details.
14 #
15 #  You should have received a copy of the GNU General Public License
16 #  along with this program; if not, write to the Free Software Foundation,
17 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #
19 # ##### END GPL LICENSE BLOCK #####
20
21 import bpy
22
23 bl_info = {
24     "name" : "Copy and Paste UV",
25     "author" : "Nutti",
26     "version" : (1,1),
27     "blender" : (2, 6, 5),
28     "location" : "UV Mapping > Copy and Paste UV",
29     "description" : "Copy and Paste UV data",
30     "warning" : "",
31     "wiki_url" : "",
32     "tracker_url" : "",
33     "category" : "UV"
34 }
35
36 src_indices = None           # source indices
37 dest_indices = None          # destination indices
38 src_obj = None               # source object
39
40
41 # copy UV
42 class CopyAndPasteUVCopyUV(bpy.types.Operator):
43     """Copying UV coordinate on selected object."""
44     
45     bl_idname = "uv.copy_uv"
46     bl_label = "Copy UV"
47     bl_description = "Copy UV data"
48     bl_options = {'REGISTER', 'UNDO'}
49
50     def execute(self, context):
51         
52         # global variables
53         global src_indices
54         global dest_indices
55         global src_obj
56         
57         # get active (source) object to be copied from
58         active_obj = bpy.context.active_object;
59
60         # change to 'OBJECT' mode, in order to access internal data
61         mode_orig = bpy.context.object.mode
62         bpy.ops.object.mode_set(mode='OBJECT')
63
64         # create source indices list
65         src_indices = []
66         for i in range(len(active_obj.data.polygons)):
67             # get selected faces
68             poly = active_obj.data.polygons[i]
69             if poly.select:
70                src_indices.extend(poly.loop_indices)
71         
72         # check if any faces are selected
73         if len(src_indices) == 0:
74             self.report({'WARNING'}, "No faces are not selected.")
75             bpy.ops.object.mode_set(mode=mode_orig)
76             return {'CANCELLED'}
77         else:
78             self.report(
79                 {'INFO'},
80                  "%d indices are selected." % len(src_indices))
81             src_obj = active_obj
82         
83         # revert to original mode
84         bpy.ops.object.mode_set(mode=mode_orig)
85         
86         return {'FINISHED'}
87
88
89 # paste UV
90 class CopyAndPasteUVPasteUV(bpy.types.Operator):
91     """Paste UV coordinate which is copied."""
92     
93     bl_idname = "uv.paste_uv"
94     bl_label = "Paste UV"
95     bl_description = "Paste UV data"
96     bl_options = {'REGISTER', 'UNDO'}
97
98     def execute(self, context):
99         
100         # global variables
101         global src_indices
102         global dest_indices
103         global src_obj
104         
105         # check if copying operation was executed
106         if src_indices is None or src_obj is None:
107                 self.report({'WARNING'}, "Do copy operation at first.")
108                 return {'CANCELLED'}
109         
110         # get active (source) object to be pasted to
111         active_obj = bpy.context.active_object
112
113         # change to 'OBJECT' mode, in order to access internal data
114         mode_orig = bpy.context.object.mode
115         bpy.ops.object.mode_set(mode='OBJECT')
116
117         # create source indices list
118         dest_indices = []
119         for i in range(len(active_obj.data.polygons)):
120             # get selected faces
121             poly = active_obj.data.polygons[i]
122             if poly.select:
123                 dest_indices.extend(poly.loop_indices)
124         
125         if len(dest_indices) != len(src_indices):
126             self.report(
127                 {'WARNING'},
128                 "Number of selected faces is different from copied faces." +
129                 "(src:%d, dest:%d)" % (len(src_indices), len(dest_indices)))
130             bpy.ops.object.mode_set(mode=mode_orig)
131             return {'CANCELLED'}
132         else:
133             dest_obj = active_obj
134
135         # update UV data
136         src_uv = src_obj.data.uv_layers.active         # source UV data
137         dest_uv = dest_obj.data.uv_layers.active       # destination UV data
138         for i in range(len(dest_indices)):
139             dest_data = dest_uv.data[dest_indices[i]]
140             src_data = src_uv.data[src_indices[i]]
141             dest_data.uv = src_data.uv
142
143         self.report(
144             {'INFO'},
145             "%d indices are copied." % len(dest_indices))
146
147         # revert to original mode
148         bpy.ops.object.mode_set(mode=mode_orig)
149
150         return {'FINISHED'}
151
152
153 # registration
154
155 def menu_func(self, context):
156     self.layout.operator("uv.copy_uv")
157     self.layout.operator("uv.paste_uv")
158
159
160 def register():
161     bpy.utils.register_module(__name__)
162     bpy.types.VIEW3D_MT_uv_map.append(menu_func)
163
164
165 def unregister():
166     bpy.utils.unregister_module(__name__)
167     bpy.types.VIEW3D_MT_uv_map.remove(menu_func)
168
169
170 if __name__ == "__main__":
171     register()