2006-01-12 21:33:42 +00:00
#!BPY
"""
2006-07-03 03:22:48 +00:00
Name : ' Stanford PLY (*.ply)... '
Blender : 241
2006-01-12 21:33:42 +00:00
Group : ' Export '
2006-07-03 03:22:48 +00:00
Tooltip : ' Export active object to Stanford PLY format '
2006-01-12 21:33:42 +00:00
"""
2007-12-05 20:21:25 +00:00
import bpy
2006-01-12 21:33:42 +00:00
import Blender
2007-01-09 16:01:38 +00:00
from Blender import Mesh , Scene , Window , sys , Image , Draw
2006-07-03 03:22:48 +00:00
import BPyMesh
2006-01-12 21:33:42 +00:00
__author__ = " Bruce Merry "
2008-08-11 03:52:21 +00:00
__version__ = " 0.93 "
2006-01-12 21:33:42 +00:00
__bpydoc__ = """ \
2007-01-09 16:01:38 +00:00
This script exports Stanford PLY files from Blender . It supports normals ,
colours , and texture coordinates per face or per vertex .
Only one mesh can be exported at a time .
2006-01-12 21:33:42 +00:00
"""
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
#
# 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.
2006-07-03 03:22:48 +00:00
# Vector rounding se we can use as keys
2007-01-09 16:01:38 +00:00
#
2008-08-11 03:52:21 +00:00
# Updated on Aug 11, 2008 by Campbell Barton
# - added 'comment' prefix to comments - Needed to comply with the PLY spec.
2007-01-09 16:01:38 +00:00
#
# Updated on Jan 1, 2007 by Gabe Ghearing
# - fixed normals so they are correctly smooth/flat
# - fixed crash when the model doesn't have uv coords or vertex colors
# - fixed crash when the model has vertex colors but doesn't have uv coords
# - changed float32 to float and uint8 to uchar for compatibility
# Errata/Notes as of Jan 1, 2007
# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
#
# Updated on Jan 3, 2007 by Gabe Ghearing
# - fixed "sticky" vertex UV exporting
# - added pupmenu to enable/disable exporting normals, uv coords, and colors
# Errata/Notes as of Jan 3, 2007
# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
# - edges should be exported since PLY files support them
# - code is getting spaghettish, it should be refactored...
#
def rvec3d ( v ) : return round ( v [ 0 ] , 6 ) , round ( v [ 1 ] , 6 ) , round ( v [ 2 ] , 6 )
def rvec2d ( v ) : return round ( v [ 0 ] , 6 ) , round ( v [ 1 ] , 6 )
2006-01-12 21:33:42 +00:00
2006-07-03 03:22:48 +00:00
def file_callback ( filename ) :
2007-01-09 16:01:38 +00:00
2006-07-03 03:22:48 +00:00
if not filename . lower ( ) . endswith ( ' .ply ' ) :
filename + = ' .ply '
2007-12-05 20:21:25 +00:00
scn = bpy . data . scenes . active
2007-01-09 16:01:38 +00:00
ob = scn . objects . active
if not ob :
2006-07-03 03:22:48 +00:00
Blender . Draw . PupMenu ( ' Error % t|Select 1 active object ' )
return
file = open ( filename , ' wb ' )
2006-07-03 20:17:40 +00:00
2007-01-09 16:01:38 +00:00
EXPORT_APPLY_MODIFIERS = Draw . Create ( 1 )
EXPORT_NORMALS = Draw . Create ( 1 )
EXPORT_UV = Draw . Create ( 1 )
EXPORT_COLORS = Draw . Create ( 1 )
#EXPORT_EDGES = Draw.Create(0)
pup_block = [ \
( ' Apply Modifiers ' , EXPORT_APPLY_MODIFIERS , ' Use transformed mesh data. ' ) , \
( ' Normals ' , EXPORT_NORMALS , ' Export vertex normal data. ' ) , \
( ' UVs ' , EXPORT_UV , ' Export texface UV coords. ' ) , \
( ' Colors ' , EXPORT_COLORS , ' Export vertex Colors. ' ) , \
#('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\
]
if not Draw . PupBlock ( ' Export... ' , pup_block ) :
return
2007-12-05 20:21:25 +00:00
is_editmode = Blender . Window . EditMode ( )
if is_editmode :
Blender . Window . EditMode ( 0 , ' ' , 0 )
2007-01-09 16:01:38 +00:00
Window . WaitCursor ( 1 )
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS . val
EXPORT_NORMALS = EXPORT_NORMALS . val
EXPORT_UV = EXPORT_UV . val
EXPORT_COLORS = EXPORT_COLORS . val
#EXPORT_EDGES = EXPORT_EDGES.val
mesh = BPyMesh . getMeshFromObject ( ob , None , EXPORT_APPLY_MODIFIERS , False , scn )
2006-07-03 03:22:48 +00:00
if not mesh :
Blender . Draw . PupMenu ( ' Error % t|Could not get mesh data from active object ' )
return
2006-07-03 20:17:40 +00:00
2007-01-09 16:01:38 +00:00
mesh . transform ( ob . matrixWorld )
faceUV = mesh . faceUV
vertexUV = mesh . vertexUV
vertexColors = mesh . vertexColors
if ( not faceUV ) and ( not vertexUV ) : EXPORT_UV = False
if not vertexColors : EXPORT_COLORS = False
2006-07-03 20:17:40 +00:00
2007-01-09 16:01:38 +00:00
if not EXPORT_UV : faceUV = vertexUV = False
if not EXPORT_COLORS : vertexColors = False
# incase
color = uvcoord = uvcoord_key = normal = normal_key = None
2006-07-03 20:17:40 +00:00
2006-07-03 03:22:48 +00:00
verts = [ ] # list of dictionaries
2007-01-09 16:01:38 +00:00
# vdict = {} # (index, normal, uv) -> new index
vdict = [ { } for i in xrange ( len ( mesh . verts ) ) ]
vert_count = 0
2006-07-03 03:22:48 +00:00
for i , f in enumerate ( mesh . faces ) :
2007-01-09 16:01:38 +00:00
smooth = f . smooth
if not smooth :
normal = tuple ( f . no )
normal_key = rvec3d ( normal )
if faceUV : uv = f . uv
if vertexColors : col = f . col
for j , v in enumerate ( f ) :
if smooth :
2007-12-05 20:21:25 +00:00
normal = tuple ( v . no )
2007-01-09 16:01:38 +00:00
normal_key = rvec3d ( normal )
if faceUV :
2008-10-20 13:36:18 +00:00
uvcoord = uv [ j ] [ 0 ] , 1.0 - uv [ j ] [ 1 ]
2007-01-09 16:01:38 +00:00
uvcoord_key = rvec2d ( uvcoord )
elif vertexUV :
2008-10-20 13:36:18 +00:00
uvcoord = v . uvco [ 0 ] , 1.0 - v . uvco [ 1 ]
2007-01-09 16:01:38 +00:00
uvcoord_key = rvec2d ( uvcoord )
2006-07-03 03:22:48 +00:00
2007-01-09 16:01:38 +00:00
if vertexColors : color = col [ j ] . r , col [ j ] . g , col [ j ] . b
key = normal_key , uvcoord_key , color
vdict_local = vdict [ v . index ]
if ( not vdict_local ) or ( not vdict_local . has_key ( key ) ) :
vdict_local [ key ] = vert_count ;
verts . append ( ( tuple ( v . co ) , normal , uvcoord , color ) )
vert_count + = 1
2006-07-03 03:22:48 +00:00
file . write ( ' ply \n ' )
file . write ( ' format ascii 1.0 \n ' )
2008-08-11 03:52:21 +00:00
file . write ( ' comment Created by Blender3D %s - www.blender.org, source file: %s \n ' % ( Blender . Get ( ' version ' ) , Blender . Get ( ' filename ' ) . split ( ' / ' ) [ - 1 ] . split ( ' \\ ' ) [ - 1 ] ) )
2006-07-03 03:22:48 +00:00
file . write ( ' element vertex %d \n ' % len ( verts ) )
2007-01-09 16:01:38 +00:00
file . write ( ' property float x \n ' )
file . write ( ' property float y \n ' )
file . write ( ' property float z \n ' )
if EXPORT_NORMALS :
file . write ( ' property float nx \n ' )
file . write ( ' property float ny \n ' )
file . write ( ' property float nz \n ' )
2006-07-03 03:22:48 +00:00
2007-01-09 16:01:38 +00:00
if EXPORT_UV :
file . write ( ' property float s \n ' )
file . write ( ' property float t \n ' )
if EXPORT_COLORS :
file . write ( ' property uchar red \n ' )
file . write ( ' property uchar green \n ' )
file . write ( ' property uchar blue \n ' )
2006-07-03 03:22:48 +00:00
file . write ( ' element face %d \n ' % len ( mesh . faces ) )
2007-01-09 16:01:38 +00:00
file . write ( ' property list uchar uint vertex_indices \n ' )
2006-07-03 03:22:48 +00:00
file . write ( ' end_header \n ' )
2006-01-12 21:33:42 +00:00
2006-07-03 03:22:48 +00:00
for i , v in enumerate ( verts ) :
2007-01-09 16:01:38 +00:00
file . write ( ' %.6f %.6f %.6f ' % v [ 0 ] ) # co
if EXPORT_NORMALS :
file . write ( ' %.6f %.6f %.6f ' % v [ 1 ] ) # no
2006-07-03 03:22:48 +00:00
2007-01-09 16:01:38 +00:00
if EXPORT_UV :
file . write ( ' %.6f %.6f ' % v [ 2 ] ) # uv
if EXPORT_COLORS :
file . write ( ' %u %u %u ' % v [ 3 ] ) # col
2006-07-03 03:22:48 +00:00
file . write ( ' \n ' )
for ( i , f ) in enumerate ( mesh . faces ) :
file . write ( ' %d ' % len ( f ) )
2007-01-09 16:01:38 +00:00
smooth = f . smooth
if not smooth : no = rvec3d ( f . no )
2006-07-03 03:22:48 +00:00
2007-01-09 16:01:38 +00:00
if faceUV : uv = f . uv
if vertexColors : col = f . col
for j , v in enumerate ( f ) :
if f . smooth : normal = rvec3d ( v . no )
else : normal = no
2008-10-20 13:36:18 +00:00
if faceUV : uvcoord = rvec2d ( ( uv [ j ] [ 0 ] , 1.0 - uv [ j ] [ 1 ] ) )
elif vertexUV : uvcoord = rvec2d ( ( v . uvco [ 0 ] , 1.0 - v . uvco [ 1 ] ) )
2007-01-09 16:01:38 +00:00
if vertexColors : color = col [ j ] . r , col [ j ] . g , col [ j ] . b
2006-07-03 03:22:48 +00:00
2007-01-09 16:01:38 +00:00
file . write ( ' %d ' % vdict [ v . index ] [ normal , uvcoord , color ] )
2006-07-03 03:22:48 +00:00
file . write ( ' \n ' )
2006-01-12 21:33:42 +00:00
file . close ( )
2007-12-05 20:21:25 +00:00
if is_editmode :
Blender . Window . EditMode ( 1 , ' ' , 0 )
2006-07-03 20:17:40 +00:00
def main ( ) :
Blender . Window . FileSelector ( file_callback , ' PLY Export ' , Blender . sys . makename ( ext = ' .ply ' ) )
if __name__ == ' __main__ ' :
main ( )