4 Name: 'Stanford PLY (*.ply)...'
7 Tooltip: 'Export active object to Stanford PLY format'
12 from Blender import Mesh, Scene, Window, sys, Image, Draw
15 __author__ = "Bruce Merry"
18 This script exports Stanford PLY files from Blender. It supports normals,
19 colours, and texture coordinates per face or per vertex.
20 Only one mesh can be exported at a time.
23 # Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
25 # This program is free software; you can redistribute it and/or
26 # modify it under the terms of the GNU General Public License
27 # as published by the Free Software Foundation; either version 2
28 # of the License, or (at your option) any later version.
30 # This program is distributed in the hope that it will be useful,
31 # but WITHOUT ANY WARRANTY; without even the implied warranty of
32 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 # GNU General Public License for more details.
35 # You should have received a copy of the GNU General Public License
36 # along with this program; if not, write to the Free Software Foundation,
37 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 # Vector rounding se we can use as keys
40 # Updated on Aug 11, 2008 by Campbell Barton
41 # - added 'comment' prefix to comments - Needed to comply with the PLY spec.
43 # Updated on Jan 1, 2007 by Gabe Ghearing
44 # - fixed normals so they are correctly smooth/flat
45 # - fixed crash when the model doesn't have uv coords or vertex colors
46 # - fixed crash when the model has vertex colors but doesn't have uv coords
47 # - changed float32 to float and uint8 to uchar for compatibility
48 # Errata/Notes as of Jan 1, 2007
49 # - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
50 # - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
52 # Updated on Jan 3, 2007 by Gabe Ghearing
53 # - fixed "sticky" vertex UV exporting
54 # - added pupmenu to enable/disable exporting normals, uv coords, and colors
55 # Errata/Notes as of Jan 3, 2007
56 # - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
57 # - edges should be exported since PLY files support them
58 # - code is getting spaghettish, it should be refactored...
62 def rvec3d(v): return round(v[0], 6), round(v[1], 6), round(v[2], 6)
63 def rvec2d(v): return round(v[0], 6), round(v[1], 6)
65 def file_callback(filename):
67 if not filename.lower().endswith('.ply'):
70 scn= bpy.data.scenes.active
71 ob= scn.objects.active
73 Blender.Draw.PupMenu('Error%t|Select 1 active object')
76 file = open(filename, 'wb')
78 EXPORT_APPLY_MODIFIERS = Draw.Create(1)
79 EXPORT_NORMALS = Draw.Create(1)
80 EXPORT_UV = Draw.Create(1)
81 EXPORT_COLORS = Draw.Create(1)
82 #EXPORT_EDGES = Draw.Create(0)
85 ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data.'),\
86 ('Normals', EXPORT_NORMALS, 'Export vertex normal data.'),\
87 ('UVs', EXPORT_UV, 'Export texface UV coords.'),\
88 ('Colors', EXPORT_COLORS, 'Export vertex Colors.'),\
89 #('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\
92 if not Draw.PupBlock('Export...', pup_block):
95 is_editmode = Blender.Window.EditMode()
97 Blender.Window.EditMode(0, '', 0)
101 EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val
102 EXPORT_NORMALS = EXPORT_NORMALS.val
103 EXPORT_UV = EXPORT_UV.val
104 EXPORT_COLORS = EXPORT_COLORS.val
105 #EXPORT_EDGES = EXPORT_EDGES.val
107 mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn)
110 Blender.Draw.PupMenu('Error%t|Could not get mesh data from active object')
113 mesh.transform(ob.matrixWorld)
116 vertexUV = mesh.vertexUV
117 vertexColors = mesh.vertexColors
119 if (not faceUV) and (not vertexUV): EXPORT_UV = False
120 if not vertexColors: EXPORT_COLORS = False
122 if not EXPORT_UV: faceUV = vertexUV = False
123 if not EXPORT_COLORS: vertexColors = False
126 color = uvcoord = uvcoord_key = normal = normal_key = None
128 verts = [] # list of dictionaries
129 # vdict = {} # (index, normal, uv) -> new index
130 vdict = [{} for i in xrange(len(mesh.verts))]
132 for i, f in enumerate(mesh.faces):
136 normal_key = rvec3d(normal)
139 if vertexColors: col = f.col
140 for j, v in enumerate(f):
143 normal_key = rvec3d(normal)
146 uvcoord= uv[j][0], 1.0-uv[j][1]
147 uvcoord_key = rvec2d(uvcoord)
149 uvcoord= v.uvco[0], 1.0-v.uvco[1]
150 uvcoord_key = rvec2d(uvcoord)
152 if vertexColors: color= col[j].r, col[j].g, col[j].b
155 key = normal_key, uvcoord_key, color
157 vdict_local = vdict[v.index]
159 if (not vdict_local) or (not vdict_local.has_key(key)):
160 vdict_local[key] = vert_count;
161 verts.append( (tuple(v.co), normal, uvcoord, color) )
166 file.write('format ascii 1.0\n')
167 file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
169 file.write('element vertex %d\n' % len(verts))
171 file.write('property float x\n')
172 file.write('property float y\n')
173 file.write('property float z\n')
175 file.write('property float nx\n')
176 file.write('property float ny\n')
177 file.write('property float nz\n')
180 file.write('property float s\n')
181 file.write('property float t\n')
183 file.write('property uchar red\n')
184 file.write('property uchar green\n')
185 file.write('property uchar blue\n')
187 file.write('element face %d\n' % len(mesh.faces))
188 file.write('property list uchar uint vertex_indices\n')
189 file.write('end_header\n')
191 for i, v in enumerate(verts):
192 file.write('%.6f %.6f %.6f ' % v[0]) # co
194 file.write('%.6f %.6f %.6f ' % v[1]) # no
197 file.write('%.6f %.6f ' % v[2]) # uv
199 file.write('%u %u %u' % v[3]) # col
202 for (i, f) in enumerate(mesh.faces):
203 file.write('%d ' % len(f))
205 if not smooth: no = rvec3d(f.no)
208 if vertexColors: col = f.col
209 for j, v in enumerate(f):
210 if f.smooth: normal= rvec3d(v.no)
212 if faceUV: uvcoord= rvec2d((uv[j][0], 1.0-uv[j][1]))
213 elif vertexUV: uvcoord= rvec2d((v.uvco[0], 1.0-v.uvco[1]))
214 if vertexColors: color= col[j].r, col[j].g, col[j].b
216 file.write('%d ' % vdict[v.index][normal, uvcoord, color])
222 Blender.Window.EditMode(1, '', 0)
225 Blender.Window.FileSelector(file_callback, 'PLY Export', Blender.sys.makename(ext='.ply'))
227 if __name__=='__main__':