This commit is contained in:
root 2025-09-05 17:06:06 +08:00
parent 95d5d00363
commit a202d3c9ea
7 changed files with 196 additions and 36 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
/target
*.o
*.exe

35
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,35 @@
{
"files.associations": {
"*.dbclient-js": "javascript",
"bit": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iterator": "cpp",
"limits": "cpp",
"map": "cpp",
"new": "cpp",
"stdexcept": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"vector": "cpp",
"xmemory": "cpp",
"xstddef": "cpp",
"xstring": "cpp",
"xtr1common": "cpp",
"xtree": "cpp",
"xutility": "cpp",
"iostream": "cpp",
"ostream": "cpp"
},
"C_Cpp.errorSquiggles": "disabled"
}

View File

@ -8,6 +8,7 @@ fn main() {
.warnings(false)
.include("./cpp_src/include")
.file("./cpp_src/fbx_parse.cpp")
.file("./cpp_src/fbx_wrap.cpp")
.compile("fbx_parse");
// -------------
println!("cargo:rustc-link-search=native=./cpp_src/lib");

View File

@ -1,62 +1,49 @@
#include <fbxsdk.h>
// external
#include <stdio.h>
// buz
#include <fbx_wrap.h>
using namespace std;
extern "C" {
// 定义给Rust调用的接口函数
void fbx_parse(const char* fbx_path) {
std::printf("%s\n", fbx_path);
void fbx_parse(const char* fbx_path)
{
printf("%s\n", fbx_path);
FbxManager* lSdkManager = FbxManager::Create();
if (lSdkManager){
std::printf("FbxManager created successfully.\n");
printf("FbxManager created\n");
} else{
std::printf("FbxManager creation failed.\n");
printf("FbxManager creation failed.\n");
}
FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");
if (lScene){
std::printf("FbxScene created successfully.\n");
printf("FbxScene created\n");
} else{
std::printf("FbxScene creation failed.\n");
printf("FbxScene creation failed.\n");
}
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings());
if (s){
std::printf("FbxImporter initialized successfully.\n");
printf("FbxImporter initialized\n");
} else{
std::printf("FbxImporter initialization failed.\n");
printf("FbxImporter initialization failed.\n");
}
lImporter->Import(lScene);
lImporter->Destroy();
FbxNode* lRootNode = lScene->GetRootNode();
if (lRootNode) {
std::printf("Root node found. Node name: %s\n", lRootNode->GetName());
int childCount = lRootNode->GetChildCount();
std::printf("Number of child nodes: %d\n", childCount);
for (int i = 0; i < childCount; ++i) {
FbxNode* childNode = lRootNode->GetChild(i);
std::printf("Child node %d name: %s\n", i, childNode->GetName());
}
each_node(lRootNode, 0);
} else {
std::printf("No root node found in the scene.\n");
}
if (lRootNode && lRootNode->GetNodeAttribute() &&
lRootNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh) {
FbxMesh* lMesh = static_cast<FbxMesh*>(lRootNode->GetNodeAttribute());
int materialCount = lMesh->GetElementMaterialCount();
std::printf("Number of materials in the mesh: %d\n", materialCount);
for (int i = 0; i < materialCount; ++i) {
FbxSurfaceMaterial* lMaterial = nullptr;
std::printf("Material name: %s\n", lMaterial->GetName());
// lMesh->GetElementMaterial(0)->eMaterial(i, lMaterial);
// if (lMaterial) {
// std::printf("Material %d name: %s\n", i, lMaterial->GetName());
// }
}
int controlPointCount = lMesh->GetControlPointsCount();
std::printf("Number of vertices in the mesh: %d\n", controlPointCount);
printf("No root node found in the scene.\n");
}
}
void load_fbx_mesh_to_db(const char* fbx_path)
{
FbxNode* root = get_fbx_root_node(fbx_path);
each_node(root, 0);
}
}

101
cpp_src/fbx_wrap.cpp Normal file
View File

@ -0,0 +1,101 @@
#include "fbx_wrap.h"
#include <stdio.h>
#include <iostream>
using namespace std;
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles) {
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);
}
return true;
}
FbxNode* get_fbx_root_node(const char* fbx_path)
{
printf("loading fbx file: %s\n", fbx_path);
FbxManager* lSdkManager = FbxManager::Create();
if (lSdkManager){
printf("FbxManager created successfully.\n");
} else{
printf("FbxManager creation failed.\n");
}
FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");
if (lScene){
printf("FbxScene created successfully.\n");
} else{
printf("FbxScene creation failed.\n");
}
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings());
if (s){
printf("FbxImporter initialized successfully.\n");
} else{
printf("FbxImporter initialization failed.\n");
}
lImporter->Import(lScene);
lImporter->Destroy();
return lScene->GetRootNode();
}
void each_node(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);
if (attr && attr->GetAttributeType() == FbxNodeAttribute::eMesh)
{
std::vector<Triangle> triangles;
int count = load_triangles(attr, triangles);
printf("triangles: %ld;", triangles.size());
std::cout << "("
<< get<0>(triangles[0]) << ", "
<< get<1>(triangles[0]) << ", "
<< get<2>(triangles[0]) << ")"
<< std::endl;
}
}
// children
if (parent_node->GetChildCount())
{
for (int i = 0; i < parent_node->GetChildCount(); i++)
{
FbxNode* child = parent_node->GetChild(i);
each_node(child, level + 1);
}
}
}
void print_node_info(FbxNode* node, int level)
{
// 打印一下节点信息
printf("|");
for (int i = 0; i < level; i++)
{
printf("-");
}
printf("> ");
printf("[%ld]: %s\n", node->GetUniqueID(), node->GetNameOnly().Buffer());
}

View File

@ -0,0 +1,31 @@
#include <fbxsdk.h>
#include <vector>
using namespace std;
using Triangle = std::tuple<int, int, int>;
struct Context {
};
/**
* FBX节点树结构
* @param parent_node nullptr则函数不执行任何操作
* @param level 0
* @note 访parent_node的所有直接子节点和间接子节点
* @warning parent_node无效
*/
void each_node(FbxNode* parent_node, int level);
/**
* FBX节点的基本信息
* @param node nullptr时输出警告日志
* @param level 4
* @details
* @example 2" |-- NodeName (Type: Mesh, Children: 3)"
*/
void print_node_info(FbxNode* node, int level);
FbxNode* get_fbx_root_node(const char* fbx_path);
int load_triangles(fbxsdk::FbxNodeAttribute* attr, std::vector<Triangle>& triangles);

View File

@ -5,12 +5,15 @@ fn main() {
unsafe extern "C" {
pub unsafe fn fbx_parse(name_in: *const u8);
pub unsafe fn load_fbx_mesh_to_db(path: *const u8);
}
fn convert_fbx_to_3dtiles(fbx_path: &str) {
unsafe {
fbx_parse(fbx_path.as_ptr() as *const u8);
// fbx_parse(fbx_path.as_ptr() as *const u8);
// 1. load to disk
load_fbx_mesh_to_db(fbx_path.as_ptr() as *const u8);
}
// unsafe {