スポンサーリンク

自作ポリゴンデータフォーマットを考えた

色々実験したいときに複雑なフォーマットだと読み込むのがいちいち大変なのでファイル形式を考えた。特徴は入力コードのコピペ量が少ないところ。

ファイル形式

ファイル内のすべての行は「,」で区切られた4つの要素からなる

[要素名] , [要素1] , [要素2] , [要素3] , [要素4]

※ただし#が先頭の場合はスキップ

・ti 三角形の頂点index

・tn 三角形の面法線

・tc 三角形の色

・pp 頂点座標

・pc 頂点色

・pn 頂点法線

 

#szlm,-,-,-,-
ti, 4 , 2 , 0 , 0
tn, 0.0 , 0.0 , 1.0 , 0
ti, 2 , 7 , 3 , 0
tn, 0.0 , -1.0 , 0.0 , 0
ti, 6 , 5 , 7 , 0
tn, -1.0 , 0.0 , 0.0 , 0
ti, 1 , 7 , 5 , 0
tn, 0.0 , 0.0 , -1.0 , 0
ti, 0 , 3 , 1 , 0
tn, 1.0 , 0.0 , -0.0 , 0
ti, 4 , 1 , 5 , 0
tn, 0.0 , 1.0 , -0.0 , 0
ti, 4 , 6 , 2 , 0
tn, 0.0 , -0.0 , 1.0 , 0
ti, 2 , 6 , 7 , 0
tn, 0.0 , -1.0 , 0.0 , 0
ti, 6 , 4 , 5 , 0
tn, -1.0 , 0.0 , 0.0 , 0
ti, 1 , 3 , 7 , 0
tn, 0.0 , 0.0 , -1.0 , 0
ti, 0 , 2 , 3 , 0
tn, 1.0 , 0.0 , 0.0 , 0
ti, 4 , 0 , 1 , 0
tn, 0.0 , 1.0 , -0.0 , 0
pp, 1.0 , 1.0 , 1.0 0
pn, 0.5773503184318542 , 0.5773503184318542 , 0.5773503184318542 , 0
pp, 1.0 , 1.0 , -1.0 0
pn, 0.5773503184318542 , 0.5773503184318542 , -0.5773503184318542 , 0
pp, 1.0 , -1.0 , 1.0 0
pn, 0.5773503184318542 , -0.5773503184318542 , 0.5773503184318542 , 0
pp, 1.0 , -1.0 , -1.0 0
pn, 0.5773503184318542 , -0.5773503184318542 , -0.5773503184318542 , 0
pp, -1.0 , 1.0 , 1.0 0
pn, -0.5773503184318542 , 0.5773503184318542 , 0.5773503184318542 , 0
pp, -1.0 , 1.0 , -1.0 0
pn, -0.5773503184318542 , 0.5773503184318542 , -0.5773503184318542 , 0
pp, -1.0 , -1.0 , 1.0 0
pn, -0.5773503184318542 , -0.5773503184318542 , 0.5773503184318542 , 0
pp, -1.0 , -1.0 , -1.0 0
pn, -0.5773503184318542 , -0.5773503184318542 , -0.5773503184318542 , 0

ファイル生成

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);
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: