Page MenuHome

cs_udim_layout_export.py

bl_info = {
"name": "Export Udim Layout",
"category": "UV",
"location": "UV Image Editor > Tools > 'ExportUdim' panel",
"author": "cscholl",
"blender" : (2,80,0),
"version": (1, 0),
}
import bpy
from bpy.props import (StringProperty,
PointerProperty,
IntProperty,
FloatProperty
)
from bpy.types import (Panel,
Operator,
AddonPreferences,
PropertyGroup,
)
# global var
def ShowMessageBox(title="Error", icon='ERROR', lines=""):
myLines=lines
def draw(self, context):
for n in myLines:
self.layout.label(text=n)
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)
# UPDATES ----------------------------------------------------------------------------------------------------------------------------------------------------------------
def compare (self, context):
scene = context.scene
cstool = scene.cs_tool
if cstool.udim_end < cstool.udim_start:
print ("end > start")
cstool.udim_end = cstool.udim_start
return None # always return None from an update.
def gridx (self, context):
scene = context.scene
cstool = scene.cs_tool
bpy.context.space_data.uv_editor.tile_grid_shape[0] = cstool.grid_size_x
return None # always return None from an update.
def gridy (self, context):
scene = context.scene
cstool = scene.cs_tool
bpy.context.space_data.uv_editor.tile_grid_shape[1] = cstool.grid_size_y
return None # always return None from an update.
# PROPERTIES ----------------------------------------------------------------------------------------------------------------------------------------------------------------
class CsProperties(bpy.types.PropertyGroup):
path : StringProperty(
name="Path",
description="Path to Directory",
default="",
maxlen=1024,
subtype='DIR_PATH')
name : StringProperty(
name= "Filename"
)
udim_start: IntProperty (
name="udim start",
description="",
min=1001,
max=1100,
default=1001,
update=compare
)
udim_end: IntProperty (
name="udim end",
description="",
min=1001,
max=1100,
default=1001,
update=compare
)
img_size: IntProperty (
name="Image size",
description="",
default=4096,
min=10,
max=8192
)
opacity: FloatProperty (
name="Opacity",
description="Level of opacity for png files",
min=0,
max=1,
default=0
)
filetype : StringProperty(
name="PNG",
description="",
default="PNG"
)
info : StringProperty(
name="info",
description="",
default="Idle"
)
grid_size_x: IntProperty (
name="udim grid size x",
description="",
default=10,
min=1,
max=10,
update=gridx
)
grid_size_y: IntProperty (
name="udim grid size y",
description="",
default=2,
min=1,
max=10,
update=gridy
)
# PANELS ----------------------------------------------------------------------------------------------------------------------------------------------------------------
class UDIMPanel(bpy.types.Panel):
bl_label = "UDIM Export layout"
bl_idname = "OBJECT_PT_udimpanel"
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
bl_category = "UDIM Export layout"
def draw(self, context):
layout = self.layout
obj = context.object
scene = context.scene
cstool = scene.cs_tool
# forcing the setting of uvmap grid default value
bpy.context.space_data.uv_editor.tile_grid_shape[0] = cstool.grid_size_x
bpy.context.space_data.uv_editor.tile_grid_shape[1] = cstool.grid_size_y
col = layout.column(align=True)
col.prop(cstool, "path", text="Path")
layout.prop(cstool, "name")
layout.prop(cstool, "udim_start")
layout.prop(cstool, "udim_end")
layout.prop(cstool, "img_size")
row = layout.row(align=True)
row.alignment = 'EXPAND'
row.operator("my.button", text="512").resolution=512
row.operator("my.button", text="1k").resolution=1024
row.operator("my.button", text="2k").resolution=2048
row.operator("my.button", text="4k").resolution=4096
row.operator("my.button", text="8k").resolution=8192
layout.prop(cstool, "opacity")
row = layout.row()
row.label(text="File format : " + cstool.filetype , icon='FILE_TICK')
row = layout.row(align=True)
row.alignment = 'EXPAND'
row.operator("my.button", text="svg").filetype="SVG"
row.operator("my.button", text="eps").filetype="EPS"
row.operator("my.button", text="png").filetype="PNG"
layout.prop(cstool, "grid_size_x")
layout.prop(cstool, "grid_size_y")
row = layout.row()
row.label(text=cstool.info , icon='INFO')
layout.operator("uvpanel.csop_export")
class MyOp(bpy.types.Operator): #The operator class derived from Operator
bl_idname="my.button" #Same as in row.operator
bl_label="my.button blabla" #Needed
resolution : bpy.props.IntProperty(
name="")
filetype : bpy.props.StringProperty(
name="")
def execute(self, context):
scene = context.scene
cstool = scene.cs_tool
cstool.img_size = self.resolution
print("Image size set to : " + str(cstool.img_size))
cstool.filetype = self.filetype
print("File format set to : " + str(cstool.filetype))
return {'FINISHED'}
class UVPANEL_OT_cs_opexp(bpy.types.Operator):
bl_label = "Export"
bl_idname = "uvpanel.csop_export"
@classmethod
def description(cls, context, properties):
return "export"
def execute(self, context):
scene = context.scene
cstool = scene.cs_tool
global i,udim,info, oops_text
# check if everything is ok
if cstool.filetype == "":
myLines=("File format type not set !","Clic on the button svg, eps or png to set the format")
ShowMessageBox(lines=myLines)
return {'CANCELLED'}
if cstool.path == "":
myLines=("Filepath not set !","Set a path before exporting")
ShowMessageBox(lines=myLines)
return {'CANCELLED'}
if cstool.name == "":
myLines=("Filename not set !","Set a Filename before exporting")
ShowMessageBox(lines=myLines)
return {'CANCELLED'}
if bpy.context.object.mode != "EDIT":
myLines=("You are not in edit mode !","Set edit mode before exporting")
ShowMessageBox(lines=myLines)
return {'CANCELLED'}
bpy.ops.uv.select_all(action='SELECT')
# used to move the uvmap to the first udim position
transx = cstool.udim_start - 1001
# used to shift the Y if the udim do not start at first line but above
start_shift_y = 0
if transx >= 10:
while transx >= 10:
transx = transx - 10
start_shift_y += 1 # we have to shift Y up to this value
move_y_back = 0 # used to get the y position of the uvmap to its original value
print ("cstool.udim_start : %s - " %cstool.udim_start)
print ("transx : %s" %transx)
print ("transy : %s" %start_shift_y)
# shift x
bpy.ops.transform.translate(value=(-transx, -0, -0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL')
# shift y
bpy.ops.transform.translate(value=(0, -start_shift_y, -0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL')
y = (cstool.udim_start % 100) // 10 # get the tens of the first udim resolution
for i in range (cstool.udim_end - cstool.udim_start + 1):
transx = cstool.udim_start + i
udim_x_pos = transx + i
print ("transx : %s - " %transx + "udim_x_pos : %s" %udim_x_pos)
udim = cstool.udim_start + i
cstool.info = "Processing UDIM " + str(udim)
self.report({'INFO'}, cstool.info)
# used for shifting uvmap down
nexty = ((cstool.udim_start + i - 1)% 100) // 10
# if there's a shift with the tens I move the uvmap down
if nexty != y:
bpy.ops.transform.translate(value=(10, -1, -0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL')
move_y_back += 1
y = nexty
# export
print ("mode : " + str(cstool.filetype))
print ("opacity :" + str(cstool.opacity))
print ("size : " + str(cstool.img_size))
bpy.ops.uv.export_layout(filepath=bpy.path.abspath(cstool.path) + "\\" + cstool.name + "_" + str(udim) , mode = cstool.filetype , opacity = cstool.opacity , size=(cstool.img_size, cstool.img_size))
bpy.ops.transform.translate(value=(-1, -0, -0), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL')
# return uv to their original position
# print ("original x : " + str(cstool.udim_end % 10))
# print ("original y : " + str(move_y_back))
# if it's an udim which unit is ending with 0 we must shift x to 10
if (cstool.udim_end % 10) == 0:
bpy.ops.transform.translate(value=( 10, move_y_back + start_shift_y, -0), orient_type='GLOBAL')
# otherwise we shift x with the unit value
else:
bpy.ops.transform.translate(value=(cstool.udim_end % 10, move_y_back + start_shift_y, -0), orient_type='GLOBAL')
# unselect
bpy.ops.uv.select_all(action='DESELECT')
cstool.info = "Export from " + str(cstool.udim_start) + " to " + str(cstool.udim_end) + " finished"
self.report({'INFO'}, cstool.info)
return {'FINISHED'}
classes = [
UDIMPanel,
UVPANEL_OT_cs_opexp,
CsProperties,
MyOp
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.cs_tool = bpy.props.PointerProperty(type= CsProperties)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
bpy.types.Scene.cs_tool
if __name__ == "__main__":
register()

File Metadata

Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a5/d5/d991dfe5ef9f960944740af63b55

Event Timeline