-
-
Save chaosgoo/108e0bf265788a4551a9651ba194fef7 to your computer and use it in GitHub Desktop.
Flutter ffi调用lib3mf库解析3mf文件信息
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <algorithm> | |
| #include <iostream> | |
| #include <lib3mf_implicit.hpp> | |
| #include <string> | |
| using namespace Lib3MF; | |
| #ifdef __ANDROID__ | |
| #include <android/log.h> | |
| #define LOG_TAG "NativeLib3mf" | |
| #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) | |
| #else | |
| #include <cstdio> | |
| #define LOGI(...) \ | |
| printf(__VA_ARGS__); \ | |
| printf("\n") | |
| #endif | |
| #include "native_lib3mf.h" | |
| void printVersion(PWrapper wrapper) { | |
| Lib3MF_uint32 nMajor, nMinor, nMicro; | |
| wrapper->GetLibraryVersion(nMajor, nMinor, nMicro); | |
| // 获取预发布和构建信息 | |
| std::string sReleaseInfo, sBuildInfo; | |
| bool hasRelease = wrapper->GetPrereleaseInformation(sReleaseInfo); | |
| bool hasBuild = wrapper->GetBuildInformation(sBuildInfo); | |
| // 格式化输出 | |
| if (hasRelease && hasBuild) { | |
| LOGI("lib3mf version = %u.%u.%u-%s+%s", nMajor, nMinor, nMicro, | |
| sReleaseInfo.c_str(), sBuildInfo.c_str()); | |
| } else if (hasRelease) { | |
| LOGI("lib3mf version = %u.%u.%u-%s", nMajor, nMinor, nMicro, | |
| sReleaseInfo.c_str()); | |
| } else if (hasBuild) { | |
| LOGI("lib3mf version = %u.%u.%u+%s", nMajor, nMinor, nMicro, | |
| sBuildInfo.c_str()); | |
| } else { | |
| LOGI("lib3mf version = %u.%u.%u", nMajor, nMinor, nMicro); | |
| } | |
| } | |
| extern "C" { | |
| void ShowTransform(sLib3MFTransform transform, std::string indent) { | |
| LOGI("Transformation: [ %f %f %f %f ]", transform.m_Fields[0][0], | |
| transform.m_Fields[1][0], transform.m_Fields[2][0], | |
| transform.m_Fields[3][0]); | |
| LOGI(" [ %f %f %f %f ]", transform.m_Fields[0][1], | |
| transform.m_Fields[1][1], transform.m_Fields[2][1], | |
| transform.m_Fields[3][1]); | |
| LOGI(" [ %f %f %f %f ]", transform.m_Fields[0][2], | |
| transform.m_Fields[1][2], transform.m_Fields[2][2], | |
| transform.m_Fields[3][2]); | |
| } | |
| void ShowSliceStack(PSliceStack sliceStack, std::string indent) { | |
| LOGI("%sSliceStackID: %u", indent.c_str(), sliceStack->GetResourceID()); | |
| if (sliceStack->GetSliceCount() > 0) { | |
| LOGI("%s Slice count: %lu", indent.c_str(), sliceStack->GetSliceCount()); | |
| } | |
| if (sliceStack->GetSliceRefCount() > 0) { | |
| LOGI("%s Slice ref count: %lu", indent.c_str(), | |
| sliceStack->GetSliceRefCount()); | |
| for (Lib3MF_uint64 iSliceRef = 0; | |
| iSliceRef < sliceStack->GetSliceRefCount(); iSliceRef++) { | |
| LOGI("%s Slice ref : %u", indent.c_str(), | |
| sliceStack->GetSliceStackReference(iSliceRef)->GetResourceID()); | |
| } | |
| } | |
| } | |
| void ShowThumbnailInformation(PModel model) { | |
| /* | |
| // TODO: this is not yet implemented in Lib3MF | |
| */ | |
| } | |
| void ShowMetaDataInformation(PMetaDataGroup metaDataGroup) { | |
| Lib3MF_uint32 nMetaDataCount = metaDataGroup->GetMetaDataCount(); | |
| for (Lib3MF_uint32 iMeta = 0; iMeta < nMetaDataCount; iMeta++) { | |
| PMetaData metaData = metaDataGroup->GetMetaData(iMeta); | |
| std::string sMetaDataValue = metaData->GetValue(); | |
| std::string sMetaDataName = metaData->GetName(); | |
| LOGI(" Metadatum %u: Name = \"%s\", Value = \"%s\"", iMeta, | |
| sMetaDataName.c_str(), sMetaDataValue.c_str()); | |
| } | |
| } | |
| void ShowObjectProperties(PObject object) { | |
| LOGI(" Name: \"%s\"", object->GetName().c_str()); | |
| LOGI(" PartNumber: \"%s\"", object->GetPartNumber().c_str()); | |
| switch (object->GetType()) { | |
| case eObjectType::Model: | |
| LOGI(" Object type: model"); | |
| break; | |
| case eObjectType::Support: | |
| LOGI(" Object type: support"); | |
| break; | |
| case eObjectType::SolidSupport: | |
| LOGI(" Object type: solidsupport"); | |
| break; | |
| case eObjectType::Other: | |
| LOGI(" Object type: other"); | |
| break; | |
| default: | |
| LOGI(" Object type: invalid"); | |
| break; | |
| } | |
| if (object->HasSlices(false)) { | |
| PSliceStack sliceStack = object->GetSliceStack(); | |
| ShowSliceStack(sliceStack, " "); | |
| } | |
| if (object->GetMetaDataGroup()->GetMetaDataCount() > 0) { | |
| ShowMetaDataInformation(object->GetMetaDataGroup()); | |
| } | |
| } | |
| void ShowComponentsObjectInformation(PComponentsObject componentsObject) { | |
| LOGI("components object #%u: ", componentsObject->GetResourceID()); | |
| ShowObjectProperties(componentsObject); | |
| LOGI(" Component count: %u", componentsObject->GetComponentCount()); | |
| for (Lib3MF_uint32 nIndex = 0; nIndex < componentsObject->GetComponentCount(); | |
| nIndex++) { | |
| PComponent component = componentsObject->GetComponent(nIndex); | |
| LOGI(" Component %u: Object ID: %u", nIndex, | |
| component->GetObjectResourceID()); | |
| if (component->HasTransform()) { | |
| ShowTransform(component->GetTransform(), " "); | |
| } else { | |
| LOGI(" Transformation: none"); | |
| } | |
| } | |
| } | |
| void ShowMeshObjectInformation(PMeshObject meshObject) { | |
| LOGI("mesh object #%u: ", meshObject->GetResourceID()); | |
| ShowObjectProperties(meshObject); | |
| Lib3MF_uint64 nVertexCount = meshObject->GetVertexCount(); | |
| Lib3MF_uint64 nTriangleCount = meshObject->GetTriangleCount(); | |
| PBeamLattice beamLattice = meshObject->BeamLattice(); | |
| // Output data | |
| LOGI(" Vertex count: %lu", nVertexCount); | |
| LOGI(" Triangle count: %lu", nTriangleCount); | |
| Lib3MF_uint64 nBeamCount = beamLattice->GetBeamCount(); | |
| if (nBeamCount > 0) { | |
| LOGI(" Beam count: %lu", nBeamCount); | |
| Lib3MF_uint32 nRepresentationMesh; | |
| if (beamLattice->GetRepresentation(nRepresentationMesh)) | |
| LOGI(" |_Representation Mesh ID: %u", nRepresentationMesh); | |
| eLib3MFBeamLatticeClipMode eClipMode; | |
| Lib3MF_uint32 nClippingMesh; | |
| beamLattice->GetClipping(eClipMode, nClippingMesh); | |
| if (eClipMode != eBeamLatticeClipMode::NoClipMode) | |
| LOGI(" |_Clipping Mesh ID: %u (mode=%d)", nClippingMesh, | |
| (int)eClipMode); | |
| if (beamLattice->GetBeamSetCount() > 0) { | |
| LOGI(" |_BeamSet count: %u", beamLattice->GetBeamSetCount()); | |
| } | |
| } | |
| } | |
| FFI_PLUGIN_EXPORT int32_t extract_info(const char* path) { | |
| PWrapper wrapper = CWrapper::loadLibrary(); | |
| LOGI("------------------------------------------------------------------"); | |
| LOGI("3MF Read example"); | |
| printVersion(wrapper); | |
| LOGI("------------------------------------------------------------------"); | |
| PModel model = wrapper->CreateModel(); | |
| // Import Model from 3MF File | |
| { | |
| PReader reader = model->QueryReader("3mf"); | |
| // And deactivate the strict mode (default is "false", anyway. This just | |
| // demonstrates where/how to use it). | |
| reader->SetStrictModeActive(false); | |
| LOGI("ReadFromFile:"); | |
| LOGI("%s", path); | |
| reader->ReadFromFile(path); | |
| for (Lib3MF_uint32 iWarning = 0; iWarning < reader->GetWarningCount(); | |
| iWarning++) { | |
| Lib3MF_uint32 nErrorCode; | |
| std::string sWarningMessage = reader->GetWarning(iWarning, nErrorCode); | |
| LOGI("Encountered warning #%u : %s", nErrorCode, sWarningMessage.c_str()); | |
| } | |
| } | |
| ShowThumbnailInformation(model); | |
| ShowMetaDataInformation(model->GetMetaDataGroup()); | |
| PSliceStackIterator sliceStacks = model->GetSliceStacks(); | |
| while (sliceStacks->MoveNext()) { | |
| PSliceStack sliceStack = sliceStacks->GetCurrentSliceStack(); | |
| ShowSliceStack(sliceStack, ""); | |
| } | |
| PObjectIterator objectIterator = model->GetObjects(); | |
| while (objectIterator->MoveNext()) { | |
| PObject object = objectIterator->GetCurrentObject(); | |
| if (object->IsMeshObject()) { | |
| ShowMeshObjectInformation( | |
| model->GetMeshObjectByID(object->GetResourceID())); | |
| } else if (object->IsComponentsObject()) { | |
| ShowComponentsObjectInformation( | |
| model->GetComponentsObjectByID(object->GetResourceID())); | |
| } else { | |
| LOGI("unknown object #%u", object->GetResourceID()); | |
| } | |
| } | |
| PBuildItemIterator buildItemIterator = model->GetBuildItems(); | |
| while (buildItemIterator->MoveNext()) { | |
| PBuildItem buildItem = buildItemIterator->GetCurrent(); | |
| LOGI("Build item (Object #%u): ", buildItem->GetObjectResourceID()); | |
| if (buildItem->HasObjectTransform()) { | |
| ShowTransform(buildItem->GetObjectTransform(), " "); | |
| } else { | |
| LOGI(" Transformation: none"); | |
| } | |
| LOGI(" Part number: \"%s\"", buildItem->GetPartNumber().c_str()); | |
| if (buildItem->GetMetaDataGroup()->GetMetaDataCount() > 0) { | |
| ShowMetaDataInformation(buildItem->GetMetaDataGroup()); | |
| } | |
| } | |
| LOGI("done"); | |
| return 0; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment