2009-11-01 15:21:20 +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.
|
2009-12-13 14:00:39 +00:00
|
|
|
#
|
2009-11-01 15:21:20 +00:00
|
|
|
# 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.
|
2009-12-13 14:00:39 +00:00
|
|
|
#
|
2009-11-01 15:21:20 +00:00
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-11-01 15:21:20 +00:00
|
|
|
#
|
|
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
|
2009-12-13 14:38:30 +00:00
|
|
|
# <pep8 compliant>
|
|
|
|
|
2010-09-01 02:48:23 +00:00
|
|
|
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
|
|
|
# Contributors: Bruce Merry, Campbell Barton
|
|
|
|
|
|
|
|
"""
|
2009-12-13 14:00:39 +00:00
|
|
|
This script exports Stanford PLY files from Blender. It supports normals,
|
2007-01-09 16:01:38 +00:00
|
|
|
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
|
|
|
"""
|
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
import bpy
|
|
|
|
import os
|
2009-12-16 13:27:30 +00:00
|
|
|
|
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
def save(operator, context, filepath="", use_modifiers=True, use_normals=True, use_uv_coords=True, use_colors=True):
|
2011-01-01 07:20:34 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
def rvec3d(v):
|
|
|
|
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
2006-01-12 21:33:42 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
def rvec2d(v):
|
|
|
|
return round(v[0], 6), round(v[1], 6)
|
2011-01-01 07:20:34 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
scene = context.scene
|
|
|
|
obj = context.object
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
if not obj:
|
2009-12-13 14:00:39 +00:00
|
|
|
raise Exception("Error, Select 1 active object")
|
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
file = open(filepath, 'w')
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-07-26 18:32:22 +00:00
|
|
|
if scene.objects.active:
|
|
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_modifiers:
|
|
|
|
mesh = obj.create_mesh(scene, True, 'PREVIEW')
|
2009-12-13 14:00:39 +00:00
|
|
|
else:
|
2010-09-01 12:11:34 +00:00
|
|
|
mesh = obj.data
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
if not mesh:
|
2010-09-01 12:11:34 +00:00
|
|
|
raise Exception("Error, could not get mesh data from active object")
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
# mesh.transform(obj.matrix_world) # XXX
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2009-12-16 13:27:30 +00:00
|
|
|
faceUV = (len(mesh.uv_textures) > 0)
|
|
|
|
vertexUV = (len(mesh.sticky) > 0)
|
2009-12-13 14:00:39 +00:00
|
|
|
vertexColors = len(mesh.vertex_colors) > 0
|
|
|
|
|
2009-12-16 13:27:30 +00:00
|
|
|
if (not faceUV) and (not vertexUV):
|
2010-09-01 12:11:34 +00:00
|
|
|
use_uv_coords = False
|
2009-12-16 13:27:30 +00:00
|
|
|
if not vertexColors:
|
2010-09-01 12:11:34 +00:00
|
|
|
use_colors = False
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
if not use_uv_coords:
|
2009-12-16 13:27:30 +00:00
|
|
|
faceUV = vertexUV = False
|
2010-09-01 12:11:34 +00:00
|
|
|
if not use_colors:
|
2009-12-16 13:27:30 +00:00
|
|
|
vertexColors = False
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
if faceUV:
|
2010-08-23 22:16:45 +00:00
|
|
|
active_uv_layer = mesh.uv_textures.active
|
2009-12-13 14:00:39 +00:00
|
|
|
if not active_uv_layer:
|
2010-09-01 12:11:34 +00:00
|
|
|
use_uv_coords = False
|
2009-12-13 14:00:39 +00:00
|
|
|
faceUV = None
|
2010-02-12 12:57:58 +00:00
|
|
|
else:
|
|
|
|
active_uv_layer = active_uv_layer.data
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
if vertexColors:
|
2010-08-23 22:16:45 +00:00
|
|
|
active_col_layer = mesh.vertex_colors.active
|
2009-12-13 14:00:39 +00:00
|
|
|
if not active_col_layer:
|
2010-09-01 12:11:34 +00:00
|
|
|
use_colors = False
|
2009-12-13 14:00:39 +00:00
|
|
|
vertexColors = None
|
2010-02-12 12:57:58 +00:00
|
|
|
else:
|
|
|
|
active_col_layer = active_col_layer.data
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
# incase
|
|
|
|
color = uvcoord = uvcoord_key = normal = normal_key = None
|
|
|
|
|
2011-01-01 07:20:34 +00:00
|
|
|
mesh_verts = mesh.vertices # save a lookup
|
|
|
|
ply_verts = [] # list of dictionaries
|
2009-12-13 14:00:39 +00:00
|
|
|
# vdict = {} # (index, normal, uv) -> new index
|
|
|
|
vdict = [{} for i in range(len(mesh_verts))]
|
|
|
|
ply_faces = [[] for f in range(len(mesh.faces))]
|
|
|
|
vert_count = 0
|
|
|
|
for i, f in enumerate(mesh.faces):
|
|
|
|
|
2010-08-18 07:14:10 +00:00
|
|
|
smooth = f.use_smooth
|
2009-12-13 14:00:39 +00:00
|
|
|
if not smooth:
|
|
|
|
normal = tuple(f.normal)
|
|
|
|
normal_key = rvec3d(normal)
|
|
|
|
|
|
|
|
if faceUV:
|
|
|
|
uv = active_uv_layer[i]
|
2011-01-01 07:20:34 +00:00
|
|
|
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
2009-12-13 14:00:39 +00:00
|
|
|
if vertexColors:
|
|
|
|
col = active_col_layer[i]
|
2010-12-24 04:24:33 +00:00
|
|
|
col = col.color1[:], col.color2[:], col.color3[:], col.color4[:]
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-08-18 03:42:26 +00:00
|
|
|
f_verts = f.vertices
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2009-12-16 13:27:30 +00:00
|
|
|
pf = ply_faces[i]
|
2009-12-13 14:00:39 +00:00
|
|
|
for j, vidx in enumerate(f_verts):
|
|
|
|
v = mesh_verts[vidx]
|
|
|
|
|
|
|
|
if smooth:
|
2009-12-16 13:27:30 +00:00
|
|
|
normal = tuple(v.normal)
|
2009-12-13 14:00:39 +00:00
|
|
|
normal_key = rvec3d(normal)
|
|
|
|
|
|
|
|
if faceUV:
|
2009-12-26 09:36:50 +00:00
|
|
|
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
2009-12-13 14:00:39 +00:00
|
|
|
uvcoord_key = rvec2d(uvcoord)
|
|
|
|
elif vertexUV:
|
2009-12-16 13:27:30 +00:00
|
|
|
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
2009-12-13 14:00:39 +00:00
|
|
|
uvcoord_key = rvec2d(uvcoord)
|
|
|
|
|
|
|
|
if vertexColors:
|
2009-12-16 13:27:30 +00:00
|
|
|
color = col[j]
|
|
|
|
color = int(color[0] * 255.0), int(color[1] * 255.0), int(color[2] * 255.0)
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
key = normal_key, uvcoord_key, color
|
|
|
|
|
|
|
|
vdict_local = vdict[vidx]
|
2011-01-01 07:20:34 +00:00
|
|
|
pf_vidx = vdict_local.get(key) # Will be None initially
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2011-01-01 07:20:34 +00:00
|
|
|
if pf_vidx is None: # same as vdict_local.has_key(key)
|
2009-12-16 13:27:30 +00:00
|
|
|
pf_vidx = vdict_local[key] = vert_count
|
2009-12-13 14:00:39 +00:00
|
|
|
ply_verts.append((vidx, normal, uvcoord, color))
|
|
|
|
vert_count += 1
|
|
|
|
|
|
|
|
pf.append(pf_vidx)
|
|
|
|
|
|
|
|
file.write('ply\n')
|
|
|
|
file.write('format ascii 1.0\n')
|
2010-09-01 12:11:34 +00:00
|
|
|
file.write('comment Created by Blender %s - www.blender.org, source file: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
file.write('element vertex %d\n' % len(ply_verts))
|
|
|
|
|
|
|
|
file.write('property float x\n')
|
|
|
|
file.write('property float y\n')
|
|
|
|
file.write('property float z\n')
|
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_normals:
|
2009-12-13 14:00:39 +00:00
|
|
|
file.write('property float nx\n')
|
|
|
|
file.write('property float ny\n')
|
|
|
|
file.write('property float nz\n')
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_uv_coords:
|
2009-12-13 14:00:39 +00:00
|
|
|
file.write('property float s\n')
|
|
|
|
file.write('property float t\n')
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_colors:
|
2009-12-13 14:00:39 +00:00
|
|
|
file.write('property uchar red\n')
|
|
|
|
file.write('property uchar green\n')
|
|
|
|
file.write('property uchar blue\n')
|
|
|
|
|
|
|
|
file.write('element face %d\n' % len(mesh.faces))
|
|
|
|
file.write('property list uchar uint vertex_indices\n')
|
|
|
|
file.write('end_header\n')
|
|
|
|
|
|
|
|
for i, v in enumerate(ply_verts):
|
2011-01-01 07:20:34 +00:00
|
|
|
file.write('%.6f %.6f %.6f ' % mesh_verts[v[0]].co[:]) # co
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_normals:
|
2011-01-01 07:20:34 +00:00
|
|
|
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_uv_coords:
|
2011-01-01 07:20:34 +00:00
|
|
|
file.write('%.6f %.6f ' % v[2]) # uv
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_colors:
|
2011-01-01 07:20:34 +00:00
|
|
|
file.write('%u %u %u' % v[3]) # col
|
2009-12-13 14:00:39 +00:00
|
|
|
file.write('\n')
|
|
|
|
|
|
|
|
for pf in ply_faces:
|
2009-12-26 09:36:50 +00:00
|
|
|
if len(pf) == 3:
|
2009-12-16 13:27:30 +00:00
|
|
|
file.write('3 %d %d %d\n' % tuple(pf))
|
|
|
|
else:
|
|
|
|
file.write('4 %d %d %d %d\n' % tuple(pf))
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
file.close()
|
2010-09-01 12:11:34 +00:00
|
|
|
print("writing %r done" % filepath)
|
2009-12-13 14:00:39 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
if use_modifiers:
|
2010-01-09 23:44:01 +00:00
|
|
|
bpy.data.meshes.remove(mesh)
|
2009-12-13 14:00:39 +00:00
|
|
|
|
|
|
|
# XXX
|
|
|
|
"""
|
|
|
|
if is_editmode:
|
|
|
|
Blender.Window.EditMode(1, '', 0)
|
|
|
|
"""
|
2011-01-01 07:20:34 +00:00
|
|
|
|
2010-09-01 12:11:34 +00:00
|
|
|
return {'FINISHED'}
|