load fbx
This commit is contained in:
parent
95d5d00363
commit
a202d3c9ea
|
@ -1 +1,3 @@
|
||||||
/target
|
/target
|
||||||
|
*.o
|
||||||
|
*.exe
|
|
@ -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"
|
||||||
|
}
|
1
build.rs
1
build.rs
|
@ -8,6 +8,7 @@ fn main() {
|
||||||
.warnings(false)
|
.warnings(false)
|
||||||
.include("./cpp_src/include")
|
.include("./cpp_src/include")
|
||||||
.file("./cpp_src/fbx_parse.cpp")
|
.file("./cpp_src/fbx_parse.cpp")
|
||||||
|
.file("./cpp_src/fbx_wrap.cpp")
|
||||||
.compile("fbx_parse");
|
.compile("fbx_parse");
|
||||||
// -------------
|
// -------------
|
||||||
println!("cargo:rustc-link-search=native=./cpp_src/lib");
|
println!("cargo:rustc-link-search=native=./cpp_src/lib");
|
||||||
|
|
|
@ -1,62 +1,49 @@
|
||||||
#include <fbxsdk.h>
|
// external
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
// buz
|
||||||
|
#include <fbx_wrap.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// 定义给Rust调用的接口函数
|
// 定义给Rust调用的接口函数
|
||||||
void fbx_parse(const char* fbx_path) {
|
void fbx_parse(const char* fbx_path)
|
||||||
std::printf("%s\n", fbx_path);
|
{
|
||||||
|
printf("%s\n", fbx_path);
|
||||||
FbxManager* lSdkManager = FbxManager::Create();
|
FbxManager* lSdkManager = FbxManager::Create();
|
||||||
if (lSdkManager){
|
if (lSdkManager){
|
||||||
std::printf("FbxManager created successfully.\n");
|
printf("FbxManager created\n");
|
||||||
} else{
|
} else{
|
||||||
std::printf("FbxManager creation failed.\n");
|
printf("FbxManager creation failed.\n");
|
||||||
}
|
}
|
||||||
FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");
|
FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");
|
||||||
if (lScene){
|
if (lScene){
|
||||||
std::printf("FbxScene created successfully.\n");
|
printf("FbxScene created\n");
|
||||||
} else{
|
} else{
|
||||||
std::printf("FbxScene creation failed.\n");
|
printf("FbxScene creation failed.\n");
|
||||||
}
|
}
|
||||||
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
|
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
|
||||||
bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings());
|
bool s = lImporter->Initialize(fbx_path, -1, lSdkManager->GetIOSettings());
|
||||||
if (s){
|
if (s){
|
||||||
std::printf("FbxImporter initialized successfully.\n");
|
printf("FbxImporter initialized\n");
|
||||||
} else{
|
} else{
|
||||||
std::printf("FbxImporter initialization failed.\n");
|
printf("FbxImporter initialization failed.\n");
|
||||||
}
|
}
|
||||||
lImporter->Import(lScene);
|
lImporter->Import(lScene);
|
||||||
lImporter->Destroy();
|
lImporter->Destroy();
|
||||||
|
|
||||||
FbxNode* lRootNode = lScene->GetRootNode();
|
FbxNode* lRootNode = lScene->GetRootNode();
|
||||||
if (lRootNode) {
|
if (lRootNode) {
|
||||||
std::printf("Root node found. Node name: %s\n", lRootNode->GetName());
|
each_node(lRootNode, 0);
|
||||||
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());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
std::printf("No root node found in the scene.\n");
|
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);
|
||||||
|
|
||||||
if (lRootNode && lRootNode->GetNodeAttribute() &&
|
each_node(root, 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
|
@ -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);
|
|
@ -5,12 +5,15 @@ fn main() {
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub unsafe fn fbx_parse(name_in: *const u8);
|
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) {
|
fn convert_fbx_to_3dtiles(fbx_path: &str) {
|
||||||
|
|
||||||
unsafe {
|
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 {
|
// unsafe {
|
||||||
|
|
Loading…
Reference in New Issue