[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17131] trunk/blender/release/scripts: fix for [#17871] PLY file import: blender seems to loose vertex color information

Campbell Barton ideasman42 at gmail.com
Mon Oct 20 15:36:20 CEST 2008


Revision: 17131
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17131
Author:   campbellbarton
Date:     2008-10-20 15:36:18 +0200 (Mon, 20 Oct 2008)

Log Message:
-----------
fix for [#17871] PLY file import: blender seems to loose vertex color information
use Mesh rather then NMesh

Modified Paths:
--------------
    trunk/blender/release/scripts/ply_export.py
    trunk/blender/release/scripts/ply_import.py

Modified: trunk/blender/release/scripts/ply_export.py
===================================================================
--- trunk/blender/release/scripts/ply_export.py	2008-10-20 12:33:31 UTC (rev 17130)
+++ trunk/blender/release/scripts/ply_export.py	2008-10-20 13:36:18 UTC (rev 17131)
@@ -143,10 +143,10 @@
 				normal_key = rvec3d(normal)
 			
 			if faceUV:
-				uvcoord=	tuple(uv[j])
+				uvcoord=	uv[j][0], 1.0-uv[j][1]
 				uvcoord_key = rvec2d(uvcoord)
 			elif vertexUV:
-				uvcoord=	tuple(v.uvco)
+				uvcoord=	v.uvco[0], 1.0-v.uvco[1]
 				uvcoord_key = rvec2d(uvcoord)
 			
 			if vertexColors:	color=		col[j].r, col[j].g, col[j].b
@@ -209,8 +209,8 @@
 		for j, v in enumerate(f):
 			if f.smooth:		normal=		rvec3d(v.no)
 			else:				normal=		no
-			if faceUV:			uvcoord=	rvec2d(uv[j])
-			elif vertexUV:		uvcoord=	rvec2d(v.uvco)
+			if faceUV:			uvcoord=	rvec2d((uv[j][0], 1.0-uv[j][1]))
+			elif vertexUV:		uvcoord=	rvec2d((v.uvco[0], 1.0-v.uvco[1]))
 			if vertexColors:	color=		col[j].r, col[j].g, col[j].b
 			
 			file.write('%d ' % vdict[v.index][normal, uvcoord, color])

Modified: trunk/blender/release/scripts/ply_import.py
===================================================================
--- trunk/blender/release/scripts/ply_import.py	2008-10-20 12:33:31 UTC (rev 17130)
+++ trunk/blender/release/scripts/ply_import.py	2008-10-20 13:36:18 UTC (rev 17131)
@@ -2,13 +2,13 @@
 
 """
 Name: 'Stanford PLY (*.ply)...'
-Blender: 241
+Blender: 248
 Group: 'Import'
 Tip: 'Import a Stanford PLY file'
 """
 
 __author__ = 'Bruce Merry'
-__version__ = '0.92'
+__version__ = '0.93'
 __bpydoc__ = """\
 This script imports Stanford PLY files into Blender. It supports per-vertex
 normals, and per-face colours and texture coordinates.
@@ -35,20 +35,20 @@
 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 
-# Updated by Campbell Barton AKA Ideasman, 10% faster code.
+# 20th Oct 2008, 0.93 - Updated by Campbell Barton AKA ideasman42, use Mesh rather then NMesh, dont import normals, vcolors work again.
+# Updated by Campbell Barton AKA Ideasman42, 10% faster code.
 
 # Portions of this code are taken from mod_meshtools.py in Blender
 # 2.32.
 
 import Blender
 try:
-	import re, struct, StringIO
+	import re, struct
 except:
 	struct= None
 
-class element_spec:
-	name = ''
-	count = 0
+class element_spec(object):
+	__slots__ = 'name', 'count', 'properties'
 	def __init__(self, name, count):
 		self.name = name
 		self.count = count
@@ -64,10 +64,8 @@
 			if p.name == name: return i
 		return -1
 
-class property_spec:
-	name = ''
-	list_type = ''
-	numeric_type = ''
+class property_spec(object):
+	__slots__ = 'name', 'list_type', 'numeric_type'
 	def __init__(self, name, list_type, numeric_type):
 		self.name = name
 		self.list_type = list_type
@@ -117,14 +115,17 @@
 		else:
 			return self.read_format(format, 1, self.numeric_type, stream)[0]
 
-class object_spec:
+class object_spec(object):
+	__slots__ = 'specs'
 	'A list of element_specs'
-	specs = []
-
+	def __init__(self):
+		self.specs = []
+	
 	def load(self, format, stream):
 		return dict([(i.name,[i.load(format, stream) for j in xrange(i.count) ]) for i in self.specs])
 		
 		'''
+		# Longhand for above LC
 		answer = {}
 		for i in self.specs:
 			answer[i.name] = []
@@ -176,7 +177,7 @@
 				if (len(tokens) < 3):
 					print 'Invalid format line'
 					return None
-				if (tokens[1] not in format_specs.keys()):
+				if (tokens[1] not in format_specs): # .keys()): # keys is implicit
 					print 'Unknown format', tokens[1]
 					return None
 				if (tokens[2] != version):
@@ -209,115 +210,132 @@
 	
 	return (obj_spec, obj);
 
-
-def add_face(vertices, varr, indices, uvindices, colindices):
-	face = Blender.NMesh.Face([varr[i] for i in indices])
-	for index in indices:
-		vertex = vertices[index];
-		
-		if uvindices:
-			face.uv.append((vertex[uvindices[0]], 1.0 - vertex[uvindices[1]]))
-			face.mode &= ~Blender.NMesh.FaceModes.TEX
-		if colindices:
-			if not uvindices: face.uv.append((0, 0)) # Force faceUV
-			face.col.append(Blender.NMesh.Col(vertex[colindices[0]], vertex[colindices[1]], vertex[colindices[2]], 255))
-			face.mode &= ~Blender.NMesh.FaceModes.TEX
-	return face
-
-def filesel_callback(filename):
+def load_ply(filename):
 	t = Blender.sys.time()
-	(obj_spec, obj) = read(filename)
+	obj_spec, obj = read(filename)
 	if obj == None:
 		print 'Invalid file'
 		return
-	vmap = {}
-	varr = []
-	uvindices = None
-	noindices = None
-	colindices = None
+	
+	uvindices = colindices = None
+	# noindices = None # Ignore normals
+	
 	for el in obj_spec.specs:
 		if el.name == 'vertex':
 			vindices = vindices_x, vindices_y, vindices_z = (el.index('x'), el.index('y'), el.index('z'))
-			if el.index('nx') >= 0 and el.index('ny') >= 0 and el.index('nz') >= 0:
-				noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
-			if el.index('s') >= 0 and el.index('t') >= 0:
-				uvindices = (el.index('s'), el.index('t'))
-			if el.index('red') >= 0 and el.index('green') and el.index('blue') >= 0:
-				colindices = (el.index('red'), el.index('green'), el.index('blue'))
+			# noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
+			# if -1 in noindices: noindices = None
+			uvindices = (el.index('s'), el.index('t'))
+			if -1 in uvindices: uvindices = None
+			colindices = (el.index('red'), el.index('green'), el.index('blue'))
+			if -1 in colindices: colindices = None
 		elif el.name == 'face':
 			findex = el.index('vertex_indices')
+	
+	mesh_faces = []
+	mesh_uvs = []
+	mesh_colors = []
+	
+	def add_face(vertices, indices, uvindices, colindices):
+		mesh_faces.append(indices)
+		if uvindices:	mesh_uvs.append([ (vertices[index][uvindices[0]], 1.0 - vertices[index][uvindices[1]]) for index in indices])
+		if colindices:	mesh_colors.append([ (vertices[index][colindices[0]], vertices[index][colindices[1]], vertices[index][colindices[2]]) for index in indices])
+	
+	
+	if uvindices or colindices:
+		# If we have Cols or UVs then we need to check the face order.
+		add_face_simple = add_face
 		
-
-	mesh = Blender.NMesh.GetRaw()
-	NMVert = Blender.NMesh.Vert
-	for v in obj['vertex']:
-		
-		if noindices > 0:
-			x,y,z,nx,ny,nz = vkey =\
-			(v[vindices_x], v[vindices_y], v[vindices_z],\
-			v[noindices[0]], v[noindices[1]], v[noindices[2]])
-		else:
-			x,y,z = vkey = (v[vindices_x], v[vindices_y], v[vindices_z])
-		#if not vmap.has_key(vkey):
-		try: # try uses 1 less dict lookup
-			varr.append(vmap[vkey])
-		except:
-			nmv = NMVert(vkey[0], vkey[1], vkey[2])
-			mesh.verts.append(nmv)
-			if noindices > 0:
-				nmv.no[0] = vkey[3]
-				nmv.no[1] = vkey[4]
-				nmv.no[2] = vkey[5]
-			vmap[vkey] = nmv
-			varr.append(vmap[vkey])
+		# EVIL EEKADOODLE - face order annoyance.
+		def add_face(vertices, indices, uvindices, colindices):
+			if len(indices)==4:
+				if indices[2]==0 or indices[3]==0:
+					indices= indices[2], indices[3], indices[0], indices[1]
+			elif len(indices)==3:
+				if indices[2]==0:
+					indices= indices[1], indices[2], indices[0]
+			
+			add_face_simple(vertices, indices, uvindices, colindices)
 	
 	verts = obj['vertex']
 	
 	if 'face' in obj:
 		for f in obj['face']:
 			ind = f[findex]
-			nind = len(ind)
-			if nind <= 4:
-				mesh.faces.append(add_face(verts, varr, ind, uvindices, colindices))
+			len_ind = len(ind)
+			if len_ind <= 4:
+				add_face(verts, ind, uvindices, colindices)
 			else:
-				for j in xrange(nind - 2):
-					mesh.faces.append(add_face(verts, varr, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices))
-
+				# Fan fill the face
+				for j in xrange(len_ind - 2):
+					add_face(verts, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices)
 	
-	del obj # Reclaim memory
+	mesh = Blender.Mesh.New()
 	
-	'''
-	if noindices:
-		normals = 1
-	else:
-		normals = 0
-	'''
+	mesh.verts.extend([(v[vindices_x], v[vindices_y], v[vindices_z]) for v in obj['vertex']])
 	
+	if mesh_faces:
+		mesh.faces.extend(mesh_faces, smooth=True, ignoreDups=True)
+		
+		if uvindices or colindices:
+			if uvindices:	mesh.faceUV = True
+			if colindices:	mesh.vertexColors = True
+			
+			for i, f in enumerate(mesh.faces):
+				if uvindices:
+					ply_uv = mesh_uvs[i]
+					for j, uv in enumerate(f.uv):
+						uv[:] = ply_uv[j]
+				
+				if colindices:
+					ply_col = mesh_colors[i]
+					for j, col in enumerate(f.col):
+						col.r, col.g, col.b = ply_col[j]
+	
+	mesh.calcNormals()
+	
+	
 	objname = Blender.sys.splitext(Blender.sys.basename(filename))[0]
 	scn= Blender.Scene.GetCurrent()
 	scn.objects.selected = []
 	
 	mesh.name= objname
-	scn.objects.new(mesh)
+	scn.objects.active = scn.objects.new(mesh)
 	
 	Blender.Redraw()
 	Blender.Window.DrawProgressBar(1.0, '')
-	print '\nSuccessfully imported ' + Blender.sys.basename(filename) + ' ' + str(Blender.sys.time()-t)
-	
+	print '\nSuccessfully imported "%s" in %.3f sec' %  (filename, Blender.sys.time()-t)
 
-
-
 def main():
 	if not struct:
-		Blender.Draw.PupMenu('This importer requires a full python install')
+		msg = 'This importer requires a full python install'
+		if Blender.mode == 'background':	print msg
+		else:	Blender.Draw.PupMenu(msg)
 		return
 	
-	Blender.Window.FileSelector(filesel_callback, 'Import PLY', '*.ply')
+	Blender.Window.FileSelector(load_ply, 'Import PLY', '*.ply')
 
 if __name__=='__main__':
 	main()
 
+'''
+import bpy
+import os
+files = os.popen('find /fe/ply -iname "*.ply"').readlines()
 
 
-
-
+files.sort()
+tot = len(files)
+for i, f in enumerate(files):
+	if i < 26 or i > 1000000:
+		continue
+	#if i != 12686:
+	#	continue
+	
+	f = f.strip()
+	print f, i, tot
+	sce = bpy.data.scenes.new(f.split('/')[-1])
+	bpy.data.scenes.active = sce
+	# Window.
+	load_ply(f)
+'''
\ No newline at end of file





More information about the Bf-blender-cvs mailing list