[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20427] branches/soc-2009-kazanbas/release /scripts/export_obj-2.5.py: Start OBJ exporter conversion.

Arystanbek Dyussenov arystan.d at gmail.com
Tue May 26 18:22:00 CEST 2009


Revision: 20427
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20427
Author:   kazanbas
Date:     2009-05-26 18:22:00 +0200 (Tue, 26 May 2009)

Log Message:
-----------
Start OBJ exporter conversion.
Just copied export_obj.py to export_obj-2.5.py leaving old one for 
reference. Once conversion is done, the new one will replace it.

Added Paths:
-----------
    branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py

Added: branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py
===================================================================
--- branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py	                        (rev 0)
+++ branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py	2009-05-26 16:22:00 UTC (rev 20427)
@@ -0,0 +1,791 @@
+#!BPY
+
+"""
+Name: 'Wavefront (.obj)...'
+Blender: 248
+Group: 'Export'
+Tooltip: 'Save a Wavefront OBJ File'
+"""
+
+__author__ = "Campbell Barton, Jiri Hnidek"
+__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
+__version__ = "1.2"
+
+__bpydoc__ = """\
+This script is an exporter to OBJ file format.
+
+Usage:
+
+Select the objects you wish to export and run this script from "File->Export" menu.
+Selecting the default options from the popup box will be good in most cases.
+All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
+will be exported as mesh data.
+"""
+
+
+# --------------------------------------------------------------------------
+# OBJ Export v1.1 by Campbell Barton (AKA Ideasman)
+# --------------------------------------------------------------------------
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+
+import bpy
+
+# import Blender
+# from Blender import Mesh, Scene, Window, sys, Image, Draw
+# import BPyMesh
+# import BPyObject
+# import BPySys
+# import BPyMessages
+
+# Returns a tuple - path,extension.
+# 'hello.obj' >  ('hello', '.obj')
+def splitExt(path):
+	dotidx = path.rfind('.')
+	if dotidx == -1:
+		return path, ''
+	else:
+		return path[:dotidx], path[dotidx:] 
+
+def fixName(name):
+	if name == None:
+		return 'None'
+	else:
+		return name.replace(' ', '_')
+
+# A Dict of Materials
+# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
+MTL_DICT = {} 
+
+def write_mtl(filename):
+	
+	world = Blender.World.GetCurrent()
+	if world:
+		worldAmb = world.getAmb()
+	else:
+		worldAmb = (0,0,0) # Default value
+	
+	file = open(filename, "w")
+	file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1])
+	file.write('# Material Count: %i\n' % len(MTL_DICT))
+	# Write material/image combinations we have used.
+	for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems():
+		
+		# Get the Blender data for the material and the image.
+		# Having an image named None will make a bug, dont do it :)
+		
+		file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
+		
+		if mat:
+			file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's 
+			file.write('Ka %.6f %.6f %.6f\n' %  tuple([c*mat.amb for c in worldAmb])  ) # Ambient, uses mirror colour,
+			file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse
+			file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular
+			file.write('Ni %.6f\n' % mat.IOR) # Refraction index
+			file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
+			
+			# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
+			if mat.getMode() & Blender.Material.Modes['SHADELESS']:
+				file.write('illum 0\n') # ignore lighting
+			elif mat.getSpec() == 0:
+				file.write('illum 1\n') # no specular.
+			else:
+				file.write('illum 2\n') # light normaly	
+		
+		else:
+			#write a dummy material here?
+			file.write('Ns 0\n')
+			file.write('Ka %.6f %.6f %.6f\n' %  tuple([c for c in worldAmb])  ) # Ambient, uses mirror colour,
+			file.write('Kd 0.8 0.8 0.8\n')
+			file.write('Ks 0.8 0.8 0.8\n')
+			file.write('d 1\n') # No alpha
+			file.write('illum 2\n') # light normaly
+		
+		# Write images!
+		if img:  # We have an image on the face!
+			file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image			
+		
+		elif mat: # No face image. if we havea material search for MTex image.
+			for mtex in mat.getTextures():
+				if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
+					try:
+						filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1]
+						file.write('map_Kd %s\n' % filename) # Diffuse mapping image
+						break
+					except:
+						# Texture has no image though its an image type, best ignore.
+						pass
+		
+		file.write('\n\n')
+	
+	file.close()
+
+def copy_file(source, dest):
+	file = open(source, 'rb')
+	data = file.read()
+	file.close()
+	
+	file = open(dest, 'wb')
+	file.write(data)
+	file.close()
+
+
+def copy_images(dest_dir):
+	if dest_dir[-1] != sys.sep:
+		dest_dir += sys.sep
+	
+	# Get unique image names
+	uniqueImages = {}
+	for matname, mat, image in MTL_DICT.itervalues(): # Only use image name
+		# Get Texface images
+		if image:
+			uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default.
+		
+		# Get MTex images
+		if mat:
+			for mtex in mat.getTextures():
+				if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
+					image_tex = mtex.tex.image
+					if image_tex:
+						try:
+							uniqueImages[image_tex] = image_tex
+						except:
+							pass
+	
+	# Now copy images
+	copyCount = 0
+	
+	for bImage in uniqueImages.itervalues():
+		image_path = sys.expandpath(bImage.filename)
+		if sys.exists(image_path):
+			# Make a name for the target path.
+			dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+			if not sys.exists(dest_image_path): # Image isnt alredy there
+				print '\tCopying "%s" > "%s"' % (image_path, dest_image_path)
+				copy_file(image_path, dest_image_path)
+				copyCount+=1
+	print '\tCopied %d images' % copyCount
+
+def write(filename, objects,\
+EXPORT_TRI=False,  EXPORT_EDGES=False,  EXPORT_NORMALS=False,  EXPORT_NORMALS_HQ=False,\
+EXPORT_UV=True,  EXPORT_MTL=True,  EXPORT_COPY_IMAGES=False,\
+EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\
+EXPORT_GROUP_BY_OB=False,  EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False):
+	'''
+	Basic write function. The context and options must be alredy set
+	This can be accessed externaly
+	eg.
+	write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
+	'''
+	
+	def veckey3d(v):
+		return round(v.x, 6), round(v.y, 6), round(v.z, 6)
+		
+	def veckey2d(v):
+		return round(v.x, 6), round(v.y, 6)
+	
+	print 'OBJ Export path: "%s"' % filename
+	temp_mesh_name = '~tmp-mesh'
+
+	time1 = sys.time()
+	scn = Scene.GetCurrent()
+
+	file = open(filename, "w")
+	
+	# Write Header
+	file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
+	file.write('# www.blender3d.org\n')
+
+	# Tell the obj file what material file to use.
+	if EXPORT_MTL:
+		mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
+		file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
+	
+	# Get the container mesh. - used for applying modifiers and non mesh objects.
+	containerMesh = meshName = tempMesh = None
+	for meshName in Blender.NMesh.GetNames():
+		if meshName.startswith(temp_mesh_name):
+			tempMesh = Mesh.Get(meshName)
+			if not tempMesh.users:
+				containerMesh = tempMesh
+	if not containerMesh:
+		containerMesh = Mesh.New(temp_mesh_name)
+	
+	if EXPORT_ROTX90:
+		mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
+		
+	del meshName
+	del tempMesh
+	
+	# Initialize totals, these are updated each object
+	totverts = totuvco = totno = 1
+	
+	face_vert_index = 1
+	
+	globalNormals = {}
+	
+	# Get all meshs
+	for ob_main in objects:
+		for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
+			# Will work for non meshes now! :)
+			# getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None)
+			me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn)
+			if not me:
+				continue
+			
+			if EXPORT_UV:
+				faceuv= me.faceUV
+			else:
+				faceuv = False
+			
+			# We have a valid mesh
+			if EXPORT_TRI and me.faces:
+				# Add a dummy object to it.
+				has_quads = False
+				for f in me.faces:
+					if len(f) == 4:
+						has_quads = True
+						break
+				
+				if has_quads:
+					oldmode = Mesh.Mode()
+					Mesh.Mode(Mesh.SelectModes['FACE'])
+					
+					me.sel = True
+					tempob = scn.objects.new(me)
+					me.quadToTriangle(0) # more=0 shortest length
+					oldmode = Mesh.Mode(oldmode)
+					scn.objects.unlink(tempob)
+					
+					Mesh.Mode(oldmode)
+			
+			# Make our own list so it can be sorted to reduce context switching
+			faces = [ f for f in me.faces ]
+			
+			if EXPORT_EDGES:
+				edges = me.edges
+			else:
+				edges = []
+			
+			if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write
+				continue # dont bother with this mesh.
+			
+			if EXPORT_ROTX90:
+				me.transform(ob_mat*mat_xrot90)
+			else:
+				me.transform(ob_mat)
+			
+			# High Quality Normals
+			if EXPORT_NORMALS and faces:
+				if EXPORT_NORMALS_HQ:
+					BPyMesh.meshCalcNormals(me)
+				else:
+					# transforming normals is incorrect
+					# when the matrix is scaled,
+					# better to recalculate them
+					me.calcNormals()
+			
+			# # Crash Blender
+			#materials = me.getMaterials(1) # 1 == will return None in the list.
+			materials = me.materials
+			
+			materialNames = []
+			materialItems = materials[:]
+			if materials:
+				for mat in materials:
+					if mat: # !=None
+						materialNames.append(mat.name)
+					else:
+						materialNames.append(None)
+				# Cant use LC because some materials are None.

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list