Dockerで遊んでいたらDocker Meetup Tokyo #3 を開催しましたというページを見つけ、このページにDockerのマスコットがポリゴン化されている画像が貼ってあり、ページにリンクを辿ると、そこはGithubのページでこのDockerのマスコットがグリグリ回っており、ここでSTLファイルなるものの存在を初めて知りました。
STLのフォーマットはアスキー形式でもOKであり、形状の情報のみなので、かなり単純です。Hogan.jsに限らずテンプレート化が超簡単です。
solid {{objName}}
{{#facets}}
facet normal {{ni}} {{nj}} {{nk}}
outer loop
vertex {{v1x}} {{v1y}} {{v1z}}
vertex {{v2x}} {{v2y}} {{v2z}}
vertex {{v3x}} {{v3y}} {{v3z}}
endloop
endfacet
{{/facets}}
といった、Hogan.js用のテンプレートファイルを用意して、 後は、このテンプレートに対応したJSONを作成して、 Hogan.jsに渡せば、あっという間に、STLファイルが出来上がり!
npm install hogan.js
var fs = require("fs");
// エンコード指定することで、文字列として読み込む。
var template = fs.readFileSync("./stl.hjs","utf8");
var outObj = {};
var facets = [];
outObj.objName = "Test STL file";
i = 0;
facets[i] = {};
facets[i].ni = 0;
facets[i].nj = 1;
facets[i].nk = 0;
facets[i].v1x = 1;
facets[i].v1y = 0;
facets[i].v1z = 1;
facets[i].v2x = 1;
facets[i].v2y = 0;
facets[i].v2z = -1;
facets[i].v3x = -1;
facets[i].v3y = 0;
facets[i].v3z = -1;
outObj.facets = facets;
console.log(hogan.compile(template).render(outObj));
npm install hogan.js
に加えて、ベクトル演算を楽する為、Three.jsを入れます。
npm install three
var fs = require("fs");
var THREE = require("three");
var hogan = require("hogan.js");
// エンコード指定することで、文字列として読み込む。
var template = fs.readFileSync("./stl.hjs", "utf8");
// calculate Roman surface by u,v parameter.
function RomanSurface(u, v) {
var x = Math.sin(u) * Math.cos(u) * Math.sin(v) * Math.sin(v);
var y = Math.sin(u) * Math.sin(v) * Math.cos(v);
var z = Math.cos(u) * Math.sin(v) * Math.cos(v);
return new THREE.Vector3(x, y, z);
}
var ustep = 0.1;
var vstep = 0.2;
var pCount = 0;
var outObj = {};
var facets = [];
var i = 0;
for (v = 0; v < Math.PI / 2; v += vstep) {
for (u = 0; u < 2 * Math.PI; u += ustep) {
v1 = RomanSurface(u, v);
v2 = RomanSurface(u + ustep, v);
v3 = RomanSurface(u + ustep, v + vstep);
v4 = RomanSurface(u, v + vstep);
var nvx1 = v1.x - v2.x;
var nvy1 = v1.y - v2.y;
var nvz1 = v1.z - v2.z;
var nvx2 = v4.x - v2.x;
var nvy2 = v4.y - v2.y;
var nvz2 = v4.z - v2.z;
var faceNormal = new THREE.Vector3();
faceNormal.crossVectors(new THREE.Vector3(nvx1, nvy1, nvz1), new THREE.Vector3(nvx2, nvy2, nvz2));
faceNormal.normalize();
facets[i] = {};
facets[i].ni = faceNormal.x;
facets[i].nj = faceNormal.y;
facets[i].nk = faceNormal.z;
facets[i].v1x = v2.x;
facets[i].v1y = v2.y;
facets[i].v1z = v2.z;
facets[i].v2x = v3.x;
facets[i].v2y = v3.y;
facets[i].v2z = v3.z;
facets[i].v3x = v1.x;
facets[i].v3y = v1.y;
facets[i].v3z = v1.z;
i++;
facets[i] = {};
facets[i].ni = faceNormal.x;
facets[i].nj = faceNormal.y;
facets[i].nk = faceNormal.z;
facets[i].v1x = v3.x;
facets[i].v1y = v3.y;
facets[i].v1z = v3.z;
facets[i].v2x = v4.x;
facets[i].v2y = v4.y;
facets[i].v2z = v4.z;
facets[i].v3x = v1.x;
facets[i].v3y = v1.y;
facets[i].v3z = v1.z;
i++;
}
}
outObj.objName = "romansurface";
outObj.facets = facets;
console.log(hogan.compile(template).render(outObj));
一昔前ならば、この手のテキスト処理は、Perlで自分は書いてましたが、 最近は何でもJavaScriptでやることが多く、別件でXMLファイルの生成をHogan.jsで行ったことがあり、 今回のJavaScriptによるテンプレートエンジンの利用を思い付きました。
- node.jsで大きな数を扱う
- Node.jsでパイプを使う外部コマンドを実行するには
- Node.jsでデバッガを使う際に必要なたった2つのこと
- Node.jsでコマンドラインアプリを書く JSONファイル編
- node.jsでHTTPプロキシ経由でhttpsアクセスするには
- node.jsでhttpsも使えるHttp proxyを書いている
- node.jsで顔検出してみた
- node.jsが80番ポートで動かない #windows
- OSXでDocker入れるとTimeMachineが遅くなるかも #solved
- Dockerやって色々勉強になってる件
- Docker入れてからのVirtualBoxのアップデート