[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1231] branches/ io_import_xcf_as_3d_layers.py: XCFto3DLayers is a highly automatized importer for GIMP's XCF format, it

Daniel Salazar zanqdo at gmail.com
Sun Dec 5 14:07:14 CET 2010


Revision: 1231
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=1231
Author:   zanqdo
Date:     2010-12-05 14:07:14 +0100 (Sun, 05 Dec 2010)

Log Message:
-----------
XCFto3DLayers is a highly automatized importer for GIMP's XCF format, it
is able to create textured planes in the 3D view for each layer in an
XCF, their respective materials and textures, renderlayers and a node tree
compositing setup supporting opacity and blending modes

Added Paths:
-----------
    branches/io_import_xcf_as_3d_layers.py

Added: branches/io_import_xcf_as_3d_layers.py
===================================================================
--- branches/io_import_xcf_as_3d_layers.py	                        (rev 0)
+++ branches/io_import_xcf_as_3d_layers.py	2010-12-05 13:07:14 UTC (rev 1231)
@@ -0,0 +1,512 @@
+# ##### 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_addon_info = {
+	"name": "Import GIMP Files as 3D Layers (.xcf)",
+	"author": "Daniel Salazar (ZanQdo)",
+	"version": (1,0),
+	"blender": (2, 5, 3),
+	"api": 33419,
+	"location": "File > Import > GIMP Images as 3D Layers(XCF)",
+	"description": "Imports GIMP multilayer image files into 3D Layers",
+	"warning": "",
+	"wiki_url": ""\
+		"",
+	"tracker_url": ""\
+		"",
+	"category": "Import/Export"}
+
+"""
+This script imports GIMP layered image files into 3D Layers.
+"""
+
+def main(File, Path, LayerViewers, MixerViewers, LayerOffset,\
+	LayerScale, OpacityMode, PremulImages, ShadelessMats,\
+	SetCamera, SetupCompo, GroupUntagged):
+	
+	#-------------------------------------------------
+	# CONFIG
+	XCFInfo = 'xcfinfo'
+	XCF2PNG = 'xcf2png'
+	#-------------------------------------------------
+	# INFO
+	
+	CMD = '%s %s%s' % (XCFInfo, Path, File)
+	
+	Info = os.popen(CMD)
+	
+	PNGs = []
+	
+	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
+			
+			PNGs.append ({\
+				'ColorMode':Line[2],\
+				'LayerMode':Mode,\
+				'LayerOpacity':Opacity,\
+				'LayerName':Line[4].rstrip(),\
+				'LayerNameShort':NameShort,\
+				'LayerCoords':Line[1].replace('x', ' ').replace('+', ' +').replace('-', ' -').split(),\
+				'RenderLayer':RenderLayer,\
+				})
+		elif Line.startswith('Version'):
+			ResX, ResY = map (int, Line.split()[2].split('x'))
+	
+	
+	#-------------------------------------------------
+	# EXTRACT
+	if OpacityMode == 'BAKE':
+		Opacity = ''
+	else:
+		Opacity = ' --percent 100'
+	for Layer in PNGs:
+		CMD = '%s -C %s%s -o %s%s.png "%s"%s' %\
+		(XCF2PNG, Path, File, Path, 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 PremulImages: 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):
+		
+		# RenderLayer
+		
+		#if not bpy.context.scene.render.layers.get(RenderLayer):
+		if SetupCompo:
+			
+			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
+		Mat.use_transparency = True
+		if ShadelessMats: Mat.use_shadeless = True
+		if OpacityMode == 'MAT': Mat.alpha = LayerOpacity
+		else: Mat.alpha = 0
+		
+		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 PremulImages: Img.use_premultiply = True
+		Img.filepath = '%s%s.png' % (Path, Name)
+		
+		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'
+		
+		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 PNGs:
+		Make3DLayer(\
+		Layer['LayerName'].replace(' ', '_'),\
+		Layer['LayerNameShort'].replace(' ', '_'),\
+		Z,\
+		Layer['LayerCoords'],\
+		Layer['RenderLayer'],\
+		Layer['LayerMode'],\
+		Layer['LayerOpacity'],\
+		)
+		
+		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 Mode != 'Normal':
+					
+					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 == 'Addition': Node.blend_type = 'ADD'
+					elif Mode == 'Subtract': Node.blend_type = 'SUBTRACT'
+					elif Mode == 'Multiply': Node.blend_type = 'MULTIPLY'
+					elif Mode == 'DarkenOnly': Node.blend_type = 'DARKEN'
+					elif Mode == 'Dodge': Node.blend_type = 'DODGE'
+					elif Mode == 'LightenOnly': Node.blend_type = 'LIGHTEN'
+					elif Mode == 'Difference': Node.blend_type = 'DIFFERENCE'
+					elif Mode == 'Divide': Node.blend_type = 'DIVIDE'
+					elif Mode == 'Overlay': Node.blend_type = 'OVERLAY'
+					elif Mode == 'Screen': Node.blend_type = 'SCREEN'
+					elif Mode == 'Burn': Node.blend_type = 'BURN'
+					elif Mode == 'Color': Node.blend_type = 'COLOR'
+					elif Mode == 'Value': Node.blend_type = 'VALUE'
+					elif Mode == 'Saturation': Node.blend_type = 'SATURATION'
+					elif Mode == 'Hue': Node.blend_type = 'HUE'
+					elif Mode == 'Softlight': 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:

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list