LoginSignup
0
1

More than 5 years have passed since last update.

processingで3D(OBJファイル)を使ってみる(汎用性無し。。です)

Posted at

※今までOBJファイルとかまったく触った事なかったのでだいぶ的外れかもしれません。。

このサイト http://cvl-demos.cs.nott.ac.uk/vrn/ に写真送ると、
OBJファイルを作ってくれるので出来たファイルをprocessingで読み込もうと思いましたが、、
凹凸のないペタッとしたのしか表示されません。。

トライ1

obj.pde
PShape obj;
void setup(){
 size(960,640,P3D);
//サイトからダウンロードしたファイルの場所を指定してください
 obj=loadShape("/home/***.obj");
}
void draw(){
 background(255);
 translate(width/2,height/2);
 shape(obj);
}

結果1

1.png

トライ2

少し調べてみるとobjファイルは、なにやら頂点データ(v)とその頂点で作られる面(f)とか
その面にテクスチャとして画像を貼れる(vt)とかがおぼろげにわかったので少しpythonで
いじってみました
元のデータは、頂点データにRGBの色データが付加されていてかつvtが無くて、面のデータ
にもテクスチャの情報が無かったのでなんとなく形を整えてみました。
また、頂点データにくっついていたRGBからテクスチャファイル(png)を作ってみました

obj.py
import math
from PIL import Image
import time
import sys
f=open("/home/input.obj","r")
ff=open("/home/output.obj","w")
ff.write("mtllib output.mtl\nusemtl face\n")
M={}
n=0
for i in f:
    if i.split()[0]=="v":
        M[n]=(int(float(i.split()[4])*255),int(float(i.split()[5])*255),int(float(i.split()[6])*255))
        ff.write(i.split()[0]+" "+i.split()[1]+" "+i.split()[2]+" "+i.split()[3]+"\n")
        n=n+1
    else:
        continue
f.close()
xy=int(math.sqrt(len(M)))+1
im=Image.new("RGB",(xy,xy))
m=0
print(len(M))
for y in range(xy):
    if m>len(M):break
    for x in range(xy):
        if m>len(M)-1:break
        ff.write("vt "+str(float(x/xy))+" "+str(float(y/xy))+"\n")
        im.putpixel((x,y),M[m])
        m=m+1

im.save("/home/outout.png")
f=open("/home/input.obj","r")
for i in f:
    if i.split()[0]=="f":
        ff.write("f "+i.split()[1]+"/"+i.split()[1]+" "+i.split()[2]+"/"+i.split()[2]+" "+i.split()[3]+"/"+i.split()[3]+"\n")
        continue
    else:
        continue
ff.close()
f.close()

結果2

凹凸できましたけど、、むちゃくちゃ・・なにこれ、、ダマスカス鋼みたい、、テクスチャの作り方が悪いのか指定の仕方が悪いのか、、うーん
スクリーンショット_2018-01-22_01-00-13.png

ちなみにテクスチャファイルはこんな感じ
kota.png

トライ3

もうOBJはひとまずおいといて、、頂点データとRGBのデータだけ抜いて
それをprocessingで読み込んで一個ずつプロットしてみようかと。

obj_to_point.py
f=open("/home/input.obj","r")
ff=open("/home/output.txt","w")
c=1
for i in f:
    if i.split()[0]=="v":
        if float(i.split()[3])<55.0:#データがすごく多いので裏側のデータを使わないようにします
            continue
        ff.write(i.split()[1]+","+i.split()[2]+","+i.split()[3]+","+str(int(float(i.split()[4])*255))+","+str(int(float(i.split()[5])*255))+","+str(int(float(i.split()[6])*255))+"\n")
    else:
        continue
f.close()
ff.close()
obj_point.pde

BufferedReader reader;//ファイルが大きいとBufferedReaderを使うそうです
String line;
void setup(){
  noFill();
  reader=createReader("/home/output.txt");
  background(255);
  size(1280,480,P3D);
}
void draw(){
  scale(2);
  try {
    line=reader.readLine();
  }catch (IOException e){
    e.printStackTrace();
    line=null;
  }
  if (line==null){
  noLoop();
  }else{
    String[] pieces=split(line,",");
    float x = float(pieces[0]);
    float y = float(pieces[1]);
    float z = float(pieces[2]);
    int r = int(pieces[3]);
    int g = int(pieces[4]);
    int b = int(pieces[5]);
    pushMatrix();
    translate(x+200,y+20,z);
    stroke(r,g,b);
    box(2);//pointだと少し隙間ができるので、、
    popMatrix();
  }
}

データが7万行ぐらいあるので書き終わるまでに時間がだいぶかかります
(古いノートPCだからかもしれませんが、、)
書き終わった後、傾かせたり動かせるといいのですが、、(だまし絵の要領で出すことをへこませたりすると
常にこっち見てるみたいにできるのかなぁ)

結果3

スクリーンショット_2018-01-22_01-32-53.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1