はじめに
**符号付き距離関数(Signed Distance Function: SDF)**について詳しくは以下参照。
符号付き距離関数は、3次元空間の各点におけるポリゴンデータへの最短距離(距離関数)を符号付きで示した関数です。符号付き距離関数の0等値面はポリゴンデータの表面と一致します。ポリゴンデータの中と外で符号が異なることが符号付き距離関数の特徴です。
$$
f(x)=\begin{cases}d(x,∂Ω)\quad if\quad x∈Ω \\-d(x,∂Ω)\quad if\quad x∈Ω^{c} \\ \end{cases}
$$
ここで、Ωはポリゴン面の境界です。
概要
**ASCII形式のSTLファイルをSDFデータに変換します。**流体解析等の物理シミュレーションをスクラッチで実装するには、複雑な境界条件のインポートが一つの大きな壁になります。そんな時、境界面のSDFデータがあると非常に便利です。
STLからSDFへの変換にはbasiliskを使用します。basiliskのインストールは以下から。
ソースコード
符号付き距離関数をcsvで出力するソースコードです。Basilisk Cで実装しています。basiliskのexampleのBasilisk - src/examples/distance.cを参考にしました(というかほとんどコピペです)。
#include <sys/stat.h>
#include "grid/octree.h"
#include "utils.h"
#include "distance.h"
#include "fractions.h"
void mk_outfilepath(char *outfilepath, char *stlfilename, char *output_dir){
char *ptr;
char *ptr2;
char *buf;
ptr = strtok(stlfilename, "/");
while(ptr != NULL) {
buf = ptr;
ptr = strtok(NULL, "/");
}
ptr2 = strtok(buf, ".");
sprintf(outfilepath,"%s%s_sdf.csv", output_dir, ptr2);
}
int main(int argc,char *argv[]){
char *input_file = argv[1];
char *output_dir = argv[2];
int grids = atoi(argv[3]);
mkdir(output_dir,0755);
coord *p = input_stl (fopen (input_file, "r"));
coord min, max;
bounding_box (p, &min, &max);
double maxl = -HUGE;
foreach_dimension()
if (max.x - min.x > maxl)
maxl = max.x - min.x;
init_grid (grids);
size (1.2*maxl);
origin ((max.x + min.x)/2. - L0/2,
(max.y + min.y)/2. - L0/2,
(max.z + min.z)/2. - L0/2);
scalar d[];
distance (d, p);
FILE *fp;
char outfilepath[256];
mk_outfilepath(outfilepath,input_file,output_dir);
if ((fp = fopen(outfilepath, "w")) == NULL) {
printf("file open error!!\n");
exit(EXIT_FAILURE);
}
fprintf(fp,"x,y,z,distance\n");
foreach() fprintf(fp,"%lf,%lf,%lf,%lf\n",x,y,z,d[]);
fclose(fp);
}
実行
stl2sdf <stlfile_path> <output_dir> <grid_size>
option | 説明 |
---|---|
stlfile_path | STLファイルのパス |
output_dir | 出力先ディレクトリ(自動生成) |
grid_size | 符号付き距離関数の空間分割数 |
output_dirに元のSTLファイル名から.stlを引いたもの+_sdf.csvが出力されます。
csvファイルの中身はx,y,z座標と各座標における符号付き距離関数です。オブジェクト内は正値、外は負値になります。以下図はStanford Bunnyの例です。
GitHub