こんにちは、ISDです。
Civil 3Dで、現地系のTINサーフェス上に、国土地理院の基盤地図情報からダウンロードした建築物の外周線のSHPファイルをもとに建築物の箱モデルを作ることがあります。

あるのですが、この作業すんなりと行ってはくれません。
何が問題かというと
「ポリラインの高度をTINサーフェスに合わせないといけない」
「3Dポリラインの各頂点の高さ(z座標)が同値でないと、押し出したときにソリッドにならない」
と、いうことです。

「ポリラインの高度をTINサーフェスに合わせないといけない。」
に関しては、FEATUREELEVSFROMSURF コマンドを使用すれば、ポリラインの各頂点をTINサーフェス上に「乗っける」とこが出来るのですが、当然TINサーフェスが水平でない場合はポリラインの各頂点の高さ(z座標)は変わってしまいます。そうなると、ポリラインを押し出したときにソリッドになってくれません。

ならば、各外周線のポリラインを手作業でTINサーフェスの高度に合わせる……なんて、そんな手間がかかる事はやりたくありません。
さて、どうするか?
ということで、Dynamo の出番です。
Dynamoを用いてTINサーフェス上に建物の箱モデルを作成する
今回の目的は、TINサーフェス上に移動した建築物の外周線のポリゴンを生成し、それをもとにソリッドオブジェクトを作成する、ということになります。
手順としては
1.建築物の外周線のポリラインの各頂点をTINサーフェス上に移動
2.TINサーフェス上に移動したポリラインの各頂点のZ座標を同値にする
3.各頂点を繋ぎ、建築物の下面のポリゴンを生成
4.建築物の下面のポリゴンを押し出してソリッドを生成
という流れになります。
今回も Civil3DToolkit のノードも使用していますので、Civil3DToolkit のパッケージをインストールしておいて下さい。
Civil3DToolkit のインストールについてはこちらをご参照ください。
https://cim-cad.com/dynamo-00-civil3dtoolkit/
使用するノード
Select Objects
Civil3Dのモデル空間からオブジェクトを選択します。(Civil3DToolkit)
標準で搭載されている Select Object のノードと違って、複数のオブジェクトを選択することが出来ます。
Object.Geometry
オブジェクトから、ジオメトリ情報を取得します。
PolyCurve.Curves
ポリカーブから、Curveのリストを取得します。
Curve.StartPoint
Curveの始点のポイントを取得します。
Surface.SamplePoint
ポイントをサーフェス上に投影した座標を取得します。
Object.IsNull
オブジェクトが Null であるか判定します。
List.AllFalse
リスト内の全ての項目が False になっているか判定します。
List.FilterByBoolMask
マスクする項目をブール値で示したリストをもとに、指定したリストをフィルタします。
Point.X
ポイントの X 座標を取得します。
Point.Y
ポイントの Y 座標を取得します。
Point.Z
ポイントの Z 座標を取得します。
List.MinimumItem
リストの最小値を取得します。
Point.ByCoordinates
X,Y,Z 座標を指定してポイントを生成します。
Polygon.ByPoints
ポイントのリストから、ポリゴンを生成します。
Curve.ExtrudeAsSolid (direction,distance)
閉じた曲線を、方向・距離を指定してソリッドを生成します。
Document.Current
現在の AutoCAD ドキュメントを取得します。
Document.ModelSpace
ドキュメントの モデル空間を取得します。
Object.ByGeometry
Dynamo オブジェクトから AutoCAD オブジェクトを生成します。

ノードを上図のように配置します。
では、Dynamoの中身を順を追って見ていきましょう。
建築物の外周線のポリラインの各頂点をTINサーフェス上に移動
建物の外周線のポリラインの頂点を取得
先ずは、建物の外周線のポリラインにおける各ポイントのリストを取得します。
Dynamoで、閉じたポリラインの各頂点のポイントを取得するには、
①オブジェクトのジオメトリ情報からポリカーブ(カーブのリスト)を取得
②それぞれのカーブの始点のポイントを取得
という手順になります。
※ 国土地理院の基盤地図情報による建築物の外周線のポリラインは、始点と終点が同位置にある開いたポリラインになっていますが、今回の Dynamo の処理では閉じたポリラインと同じ手順で OK です。

実際の Dynamo のグラフは上図のようになります。
ちなみに、開いたポリラインの場合は、さらに
③ポイントのリストの最後にポリカーブの最終点のポイントを追加する。
という処理が入ります。(今回は使いませんが……)

これは、Dynamo で Civil 3D からポリラインの情報を取ってくるとき常套手段としてチョイチョイ使うので、カスタムノード化しておいても良いかも。
ポイントを TINサーフェス上に投影する
次に、ポリラインの各ポイントをTINサーフェス上に投影します。

Surface.SamplePoint のノードで、建築物の外周線のポリラインのポイントをTINサーフェス上に投影します。
このとき、TINサーフェスの範囲から外れているポイントは、結果が Null になりますが、Null が含まれているとこの後の処理でエラーになってしまうので、Object.IsNull → List.AllFalse で Null があるかを判別し、List.FilterByBoolMask で、Null が含まれるポイントリストを除外します。
つまり、TINサーフェスから頂点がはみ出すポリラインは、処理から除外されることになります。
これで、TINサーフェス上に投影された建築物の外周線のポリラインのポイントのリストが取得できました。
TINサーフェス上に移動したポリラインの各ポイントのZ座標を同値にする
次は、各ポリラインのポイントのZ座標を同値にします。
ここで、Z座標の高さをどう設定するかですが、
建物の箱モデルが地形から浮いてしまう部分があるとよろしくないので、Z座標は、ポリラインの各ポイントで一番低い点のZ座標に合わせることにします。
では、Dynamo のノードを見てみましょう。

ポリラインのポイントのリストから、X座標、Y座標、Z座標のリストを抽出します。
Z座標については、List.MinimumItem で、各ポリラインのポイントのZ座標の最小値を取得します。
そして、Point.ByCoordinates のノードで、X,Y座標はそのまま、Z座標に各ポリラインのポイントのZ座標の最小値を入力し、新しくポイントのリストを生成します。
下面のポリゴンを生成し 押し出してソリッドを生成
続いて、ポイントのリストをもとに建物の下面のポリゴンを生成します。
Dynamo の ノードを見てみましょう。

下面のポリゴンは、Polygon.ByPoints にポイントのリストをそのまま流せばポリゴンが生成されます。
そして、そのポリゴンを Curve.ExtrudeAsSolid のノードで方向と距離を指定して押し出します。
方向は、デフォルトで (0,0,1)が設定されているので、そのまま何も指定せずにOKです。
最後に Object.ByGeometry のノードでAutoCAD( Civil 3D )のモデル空間に建物の箱モデルを生成します。今回は、”-Dynamo” というレイヤにソリッドを生成していますが、適宜変更してください。

今回は、サンプルということで、建物の高さは一律同じ高さにしていますが、ポリラインのレイヤによって高さを設定してみたり、ランダム要素を入れてみたりしても良いかもしれませんね。
なお、今回生成されたソリッドオブジェクトは、ただの 3Dソリッド 扱いになるので、EXTRUDE コマンドで生成したソリッドのようにプロパティパレットから高さを変更したりすることは出来ないので、ご注意ください。
今回の Dynamo のファイルは、こちらからダウンロードできますのでよろしければどうぞ。


コメント