広告
公式ドキュメントの和訳です。
原文:「C++ Specific Issues」
Fusion 360は、一つのAPIを持っています。それは、いくつかの異なるプログラミング言語から使用することができます。ほとんどの場合、APIは、ほんの少しの言語固有の構文の変更とプログラミング言語のそれぞれと非常によく似た方法で使用されます。しかしながら、場合によっては、特定の言語のために、APIが、どのように使われるかに、著しい違いがあります。このトピックでは、違いについて説明します。それは、C++に固有です。そして、以下の一覧にした話題を網羅しています。
OS固有の問題
OS Specific Issues
新しいPythonとJavaScriptスクリプトやアドインを作成するとき、「スクリプトとアドイン」コマンドを用いて、一つのcppが、作成されます。しかし、Visual Studio (.vcxproj)とXcode(.xcodeproj)プロジェクトの両方が、作成されます。それは、その一つのcppを使用します。ほとんどの場合、あなたが、OS固有の外部ライブラリを使う選択をしない限り、同じコードをWindowsとMac上で使用することができます。それは、通常、使用できますが、同じソース・コードが、MacとWindowsで使用することができます。Fusionによって使用されるバイナリはOS固有です。これは、あなたは、WindowsとOS XとそれをMacのためにコンパイルするXcodeのために、あなたのスクリプトやアドインをコンパイルするために、WindowsとVisual Studioを使用する必要があることを示しています。
以下の議論のほとんどは、あなたのスクリプトやアドインのコードについてです。そして、プラットホームを選びません。それで、それは、MacとWindowsに適用します。最後のトピックは、OS固有の、あなたのスクリプトやアドインをデバッグすることを説明します。
オブジェクト宣言
Object Declaration
Fusionで定義された型を使用する変数の宣言と関数の引数は、常に、高性能なポインターを作成するために、Fusionで定義されたPtrテンプレートを使用する必要があります。高性能なポインターは、参照の追加、そして、削除し、それが、もはや必要でない(すなわち、変数が、スコープから出るか、明示的にnullptrに設定されるとき)、そして、型変換するとき、参照を消去することを自動的に処理します。
Ptr<SketchLine> line1;
bool doAnimation(Ptr<SketchCurve> pathCurve, Ptr<Vector3D> upDirection)
{
}
エラーを扱う
Handling Errors
Fusion APIのC++実装では、すべてのエラーは、エラーコードを通して報告されます。発生をアサートしません。それで、try catchステートメントは、動作しません。ほとんどの場合、これは、2つの事のうちの1つを示します。まず、関数が、オブジェクトを返すことを期待される場合、それは、期待されるオブジェクトどちらかを返します。あるいは、いくつかの他の記録された結果(通常null)は、関数が、失敗していることを示します。これは、以下を説明します。
Ptr<SketchLine> ln = lines->addByTwoPoints(p1, p2);
if (!ln)
return false;
関数が機能しないならば、あなたは、ApplicationオブジェクトのgetLastErrorメソッドを使用して、失敗についての追加の情報を取得することができます。これは、以下で説明します。
Ptr<SketchLine> ln;
ln = lines->addByTwoPoints(p1, p2);
If (!ln)
{
// エラーメッセージを取得します
std::string errorMessage;
int errorCode = app->getLastError(&errorMessage);
if (GenericErrors::Ok != errorCode)
ui->messageBox(errorMessage);
return false;
}
2つ目のエラー報告メソッドは、以下に示すように、成功または失敗を示すbooleanを返す関数です。再び、あなたは、エラーの詳細を取得するために、getLastErrorメソッドを使用することができます。
bool isOK = sk->isComputeDeferred(false);
if (!isOK)
return false;
プロパティ
Properties
C++は、APIで定義される、そして、それらが、JavaScriptとPythonで使われるように、この方法で、プロパティをサポートしません。JavaScriptのサンプルは、以下でコンポーネントの既存の名前を取得するために、Componentオブジェクトのread-write nameプロパティを使用して、そして、続いて、それを設定することを説明します。
// JavaScript
if (comp.name == "Test")
comp.name = "New Test";
C++では、プロパティは、プロパティの読み込みバージョンが、どんな引数も持っていない、そして、プロパティの値を返す関数として実装される、2つのオーバーロード関数を使用して実装されます。プロパティの値を設定することは、一つの引数を取得する関数によって実行されます。それは、プロパティの新しい値です。そして、成功や失敗を示すboolを返します。これらは、両方とも、以下で説明されます。
// C++
if (comp->name() == "Test")
bool isOK = comp.name("New Test");
オブジェクトの型と型変換
Object Types and Casting
PythonとJavaScriptとは異なり、C++は、厳密に型指定された言語です。そして、変数は、特定の型と割当てが、型と一致する必要があるため、宣言する必要があります。先に述べたように、新しい変数を宣言するとき、あなたは、常に、特定の型の高性能なポインターを作成するPtrテンプレートを使用する必要があります。参照されているオブジェクトの型を確認するために、変数によって、あなたは、すべてのFusionオブジェクトでサポートされる、objectTypeプロパティを使用できます。この関数は、変数が宣言された型である必要はなく、オブジェクトの実際の型である文字列を返します。例えば、以下のコードは、スケッチの線であるか、確かめるために検査する、現在選択されているエンティティを取得します。(それは、何でもかまいません。それで、変数は、Baseとして宣言されます)
Ptr<Selection> selection = ui->activeSelections()->item(0);
Ptr<Base> selectedEnt = selection->entity();
if (selectedEnt->objectType() == adsk::fusion::SketchLine::classType())
ui->messageBox("Selected entity is a sketch line.");
else
ui->messageBox("Selected entity is NOT a sketch line.");
SketchLineオブジェクトは、SketchCurveクラスから派生しています。そして、それは、最後に、基底クラスから派生するSketchEntityクラスから派生します。あなたが、知りたい場合、選択されたエンティティは、あなたは、以下で使用することができる、SketchCurveから派生する型の1つです。
Ptr<Selection> selection = ui->activeSelections()->item(0);
Ptr<Base> selectedEnt = selection->entity();
if (Ptr<SketchCurve>(selectedEnt))
ui->messageBox("Selected entity is a sketch curve.");
else
ui->messageBox("Selected entity is NOT a sketch curve.");
上のコードは、型変換を自動的に処理するFusionの高性能なポインターのフィーチャの1つを利用します。SketchCurveへキャストされたselectEntへのPtrテンプレートで、実行される自動型変換を使用します。そして、それが成功した場合、結果として、ステートメントは、trueになります。以下は、実行中のプロダクトが、基底クラスのProductクラスとして取得される型変換が使われる、一般的な場合の他の例です。それは、続いて、Designとして宣言された変数に、割り当てられます。実行中のプロダクトが、デザインである場合、これは成功しています。そして、変数"des"は、実行中のデザインを参照します。実行中のプロダクトがCAMやDrawingプロダクトの場合、続いて、変数"des"は、型変換が機能しなかったため、nullです。
Ptr<Product> prod = app->activeProduct();
if (!prod)
return false;
Ptr<Design> des = prod;
if (!des)
// 製品は、アクティブでありません。
return false;
イベント
Events
C++で、実装するイベントは、それが、どのようにJavaScriptとPythonで実行するかによく似ています。概念は、すべての言語で同じですが、それぞれ独自の要件を持っています。以下は、C++で、イベントを実装する手順のリスト、そして、これらの手順を説明するいくつかのサンプルコードです。
- イベントをサポートするオブジェクトに、参照を取得します。(line 13)
- イベントオブジェクトを取得します(line 18)。
- イベントオブジェクトで、addメソッドを呼び出します。イベント・ハンドラ・クラスに渡します(line 19)。line 56上のイベント・ハンドラ・クラス定義の一部として、中で渡されている変数が、宣言されていることに注意します。
- 適切なFusionクラスから、派生するイベント・ハンドラ・クラスを作成します(line 21)。
- 適切なシグネチャで、notify関数を実装します(line 24)。
- notify関数に、また、他のイベントの接続を含めることができるイベントを処理するとき、実行されるコードを追加します。(lines 25-52)。
extern "C" XI_EXPORT bool run(const char* context)
{
_app = Application::get();
if (!_app)
return false;
_ui = _app->userInterface();
if (!_ui)
return false;
// ボタンのコマンドの定義を作成します。
Ptr<CommandDefinitions> cmdDefs = _ui->commandDefinitions();
sampleCmdDef = cmdDefs->addButtonDefinition("sampleCmdID", "Sample",
"Sample tooltip",
"./Resources/Sample");
// コマンドを作成したイベントに接続します。
Ptr<CommandCreatedEvent> commandCreatedEvent = sampleCmdDef->commandCreated();
commandCreatedEvent->add(&_cmdCreated);
}
// CommandCreatedイベント・ハンドラ。
class CommandCreatedEventHandler : public adsk::core::CommandCreatedEventHandler
{
public:
void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
{
if (eventArgs)
{
Ptr<Command> cmd = eventArgs->command();
if (cmd)
{
//入力を定義する.
Ptr<CommandInputs> inputs = cmd->commandInputs();
// スケッチ曲線や稜線を選択する必要があるために、入力を追加します
Ptr<SelectionCommandInput> curveInput;
curveInput = inputs->addSelectionInput("curveInput", "Curve",
"Select the sketch or edge curve.");
curveInput->addSelectionFilter("SketchCurves");
curveInput->addSelectionFilter("Edges");
// true/false入力を取得するために、入力を追加します。
Ptr<BoolValueCommandInput> trueFalseInput;
trueFalseInput = inputs->addBoolValueInput("trueFalseInput", "Yes or No",
true, "", true);
// コマンド実行イベントに接続します。
Ptr<CommandEvent> onExec = cmd->execute();
bool isOk = onExec->add(&onExecuteHandler_);
}
}
}
private:
OnExecuteEventHander onExecuteHandler_;
} _cmdCreated;
ヘッダファイル
Header Files
Fusion APIへのC++インターフェイスは、Fusionインストールの一部として、提供される多くの.hファイルで説明されます。クラスごとに、別々の.hファイルがあります。そして、それらは、「…/API/CPP/include」フォルダで、フォルダに系統化されます。"Core"と"Fusion"と呼ばれる、2つの最上位のフォルダがあります。"Core"フォルダには、機能が含まれています。それは、Fusion固有でありません。(UI、マテリアル、ジオメトリーなど)そして、Fusionには、Fusion固有機能(スケッチ、フィーチャ、コンポーネントなど)が含まれています。これらの各々の中に、特定の機能をグループ化したフォルダがあります。簡単なプログラムを記述するために、それは、線と押出しのプロファイルを作成します。あなたは、以下のヘッダファイルを含める必要があるクラスを使用するでしょう。
#include <Core/Application/Application.h>
#include <Fusion/Fusion/Design.h>
#include <Fusion/Components/Component.h>
#include <Fusion/Construction/ConstructionPlane.h>
#include <Fusion/Sketch/Sketches.h>
#include <Fusion/Sketch/Sketch.h>
#include <Fusion/Sketch/SketchCurves.h>
#include <Fusion/Sketch/SketchLines.h>
#include <Fusion/Sketch/SketchLine.h>
#include <Fusion/Sketch/Profiles.h>
#include <Fusion/Sketch/Profile.h>
#include <Fusion/Features/Features.h>
#include <Fusion/Features/ExtrudeFeatureInput.h>
#include <Fusion/Features/ExtrudeFeatures.h>
#include <Fusion/Features/ExtrudeFeature.h>
それは、特定のクラスのための.hファイルを探すためのフォルダが、常に、明らかなわけではありません。各々のクラス、メソッド、プロパティとイベントリストのためのヘルプ・トピックは、その機能を使うために、.hファイルを含める必要があります。それは、標準的なC++の習慣ではありませんが、あなたは、"CoreAll.h"と"FusionAll.h"ファイルを使用して、プログラムで使われる、すべてのクラスのための、#includeステートメントを追加する必要を避けることができます。これらの2つのファイルは、利用可能である、すべてのFusionに関連した.hファイルが含まれています。その結果、同じ実行時のコンパイラの最適化の結果のため、コンパイル時間が長くなります。
#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
また、APIの使い方を分かりやすくするため、あなたは、"using namespace"ステートメントを使って、coreとfusionの名前空間を参照することができます。それで、あなたは、変数を宣言するとき、完全な名前空間を指定する必要はありません。CoreやFusion内で、クラスを定義する場合、2つのステートメントを使用して、以下を、あなたが、調べる必要はありません。
using namespace adsk::core;
using namespace adsk::fusion;
あなたが、使うことができる型"Application"の変数を宣言するとき、:
Ptr<Application> app = Application::get();
以下の代わりに:
Ptr app = Application::get();
もちろん!CoreAll.hとFusionAll.hを使用する場合と、名前空間ステートメントを使用する場合の両方で、これらのショートカットを使用するか、より多くの標準的なC++の習慣を使うための選択肢は、あなたのものです。
繰返し
Iteration
あなたは、Fusionコレクションの内容を繰り返すために、標準的なC++反復メソッドを使用することができます。例えば、次のコードは、ボディ内のすべての面を反復処理します。
for (Ptr<BRepFace> newFace : selectedBody->faces())
{
//面で何かします。
}
オブジェクトの同一性
Object Equality
それは、多くの場合、確かめるために2つの変数を比較するために役に立ちます。それらが、同じFusionオブジェクトを参照する場合、Fusionで、エンティティを参照するAPIオブジェクトを返す、すべてのC ++ API関数は、同じポインタを持つC ++ラッパーを作成します。これは、あなたが、確かめるために、直接、2つの変数のポインターを比較することを示しています。それらが、同じオブジェクトを参照する場合、例えば、以下は、同じ面を参照する場合、確かめるために、2つの変数を比較します。
If (face1 == face2)
ui.messageBox(“Faces are the same.”);
ユーティリティ関数
Utility Functions
また、C++インターフェイスは、いくつかの特別な場合に役立つ、Core/Utils.hで定義される、いくつかのユーティリティ関数をサポートしています。
- adsk::doEvents()
これは、あなたのスクリプトやアドインの実行を一時停止します。そして、Fusionは、現在のキュー内のすべてのメッセージを処理できます。あなたは、Fusionが、視覚的に維持しないプログラムを使用して、Fusionを駆動している場合が、あります。doEventsを呼び出すと、Fusionは、表示に、追いついて更新することができます。
- adsk::autoTerminate()
C++スクリプトが、実行されるとき、それは、自動的に終了します。ほとんどの場合、スクリプトは、通常、それらの関数を実行し、そして、完了しすることで、実行されるため、これは、望ましい動作です。あなたが、継続するために、実行するために、そして、自動的に終了しない、プログラムを望む場合、スクリプトを使うよりはむしろ、アドインを作成することをお勧めします。しかしながら、autoTerminateプロパティを使用して、自動的には行なわない、実行し続けるスクリプトを持つことは可能です。このプロパティを使用して、あなたは、現在の自動終了状態を確認することができ、それを設定することができます。
- adsk::terminate()
terminate関数は、スクリプトや「アドインを強制終了させます。これは、あなたが、スクリプトで、autoTerminateを使用している場合に特に便利です。そのため、それは、自動的に終了しませんでした。terminate関数を使用して、スクリプトが、終了するとき、あなたは、決定することができます。
Windowsのスクリプトやアドインをデバッグする
Debugging a Windows Script or Add-In
Windows上のVisual Studioを使用して、あなたは、C++スクリプトやアドインをデバッグすることができます。以下は、デバッグのための手順を説明します。
- まず、あなたは、うまく、スクリプトやアドインをコンパイルできる必要があります。
- 必要なブレークポイントを追加してください。デバッグ中に、更にブレークポイントを追加することができますが、あなたは、少なくとも、あなたが調べたいコードの部分で、実行を停止する、ブレークポイントを追加することを望むでしょう。それ以外の場合には、それは、あなたにそれを調べる機会を与えることなく、ただコードによって実行します。
- Debugメニューでは、以下で示すように、"Attach to Process…"コマンドを実行します。
Attach to Processダイアログでは、"Attach to"オプションが"Native code"に設定されていることを確認します。そして、以下に示すように、リストから「Fusion360.exe」を選択します。そして、"Attach"をクリックします。
ここで重要な点は、あなたのスクリプトやアドインは、Fusionに添付されます。しかし、それは、実行していません。あなたは、Visual Studioで、この表示を見るでしょう。なぜなら、以下に示すように、すべてのブレークポイントは、無効になっています。
- Fusionで、あなたのスクリプトやアドインを実行するには、あなたは、以下に示される、"Scripts and Add-Ins"コマンドを使用する必要があります。あなたのスクリプトやアドインを選択し、"Run"ボタンをクリックします。最初にアドインを作成しデバッグしている間、あなたは、"Run on Startup"機能を有効にするべきでありません。しかし、デバッグ工程の一部として、アドインを手動でのみ実行します。
- スクリプトとアドインの両方のrun関数は、次に、呼び出し、そして、そこから、呼び出した、その関数のブレークポイントや関数をヒットします。ブレークポイントが、あなたのコードの他の領域にある場合、続いて、あなたは、実行するコードのそれらの部分の原因となる方法で、アドインを実行する必要があります。例えば、あなたのアドインが、コマンドを作成する場合、そして、あなたのブレークポイントは、コード内の固有のコマンドです。あなたは、ユーザー・インターフェイスのコマンド・ボタンをクリックすることで、コマンドを実行する必要があります。いずれにせよ、一旦、あなたは、ブレークポイントを打ちました。あなたは、次に、コードをステップ実行し、標準的なデバッグ操作を実行することができます。
- デバッグを停止するために、あなたは、スクリプトとアドイン・コマンドを使用して、スクリプトやアドインの実行を停止する必要があります。
そして、あなたは、同様に、Visual Studioから、デバッグを停止する必要があります。それを、あなたは、"Stop Debugging"コマンドを使用してすることができます。これにより、デバッグが中止され、usionから切り離されます。あなたは、現在、コードを編集できるようになりました。再コンパイルしてステップ3に戻り、デバッグ工程を、再度、開始します。
あなたのスクリプトやアドインをコンパイルするとき、次のようなエラーが、表示された場合、それは、一般的に、スクリプトやアドインが、まだ、Fusionで実行されているために、あなたが、上記のように、それを停止する必要があることを示しています。
Macのスクリプトやアドインをデバッグする
Debugging a Mac Script or Add-In
Mac上のXcodeを使用して、あなたは、あなたのC++スクリプトやアドインをデバッグすることができます。以下は、デバッグのための手順を説明します。
- まず、あなたは、うまく、スクリプトやアドインをビルドできる必要があります。
- 必要なブレークポイントを追加してください。デバッグ中に、更にブレークポイントを追加することができますが、あなたは、少なくとも、あなたが調べたいコードの部分で、実行を停止する、ブレークポイントを追加することを望むでしょう。それ以外の場合には、それは、あなたに、それを調べる機会を与えることなく、ただコードを実行するだけです。
- Debugメニューでは、"Attach to Process"を選択し、そして、以下に示すように、リストから、"Autodesk Fusion 360"を選択します。
ここで重要な点は、あなたのスクリプトやアドインは、Fusionに添付されますが、実行していません。
- Fusionで、あなたのスクリプトやアドインを実行するには、以下に示すように、あなたは、"Scripts and Add-Ins"コマンドを使用する必要があります。あなたのスクリプトやアドインを選択し、"Run"ボタンをクリックします。最初にアドインを作成しデバッグしている間、あなたは、"Run on Startup"機能を有効にするべきでありませんが、デバッグ工程の一部として、あなたのアドインを、手動でだけ、実行します。
- 両方のスクリプトとアドインのrun関数は、現在、呼び出されます。そして、その関数内の任意のブレークポイント、あるいは、そこから呼び出される関数は、打たれます。ブレークポイントが、あなたのコードの他の領域にある場合、続いて、あなたは、実行するコードのそれらの部分の原因となる方法で、アドインを実行する必要があります。例えば、あなたのアドインが、コマンドを作成する場合、そして、ユーザー・インターフェイスでは、あなたのブレークポイントは、コマンドボタンをクリックすることで、コマンドを実行する必要がある、コード内の固有のコマンドです。
- いずれにせよ、一旦、あなたが、ブレークポイントを打つと、あなたは、次に、コードをステップ実行し、標準的なデバッグ操作を実行することができます。
デバッグを停止するために、「スクリプトとアドイン」コマンドを使用して、あなたは、スクリプトやアドインの実行を停止する必要があります。
そして、あなたは、同様に、それを行うことができる"Detach"コマンドを用いて、Xcodeから、デバッグを停止する必要があります。Debugメニューでは、これにより、デバッグが中止され、Fusionから切り離されます。あなたは、現在、コードを編集できるようになりました。再コンパイルしてステップ3に戻り、デバッグ工程を、再度、開始します。
広告