diff --git a/cpp_src/db_ops.cpp b/cpp_src/db_ops.cpp index 1a01092..d6e7480 100644 --- a/cpp_src/db_ops.cpp +++ b/cpp_src/db_ops.cpp @@ -51,6 +51,7 @@ void create_tables(sqlite3 *db) const char *sql_vertices = R"( CREATE TABLE IF NOT EXISTS vertices ( id INTEGER PRIMARY KEY AUTOINCREMENT, + vert_id INTEGER NOT NULL, mesh_id INTEGER NOT NULL, position_x REAL NOT NULL, position_y REAL NOT NULL, @@ -117,22 +118,23 @@ void create_tables(sqlite3 *db) } } - // 函数定义 -int save_mesh_to_table(FttContext* ctx, - sqlite3* db, - uint id, - 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, + const std::string &name, + int vertex_count, int index_count, + const std::string &fbx_id) { - if (!db || name.empty() || fbx_id.empty()) return -1; + if (!db || name.empty() || fbx_id.empty()) + return -1; - sqlite3_stmt* stmt = nullptr; - const char* sql = "INSERT OR IGNORE INTO meshes (id, name, vertex_count, index_count, fbx_id) VALUES (?, ?, ?, ?, ?);"; + sqlite3_stmt *stmt = nullptr; + const char *sql = "INSERT OR IGNORE INTO meshes (id, name, vertex_count, index_count, fbx_id) VALUES (?, ?, ?, ?, ?);"; int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr); - if (rc != SQLITE_OK) { + if (rc != SQLITE_OK) + { fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(db)); return rc; } @@ -144,10 +146,46 @@ int save_mesh_to_table(FttContext* ctx, sqlite3_bind_text(stmt, 5, fbx_id.c_str(), -1, SQLITE_STATIC); rc = sqlite3_step(stmt); - if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT) { + if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT) + { fprintf(stderr, "SQL step failed: %s\n", sqlite3_errmsg(db)); } sqlite3_finalize(stmt); return rc == SQLITE_DONE ? 0 : -1; -} \ No newline at end of file +} + +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) { + 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++) { + sqlite3_reset(stmt); // 重置语句 + sqlite3_bind_int64(stmt, 1, mesh_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) { + 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); + return rc; + } + } + + sqlite3_exec(ctx->db, "COMMIT;", nullptr, nullptr, nullptr); // 提交事务 + sqlite3_finalize(stmt); + return 0; +} diff --git a/cpp_src/fbx_parse.cpp b/cpp_src/fbx_parse.cpp index 687f873..01596e2 100644 --- a/cpp_src/fbx_parse.cpp +++ b/cpp_src/fbx_parse.cpp @@ -6,58 +6,72 @@ using namespace std; -extern "C" { +extern "C" +{ // 定义给Rust调用的接口函数 - void fbx_parse(FttContext* ctx) + void fbx_parse(FttContext *ctx) { printf("%s\n", ctx->fbx_file); - FbxManager* lSdkManager = FbxManager::Create(); - if (lSdkManager){ + FbxManager *lSdkManager = FbxManager::Create(); + if (lSdkManager) + { printf("FbxManager created\n"); - } else{ + } + else + { printf("FbxManager creation failed.\n"); } - FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene"); - if (lScene){ + FbxScene *lScene = FbxScene::Create(lSdkManager, "myScene"); + if (lScene) + { printf("FbxScene created\n"); - } else{ + } + else + { printf("FbxScene creation failed.\n"); } - FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); + FbxImporter *lImporter = FbxImporter::Create(lSdkManager, ""); bool s = lImporter->Initialize(ctx->fbx_file, -1, lSdkManager->GetIOSettings()); - if (s){ + if (s) + { printf("FbxImporter initialized\n"); - } else{ + } + else + { printf("FbxImporter initialization failed.\n"); } lImporter->Import(lScene); lImporter->Destroy(); - FbxNode* lRootNode = lScene->GetRootNode(); - if (lRootNode) { + FbxNode *lRootNode = lScene->GetRootNode(); + if (lRootNode) + { each_node(ctx, lRootNode, 0); - } else { + } + else + { printf("No root node found in the scene.\n"); } } - void load_fbx_mesh_to_db( FttContext* ctx) + void load_fbx_mesh_to_db(FttContext *ctx) { // get mutable data auto temp = ctx_from_const(ctx); - FttContext* mut_ctx = &temp; + FttContext *mut_ctx = &temp; // 按fbx名称生成 ${ctx.out_dir}/sqlite3.db // 初始化db赋值到ctx.db - sqlite3* db = create_db((std::string(ctx->out_dir) + "/db.sqlite3").c_str(), true); - if (db == NULL) { + sqlite3 *db = create_db((std::string(ctx->out_dir) + "/db.sqlite3").c_str(), true); + if (db == NULL) + { return; } mut_ctx->db = db; // init db tables create_tables(mut_ctx->db); - FbxNode* root = get_fbx_root_node(ctx->fbx_file); + FbxNode *root = get_fbx_root_node(ctx->fbx_file); each_node(mut_ctx, root, 0); } } diff --git a/cpp_src/fbx_wrap.cpp b/cpp_src/fbx_wrap.cpp index c7aaf64..c844189 100644 --- a/cpp_src/fbx_wrap.cpp +++ b/cpp_src/fbx_wrap.cpp @@ -6,20 +6,26 @@ using namespace std; -int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector& indices, std::vector& triangles) { - if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) return false; - FbxMesh* mesh = static_cast(attr); +int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector &indices, std::vector &triangles) +{ + if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) + return false; + FbxMesh *mesh = static_cast(attr); int polyCount = mesh->GetPolygonCount(); - for (int i = 0; i < polyCount; ++i) { + for (int i = 0; i < polyCount; ++i) + { int vertexCount = mesh->GetPolygonSize(i); std::vector polyIndices; - for (int j = 0; j < vertexCount; ++j) { + for (int j = 0; j < vertexCount; ++j) + { polyIndices.push_back(mesh->GetPolygonVertex(i, j)); } - for (int j = 2; j < vertexCount; ++j) { - indices.push_back({polyIndices[0], polyIndices[j-1], polyIndices[j]}); - for (int k : {0, j-1, j}) { + for (int j = 2; j < vertexCount; ++j) + { + indices.push_back({polyIndices[0], polyIndices[j - 1], polyIndices[j]}); + for (int k : {0, j - 1, j}) + { FbxVector4 pos = mesh->GetControlPointAt(polyIndices[k]); triangles.push_back({(float)pos[0], (float)pos[1], (float)pos[2]}); } @@ -28,26 +34,35 @@ int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector& indices, std return 0; } -FbxNode* get_fbx_root_node(const char* fbx_path) +FbxNode *get_fbx_root_node(const char *fbx_path) { printf("loading fbx file: %s\n", fbx_path); - FbxManager* lSdkManager = FbxManager::Create(); - if (lSdkManager){ + FbxManager *lSdkManager = FbxManager::Create(); + if (lSdkManager) + { printf("FbxManager created successfully.\n"); - } else{ + } + else + { printf("FbxManager creation failed.\n"); } - FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene"); - if (lScene){ + FbxScene *lScene = FbxScene::Create(lSdkManager, "myScene"); + if (lScene) + { printf("FbxScene created successfully.\n"); - } else{ + } + else + { printf("FbxScene creation failed.\n"); } - FbxImporter* lImporter = FbxImporter::Create(lSdkManager, ""); + FbxImporter *lImporter = FbxImporter::Create(lSdkManager, ""); bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings()); - if (s){ + if (s) + { printf("FbxImporter initialized successfully.\n"); - } else{ + } + else + { printf("FbxImporter initialization failed.\n"); } lImporter->Import(lScene); @@ -56,47 +71,47 @@ 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 *parent_node, int level) { // info print_node_info(parent_node, level); // data for (int i = 0; i < parent_node->GetNodeAttributeCount(); i++) { - FbxNodeAttribute* attr = parent_node->GetNodeAttributeByIndex(i); + FbxNodeAttribute *attr = parent_node->GetNodeAttributeByIndex(i); if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh) { std::vector vertices; std::vector triangles; int count = load_triangles(attr, vertices, triangles); uint id = attr->GetUniqueID(); - printf("[%ld]triangles: %ld\n", id, triangles.size()); + printf("[%d]triangles: %ld\n", id, triangles.size()); // save data to database - sqlite3* db = ctx->db; + sqlite3 *db = ctx->db; // todo save mesh into db - save_mesh_to_table(ctx, ctx->db, - id, - attr->GetName(), - vertices.size(), triangles.size(), - parent_node->GetNameOnly().Buffer()); + save_mesh_to_table(ctx, ctx->db, + id, + attr->GetName(), + vertices.size(), triangles.size(), + parent_node->GetNameOnly().Buffer()); + + save_mesh_vertices(ctx, id, vertices); } - } - + // children - if (parent_node->GetChildCount()) + if (parent_node->GetChildCount()) { - for (int i = 0; i < parent_node->GetChildCount(); i++) + for (int i = 0; i < parent_node->GetChildCount(); i++) { - FbxNode* child = parent_node->GetChild(i); + FbxNode *child = parent_node->GetChild(i); each_node(ctx, child, level + 1); } } } -void print_node_info(FbxNode* node, int level) +void print_node_info(FbxNode *node, int level) { // 打印一下节点信息 printf("|"); @@ -105,5 +120,5 @@ void print_node_info(FbxNode* node, int level) printf("-"); } printf("> "); - printf("[%ld]: %s\n", node->GetUniqueID(), node->GetNameOnly().Buffer()); + printf("[%lld]: %s\n", node->GetUniqueID(), node->GetNameOnly().Buffer()); } \ No newline at end of file diff --git a/cpp_src/include/db_ops.h b/cpp_src/include/db_ops.h index 3a8f7b8..5c14f4c 100644 --- a/cpp_src/include/db_ops.h +++ b/cpp_src/include/db_ops.h @@ -32,4 +32,6 @@ void create_tables(sqlite3* db); * @note 1. 参数需确保有效:ctx/db非NULL,name/fbx_id非空 * 2. 内部自动处理事务,重复name会触发唯一键冲突 */ -int save_mesh_to_table(FttContext *ctx, sqlite3 *db, uint id, 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, const std::string &name, int vertex_count, int index_count, const std::string &fbx_id); + +int save_mesh_vertices(FttContext* ctx, uint mesh_id, std::vector vertices); \ No newline at end of file diff --git a/cpp_src/include/fbx_wrap.h b/cpp_src/include/fbx_wrap.h index 4acec55..7604f77 100644 --- a/cpp_src/include/fbx_wrap.h +++ b/cpp_src/include/fbx_wrap.h @@ -2,7 +2,6 @@ using namespace std; -using V3 = std::tuple; /** * 递归遍历FBX节点树结构 diff --git a/cpp_src/include/tools.h b/cpp_src/include/tools.h index 08ed26d..2661378 100644 --- a/cpp_src/include/tools.h +++ b/cpp_src/include/tools.h @@ -17,6 +17,8 @@ typedef struct { sqlite3* db; } FttContext; +using V3 = std::tuple; + FttContext ctx_from_const(const FttContext* ctx); #endif diff --git a/cpp_src/tools.cpp b/cpp_src/tools.cpp index 35c9706..59a78af 100644 --- a/cpp_src/tools.cpp +++ b/cpp_src/tools.cpp @@ -1,6 +1,7 @@ #include -FttContext ctx_from_const(const FttContext* ctx) { +FttContext ctx_from_const(const FttContext *ctx) +{ FttContext mut_ctx; mut_ctx.db = ctx->db; diff --git a/src/main.rs b/src/main.rs index 413bb89..57183f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ use std::{ffi::CString, os::raw::c_char}; fn main() { - convert_fbx_to_3dtiles("/root/src/fbx_to_3dtiles/out/绿科-三维视图-{三维}111.fbx", - "/root/src/fbx_to_3dtiles/out/lk"); + convert_fbx_to_3dtiles("./out/绿科-三维视图-{三维}111.fbx", + "./out/lk"); } #[repr(C)]