sqlite
This commit is contained in:
parent
72c0fdc1cb
commit
cd6038ea13
|
@ -2,4 +2,6 @@
|
|||
*.o
|
||||
*.exe
|
||||
.vscode/
|
||||
.idea/
|
||||
.idea/
|
||||
*.dump
|
||||
out/
|
2
build.rs
2
build.rs
|
@ -9,8 +9,10 @@ fn main() {
|
|||
.include("./cpp_src/include")
|
||||
.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");
|
||||
println!("cargo:rustc-link-lib=fbxsdk");
|
||||
println!("cargo:rustc-link-lib=sqlite3");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
#include <db_ops.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
||||
{
|
||||
if (overwrite_file)
|
||||
{
|
||||
if (remove(db_path) != 0 && errno != ENOENT)
|
||||
{
|
||||
fprintf(stderr, "Failed to remove old DB file: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3 *db = NULL;
|
||||
int result_code = sqlite3_open(db_path, &db);
|
||||
if (result_code != SQLITE_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to open DB: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return NULL;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
void create_tables(sqlite3 *db)
|
||||
{
|
||||
const char *sql_meshes = R"(
|
||||
CREATE TABLE IF NOT EXISTS meshes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
vertex_count INTEGER NOT NULL,
|
||||
index_count INTEGER NOT NULL,
|
||||
fbx_id TEXT UNIQUE NOT NULL
|
||||
);
|
||||
)";
|
||||
|
||||
const char *sql_materials = R"(
|
||||
CREATE TABLE IF NOT EXISTS materials (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
shader_name TEXT,
|
||||
fbx_id TEXT UNIQUE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
)";
|
||||
|
||||
const char *sql_vertices = R"(
|
||||
CREATE TABLE IF NOT EXISTS vertices (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
mesh_id INTEGER NOT NULL,
|
||||
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
|
||||
);
|
||||
)";
|
||||
|
||||
const char *sql_indices = R"(
|
||||
CREATE TABLE IF NOT EXISTS indices (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
mesh_id INTEGER NOT NULL,
|
||||
value INTEGER NOT NULL,
|
||||
FOREIGN KEY(mesh_id) REFERENCES meshes(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
const char *sql_material_props = R"(
|
||||
CREATE TABLE IF NOT EXISTS material_properties (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
material_id INTEGER NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
FOREIGN KEY(material_id) REFERENCES materials(id) ON DELETE CASCADE,
|
||||
UNIQUE(material_id, key)
|
||||
);
|
||||
)";
|
||||
|
||||
const char *sql[] = {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]);
|
||||
// 检查前置条件:数据库连接和SQL语句必须有效
|
||||
if (!db)
|
||||
{
|
||||
printf("db 是空的");
|
||||
// 处理空连接错误(如log.Fatalf("db connection is NULL"))
|
||||
return; // 或抛异常终止
|
||||
}
|
||||
if (!sql[i] || strlen(sql[i]) == 0)
|
||||
{
|
||||
printf("SQL Query 是空的");
|
||||
// 处理空SQL错误(如log.Errorf("sql[%d] is NULL/empty", i))
|
||||
continue; // 或终止
|
||||
}
|
||||
|
||||
char *err_msg = nullptr;
|
||||
int ret = sqlite3_exec(db, sql[i], nullptr, nullptr, &err_msg);
|
||||
printf("db ret: %d, err_msg: %s\n", ret, err_msg);
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
// 必须处理错误:记录具体SQL和错误信息
|
||||
// log.Criticalf("SQL error (i=%d): %s, SQL: %s", i, err_msg ? err_msg : "unknown", sql[i]);
|
||||
sqlite3_free(err_msg); // 释放错误信息
|
||||
return; // 或根据场景决定是否继续
|
||||
}
|
||||
// 成功执行无需释放err_msg(sqlite3_exec成功时err_msg为NULL)
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
// buz
|
||||
#include <fbx_wrap.h>
|
||||
#include <db_ops.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -40,8 +41,18 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
|
||||
void load_fbx_mesh_to_db(const FttContext* ctx)
|
||||
void load_fbx_mesh_to_db(FttContext* ctx)
|
||||
{
|
||||
|
||||
// 按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;
|
||||
// init db tables
|
||||
create_tables(ctx->db);
|
||||
|
||||
|
||||
FbxNode* root = get_fbx_root_node(ctx->fbx_file);
|
||||
each_node(ctx, root, 0);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@ void each_node(const FttContext* ctx, FbxNode* parent_node, int level)
|
|||
int count = load_triangles(attr, triangles);
|
||||
printf("triangles: %ld\n", triangles.size());
|
||||
// save data to database
|
||||
sqlite3* db = ctx->db;
|
||||
// todo save mesh into db
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include <sqlite3.h>
|
||||
|
||||
|
||||
sqlite3* create_db(const char* db_path, bool overwrite_file);
|
||||
|
||||
void create_tables(sqlite3* db);
|
|
@ -23,7 +23,20 @@ void each_node(const FttContext* ctx, FbxNode* parent_node, int level);
|
|||
* @example 层级2的节点打印格式:" |-- NodeName (Type: Mesh, Children: 3)"
|
||||
*/
|
||||
void print_node_info(FbxNode* node, int level);
|
||||
|
||||
/**
|
||||
* 从FBX文件加载并返回根节点
|
||||
* @param fbx_path FBX文件路径(需绝对路径或相对于可执行文件路径)
|
||||
* @return FbxNode* 成功时返回根节点指针,失败返回nullptr
|
||||
* @note 内部会初始化FBX SDK环境并自动释放资源
|
||||
* @warning 路径无效或文件损坏时返回空指针,需调用方检查
|
||||
*/
|
||||
FbxNode* get_fbx_root_node(const char* fbx_path);
|
||||
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles);
|
||||
/**
|
||||
* 从FBX属性提取三角形数据并填充到向量
|
||||
* @param attr FBX节点属性指针(需为Mesh类型,非Mesh类型返回0)
|
||||
* @param triangles 输出三角形数据的向量引用(会自动清空原有数据)
|
||||
* @return int 成功提取的三角形数量,失败返回-1(如attr为空或非Mesh类型)
|
||||
* @note 仅处理三角形网格,四边形等多边形会被自动三角化
|
||||
*/
|
||||
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles);
|
|
@ -1,5 +1,12 @@
|
|||
#include <sqlite3.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
char* fbx_file;
|
||||
char* out_dir;
|
||||
} FttContext;
|
||||
|
||||
sqlite3* db;
|
||||
} FttContext;
|
||||
|
||||
|
||||
void create_tables(sqlite3* db);
|
|
@ -1,7 +1,8 @@
|
|||
use std::{ffi::CString, os::raw::c_char};
|
||||
|
||||
fn main() {
|
||||
convert_fbx_to_3dtiles("/root/data/绿科-三维视图-{三维}111.fbx", "/root/data/out");
|
||||
convert_fbx_to_3dtiles("/root/data/绿科-三维视图-{三维}111.fbx",
|
||||
"/root/data/out/lk");
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -18,7 +19,7 @@ unsafe extern "C" {
|
|||
|
||||
fn convert_fbx_to_3dtiles(fbx_path: &str, out_dir: &str) {
|
||||
|
||||
|
||||
|
||||
let ctx = &FttContext{
|
||||
fbx_file: CString::new(fbx_path).unwrap().into_raw(),
|
||||
out_dir: CString::new(out_dir).unwrap().into_raw()
|
||||
|
|
Loading…
Reference in New Issue