| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | #!BPY | 
					
						
							| 
									
										
										
										
											2004-06-07 01:34:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | Name: 'Wavefront (.obj)...' | 
					
						
							| 
									
										
										
										
											2005-06-13 17:21:30 +00:00
										 |  |  | Blender: 232 | 
					
						
							| 
									
										
										
										
											2004-06-08 04:43:40 +00:00
										 |  |  | Group: 'Export' | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | Tooltip: 'Save a Wavefront OBJ File' | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2004-06-07 01:34:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-12 13:42:49 +00:00
										 |  |  | __author__ = "Campbell Barton, Jiri Hnidek" | 
					
						
							| 
									
										
										
										
											2004-11-07 16:31:13 +00:00
										 |  |  | __url__ = ["blender", "elysiun"] | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | __version__ = "1.0" | 
					
						
							| 
									
										
										
										
											2004-11-07 16:31:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | __bpydoc__ = """\
 | 
					
						
							|  |  |  | This script is an exporter to OBJ file format. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Usage: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2004-11-07 16:31:13 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | # -------------------------------------------------------------------------- | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | # OBJ Export v1.0 by Campbell Barton (AKA Ideasman) | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | # -------------------------------------------------------------------------- | 
					
						
							|  |  |  | # ***** 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 ***** | 
					
						
							|  |  |  | # -------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-30 02:26:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | import Blender | 
					
						
							|  |  |  | from Blender import Mesh, Scene, Window, sys, Image, Draw | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | import BPyMesh | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | import BPyObject | 
					
						
							|  |  |  | reload(BPyObject) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | import BPyMessages | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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:]  | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | def fixName(name): | 
					
						
							|  |  |  | 	if name == None: | 
					
						
							|  |  |  | 		return 'None' | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		return name.replace(' ', '_') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | # Used to add the scene name into the filename without using odd chars | 
					
						
							|  |  |  | def saneFilechars(name): | 
					
						
							|  |  |  | 	for ch in ' /\\~!@#$%^&*()+=[];\':",./<>?\t\r\n': | 
					
						
							|  |  |  | 		name = name.replace(ch, '_') | 
					
						
							|  |  |  | 	return name | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | global MTL_DICT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A Dict of Materials | 
					
						
							|  |  |  | # (material.name, image.name):matname_imagename # matname_imagename has gaps removed. | 
					
						
							|  |  |  | MTL_DICT = {}  | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | def write_mtl(filename): | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	global MTL_DICT | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	world = Blender.World.GetCurrent() | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	if world: | 
					
						
							|  |  |  | 		worldAmb = world.getAmb() | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		worldAmb = (0,0,0) # Default value | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 	file = open(filename, "w") | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | 	file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	file.write('# Material Count: %i\n' % len(MTL_DICT)) | 
					
						
							|  |  |  | 	# Write material/image combinations we have used. | 
					
						
							|  |  |  | 	for key, mtl_mat_name 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 key[0] == None: | 
					
						
							|  |  |  | 			#write a dummy material here? | 
					
						
							|  |  |  | 			file.write('Ns 0\n') | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | 			file.write('Ka %.6f %.6f %.6f\n' %  tuple([c for c in worldAmb])  ) # Ambient, uses mirror colour, | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 			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	 | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			mat = Blender.Material.Get(key[0]) | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | 			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.getAmb() for c in worldAmb])  ) # Ambient, uses mirror colour, | 
					
						
							|  |  |  | 			file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.getRef() for c in mat.getRGBCol()]) ) # Diffuse | 
					
						
							|  |  |  | 			file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.getSpec() for c in mat.getSpecCol()]) ) # Specular | 
					
						
							|  |  |  | 			file.write('Ni %.6f\n' % mat.getIOR()) # Refraction index | 
					
						
							|  |  |  | 			file.write('d %.6f\n' % mat.getAlpha()) # Alpha (obj uses 'd' for dissolve) | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			if mat.getMode() & Blender.Material.Modes['SHADELESS']: | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 				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	 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		# Write images! | 
					
						
							|  |  |  | 		if key[1] != None:  # We have an image on the face! | 
					
						
							|  |  |  | 			img = Image.Get(key[1]) | 
					
						
							|  |  |  | 			file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image			 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		elif key[0] != None: # No face image. if we havea material search for MTex image. | 
					
						
							|  |  |  | 			for mtex in mat.getTextures(): | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 				if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 					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') | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 	file.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | def copy_file(source, dest): | 
					
						
							|  |  |  | 	file = open(source, 'rb') | 
					
						
							|  |  |  | 	data = file.read() | 
					
						
							|  |  |  | 	file.close() | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	file = open(dest, 'wb') | 
					
						
							|  |  |  | 	file.write(data) | 
					
						
							|  |  |  | 	file.close() | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | def copy_images(dest_dir): | 
					
						
							|  |  |  | 	if dest_dir[-1] != sys.sep: | 
					
						
							|  |  |  | 		dest_dir += sys.sep | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	# Get unique image names | 
					
						
							|  |  |  | 	uniqueImages = {} | 
					
						
							|  |  |  | 	for matname, imagename in MTL_DICT.iterkeys(): # Only use image name | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | 		# Get Texface images | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 		if imagename != None: | 
					
						
							|  |  |  | 			uniqueImages[imagename] = None # Should use sets here. wait until Python 2.4 is default. | 
					
						
							| 
									
										
										
										
											2006-04-07 00:47:39 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		# Get MTex images | 
					
						
							|  |  |  | 		if matname != None: | 
					
						
							|  |  |  | 			mat= Material.Get(matname) | 
					
						
							| 
									
										
										
										
											2006-04-10 21:42:18 +00:00
										 |  |  | 			for mtex in mat.getTextures(): | 
					
						
							|  |  |  | 				if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: | 
					
						
							|  |  |  | 					try: | 
					
						
							|  |  |  | 						uniqueImages[mtex.tex.image.name] = None | 
					
						
							|  |  |  | 					except: | 
					
						
							|  |  |  | 						pass | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# Now copy images | 
					
						
							|  |  |  | 	copyCount = 0 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for imageName in uniqueImages.iterkeys(): | 
					
						
							|  |  |  | 		bImage = Image.Get(imageName) | 
					
						
							|  |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | def write(filename, objects,\ | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | EXPORT_TRI=False,  EXPORT_EDGES=False,  EXPORT_NORMALS=False,  EXPORT_NORMALS_HQ=False,\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | EXPORT_UV=True,  EXPORT_MTL=True,  EXPORT_COPY_IMAGES=False,\ | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | EXPORT_GROUP_BY_OB=False,  EXPORT_GROUP_BY_MAT=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. | 
					
						
							|  |  |  | 	'''
 | 
					
						
							|  |  |  | 	print 'OBJ Export path: "%s"' % filename | 
					
						
							|  |  |  | 	global MTL_DICT | 
					
						
							|  |  |  | 	temp_mesh_name = '~tmp-mesh' | 
					
						
							| 
									
										
										
										
											2006-04-03 16:14:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	time1 = sys.time() | 
					
						
							| 
									
										
										
										
											2005-05-30 02:26:40 +00:00
										 |  |  | 	scn = Scene.GetCurrent() | 
					
						
							| 
									
										
										
										
											2004-06-21 12:01:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	file = open(filename, "w") | 
					
						
							| 
									
										
										
										
											2005-08-01 03:06:24 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	# Write Header | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 	file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	file.write('# www.blender3d.org\n') | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Tell the obj file what material file to use. | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) | 
					
						
							| 
									
										
										
										
											2005-05-30 02:26:40 +00:00
										 |  |  | 	file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-04-02 01:46:10 +00:00
										 |  |  | 	# 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) | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if EXPORT_ROTX90: | 
					
						
							|  |  |  | 		mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x') | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2006-04-02 01:46:10 +00:00
										 |  |  | 	del meshName | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 	del tempMesh | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	# Initialize totals, these are updated each object | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	totverts = totuvco = totno = 1 | 
					
						
							| 
									
										
										
										
											2005-05-30 02:26:40 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-08-01 03:06:24 +00:00
										 |  |  | 	globalUVCoords = {} | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	globalNormals = {} | 
					
						
							| 
									
										
										
										
											2005-08-01 03:06:24 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	# Get all meshs | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 	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 | 
					
						
							|  |  |  | 			faceuv= me.faceUV | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			# We have a valid mesh | 
					
						
							|  |  |  | 			if EXPORT_TRI and me.faces: | 
					
						
							|  |  |  | 				# Add a dummy object to it. | 
					
						
							|  |  |  | 				oldmode = Mesh.Mode() | 
					
						
							|  |  |  | 				Mesh.Mode(Mesh.SelectModes['FACE']) | 
					
						
							|  |  |  | 				quadcount = 0 | 
					
						
							|  |  |  | 				for f in me.faces: | 
					
						
							|  |  |  | 					if len(f) == 4: | 
					
						
							|  |  |  | 						f.sel = True | 
					
						
							|  |  |  | 						quadcount +=1 | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				if quadcount: | 
					
						
							|  |  |  | 					tempob = Blender.Object.New('Mesh') | 
					
						
							|  |  |  | 					tempob.link(me) | 
					
						
							|  |  |  | 					scn.link(tempob) | 
					
						
							|  |  |  | 					me.quadToTriangle(0) # more=0 shortest length | 
					
						
							|  |  |  | 					oldmode = Mesh.Mode(oldmode) | 
					
						
							|  |  |  | 					scn.unlink(tempob) | 
					
						
							|  |  |  | 				Mesh.Mode(oldmode) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			# 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 EXPORT_NORMALS_HQ and faces: | 
					
						
							|  |  |  | 				BPyMesh.meshCalcNormals(me) | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			# # Crash Blender | 
					
						
							|  |  |  | 			#materials = me.getMaterials(1) # 1 == will return None in the list. | 
					
						
							|  |  |  | 			materials = me.materials | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			materialNames = [] | 
					
						
							|  |  |  | 			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. | 
					
						
							|  |  |  | 				# materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken.	 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			# Possible there null materials, will mess up indicies | 
					
						
							|  |  |  | 			# but at least it will export, wait until Blender gets fixed. | 
					
						
							|  |  |  | 			materialNames.extend((16-len(materialNames)) * [None]) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# Sort by Material, then images | 
					
						
							|  |  |  | 			# so we dont over context switch in the obj file. | 
					
						
							|  |  |  | 			if faceuv and EXPORT_UV: | 
					
						
							|  |  |  | 				faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) | 
					
						
							|  |  |  | 			elif len(materials) > 1: | 
					
						
							|  |  |  | 				faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				# no materials | 
					
						
							|  |  |  | 				faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			# Set the default mat to no material and no image. | 
					
						
							|  |  |  | 			contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. | 
					
						
							|  |  |  | 			contextSmooth = None # Will either be true or false,  set bad to force initialization switch. | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: | 
					
						
							|  |  |  | 				obnamestring = '%s_%s' % (fixName(ob.name), fixName(ob.getData(1))) | 
					
						
							|  |  |  | 				if EXPORT_BLEN_OBS: | 
					
						
							|  |  |  | 					file.write('o %s\n' % obnamestring) # Write Object name | 
					
						
							|  |  |  | 				else: # if EXPORT_GROUP_BY_OB: | 
					
						
							|  |  |  | 					file.write('g %s\n' % obnamestring) | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			# Vert | 
					
						
							|  |  |  | 			for v in me.verts: | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | 				file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# UV | 
					
						
							|  |  |  | 			if faceuv and EXPORT_UV: | 
					
						
							|  |  |  | 				for f in faces: | 
					
						
							|  |  |  | 					for uvKey in f.uv: | 
					
						
							|  |  |  | 						uvKey = veckey2d(uvKey) | 
					
						
							|  |  |  | 						if not globalUVCoords.has_key(uvKey): | 
					
						
							|  |  |  | 							globalUVCoords[uvKey] = totuvco | 
					
						
							|  |  |  | 							totuvco +=1 | 
					
						
							|  |  |  | 							file.write('vt %.6f %.6f 0.0\n' % uvKey) | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			# NORMAL, Smooth/Non smoothed. | 
					
						
							|  |  |  | 			if EXPORT_NORMALS: | 
					
						
							|  |  |  | 				for f in faces: | 
					
						
							|  |  |  | 					if f.smooth: | 
					
						
							|  |  |  | 						for v in f.v: | 
					
						
							|  |  |  | 							noKey = veckey3d(v.no) | 
					
						
							|  |  |  | 							if not globalNormals.has_key( noKey ): | 
					
						
							|  |  |  | 								globalNormals[noKey] = totno | 
					
						
							|  |  |  | 								totno +=1 | 
					
						
							|  |  |  | 								file.write('vn %.6f %.6f %.6f\n' % noKey) | 
					
						
							|  |  |  | 					else: | 
					
						
							|  |  |  | 						# Hard, 1 normal from the face. | 
					
						
							|  |  |  | 						noKey = veckey3d(f.no) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 						if not globalNormals.has_key( noKey ): | 
					
						
							|  |  |  | 							globalNormals[noKey] = totno | 
					
						
							|  |  |  | 							totno +=1 | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | 							file.write('vn %.6f %.6f %.6f\n' % noKey) | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			uvIdx = 0 | 
					
						
							|  |  |  | 			for f in faces: | 
					
						
							|  |  |  | 				f_v= f.v | 
					
						
							|  |  |  | 				if faceuv: | 
					
						
							|  |  |  | 					f_uv= f.uv | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				# MAKE KEY | 
					
						
							|  |  |  | 				if EXPORT_UV and faceuv and f.image: # Object is always true. | 
					
						
							|  |  |  | 					key = materialNames[min(f.mat,len(materialNames)-1)],  f.image.name | 
					
						
							|  |  |  | 					#key = materialNames[f.mat],  f.image.name | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 				else: | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 					key = materialNames[min(f.mat,len(materialNames)-1)],  None # No image, use None instead. | 
					
						
							|  |  |  | 					#key = materialNames[f.mat],  None # No image, use None instead. | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				# CHECK FOR CONTEXT SWITCH | 
					
						
							|  |  |  | 				if key == contextMat: | 
					
						
							|  |  |  | 					pass # Context alredy switched, dont do anythoing | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					if key[0] == None and key[1] == None: | 
					
						
							|  |  |  | 						# Write a null material, since we know the context has changed. | 
					
						
							|  |  |  | 						matstring = '(null)' | 
					
						
							|  |  |  | 						file.write('usemtl (null)\n') # mat, image | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 						 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 					else: | 
					
						
							|  |  |  | 						try: # Faster to try then 2x dict lookups. | 
					
						
							|  |  |  | 							# We have the material, just need to write the context switch, | 
					
						
							|  |  |  | 							matstring = MTL_DICT[key] | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 						except KeyError: | 
					
						
							|  |  |  | 							# First add to global dict so we can export to mtl | 
					
						
							|  |  |  | 							# Then write mtl | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							# Make a new names from the mat and image name, | 
					
						
							|  |  |  | 							# converting any spaces to underscores with fixName. | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							# If none image dont bother adding it to the name | 
					
						
							|  |  |  | 							if key[1] == None: | 
					
						
							|  |  |  | 								matstring = MTL_DICT[key] ='%s' % fixName(key[0]) | 
					
						
							|  |  |  | 							else: | 
					
						
							|  |  |  | 								matstring = MTL_DICT[key] = '%s_%s' % (fixName(key[0]), fixName(key[1])) | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 					if EXPORT_GROUP_BY_MAT: | 
					
						
							|  |  |  | 						file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), matstring) ) # can be mat_image or (null) | 
					
						
							|  |  |  | 					file.write('usemtl %s\n' % matstring) # can be mat_image or (null) | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 				contextMat = key | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 				if f.smooth != contextSmooth: | 
					
						
							|  |  |  | 					if contextSmooth: # on now off | 
					
						
							|  |  |  | 						file.write('s off\n') | 
					
						
							|  |  |  | 					else: # was off now on | 
					
						
							|  |  |  | 						file.write('s 1\n') | 
					
						
							|  |  |  | 						 | 
					
						
							|  |  |  | 					contextSmooth = f.smooth | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 				file.write('f') | 
					
						
							|  |  |  | 				if faceuv and EXPORT_UV: | 
					
						
							|  |  |  | 					if EXPORT_NORMALS: | 
					
						
							|  |  |  | 						if f.smooth: # Smoothed, use vertex normals | 
					
						
							|  |  |  | 							for vi, v in enumerate(f_v): | 
					
						
							|  |  |  | 								file.write( ' %d/%d/%d' % (\ | 
					
						
							|  |  |  | 								  v.index+totverts,\ | 
					
						
							|  |  |  | 								  globalUVCoords[ veckey2d(f_uv[vi]) ],\ | 
					
						
							|  |  |  | 								  globalNormals[ veckey3d(v.no) ])) # vert, uv, normal | 
					
						
							|  |  |  | 						else: # No smoothing, face normals | 
					
						
							|  |  |  | 							no = globalNormals[ veckey3d(f.no) ] | 
					
						
							|  |  |  | 							for vi, v in enumerate(f_v): | 
					
						
							|  |  |  | 								file.write( ' %d/%d/%d' % (\ | 
					
						
							|  |  |  | 								  v.index+totverts,\ | 
					
						
							|  |  |  | 								  globalUVCoords[ veckey2d(f_uv[vi]) ],\ | 
					
						
							|  |  |  | 								  no)) # vert, uv, normal | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 					else: # No Normals | 
					
						
							| 
									
										
										
										
											2006-06-07 02:10:10 +00:00
										 |  |  | 						for vi, v in enumerate(f_v): | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 							file.write( ' %d/%d' % (\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 							  v.index+totverts,\ | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 							  globalUVCoords[ veckey2d(f_uv[vi])])) # vert, uv | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 				 | 
					
						
							|  |  |  | 				else: # No UV's | 
					
						
							|  |  |  | 					if EXPORT_NORMALS: | 
					
						
							|  |  |  | 						if f.smooth: # Smoothed, use vertex normals | 
					
						
							|  |  |  | 							for v in f_v: | 
					
						
							|  |  |  | 								file.write( ' %d//%d' % (\ | 
					
						
							|  |  |  | 								  v.index+totverts,\ | 
					
						
							|  |  |  | 								  globalNormals[ veckey3d(v.no) ])) | 
					
						
							|  |  |  | 						else: # No smoothing, face normals | 
					
						
							|  |  |  | 							no = globalNormals[ veckey3d(f.no) ] | 
					
						
							|  |  |  | 							for v in f_v: | 
					
						
							|  |  |  | 								file.write( ' %d//%d' % (\ | 
					
						
							|  |  |  | 								  v.index+totverts,\ | 
					
						
							|  |  |  | 								  no)) | 
					
						
							|  |  |  | 					else: # No Normals | 
					
						
							| 
									
										
										
										
											2006-06-07 02:10:10 +00:00
										 |  |  | 						for v in f_v: | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 							file.write( ' %d' % (\ | 
					
						
							|  |  |  | 							  v.index+totverts)) | 
					
						
							|  |  |  | 						 | 
					
						
							|  |  |  | 				file.write('\n') | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 			# Write edges. | 
					
						
							|  |  |  | 			if EXPORT_EDGES: | 
					
						
							|  |  |  | 				LOOSE= Mesh.EdgeFlags.LOOSE | 
					
						
							|  |  |  | 				for ed in edges: | 
					
						
							|  |  |  | 					if ed.flag & LOOSE: | 
					
						
							|  |  |  | 						file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			# Make the indicies global rather then per mesh | 
					
						
							|  |  |  | 			totverts += len(me.verts) | 
					
						
							|  |  |  | 			me.verts= None | 
					
						
							| 
									
										
										
										
											2004-09-19 10:41:04 +00:00
										 |  |  | 	file.close() | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Now we have all our materials, save them | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	if EXPORT_MTL: | 
					
						
							|  |  |  | 		write_mtl(mtlfilename) | 
					
						
							|  |  |  | 	if EXPORT_COPY_IMAGES: | 
					
						
							|  |  |  | 		dest_dir = filename | 
					
						
							|  |  |  | 		# Remove chars until we are just the path. | 
					
						
							|  |  |  | 		while dest_dir and dest_dir[-1] not in '\\/': | 
					
						
							|  |  |  | 			dest_dir = dest_dir[:-1] | 
					
						
							|  |  |  | 		if dest_dir: | 
					
						
							|  |  |  | 			copy_images(dest_dir) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			print '\tError: "%s" could not be used as a base for an image path.' % filename | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	print "OBJ Export time: %.2f" % (sys.time() - time1) | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-08-04 06:16:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | def write_ui(filename): | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	EXPORT_APPLY_MODIFIERS = Draw.Create(1) | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | 	EXPORT_ROTX90 = Draw.Create(1) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	EXPORT_TRI = Draw.Create(0) | 
					
						
							| 
									
										
										
										
											2006-10-01 14:02:51 +00:00
										 |  |  | 	EXPORT_EDGES = Draw.Create(1) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	EXPORT_NORMALS = Draw.Create(0) | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | 	EXPORT_NORMALS_HQ = Draw.Create(0) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	EXPORT_UV = Draw.Create(1) | 
					
						
							|  |  |  | 	EXPORT_MTL = Draw.Create(1) | 
					
						
							|  |  |  | 	EXPORT_SEL_ONLY = Draw.Create(1) | 
					
						
							|  |  |  | 	EXPORT_ALL_SCENES = Draw.Create(0) | 
					
						
							|  |  |  | 	EXPORT_ANIMATION = Draw.Create(0) | 
					
						
							|  |  |  | 	EXPORT_COPY_IMAGES = Draw.Create(0) | 
					
						
							|  |  |  | 	EXPORT_BLEN_OBS = Draw.Create(1) | 
					
						
							|  |  |  | 	EXPORT_GROUP_BY_OB = Draw.Create(0) | 
					
						
							|  |  |  | 	EXPORT_GROUP_BY_MAT = Draw.Create(0) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Get USER Options | 
					
						
							|  |  |  | 	pup_block = [\ | 
					
						
							|  |  |  | 	('Mesh Options...'),\ | 
					
						
							|  |  |  | 	('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\ | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | 	('Rotate X90', EXPORT_ROTX90 , 'Rotate on export so Blenders UP is translated into OBJs UP'),\ | 
					
						
							| 
									
										
										
										
											2006-04-03 16:14:24 +00:00
										 |  |  | 	('Triangulate', EXPORT_TRI, 'Triangulate quadsModifiers.'),\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\ | 
					
						
							|  |  |  | 	('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\ | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | 	('High Quality Normals', EXPORT_NORMALS_HQ, 'Calculate high quality normals for rendering.'),\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	('UVs', EXPORT_UV, 'Export texface UV coords.'),\ | 
					
						
							| 
									
										
										
										
											2006-04-03 21:48:18 +00:00
										 |  |  | 	('Materials', EXPORT_MTL, 'Write a separate MTL file with the OBJ.'),\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	('Context...'),\ | 
					
						
							|  |  |  | 	('Selection Only', EXPORT_SEL_ONLY, 'Only export objects in visible selection. Else export whole scene.'),\ | 
					
						
							|  |  |  | 	('All Scenes', EXPORT_ALL_SCENES, 'Each scene as a seperate OBJ file.'),\ | 
					
						
							|  |  |  | 	('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\ | 
					
						
							|  |  |  | 	('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\ | 
					
						
							|  |  |  | 	('Grouping...'),\ | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | 	('Objects', EXPORT_BLEN_OBS, 'Export blender objects as "OBJ objects".'),\ | 
					
						
							|  |  |  | 	('Object Groups', EXPORT_GROUP_BY_OB, 'Export blender objects as "OBJ Groups".'),\ | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	('Material Groups', EXPORT_GROUP_BY_MAT, 'Group by materials.'),\ | 
					
						
							|  |  |  | 	] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if not Draw.PupBlock('Export...', pup_block): | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 	Window.EditMode(0) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	Window.WaitCursor(1) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val | 
					
						
							| 
									
										
										
										
											2006-08-06 11:32:12 +00:00
										 |  |  | 	EXPORT_ROTX90 = EXPORT_ROTX90.val | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	EXPORT_TRI = EXPORT_TRI.val | 
					
						
							|  |  |  | 	EXPORT_EDGES = EXPORT_EDGES.val | 
					
						
							|  |  |  | 	EXPORT_NORMALS = EXPORT_NORMALS.val | 
					
						
							| 
									
										
										
										
											2006-07-06 12:25:04 +00:00
										 |  |  | 	EXPORT_NORMALS_HQ = EXPORT_NORMALS_HQ.val | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 	EXPORT_UV = EXPORT_UV.val | 
					
						
							|  |  |  | 	EXPORT_MTL = EXPORT_MTL.val | 
					
						
							|  |  |  | 	EXPORT_SEL_ONLY = EXPORT_SEL_ONLY.val | 
					
						
							|  |  |  | 	EXPORT_ALL_SCENES = EXPORT_ALL_SCENES.val | 
					
						
							|  |  |  | 	EXPORT_ANIMATION = EXPORT_ANIMATION.val | 
					
						
							|  |  |  | 	EXPORT_COPY_IMAGES = EXPORT_COPY_IMAGES.val | 
					
						
							|  |  |  | 	EXPORT_BLEN_OBS = EXPORT_BLEN_OBS.val | 
					
						
							|  |  |  | 	EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val | 
					
						
							|  |  |  | 	EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	base_name, ext = splitExt(filename) | 
					
						
							|  |  |  | 	context_name = [base_name, '', '', ext] # basename, scene_name, framenumber, extension | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Use the options to export the data using write() | 
					
						
							|  |  |  | 	# def write(filename, objects, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True): | 
					
						
							|  |  |  | 	orig_scene = Scene.GetCurrent() | 
					
						
							|  |  |  | 	if EXPORT_ALL_SCENES: | 
					
						
							|  |  |  | 		export_scenes = Scene.Get() | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		export_scenes = [orig_scene] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Export all scenes. | 
					
						
							|  |  |  | 	for scn in export_scenes: | 
					
						
							|  |  |  | 		scn.makeCurrent() # If alredy current, this is not slow. | 
					
						
							|  |  |  | 		context = scn.getRenderingContext() | 
					
						
							|  |  |  | 		orig_frame = Blender.Get('curframe') | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if EXPORT_ALL_SCENES: # Add scene name into the context_name | 
					
						
							|  |  |  | 			context_name[1] = '_%s' % saneFilechars(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		# Export an animation? | 
					
						
							|  |  |  | 		if EXPORT_ANIMATION: | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 			scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame. | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			scene_frames = [orig_frame] # Dont export an animation. | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		# Loop through all frames in the scene and export. | 
					
						
							|  |  |  | 		for frame in scene_frames: | 
					
						
							|  |  |  | 			if EXPORT_ANIMATION: # Add frame to the filename. | 
					
						
							|  |  |  | 				context_name[2] = '_%.6d' % frame | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			Blender.Set('curframe', frame) | 
					
						
							|  |  |  | 			if EXPORT_SEL_ONLY: | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 				export_objects = scn.objects.selected #Blender.Object.GetSelected() # Export Context | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			else:	 | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 				export_objects = scn.objects # scn.getChildren() | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			full_path= ''.join(context_name) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-09-25 05:12:37 +00:00
										 |  |  | 			if BPyMessages.Warning_SaveOver(full_path): | 
					
						
							|  |  |  | 				# EXPORT THE FILE. | 
					
						
							|  |  |  | 				write(full_path, export_objects,\ | 
					
						
							|  |  |  | 				EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ | 
					
						
							|  |  |  | 				EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ | 
					
						
							|  |  |  | 				EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ | 
					
						
							|  |  |  | 				EXPORT_ROTX90, EXPORT_BLEN_OBS,\ | 
					
						
							|  |  |  | 				EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT) | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		Blender.Set('curframe', orig_frame) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Restore old active scene. | 
					
						
							|  |  |  | 	orig_scene.makeCurrent() | 
					
						
							|  |  |  | 	Window.WaitCursor(0) | 
					
						
							| 
									
										
										
										
											2005-10-11 02:32:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-29 19:17:53 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  | 	Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj')) |