色々実験したいときに複雑なフォーマットだと読み込むのがいちいち大変なのでファイル形式を考えた。特徴は入力コードのコピペ量が少ないところ。
ファイル内のすべての行は「,」で区切られた4つの要素からなる
※ただし#が先頭の場合はスキップ
・ti 三角形の頂点index
・tn 三角形の面法線
・tc 三角形の色
・pp 頂点座標
・pc 頂点色
・pn 頂点法線
import bpy import sys def my_triangulation(target = bpy.context.object) : # なにも選択されていなければ終了 if target == None: return False # メッシュだけを対象とする if target.type == 'MESH' : # EDITモードへ移行するために現在のモードを保存して奥 current = bpy.context.object.mode # Editモードへ移行 bpy.ops.object.mode_set(mode = 'EDIT') # 三角形分割実行 bpy.ops.mesh.quads_convert_to_tris() # モードをリストア。これをしないとEDITモードのままで終わる。 bpy.ops.object.mode_set(mode = current) else: return False return True ############################################ ############################################ def to_simple_polygon_file(outputto) : obj = bpy.context.active_object mesh = obj.data pvecname = "points" # 頂点データの配列の変数名 vnvecname = "vnorms" # 頂点法線の配列の変数名 fvecname = "faces" # 面データの配列の変数名 fnvecname = "fnorms" # 面法線の配列の変数名 print("/////////////////////////////////////") print("#szlm,-,-,-,-", file = outputto) for f in mesh.polygons: if not fvecname is None : print( "ti,", f.vertices[0], ",", f.vertices[1], ",", f.vertices[2], 0, file = outputto ) if not fnvecname is None : print( "tn,", f.normal.x, ",", f.normal.y, ",", f.normal.z, 0, file = outputto ) for v in mesh.vertices: if not pvecname is None : print( "pp,", v.co.x, ",", v.co.y, ",", v.co.z, 0, file = outputto ) if not vnvecname is None : print( "pn,", v.normal.x, ",", v.normal.y, ",", v.normal.z, 0, file = outputto ) # 三角形分割 ret = my_triangulation() o = open('c:/data/myfile3.txt', 'w') to_simple_polygon_file(o) o.close() #as_cpp_array(sys.stdout)
#pragma once #pragma warning(disable:4996) #include <vector> #include <array> #include <type_traits> #include <string> /* #szlm,-,-,-,- ti,1,2,3,- tc,0.1,0.1,0.1,- tn,0.1,0.1,0.1,- pp,0.1,0.1,0.1,- pc,0.1,0.1,0.1,- pn,0.1,0.1,0.1,- */ struct szlm { std::vector<std::array<int, 4>> ti; std::vector<std::array<float, 4>> tc // triangle color ,tn// triangle normal ,pp// point position ,pc// point color ,pn// point normal ; }; //! @brief 簡易的メッシュフォーマットの読み込み //! @param [in] file ファイル名 //! @param [out] mesh メッシュを保存する構造体 bool read_mesh(const char* file, szlm* mesh) { FILE* fp = fopen(file, "r"); if (fp == NULL) return false; constexpr size_t DIM = 4; const size_t BUFFERSIZE = 2048; char b[BUFFERSIZE]; //,で分割 auto split = [](char* buffer, std::vector<std::string>& split)->void { const char* sp = ","; char* tok = strtok(buffer, sp); while (tok != NULL) { split.push_back(tok); tok = strtok(NULL, sp); /* 2回目以降 */ } }; //配列へ入力 while (fgets(b, BUFFERSIZE, fp) != NULL) { std::array<int, DIM> ii; std::array<float, DIM> ff; std::fill_n(ii.begin(), DIM, -1); std::fill_n(ff.begin(), DIM, INFINITY); std::vector<std::string> line; split(b, line);//入力行を,で分割 for (size_t i = 1; i < (std::min)(DIM, line.size()); i++) { ii[i - 1] = atoi(line[i].c_str()); ff[i - 1] = atof(line[i].c_str()); } if (b[0] == '#')continue; else if (strncmp(b, "ti", 2) == 0)mesh->ti.push_back({ ii[0],ii[1],ii[2],ii[3] });// triangle pointindex else if (strncmp(b, "tc", 2) == 0)mesh->tc.push_back({ ff[0],ff[1],ff[2],ff[3] });// triangle color else if (strncmp(b, "tn", 2) == 0)mesh->tn.push_back({ ff[0],ff[1],ff[2],ff[3] });// triangle normal else if (strncmp(b, "pp", 2) == 0)mesh->pp.push_back({ ff[0],ff[1],ff[2],ff[3] });// point position else if (strncmp(b, "pc", 2) == 0)mesh->pc.push_back({ ff[0],ff[1],ff[2],ff[3] });// point color else if (strncmp(b, "pn", 2) == 0)mesh->pn.push_back({ ff[0],ff[1],ff[2],ff[3] });// point normal } fclose(fp); return false; }
void disp(const szlm& mesh) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_TRIANGLES); for (size_t i = 0; i < mesh.ti.size(); i++) { int v0 = mesh.ti[i][0]; int v1 = mesh.ti[i][1]; int v2 = mesh.ti[i][2]; glNormal3fv(mesh.tn[i].data()); glVertex3fv(mesh.pp[v0].data()); glVertex3fv(mesh.pp[v1].data()); glVertex3fv(mesh.pp[v2].data()); } glEnd(); } int main() { struct szlm mesh; read_mesh("C:\\data\\myfile3.txt", &mesh); /* ... */ disp(mesh); }