stanford ply読み込み

ousttrue2007-05-01

stanfordのply形式の読み込みを作ってみました。
うさぎの置物を読み込んでみたが法線が無いので真っ黒です。

今回は、python名前空間界隈ではまってしまった。
__import()__とか__init__.pyがよくわからず、
関数内で__import__()を使うとglobalにモジュールが読み込まれないとかで数時間試行錯誤してしまいました。
importが何してるのか理解する必要がありそう。
pythonのパッケージは癖がありますな。

# -*- coding: utf-8 -*-
# plyファイルの読み込み

import re
import numpy

class Scene:
  def __init__(self):
    self.elements=[]
    pass

  def Load(self, io):
    print "ply.load"
    self.io=io

    try:
      # header
      current=None
      while True:
        line=io.next().strip()
        if(line=='end_header'):
          break
        fields=line.split()
        if(fields[0]=='format'):
          self.format=fields[1]
          self.version=fields[2]
        elif(fields[0]=='comment'):
          self.comment=line[8:]
        elif(fields[0]=='element'):
          current={}
          current['name']=fields[1]
          current['properties']=[]
          current['count']=int(fields[2])
          self.elements.append(current)
        elif(fields[0]=='property'):
          current['properties'].append(line)

      # elements
      for element in self.elements:
        element['data']=[]
        for i in range(element['count']):
          line=io.next().strip()
          element['data'].append(line.split())

      print io.next()

    except StopIteration:
      print "EOF"
      # end

  def GetVertexArray(self):
    face=filter(lambda element: element['name']=='face', self.elements)[0]
    assert(face)
    vertex=filter(lambda element: element['name']=='vertex', self.elements)[0]
    assert(vertex)
    vertex_array = numpy.zeros((face['count']*3, 3), 'f')    
    count=0
    for face in face['data']:
      if face[0]!='3': raise NotTriangle
      for vertex_index_in_triangle in face[1:]:
        index=int(vertex_index_in_triangle)
        vertex_array[count, 0]=float(vertex['data'][index][0]) # x
        vertex_array[count, 1]=float(vertex['data'][index][1]) # y
        vertex_array[count, 2]=float(vertex['data'][index][2]) # z
        count+=1
    return vertex_array

################################################################################
# test
################################################################################
if __name__=='__main__':
  def test():
    s=Scene()
    s.Load(open("bun_zipper_res3.ply"))
    s.GetVertexArray()

  import timeit
  t = timeit.Timer('test()', 'from __main__ import test')
  print "%.6f sec" % (t.timeit(1))