[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21219] branches/soc-2009-kazanbas: OBJ exporter working (Python 3.0), but needs testing and fixing.
Arystanbek Dyussenov
arystan.d at gmail.com
Sun Jun 28 15:29:03 CEST 2009
Revision: 21219
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21219
Author: kazanbas
Date: 2009-06-28 15:29:03 +0200 (Sun, 28 Jun 2009)
Log Message:
-----------
OBJ exporter working (Python 3.0), but needs testing and fixing.
Current issues:
- NURBS - needs API additions
- "all scenes" export - cannot switch scene in bpy
- normal calculation, disabled
- duplis - need testing, only dupliverts tested
- matrix problem
- UI, 18 options currently don't fit into filesel panel, will do manual lay out once it's available
- probably others...
BPY:
- made operator "execute" method required to avoid crash
- added bpy.sys module which replicates old "sys" module
API:
- replaced create_*_mesh with a single create_mesh accepting type parameter
- added Mesh.create_copy to create a copy of a mesh with 0 users
Ran `dos2unix` on source/blender/python/SConscript
Modified Paths:
--------------
branches/soc-2009-kazanbas/release/io/export_ply.py
branches/soc-2009-kazanbas/release/scripts/3ds_export.py
branches/soc-2009-kazanbas/release/ui/space_script.py
branches/soc-2009-kazanbas/source/blender/makesrna/intern/rna_mesh_api.c
branches/soc-2009-kazanbas/source/blender/makesrna/intern/rna_object_api.c
branches/soc-2009-kazanbas/source/blender/python/SConscript
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_interface.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_operator_wrap.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_rna.c
Added Paths:
-----------
branches/soc-2009-kazanbas/release/io/export_obj.py
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_sys.c
branches/soc-2009-kazanbas/source/blender/python/intern/bpy_sys.h
Removed Paths:
-------------
branches/soc-2009-kazanbas/release/io/export_obj.py
branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py
Deleted: branches/soc-2009-kazanbas/release/io/export_obj.py
===================================================================
--- branches/soc-2009-kazanbas/release/io/export_obj.py 2009-06-28 13:27:06 UTC (rev 21218)
+++ branches/soc-2009-kazanbas/release/io/export_obj.py 2009-06-28 13:29:03 UTC (rev 21219)
@@ -1,83 +0,0 @@
-import bpy
-
-def write_obj(filepath, scene, ob):
- out = open(filepath, 'w')
-
- # create a temporary mesh
- mesh = ob.create_render_mesh(scene)
-
- # for vert in mesh.verts:
- # ^ iterating that way doesn't work atm for some reason
-
- for i in range(len(mesh.verts)):
- vert = mesh.verts[i]
- out.write('v {0} {1} {2}\n'.format(vert.co[0], vert.co[1], vert.co[2]))
-
- for i in range(len(mesh.faces)):
- face = mesh.faces[i]
- out.write('f')
-
- # but this works
- for index in face.verts:
- out.write(' {0}'.format(index + 1))
- out.write('\n')
-
- # delete mesh gain
- bpy.data.remove_mesh(mesh)
-
- out.close()
-
-class SCRIPT_OT_export_obj(bpy.types.Operator):
- '''A very basic OBJ exporter, writes only active object's mesh.'''
-
- __label__ = 'Export OBJ'
-
- # List of operator properties, the attributes will be assigned
- # to the class instance from the operator settings before calling.
- __props__ = [
- bpy.props.StringProperty(attr="filename", name="filename")
- ]
-
- def debug(self, message):
- print("{0}: {1}".format(self.__class__.__name__, message))
-
- def execute_(self, context):
- self.debug("exec")
- self.debug("filename = " + self.filename)
-
- act = context.active_object
-
- if act.type == 'MESH':
- write_obj(self.filename, context.scene, act)
- else:
- self.debug("Active object is not a MESH.")
-
- # XXX errors are silenced for some reason
-# raise Exception("oops!")
-
- return ('FINISHED',)
-
- def execute(self, context):
- self.debug("exec")
-
- act = context.active_object
-
- act.create_dupli_list()
- print("{0} has {1} dupli objects".format(act.name, len(act.dupli_list)))
-
- act.free_dupli_list()
-
- return ('FINISHED',)
-
- def invoke(self, context, event):
- self.debug("invoke")
- wm = context.manager
- wm.add_fileselect(self.__operator__)
- return ('RUNNING_MODAL',)
-
- def poll(self, context): # poll isnt working yet
- self.debug("poll")
- return True
-
-bpy.ops.add(SCRIPT_OT_export_obj)
-
Copied: branches/soc-2009-kazanbas/release/io/export_obj.py (from rev 21172, branches/soc-2009-kazanbas/release/scripts/export_obj-2.5.py)
===================================================================
--- branches/soc-2009-kazanbas/release/io/export_obj.py (rev 0)
+++ branches/soc-2009-kazanbas/release/io/export_obj.py 2009-06-28 13:29:03 UTC (rev 21219)
@@ -0,0 +1,961 @@
+#!BPY
+
+"""
+Name: 'Wavefront (.obj)...'
+Blender: 248
+Group: 'Export'
+Tooltip: 'Save a Wavefront OBJ File'
+"""
+
+__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
+__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
+__version__ = "1.21"
+
+__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 os # os.sep
+import Mathutils
+
+# 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(' ', '_')
+
+
+# this used to be in BPySys module
+# frankly, I don't understand how it works
+def BPySys_cleanName(name):
+
+ v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
+
+ invalid = ''.join([chr(i) for i in v])
+
+ for ch in invalid:
+ name = name.replace(ch, '_')
+ return name
+
+# A Dict of Materials
+# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
+MTL_DICT = {}
+
+def write_mtl(scene, filename):
+
+ world = scene.world
+ worldAmb = world.ambient_color
+
+ file = open(filename, "w")
+ # XXX
+# 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.items():
+
+ # 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.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_reflection for c in mat.diffuse_color]) ) # Diffuse
+ file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_reflection for c in mat.specular_color]) ) # 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.shadeless:
+ file.write('illum 0\n') # ignore lighting
+ elif mat.specular_reflection == 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.textures:
+ if mtex and mtex.texure.type == 'IMAGE':
+ try:
+ filename = mtex.texture.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] != os.sep:
+ dest_dir += os.sep
+# if dest_dir[-1] != sys.sep:
+# dest_dir += sys.sep
+
+ # Get unique image names
+ uniqueImages = {}
+ for matname, mat, image in MTL_DICT.values(): # 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.textures:
+ if mtex and mtex.texture.type == 'IMAGE':
+ image_tex = mtex.texture.image
+ if image_tex:
+ try:
+ uniqueImages[image_tex] = image_tex
+ except:
+ pass
+
+ # Now copy images
+ copyCount = 0
+
+ for bImage in uniqueImages.values():
+ image_path = bpy.sys.expandpath(bImage.filename)
+ if bpy.sys.exists(image_path):
+ # Make a name for the target path.
+ dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+ if not bpy.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)
+
+# XXX not converted
+def test_nurbs_compat(ob):
+ if ob.type != 'CURVE':
+ return False
+
+ for nu in ob.data.curves:
+ if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier
+ return True
+
+# for nu in ob.data:
+# if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier
+# return True
+
+ return False
+
+# XXX not converted
+def write_nurb(file, ob, ob_mat):
+ tot_verts = 0
+ cu = ob.data
+
+ # use negative indices
+ Vector = Blender.Mathutils.Vector
+ for nu in cu:
+
+ if nu.type==0: DEG_ORDER_U = 1
+ else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
+
+ if nu.type==1:
+ print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported")
+ continue
+
+ if nu.knotsV:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list