HOOPS Exchange是什么?
是一組軟件庫,可以幫助開發人員在開發應用程序時讀取和寫入主流的 2D 和 3D 格式。HOOPS Exchange 支持在主流的3D 文件格式中讀取 CAD 數據,并支持將 3D 數據轉換為 PRC 數據格式,這是一種高度可壓縮和開放的文件格式,并已通過國際標準化組織 (ISO 14739-1:2014) 的認證。PRC 也是 Adobe PDF 中用于 3D 的格式之一。HOOPS Exchange 持續優化讀取各種 3D 數據的功能,尤其是對于來自計算機輔助設計 (CAD) 系統的數據。
打印裝配結構
學習創建一個使用 HOOPS Exchange 打印輸入文件的匯編結構的基本應用程序。
介紹
本教程將引導您使用 HOOPS Exchange 編寫控制臺應用程序的基礎知識。完成本教程后,您應該對該技術有足夠的了解,可以開始將 HOOPS Exchange 集成到您的應用程序中。
本教程的先決條件是對 C/C++ 應用程序開發有基本的了解。您應該從配置為構建和運行基本“hello world”示例應用程序的 IDE 開始本教程。無需高級 CAD 專業知識或 GUI 開發技能。
完成的項目將加載指定的輸入文件并將程序集結構打印到stdout.
使用 HOOPS Exchange 構建
在本節中,您將學習如何將 HOOPS Exchange 添加到構建系統中。
要使用 HOOPS Exchange 構建,我們必須將包含文件夾添加到搜索路徑。在 macOS 和 Linux 上,我們還必須添加動態鏈接器庫“dl”。
添加包含文件夾
Windows 用戶應在 Visual Studio 中編輯項目屬性,并在 C/C++ 窗格中添加包含文件夾。
如果您正在使用cmake,請編輯CMakeLists.txt以下行并將其添加到文件中:
包含目錄(/opt/ts3d/HOOPS_Exchange_Publish_2021_SP2_U2/include)
注意:參數應指定您安裝 HOOPS Exchange 的位置。
添加動態鏈接器(僅限 macOS 和 Linux)
如果您正在使用 cmake 編輯 CMakeLists.txt 并將以下行添加到文件中:
target_link_libraries(he_basic_app -ldl)
這是一個完整的文件,可以作為您的簡單起點 CMakeLists.txt.
cmake_minimum_required(版本 3.0.0)
項目(he_basic_app)
add_executable(he_basic_app main.cpp)
target_link_libraries(he_basic_app ${CMAKE_DL_LIBS})
如果(WIN32)
target_include_directories(he_basic_app "X:/HOOPS_Exchange_Publish_2021_SP2_U2/include")
別的()
target_include_directories(he_basic_app "/opt/local/ts3d/HOOPS_Exchange_2021_SP2_U2/include")
萬一()
構建并運行
作為健全性檢查,請記住構建并運行!
包括 HOOPS Exchange
在本節中,您將學習如何在源代碼中正確包含 HOOPS Exchange。
要使用 HOOPS Exchange API,您必須包含其標頭。這個包羅萬象的標題使您可以訪問整個工具包。在 IDE 的編輯器中打開main.cpp 。將以下行添加到文件頂部的第 1 行。
#include <A3DSDKIncludes.h>
添加此行后,如果您在上一節中正確指定了包含路徑,您應該能夠構建和運行。
要正確初始化 HOOPS Exchange,應用程序中的一個編譯單元必須在包含上述標頭之前聲明一個預處理器宏。通過添加此預處理器定義,您將啟用創建 API 本身的全局實例的代碼。在包含 Exchange 標頭之前添加以下行。
#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>
請記住,這個預處理器定義應該只存在于您的一個編譯單元中。如果多個編譯單元包含該定義,您將在鏈接時遇到重復的符號。由于我們的項目只包含一個編譯單元(main.cpp),這不會有問題,但是在將 HOOPS Exchange 集成到您自己的應用程序中時,您應該注意這一點。
現在可能是像以前一樣構建和運行項目的好時機。
初始化 HOOPS Exchange
在本節中,您將學習如何初始化 HOOPS Exchange 庫。我們還將介紹用于在使用后將其拆除的功能。
加載庫
第一步是將動態庫加載到內存中,并將所有 API 函數指針初始化為對應的實現。聽起來很復雜,對吧?幸運的是,這是通過簡單地調用一個函數來完成的。在 main.js 中添加以下代碼行。
A3DBool const is_loaded = A3DSDKLoadLibraryA( "X:/HOOPS_Exchange_Publish_2021_SP2_U2/bin/win64_v140" );
如果(!is_loaded){
std::cerr << "無法加載 HOOPS Exchange。" << std::endl;
返回-1;
}其他{
std::cout << "已加載。" << std::endl;
}
確保您指定為參數的路徑與您的安裝和平臺的細節相匹配。我們將信守承諾,在完成后卸載庫。輕松完成 - 只需在返回0之前添加此行。
A3DSDKUnloadLibrary();
返回0;
構建并運行。
提供許可證
要解鎖 HOOPS Exchange 工具包,您必須使用許可證字符串。您的許可證字符串應保密。您將使用的許可證字符串位于 HOOPS Exchange 包含文件夾中名為hoops_license.h的文件中。驗證它是否存在。
通過在文件頂部添加以下行來包含許可證文件頭。
#include <hoops_license.h>
使用 API 解鎖 HOOPS Exchange,方法是在您剛剛添加的庫加載功能之后添加以下代碼行。
A3DStatus常量license_status = A3DLicPutUnifiedLicense( HOOPS_LICENSE );
如果(A3D_SUCCESS!= license_status){
std::cerr << "無法授權 HOOPS Exchange" << std::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg( license_status ) <<
標準::endl;
返回-1;
}其他{
std::cout << "已授權。" << std::endl;
}
如果您在卸載庫后意外添加了此代碼,您將遇到問題。HOOPS_LICENSE是包含在hoops_license.h中的預處理器定義。它是一個包含您的許可證密鑰的長字符串。
您現在可以通過按原樣運行代碼來驗證您的許可證是否存在并且處于良好的工作狀態。如果一切正常,您應該會看到“許可”消息。在標準輸出上。
初始化 HOOPS Exchange
最后一步允許 HOOPS Exchange 執行其內部狀態的初始化。此外,此函數會檢查以確保您包含的 Exchange 標頭中聲明的版本號與嵌入到動態庫中的版本號匹配。這是要添加的代碼行。
A3DStatus const init_status = A3DDllInitialize(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION);
如果(A3D_SUCCESS!= init_status){
std::cerr << "無法初始化 HOOPS Exchange。" << std::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg( init_status ) <<
標準::endl;
返回-1;
}其他{
std::cout << "準備使用。" << std::endl;
}
// 這里使用交換
A3DDllTerminate();
A3DSDKUnloadLibrary();
返回0;
這就是它的全部。如果您覺得這太費力并且適合您的使用,您可以改用 class A3DSDKHOOPSExchangeLoader。它在內部實現了所有這些功能。唯一需要注意的是,您聲明的對象的生命周期必須匹配或超過您對任何 Exchange API 的使用。如果你走這條路,我們的整個程序就變成了下面這樣。
int main(int,char **){
A3DSDKHOOPSExchangeLoader
裝載機(L “X:/HOOPS_Exchange_Publish_2021_SP2_U2/bin/win64_v140”);
如果(!loader.m_bSDKLoaded){
std::cerr << "無法加載 HOOPS Exchange。" << std::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg(loader.m_eSDKStatus) <<
標準::endl;
返回-1;
}
std::cout << "準備使用。" << std::endl;
返回0;
}
這更容易。請記住要小心管理加載器對象的生命周期。對于本教程,我們可以堅持使用更簡單的實現。在 macOS 和 Linux 上,去掉參數前面的“L”。
現在您了解了 HOOPS Exchange 是如何初始化的。如果出現問題,您可以很好地找出原因。
加載文件
在本節中,您將學習使用 HOOPS Exchange 加載文件的最基本方法。為了實現這個目標,您將首先聲明和初始化加載選項。加載選項由加載 API 使用,該 API 返回加載文件的句柄。
配置加載選項
我們將用于加載輸入文件的 API 接受一個控制其行為的選項結構。由于目標是簡單地加載文件并打印程序集結構,因此默認選項就可以了。
聲明選項結構并使用以下代碼對其進行初始化。稍后我們將更詳細地描述此代碼。
A3DRWParamsLoadData load_params;
A3D_INITIALIZE_DATA(A3DRWParamsLoadData, load_params);
接下來,我們需要一個變量來保存生成的模型文件句柄。
A3DAsmModelFile *model_file = nullptr ;
這聲明了一個不透明的句柄,用于引用與您剛剛加載的文件關聯的數據。您將很快了解如何訪問數據。
最后,我們可以調用加載文件的 Exchange 函數。請注意此處輸入文件的硬編碼文件路徑。您至少應該將其更改為您的安裝路徑,但您可以將其指向您想要的任何文件,前提是HOOPS Exchange支持該格式。
auto const input_file = "X:/HOOPS_Exchange_2021_SP2_U2/samples/data/prc/__drill.prc" ;
A3DStatus load_status = A3DAsmModelFileLoadFromFile( input_file, &load_params, &model_file );
如果(A3D_SUCCESS!= load_status){
std::cerr << "無法加載指定文件:" << input_file <<
標準::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg( load_status ) <<
標準::endl;
返回-1;
}其他{
std::cout << "加載的文件:" << input_file << std::endl;
}
讓我們成為好公民,并為自己打掃衛生。假設模型文件有一些用途,當我們完成后,應該在程序退出之前清理它。
A3DAsmModelFileDelete(model_file);
model_file = nullptr ;
返回0;
當您構建并運行此時擁有的代碼時,您將擁有代碼并了解如何使用 HOOPS Exchange 工具包加載任何受支持的文件格式。您應該會看到一條寫入標準輸出的消息,聲明已加載失敗。
獲取 HOOPS Exchange 實體的名稱
在本節中,您將學習如何從 HOOPS Exchange API 中提取數據,以便在您的應用程序中使用它。您還將了解從 Exchange 檢索所有數據的基本使用模式。
讓我們將模型文件對象的名稱打印到stdout. 在 main 之上創建一個函數,如下所示:
#include <字符串>
std::string getName(A3DEntity *ntt) {
返回std::string();
}
A3DEntity是一種通用句柄類型,可用于引用 Exchange 中的任何對象。我們將使用這樣一個事實,即 Exchange 中的每個對象都有一組可通過 A3DRootBase 接口獲得的通用基礎數據。
聲明并初始化存儲
HOOPS Exchange 使用 C 風格的結構來讀?。ê蛯?入)其內部數據表示。在我們讀取數據之前,我們必須聲明一個適當類型的結構來保存結果。該結構必須在使用之前使用宏進行初始化。在其他可能的事情中,初始化宏設置m_usStructSize字段,作為內部檢查。在剛剛存根的函數中,添加以下代碼行。
標準::字符串名稱;
A3DRootBaseData rbd;
A3D_INITIALIZE_DATA(A3DRootBaseData, rbd);
讀取數據
使用 HOOPS Exchange API 時,遵循的模式很普遍。每當您讀取數據時,您必須確保進行相應的調用以釋放它。這種模式看起來像這樣。
if ( A3D_SUCCESS == A3DRootBaseGet( ntt, &rbd ) ) {
名稱 = rbd.m_pcName ?rbd.m_pcName : "" ;
A3DRootBaseGet( nullptr , &rbd);
您可以通過此處找到的包裝器對象避免初始化和使用模式。出于本教程的目的,我們將堅持使用更純粹的方法。
完成后,您的函數應如下所示:
#include <字符串>
std::string getName(A3DEntity *ntt) {
標準::字符串名稱;
A3DRootBaseData rbd;
A3D_INITIALIZE_DATA(A3DRootBaseData, rbd);
if ( A3D_SUCCESS == A3DRootBaseGet( ntt, &rbd ) ) {
名稱 = rbd.m_pcName ?rbd.m_pcName : "" ;
}
A3DRootBaseGet( nullptr , &rbd);
返回名稱;
}
打印名稱
回到main,在模型文件加載成功后添加以下代碼行。
std::cout << getName(model_file) << std::endl;
當我們迭代裝配結構時,我們在這里編寫的功能肯定會派上用場。
構建并運行
花點時間構建和運行您剛剛添加的代碼。除了指示文件已加載的消息外,您現在應該看到模型文件對象的名稱打印到標準輸出。
遍歷程序集
在本節中,您將了解負責在模型文件中表示裝配結構的 Exchange 對象。您還將學習遍歷結構的常用方法。
遞歸結構
在 HOOPS Exchange 中,用于表示裝配結構中節點的對象類型是A3DAsmProductOccurrence. 模型文件包含一個或多個(但通常只有一個)“根節點”的集合,它們是產品的出現。
每個產品出現對象本身可以包含一個或多個節點的集合,這些節點也是產品出現對象。因此,我們有一個遞歸結構,用于表示模型文件中的裝配層次結構。
除了可能擁有一個裝配節點集合之外,產品引用還可以包含一個零件。
讓我們利用所有先前奠定的基礎來編寫一個遍歷裝配結構并打印節點名稱的遞歸函數。在 main 上方、下方創建以下函數getName。
無效遍歷(A3DAsmProductOccurrence *po,int indent = 1){
if ( nullptr == po ) {
返回;
}
std::cout << std::string( 2*indent, ' ' ) << getName( po ) << std::endl;
A3DAsmProductOccurrenceData pd;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, pd);
if ( A3D_SUCCESS == A3DAsmProductOccurrenceGet( po, &pd ) ) {
對于(A3DUns32 idx = 0u;idx < pd.m_uiPOccurrencesSize;++idx){
遍歷(pd.m_ppPOOccurrences[idx],縮進 + 1);
}
}
A3DAsmProductOccurrenceGet( nullptr , &pd);
}
最后一步
現在有了這個函數,我們可以修改主函數體來使用它?;叵胍幌?,我們有一個模型文件對象,因此我們必須檢索其內容并遍歷根裝配節點的集合。對于每個根節點,我們將調用 traverse。
A3DAsmModelFileData mfd;
A3D_INITIALIZE_DATA(A3DAsmModelFileData, mfd);
如果(A3D_SUCCESS == A3DAsmModelFileGet(模型文件,&mfd)){
對于(A3DUns32 idx = 0u;idx < mfd.m_uiPOccurrencesSize;++idx){
遍歷(mfd.m_ppPOOccurrences[idx]);
}
}
A3DAsmModelFileGet( nullptr , &mfd);
構建并運行應用程序,看看我們已經完成了我們設定的目標。您的輸出應如下所示:
準備啟用。加載文件:X:/HOOPS_Exchange_2021_SP2_U2/samples/data/prc/__drill.prc __drill __drill ENGINE ENG_BLOCK_REAR ENG_BEARING ENG_BLOCK_FRONT ENG_BEARING CYLINDER BOLT_5-18<BOLT> BOLT_5-18<BOLT> BOLT_5-28<BOLT> BOLT_5-28<BOLT -28<螺栓>曲軸曲軸飛輪
結論
通過完成本教程,您已經學到了很多東西。您已經奠定了基礎技能,這些技能在您使用 HOOPS Exchange 的過程中會很有用。
您擁有的完整代碼應如下所示:
#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>
#include <iostream>
#include <字符串>
std::string getName(A3DEntity *ntt) {
標準::字符串名稱;
A3DRootBaseData rbd;
A3D_INITIALIZE_DATA(A3DRootBaseData, rbd);
if ( A3D_SUCCESS == A3DRootBaseGet( ntt, &rbd ) ) {
名稱 = rbd.m_pcName ?rbd.m_pcName : "" ;
}
A3DRootBaseGet( nullptr , &rbd);
返回名稱;
}
無效遍歷(A3DAsmProductOccurrence *po,int indent = 1){
if ( nullptr == po ) {
返回;
}
std::cout << std::string( 2*indent, ' ' ) << getName( po ) << std::endl;
A3DAsmProductOccurrenceData pd;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, pd);
if ( A3D_SUCCESS == A3DAsmProductOccurrenceGet( po, &pd ) ) {
對于(A3DUns32 idx = 0u;idx < pd.m_uiPOccurrencesSize;++idx){
遍歷(pd.m_ppPOOccurrences[idx],縮進 + 1);
}
}
A3DAsmProductOccurrenceGet( nullptr , &pd);
}
int main(int,char **){
A3DSDKHOOPSExchangeLoader loader( "X:/HOOPS_Exchange_Publish_2021_SP2_U2/bin/win64_v140" );
如果(!loader.m_bSDKLoaded){
std::cerr << "無法加載 HOOPS Exchange。" << std::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg(loader.m_eSDKStatus) << std::endl;
返回-1;
}
std::cout << "準備使用。" << std::endl;
A3DRWParamsLoadData load_params;
A3D_INITIALIZE_DATA(A3DRWParamsLoadData, load_params);
A3DAsmModelFile *model_file = nullptr ;
字符 常量*input_file =
"X:/HOOPS_Exchange_2021_SP2_U2/samples/data/prc/__drill.prc" ;
A3DStatus load_status = A3DAsmModelFileLoadFromFile( input_file, &load_params, &model_file );
如果(A3D_SUCCESS!= load_status){
std::cerr << "無法加載指定文件:" << input_file << std::endl;
std::cerr << "狀態:" << A3DMiscGetErrorMsg( load_status ) << std::endl;
返回-1;
}其他{
std::cout << "加載的文件:" << input_file << std::endl;
}
std::cout << getName(model_file) << std::endl;
A3DAsmModelFileData mfd;
A3D_INITIALIZE_DATA(A3DAsmModelFileData, mfd);
如果(A3D_SUCCESS == A3DAsmModelFileGet(模型文件,&mfd)){
對于(A3DUns32 idx = 0u;idx < mfd.m_uiPOccurrencesSize;++idx){
遍歷(mfd.m_ppPOOccurrences[idx]);
}
}
A3DAsmModelFileGet( nullptr , &mfd);
A3DAsmModelFileDelete(model_file);
model_file = nullptr ;
返回0;
}
了解HOOPS技術詳情歡迎進入
慧都科技是中國地區的指定經銷商,提供售賣、HOOPS 60天的免費試用、中文技術支持,同時提供工業3D解決方案,如果您對此感興趣,歡迎電話咨詢:023-68661681
↓ ↓ 關注“HOOPS技術”微信公眾號,了解HOOPS技術的真實應用 ↓ ↓
標簽:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn