Processing(Java)で.plyファイル読み込み

2010-05-12

スタンフォードバニーとかドラゴンとか出したいときはあると便利だよね。

// .plyファイル読み込み
class PLYLoader {
int vertnum;
float[] verts;
int facenum;
int[] indices;

boolean load(String fn) {
BufferedReader reader = createReader(fn);
try {
if (reader == null) return false;
if (!read_header(reader)) return false;
if (!read_verts(reader)) return false;
if (!read_faces(reader)) return false;
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}

boolean read_header(BufferedReader reader) throws IOException {
if (!reader.readLine().equals("ply")) return false;
if (match(reader.readLine(), "^format ascii [0-9\\.]+$") == null) return false;
for (;;) {
String s = reader.readLine();
if (s == null) return false;
if (s.equals("end_header")) break;
String[] m;
if ((m = match(s, "^element vertex (\\d+)$")) != null) {
vertnum = int(m[1]);
} else if ((m = match(s, "^element face (\\d+)$")) != null) {
facenum = int(m[1]);
}
}
return vertnum > 0 && facenum > 0;
}

boolean read_verts(BufferedReader reader) throws IOException {
verts = new float[vertnum * 3]; // xyz
for (int i = 0; i < vertnum; ++i) {
String[] a = split(reader.readLine(), " ");
verts[i*3+0] = float(a[0]);
verts[i*3+1] = float(a[1]);
verts[i*3+2] = float(a[2]);
}
return true;
}

boolean read_faces(BufferedReader reader) throws IOException {
ArrayList temp = new ArrayList();
for (int i = 0; i < facenum; ++i) {
String[] a = split(reader.readLine(), " ");
int nvtx = int(a[0]);
// 三角形に分割
for (int j = 2; j < nvtx; ++j) {
temp.add(int(a[1]));
temp.add(int(a[j]));
temp.add(int(a[j+1]));
}
}
indices = new int[temp.size()];
for (int i = 0; i < temp.size(); ++i)
indices[i] = ((Integer)temp.get(i)).intValue();
return true;
}
}
  • フォーマットはPLY (file format) - Wikipediaとか
  • asciiのみ
  • propertyとかで任意の頂点要素、UVとか法線とか追加できるらしいけどみてない、頂点座標のみ