arrow-left

All pages
gitbookPowered by GitBook
1 of 3

Loading...

Loading...

Loading...

オブジェクト バインド

Dynamo for Civil 3D には、各ノードで作成されたオブジェクトを「記憶する」ための非常に強力なメカニズムが含まれています。このメカニズムはオブジェクト バインドと呼ばれ、これにより、Dynamo グラフは同じドキュメントで実行されるたびに一貫した結果を生成することができます。これは多くの状況で非常に望ましいことですが、Dynamo の動作をより詳細にコントロールしなければならない場合もあります。このセクションでは、オブジェクト バインドの仕組みと、その利点について説明します。

hashtag
例

現在のレイヤでモデル空間に円を作成するこのグラフについて考えてみましょう。

円を作成するための単純なグラフ

半径が変更されるとどうなるかに注目してください。

これが実際のオブジェクト バインドです。Dynamo の既定の動作では、半径の入力が変更されるたびに新しい円が作成されるのではなく、円の半径が 修正 されます。これは、グラフを実行するたびに、Object.ByGeometry ノードが 特定の 円を作成したことを「記憶」するためです。さらに、Dynamo はこの情報を保存するので、次に Civil 3D ドキュメントを開いてグラフを実行すると、まったく同じ動作が実行されます。

hashtag
別の例

次に、Dynamo の既定のオブジェクト バインド動作を変更する例を見てみましょう。たとえば、円の中央にテキストを配置するグラフを作成するとします。ただし、このグラフの目的は、繰り返し実行でき、選択した円に毎回新しいテキストを配置できるようにすることです。グラフは次のようになります。

ただし、別の円を選択すると、実際にはこのようになります。

グラフを実行するたびにテキストが削除され、再作成されているように見えます。実際には、選択した円に応じてテキストの位置が 修正 されています。つまり、同じテキストが、別の場所に配置されているだけです。毎回新しいテキストを作成するには、バインド データが保持されないように、Dynamo のオブジェクト バインド設定を修正する必要があります(以下の「」を参照してください)。

この変更を行うと、求めている動作が得られます。

hashtag
バインド設定

Dynamo for Civil 3D では、Dynamo メニューの [バインド データ ストレージ] 設定を使用して、既定のオブジェクト バインドの動作を変更することができます。

circle-info

[バインド データ ストレージ]オプションは、Civil 3D 2022.1 以降で使用できることに注意してください。

すべてのオプションは既定で有効になっています。各オプションの機能の概要を次に示します。

hashtag
オプション1: バインド データを保持しない

このオプションを有効にすると、Dynamo は最後にグラフを実行したときに作成したオブジェクトを「忘れる」ようになります。したがって、グラフは、どのような状況でも任意の図面で実行でき、毎回新しいオブジェクトを作成します。

circle-info

使用する状況

このオプションは、前回の実行で行った操作をすべて Dynamo が「忘れて」、毎回新しいオブジェクトを作成する場合に使用します。

hashtag
オプション2: Dynamo のグラフに保存する

このオプションを選択すると、オブジェクト バインド メタデータが保存時にグラフ(.dyn ファイル)にシリアル化されます。グラフを閉じて再度開き、同じ図面で実行すると、すべてが、グラフを閉じる前と同じように動作するはずです。別の図面でグラフを実行すると、グラフからバインド データが削除され、新しいオブジェクトが作成されます。これは、元の図面を開いてグラフを再度実行すると、古いオブジェクトに加えて新しいオブジェクトが作成されることを意味します。

circle-info

使用する状況

このオプションは、特定の図面 で最後に作成したオブジェクトを Dynamo に「記憶」させたい場合に使用します。

circle-exclamation

このオプションは、特定の図面 と Dynamo グラフの間で 1:1 の関係を維持できる場合に最適です。オプション 1 と 3 は、複数の図面で実行するように設計されたグラフに適しています。

hashtag
オプション3: Dynamo の図面に保存する

これは、オブジェクト バインド データがグラフ(.dyn ファイル)ではなく図面内でシリアル化される点を除き、オプション 2 と同様です。グラフを閉じて再度開き、同じ図面で実行すると、すべてが、グラフを閉じる前と同じように動作するはずです。別の図面でグラフを実行すると、バインド データはグラフではなく図面に保存されるため、元の図面でも保持されます。

circle-info

使用する状況

