diff options
Diffstat (limited to 'io_import_gimp_image_to_scene.py')
-rw-r--r-- | io_import_gimp_image_to_scene.py | 1236 |
1 files changed, 618 insertions, 618 deletions
diff --git a/io_import_gimp_image_to_scene.py b/io_import_gimp_image_to_scene.py index bdd4552e..32b57b85 100644 --- a/io_import_gimp_image_to_scene.py +++ b/io_import_gimp_image_to_scene.py @@ -17,517 +17,517 @@ # ##### END GPL LICENSE BLOCK ##### bl_addon_info = { - "name": "Import GIMP Image to Scene (.xcf, .xjt)", - "author": "Daniel Salazar (ZanQdo)", - "version": (2,0,0), - "blender": (2, 5, 5), - "api": 33419, - "location": "File > Import > GIMP Image to Scene(.xcf, .xjt)", - "description": "Imports GIMP multilayer image files into 3D Layers", - "warning": "XCF import requires xcftools installed", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ - "Scripts/File_I-O/GIMPImageToScene", - "tracker_url": "http://projects.blender.org/tracker/index.php?"\ - "func=detail&aid=25136&group_id=153&atid=469", - "category": "Import/Export"} + "name": "Import GIMP Image to Scene (.xcf, .xjt)", + "author": "Daniel Salazar (ZanQdo)", + "version": (2, 0, 0), + "blender": (2, 5, 5), + "api": 33419, + "location": "File > Import > GIMP Image to Scene(.xcf, .xjt)", + "description": "Imports GIMP multilayer image files into 3D Layers", + "warning": "XCF import requires xcftools installed", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ + "Scripts/Import-Export/GIMPImageToScene", + "tracker_url": "http://projects.blender.org/tracker/index.php?"\ + "func=detail&aid=25136&group_id=153&atid=469", + "category": "Import-Export"} """ This script imports GIMP layered image files into 3D Scenes (.xcf, .xjt) """ def main(File, Path, LayerViewers, MixerViewers, LayerOffset,\ - LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ - SetCamera, SetupCompo, GroupUntagged, Ext): - - #------------------------------------------------- - - #Folder = '['+File.rstrip(Ext)+']'+'_images/' - Folder = 'images_'+'['+File.rstrip(Ext)+']/' - - if bpy.data.is_dirty: - PathSaveRaw = Path+Folder - PathSave = PathSaveRaw.replace(' ', '\ ') - try: os.mkdir(PathSaveRaw) - except: pass - else: - PathSave = bpy.data.filepath - RSlash = PathSave.rfind('/') - PathSaveRaw = PathSave[:RSlash+1]+Folder - PathSave = PathSaveRaw.replace(' ', '\ ') - try: os.mkdir(PathSaveRaw) - except: pass - PathSaveRaw = bpy.path.relpath(PathSaveRaw)+'/' - - PathRaw = Path - Path = Path.replace(' ', '\ ') - if Ext == '.xjt': - ExtSave = '.jpg' - #------------------------------------------------- - # EXTRACT XJT - import tarfile - - IMG = tarfile.open ('%s%s' % (PathRaw, File)) - PRP = IMG.extractfile('PRP') - - Members = IMG.getmembers() - - for Member in Members: - Name = Member.name - if Name.startswith('l') and Name.endswith('.jpg'): - IMG.extract(Name, path=PathSaveRaw) - - #------------------------------------------------- - # INFO XJT - IMGs = [] - for Line in PRP.readlines(): - Line = str(Line) - - if Line.startswith("b'GIMP_XJ_IMAGE"): - for Segment in Line.split(): - if Segment.startswith('w/h:'): - ResX, ResY = map (int, Segment[4:].split(',')) - if Line.startswith("b'L") or Line.startswith("b'l"): - - if Line.startswith("b'L"): HasAlpha = True - else: HasAlpha = False - - md = None - op = 1 - ox, oy = 0,0 - - for Segment in Line.split(): - - if Segment.startswith("b'"): - imageFile = 'l' + Segment[3:] + '.jpg' - imageFileAlpha ='la'+Segment[3:]+'.jpg' - - # Get Widht and Height from images - data = open(PathSaveRaw+imageFile, "rb").read() - - hexList = [] - for ch in data: - byt = "%02X" % ch - hexList.append(byt) - - for k in range(len(hexList)-1): - if hexList[k] == 'FF' and (hexList[k+1] == 'C0' or hexList[k+1] == 'C2'): - ow = int(hexList[k+7],16)*256 + int(hexList[k+8],16) - oh = int(hexList[k+5],16)*256 + int(hexList[k+6],16) - - elif Segment.startswith('md:'): # mode - md = Segment[3:] - - elif Segment.startswith('op:'): # opacity - op = float(Segment[3:])*.01 - - elif Segment.startswith('o:'): # origin - ox, oy = map(int, Segment[2:].split(',')) - - elif Segment.startswith('n:'): # name - n = Segment[3:-4] - OpenBracket = n.find ('[') - CloseBracket = n.find (']') - - if OpenBracket != -1 and CloseBracket != -1: - RenderLayer = n[OpenBracket+1:CloseBracket] - NameShort = n[:OpenBracket] - - else: - RenderLayer = n - NameShort = n - - os.rename(PathSaveRaw+imageFile, PathSaveRaw+NameShort+'.jpg') - if HasAlpha: os.rename(PathSaveRaw+imageFileAlpha, PathSaveRaw+NameShort+'_A'+'.jpg') - - IMGs.append({'LayerMode':md, 'LayerOpacity':op,\ - 'LayerName':n, 'LayerNameShort':NameShort,\ - 'RenderLayer':RenderLayer, 'LayerCoords':[ow, oh, ox, oy], 'HasAlpha':HasAlpha}) - - else: # Ext == '.xcf': - ExtSave = '.png' - #------------------------------------------------- - # CONFIG - XCFInfo = 'xcfinfo' - XCF2PNG = 'xcf2png' - #------------------------------------------------- - # INFO XCF - - CMD = '%s %s%s' % (XCFInfo, Path, File) - - Info = os.popen(CMD) - - IMGs = [] - for Line in Info.readlines(): - if Line.startswith ('+'): - - Line = Line.split(' ', 4) - - RenderLayer = Line[4] - - OpenBracket = RenderLayer.find ('[') - CloseBracket = RenderLayer.find (']') - - if OpenBracket != -1 and CloseBracket != -1: - RenderLayer = RenderLayer[OpenBracket+1:CloseBracket] - NameShort = Line[4][:OpenBracket] - else: - NameShort = Line[4].rstrip() - if GroupUntagged: - RenderLayer = '__Undefined__' - else: - RenderLayer = NameShort - - LineThree = Line[3] - Slash = LineThree.find('/') - if Slash == -1: - Mode = LineThree - Opacity = 1 - else: - Mode = LineThree[:Slash] - Opacity = float(LineThree[Slash+1:LineThree.find('%')])*.01 - - IMGs.append ({\ - 'LayerMode':Mode,\ - 'LayerOpacity':Opacity,\ - 'LayerName':Line[4].rstrip(),\ - 'LayerNameShort':NameShort,\ - 'LayerCoords':list(map(int, Line[1].replace('x', ' ').replace('+', ' +').replace('-', ' -').split())),\ - 'RenderLayer':RenderLayer,\ - 'HasAlpha':True,\ - }) - elif Line.startswith('Version'): - ResX, ResY = map (int, Line.split()[2].split('x')) - - #------------------------------------------------- - # EXTRACT XCF - if OpacityMode == 'BAKE': - Opacity = '' - else: - Opacity = ' --percent 100' - for Layer in IMGs: - CMD = '%s -C %s%s -o %s%s.png "%s"%s' %\ - (XCF2PNG, Path, File, PathSave, Layer['LayerName'].replace(' ', '_'), Layer['LayerName'], Opacity) - os.system(CMD) - - #------------------------------------------------- - Scene = bpy.context.scene - #------------------------------------------------- - # CAMERA - - if SetCamera: - bpy.ops.object.camera_add(location=(0, 0, 10)) - - Camera = bpy.context.active_object.data - - Camera.type = 'ORTHO' - Camera.ortho_scale = ResX * .01 - - #------------------------------------------------- - # RENDER SETTINGS - - Render = Scene.render - - if SetCamera: - Render.resolution_x = ResX - Render.resolution_y = ResY - Render.resolution_percentage = 100 - if PremulAlpha: Render.alpha_mode = 'PREMUL' - - #------------------------------------------------- - # 3D VIEW SETTINGS - - Scene.game_settings.material_mode = 'GLSL' - - Areas = bpy.context.screen.areas - - for Area in Areas: - if Area.type == 'VIEW_3D': - Area.active_space.viewport_shade = 'TEXTURED' - Area.active_space.show_textured_solid = True - Area.active_space.show_floor = False - - #------------------------------------------------- - # 3D LAYERS - - def Make3DLayer (Name, NameShort, Z, Coords, RenderLayer, LayerMode, LayerOpacity, HasAlpha): - - # RenderLayer - - if SetupCompo: - if not bpy.context.scene.render.layers.get(RenderLayer): - - bpy.ops.scene.render_layer_add() - - LayerActive = bpy.context.scene.render.layers.active - LayerActive.name = RenderLayer - LayerActive.use_pass_vector = True - LayerActive.use_sky = False - LayerActive.use_edge_enhance = False - LayerActive.use_strand = False - LayerActive.use_halo = False - - global LayerNum - for i in range (0,20): - if not i == LayerNum: - LayerActive.layers[i] = False - - bpy.context.scene.layers[LayerNum] = True - - LayerFlags[RenderLayer] = bpy.context.scene.render.layers.active.layers - - LayerList.append([RenderLayer, LayerMode, LayerOpacity]) - - LayerNum += 1 - - # Object - bpy.ops.mesh.primitive_plane_add(\ - view_align=False,\ - enter_editmode=False,\ - rotation=(0, 0, pi)) - - bpy.ops.object.rotation_apply() - - Active = bpy.context.active_object - - if SetupCompo: - Active.layers = LayerFlags[RenderLayer] - - Active.location = (\ - (float(Coords[2])-(ResX*0.5))*LayerScale,\ - (-float(Coords[3])+(ResY*0.5))*LayerScale, Z) - - for Vert in Active.data.vertices: - Vert.co[0] += 1 - Vert.co[1] += -1 - - Active.dimensions = float(Coords[0])*LayerScale, float(Coords[1])*LayerScale, 0 - - bpy.ops.object.scale_apply() - - bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN') - - Active.show_wire = True - - Active.name = NameShort - bpy.ops.mesh.uv_texture_add() - - # Material - - '''if bpy.data.materials.get(NameShort): - Mat = bpy.data.materials[NameShort] - if not Active.material_slots: - bpy.ops.object.material_slot_add() - Active.material_slots[0].material = Mat - else:''' - - Mat = bpy.data.materials.new(NameShort) - Mat.diffuse_color = (1,1,1) - Mat.use_raytrace = False - Mat.use_shadows = False - Mat.use_cast_buffer_shadows = False - Mat.use_cast_approximate = False - if HasAlpha: - Mat.use_transparency = True - if OpacityMode == 'MAT': Mat.alpha = LayerOpacity - else: Mat.alpha = 0 - if ShadelessMats: Mat.use_shadeless = True - - if Ext == '.xcf': - # Color & Alpha PNG - Tex = bpy.data.textures.new(NameShort, 'IMAGE') - Tex.extension = 'CLIP' - Tex.use_preview_alpha = True - - Img = bpy.data.images.new(NameShort) - Img.source = 'FILE' - if PremulAlpha: Img.use_premultiply = True - Img.filepath = '%s%s%s' % (PathSaveRaw, Name, ExtSave) - - UVFace = Active.data.uv_textures[0].data[0] - UVFace.image = Img - UVFace.use_image = True - - Tex.image = Img - - Mat.texture_slots.add() - TexSlot = Mat.texture_slots[0] - TexSlot.texture = Tex - TexSlot.use_map_alpha = True - TexSlot.texture_coords = 'UV' - if OpacityMode == 'TEX': TexSlot.alpha_factor = LayerOpacity - elif OpacityMode == 'MAT': TexSlot.blend_type = 'MULTIPLY' - - else: # Ext == '.xjt' - # Color JPG - Tex = bpy.data.textures.new(NameShort, 'IMAGE') - Tex.extension = 'CLIP' - - Img = bpy.data.images.new(NameShort) - Img.source = 'FILE' - Img.filepath = '%s%s%s' % (PathSaveRaw, Name, ExtSave) - - UVFace = Active.data.uv_textures[0].data[0] - UVFace.image = Img - UVFace.use_image = True - - Tex.image = Img - - Mat.texture_slots.add() - TexSlot = Mat.texture_slots[0] - TexSlot.texture = Tex - TexSlot.texture_coords = 'UV' - - if HasAlpha: - # Alpha JPG - Tex = bpy.data.textures.new(NameShort+'_A', 'IMAGE') - Tex.extension = 'CLIP' - Tex.use_preview_alpha = True - Tex.use_alpha = False - - Img = bpy.data.images.new(NameShort+'_A') - Img.source = 'FILE' - if PremulAlpha: Img.use_premultiply = True - Img.filepath = '%s%s_A%s' % (PathSaveRaw, Name, ExtSave) - - Tex.image = Img - - Mat.texture_slots.add() - TexSlot = Mat.texture_slots[1] - TexSlot.texture = Tex - TexSlot.use_map_alpha = True - TexSlot.use_map_color_diffuse = False - TexSlot.texture_coords = 'UV' - if OpacityMode == 'TEX': TexSlot.alpha_factor = LayerOpacity - elif OpacityMode == 'MAT': TexSlot.blend_type = 'MULTIPLY' - - if not Active.material_slots: - bpy.ops.object.material_slot_add() - - Active.material_slots[0].material = Mat + LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ + SetCamera, SetupCompo, GroupUntagged, Ext): + + #------------------------------------------------- + + #Folder = '['+File.rstrip(Ext)+']'+'_images/' + Folder = 'images_'+'['+File.rstrip(Ext)+']/' + + if bpy.data.is_dirty: + PathSaveRaw = Path+Folder + PathSave = PathSaveRaw.replace(' ', '\ ') + try: os.mkdir(PathSaveRaw) + except: pass + else: + PathSave = bpy.data.filepath + RSlash = PathSave.rfind('/') + PathSaveRaw = PathSave[:RSlash+1]+Folder + PathSave = PathSaveRaw.replace(' ', '\ ') + try: os.mkdir(PathSaveRaw) + except: pass + PathSaveRaw = bpy.path.relpath(PathSaveRaw)+'/' + + PathRaw = Path + Path = Path.replace(' ', '\ ') + if Ext == '.xjt': + ExtSave = '.jpg' + #------------------------------------------------- + # EXTRACT XJT + import tarfile + + IMG = tarfile.open ('%s%s' % (PathRaw, File)) + PRP = IMG.extractfile('PRP') + + Members = IMG.getmembers() + + for Member in Members: + Name = Member.name + if Name.startswith('l') and Name.endswith('.jpg'): + IMG.extract(Name, path=PathSaveRaw) + + #------------------------------------------------- + # INFO XJT + IMGs = [] + for Line in PRP.readlines(): + Line = str(Line) + + if Line.startswith("b'GIMP_XJ_IMAGE"): + for Segment in Line.split(): + if Segment.startswith('w/h:'): + ResX, ResY = map (int, Segment[4:].split(',')) + if Line.startswith("b'L") or Line.startswith("b'l"): + + if Line.startswith("b'L"): HasAlpha = True + else: HasAlpha = False + + md = None + op = 1 + ox, oy = 0,0 + + for Segment in Line.split(): + + if Segment.startswith("b'"): + imageFile = 'l' + Segment[3:] + '.jpg' + imageFileAlpha ='la'+Segment[3:]+'.jpg' + + # Get Widht and Height from images + data = open(PathSaveRaw+imageFile, "rb").read() + + hexList = [] + for ch in data: + byt = "%02X" % ch + hexList.append(byt) + + for k in range(len(hexList)-1): + if hexList[k] == 'FF' and (hexList[k+1] == 'C0' or hexList[k+1] == 'C2'): + ow = int(hexList[k+7],16)*256 + int(hexList[k+8],16) + oh = int(hexList[k+5],16)*256 + int(hexList[k+6],16) + + elif Segment.startswith('md:'): # mode + md = Segment[3:] + + elif Segment.startswith('op:'): # opacity + op = float(Segment[3:])*.01 + + elif Segment.startswith('o:'): # origin + ox, oy = map(int, Segment[2:].split(',')) + + elif Segment.startswith('n:'): # name + n = Segment[3:-4] + OpenBracket = n.find ('[') + CloseBracket = n.find (']') + + if OpenBracket != -1 and CloseBracket != -1: + RenderLayer = n[OpenBracket+1:CloseBracket] + NameShort = n[:OpenBracket] + + else: + RenderLayer = n + NameShort = n + + os.rename(PathSaveRaw+imageFile, PathSaveRaw+NameShort+'.jpg') + if HasAlpha: os.rename(PathSaveRaw+imageFileAlpha, PathSaveRaw+NameShort+'_A'+'.jpg') + + IMGs.append({'LayerMode':md, 'LayerOpacity':op,\ + 'LayerName':n, 'LayerNameShort':NameShort,\ + 'RenderLayer':RenderLayer, 'LayerCoords':[ow, oh, ox, oy], 'HasAlpha':HasAlpha}) + + else: # Ext == '.xcf': + ExtSave = '.png' + #------------------------------------------------- + # CONFIG + XCFInfo = 'xcfinfo' + XCF2PNG = 'xcf2png' + #------------------------------------------------- + # INFO XCF + + CMD = '%s %s%s' % (XCFInfo, Path, File) + + Info = os.popen(CMD) + + IMGs = [] + for Line in Info.readlines(): + if Line.startswith ('+'): + + Line = Line.split(' ', 4) + + RenderLayer = Line[4] + + OpenBracket = RenderLayer.find ('[') + CloseBracket = RenderLayer.find (']') + + if OpenBracket != -1 and CloseBracket != -1: + RenderLayer = RenderLayer[OpenBracket+1:CloseBracket] + NameShort = Line[4][:OpenBracket] + else: + NameShort = Line[4].rstrip() + if GroupUntagged: + RenderLayer = '__Undefined__' + else: + RenderLayer = NameShort + + LineThree = Line[3] + Slash = LineThree.find('/') + if Slash == -1: + Mode = LineThree + Opacity = 1 + else: + Mode = LineThree[:Slash] + Opacity = float(LineThree[Slash+1:LineThree.find('%')])*.01 + + IMGs.append ({\ + 'LayerMode':Mode,\ + 'LayerOpacity':Opacity,\ + 'LayerName':Line[4].rstrip(),\ + 'LayerNameShort':NameShort,\ + 'LayerCoords':list(map(int, Line[1].replace('x', ' ').replace('+', ' +').replace('-', ' -').split())),\ + 'RenderLayer':RenderLayer,\ + 'HasAlpha':True,\ + }) + elif Line.startswith('Version'): + ResX, ResY = map (int, Line.split()[2].split('x')) + + #------------------------------------------------- + # EXTRACT XCF + if OpacityMode == 'BAKE': + Opacity = '' + else: + Opacity = ' --percent 100' + for Layer in IMGs: + CMD = '%s -C %s%s -o %s%s.png "%s"%s' %\ + (XCF2PNG, Path, File, PathSave, Layer['LayerName'].replace(' ', '_'), Layer['LayerName'], Opacity) + os.system(CMD) + + #------------------------------------------------- + Scene = bpy.context.scene + #------------------------------------------------- + # CAMERA + + if SetCamera: + bpy.ops.object.camera_add(location=(0, 0, 10)) + + Camera = bpy.context.active_object.data + + Camera.type = 'ORTHO' + Camera.ortho_scale = ResX * .01 + + #------------------------------------------------- + # RENDER SETTINGS + + Render = Scene.render + + if SetCamera: + Render.resolution_x = ResX + Render.resolution_y = ResY + Render.resolution_percentage = 100 + if PremulAlpha: Render.alpha_mode = 'PREMUL' + + #------------------------------------------------- + # 3D VIEW SETTINGS + + Scene.game_settings.material_mode = 'GLSL' + + Areas = bpy.context.screen.areas + + for Area in Areas: + if Area.type == 'VIEW_3D': + Area.active_space.viewport_shade = 'TEXTURED' + Area.active_space.show_textured_solid = True + Area.active_space.show_floor = False + + #------------------------------------------------- + # 3D LAYERS + + def Make3DLayer (Name, NameShort, Z, Coords, RenderLayer, LayerMode, LayerOpacity, HasAlpha): + + # RenderLayer + + if SetupCompo: + if not bpy.context.scene.render.layers.get(RenderLayer): + + bpy.ops.scene.render_layer_add() + + LayerActive = bpy.context.scene.render.layers.active + LayerActive.name = RenderLayer + LayerActive.use_pass_vector = True + LayerActive.use_sky = False + LayerActive.use_edge_enhance = False + LayerActive.use_strand = False + LayerActive.use_halo = False + + global LayerNum + for i in range (0,20): + if not i == LayerNum: + LayerActive.layers[i] = False + + bpy.context.scene.layers[LayerNum] = True + + LayerFlags[RenderLayer] = bpy.context.scene.render.layers.active.layers + + LayerList.append([RenderLayer, LayerMode, LayerOpacity]) + + LayerNum += 1 + + # Object + bpy.ops.mesh.primitive_plane_add(\ + view_align=False,\ + enter_editmode=False,\ + rotation=(0, 0, pi)) + + bpy.ops.object.rotation_apply() + + Active = bpy.context.active_object + + if SetupCompo: + Active.layers = LayerFlags[RenderLayer] + + Active.location = (\ + (float(Coords[2])-(ResX*0.5))*LayerScale,\ + (-float(Coords[3])+(ResY*0.5))*LayerScale, Z) + + for Vert in Active.data.vertices: + Vert.co[0] += 1 + Vert.co[1] += -1 + + Active.dimensions = float(Coords[0])*LayerScale, float(Coords[1])*LayerScale, 0 + + bpy.ops.object.scale_apply() + + bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN') + + Active.show_wire = True + + Active.name = NameShort + bpy.ops.mesh.uv_texture_add() + + # Material + + '''if bpy.data.materials.get(NameShort): + Mat = bpy.data.materials[NameShort] + if not Active.material_slots: + bpy.ops.object.material_slot_add() + Active.material_slots[0].material = Mat + else:''' + + Mat = bpy.data.materials.new(NameShort) + Mat.diffuse_color = (1,1,1) + Mat.use_raytrace = False + Mat.use_shadows = False + Mat.use_cast_buffer_shadows = False + Mat.use_cast_approximate = False + if HasAlpha: + Mat.use_transparency = True + if OpacityMode == 'MAT': Mat.alpha = LayerOpacity + else: Mat.alpha = 0 + if ShadelessMats: Mat.use_shadeless = True + + if Ext == '.xcf': + # Color & Alpha PNG + Tex = bpy.data.textures.new(NameShort, 'IMAGE') + Tex.extension = 'CLIP' + Tex.use_preview_alpha = True + + Img = bpy.data.images.new(NameShort) + Img.source = 'FILE' + if PremulAlpha: Img.use_premultiply = True + Img.filepath = '%s%s%s' % (PathSaveRaw, Name, ExtSave) + + UVFace = Active.data.uv_textures[0].data[0] + UVFace.image = Img + UVFace.use_image = True + + Tex.image = Img + + Mat.texture_slots.add() + TexSlot = Mat.texture_slots[0] + TexSlot.texture = Tex + TexSlot.use_map_alpha = True + TexSlot.texture_coords = 'UV' + if OpacityMode == 'TEX': TexSlot.alpha_factor = LayerOpacity + elif OpacityMode == 'MAT': TexSlot.blend_type = 'MULTIPLY' + + else: # Ext == '.xjt' + # Color JPG + Tex = bpy.data.textures.new(NameShort, 'IMAGE') + Tex.extension = 'CLIP' + + Img = bpy.data.images.new(NameShort) + Img.source = 'FILE' + Img.filepath = '%s%s%s' % (PathSaveRaw, Name, ExtSave) + + UVFace = Active.data.uv_textures[0].data[0] + UVFace.image = Img + UVFace.use_image = True + + Tex.image = Img + + Mat.texture_slots.add() + TexSlot = Mat.texture_slots[0] + TexSlot.texture = Tex + TexSlot.texture_coords = 'UV' + + if HasAlpha: + # Alpha JPG + Tex = bpy.data.textures.new(NameShort+'_A', 'IMAGE') + Tex.extension = 'CLIP' + Tex.use_preview_alpha = True + Tex.use_alpha = False + + Img = bpy.data.images.new(NameShort+'_A') + Img.source = 'FILE' + if PremulAlpha: Img.use_premultiply = True + Img.filepath = '%s%s_A%s' % (PathSaveRaw, Name, ExtSave) + + Tex.image = Img + + Mat.texture_slots.add() + TexSlot = Mat.texture_slots[1] + TexSlot.texture = Tex + TexSlot.use_map_alpha = True + TexSlot.use_map_color_diffuse = False + TexSlot.texture_coords = 'UV' + if OpacityMode == 'TEX': TexSlot.alpha_factor = LayerOpacity + elif OpacityMode == 'MAT': TexSlot.blend_type = 'MULTIPLY' + + if not Active.material_slots: + bpy.ops.object.material_slot_add() + + Active.material_slots[0].material = Mat - Z = 0 - global LayerNum - LayerNum = 0 - LayerFlags = {} - LayerList = [] - - for Layer in IMGs: - Make3DLayer(\ - Layer['LayerName'].replace(' ', '_'),\ - Layer['LayerNameShort'].replace(' ', '_'),\ - Z,\ - Layer['LayerCoords'],\ - Layer['RenderLayer'],\ - Layer['LayerMode'],\ - Layer['LayerOpacity'],\ - Layer['HasAlpha'],\ - ) - - Z -= LayerOffset - - if SetupCompo: - #------------------------------------------------- - # COMPO NODES - - Scene.use_nodes = True - - Tree = Scene.node_tree - - for i in Tree.nodes: - Tree.nodes.remove(i) - - LayerList.reverse() - - Offset = 0 - LayerLen = len(LayerList) - - for Layer in LayerList: - - Offset += 1 - - X_Offset = (500*Offset) - Y_Offset = (-300*Offset) - - Node = Tree.nodes.new('R_LAYERS') - Node.location = (-500+X_Offset, 300+Y_Offset) - Node.name = 'R_'+ str(Offset) - Node.scene = Scene - Node.layer = Layer[0] - - if LayerViewers: - Node_V = Tree.nodes.new('VIEWER') - Node_V.name = Layer[0] - Node_V.location = (-200+X_Offset, 200+Y_Offset) - - Tree.links.new(Node.outputs[0], Node_V.inputs[0]) - - if LayerLen > Offset: - - Mode = LayerList[Offset][1] # has to go one step further - LayerOpacity = LayerList[Offset][2] - - if not Mode in ('Normal', '-1'): - - Node = Tree.nodes.new('MIX_RGB') - if OpacityMode == 'COMPO': Node.inputs['Fac'].default_value[0] = LayerOpacity - else: Node.inputs['Fac'].default_value[0] = 1 - Node.use_alpha = True - - if Mode in ('Addition', '7'): Node.blend_type = 'ADD' - elif Mode in ('Subtract', '8'): Node.blend_type = 'SUBTRACT' - elif Mode in ('Multiply', '3'): Node.blend_type = 'MULTIPLY' - elif Mode in ('DarkenOnly', '9'): Node.blend_type = 'DARKEN' - elif Mode in ('Dodge', '16'): Node.blend_type = 'DODGE' - elif Mode in ('LightenOnly', '10'): Node.blend_type = 'LIGHTEN' - elif Mode in ('Difference', '6'): Node.blend_type = 'DIFFERENCE' - elif Mode in ('Divide', '15'): Node.blend_type = 'DIVIDE' - elif Mode in ('Overlay', '5'): Node.blend_type = 'OVERLAY' - elif Mode in ('Screen', '4'): Node.blend_type = 'SCREEN' - elif Mode in ('Burn', '17'): Node.blend_type = 'BURN' - elif Mode in ('Color', '13'): Node.blend_type = 'COLOR' - elif Mode in ('Value', '14'): Node.blend_type = 'VALUE' - elif Mode in ('Saturation', '12'): Node.blend_type = 'SATURATION' - elif Mode in ('Hue', '11'): Node.blend_type = 'HUE' - elif Mode in ('Softlight', '19'): Node.blend_type = 'SOFT_LIGHT' - else: pass - - else: - Node = Tree.nodes.new('ALPHAOVER') - if OpacityMode == 'COMPO': Node.inputs['Fac'].default_value[0] = LayerOpacity - Node.name = 'M_' + str(Offset) - Node.location = (300+X_Offset, 250+Y_Offset) - - if MixerViewers: - Node_V = Tree.nodes.new('VIEWER') - Node_V.name = Layer[0] - Node_V.location = (500+X_Offset, 350+Y_Offset) - - Tree.links.new(Node.outputs[0], Node_V.inputs[0]) - - else: - Node = Tree.nodes.new('COMPOSITE') - Node.name = 'Composite' - Node.location = (400+X_Offset, 350+Y_Offset) - - Nodes = bpy.context.scene.node_tree.nodes - - if LayerLen > 1: - for i in range (1, LayerLen+1): - if i == 1: - Tree.links.new(Nodes['R_'+str(i)].outputs[0], Nodes['M_'+str(i)].inputs[1]) - if 1 < i < LayerLen: - Tree.links.new(Nodes['M_'+str(i-1)].outputs[0], Nodes['M_'+str(i)].inputs[1]) - if 1 < i < LayerLen+1: - Tree.links.new(Nodes['R_'+str(i)].outputs[0], Nodes['M_'+str(i-1)].inputs[2]) - if i == LayerLen: - Tree.links.new(Nodes['M_'+str(i-1)].outputs[0], Nodes['Composite'].inputs[0]) - else: - Tree.links.new(Nodes['R_1'].outputs[0], Nodes['Composite'].inputs[0]) - - for i in Tree.nodes: - i.location[0] += -250*Offset - i.location[1] += 150*Offset + Z = 0 + global LayerNum + LayerNum = 0 + LayerFlags = {} + LayerList = [] + + for Layer in IMGs: + Make3DLayer(\ + Layer['LayerName'].replace(' ', '_'),\ + Layer['LayerNameShort'].replace(' ', '_'),\ + Z,\ + Layer['LayerCoords'],\ + Layer['RenderLayer'],\ + Layer['LayerMode'],\ + Layer['LayerOpacity'],\ + Layer['HasAlpha'],\ + ) + + Z -= LayerOffset + + if SetupCompo: + #------------------------------------------------- + # COMPO NODES + + Scene.use_nodes = True + + Tree = Scene.node_tree + + for i in Tree.nodes: + Tree.nodes.remove(i) + + LayerList.reverse() + + Offset = 0 + LayerLen = len(LayerList) + + for Layer in LayerList: + + Offset += 1 + + X_Offset = (500*Offset) + Y_Offset = (-300*Offset) + + Node = Tree.nodes.new('R_LAYERS') + Node.location = (-500+X_Offset, 300+Y_Offset) + Node.name = 'R_'+ str(Offset) + Node.scene = Scene + Node.layer = Layer[0] + + if LayerViewers: + Node_V = Tree.nodes.new('VIEWER') + Node_V.name = Layer[0] + Node_V.location = (-200+X_Offset, 200+Y_Offset) + + Tree.links.new(Node.outputs[0], Node_V.inputs[0]) + + if LayerLen > Offset: + + Mode = LayerList[Offset][1] # has to go one step further + LayerOpacity = LayerList[Offset][2] + + if not Mode in ('Normal', '-1'): + + Node = Tree.nodes.new('MIX_RGB') + if OpacityMode == 'COMPO': Node.inputs['Fac'].default_value[0] = LayerOpacity + else: Node.inputs['Fac'].default_value[0] = 1 + Node.use_alpha = True + + if Mode in ('Addition', '7'): Node.blend_type = 'ADD' + elif Mode in ('Subtract', '8'): Node.blend_type = 'SUBTRACT' + elif Mode in ('Multiply', '3'): Node.blend_type = 'MULTIPLY' + elif Mode in ('DarkenOnly', '9'): Node.blend_type = 'DARKEN' + elif Mode in ('Dodge', '16'): Node.blend_type = 'DODGE' + elif Mode in ('LightenOnly', '10'): Node.blend_type = 'LIGHTEN' + elif Mode in ('Difference', '6'): Node.blend_type = 'DIFFERENCE' + elif Mode in ('Divide', '15'): Node.blend_type = 'DIVIDE' + elif Mode in ('Overlay', '5'): Node.blend_type = 'OVERLAY' + elif Mode in ('Screen', '4'): Node.blend_type = 'SCREEN' + elif Mode in ('Burn', '17'): Node.blend_type = 'BURN' + elif Mode in ('Color', '13'): Node.blend_type = 'COLOR' + elif Mode in ('Value', '14'): Node.blend_type = 'VALUE' + elif Mode in ('Saturation', '12'): Node.blend_type = 'SATURATION' + elif Mode in ('Hue', '11'): Node.blend_type = 'HUE' + elif Mode in ('Softlight', '19'): Node.blend_type = 'SOFT_LIGHT' + else: pass + + else: + Node = Tree.nodes.new('ALPHAOVER') + if OpacityMode == 'COMPO': Node.inputs['Fac'].default_value[0] = LayerOpacity + Node.name = 'M_' + str(Offset) + Node.location = (300+X_Offset, 250+Y_Offset) + + if MixerViewers: + Node_V = Tree.nodes.new('VIEWER') + Node_V.name = Layer[0] + Node_V.location = (500+X_Offset, 350+Y_Offset) + + Tree.links.new(Node.outputs[0], Node_V.inputs[0]) + + else: + Node = Tree.nodes.new('COMPOSITE') + Node.name = 'Composite' + Node.location = (400+X_Offset, 350+Y_Offset) + + Nodes = bpy.context.scene.node_tree.nodes + + if LayerLen > 1: + for i in range (1, LayerLen+1): + if i == 1: + Tree.links.new(Nodes['R_'+str(i)].outputs[0], Nodes['M_'+str(i)].inputs[1]) + if 1 < i < LayerLen: + Tree.links.new(Nodes['M_'+str(i-1)].outputs[0], Nodes['M_'+str(i)].inputs[1]) + if 1 < i < LayerLen+1: + Tree.links.new(Nodes['R_'+str(i)].outputs[0], Nodes['M_'+str(i-1)].inputs[2]) + if i == LayerLen: + Tree.links.new(Nodes['M_'+str(i-1)].outputs[0], Nodes['Composite'].inputs[0]) + else: + Tree.links.new(Nodes['R_1'].outputs[0], Nodes['Composite'].inputs[0]) + + for i in Tree.nodes: + i.location[0] += -250*Offset + i.location[1] += 150*Offset #------------------------------------------------------------------------ import os @@ -537,134 +537,134 @@ from math import pi # Operator class GIMPImageToScene(bpy.types.Operator): - '''''' - bl_idname = "import.gimp_image_to_scene" - bl_label = "GIMP Image to Scene" - bl_description = "Imports GIMP multilayer image files into 3D Scenes" - bl_options = {'REGISTER', 'UNDO'} - - filename = StringProperty(name="File Name", - description="Name of the file") - directory = StringProperty(name="Directory", - description="Directory of the file") - - LayerViewers = BoolProperty(name="Layer Viewers", - description="Add Viewer nodes to each Render Layer node", - default=True) - - MixerViewers = BoolProperty(name="Mixer Viewers", - description="Add Viewer nodes to each Mix node", - default=True) - - PremulAlpha = BoolProperty(name="Premuliply Alpha", - description="Set Image and Render settings to premultiplied alpha", - default=True) + '''''' + bl_idname = "import.gimp_image_to_scene" + bl_label = "GIMP Image to Scene" + bl_description = "Imports GIMP multilayer image files into 3D Scenes" + bl_options = {'REGISTER', 'UNDO'} + + filename = StringProperty(name="File Name", + description="Name of the file") + directory = StringProperty(name="Directory", + description="Directory of the file") + + LayerViewers = BoolProperty(name="Layer Viewers", + description="Add Viewer nodes to each Render Layer node", + default=True) + + MixerViewers = BoolProperty(name="Mixer Viewers", + description="Add Viewer nodes to each Mix node", + default=True) + + PremulAlpha = BoolProperty(name="Premuliply Alpha", + description="Set Image and Render settings to premultiplied alpha", + default=True) - ShadelessMats = BoolProperty(name="Shadeless Material", - description="Set Materials as Shadeless", - default=True) - - OpacityMode = EnumProperty(name="Opacity Mode", - description="Layer Opacity management", - items=( - ('TEX', 'Texture Alpha Factor', ''), - ('MAT', 'Material Alpha Value', ''), - ('COMPO', 'Mixer Node Factor', ''), - ('BAKE', 'Baked in Image Alpha', '')), - default='TEX') - - SetCamera = BoolProperty(name="Set Camera", - description="Create an Ortho Camera matching image resolution", - default=True) - - SetupCompo = BoolProperty(name="Setup Node Compositing", - description="Create a compositing node setup (will delete existing nodes)", - default=False) - - GroupUntagged = BoolProperty(name="Group Untagged", - description="Layers with no tag go to a single Render Layer", - default=False) - - LayerOffset = FloatProperty(name="Layer Separation", - description="Distance between each 3D Layer in the Z axis", - min=0, - default=0.01) - - LayerScale = FloatProperty(name="Layer Scale", - description="Scale pixel resolution by Blender units", - min=0, - default=0.01) - - def draw(self, context): - layout = self.layout - box = layout.box() - box.label('3D Layers:', icon='SORTSIZE') - box.prop(self, 'SetCamera', icon='OUTLINER_DATA_CAMERA') - box.prop(self, 'OpacityMode', icon='GHOST') - if self.OpacityMode == 'COMPO' and self.SetupCompo == False: - box.label('Tip: Enable Node Compositing', icon='INFO') - box.prop(self, 'PremulAlpha', icon='IMAGE_RGB_ALPHA') - box.prop(self, 'ShadelessMats', icon='SOLID') - box.prop(self, 'LayerOffset') - box.prop(self, 'LayerScale') - box = layout.box() - box.label('Compositing:', icon='RENDERLAYERS') - box.prop(self, 'SetupCompo', icon='NODETREE') - if self.SetupCompo: - box.prop(self, 'GroupUntagged', icon='IMAGE_ZDEPTH') - box.prop(self, 'LayerViewers', icon='NODE') - box.prop(self, 'MixerViewers', icon='NODE') - - def execute(self, context): - # File Path - filename = self.filename - directory = self.directory - - # Settings - LayerViewers = self.LayerViewers - MixerViewers = self.MixerViewers - OpacityMode = self.OpacityMode - PremulAlpha = self.PremulAlpha - ShadelessMats = self.ShadelessMats - SetCamera = self.SetCamera - SetupCompo = self.SetupCompo - GroupUntagged = self.GroupUntagged - LayerOffset = self.LayerOffset - LayerScale = self.LayerScale - - Ext = None - if filename.endswith('.xcf'): Ext = '.xcf' - elif filename.endswith('.xjt'): Ext = '.xjt' - - # Call Main Function - if Ext: - main(filename, directory, LayerViewers, MixerViewers, LayerOffset,\ - LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ - SetCamera, SetupCompo, GroupUntagged, Ext) - else: - self.report({'ERROR'},"Selected file wasn't valid, try .xcf or .xjt") - - return {'FINISHED'} + ShadelessMats = BoolProperty(name="Shadeless Material", + description="Set Materials as Shadeless", + default=True) + + OpacityMode = EnumProperty(name="Opacity Mode", + description="Layer Opacity management", + items=( + ('TEX', 'Texture Alpha Factor', ''), + ('MAT', 'Material Alpha Value', ''), + ('COMPO', 'Mixer Node Factor', ''), + ('BAKE', 'Baked in Image Alpha', '')), + default='TEX') + + SetCamera = BoolProperty(name="Set Camera", + description="Create an Ortho Camera matching image resolution", + default=True) + + SetupCompo = BoolProperty(name="Setup Node Compositing", + description="Create a compositing node setup (will delete existing nodes)", + default=False) + + GroupUntagged = BoolProperty(name="Group Untagged", + description="Layers with no tag go to a single Render Layer", + default=False) + + LayerOffset = FloatProperty(name="Layer Separation", + description="Distance between each 3D Layer in the Z axis", + min=0, + default=0.01) + + LayerScale = FloatProperty(name="Layer Scale", + description="Scale pixel resolution by Blender units", + min=0, + default=0.01) + + def draw(self, context): + layout = self.layout + box = layout.box() + box.label('3D Layers:', icon='SORTSIZE') + box.prop(self, 'SetCamera', icon='OUTLINER_DATA_CAMERA') + box.prop(self, 'OpacityMode', icon='GHOST') + if self.OpacityMode == 'COMPO' and self.SetupCompo == False: + box.label('Tip: Enable Node Compositing', icon='INFO') + box.prop(self, 'PremulAlpha', icon='IMAGE_RGB_ALPHA') + box.prop(self, 'ShadelessMats', icon='SOLID') + box.prop(self, 'LayerOffset') + box.prop(self, 'LayerScale') + box = layout.box() + box.label('Compositing:', icon='RENDERLAYERS') + box.prop(self, 'SetupCompo', icon='NODETREE') + if self.SetupCompo: + box.prop(self, 'GroupUntagged', icon='IMAGE_ZDEPTH') + box.prop(self, 'LayerViewers', icon='NODE') + box.prop(self, 'MixerViewers', icon='NODE') + + def execute(self, context): + # File Path + filename = self.filename + directory = self.directory + + # Settings + LayerViewers = self.LayerViewers + MixerViewers = self.MixerViewers + OpacityMode = self.OpacityMode + PremulAlpha = self.PremulAlpha + ShadelessMats = self.ShadelessMats + SetCamera = self.SetCamera + SetupCompo = self.SetupCompo + GroupUntagged = self.GroupUntagged + LayerOffset = self.LayerOffset + LayerScale = self.LayerScale + + Ext = None + if filename.endswith('.xcf'): Ext = '.xcf' + elif filename.endswith('.xjt'): Ext = '.xjt' + + # Call Main Function + if Ext: + main(filename, directory, LayerViewers, MixerViewers, LayerOffset,\ + LayerScale, OpacityMode, PremulAlpha, ShadelessMats,\ + SetCamera, SetupCompo, GroupUntagged, Ext) + else: + self.report({'ERROR'},"Selected file wasn't valid, try .xcf or .xjt") + + return {'FINISHED'} - def invoke(self, context, event): - wm = bpy.context.window_manager - wm.fileselect_add(self) + def invoke(self, context, event): + wm = bpy.context.window_manager + wm.fileselect_add(self) - return {'RUNNING_MODAL'} + return {'RUNNING_MODAL'} # Registering / Unregister def menu_func(self, context): - self.layout.operator(GIMPImageToScene.bl_idname, text="GIMP Image to Scene (.xcf, .xjt)", icon='PLUGIN') + self.layout.operator(GIMPImageToScene.bl_idname, text="GIMP Image to Scene (.xcf, .xjt)", icon='PLUGIN') def register(): - bpy.types.INFO_MT_file_import.append(menu_func) + bpy.types.INFO_MT_file_import.append(menu_func) def unregister(): - bpy.types.INFO_MT_file_import.remove(menu_func) + bpy.types.INFO_MT_file_import.remove(menu_func) if __name__ == "__main__": - register() + register() |