4 Name: 'Stanford PLY (*.ply)...'
7 Tooltip: 'Export active object to Stanford PLY format'
11 from Blender
import Mesh
, Scene
, Window
, sys
, Image
, Draw
14 __author__
= "Bruce Merry"
17 This script exports Stanford PLY files from Blender. It supports normals,
18 colours, and texture coordinates per face or per vertex.
19 Only one mesh can be exported at a time.
22 # Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
24 # This program is free software; you can redistribute it and/or
25 # modify it under the terms of the GNU General Public License
26 # as published by the Free Software Foundation; either version 2
27 # of the License, or (at your option) any later version.
29 # This program is distributed in the hope that it will be useful,
30 # but WITHOUT ANY WARRANTY; without even the implied warranty of
31 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 # GNU General Public License for more details.
34 # You should have received a copy of the GNU General Public License
35 # along with this program; if not, write to the Free Software Foundation,
36 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 # Vector rounding se we can use as keys
40 # Updated on Jan 1, 2007 by Gabe Ghearing
41 # - fixed normals so they are correctly smooth/flat
42 # - fixed crash when the model doesn't have uv coords or vertex colors
43 # - fixed crash when the model has vertex colors but doesn't have uv coords
44 # - changed float32 to float and uint8 to uchar for compatibility
45 # Errata/Notes as of Jan 1, 2007
46 # - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
47 # - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
49 # Updated on Jan 3, 2007 by Gabe Ghearing
50 # - fixed "sticky" vertex UV exporting
51 # - added pupmenu to enable/disable exporting normals, uv coords, and colors
52 # Errata/Notes as of Jan 3, 2007
53 # - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
54 # - edges should be exported since PLY files support them
55 # - code is getting spaghettish, it should be refactored...
59 def rvec3d(v
): return round(v
[0], 6), round(v
[1], 6), round(v
[2], 6)
60 def rvec2d(v
): return round(v
[0], 6), round(v
[1], 6)
62 def file_callback(filename
):
64 if not filename
.lower().endswith('.ply'):
67 scn
= Blender
.Scene
.GetCurrent()
68 ob
= scn
.objects
.active
70 Blender
.Draw
.PupMenu('Error%t|Select 1 active object')
73 file = open(filename
, 'wb')
75 EXPORT_APPLY_MODIFIERS
= Draw
.Create(1)
76 EXPORT_NORMALS
= Draw
.Create(1)
77 EXPORT_UV
= Draw
.Create(1)
78 EXPORT_COLORS
= Draw
.Create(1)
79 #EXPORT_EDGES = Draw.Create(0)
82 ('Apply Modifiers', EXPORT_APPLY_MODIFIERS
, 'Use transformed mesh data.'),\
83 ('Normals', EXPORT_NORMALS
, 'Export vertex normal data.'),\
84 ('UVs', EXPORT_UV
, 'Export texface UV coords.'),\
85 ('Colors', EXPORT_COLORS
, 'Export vertex Colors.'),\
86 #('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\
89 if not Draw
.PupBlock('Export...', pup_block
):
94 EXPORT_APPLY_MODIFIERS
= EXPORT_APPLY_MODIFIERS
.val
95 EXPORT_NORMALS
= EXPORT_NORMALS
.val
96 EXPORT_UV
= EXPORT_UV
.val
97 EXPORT_COLORS
= EXPORT_COLORS
.val
98 #EXPORT_EDGES = EXPORT_EDGES.val
100 mesh
= BPyMesh
.getMeshFromObject(ob
, None, EXPORT_APPLY_MODIFIERS
, False, scn
)
103 Blender
.Draw
.PupMenu('Error%t|Could not get mesh data from active object')
106 mesh
.transform(ob
.matrixWorld
)
109 vertexUV
= mesh
.vertexUV
110 vertexColors
= mesh
.vertexColors
112 if (not faceUV
) and (not vertexUV
): EXPORT_UV
= False
113 if not vertexColors
: EXPORT_COLORS
= False
115 if not EXPORT_UV
: faceUV
= vertexUV
= False
116 if not EXPORT_COLORS
: vertexColors
= False
119 color
= uvcoord
= uvcoord_key
= normal
= normal_key
= None
121 verts
= [] # list of dictionaries
122 # vdict = {} # (index, normal, uv) -> new index
123 vdict
= [{} for i
in xrange(len(mesh
.verts
))]
125 for i
, f
in enumerate(mesh
.faces
):
129 normal_key
= rvec3d(normal
)
132 if vertexColors
: col
= f
.col
133 for j
, v
in enumerate(f
):
136 normal_key
= rvec3d(normal
)
139 uvcoord
= tuple(uv
[j
])
140 uvcoord_key
= rvec2d(uvcoord
)
142 uvcoord
= tuple(v
.uvco
)
143 uvcoord_key
= rvec2d(uvcoord
)
145 if vertexColors
: color
= col
[j
].r
, col
[j
].g
, col
[j
].b
148 key
= normal_key
, uvcoord_key
, color
150 vdict_local
= vdict
[v
.index
]
152 if (not vdict_local
) or (not vdict_local
.has_key(key
)):
153 vdict_local
[key
] = vert_count
;
154 verts
.append( (tuple(v
.co
), normal
, uvcoord
, color
) )
159 file.write('format ascii 1.0\n')
160 file.write('Created by Blender3D %s - www.blender.org, source file: %s\n' % (Blender
.Get('version'), Blender
.Get('filename').split('/')[-1].split('\\')[-1] ))
162 file.write('element vertex %d\n' % len(verts
))
164 file.write('property float x\n')
165 file.write('property float y\n')
166 file.write('property float z\n')
168 file.write('property float nx\n')
169 file.write('property float ny\n')
170 file.write('property float nz\n')
173 file.write('property float s\n')
174 file.write('property float t\n')
176 file.write('property uchar red\n')
177 file.write('property uchar green\n')
178 file.write('property uchar blue\n')
180 file.write('element face %d\n' % len(mesh
.faces
))
181 file.write('property list uchar uint vertex_indices\n')
182 file.write('end_header\n')
184 for i
, v
in enumerate(verts
):
185 file.write('%.6f %.6f %.6f ' % v
[0]) # co
187 file.write('%.6f %.6f %.6f ' % v
[1]) # no
190 file.write('%.6f %.6f ' % v
[2]) # uv
192 file.write('%u %u %u' % v
[3]) # col
195 for (i
, f
) in enumerate(mesh
.faces
):
196 file.write('%d ' % len(f
))
198 if not smooth
: no
= rvec3d(f
.no
)
201 if vertexColors
: col
= f
.col
202 for j
, v
in enumerate(f
):
203 if f
.smooth
: normal
= rvec3d(v
.no
)
205 if faceUV
: uvcoord
= rvec2d(uv
[j
])
206 elif vertexUV
: uvcoord
= rvec2d(v
.uvco
)
207 if vertexColors
: color
= col
[j
].r
, col
[j
].g
, col
[j
].b
210 file.write('%d ' % vdict
[v
.index
][normal
, uvcoord
, color
])
218 Blender
.Window
.FileSelector(file_callback
, 'PLY Export', Blender
.sys
.makename(ext
='.ply'))
221 if __name__
=='__main__':