CADシステムAPIが必要な理由
最初は、いつものように、少量の水。
CADシステムの拡張機能の開発は非常に一般的です。これは、どの設計にも、さまざまな高度に特殊化された機能を必要とする設計ドキュメントのさまざまな領域、セクション、および標準があるためです。 さらに、計算、視覚化、ワークフロー、その他多くのプログラムとの統合タスクがあります。 解決策は、システムの機能を拡張するプラグインを作成することです。
簡単な拡張の例
拡張機能を作成する基本的な手順を見ていきましょう。 VisualStudioと、C ++を知っていることの確実性が必要になります(Rengaには現在C ++ APIがありますが、将来はCOMに切り替えて、.Net拡張をサポートします)。
したがって、次の手順で:
- ここから SDK をダウンロードし、便利な場所に解凍します。
- デフォルト設定で単純なdllを作成し、MyPluginを呼び出します。
- 追加のインクルードフォルダーと追加のlibフォルダーで、RengaSDKへのパスを追加し、RengaApi.libとRengaBase.libをインクルードライブラリに追加します。
- 次に、最小限の実装を作成します。 本質的に、RengaのC ++拡張機能は、IPluginインターフェイスへのポインターを返すエクスポート関数を持つ通常のdllライブラリです。 したがって、必要なことは次のとおりです。
a)このインターフェースから継承したクラスを作成します。 インターフェースの開始メソッドと停止メソッドの両方をクラスに実装します;これらのメソッドは、それぞれロード後とアンロード前に呼び出されます。 現時点では実装を空のままにします。
b)IPluginインターフェイスへのポインターを返すエクスポート関数を実装します。 これを行うには、EXPORT_PLUGINマクロを使用できます。 - 次のテキストを含むMyPlugin.rnedescという名前の拡張機能記述ファイルを作成します。
<RengaPlugin> <Name>MyPlugin</Name> <Version>1.0</Version> <Vendor>Vendor name</Vendor> <Copyright>Copyright text</Copyright> <RequiredAPIVersion>1.2</RequiredAPIVersion> <PluginFilename>MyPlugin.dll</PluginFilename> </RengaPlugin>
- PluginsフォルダーのRengaインストールフォルダーのRengaに拡張機能を表示するには、dllと説明ファイルを入れるMyPluginフォルダーを作成します。
すべてが正しく行われた場合、Rengaが起動すると、「拡張機能」セクションの設定ダイアログに、何も機能しない拡張機能が表示されます。
彼に、建物に壁を作るのに必要なレンガの量を計算させましょう。 消費率を考慮してください-縫い目を考慮して、1立方メートルあたり400個。
1.最初に、メインアプリケーションパネルにボタンを作成します。 initializeメソッドで正しくやってみましょう
bool MyPlugin::initialize(const wchar_t * pluginPath) { auto countBricksAction = rengaapi::UIControls::createAction(); countBricksAction.setToolTip(rengabase::String(L" ")); auto primaryPanelExtension = rengaapi::UIControls::createToolPanelExtension(); primaryPanelExtension.addToolButton(countBricksAction); return true; }
2.次に、ボタンクリックハンドラーを実装し、rengaapi :: IInvokableインターフェイスの子孫であるCountBricksHandlerクラスを作成します。 MyPluginクラスで作成し、ボタンハンドラーとして設定します。
//CountBricksHandler.h #pragma once #include <RengaAPI/IInvokable.h> class CountBricksHandler : public rengaapi::IInvokable { public: void invoke(); }; //CountBricksHandler.cpp #include "stdafx.h" #include "CountBricksHandler.h" void CountBricksHandler::invoke() {}
3. MyPluginクラスのprivateセクションでm_countBricksHandlerフィールドを宣言し、countBricksActionのハンドラーとして設定します。
auto countBricksAction = rengaapi::UIControls::createAction(); countBricksAction.setToolTip(rengabase::String(L"Count bricks in walls")); countBricksAction.setTriggerHandler(&m_countBricksHandler);
4.ここで、壁のレンガの数の計算を実装します。 シンプルなクラスを作成しましょう-計算機。壁で使用される「レンガ」素材の量を計算し、転送された消費率に応じて量を計算します。 ボタンハンドラーのInvokeメソッドで計算を呼び出します。
//BricksCounter.h #pragma once namespace rengaapi { class Wall; } class BricksCounter { public: BricksCounter(int consumptionRatePerM3); int calculateBricks(); private: double calculateBricksVolume(); double calculateBricksVolumeInSingleWall(rengaapi::Wall* pWall); int calculateBricksCountInVolume(double bricksVolume); private: int m_consumptionRatePerM3; };
//BricksCounter.cpp #include "stdafx.h" #include "BricksCounter.h" #include <RengaAPI/Project.h> #include <RengaAPI/ModelObjectTypes.h> #include <RengaAPI/Wall.h> #include <RengaAPI/Materials.h> const wchar_t* c_briksMaterialName = L""; BricksCounter::BricksCounter(int consumptionRatePerM3) : m_consumptionRatePerM3(consumptionRatePerM3) { } int BricksCounter::calculateBricks() { double bricksVolume = calculateBricksVolume(); int bricksNumber = calculateBricksInVolume(bricksVolume); return bricksNumber; } double BricksCounter::calculateBricksVolume() { double result = 0.0; assert(rengaapi::Project::hasProject()); auto allObjects = rengaapi::Project::model().objects(); for (auto objectIt = allObjects.begin(); objectIt != allObjects.end(); ++objectIt) { if ((*objectIt)->type() == rengaapi::ModelObjectTypes::WallType) { rengaapi::Wall* pWall = dynamic_cast<rengaapi::Wall*>(*objectIt); assert(pWall != nullptr); result += calculateBricksVolumeInSingleWall(pWall); } } return result; } double BricksCounter::calculateBricksVolumeInSingleWall(rengaapi::Wall * pWall) { auto materialId = pWall->material(); rengaapi::LayeredMaterial wallMaterial; rengaapi::Materials::layeredMaterial(materialId, wallMaterial); auto materialLayers = wallMaterial.layers(); auto layerQuantityCollection = pWall->quantities().materialQuantities(); double bricksVolume = 0.0; for (size_t i = 0; i < materialLayers.size(); ++i) { if (materialLayers.get(i).material().name_() == rengabase::String(c_briksMaterialName)) { auto oVolumeMeasure = layerQuantityCollection.get(i).netVolume(); if (oVolumeMeasure.hasValue()) { bricksVolume += oVolumeMeasure.getValue()->inMeters3(); } } } return bricksVolume; } int BricksCounter::calculateBricksInVolume(double bricksVolume) { return static_cast<int>(bricksVolume * m_consumptionRatePerM3); }
// CountBricksHandler.cpp #include "stdafx.h" #include "CountBricksHandler.h" #include "BricksCounter.h" #include <RengaAPI/Project.h> #include <RengaAPI/Message.h> const int c_bricksConsumptionRatePerM3 = 400; void CountBricksHandler::invoke() { if (!rengaapi::Project::hasProject()) { rengaapi::Message::showMessageBox(rengaapi::Message::Info, rengabase::String(L" MyPlugin"), rengabase::String(L" . .")); } else { BricksCounter counter(c_bricksConsumptionRatePerM3); int bricksCount = counter.calculateBricks(); std::wstring message = std::wstring(L" , : ") + std::to_wstring(bricksCount); rengaapi::Message::showMessageBox(rengaapi::Message::Info, rengabase::String(L" MyPlugin"), rengabase::String(message.data())); } }
完全な拡張コードはこちら
Renga拡張機能の詳細
原則として、Renga APIの使用を開始するためのすべてはSDK(http://rengabim.com/sdk/)にあり、すべての主要機能の例もあります。
また、例として、モデルを階層構造(ツリー)の形式で表示するための拡張機能と、さまざまな基準に従ってモデルオブジェクトをフィルタリングするための拡張機能を開発しました。 これらの拡張機能は、組み立てられた形式とソースコードの形式の両方で利用でき、例として使用したり、好みに合わせて変更したりできます。 さらに、サードパーティの開発者は、3Dレンダリングおよび3D PDFへのエクスポート用の拡張機能を作成しました。 ここでこれらの拡張機能と新しい拡張機能を探してください。
APIが許可するもの
Renga APIにより、次のことが可能になりました。
- オブジェクトの3D表現をポリゴンメッシュ(メッシュ表現)の形式でエクスポートし、グループに分割して、たとえば壁のファサードを端から区別できるようにします。
- Rengaユーザーインターフェイスにコントロールを追加します(もちろん、それらに応答します)。
- モデルの3次元オブジェクトのパラメーターと計算された特性(ボリューム、面積、サイズなど)を取得します。
- カスタムプロパティを作成し、モデルオブジェクトに割り当て、値を変更します。
- 可視性を管理し、モデルオブジェクトを強調表示します。
今日は以上です。ご質問にお答えします。 Rengaで書いて、アイデアを生み出し、私たちと一緒に開発しましょう!
Eugene Tian、Renga Softwareのリードプログラマー。