このオプションは、複数の図面で同じグラフを使用し、Dynamo にそれぞれのグラフで行ったことを「記憶」させる場合に使用します。

hashtag
オプション4: Dynamo プレーヤの図面に保存する

このオプションで最初に注意する点は、メインの Dynamo インタフェースでグラフを実行する場合に、グラフと図面の相互作用に影響を与えないことです。このオプションは、Dynamo プレーヤを使用してグラフを実行する場合に のみ 適用されます。

circle-info

Dynamo プレーヤを初めて使用する場合は、「 」セクションを参照してください。

メインの Dynamo インタフェースを使用してグラフを実行し、その後閉じて、次に Dynamo プレーヤを使用して同じグラフを実行すると、以前に作成したオブジェクトの上に新しいオブジェクトが作成されます。ただし、Dynamo プレーヤでグラフを一度実行すると、図面内のオブジェクト バインド データがシリアル化されます。したがって、Dynamo プレーヤでグラフを複数回実行する場合、新しいオブジェクトを作成するのではなく、オブジェクトが更新されます。別の図面で Dynamo プレーヤを使用してグラフを実行した場合、バインド データはグラフではなく図面に保存されるため、元の図面で保持されます。

circle-info

使用する状況

このオプションは、複数の図面で Dynamo プレーヤを使用してグラフを実行し、各グラフで行ったことを「記憶」させる場合に使用します。

Dynamo プレーヤ
Dynamo で半径の入力を変更する
選択した円の中心にテキストを配置する単純なグラフ
新しい円を選択したときの Dynamo の既定の動作
オブジェクト バインド設定
オブジェクト バインドが無効になっている場合の動作
オブジェクト バインド

高度なトピック

時間の経過とともに、基本を超えて、Dynamo の内部の仕組みを詳細に理解する必要が出てくることがあります。このセクションのページでは、グラフを次のレベルに引き上げることができるように、Dynamo for Civil 3D の高度な機能を明らかにしていきます。

Python と Civil 3D

Dynamo はビジュアル プログラミング ツールとして非常に強力ですが、ノードやワイヤを超えて、テキスト形式でコードを記述することもできます。これを行うには、次の 2 つの方法があります。

  1. Code Block ノードを使用して DesignScript を記述する

  2. Python ノードを使用して Python を記述する

このセクションでは、Civil 3D 環境で Python を活用して、AutoCAD および Civil 3D .NET API を利用する方法について説明します。

circle-info

Dynamo での Python の使用に関する一般情報については、「 」セクションを参照してください。

hashtag
API ドキュメント

AutoCAD と Civil 3D にはどちらにも、開発者がカスタム機能を使用してコア製品を拡張できるようにする複数の API が用意されています。Dynamo のコンテキストで関連するのは、Managed .NET API です。次のリンクは、API の構造とその仕組みを理解するために不可欠です。

circle-info

このセクションを進めていくと、データベース、トランザクション、メソッド、プロパティなど、馴染みのない概念が出てくるかもしれません。これらの概念の多くは、.NET API を使用するための中核であり、Dynamo や Python に固有のものではありません。これらの項目の詳細については、Primer のこのセクションでは取り上げません。詳細については、上記のリンクを頻繁に参照することをお勧めします。

hashtag
コード テンプレート

新しい Python ノードを初めて編集すると、開始するためのテンプレート コードがあらかじめ入力されます。ここでは、テンプレートの概要と各ブロックに関する説明を示します。

  1. sys モジュールおよび clr モジュールを読み込みます。どちらも Python インタプリタが正しく機能するために必要なモジュールです。特に、clr モジュールを使用すると、.NET 名前空間を基本的に Python パッケージとして扱うことができます。

  2. AutoCAD および Civil 3D のマネージド .NET API を使用するための標準アセンブリ(DLL)をロードします。

circle-info

カスタマイズする場合 既定の Python テンプレートは、C:\ProgramData\Autodesk\C3D <version>\Dynamo 内の PythonTemplate.py ファイルを編集することで修正できます。

hashtag
例

Dynamo for Civil 3D で Python スクリプトを作成する場合の基本的な概念について、例を見ていきましょう。

hashtag
目標

🎯 図面内のすべての集水域の境界ジオメトリを取得します。

hashtag
データセット

この演習で参照できるサンプル ファイルを次に示します。

hashtag
対処法の概要

