node info
This commit is contained in:
parent
93b4efead1
commit
c05f74cc19
|
@ -1,8 +1,5 @@
|
||||||
#include <db_ops.h>
|
#include <db_ops.h>
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
|
||||||
#include <tools.h>
|
#include <tools.h>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
||||||
{
|
{
|
||||||
|
@ -28,25 +25,23 @@ sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
||||||
|
|
||||||
void create_tables(sqlite3 *db)
|
void create_tables(sqlite3 *db)
|
||||||
{
|
{
|
||||||
const char *sql_nodes = R"
|
const char *sql_nodes = R"(
|
||||||
CREATE TABLE IF NOT EXISTS nodes (
|
CREATE TABLE IF NOT EXISTS nodes (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
unique_id INTEGER NOT NULL UNIQUE,
|
pid INTEGER,
|
||||||
parent_id INTEGER,
|
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
lcl_translation_x REAL,
|
t_x,
|
||||||
lcl_translation_y REAL,
|
t_y,
|
||||||
lcl_translation_z REAL,
|
t_z,
|
||||||
lcl_rotation_x REAL,
|
r_x,
|
||||||
lcl_rotation_y REAL,
|
r_y,
|
||||||
lcl_rotation_z REAL,
|
r_z,
|
||||||
lcl_scaling_x REAL,
|
s_x,
|
||||||
lcl_scaling_y REAL,
|
s_y,
|
||||||
lcl_scaling_z REAL,
|
s_z,
|
||||||
properties TEXT,
|
properties TEXT
|
||||||
FOREIGN KEY (parent_id) REFERENCES fbx_nodes(unique_id)
|
|
||||||
);
|
);
|
||||||
";
|
)";
|
||||||
|
|
||||||
const char *sql_meshes = R"(
|
const char *sql_meshes = R"(
|
||||||
CREATE TABLE IF NOT EXISTS meshes (
|
CREATE TABLE IF NOT EXISTS meshes (
|
||||||
|
@ -105,7 +100,7 @@ void create_tables(sqlite3 *db)
|
||||||
);
|
);
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const char *sql[] = {sql_meshes, sql_materials, sql_vertices, sql_indices, sql_material_props};
|
const char *sql[] = {sql_nodes, sql_meshes, sql_materials, sql_vertices, sql_indices, sql_material_props};
|
||||||
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); ++i)
|
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); ++i)
|
||||||
{
|
{
|
||||||
printf("开始执行:%s", sql[i]);
|
printf("开始执行:%s", sql[i]);
|
||||||
|
@ -176,29 +171,34 @@ int save_mesh_to_table(FttContext *ctx,
|
||||||
return rc == SQLITE_DONE ? 0 : -1;
|
return rc == SQLITE_DONE ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector<V3> vertices) {
|
int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector<V3> vertices)
|
||||||
if (!ctx->db) return -1;
|
{
|
||||||
|
if (!ctx->db)
|
||||||
|
return -1;
|
||||||
|
|
||||||
sqlite3_stmt *stmt = nullptr;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
const char *sql = "INSERT OR IGNORE INTO vertices (mesh_id, vert_id, position_x, position_y, position_z) VALUES (?, ?, ?, ?, ?);";
|
const char *sql = "INSERT OR IGNORE INTO vertices (mesh_id, vert_id, position_x, position_y, position_z) VALUES (?, ?, ?, ?, ?);";
|
||||||
int rc = sqlite3_prepare_v2(ctx->db, sql, -1, &stmt, nullptr);
|
int rc = sqlite3_prepare_v2(ctx->db, sql, -1, &stmt, nullptr);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(ctx->db));
|
fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(ctx->db));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_exec(ctx->db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); // 开启事务
|
sqlite3_exec(ctx->db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); // 开启事务
|
||||||
|
|
||||||
for (int i = 0; i < vertices.size(); i++) {
|
for (int i = 0; i < vertices.size(); i++)
|
||||||
|
{
|
||||||
sqlite3_reset(stmt); // 重置语句
|
sqlite3_reset(stmt); // 重置语句
|
||||||
sqlite3_bind_int64(stmt, 1, mesh_id);
|
sqlite3_bind_int64(stmt, 1, mesh_id);
|
||||||
sqlite3_bind_int64(stmt, 2, i); // vert_id使用索引
|
sqlite3_bind_int64(stmt, 2, i); // vert_id使用索引
|
||||||
sqlite3_bind_double(stmt, 3, std::get<0>(vertices[i])); // 修正为double类型绑定
|
sqlite3_bind_double(stmt, 3, std::get<0>(vertices[i])); // 修正为double类型绑定
|
||||||
sqlite3_bind_double(stmt, 4, std::get<1>(vertices[i]));
|
sqlite3_bind_double(stmt, 4, std::get<1>(vertices[i]));
|
||||||
sqlite3_bind_double(stmt, 5, std::get<2>(vertices[i]));
|
sqlite3_bind_double(stmt, 5, std::get<2>(vertices[i]));
|
||||||
|
|
||||||
rc = sqlite3_step(stmt);
|
rc = sqlite3_step(stmt);
|
||||||
if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT) {
|
if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT)
|
||||||
|
{
|
||||||
fprintf(stderr, "SQL step failed at vertex %d: %s\n", i, sqlite3_errmsg(ctx->db));
|
fprintf(stderr, "SQL step failed at vertex %d: %s\n", i, sqlite3_errmsg(ctx->db));
|
||||||
sqlite3_exec(ctx->db, "ROLLBACK;", nullptr, nullptr, nullptr);
|
sqlite3_exec(ctx->db, "ROLLBACK;", nullptr, nullptr, nullptr);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
@ -211,14 +211,15 @@ int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector<V3> vertices)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector<unsigned int> indices) {
|
int save_mesh_indices(FttContext *ctx, uint mesh_id, std::vector<unsigned int> indices)
|
||||||
if (!ctx->db) return -1;
|
{
|
||||||
|
if (!ctx->db)
|
||||||
|
return -1;
|
||||||
printf("save indices: %d\n", indices.size());
|
printf("save indices: %d\n", indices.size());
|
||||||
for (int i = 0; i < indices.size(); i++)
|
for (int i = 0; i < indices.size(); i++)
|
||||||
{
|
{
|
||||||
printf("%d ", indices[i]);
|
printf("%d ", indices[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// sqlite3_stmt *stmt = nullptr;
|
// sqlite3_stmt *stmt = nullptr;
|
||||||
// const char *sql = "INSERT OR IGNORE INTO indices (mesh_id, index_id, position_x, position_y, position_z) VALUES (?, ?, ?, ?, ?);";
|
// const char *sql = "INSERT OR IGNORE INTO indices (mesh_id, index_id, position_x, position_y, position_z) VALUES (?, ?, ?, ?, ?);";
|
||||||
|
@ -251,3 +252,52 @@ int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector<unsigned int> i
|
||||||
// sqlite3_finalize(stmt);
|
// sqlite3_finalize(stmt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int save_nodes(FttContext *ctx, uint id, uint pid,
|
||||||
|
const std::string &name,
|
||||||
|
double t_x,
|
||||||
|
double t_y,
|
||||||
|
double t_z,
|
||||||
|
double r_x,
|
||||||
|
double r_y,
|
||||||
|
double r_z,
|
||||||
|
double s_x,
|
||||||
|
double s_y,
|
||||||
|
double s_z,
|
||||||
|
const std::string &properties)
|
||||||
|
{
|
||||||
|
if (!ctx->db)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt = nullptr;
|
||||||
|
const char *sql = "INSERT OR IGNORE INTO nodes(id,pid,name,t_x,t_y,t_z,r_x,r_y,r_z,s_x,s_y,s_z,properties) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
|
||||||
|
int rc = sqlite3_prepare_v2(ctx->db, sql, -1, &stmt, nullptr);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(ctx->db));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_int64(stmt, 1, id);
|
||||||
|
sqlite3_bind_int64(stmt, 2, pid);
|
||||||
|
sqlite3_bind_text(stmt, 3, name.c_str(), -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_double(stmt, 4, t_x);
|
||||||
|
sqlite3_bind_double(stmt, 5, t_y);
|
||||||
|
sqlite3_bind_double(stmt, 6, t_z);
|
||||||
|
sqlite3_bind_double(stmt, 7, r_x);
|
||||||
|
sqlite3_bind_double(stmt, 8, r_y);
|
||||||
|
sqlite3_bind_double(stmt, 9, r_z);
|
||||||
|
sqlite3_bind_double(stmt, 10, s_x);
|
||||||
|
sqlite3_bind_double(stmt, 11, s_y);
|
||||||
|
sqlite3_bind_double(stmt, 12, s_z);
|
||||||
|
sqlite3_bind_text(stmt, 13, properties.c_str(), -1, SQLITE_STATIC);
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SQL step failed: %s\n", sqlite3_errmsg(ctx->db));
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return rc == SQLITE_DONE ? 0 : -1;
|
||||||
|
}
|
|
@ -4,8 +4,6 @@
|
||||||
#include <db_ops.h>
|
#include <db_ops.h>
|
||||||
#include <tools.h>
|
#include <tools.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector<unsigned int> indices, std::vector<V3> &vertices)
|
int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector<unsigned int> indices, std::vector<V3> &vertices)
|
||||||
{
|
{
|
||||||
if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh)
|
if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh)
|
||||||
|
@ -71,14 +69,29 @@ FbxNode *get_fbx_root_node(const char *fbx_path)
|
||||||
return lScene->GetRootNode();
|
return lScene->GetRootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void each_node(FttContext *ctx, FbxNode *parent_node, int level)
|
void each_node(FttContext *ctx, FbxNode *node, int level)
|
||||||
{
|
{
|
||||||
// info
|
|
||||||
print_node_info(parent_node, level);
|
uint id = node->GetUniqueID();
|
||||||
|
uint pid = node->GetParent() == NULL ? 0 : node->GetParent()->GetUniqueID();
|
||||||
|
FbxString name = node->GetNameOnly();
|
||||||
|
|
||||||
|
print_node_info(node, level);
|
||||||
|
// 变化矩阵信息
|
||||||
|
FbxDouble3 t = node->LclTranslation.Get();
|
||||||
|
FbxDouble3 r = node->LclRotation.Get();
|
||||||
|
FbxDouble3 s = node->LclScaling.Get();
|
||||||
|
save_nodes(ctx, id, pid, name.Buffer(),
|
||||||
|
t[0], t[1], t[2],
|
||||||
|
r[0], r[1], r[2],
|
||||||
|
s[0], s[1], s[2],
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
// data
|
// data
|
||||||
for (int i = 0; i < parent_node->GetNodeAttributeCount(); i++)
|
for (int i = 0; i < node->GetNodeAttributeCount(); i++)
|
||||||
{
|
{
|
||||||
FbxNodeAttribute *attr = parent_node->GetNodeAttributeByIndex(i);
|
FbxNodeAttribute *attr = node->GetNodeAttributeByIndex(i);
|
||||||
if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh)
|
if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh)
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
|
@ -86,9 +99,6 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level)
|
||||||
|
|
||||||
int count = load_triangles(attr, indices, vertices);
|
int count = load_triangles(attr, indices, vertices);
|
||||||
|
|
||||||
uint id = attr->GetUniqueID();
|
|
||||||
uint pid = parent_node->GetUniqueID();
|
|
||||||
|
|
||||||
printf("[%d]vertices: %ld\n", count);
|
printf("[%d]vertices: %ld\n", count);
|
||||||
// save data to database
|
// save data to database
|
||||||
sqlite3 *db = ctx->db;
|
sqlite3 *db = ctx->db;
|
||||||
|
@ -99,7 +109,7 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level)
|
||||||
pid,
|
pid,
|
||||||
attr->GetName(),
|
attr->GetName(),
|
||||||
vertices.size(), indices.size(),
|
vertices.size(), indices.size(),
|
||||||
parent_node->GetNameOnly().Buffer());
|
node->GetNameOnly().Buffer());
|
||||||
|
|
||||||
save_mesh_vertices(ctx, id, vertices);
|
save_mesh_vertices(ctx, id, vertices);
|
||||||
save_mesh_indices(ctx, id, indices);
|
save_mesh_indices(ctx, id, indices);
|
||||||
|
@ -107,11 +117,11 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// children
|
// children
|
||||||
if (parent_node->GetChildCount())
|
if (node->GetChildCount())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < parent_node->GetChildCount(); i++)
|
for (int i = 0; i < node->GetChildCount(); i++)
|
||||||
{
|
{
|
||||||
FbxNode *child = parent_node->GetChild(i);
|
FbxNode *child = node->GetChild(i);
|
||||||
each_node(ctx, child, level + 1);
|
each_node(ctx, child, level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +152,6 @@ void print_node_info(FbxNode* node, int level) {
|
||||||
int prop_count = 0;
|
int prop_count = 0;
|
||||||
printf(" Properties: ");
|
printf(" Properties: ");
|
||||||
while (p.IsValid() && prop_count < 5) {
|
while (p.IsValid() && prop_count < 5) {
|
||||||
|
|
||||||
printf("%s[%.2f] ", p.GetName().Buffer(), p.Get<double>());
|
printf("%s[%.2f] ", p.GetName().Buffer(), p.Get<double>());
|
||||||
prop_count++;
|
prop_count++;
|
||||||
p = node->GetNextProperty(p);
|
p = node->GetNextProperty(p);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <tools.h>
|
#include <tools.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
/**
|
/**
|
||||||
* @brief 创建并打开SQLite数据库连接
|
* @brief 创建并打开SQLite数据库连接
|
||||||
|
@ -33,6 +34,49 @@ void create_tables(sqlite3* db);
|
||||||
* 2. 内部自动处理事务,重复name会触发唯一键冲突
|
* 2. 内部自动处理事务,重复name会触发唯一键冲突
|
||||||
*/
|
*/
|
||||||
int save_mesh_to_table(FttContext* ctx, sqlite3 *db, uint id, uint pid, const std::string &name, int vertex_count, int index_count, const std::string &fbx_id);
|
int save_mesh_to_table(FttContext* ctx, sqlite3 *db, uint id, uint pid, const std::string &name, int vertex_count, int index_count, const std::string &fbx_id);
|
||||||
|
/**
|
||||||
|
* @brief 保存网格顶点数据到上下文
|
||||||
|
* @param ctx FttContext上下文指针,用于管理网格数据存储
|
||||||
|
* @param mesh_id 目标网格的唯一标识符
|
||||||
|
* @param vertices 顶点数据容器,存储V3类型的顶点坐标集合
|
||||||
|
* @return 成功返回0,失败返回非0错误码
|
||||||
|
*/
|
||||||
int save_mesh_vertices(FttContext* ctx, uint mesh_id, std::vector<V3> vertices);
|
int save_mesh_vertices(FttContext* ctx, uint mesh_id, std::vector<V3> vertices);
|
||||||
int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector<unsigned int> indices);
|
|
||||||
|
/**
|
||||||
|
* @brief 保存网格索引数据到上下文
|
||||||
|
* @param ctx FttContext上下文指针,用于管理网格数据存储
|
||||||
|
* @param mesh_id 目标网格的唯一标识符,需与顶点数据的mesh_id对应
|
||||||
|
* @param indices 索引数据容器,存储unsigned int类型的顶点索引集合
|
||||||
|
* @return 成功返回0,失败返回非0错误码
|
||||||
|
*/
|
||||||
|
int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector<unsigned int> indices);
|
||||||
|
|
||||||
|
/*
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
pid INTEGER,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
t_x REAL,
|
||||||
|
t_y REAL,
|
||||||
|
t_z REAL,
|
||||||
|
r_x REAL,
|
||||||
|
r_y REAL,
|
||||||
|
r_z REAL,
|
||||||
|
s_x REAL,
|
||||||
|
s_y REAL,
|
||||||
|
s_z REAL,
|
||||||
|
properties TEXT
|
||||||
|
*/
|
||||||
|
int save_nodes(FttContext* ctx, uint id, uint pid,
|
||||||
|
const std::string &name,
|
||||||
|
double t_x,
|
||||||
|
double t_y,
|
||||||
|
double t_z,
|
||||||
|
double r_x,
|
||||||
|
double r_y,
|
||||||
|
double r_z,
|
||||||
|
double s_x,
|
||||||
|
double s_y,
|
||||||
|
double s_z,
|
||||||
|
const std::string &properties
|
||||||
|
);
|
|
@ -5,7 +5,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
Loading…
Reference in New Issue