blender does support multi-object edit mode and unwrapping.
the uvmap handling did not yet support it.
I wrote these very useful operators below, and want to donate its code.
would someone please add it to the code base ?
almost all you have to do:
copy the code into scripts/startup/bl_ui/properties_data_mesh.py
and register the classes (see below).
thank you!
new operators (multi object):
add a uvmap to all selected objects
dis-/activate them (use selection)
delete uvmap from selected objects
CODE:
"""
# add script to file:
# scripts/startup/bl_ui/properties_data_mesh.py
# note:
# do not forget to register classes, at end of file:
classes += classes_MESH_uvmap
###########################################################
# for the context menu (dropdown in data panel, uvmap section), add this line:
col.menu( 'MESH_MT_uvmap_context_menu', icon='DOWNARROW_HLT', text='' )
# to **draw function** of
class DATA_PT_uv_texture
#############################################################
# 2021-11 by Emanuel Rumpf, em-rumpf[AT]gmx.de
########## optional: move operators to: scripts/startup/bl_operators/mesh.py
########## optional: instead create new file: scripts/startup/bl_operators/uvmap_operators.py
"""
class MESH_MT_uvmap_context_menu(Menu):
'''
adds the context menu for the uvmap-section in data-panel. (properties_data_mesh.py)
'''
bl_label = "uvmap - special functions (applied to selection)"
bl_idname = 'MESH_MT_uvmap_context_menu'
def draw(self, _context):
layout = self.layout
layout.label( text='uvmap - special functions (applied to selection)' )
layout.separator()
layout.operator( 'selection.uvmap_add_to_selected' , icon='ADD' )
layout.operator( 'selection.uvmap_change_active_states' , icon='OUTLINER_DATA_FONT' )
layout.operator( 'selection.uvmap_delete_from_selected' , icon='X' )
#
#end class: MESH_MT_uvmap_context_menu
class MESH_OT_uvmap_change_active_states(bpy.types.Operator):
bl_idname = "selection.uvmap_change_active_states"
bl_label = "Change active-state or active_render of named uvmap"
uv_set_active: bpy.props.BoolProperty(name="Activate uvmap", default=True)
uv_set_render: bpy.props.BoolProperty(name="Activate for rendering", default=False)
uv_new_name: bpy.props.StringProperty(name="UV map name", default="new map.01")
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
col = layout.column()
#col.label(text="Add new UV maps to selected objects")
row = col.row()
#row.prop(self, "my_float")
row.prop(self, "uv_set_active")
row.prop(self, "uv_set_render")
col.prop(self, "uv_new_name")
def execute(self, context):
#
AA = bool( self.uv_set_active )
RR = bool( self.uv_set_render )
#
self .FUNC_uvmap_change_active_states( context , self.uv_new_name , make_active=AA , active_for_render=RR )
return {'FINISHED'}
@staticmethod
def FUNC_uvmap_change_active_states( context, uvmap_name, make_active=True, active_for_render=False ):
'''
(class independent function)
change the active-state of the named uvmap for all selected objects.
'''
# 2021-11 by Emanuel Rumpf, em-rumpf[AT]gmx.de
slc = context.selected_objects
#print( 'called: FUNC_change_uv_active_state_for_selected. count of selected obs: ', str(len(slc)) )
#
success = True
#
for obj in slc:
#
dt = obj.data
## remove same_name
try: uvlay = dt.uv_layers[uvmap_name]
except: uvlay = None
#
if uvlay is None:
print( f'Warning: uvmap with name: {uvmap_name} does not exist for object: {obj.name} -- FUNC_uvmap_change_active_states()')
success = False
else:
uvlay.active_render = True if active_for_render else False
uvlay.active = True if make_active else False
#
#
#end for
#
wm = context.window_manager
#
if success:
def draw_message( popup, context):
popup.layout.label( text='' )
wm.popup_menu( draw_message, title='success', icon='INFO' )
else:
def draw_message( popup, context):
popup.layout.label( text='' )
wm.popup_menu( draw_message, title='failed, see console message', icon='ERROR' )
#
#
#end class: MESH_OT_uvmap_change_active_states
class MESH_OT_uvmap_delete_from_selected(bpy.types.Operator):
bl_idname = "selection.uvmap_delete_from_selected"
bl_label = "Delete a uvmap by name, from all selected objects"
#filepath: bpy.props.StringProperty(subtype="FILE_PATH")
uv_new_name: bpy.props.StringProperty(name="UV map name", default="new map.01")
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
col = layout.column()
#col.label(text="Add new UV maps to selected objects")
row = col.row()
#row.prop(self, "my_float")
row.prop(self, "uv_set_active")
row.prop(self, "uv_set_render")
col.prop(self, "uv_new_name")
def execute(self, context):
#
self .FUNC_uvmap_delete_from_selected( context , self.uv_new_name )
return {'FINISHED'}
#
@staticmethod
def FUNC_uvmap_delete_from_selected( ctx, uvmap_name ):
'''
(class independent function)
delete the uvmap with given name, from all selected objects.
'''
# 2021-11 by Emanuel Rumpf, em-rumpf[AT]gmx.de
slc = ctx.selected_objects
#print( 'called: FUNC_change_uv_active_state_for_selected. count of selected obs: ', str(len(slc)) )
#
for obj in slc:
#
dt = obj.data
## remove same_name
try: uvlay = dt.uv_layers[uvmap_name]
except: uvlay = None
#
if uvlay is None:
print( f'Warning: uvmap with name: {uvmap_name} does not exist for object: {obj.name} -- FUNC_uvmap_delete_from_selected()')
else:
dt.uv_layers.remove( uvlay )
#
#
#end for
#
#end class: MESH_OT_uvmap_delete_from_selected
class MESH_OT_uvmap_add_to_selected(bpy.types.Operator):
bl_idname = "selection.uvmap_add_to_selected"
bl_label = "Add a new UV map to all selected objects" # note: replaces uvmap with equal name
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
#my_float: bpy.props.FloatProperty(name="Float")
uv_set_active: bpy.props.BoolProperty(name="Activate new UV map", default=True)
uv_set_render: bpy.props.BoolProperty(name="Activate for rendering", default=False)
uv_new_name: bpy.props.StringProperty(name="UV map name", default="new map.01")
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
col = layout.column()
#col.label(text="Add new UV maps to selected objects")
row = col.row()
#row.prop(self, "my_float")
row.prop(self, "uv_set_active")
row.prop(self, "uv_set_render")
col.prop(self, "uv_new_name")
def execute(self, context):
#print( 'OT__add_uv_maps_to_selected - calles: FUNC_add_uvmaps_to_selected.', self)
#print( ' new UV name: ', self.uv_new_name )
#print( ' set active: ', self.uv_set_active )
#print( ' set render: ', self.uv_set_render )
#
self .FUNC_uvmap_add_to_selected( context , self.uv_new_name , make_active=self.uv_set_active , active_for_render=self.uv_set_render )
return {'FINISHED'}
@staticmethod
def FUNC_uvmap_add_to_selected( ctx, uvmap_name, make_active=True, active_for_render=False ):
'''
(class independent function)
adds a uv-map with name to each selected object and makes it active (or not)
--
example call:
FUNC_add_uvmaps_to_selected( bpy.context , 'atlas.a1' , make_active=True , replace_same_name=True )
'''
# 2021-11 by Emanuel Rumpf, em-rumpf[AT]gmx.de
slc = ctx.selected_objects
#print( 'called: FUNC_add_uvmaps_to_selected. count of selected obs: ', str(len(slc)) )
#print( 'len: ', len(slc) )
#
for obj in slc:
#
dt = obj.data
#print( ' FUNC_add_uvmaps_to_selected: iterated.name: ', obj.name )
## remove same_name
try: uvold = dt.uv_layers[uvmap_name]
except: uvold = None
if uvold is not None:
#print( ' FUNC_add_uvmaps_to_selected: uv_map with name exists - replacing' )
dt.uv_layers.remove( uvold )
#
#
uvnew = dt.uv_layers .new( name=uvmap_name, do_init=True ) # do_init: copy active uv map
if uvnew is None:
print( f'Warning: : creating uvmap failed. uvnew is None for obj_name: {obj.name} -- FUNC_uvmap_add_to_selected' )
continue
#
uvnew.active_render = True if active_for_render else False
uvnew.active = True if make_active else False
#
#end for
#
#end class: MESH_OT_uvmap_add_to_selected
#
## classes list for MESH_uvmap handling
classes_MESH_uvmap = (
MESH_OT_uvmap_change_active_states,
MESH_OT_uvmap_delete_from_selected,
MESH_OT_uvmap_add_to_selected,
MESH_MT_uvmap_context_menu,
)
#end of code