このグラフのロジックの概要を次に示します。

  1. Civil 3D API のドキュメントを確認する

  2. レイヤ名でドキュメント内のすべての集水域を選択する

  3. Dynamo オブジェクトを「アンラップ」して、内部の Civil 3D API メンバーにアクセスする

以上です。

hashtag
API ドキュメントを確認する

グラフの作成とコードの作成を開始する前に、Civil 3D API のドキュメントを参照して、API が提供する機能を理解することをお勧めします。この場合、集水域の境界点を返すに存在します。このプロパティは、Dynamo が処理する必要があるオブジェクトとは異なる Point3dCollection オブジェクトを返すことに注意してください。つまり、Point3dCollection からポリカーブを作成することはできないため、最終的にはすべてを Dynamo の点に変換する必要があります。詳細については、後で説明します。

hashtag
すべての集水域を取得する

これで、グラフ ロジックの作成を開始することができます。最初に、ドキュメント内のすべての集水域のリストを取得します。これに使用できるノードがあるため、Python スクリプトに含める必要はありません。ノードを使用すると、(Python スクリプトに多くのコードを埋め込むんだ場合に比べて)、他のユーザはグラフを読みやすくなり、Python スクリプトは集水域の境界点を返すという 1 つの事柄にも対処できます。

All Objects on Layer ノードからの出力は、CivilObjects のリストであることに注意してください。これは、Dynamo for Civil 3D には現在、集水域を操作するためのノードが存在しないためです。これが、Python を使用して API にアクセスする必要がある理由です。

hashtag
オブジェクトをアンラップする

先に進む前に、重要な概念について簡単に説明する必要があります。「」セクションで、オブジェクトと CivilObjects の関係について説明しました。これをもう少し詳しく説明すると、Dynamo オブジェクト は AutoCAD 図形 のラッパーです。同様に、Dynamo CivilObject は、Civil 3D 図形のラッパーです。InternalDBObject プロパティまたは InternalObjectId プロパティにアクセスすることで、オブジェクトを「アンラップ」することができます。

Dynamo タイプ
ラップ
circle-exclamation

経験則として、InternalObjectId プロパティを使用してオブジェクト ID を取得し、トランザクションでラップされたオブジェクトにアクセスする方が一般的に安全です。これは、InternalDBObject プロパティは書き込み可能な状態でない AutoCAD DBObject を返すためです。

hashtag
Python スクリプト

内部の集水域オブジェクトにアクセスして境界点を取得する作業を行う完全な Python スクリプトを以下に示します。ハイライト表示された行は、既定のテンプレート コードから修正または追加された行を表します。

circle-info

スクリプト内の下線付きのテキストをクリックすると、その行の説明が表示されます。

circle-exclamation

経験則として、スクリプト ロジックの大部分をトランザクション内に含めることをお勧めします。これにより、スクリプトが読み取り/書き込みを行うオブジェクトに安全にアクセスできるようになります。多くの場合、トランザクションを省略すると致命的なエラーが発生する可能性があります。

hashtag
ポリカーブを作成する

この段階では、Python スクリプトは、背景プレビューで確認できるように Dynamo の点のリストを出力する必要があります。最後の手順は、点から単純にポリカーブを作成します。これは Python スクリプトで直接行うこともできますが、より見やすくするために、ノードのスクリプトの外側に意図的に配置しています。最終的なグラフは次のようなものになります。

hashtag
結果

最終的な Dynamo ジオメトリは次のとおりです。

🎉 ミッションが達成されました。

hashtag
IronPython と CPython

最後に、注意事項を簡単に説明します。使用している Civil 3D のバージョンに応じて、Python ノードの設定が異なる場合があります。Civil 3D 2020 および 2021 では、Dynamo は IronPython というツールを使用して .NET オブジェクトと Python スクリプトの間でデータを移動しました。Civil 3D 2022 では、Dynamo は Python 3 を使用するのではなく、標準のネイティブ Python インタプリタ(CPython とも呼ばれる)を使用するように移行しました。この移行には、人気のある最新ライブラリや新しいプラットフォーム機能、基本的なメンテナンス、セキュリティ パッチへのアクセスなどのメリットがあります。

circle-info

この移行の詳細と、従来のスクリプトのアップグレード方法については、 を参照してください。IronPython を今後も使用する場合は、Dynamo Package Manager を使用して DynamoIronPython2.7 パッケージをインストールする必要があります。

