diff --git a/cpp_src/db_ops.cpp b/cpp_src/db_ops.cpp index 6be7882..ad88cb0 100644 --- a/cpp_src/db_ops.cpp +++ b/cpp_src/db_ops.cpp @@ -31,6 +31,7 @@ void create_tables(sqlite3 *db) const char *sql_meshes = R"( CREATE TABLE IF NOT EXISTS meshes ( id INTEGER PRIMARY KEY AUTOINCREMENT, + pid INTEGER, name TEXT NOT NULL, vertex_count INTEGER NOT NULL, index_count INTEGER NOT NULL, @@ -56,11 +57,6 @@ void create_tables(sqlite3 *db) position_x REAL NOT NULL, position_y REAL NOT NULL, position_z REAL NOT NULL, - normal_x REAL, - normal_y REAL, - normal_z REAL, - uv_u REAL, - uv_v REAL, FOREIGN KEY(mesh_id) REFERENCES meshes(id) ON DELETE CASCADE ); )"; @@ -125,6 +121,7 @@ void create_tables(sqlite3 *db) 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) @@ -134,7 +131,7 @@ int save_mesh_to_table(FttContext *ctx, return -1; sqlite3_stmt *stmt = nullptr; - const char *sql = "INSERT OR IGNORE INTO meshes (id, name, vertex_count, index_count, fbx_id) VALUES (?, ?, ?, ?, ?);"; + const char *sql = "INSERT OR IGNORE INTO meshes (id, pid, name, vertex_count, index_count, fbx_id) VALUES (?, ?, ?, ?, ?, ?);"; int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr); if (rc != SQLITE_OK) { @@ -143,10 +140,11 @@ int save_mesh_to_table(FttContext *ctx, } sqlite3_bind_int64(stmt, 1, id); - sqlite3_bind_text(stmt, 2, name.c_str(), -1, SQLITE_STATIC); - sqlite3_bind_int(stmt, 3, vertex_count); - sqlite3_bind_int(stmt, 4, index_count); - sqlite3_bind_text(stmt, 5, fbx_id.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int64(stmt, 2, pid); + sqlite3_bind_text(stmt, 3, name.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 4, vertex_count); + sqlite3_bind_int(stmt, 5, index_count); + sqlite3_bind_text(stmt, 6, fbx_id.c_str(), -1, SQLITE_STATIC); rc = sqlite3_step(stmt); if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT) @@ -193,37 +191,43 @@ 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) { +int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector indices) { if (!ctx->db) return -1; - - sqlite3_stmt *stmt = nullptr; - const char *sql = "INSERT OR IGNORE INTO indices (mesh_id, index_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; + printf("save indices: %d\n", indices.size()); + for (int i = 0; i < indices.size(); i++) + { + printf("%d ", indices[i]); } + - sqlite3_exec(ctx->db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); // 开启事务 + // sqlite3_stmt *stmt = nullptr; + // const char *sql = "INSERT OR IGNORE INTO indices (mesh_id, index_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; + // } - for (int i = 0; i < indices.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>(indices[i])); // 修正为double类型绑定 - sqlite3_bind_double(stmt, 4, std::get<1>(indices[i])); - sqlite3_bind_double(stmt, 5, std::get<2>(indices[i])); + // sqlite3_exec(ctx->db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr); // 开启事务 - 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; - } - } + // for (int i = 0; i < indices.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>(indices[i])); // 修正为double类型绑定 + // sqlite3_bind_double(stmt, 4, std::get<1>(indices[i])); + // sqlite3_bind_double(stmt, 5, std::get<2>(indices[i])); - sqlite3_exec(ctx->db, "COMMIT;", nullptr, nullptr, nullptr); // 提交事务 - sqlite3_finalize(stmt); + // 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_wrap.cpp b/cpp_src/fbx_wrap.cpp index 17124bb..3938778 100644 --- a/cpp_src/fbx_wrap.cpp +++ b/cpp_src/fbx_wrap.cpp @@ -6,32 +6,32 @@ using namespace std; -int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector &indices, std::vector &triangles) +int load_triangles(fbxsdk::FbxNodeAttribute *attr, std::vector indices, std::vector &vertices) { if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) return false; FbxMesh *mesh = static_cast(attr); - int polyCount = mesh->GetPolygonCount(); - for (int i = 0; i < polyCount; ++i) + + unsigned int index_p = 0; + FbxVector4* control_points = mesh->GetControlPoints(); + for (int p = 0; p < mesh->GetPolygonCount(); p++) { - int vertexCount = mesh->GetPolygonSize(i); - std::vector polyIndices; - for (int j = 0; j < vertexCount; ++j) - { - polyIndices.push_back(mesh->GetPolygonVertex(i, j)); + if (mesh->GetPolygonSize(p) != 3) { + // 不是三角形 + return index_p; } - for (int j = 2; j < vertexCount; ++j) + for (int p_vertex = 0; p_vertex < mesh->GetPolygonSize(p); p_vertex++) { - 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]}); - } + int vertex_indexed = mesh->GetPolygonVertex(p, p_vertex); + FbxVector4 control_point = control_points[vertex_indexed]; + V3 v = V3(control_point.mData[0], control_point.mData[1], control_point.mData[2]); + vertices.push_back(v); + indices.push_back(index_p++); } } - return 0; + + return index_p; } FbxNode *get_fbx_root_node(const char *fbx_path) @@ -81,23 +81,28 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level) FbxNodeAttribute *attr = parent_node->GetNodeAttributeByIndex(i); if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh) { + std::vector indices; std::vector vertices; - std::vector triangles; - int count = load_triangles(attr, vertices, triangles); + + int count = load_triangles(attr, indices, vertices); + uint id = attr->GetUniqueID(); - printf("[%d]triangles: %ld\n", id, triangles.size()); + uint pid = parent_node->GetUniqueID(); + + printf("[%d]vertices: %ld\n", count); // save data to database sqlite3 *db = ctx->db; // todo save mesh into db save_mesh_to_table(ctx, ctx->db, id, + pid, attr->GetName(), - vertices.size(), triangles.size(), + vertices.size(), indices.size(), parent_node->GetNameOnly().Buffer()); - save_mesh_vertices(ctx, id, triangles); - save_mesh_indices(ctx, id, vertices); + save_mesh_vertices(ctx, id, vertices); + save_mesh_indices(ctx, id, indices); } } @@ -114,6 +119,12 @@ void each_node(FttContext *ctx, FbxNode *parent_node, int level) void print_node_info(FbxNode *node, int level) { + // todo 打印一下节点信息 + // 1. 平移、旋转、缩放等矩阵 + // 2. 名称,id, pid等 + // 3. 节点其他properties + + // 打印一下节点信息 printf("|"); for (int i = 0; i < level; i++) @@ -121,5 +132,10 @@ void print_node_info(FbxNode *node, int level) printf("-"); } printf("> "); - printf("[%lld]: %s\n", node->GetUniqueID(), node->GetNameOnly().Buffer()); + FbxNode* parent = node->GetParent(); + uint parent_id = 0; + if (parent != NULL) { + parent_id = parent->GetUniqueID(); + } + printf("[%lld/%lld]: %s\n", node->GetUniqueID(), parent_id, 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 cc9928f..8e3d47a 100644 --- a/cpp_src/include/db_ops.h +++ b/cpp_src/include/db_ops.h @@ -32,7 +32,7 @@ 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, uint pid, 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); -int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector indices); \ No newline at end of file +int save_mesh_indices(FttContext* ctx, uint mesh_id, std::vector indices); \ No newline at end of file diff --git a/cpp_src/include/fbx_wrap.h b/cpp_src/include/fbx_wrap.h index 7604f77..c626392 100644 --- a/cpp_src/include/fbx_wrap.h +++ b/cpp_src/include/fbx_wrap.h @@ -32,9 +32,9 @@ FbxNode* get_fbx_root_node(const char* fbx_path); /** * @brief 从FBX网格属性加载顶点数据和三角化索引 * @param[in] attr FBX节点属性,需为FbxMesh类型 + * @param[out] indices 输出三角形索引数组(每个Triangle存储3个顶点索引) * @param[out] vertices 输出顶点坐标数组(每个Triangle存储3个FbxVector4顶点) - * @param[out] triangles 输出三角形索引数组(每个Triangle存储3个顶点索引) * @return bool 成功返回true,失败返回false * @note 内部会强制三角化网格,非三角形多边形将被忽略 */ -int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector& indices, std::vector& triangles); +int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector indices, std::vector &vertices); diff --git a/cpp_src/include/tools.h b/cpp_src/include/tools.h index 2661378..9a84846 100644 --- a/cpp_src/include/tools.h +++ b/cpp_src/include/tools.h @@ -17,7 +17,7 @@ typedef struct { sqlite3* db; } FttContext; -using V3 = std::tuple; +using V3 = std::tuple; FttContext ctx_from_const(const FttContext* ctx);