save mesh info
This commit is contained in:
parent
cd6038ea13
commit
691109e12a
3
build.rs
3
build.rs
|
@ -7,9 +7,10 @@ fn main() {
|
|||
// .flag("-std=c++11")
|
||||
.warnings(false)
|
||||
.include("./cpp_src/include")
|
||||
.file("./cpp_src/tools.cpp")
|
||||
.file("./cpp_src/db_ops.cpp")
|
||||
.file("./cpp_src/fbx_parse.cpp")
|
||||
.file("./cpp_src/fbx_wrap.cpp")
|
||||
.file("./cpp_src/db_ops.cpp")
|
||||
.compile("fbx_parse");
|
||||
// -------------
|
||||
println!("cargo:rustc-link-search=native=./cpp_src/lib");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <db_ops.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <tools.h>
|
||||
using namespace std;
|
||||
|
||||
sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
||||
|
@ -19,7 +19,7 @@ sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
|||
int result_code = sqlite3_open(db_path, &db);
|
||||
if (result_code != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to open DB: %s\n", sqlite3_errmsg(db));
|
||||
fprintf(stderr, "Failed to open DB: %s[%d]\n", sqlite3_errmsg(db), result_code);
|
||||
sqlite3_close(db);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -116,3 +116,38 @@ void create_tables(sqlite3 *db)
|
|||
// 成功执行无需释放err_msg(sqlite3_exec成功时err_msg为NULL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 函数定义
|
||||
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;
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(db));
|
||||
return rc;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
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;
|
||||
}
|
|
@ -8,7 +8,7 @@ using namespace std;
|
|||
|
||||
extern "C" {
|
||||
// 定义给Rust调用的接口函数
|
||||
void fbx_parse(const FttContext* ctx)
|
||||
void fbx_parse(FttContext* ctx)
|
||||
{
|
||||
printf("%s\n", ctx->fbx_file);
|
||||
FbxManager* lSdkManager = FbxManager::Create();
|
||||
|
@ -43,17 +43,21 @@ extern "C" {
|
|||
|
||||
void load_fbx_mesh_to_db( FttContext* ctx)
|
||||
{
|
||||
// get mutable data
|
||||
auto temp = ctx_from_const(ctx);
|
||||
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);
|
||||
printf("db---> %x\n", db);
|
||||
ctx->db = db;
|
||||
if (db == NULL) {
|
||||
return;
|
||||
}
|
||||
mut_ctx->db = db;
|
||||
// init db tables
|
||||
create_tables(ctx->db);
|
||||
|
||||
create_tables(mut_ctx->db);
|
||||
|
||||
FbxNode* root = get_fbx_root_node(ctx->fbx_file);
|
||||
each_node(ctx, root, 0);
|
||||
each_node(mut_ctx, root, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
#include "fbx_wrap.h"
|
||||
#include <fbx_wrap.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <db_ops.h>
|
||||
#include <tools.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles) {
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<V3>& indices, std::vector<V3>& triangles) {
|
||||
if (!attr || attr->GetAttributeType() != FbxNodeAttribute::eMesh) return false;
|
||||
FbxMesh* mesh = static_cast<FbxMesh*>(attr);
|
||||
// 顶点数据
|
||||
// int ctrlPointCount = mesh->GetControlPointsCount();
|
||||
// vertices.assign(mesh->GetControlPoints(), mesh->GetControlPoints() + ctrlPointCount);
|
||||
|
||||
// 三角化并提取三角形索引
|
||||
FbxGeometryConverter converter(mesh->GetFbxManager());
|
||||
if (!converter.Triangulate(mesh, true)) return false; // 强制三角化
|
||||
|
||||
int polyCount = mesh->GetPolygonCount();
|
||||
triangles.reserve(polyCount);
|
||||
for (int i = 0; i < polyCount; ++i) {
|
||||
if (mesh->GetPolygonSize(i) != 3) continue; // 跳过非三角形(理论上不会存在)
|
||||
int i0 = mesh->GetPolygonVertex(i, 0);
|
||||
int i1 = mesh->GetPolygonVertex(i, 1);
|
||||
int i2 = mesh->GetPolygonVertex(i, 2);
|
||||
triangles.emplace_back(i0, i1, i2);
|
||||
int vertexCount = mesh->GetPolygonSize(i);
|
||||
std::vector<int> polyIndices;
|
||||
for (int j = 0; j < vertexCount; ++j) {
|
||||
polyIndices.push_back(mesh->GetPolygonVertex(i, j));
|
||||
}
|
||||
return true;
|
||||
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]});
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FbxNode* get_fbx_root_node(const char* fbx_path)
|
||||
|
@ -55,7 +57,7 @@ FbxNode* get_fbx_root_node(const char* fbx_path)
|
|||
}
|
||||
|
||||
|
||||
void each_node(const FttContext* ctx, FbxNode* parent_node, int level)
|
||||
void each_node(FttContext* ctx, FbxNode* parent_node, int level)
|
||||
{
|
||||
// info
|
||||
print_node_info(parent_node, level);
|
||||
|
@ -65,12 +67,20 @@ void each_node(const FttContext* ctx, FbxNode* parent_node, int level)
|
|||
FbxNodeAttribute* attr = parent_node->GetNodeAttributeByIndex(i);
|
||||
if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh)
|
||||
{
|
||||
std::vector<Triangle> triangles;
|
||||
int count = load_triangles(attr, triangles);
|
||||
printf("triangles: %ld\n", triangles.size());
|
||||
std::vector<V3> vertices;
|
||||
std::vector<V3> triangles;
|
||||
int count = load_triangles(attr, vertices, triangles);
|
||||
uint id = attr->GetUniqueID();
|
||||
printf("[%ld]triangles: %ld\n", id, triangles.size());
|
||||
// save data to database
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,35 @@
|
|||
#include <sqlite3.h>
|
||||
|
||||
|
||||
#include <tools.h>
|
||||
using namespace std;
|
||||
/**
|
||||
* @brief 创建并打开SQLite数据库连接
|
||||
* @param db_path 数据库文件路径
|
||||
* @param overwrite_file 若为true则删除已有文件后创建新数据库
|
||||
* @return 成功返回sqlite3句柄,失败返回NULL
|
||||
*/
|
||||
sqlite3* create_db(const char* db_path, bool overwrite_file);
|
||||
|
||||
/**
|
||||
* @brief 在指定数据库中创建必要表结构
|
||||
* @param db 已打开的SQLite数据库句柄
|
||||
* @note 需确保db参数有效且已成功打开
|
||||
*/
|
||||
void create_tables(sqlite3* db);
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//////// 数据保存 /////////
|
||||
///////////////////////////
|
||||
|
||||
/**
|
||||
* @brief 将网格数据元信息保存到数据库表
|
||||
* @param ctx FTT上下文句柄,包含日志/错误处理等公共资源
|
||||
* @param db 已打开的SQLite数据库连接
|
||||
* @param name 网格名称(唯一标识)
|
||||
* @param vertex_count 顶点数量
|
||||
* @param index_count 索引数量
|
||||
* @param fbx_id 关联的FBX文件ID
|
||||
* @return 成功返回SQLITE_OK,失败返回SQLite错误码(<0)
|
||||
* @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);
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#include <fbxsdk.h>
|
||||
#include <vector>
|
||||
#include <tools.h>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using Triangle = std::tuple<int, int, int>;
|
||||
using V3 = std::tuple<int, int, int>;
|
||||
|
||||
/**
|
||||
* 递归遍历FBX节点树结构
|
||||
|
@ -14,7 +11,7 @@ using Triangle = std::tuple<int, int, int>;
|
|||
* @note 函数内部会递归访问parent_node的所有直接子节点和间接子节点
|
||||
* @warning 若输入的parent_node无效(如野指针)可能导致程序崩溃
|
||||
*/
|
||||
void each_node(const FttContext* ctx, FbxNode* parent_node, int level);
|
||||
void each_node(FttContext* ctx, FbxNode* parent_node, int level);
|
||||
/**
|
||||
* 打印FBX节点的基本信息(含层级缩进)
|
||||
* @param node 待打印信息的节点指针(nullptr时输出警告日志)
|
||||
|
@ -32,11 +29,13 @@ void print_node_info(FbxNode* node, int level);
|
|||
*/
|
||||
FbxNode* get_fbx_root_node(const char* fbx_path);
|
||||
|
||||
|
||||
/**
|
||||
* 从FBX属性提取三角形数据并填充到向量
|
||||
* @param attr FBX节点属性指针(需为Mesh类型,非Mesh类型返回0)
|
||||
* @param triangles 输出三角形数据的向量引用(会自动清空原有数据)
|
||||
* @return int 成功提取的三角形数量,失败返回-1(如attr为空或非Mesh类型)
|
||||
* @note 仅处理三角形网格,四边形等多边形会被自动三角化
|
||||
* @brief 从FBX网格属性加载顶点数据和三角化索引
|
||||
* @param[in] attr FBX节点属性,需为FbxMesh类型
|
||||
* @param[out] vertices 输出顶点坐标数组(每个Triangle存储3个FbxVector4顶点)
|
||||
* @param[out] triangles 输出三角形索引数组(每个Triangle存储3个顶点索引)
|
||||
* @return bool 成功返回true,失败返回false
|
||||
* @note 内部会强制三角化网格,非三角形多边形将被忽略
|
||||
*/
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles);
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<V3>& indices, std::vector<V3>& triangles);
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#ifndef _TOOLS_H_
|
||||
#define _TOOLS_H_
|
||||
|
||||
#include <fbxsdk.h>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct {
|
||||
char* fbx_file;
|
||||
|
@ -8,5 +17,7 @@ typedef struct {
|
|||
sqlite3* db;
|
||||
} FttContext;
|
||||
|
||||
FttContext ctx_from_const(const FttContext* ctx);
|
||||
|
||||
#endif
|
||||
|
||||
void create_tables(sqlite3* db);
|
|
@ -0,0 +1,11 @@
|
|||
#include <tools.h>
|
||||
|
||||
FttContext ctx_from_const(const FttContext* ctx) {
|
||||
FttContext mut_ctx;
|
||||
|
||||
mut_ctx.db = ctx->db;
|
||||
mut_ctx.fbx_file = ctx->fbx_file;
|
||||
mut_ctx.out_dir = ctx->out_dir;
|
||||
|
||||
return mut_ctx;
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use std::{ffi::CString, os::raw::c_char};
|
||||
|
||||
fn main() {
|
||||
convert_fbx_to_3dtiles("/root/data/绿科-三维视图-{三维}111.fbx",
|
||||
"/root/data/out/lk");
|
||||
convert_fbx_to_3dtiles("/root/src/fbx_to_3dtiles/out/绿科-三维视图-{三维}111.fbx",
|
||||
"/root/src/fbx_to_3dtiles/out/lk");
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
Loading…
Reference in New Issue