uv_texture_atlas.py: move to contrib: T63750
This commit is contained in:
parent
962fd14ae3
commit
2e41fe16c5
|
@ -1,831 +0,0 @@
|
|||
# BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# END GPL LICENSE BLOCK #####
|
||||
|
||||
|
||||
bl_info = {
|
||||
"name": "Texture Atlas",
|
||||
"author": "Andreas Esau, Paul Geraskin, Campbell Barton",
|
||||
"version": (0, 2, 1),
|
||||
"blender": (2, 67, 0),
|
||||
"location": "Properties > Render",
|
||||
"description": "A simple Texture Atlas for unwrapping many objects. It creates additional UV",
|
||||
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
|
||||
"Scripts/UV/TextureAtlas",
|
||||
"category": "UV",
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Operator,
|
||||
Panel,
|
||||
PropertyGroup,
|
||||
)
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
FloatProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
import mathutils
|
||||
|
||||
|
||||
def check_all_objects_visible(self, context):
|
||||
scene = context.scene
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
isAllObjectsVisible = True
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for thisObject in bpy.data.collections[group.name].objects:
|
||||
isThisObjectVisible = False
|
||||
# scene.objects.active = thisObject
|
||||
for thisLayerNumb in range(20):
|
||||
if thisObject.layers[thisLayerNumb] is True and scene.layers[thisLayerNumb] is True:
|
||||
isThisObjectVisible = True
|
||||
break
|
||||
# If Object is on an invisible Layer
|
||||
if isThisObjectVisible is False:
|
||||
isAllObjectsVisible = False
|
||||
return isAllObjectsVisible
|
||||
|
||||
|
||||
def check_group_exist(self, context, use_report=True):
|
||||
scene = context.scene
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
|
||||
if group.name in bpy.data.collections:
|
||||
return True
|
||||
else:
|
||||
if use_report:
|
||||
self.report({'INFO'}, "No Such Group %r!" % group.name)
|
||||
return False
|
||||
|
||||
|
||||
class TexAtl_Main(Panel):
|
||||
bl_idname = "UVTEX_ATLAS_PT_main"
|
||||
bl_label = "Texture Atlas"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
ob = context.object
|
||||
|
||||
col = self.layout.column()
|
||||
row = self.layout.row()
|
||||
split = self.layout.split()
|
||||
|
||||
row.template_list("UI_UL_list", "template_list_controls", scene,
|
||||
"ms_lightmap_groups", scene, "ms_lightmap_groups_index", rows=2, maxrows=5)
|
||||
col = row.column(align=True)
|
||||
col.operator("scene.ms_add_lightmap_group", icon='ADD', text="")
|
||||
col.operator("scene.ms_del_lightmap_group", icon='REMOVE', text="")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
# Resolution and Unwrap types (only if Lightmap group is added)
|
||||
if context.scene.ms_lightmap_groups:
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
row.label(text="Resolution:")
|
||||
row.prop(group, 'resolutionX', text='')
|
||||
row.prop(group, 'resolutionY', text='')
|
||||
row = self.layout.row()
|
||||
#self.layout.separator()
|
||||
|
||||
row = self.layout.row()
|
||||
row.operator("scene.ms_remove_other_uv",
|
||||
text="RemoveOtherUVs", icon="GROUP")
|
||||
row.operator("scene.ms_remove_selected",
|
||||
text="RemoveSelected", icon="GROUP")
|
||||
#self.layout.separator()
|
||||
|
||||
row = self.layout.row()
|
||||
row.operator("scene.ms_add_selected_to_group",
|
||||
text="AddSelected", icon="GROUP")
|
||||
row.operator("scene.ms_select_group",
|
||||
text="SelectGroup", icon="GROUP")
|
||||
|
||||
#self.layout.separator()
|
||||
self.layout.label(text="Auto Unwrap:")
|
||||
self.layout.prop(group, 'unwrap_type', text='Lightmap', expand=True)
|
||||
row = self.layout.row()
|
||||
row.operator(
|
||||
"object.ms_auto", text="Auto Unwrap", icon="LIGHT_SPOT")
|
||||
row.prop(group, 'autoUnwrapPrecision', text='')
|
||||
|
||||
self.layout.label(text="Manual Unwrap:")
|
||||
row = self.layout.row()
|
||||
row.operator(
|
||||
"object.ms_run", text="StartManualUnwrap", icon="LIGHT_SPOT")
|
||||
row.operator(
|
||||
"object.ms_run_remove", text="FinishManualUnwrap", icon="LIGHT_SPOT")
|
||||
|
||||
|
||||
class TexAtl_RunAuto(Operator):
|
||||
bl_idname = "object.ms_auto"
|
||||
bl_label = "Auto Unwrapping"
|
||||
bl_description = "Auto Unwrapping"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
|
||||
# get old context
|
||||
old_context = None
|
||||
if context.area:
|
||||
old_context = context.area.type
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
if context.area:
|
||||
context.area.type = 'VIEW_3D'
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if group.bake is True and bpy.data.collections[group.name].objects:
|
||||
|
||||
# Check if objects are all on the visible Layers.
|
||||
isAllObjVisible = check_all_objects_visible(self, context)
|
||||
|
||||
if isAllObjVisible is True:
|
||||
resX = int(group.resolutionX)
|
||||
resY = int(group.resolutionY)
|
||||
bpy.ops.object.ms_create_lightmap(
|
||||
group_name=group.name, resolutionX=resX, resolutionY=resY)
|
||||
bpy.ops.object.ms_merge_objects(
|
||||
group_name=group.name, unwrap=True)
|
||||
bpy.ops.object.ms_separate_objects(group_name=group.name)
|
||||
else:
|
||||
self.report({'INFO'}, "Not All Objects Are Visible!!!")
|
||||
|
||||
# set old context back
|
||||
if context.area:
|
||||
context.area.type = old_context
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_RunStart(Operator):
|
||||
bl_idname = "object.ms_run"
|
||||
bl_label = "Make Manual Unwrapping Object"
|
||||
bl_description = "Makes Manual Unwrapping Object"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
|
||||
# get old context
|
||||
old_context = None
|
||||
if context.area:
|
||||
old_context = context.area.type
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
if context.area:
|
||||
context.area.type = 'VIEW_3D'
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if group.bake is True and bpy.data.collections[group.name].objects:
|
||||
|
||||
# Check if objects are all on the visible Layers.
|
||||
isAllObjVisible = check_all_objects_visible(self, context)
|
||||
|
||||
if bpy.data.objects.get(group.name + "_mergedObject") is not None:
|
||||
self.report({'INFO'}, "Old Merged Object Exists!!!")
|
||||
elif isAllObjVisible is False:
|
||||
self.report({'INFO'}, "Not All Objects Are Visible!!!")
|
||||
else:
|
||||
resX = int(group.resolutionX)
|
||||
resY = int(group.resolutionY)
|
||||
bpy.ops.object.ms_create_lightmap(
|
||||
group_name=group.name, resolutionX=resX, resolutionY=resY)
|
||||
bpy.ops.object.ms_merge_objects(
|
||||
group_name=group.name, unwrap=False)
|
||||
|
||||
# set old context back
|
||||
if context.area:
|
||||
context.area.type = old_context
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_RunFinish(Operator):
|
||||
bl_idname = "object.ms_run_remove"
|
||||
bl_label = "Remove Manual Unwrapping Object"
|
||||
bl_description = "Removes Manual Unwrapping Object"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
|
||||
# get old context
|
||||
old_context = None
|
||||
if context.area:
|
||||
old_context = context.area.type
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
group = scene.ms_lightmap_groups[scene.ms_lightmap_groups_index]
|
||||
if context.area:
|
||||
context.area.type = 'VIEW_3D'
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if group.bake is True and bpy.data.collections[group.name].objects:
|
||||
|
||||
# Check if objects are all on the visible Layers.
|
||||
isAllObjVisible = check_all_objects_visible(self, context)
|
||||
|
||||
if isAllObjVisible is True:
|
||||
bpy.ops.object.ms_separate_objects(group_name=group.name)
|
||||
else:
|
||||
self.report({'INFO'}, "Not All Objects Are Visible!!!")
|
||||
|
||||
# set old context back
|
||||
if context.area:
|
||||
context.area.type = old_context
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_UVLayers(PropertyGroup):
|
||||
name: StringProperty(default="")
|
||||
|
||||
|
||||
class TexAtl_VertexGroups(PropertyGroup):
|
||||
name: StringProperty(default="")
|
||||
|
||||
|
||||
class TexAtl_Groups(PropertyGroup):
|
||||
name: StringProperty(default="")
|
||||
|
||||
|
||||
class TexAtl_MSLightmapGroups(PropertyGroup):
|
||||
|
||||
name: StringProperty(default="")
|
||||
bake: BoolProperty(default=True)
|
||||
|
||||
unwrap_type: EnumProperty(
|
||||
name="unwrap_type",
|
||||
items=(('0', 'Smart_Unwrap', 'Smart_Unwrap'),
|
||||
('1', 'Lightmap', 'Lightmap'),
|
||||
('2', 'No_Unwrap', 'No_Unwrap'),
|
||||
),
|
||||
)
|
||||
resolutionX: EnumProperty(
|
||||
name="resolutionX",
|
||||
items=(('256', '256', ''),
|
||||
('512', '512', ''),
|
||||
('1024', '1024', ''),
|
||||
('2048', '2048', ''),
|
||||
('4096', '4096', ''),
|
||||
('8192', '8192', ''),
|
||||
('16384', '16384', ''),
|
||||
),
|
||||
default='1024'
|
||||
)
|
||||
resolutionY: EnumProperty(
|
||||
name="resolutionY",
|
||||
items=(('256', '256', ''),
|
||||
('512', '512', ''),
|
||||
('1024', '1024', ''),
|
||||
('2048', '2048', ''),
|
||||
('4096', '4096', ''),
|
||||
('8192', '8192', ''),
|
||||
('16384', '16384', ''),
|
||||
),
|
||||
default='1024'
|
||||
)
|
||||
autoUnwrapPrecision: FloatProperty(
|
||||
name="autoUnwrapPrecision",
|
||||
default=0.01,
|
||||
min=0.001,
|
||||
max=10
|
||||
)
|
||||
template_list_controls: StringProperty(
|
||||
default="bake",
|
||||
options={"HIDDEN"},
|
||||
)
|
||||
|
||||
|
||||
class TexAtl_MergedObjects(PropertyGroup):
|
||||
name: StringProperty()
|
||||
vertex_groups: CollectionProperty(
|
||||
type=TexAtl_VertexGroups,
|
||||
)
|
||||
groups: CollectionProperty(type=TexAtl_Groups)
|
||||
uv_layers: CollectionProperty(type=TexAtl_UVLayers)
|
||||
|
||||
|
||||
class TexAtl_AddSelectedToGroup(Operator):
|
||||
bl_idname = "scene.ms_add_selected_to_group"
|
||||
bl_label = "Add to Group"
|
||||
bl_description = "Adds selected Objects to current Group"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
group_name = scene.ms_lightmap_groups[
|
||||
scene.ms_lightmap_groups_index].name
|
||||
|
||||
# Create a New Group if it was deleted.
|
||||
obj_group = bpy.data.collections.get(group_name)
|
||||
if obj_group is None:
|
||||
obj_group = bpy.data.collections.new(group_name)
|
||||
|
||||
# Add objects to a group
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
for object in context.selected_objects:
|
||||
if object.type == 'MESH' and object.name not in obj_group.objects:
|
||||
obj_group.objects.link(object)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_SelectGroup(Operator):
|
||||
bl_idname = "scene.ms_select_group"
|
||||
bl_label = "sel Group"
|
||||
bl_description = "Selected Objects of current Group"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
group_name = scene.ms_lightmap_groups[
|
||||
scene.ms_lightmap_groups_index].name
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj_group = bpy.data.collections[group_name]
|
||||
for object in obj_group.objects:
|
||||
object.select_set(True)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_RemoveFromGroup(Operator):
|
||||
bl_idname = "scene.ms_remove_selected"
|
||||
bl_label = "del Selected"
|
||||
bl_description = "Remove Selected Group and UVs"
|
||||
|
||||
# remove all modifiers
|
||||
# for m in mesh.modifiers:
|
||||
# bpy.ops.object.modifier_remove(modifier=m.name)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
for group in scene.ms_lightmap_groups:
|
||||
group_name = group.name
|
||||
|
||||
obj_group = bpy.data.collections[group_name]
|
||||
for object in context.selected_objects:
|
||||
view_layer.objects.active = object
|
||||
|
||||
if object.type == 'MESH' and object.name in obj_group.objects:
|
||||
|
||||
# remove UV
|
||||
tex = object.data.uv_textures.get(group_name)
|
||||
if tex is not None:
|
||||
object.data.uv_textures.remove(tex)
|
||||
|
||||
# remove from group
|
||||
obj_group.objects.unlink(object)
|
||||
object.hide_render = False
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_RemoveOtherUVs(Operator):
|
||||
bl_idname = "scene.ms_remove_other_uv"
|
||||
bl_label = "remOther"
|
||||
bl_description = "Remove Other UVs from Selected"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
group_name = scene.ms_lightmap_groups[
|
||||
scene.ms_lightmap_groups_index].name
|
||||
|
||||
# Check if group exists
|
||||
if check_group_exist(self, context) is False:
|
||||
return {'CANCELLED'}
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
# bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
obj_group = bpy.data.collections[group_name]
|
||||
|
||||
# Remove other UVs of selected objects
|
||||
for object in context.selected_objects:
|
||||
view_layer.objects.active = object
|
||||
if object.type == 'MESH' and object.name in obj_group.objects:
|
||||
|
||||
# remove UVs
|
||||
UVLIST = []
|
||||
for uv in object.data.uv_textures:
|
||||
if uv.name != group_name:
|
||||
UVLIST.append(uv.name)
|
||||
|
||||
for uvName in UVLIST:
|
||||
tex = object.data.uv_textures[uvName]
|
||||
object.data.uv_textures.remove(tex)
|
||||
|
||||
UVLIST.clear() # clear array
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_AddLightmapGroup(Operator):
|
||||
bl_idname = "scene.ms_add_lightmap_group"
|
||||
bl_label = "add Lightmap"
|
||||
bl_description = "Adds a new Lightmap Group"
|
||||
|
||||
name: StringProperty(name="Group Name", default='TextureAtlas')
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
obj_group = bpy.data.collections.new(self.name)
|
||||
|
||||
item = scene.ms_lightmap_groups.add()
|
||||
item.name = obj_group.name
|
||||
#item.resolution = '1024'
|
||||
scene.ms_lightmap_groups_index = len(scene.ms_lightmap_groups) - 1
|
||||
|
||||
# Add selested objects to group
|
||||
for object in context.selected_objects:
|
||||
if object.type == 'MESH':
|
||||
obj_group.objects.link(object)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
class TexAtl_DelLightmapGroup(Operator):
|
||||
bl_idname = "scene.ms_del_lightmap_group"
|
||||
bl_label = "delete Lightmap"
|
||||
bl_description = "Deletes active Lightmap Group"
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
if len(scene.ms_lightmap_groups) > 0:
|
||||
idx = scene.ms_lightmap_groups_index
|
||||
group_name = scene.ms_lightmap_groups[idx].name
|
||||
|
||||
# Remove Group
|
||||
group = bpy.data.collections.get(group_name)
|
||||
if group is not None:
|
||||
|
||||
# Unhide Objects if they are hidden
|
||||
for obj in group.objects:
|
||||
obj.hide_render = False
|
||||
obj.hide = False
|
||||
|
||||
bpy.data.collections.remove(group, do_unlink=True)
|
||||
|
||||
# Remove Lightmap Group
|
||||
scene.ms_lightmap_groups.remove(scene.ms_lightmap_groups_index)
|
||||
scene.ms_lightmap_groups_index -= 1
|
||||
if scene.ms_lightmap_groups_index < 0:
|
||||
scene.ms_lightmap_groups_index = 0
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_CreateLightmap(Operator):
|
||||
bl_idname = "object.ms_create_lightmap"
|
||||
bl_label = "TextureAtlas - Generate Lightmap"
|
||||
bl_description = "Generates a Lightmap"
|
||||
|
||||
group_name: StringProperty(default='')
|
||||
resolutionX: IntProperty(default=1024)
|
||||
resolutionY: IntProperty(default=1024)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
|
||||
# Create/Update Image
|
||||
image = bpy.data.images.get(self.group_name)
|
||||
if image is None:
|
||||
image = bpy.data.images.new(
|
||||
name=self.group_name, width=self.resolutionX, height=self.resolutionY)
|
||||
|
||||
image.generated_type = 'COLOR_GRID'
|
||||
image.generated_width = self.resolutionX
|
||||
image.generated_height = self.resolutionY
|
||||
obj_group = bpy.data.collections[self.group_name]
|
||||
|
||||
# non MESH objects for removal list
|
||||
NON_MESH_LIST = []
|
||||
|
||||
for object in obj_group.objects:
|
||||
# Remove non MESH objects
|
||||
|
||||
if object.type != 'MESH':
|
||||
NON_MESH_LIST.append(object)
|
||||
elif object.type == 'MESH' and len(object.data.vertices) == 0:
|
||||
NON_MESH_LIST.append(object)
|
||||
else:
|
||||
# Add Image to faces
|
||||
if object.data.uv_textures.active is None:
|
||||
tex = object.data.uv_textures.new()
|
||||
tex.name = self.group_name
|
||||
else:
|
||||
if self.group_name not in object.data.uv_textures:
|
||||
tex = object.data.uv_textures.new()
|
||||
tex.name = self.group_name
|
||||
tex.active = True
|
||||
tex.active_render = True
|
||||
else:
|
||||
tex = object.data.uv_textures[self.group_name]
|
||||
tex.active = True
|
||||
tex.active_render = True
|
||||
|
||||
for face_tex in tex.data:
|
||||
face_tex.image = image
|
||||
|
||||
# remove non NESH objects
|
||||
for object in NON_MESH_LIST:
|
||||
obj_group.objects.unlink(object)
|
||||
|
||||
NON_MESH_LIST.clear() # clear array
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_MergeObjects(Operator):
|
||||
bl_idname = "object.ms_merge_objects"
|
||||
bl_label = "TextureAtlas - TexAtl_MergeObjects"
|
||||
bl_description = "Merges Objects and stores Origins"
|
||||
|
||||
group_name: StringProperty(default='')
|
||||
unwrap: BoolProperty(default=False)
|
||||
|
||||
def execute(self, context):
|
||||
collection = context.collection
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
# objToDelete = None
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_merged_old = bpy.data.objects.get(self.group_name + "_mergedObject")
|
||||
if ob_merged_old is not None:
|
||||
ob_merged_old.select_set(True)
|
||||
view_layer.objects.active = ob_merged_old
|
||||
bpy.ops.object.delete(use_global=True)
|
||||
|
||||
me = bpy.data.meshes.new(self.group_name + '_mergedObject')
|
||||
ob_merge = bpy.data.objects.new(self.group_name + '_mergedObject', me)
|
||||
ob_merge.location = scene.cursor.location # position object at 3d-cursor
|
||||
collection.objects.link(ob_merge) # Link object to collection
|
||||
me.update()
|
||||
ob_merge.select_set(False)
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
# We do the MergeList because we will duplicate grouped objects
|
||||
mergeList = []
|
||||
for object in bpy.data.collections[self.group_name].objects:
|
||||
mergeList.append(object)
|
||||
|
||||
for object in mergeList:
|
||||
# make object temporary unhidden
|
||||
isObjHideSelect = object.hide_select
|
||||
object.hide = False
|
||||
object.hide_select = False
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
object.select_set(True)
|
||||
|
||||
# activate lightmap uv if existent
|
||||
for uv in object.data.uv_textures:
|
||||
if uv.name == self.group_name:
|
||||
uv.active = True
|
||||
view_layer.objects.active = object
|
||||
|
||||
# Duplicate Temp Object
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
object.select_set(True)
|
||||
view_layer.objects.active = object
|
||||
bpy.ops.object.duplicate(linked=False, mode='TRANSLATION')
|
||||
activeNowObject = view_layer.objects.active
|
||||
activeNowObject.select_set(True)
|
||||
|
||||
# hide render of original mesh
|
||||
object.hide_render = True
|
||||
object.hide = True
|
||||
object.select_set(False)
|
||||
object.hide_select = isObjHideSelect
|
||||
|
||||
# remove unused UV
|
||||
# remove UVs
|
||||
UVLIST = []
|
||||
for uv in activeNowObject.data.uv_textures:
|
||||
if uv.name != self.group_name:
|
||||
UVLIST.append(uv.name)
|
||||
|
||||
for uvName in UVLIST:
|
||||
tex = activeNowObject.data.uv_textures[uvName]
|
||||
activeNowObject.data.uv_textures.remove(tex)
|
||||
|
||||
UVLIST.clear() # clear array
|
||||
|
||||
# create vertex groups for each selected object
|
||||
view_layer.objects.active = activeNowObject
|
||||
vgroup = activeNowObject.vertex_groups.new(name=object.name)
|
||||
vgroup.add(
|
||||
list(range(len(activeNowObject.data.vertices))), weight=1.0, type='ADD')
|
||||
|
||||
# save object name in merged object
|
||||
item = ob_merge.ms_merged_objects.add()
|
||||
item.name = object.name
|
||||
|
||||
# Add material to a tempObject if there are no materialSlots on the object
|
||||
if not activeNowObject.data.materials:
|
||||
matName = "zz_TextureAtlas_NO_Material"
|
||||
mat = bpy.data.materials.get(matName)
|
||||
|
||||
if mat is None:
|
||||
mat = bpy.data.materials.new(matName)
|
||||
|
||||
activeNowObject.data.materials.append(mat)
|
||||
|
||||
# merge objects together
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
activeNowObject.select_set(True)
|
||||
ob_merge.select_set(True)
|
||||
view_layer.objects.active = ob_merge
|
||||
bpy.ops.object.join()
|
||||
|
||||
mergeList.clear() # Clear Merge List
|
||||
|
||||
# make Unwrap
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_merge.select_set(True)
|
||||
view_layer.objects.active = ob_merge
|
||||
|
||||
# Unfide all faces
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.reveal()
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if self.unwrap is True:
|
||||
groupProps = scene.ms_lightmap_groups[self.group_name]
|
||||
unwrapType = groupProps.unwrap_type
|
||||
|
||||
if unwrapType == '0' or unwrapType == '1':
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
if unwrapType == '0':
|
||||
|
||||
bpy.ops.uv.smart_project(
|
||||
angle_limit=72.0, island_margin=groupProps.autoUnwrapPrecision, user_area_weight=0.0)
|
||||
elif unwrapType == '1':
|
||||
bpy.ops.uv.lightmap_pack(
|
||||
PREF_CONTEXT='ALL_FACES', PREF_PACK_IN_ONE=True, PREF_NEW_UVLAYER=False,
|
||||
PREF_APPLY_IMAGE=False, PREF_IMG_PX_SIZE=1024, PREF_BOX_DIV=48, PREF_MARGIN_DIV=groupProps.autoUnwrapPrecision)
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
class TexAtl_SeparateObjects(Operator):
|
||||
bl_idname = "object.ms_separate_objects"
|
||||
bl_label = "TextureAtlas - Separate Objects"
|
||||
bl_description = "Separates Objects and restores Origin"
|
||||
|
||||
group_name: StringProperty(default='')
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
|
||||
ob_merged = bpy.data.objects.get(self.group_name + "_mergedObject")
|
||||
if ob_merged is not None:
|
||||
|
||||
# if view_layer.objects.active is not None:
|
||||
# bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_merged.hide = False
|
||||
ob_merged.select_set(True)
|
||||
groupSeparate = bpy.data.collections.new(ob_merged.name)
|
||||
groupSeparate.objects.link(ob_merged)
|
||||
ob_merged.select_set(False)
|
||||
|
||||
doUnhidePolygons = False
|
||||
for ms_obj in ob_merged.ms_merged_objects:
|
||||
# select vertex groups and separate group from merged
|
||||
# object
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_merged.select_set(True)
|
||||
view_layer.objects.active = ob_merged
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
if doUnhidePolygons is False:
|
||||
# Unhide Polygons only once
|
||||
bpy.ops.mesh.reveal()
|
||||
doUnhidePolygons = True
|
||||
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
ob_merged.vertex_groups.active_index = ob_merged.vertex_groups[
|
||||
ms_obj.name].index
|
||||
bpy.ops.object.vertex_group_select()
|
||||
bpy.ops.mesh.separate(type='SELECTED')
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
# view_layer.objects.active.select_set(False)
|
||||
|
||||
# find separated object
|
||||
ob_separeted = None
|
||||
for obj in groupSeparate.objects:
|
||||
if obj != ob_merged:
|
||||
ob_separeted = obj
|
||||
break
|
||||
|
||||
# Copy UV Coordinates to the original mesh
|
||||
if ms_obj.name in scene.objects:
|
||||
ob_merged.select_set(False)
|
||||
ob_original = scene.objects[ms_obj.name]
|
||||
isOriginalToSelect = ob_original.hide_select
|
||||
ob_original.hide_select = False
|
||||
ob_original.hide = False
|
||||
ob_original.select_set(True)
|
||||
view_layer.objects.active = ob_separeted
|
||||
bpy.ops.object.join_uvs()
|
||||
ob_original.hide_render = False
|
||||
ob_original.select_set(False)
|
||||
ob_original.hide_select = isOriginalToSelect
|
||||
ob_original.data.update()
|
||||
|
||||
# delete separated object
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_separeted.select_set(True)
|
||||
bpy.ops.object.delete(use_global=False)
|
||||
|
||||
# delete duplicated object
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
ob_merged.select_set(True)
|
||||
bpy.ops.object.delete(use_global=False)
|
||||
|
||||
return{'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_module(__name__)
|
||||
|
||||
bpy.types.Object.ms_merged_objects = CollectionProperty(
|
||||
type=TexAtl_MergedObjects)
|
||||
|
||||
bpy.types.Scene.ms_lightmap_groups = CollectionProperty(
|
||||
type=TexAtl_MSLightmapGroups)
|
||||
|
||||
bpy.types.Scene.ms_lightmap_groups_index = IntProperty()
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_module(__name__)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
Loading…
Reference in New Issue