Merge branch 'master' into blender2.8
[blender-addons.git] / uv_texture_atlas.py
blobb0936a8a30d3bbf5be173874665dbea0f4177c1f
1 # BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # END GPL LICENSE BLOCK #####
20 bl_info = {
21 "name": "Texture Atlas",
22 "author": "Andreas Esau, Paul Geraskin, Campbell Barton",
23 "version": (0, 2, 1),
24 "blender": (2, 67, 0),
25 "location": "Properties > Render",
26 "description": "A simple Texture Atlas for unwrapping many objects. It creates additional UV",
27 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
28 "Scripts/UV/TextureAtlas",
29 "category": "UV",
32 import bpy
33 from bpy.types import (
34 Operator,
35 Panel,
36 PropertyGroup,
38 from bpy.props import (
39 BoolProperty,
40 CollectionProperty,
41 EnumProperty,
42 FloatProperty,
43 IntProperty,
44 StringProperty,
46 import mathutils
49 def check_all_objects_visible(self, context):
50 scene = context.scene
51 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
52 isAllObjectsVisible = True
53 bpy.ops.object.select_all(action='DESELECT')
54 for thisObject in bpy.data.groups[group.name].objects:
55 isThisObjectVisible = False
56 # scene.objects.active = thisObject
57 for thisLayerNumb in range(20):
58 if thisObject.layers[thisLayerNumb] is True and scene.layers[thisLayerNumb] is True:
59 isThisObjectVisible = True
60 break
61 # If Object is on an invisible Layer
62 if isThisObjectVisible is False:
63 isAllObjectsVisible = False
64 return isAllObjectsVisible
67 def check_group_exist(self, context, use_report=True):
68 scene = context.scene
69 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
71 if group.name in bpy.data.groups:
72 return True
73 else:
74 if use_report:
75 self.report({'INFO'}, "No Such Group %r!" % group.name)
76 return False
79 class TexAtl_Main(Panel):
80 bl_idname = "UVTEX_ATLAS_PT_main"
81 bl_label = "Texture Atlas"
82 bl_space_type = 'PROPERTIES'
83 bl_region_type = 'WINDOW'
84 bl_context = "render"
85 bl_options = {'DEFAULT_CLOSED'}
87 def draw(self, context):
88 scene = context.scene
89 ob = context.object
91 col = self.layout.column()
92 row = self.layout.row()
93 split = self.layout.split()
95 row.template_list("UI_UL_list", "template_list_controls", scene,
96 "ms_lightmap_groups", scene, "ms_lightmap_groups_index", rows=2, maxrows=5)
97 col = row.column(align=True)
98 col.operator("scene.ms_add_lightmap_group", icon='ZOOMIN', text="")
99 col.operator("scene.ms_del_lightmap_group", icon='ZOOMOUT', text="")
101 row = self.layout.row(align=True)
103 # Resolution and Unwrap types (only if Lightmap group is added)
104 if context.scene.ms_lightmap_groups:
105 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
106 row.label(text="Resolution:")
107 row.prop(group, 'resolutionX', text='')
108 row.prop(group, 'resolutionY', text='')
109 row = self.layout.row()
110 #self.layout.separator()
112 row = self.layout.row()
113 row.operator("scene.ms_remove_other_uv",
114 text="RemoveOtherUVs", icon="GROUP")
115 row.operator("scene.ms_remove_selected",
116 text="RemoveSelected", icon="GROUP")
117 #self.layout.separator()
119 row = self.layout.row()
120 row.operator("scene.ms_add_selected_to_group",
121 text="AddSelected", icon="GROUP")
122 row.operator("scene.ms_select_group",
123 text="SelectGroup", icon="GROUP")
125 #self.layout.separator()
126 self.layout.label(text="Auto Unwrap:")
127 self.layout.prop(group, 'unwrap_type', text='Lightmap', expand=True)
128 row = self.layout.row()
129 row.operator(
130 "object.ms_auto", text="Auto Unwrap", icon="LIGHT_SPOT")
131 row.prop(group, 'autoUnwrapPrecision', text='')
133 self.layout.label(text="Manual Unwrap:")
134 row = self.layout.row()
135 row.operator(
136 "object.ms_run", text="StartManualUnwrap", icon="LIGHT_SPOT")
137 row.operator(
138 "object.ms_run_remove", text="FinishManualUnwrap", icon="LIGHT_SPOT")
141 class TexAtl_RunAuto(Operator):
142 bl_idname = "object.ms_auto"
143 bl_label = "Auto Unwrapping"
144 bl_description = "Auto Unwrapping"
146 def execute(self, context):
147 scene = context.scene
149 # get old context
150 old_context = None
151 if context.area:
152 old_context = context.area.type
154 # Check if group exists
155 if check_group_exist(self, context) is False:
156 return {'CANCELLED'}
158 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
159 if context.area:
160 context.area.type = 'VIEW_3D'
162 if bpy.ops.object.mode_set.poll():
163 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
165 if group.bake is True and bpy.data.groups[group.name].objects:
167 # Check if objects are all on the visible Layers.
168 isAllObjVisible = check_all_objects_visible(self, context)
170 if isAllObjVisible is True:
171 resX = int(group.resolutionX)
172 resY = int(group.resolutionY)
173 bpy.ops.object.ms_create_lightmap(
174 group_name=group.name, resolutionX=resX, resolutionY=resY)
175 bpy.ops.object.ms_merge_objects(
176 group_name=group.name, unwrap=True)
177 bpy.ops.object.ms_separate_objects(group_name=group.name)
178 else:
179 self.report({'INFO'}, "Not All Objects Are Visible!!!")
181 # set old context back
182 if context.area:
183 context.area.type = old_context
185 return{'FINISHED'}
188 class TexAtl_RunStart(Operator):
189 bl_idname = "object.ms_run"
190 bl_label = "Make Manual Unwrapping Object"
191 bl_description = "Makes Manual Unwrapping Object"
193 def execute(self, context):
194 scene = context.scene
196 # get old context
197 old_context = None
198 if context.area:
199 old_context = context.area.type
201 # Check if group exists
202 if check_group_exist(self, context) is False:
203 return {'CANCELLED'}
205 if context.area:
206 context.area.type = 'VIEW_3D'
207 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
209 if bpy.ops.object.mode_set.poll():
210 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
212 if group.bake is True and bpy.data.groups[group.name].objects:
214 # Check if objects are all on the visible Layers.
215 isAllObjVisible = check_all_objects_visible(self, context)
217 if bpy.data.objects.get(group.name + "_mergedObject") is not None:
218 self.report({'INFO'}, "Old Merged Object Exists!!!")
219 elif isAllObjVisible is False:
220 self.report({'INFO'}, "Not All Objects Are Visible!!!")
221 else:
222 resX = int(group.resolutionX)
223 resY = int(group.resolutionY)
224 bpy.ops.object.ms_create_lightmap(
225 group_name=group.name, resolutionX=resX, resolutionY=resY)
226 bpy.ops.object.ms_merge_objects(
227 group_name=group.name, unwrap=False)
229 # set old context back
230 if context.area:
231 context.area.type = old_context
233 return{'FINISHED'}
236 class TexAtl_RunFinish(Operator):
237 bl_idname = "object.ms_run_remove"
238 bl_label = "Remove Manual Unwrapping Object"
239 bl_description = "Removes Manual Unwrapping Object"
241 def execute(self, context):
242 scene = context.scene
244 # get old context
245 old_context = None
246 if context.area:
247 old_context = context.area.type
249 # Check if group exists
250 if check_group_exist(self, context) is False:
251 return {'CANCELLED'}
253 group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
254 if context.area:
255 context.area.type = 'VIEW_3D'
257 if bpy.ops.object.mode_set.poll():
258 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
260 if group.bake is True and bpy.data.groups[group.name].objects:
262 # Check if objects are all on the visible Layers.
263 isAllObjVisible = check_all_objects_visible(self, context)
265 if isAllObjVisible is True:
266 bpy.ops.object.ms_separate_objects(group_name=group.name)
267 else:
268 self.report({'INFO'}, "Not All Objects Are Visible!!!")
270 # set old context back
271 if context.area:
272 context.area.type = old_context
274 return{'FINISHED'}
277 class TexAtl_UVLayers(PropertyGroup):
278 name = StringProperty(default="")
281 class TexAtl_VertexGroups(PropertyGroup):
282 name = StringProperty(default="")
285 class TexAtl_Groups(PropertyGroup):
286 name = StringProperty(default="")
289 class TexAtl_MSLightmapGroups(PropertyGroup):
291 name = StringProperty(default="")
292 bake = BoolProperty(default=True)
294 unwrap_type = EnumProperty(
295 name="unwrap_type",
296 items=(('0', 'Smart_Unwrap', 'Smart_Unwrap'),
297 ('1', 'Lightmap', 'Lightmap'),
298 ('2', 'No_Unwrap', 'No_Unwrap'),
301 resolutionX = EnumProperty(
302 name="resolutionX",
303 items=(('256', '256', ''),
304 ('512', '512', ''),
305 ('1024', '1024', ''),
306 ('2048', '2048', ''),
307 ('4096', '4096', ''),
308 ('8192', '8192', ''),
309 ('16384', '16384', ''),
311 default='1024'
313 resolutionY = EnumProperty(
314 name="resolutionY",
315 items=(('256', '256', ''),
316 ('512', '512', ''),
317 ('1024', '1024', ''),
318 ('2048', '2048', ''),
319 ('4096', '4096', ''),
320 ('8192', '8192', ''),
321 ('16384', '16384', ''),
323 default='1024'
325 autoUnwrapPrecision = FloatProperty(
326 name="autoUnwrapPrecision",
327 default=0.01,
328 min=0.001,
329 max=10
331 template_list_controls = StringProperty(
332 default="bake",
333 options={"HIDDEN"},
337 class TexAtl_MergedObjects(PropertyGroup):
338 name = StringProperty()
339 vertex_groups = CollectionProperty(
340 type=TexAtl_VertexGroups,
342 groups = CollectionProperty(type=TexAtl_Groups)
343 uv_layers = CollectionProperty(type=TexAtl_UVLayers)
346 class TexAtl_AddSelectedToGroup(Operator):
347 bl_idname = "scene.ms_add_selected_to_group"
348 bl_label = "Add to Group"
349 bl_description = "Adds selected Objects to current Group"
351 def execute(self, context):
352 scene = context.scene
353 group_name = scene.ms_lightmap_groups[
354 scene.ms_lightmap_groups_index].name
356 # Create a New Group if it was deleted.
357 obj_group = bpy.data.groups.get(group_name)
358 if obj_group is None:
359 obj_group = bpy.data.groups.new(group_name)
361 # Add objects to a group
362 if bpy.ops.object.mode_set.poll():
363 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
365 for object in context.selected_objects:
366 if object.type == 'MESH' and object.name not in obj_group.objects:
367 obj_group.objects.link(object)
369 return {'FINISHED'}
372 class TexAtl_SelectGroup(Operator):
373 bl_idname = "scene.ms_select_group"
374 bl_label = "sel Group"
375 bl_description = "Selected Objects of current Group"
377 def execute(self, context):
378 scene = context.scene
379 group_name = scene.ms_lightmap_groups[
380 scene.ms_lightmap_groups_index].name
382 # Check if group exists
383 if check_group_exist(self, context) is False:
384 return {'CANCELLED'}
386 if bpy.ops.object.mode_set.poll():
387 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
389 bpy.ops.object.select_all(action='DESELECT')
390 obj_group = bpy.data.groups[group_name]
391 for object in obj_group.objects:
392 object.select = True
393 return {'FINISHED'}
396 class TexAtl_RemoveFromGroup(Operator):
397 bl_idname = "scene.ms_remove_selected"
398 bl_label = "del Selected"
399 bl_description = "Remove Selected Group and UVs"
401 # remove all modifiers
402 # for m in mesh.modifiers:
403 # bpy.ops.object.modifier_remove(modifier=m.name)
405 def execute(self, context):
406 scene = context.scene
408 # Check if group exists
409 if check_group_exist(self, context) is False:
410 return {'CANCELLED'}
412 if bpy.ops.object.mode_set.poll():
413 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
415 for group in scene.ms_lightmap_groups:
416 group_name = group.name
418 obj_group = bpy.data.groups[group_name]
419 for object in context.selected_objects:
420 scene.objects.active = object
422 if object.type == 'MESH' and object.name in obj_group.objects:
424 # remove UV
425 tex = object.data.uv_textures.get(group_name)
426 if tex is not None:
427 object.data.uv_textures.remove(tex)
429 # remove from group
430 obj_group.objects.unlink(object)
431 object.hide_render = False
433 return {'FINISHED'}
436 class TexAtl_RemoveOtherUVs(Operator):
437 bl_idname = "scene.ms_remove_other_uv"
438 bl_label = "remOther"
439 bl_description = "Remove Other UVs from Selected"
441 def execute(self, context):
442 scene = context.scene
443 group_name = scene.ms_lightmap_groups[
444 scene.ms_lightmap_groups_index].name
446 # Check if group exists
447 if check_group_exist(self, context) is False:
448 return {'CANCELLED'}
450 if bpy.ops.object.mode_set.poll():
451 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
452 # bpy.ops.object.select_all(action='DESELECT')
454 obj_group = bpy.data.groups[group_name]
456 # Remove other UVs of selected objects
457 for object in context.selected_objects:
458 scene.objects.active = object
459 if object.type == 'MESH' and object.name in obj_group.objects:
461 # remove UVs
462 UVLIST = []
463 for uv in object.data.uv_textures:
464 if uv.name != group_name:
465 UVLIST.append(uv.name)
467 for uvName in UVLIST:
468 tex = object.data.uv_textures[uvName]
469 object.data.uv_textures.remove(tex)
471 UVLIST.clear() # clear array
473 return {'FINISHED'}
476 class TexAtl_AddLightmapGroup(Operator):
477 bl_idname = "scene.ms_add_lightmap_group"
478 bl_label = "add Lightmap"
479 bl_description = "Adds a new Lightmap Group"
481 name = StringProperty(name="Group Name", default='TextureAtlas')
483 def execute(self, context):
484 scene = context.scene
485 obj_group = bpy.data.groups.new(self.name)
487 item = scene.ms_lightmap_groups.add()
488 item.name = obj_group.name
489 #item.resolution = '1024'
490 scene.ms_lightmap_groups_index = len(scene.ms_lightmap_groups) - 1
492 # Add selested objects to group
493 for object in context.selected_objects:
494 if object.type == 'MESH':
495 obj_group.objects.link(object)
497 return {'FINISHED'}
499 def invoke(self, context, event):
500 wm = context.window_manager
501 return wm.invoke_props_dialog(self)
504 class TexAtl_DelLightmapGroup(Operator):
505 bl_idname = "scene.ms_del_lightmap_group"
506 bl_label = "delete Lightmap"
507 bl_description = "Deletes active Lightmap Group"
509 def execute(self, context):
510 scene = context.scene
511 if len(scene.ms_lightmap_groups) > 0:
512 idx = scene.ms_lightmap_groups_index
513 group_name = scene.ms_lightmap_groups[idx].name
515 # Remove Group
516 group = bpy.data.groups.get(group_name)
517 if group is not None:
519 # Unhide Objects if they are hidden
520 for obj in group.objects:
521 obj.hide_render = False
522 obj.hide = False
524 bpy.data.groups.remove(group, do_unlink=True)
526 # Remove Lightmap Group
527 scene.ms_lightmap_groups.remove(scene.ms_lightmap_groups_index)
528 scene.ms_lightmap_groups_index -= 1
529 if scene.ms_lightmap_groups_index < 0:
530 scene.ms_lightmap_groups_index = 0
532 return {'FINISHED'}
535 class TexAtl_CreateLightmap(Operator):
536 bl_idname = "object.ms_create_lightmap"
537 bl_label = "TextureAtlas - Generate Lightmap"
538 bl_description = "Generates a Lightmap"
540 group_name = StringProperty(default='')
541 resolutionX = IntProperty(default=1024)
542 resolutionY = IntProperty(default=1024)
544 def execute(self, context):
545 scene = context.scene
547 # Create/Update Image
548 image = bpy.data.images.get(self.group_name)
549 if image is None:
550 image = bpy.data.images.new(
551 name=self.group_name, width=self.resolutionX, height=self.resolutionY)
553 image.generated_type = 'COLOR_GRID'
554 image.generated_width = self.resolutionX
555 image.generated_height = self.resolutionY
556 obj_group = bpy.data.groups[self.group_name]
558 # non MESH objects for removal list
559 NON_MESH_LIST = []
561 for object in obj_group.objects:
562 # Remove non MESH objects
564 if object.type != 'MESH':
565 NON_MESH_LIST.append(object)
566 elif object.type == 'MESH' and len(object.data.vertices) == 0:
567 NON_MESH_LIST.append(object)
568 else:
569 # Add Image to faces
570 if object.data.uv_textures.active is None:
571 tex = object.data.uv_textures.new()
572 tex.name = self.group_name
573 else:
574 if self.group_name not in object.data.uv_textures:
575 tex = object.data.uv_textures.new()
576 tex.name = self.group_name
577 tex.active = True
578 tex.active_render = True
579 else:
580 tex = object.data.uv_textures[self.group_name]
581 tex.active = True
582 tex.active_render = True
584 for face_tex in tex.data:
585 face_tex.image = image
587 # remove non NESH objects
588 for object in NON_MESH_LIST:
589 obj_group.objects.unlink(object)
591 NON_MESH_LIST.clear() # clear array
593 return{'FINISHED'}
596 class TexAtl_MergeObjects(Operator):
597 bl_idname = "object.ms_merge_objects"
598 bl_label = "TextureAtlas - TexAtl_MergeObjects"
599 bl_description = "Merges Objects and stores Origins"
601 group_name = StringProperty(default='')
602 unwrap = BoolProperty(default=False)
604 def execute(self, context):
605 scene = context.scene
607 # objToDelete = None
608 bpy.ops.object.select_all(action='DESELECT')
609 ob_merged_old = bpy.data.objects.get(self.group_name + "_mergedObject")
610 if ob_merged_old is not None:
611 ob_merged_old.select = True
612 scene.objects.active = ob_merged_old
613 bpy.ops.object.delete(use_global=True)
615 me = bpy.data.meshes.new(self.group_name + '_mergedObject')
616 ob_merge = bpy.data.objects.new(self.group_name + '_mergedObject', me)
617 ob_merge.location = scene.cursor_location # position object at 3d-cursor
618 scene.objects.link(ob_merge) # Link object to scene
619 me.update()
620 ob_merge.select = False
622 bpy.ops.object.select_all(action='DESELECT')
624 # We do the MergeList beacuse we will duplicate grouped objects
625 mergeList = []
626 for object in bpy.data.groups[self.group_name].objects:
627 mergeList.append(object)
629 for object in mergeList:
630 # make object temporary unhidden
631 isObjHideSelect = object.hide_select
632 object.hide = False
633 object.hide_select = False
635 bpy.ops.object.select_all(action='DESELECT')
636 object.select = True
638 # activate lightmap uv if existant
639 for uv in object.data.uv_textures:
640 if uv.name == self.group_name:
641 uv.active = True
642 scene.objects.active = object
644 # Duplicate Temp Object
645 bpy.ops.object.select_all(action='DESELECT')
646 object.select = True
647 scene.objects.active = object
648 bpy.ops.object.duplicate(linked=False, mode='TRANSLATION')
649 activeNowObject = scene.objects.active
650 activeNowObject.select = True
652 # hide render of original mesh
653 object.hide_render = True
654 object.hide = True
655 object.select = False
656 object.hide_select = isObjHideSelect
658 # remove unused UV
659 # remove UVs
660 UVLIST = []
661 for uv in activeNowObject.data.uv_textures:
662 if uv.name != self.group_name:
663 UVLIST.append(uv.name)
665 for uvName in UVLIST:
666 tex = activeNowObject.data.uv_textures[uvName]
667 activeNowObject.data.uv_textures.remove(tex)
669 UVLIST.clear() # clear array
671 # create vertex groups for each selected object
672 scene.objects.active = activeNowObject
673 vgroup = activeNowObject.vertex_groups.new(name=object.name)
674 vgroup.add(
675 list(range(len(activeNowObject.data.vertices))), weight=1.0, type='ADD')
677 # save object name in merged object
678 item = ob_merge.ms_merged_objects.add()
679 item.name = object.name
681 # Add material to a tempObject if there are no materialSlots on the object
682 if not activeNowObject.data.materials:
683 matName = "zz_TextureAtlas_NO_Material"
684 mat = bpy.data.materials.get(matName)
686 if mat is None:
687 mat = bpy.data.materials.new(matName)
689 activeNowObject.data.materials.append(mat)
691 # merge objects together
692 bpy.ops.object.select_all(action='DESELECT')
693 activeNowObject.select = True
694 ob_merge.select = True
695 scene.objects.active = ob_merge
696 bpy.ops.object.join()
698 mergeList.clear() # Clear Merge List
700 # make Unwrap
701 bpy.ops.object.select_all(action='DESELECT')
702 ob_merge.select = True
703 scene.objects.active = ob_merge
705 # Unfide all faces
706 bpy.ops.object.mode_set(mode='EDIT')
707 bpy.ops.mesh.reveal()
708 bpy.ops.mesh.select_all(action='SELECT')
709 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
711 if self.unwrap is True:
712 groupProps = scene.ms_lightmap_groups[self.group_name]
713 unwrapType = groupProps.unwrap_type
715 if unwrapType == '0' or unwrapType == '1':
716 bpy.ops.object.mode_set(mode='EDIT')
718 if unwrapType == '0':
720 bpy.ops.uv.smart_project(
721 angle_limit=72.0, island_margin=groupProps.autoUnwrapPrecision, user_area_weight=0.0)
722 elif unwrapType == '1':
723 bpy.ops.uv.lightmap_pack(
724 PREF_CONTEXT='ALL_FACES', PREF_PACK_IN_ONE=True, PREF_NEW_UVLAYER=False,
725 PREF_APPLY_IMAGE=False, PREF_IMG_PX_SIZE=1024, PREF_BOX_DIV=48, PREF_MARGIN_DIV=groupProps.autoUnwrapPrecision)
726 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
728 return{'FINISHED'}
731 class TexAtl_SeparateObjects(Operator):
732 bl_idname = "object.ms_separate_objects"
733 bl_label = "TextureAtlas - Separate Objects"
734 bl_description = "Separates Objects and restores Origin"
736 group_name = StringProperty(default='')
738 def execute(self, context):
739 scene = context.scene
741 ob_merged = bpy.data.objects.get(self.group_name + "_mergedObject")
742 if ob_merged is not None:
744 # if scene.objects.active is not None:
745 # bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
746 bpy.ops.object.select_all(action='DESELECT')
747 ob_merged.hide = False
748 ob_merged.select = True
749 groupSeparate = bpy.data.groups.new(ob_merged.name)
750 groupSeparate.objects.link(ob_merged)
751 ob_merged.select = False
753 doUnhidePolygons = False
754 for ms_obj in ob_merged.ms_merged_objects:
755 # select vertex groups and separate group from merged
756 # object
757 bpy.ops.object.select_all(action='DESELECT')
758 ob_merged.select = True
759 scene.objects.active = ob_merged
761 bpy.ops.object.mode_set(mode='EDIT')
762 if doUnhidePolygons is False:
763 # Unhide Polygons only once
764 bpy.ops.mesh.reveal()
765 doUnhidePolygons = True
767 bpy.ops.mesh.select_all(action='DESELECT')
768 ob_merged.vertex_groups.active_index = ob_merged.vertex_groups[
769 ms_obj.name].index
770 bpy.ops.object.vertex_group_select()
771 bpy.ops.mesh.separate(type='SELECTED')
772 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
773 # scene.objects.active.select = False
775 # find separeted object
776 ob_separeted = None
777 for obj in groupSeparate.objects:
778 if obj != ob_merged:
779 ob_separeted = obj
780 break
782 # Copy UV Coordinates to the original mesh
783 if ms_obj.name in scene.objects:
784 ob_merged.select = False
785 ob_original = scene.objects[ms_obj.name]
786 isOriginalToSelect = ob_original.hide_select
787 ob_original.hide_select = False
788 ob_original.hide = False
789 ob_original.select = True
790 scene.objects.active = ob_separeted
791 bpy.ops.object.join_uvs()
792 ob_original.hide_render = False
793 ob_original.select = False
794 ob_original.hide_select = isOriginalToSelect
795 ob_original.data.update()
797 # delete separeted object
798 bpy.ops.object.select_all(action='DESELECT')
799 ob_separeted.select = True
800 bpy.ops.object.delete(use_global=False)
802 # delete duplicated object
803 bpy.ops.object.select_all(action='DESELECT')
804 ob_merged.select = True
805 bpy.ops.object.delete(use_global=False)
807 return{'FINISHED'}
810 def register():
811 bpy.utils.register_module(__name__)
813 bpy.types.Object.ms_merged_objects = CollectionProperty(
814 type=TexAtl_MergedObjects)
816 bpy.types.Scene.ms_lightmap_groups = CollectionProperty(
817 type=TexAtl_MSLightmapGroups)
819 bpy.types.Scene.ms_lightmap_groups_index = IntProperty()
821 def unregister():
822 bpy.utils.unregister_module(__name__)
825 if __name__ == "__main__":
826 register()