From c05f74cc19b6b80081a98612970f740ee2249ccf Mon Sep 17 00:00:00 2001 From: dqn Date: Tue, 16 Sep 2025 16:10:47 +0800 Subject: [PATCH] node info --- cpp_src/db_ops.cpp | 106 ++++++++++++++++++++++++++++----------- cpp_src/fbx_wrap.cpp | 39 ++++++++------ cpp_src/include/db_ops.h | 48 +++++++++++++++++- cpp_src/include/tools.h | 2 +- 4 files changed, 149 insertions(+), 46 deletions(-) diff --git a/cpp_src/db_ops.cpp b/cpp_src/db_ops.cpp index d3c892e..2e1cbaf 100644 --- a/cpp_src/db_ops.cpp +++ b/cpp_src/db_ops.cpp @@ -1,8 +1,5 @@ #include -#include -#include #include -using namespace std; 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) { - const char *sql_nodes = R" + const char *sql_nodes = R"( CREATE TABLE IF NOT EXISTS nodes ( id INTEGER PRIMARY KEY, - unique_id INTEGER NOT NULL UNIQUE, - parent_id INTEGER, + pid INTEGER, name TEXT NOT NULL, - lcl_translation_x REAL, - lcl_translation_y REAL, - lcl_translation_z REAL, - lcl_rotation_x REAL, - lcl_rotation_y REAL, - lcl_rotation_z REAL, - lcl_scaling_x REAL, - lcl_scaling_y REAL, - lcl_scaling_z REAL, - properties TEXT, - FOREIGN KEY (parent_id) REFERENCES fbx_nodes(unique_id) + t_x, + t_y, + t_z, + r_x, + r_y, + r_z, + s_x, + s_y, + s_z, + properties TEXT ); - "; + )"; const char *sql_meshes = R"( 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) { printf("开始执行:%s", sql[i]); @@ -176,29 +171,34 @@ int save_mesh_to_table(FttContext *ctx, return rc == SQLITE_DONE ? 0 : -1; } -int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector vertices) { - if (!ctx->db) return -1; +int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector vertices) +{ + if (!ctx->db) + return -1; sqlite3_stmt *stmt = nullptr; 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); - if (rc != SQLITE_OK) { + if (rc != SQLITE_OK) + { fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(ctx->db)); return rc; } 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_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, 4, std::get<1>(vertices[i])); sqlite3_bind_double(stmt, 5, std::get<2>(vertices[i])); 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)); sqlite3_exec(ctx->db, "ROLLBACK;", nullptr, nullptr, nullptr); sqlite3_finalize(stmt); @@ -211,14 +211,15 @@ int save_mesh_vertices(FttContext *ctx, uint mesh_id, std::vector vertices) return 0; } -int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector indices) { - if (!ctx->db) return -1; +int save_mesh_indices(FttContext *ctx, uint mesh_id, std::vector indices) +{ + if (!ctx->db) + return -1; printf("save indices: %d\n", indices.size()); for (int i = 0; i < indices.size(); i++) { printf("%d ", indices[i]); } - // sqlite3_stmt *stmt = nullptr; // 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 i // sqlite3_finalize(stmt); 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; +} \ No newline at end of file diff --git a/cpp_src/fbx_wrap.cpp b/cpp_src/fbx_wrap.cpp index b01cc45..880fe2d 100644 --- a/cpp_src/fbx_wrap.cpp +++ b/cpp_src/fbx_wrap.cpp @@ -4,8 +4,6 @@ #include #include -using namespace std; - int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector indices, std::vector &vertices) { if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) @@ -71,14 +69,29 @@ FbxNode *get_fbx_root_node(const char *fbx_path) 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 - 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) { std::vector indices; @@ -86,9 +99,6 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level) int count = load_triangles(attr, indices, vertices); - uint id = attr->GetUniqueID(); - uint pid = parent_node->GetUniqueID(); - printf("[%d]vertices: %ld\n", count); // save data to database sqlite3 *db = ctx->db; @@ -99,7 +109,7 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level) pid, attr->GetName(), vertices.size(), indices.size(), - parent_node->GetNameOnly().Buffer()); + node->GetNameOnly().Buffer()); save_mesh_vertices(ctx, id, vertices); save_mesh_indices(ctx, id, indices); @@ -107,11 +117,11 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level) } // 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); } } @@ -142,7 +152,6 @@ void print_node_info(FbxNode* node, int level) { int prop_count = 0; printf(" Properties: "); while (p.IsValid() && prop_count < 5) { - printf("%s[%.2f] ", p.GetName().Buffer(), p.Get()); prop_count++; p = node->GetNextProperty(p); diff --git a/cpp_src/include/db_ops.h b/cpp_src/include/db_ops.h index 8e3d47a..a64e85d 100644 --- a/cpp_src/include/db_ops.h +++ b/cpp_src/include/db_ops.h @@ -1,4 +1,5 @@ #include + using namespace std; /** * @brief 创建并打开SQLite数据库连接 @@ -33,6 +34,49 @@ void create_tables(sqlite3* db); * 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); - +/** + * @brief 保存网格顶点数据到上下文 + * @param ctx FttContext上下文指针,用于管理网格数据存储 + * @param mesh_id 目标网格的唯一标识符 + * @param vertices 顶点数据容器,存储V3类型的顶点坐标集合 + * @return 成功返回0,失败返回非0错误码 + */ int save_mesh_vertices(FttContext* ctx, uint mesh_id, std::vector vertices); -int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector indices); \ No newline at end of file + +/** + * @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 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 +); \ No newline at end of file diff --git a/cpp_src/include/tools.h b/cpp_src/include/tools.h index 9a84846..b2086be 100644 --- a/cpp_src/include/tools.h +++ b/cpp_src/include/tools.h @@ -5,7 +5,7 @@ #include #include #include - +#include #include using namespace std;