標準の AutoCAD および Civil 3D 名前空間に参照設定を追加します。これらは、それぞれ、C# または VB.NET の using ディレクティブまたは Imports ディレクティブに相当します。

  • ノードの入力ポートには、IN と呼ばれる定義済みのリストを使用してアクセスできます。特定のポートのデータには、そのインデックス番号を使用してアクセスできます(例: dataInFirstPort = IN[0])。

  • アクティブなドキュメントおよびエディタを取得します。

  • ドキュメントをロックし、データベース トランザクションを開始します。

  • ここに、スクリプトのロジックの大部分を配置する必要があります。

  • メインの作業が完了した後にトランザクションをコミットするには、この行のコメントを解除します。

  • ノードからデータを出力する場合は、スクリプトの最後にある変数 OUT に出力するデータを割り当てます。

  • AutoCAD の点から Dynamo の点を作成する

  • 点からポリカーブを作成する

  • オブジェクト Autodesk.AutoCAD.DynamoNodes.Object

    図形 Autodesk.AutoCAD.DatabaseServices.Entity

    CivilObject Autodesk.Civil.DynamoNodes.CivilObject

    図形 Autodesk.Civil.DatabaseServices.Entity

    Python
    AutoCAD .NET API 開発者用ガイドarrow-up-right
    AutoCAD .NET API リファレンス ガイドarrow-up-right
    Civil 3D .NET API 開発者用ガイドarrow-up-right
    Civil 3D .NET API リファレンス ガイドarrow-up-right
    file-download
    15KB
    Python_Catchments.dyn
    arrow-up-right-from-squareOpen
    file-download
    961KB
    Python_Catchments.dwg
    arrow-up-right-from-squareOpen
    プロパティが Catchment クラスarrow-up-right
    ノード ライブラリ
    Dynamo Blogarrow-up-right
    Civil 3D の既定の Python テンプレート
    ドキュメント内のすべての集水域をレイヤごとに取得する
    最終的なグラフ
    集水域境界の、結果として生じた Dynamo ポリカーブ
    # Python 標準ライブラリと DesignScript ライブラリをロードします
    import sys
    import clr
    
    # AutoCAD および Civil3D のアセンブリを追加します
    clr.AddReference('AcMgd')
    clr.AddReference('AcCoreMgd')
    clr.AddReference('AcDbMgd')
    clr.AddReference('AecBaseMgd')
    clr.AddReference('AecPropDataMgd')
    clr.AddReference('AeccDbMgd')
    
    clr.AddReference('ProtoGeometry')
    
    # AutoCAD から参照設定をインポートします
    from Autodesk.AutoCAD.Runtime import *
    from Autodesk.AutoCAD.ApplicationServices import *
    from Autodesk.AutoCAD.EditorInput import *
    from Autodesk.AutoCAD.DatabaseServices import *
    from Autodesk.AutoCAD.Geometry import *
    
    # Civil3D から参照設定をインポートします
    from Autodesk.Civil.ApplicationServices import *
    from Autodesk.Civil.DatabaseServices import *
    
    from Autodesk.DesignScript.Geometry import Point as DynPoint
    
    # このノードへの入力は、IN 変数にリストとして保存されます。
    objs = IN[0]
    
    output = []
    
    if objs is None:
        sys.exit("The input is null or empty.")
    
    if not isinstance(objs, list):
        objs = [objs]
       
    adoc = Application.DocumentManager.MdiActiveDocument
    editor = adoc.Editor
    
    with adoc.LockDocument():
        with adoc.Database as db:
            
            with db.TransactionManager.StartTransaction() as t:
                for obj in objs:             
                    id = obj.InternalObjectId
                    aeccObj = t.GetObject(id, OpenMode.ForRead)               
                    if isinstance(aeccObj, Catchment):
                        catchment = aeccObj
                        acPnts = catchment.BoundaryPolyline3d                   
                        dynPnts = []
                        for acPnt in acPnts:
                            pnt = DynPoint.ByCoordinates(acPnt.X, acPnt.Y, acPnt.Z)
                            dynPnts.append(pnt)
                        output.append(dynPnts)
               
                # トランザクション終了前にコミットする
                t.Commit()
                pass
                
    # OUT 変数に出力をアサインします。
    OUT = output