ラベル ダイナモ の投稿を表示しています。 すべての投稿を表示
ラベル ダイナモ の投稿を表示しています。 すべての投稿を表示

2026年3月8日日曜日

3点を通る球体~Dynamo

回転球体法

避雷針の保護範囲を計測する方法として回転球体法(JIS Z 9290‑3)があります。様々なパターンがありますが、3つの避雷針で保護される範囲はそれぞれの先端に接する半径R(レベルによる)の下側ということになります。

このような「3点A,B,Cに接する半径Rの球」をDynamoで作成してみましょう。

3点に接する半径Rの球を作成するには?

幾何学的には案外単純

3点A,B,Cを通る半径Rの球体の中心点は、△ABCの外接円の中心を、面の法線方向に伸ばした線上にあります。幾何学的には割と単純な話ですがこれをDynamoで解くとなると一工夫必要です。

Dynamoの新規グラフを作成する

[管理]タブ>[ビジュアルプログラミング]パネル>[Dynamo]をクリックし[新規作成]を選択

プログラムの実行モードは[手動]に切り替えておきましょう。


Dynamoでは点が指定できない

現在のDynamoの仕様ではユーザーが指定した点を取得することはできません。そこで要素のエッジを選択してその両端のうちZの値が大きいほうを選ぶようにしてみます。以下はその部分を示すグラフです。

選択したエッジの両端のうちZが大きいほうを選ぶ

ここで使用しているノードは次の通りです。

  • SelectEdge : ユーザーにエッジを選択を促す
  • Curve.StartPoint/EndPoint : エッジの始点と終点
  • List.Create : エッジの始点と終点をリストにする
  • List.MaximumItemByKey : リストのうちPoint.Zの値が最大のアイテムを返す

これを複製して3つ追加します。

3点を選ぶために複写

この状態でSelectEdgeの選択ボタンを押して、3つの避雷針のエッジを選択しておきます。

半径を入力

半径を入力するのですが、入力自体はm単位で、計算は基本的にmmなのでメートルからミリに変換します。1000を掛ければいいのですが、今回は単位変換ノードを使用します。

半径を取得
ここで使用しているノードは次の通りです。

  • Number : 半径をユーザーが入力
  • Convert By Unit : メートルをミリメートルに変換

3点を通り半径Rの球体の中心点を求める

幾何学的には簡単、と申し上げましたがDynamoのノードだけでこれを行うのはなかなか大変です。そこでPythonスクリプトを使って求めることにします。

まず、Puthon Scriptノードを追加し+ボタンをおして、入力端子をIN[0]~[3]まで作成します。


次にノードを右クリックして[編集]を選択してエディタを開きます。そして既存のコードを削除して、以下を丸ごと張り付けてください。


# Python 標準ライブラリおよび DesignScript ライブラリをロード
# Dynamo Python Node
# IN[0]=p1, IN[1]=p2, IN[2]=p3 : Geometry.Point
# IN[3]=r : radius (same unit as points)
# OUT = c1 : Geometry.Point (higher Z)
import math
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import Point, Vector
# このノードへの入力は、リスト形式で IN 変数に格納されます。
p1 = IN[0]
p2 = IN[1]
p3 = IN[2]
r  = float(IN[3])
# この行の下にコードを配置します
def circumcenter(p1, p2, p3, eps=1e-12):
    a = Vector.ByTwoPoints(p1, p2)
    b = Vector.ByTwoPoints(p1, p3)
    n0 = a.Cross(b)
       
    if n0.Length < eps:
        raise Exception("3 points are nearly collinear")
      
    aLen2 = a.Dot(a)
    bLen2 = b.Dot(b)
    n0Len2 = n0.Dot(n0)
    term1 = b.Cross(n0).Scale(aLen2)
    term2 = n0.Cross(a).Scale(bLen2)
    c_vec = term1.Add(term2).Scale(1.0 / (2.0 * n0Len2))
    c = p1.Add(c_vec)
    n = n0.Normalized()
    return c, n
    
def sphere_center_z_higher(p1, p2, p3, r):
    
    c, n = circumcenter(p1, p2, p3)
    rho = c.DistanceTo(p1)
    if r < rho:
        raise Exception("r is smaller than circumradius")
    h = math.sqrt(r*r - rho*rho)
    cA = c.Add(n.Scale(h))
    cB = c.Add(n.Scale(-h))
    return cA if cA.Z >= cB.Z else cB
# 出力を OUT 変数に割り当てます。
OUT = sphere_center_z_higher(p1, p2, p3, r)


ここでは詳細な説明は省きますが、コピーするときは一度メモ帳などに貼り付けて書式を解除したうえで貼り付けてください。

球体の中心は三角形ABC(p1-p2-p3)の上側と下側の両方にあるので、ここでは上側の中心点のみをOUTのポートに返すようにしています。

[保存して実行]を押して閉じたらIN[0]~[2]に指定した3点を、IN[3]に半径を接続します。

Python Scriptノードに入力を接続

球体をダイレクトシェイプで作成

中心がわかったのでダイレクトシェイプを使って球体を作成します。まずはSOLIDで球体を作成し、それをもとにダイレクトシェイプを作成します。

ダイレクトシェイプの作成

ここで使用しているノードは

  • Sphere.ByCenterPointRadius : 中心点と半径で球体SOLIDを作成
  • DirectShape.ByGeometry : ジオメトリとカテゴリを指定してダイレクトシェイプを作成
  • Categories : カテゴリを選択


Sphere.ByCenterPointRadiusのcenterPonintに球体の中心点を、Radiusに半径を接続します。

中心点と半径を接続


これで実行してみましょう。球体の大きさが避雷針の互いの距離よりも短かければ球体が作成されるはずです。

3点を通る半径Rの球体

2019年2月9日土曜日

ダイナモ白熱教室~床の躯体天端レベルをタグに表示する

Dynamoでパラメータを操作する

躯体天端レベルをタグに表示するにはどうすればよいでしょうか?残念ながら床タグでは床レベルのパラメータはありませんし、ましてや躯体の天端レベルというパラメータはありません。「レベルからのオフセット」すらタグに表示できないのです。
躯体天端レベルをタグに表示するには?
「上部躯体の高さ」というパラメータが使用可能ですが、惜しいかなこの値は高さ(Z)の座標値で、レベルからの相対距離ではありません。
床の「上部躯体の高さ」はzの値でレベルからの相対距離ではない
APIを使えはもちろん可能ですが、この「床の躯体天端レベルをタグに表示する」というお題をダイナモで解いてみます。

共有パラメータの準備

タグに値を表示するのですから、まずは床に躯体天端レベルの値を表示するインスタンスパラメータを共有パラメータとして作成します。
共有パラメータを作成し、床のインスタンスパラメータとして設定する。
ここでは「スラブレベル」という共有パラメータを作成し、床のインスタンスプロパティとして設定しました。

Dynamo:構造の床を集める

まず、すべての床を集めます。ただし、床のインスタンスプロパティ「構造」にチェックが入っているものだけです。そうでないと「上部躯体の高さ」の値が「なし」になってしまうからです。


  1. [Revit]>[Selection]>[Categories]を追加し「床」を選択。
  2. [Revit]>[Selection]>[All Elements of Category]を追加し、1と接続。
  3. [Revit]>[Element]>[GetParameterValurByName]を追加し、2のElementsをElementに接続。
  4. [Input]>[Basic]>[String]を追加し「構造」と入力、3のParameterNameに接続。
  5. [Math]>[Operaters]>[==]を追加し、Xに4のvar[]..[]を接続。
  6. [Input]>[Basic]>[Number]を追加し、値を1とし、==のyに接続。(これによりパラメータの値の1/0をTrue/Falseに変換する)
  7. [List]>[Modify]>[FilterByBoolMask]を追加し、==のvar[]..[]とmaskを接続。
  8. 7のlistと2のElementsを接続。
これでFilterByBoolMaskの[in]に、パラメータ「構造」にチェックが入った床のインスタンスを集めることができました。

Dynamo:スラブレベルを計算する

スラブレベルを「上部躯体の高さ-床の参照レベルの高さ」で計算します。床のレベルの高さはまず床の参照レベルをパラメータでもとめ、さらにレベルの高さパラメータの値を取得します。
  1. [Revit]>[Element]>[GetParameterValurByName]を追加し、[in]と[element]を接続。
  2. [Input]>[Basic]>[String]を追加し「レベル」と入力、2のParameterNameに接続。
  3. [Revit]>[Element]>[GetParameterValurByName]を追加し、1のvar[]..[]と接続。
  4. [Input]>[Basic]>[String]を追加し「高さ」と入力、3のParameterNameに接続。これで床の参照レベルの高さを取得できました。
  5. [Revit]>[Element]>[GetParameterValurByName]を追加し、[in]と[element]を接続。
  6. [Input]>[Basic]>[String]を追加し「上部躯体の高さ」と入力、5のParameterNameに接続。
  7. [Math]>[Operators]>[-]を追加し、[x]には5(上部躯体の高さ)のvar[]..[]、[y]には3(レベルの高さ)を接続
ここでWatchノードなどで値を確認してください。

Dynamo:スラブレベルの値を床にセットする

最後に、求めたスラブレベルを床のインスタンスプロパティ「スラブレベル」にセットします。
スラブレベルの値を床にセットする
  1. [Revit]>[Element]>[SetParameterValurByName]を追加し、
    1. elementsを[List.FilterByBoolMask]の[in]へ接続。
    2. valueを[-]のvar[]..[]に接続
  2. [Input]>[Basic]>[String]を追加し「スラブレベル」と入力し、1のParameterNameに接続。
以上で床にスラブ(躯体)レベルを設定することができました。
スラブレベルの値が設定された
あとは、共有パラメータ「スラブレベル」を使った床タグを配置すればスラブレベルが表示されます。Dynamoを開いておけば、床の変更にリアルタイムに追随します。
モデルの変更にリアルタイムに追随する
躯体の天端なので、仕上があってもスラブレベルを表示します。
また、躯体境界よりも上にレイヤがあっても問題ありません。

仕上が入っても躯体レベルを表示する
このグラフはこちらからダウンロードできます

2018年9月24日月曜日

スラブのレベルごとに色分けする

パラメータの値で色分けするには?

躯体図や構造伏図でスラブをレベルごとに色分けできるとわかりやすいのですが、その方法としてはフィルタを使う方法があります。しかしながら、「レベル高さからのオフセット(2018)」の値を指定しなくてはいけないので、新しい値が発生するたびにフィルタを追加する必要があります。
ダイナモを使って、ダイナミックに色を更新してみましょう。
床のパラメータの値で色分けするには?

Dynamo:現在のビューに表示されている床を選択する




  1. [Revit]>[Views]>[View]>[All Elements In Active View]①
  2. [List]>[Modify]>[RemoveIfNot]②を追加し、①のelementsとlistを接続。
  3. [Input]>[Basic]>[String]を追加し、「Floor」と設定し、②のtypeに接続。
これで現在のビューに表示されている床をすべて選択できました。

Dynamo:パラメータの値を取り出す


  1. [Revit]>[Element]>[GetParameterValueByName]③を追加し、②のVar[]..[]とelementを接続。
  2. [Input]>[Basic]>[String]を追加し、「レベルからの高さオフセット」と設定し、③のparameterNameと接続。
パラメータの名前は各バージョンで異なりますので、床を選択してパラメータの名称を確認してください。

Dynamo:色範囲を設定する

取得した値を色に割り当てます。そのために割り当てる「色の範囲」を決めます。今回は一番低い値を赤、一番高い値を青色としてそのグラデーションを使ってパラメータの値を表現してみましょう。

  1. [Input]>[Basic]>[Number]①を二つ追加し、それぞれ「0」と[255]を入力。
  2. [Display]>[Color]>[ByARGB]②をつ追加。
  3. ①の255を②のrと接続し、g、bを①の0のノードと接続。これが赤です。
  4. [Display]>[Color]>[ByARGB]をもう一つ追加。
  5. bに255のノードを、他を0のノードと接続。これが青です。
  6. [List]>[Generate]>[List Create]を追加し、[+]をクリックしてItem1を追加。
  7. item0に赤、item1に青を接続
  8. [Display]>[Color Range]>[Color Range]を追加し、List Createのlistをcolorsに追加。
カラーが左から右に向かって赤から青へ色が変化していることを確認してください。エラーになりますが気にしないでください。

Dynamo:パラメータの値を0~1に再割り当てする


Color Rangeのvalueは0~1の値しか受け付けないので、取得したパラメータの値を0から1の値に再割り当てする必要があります。

  1. [Math]>[RemapRange]を追加し[Element.GetParameterValueByName]のvar[]..[]とnumberを接続。
  2. Input]>[Basic]>[Number]を二つ追加し、それぞれ「0」と[1]を入力。
  3. [RemapRang]のnewMinに0、newMaxに1を接続。
これで、パラメータの値が、0~1の値に再割り当てされます。

Dynamo:要素の色付け

現在のビューで要素を色付けしてみます。

  1. [Math.RemapRange]のlistを[Color Range]のvalue に接続。
  2. [Revit]>[Elements]>[Element]>[OverrideColorInView]を追加し、[Color Range]のcolorをcolorに接続。
  3. [List.RemoveIfNot]のvar[]..[]をelementに接続。
以上で、現在のビューにある床をレベルごとに色分けすることができました。

試しに、床の「レベルからのオフセット」の値を変更してみると・・・

色が自動的に再割り当てされることがわかります。これはもちろん3Dビュー(隠線処理・シェーディング・べた塗りのみ)でも有効です。

こちらのグラフを参考にしていろいろと試してみてください。

2018年9月15日土曜日

梁の座標

Dynamo!

梁の端点の座標をDynamoを使ってEXCELに出力してみましょう。サンプルのデータは標準で付属している[rst_advanced_sample_project.rvt]を使います。
この構造フレームの両端の座標を

このように出力することが目標です。Dynamoを起動して新規作成を選択しましょう。

構造フレームを選択する



  1. Revit > Selection > Categories で「構造フレーム」を選択。
  2. Revit > Selection > All Elements of Category を選択し1のCategoryとCategoryを結ぶ。

構造フレームの位置(カーブ)を抽出



  1. Revit > Elements > StructuralFraming > Location を追加し、All Elements of Category の ElementsとstructuralFramingを結ぶ。
  2. バックグラウンドに構造フレームの位置を示すカーブが描画される。

カーブの始点と終点の座標を求める


  1. Geometry > Curves > Curve > StartPoint EndPoint を追加。
  2. StructuralFraming.Location の Curveとそれぞれの curve を結ぶ。バックグラウンドのカーブ(直線)の端点に●が表示されます。

XYZの値に分解する

ExcelのセルにX,Y,Zの値をそれぞれ格納するために値を分解します。

  1. Geometry > Points > Point > X,Y,Z を2つずつ追加。
  2. Curve.StartPointとCurve.EndPointのPointをX,Y,ZのPointとつなぐ。

ファミリ名の取得

Excelに出力するときファミリ名とタイプ名があると便利です。

  1. Revit > Elemennts > Element > ElementType を追加し、All Elements of Category の Elementsとelementと結ぶ。

  1. Revit > Elemennts > FamilyType > Family を追加し、ElementTypeとfamilyTypeを接続。
  2. Revit > Elemennts > Family > Name を追加し、Familyとfamilyを接続。これによりファミリの名前のリストを取得できます。

タイプ名の取得


  1. Revit > Elemennts > FamilyType > Name を追加し、Element.ElementTypeのElementTypeとfamilyType を接続。

プロパティの取得

構造フレームのレベルは「参照レベル」という名前のプロパティに格納されています。プロパティの値を取得しましょう。

  1. Input > Basic > String を追加し「参照レベル」と設定。
  2. Revit > Elements > Parameter > ParameterByName を追加し、Stringの > と nameを結ぶ。
  3. All Elements of Category の Elements と elmenet を結ぶ。
参照レベルの値が取得できたか、Listを確認してください。

取得した値のリスト化

以上でEXCELに出力する項目の値はすべて取得しました。次に各セルに値を格納するために、一行分を取り出してリスト化します。


  1. List > Generate > List Create を追加し[+]をクリックしてitem0からitem8まで作成。
  2. item0からitem8までを図のように接続する.

リストの列と行を入れ替える


  1. List > Organize > Transpose を追加し、list とlists を接続。
  2. 作成されたリストを確認。

EXCEL出力する

作成したリストをEXCELにエクスポートします。

  1. ImportExport > Data > ExportExcel を追加。
  2. ImportExport > File System > File Path を追加し、file Pathに接続。
  3. Input > Basic > String を追加し、「梁の座標」と入力し、sheetNameに接続。
  4. Input > Basic > Number を 2つ追加し、startRowとstartColに接続。
  5. Input > Basic > Boolean を追加し、Trueを選択し、overwriteに接続。
  6. 最後に List.Transpose のListsをdataに接続すると、Excelが起動し座標が出力される。

完成したグラフはこちらからダウンロードできます。


めざせ!ダイナモマスター

ダイナモを基礎から習得するには、こちらの Dynamo Primer がベストです。ダイナモの習得に必要な基礎知識、チュートリアルがそろっています。すべてを理解するにはかなりの時間がかかりますが、昼休みに少しずつやってみれば3カ月もすれば、あなたもダイナモマスターに必ずなれます。

頑張りましょう!





2018年3月18日日曜日

ダイナモ白熱教室(13)~壁の造作材の体積

壁のスイープの数量

幅木を「壁のスイープ(造作材)」で作成した場合、そのマテリアルのマテリアル別の体積は算出できるでしょうか?
壁のスイープで作成した幅木の数量は?
残念ながら答えはNoです。壁の造作は[表示]タブ>[作成]パネル>[部材拾い出し]では、そのマテリアルを拾い出すことはできません。壁のスイープは長さしか拾えません。普通に集計表を作成すると、マテリアル別の長さを集計することが可能です。
集計表で長さは拾える
実際のところ、幅木や廻り縁であれば、数量としては長さがわかればよいので実質的な問題はないといえます。

ここでダイナモ

そうはいっても、マテリアル別の体積を計測することはできないのでしょうか?断面積×長さでもよさそうなものですが、ダイナモを使って実際の体積をマテリアル別に求めてみましょう。

要素を選択する部分

ダイナモを立ち上げて、下の図のようにカテゴリで要素を選択します。
カテゴリで選択

[Revit]>[Selection]>[Categories]ノードと、[Revit]>[Selection]>[All Element of Category]ノードを追加し、図のように結びます。これですべての壁のスイープを選択できます。

Solidの取り出し体積を測定

壁のスイープからSolidを取り出します。

  1. [Revit]>[Element]>[Element]>[Geometry]
  2. [Geometry]>[Solid]>[Volume]
  3. [Core]>[Units]>[Convert between units]
を追加し、[All Element of Category]に接続します。
Solidを取り出して体積を抽出
Watchノードを追加し結果を確認します。

マテリアルの取り出し

マテリアルの名前を取り出します。
  1. [Revit]>[Elements]>[Element]>[GetMaterials]
  2. [Revit]>[Elements]>[Material]>[Name]
を追加し、これも[All Element of Category]に接続します。
マテリアル名のリストを取得
Watchノードで結果を確認します。

マテリアルと体積をリストに編成

Watchノードをよく見てください。マテリアルの名前も体積も選択した要素と同じ並び順になっています。これらの情報をエクセルに出力しましょう。

  1. [Builtin]>[Flatten]を二つ追加
  2. [Core]>[List]>[List.Create]を追加し、[+]で[Item1]を増やす
  3. それぞれ[Materiarl.Name]と[Convert Between Unit]に接続
    マテリアルと体積をリストにする
Watchで確認して、リストを確認します。

行列を入れ替えてExcelに出力

結果をエクセルに出力する前に行列を入れ替えます。
  1. [Core]>[List]>[Transpose]
  2. [Office]>[WriteToFile]
  3. [Core]>[Input]>[FilePath],[String],[Number],[Boolean]
  4. エクセルを開き、空のブックを作成して保存し、[FilePath]の[参照]を押して選択します。
  5. 下の図のように接続
    エクセルへ出力
これで、エクセルに容積が出力されます。
エクセルに出力
Revitは基本的にSolidモデラーですので、ネイティブの要素であれば、地形を除いて体積を持っています。したがって体積を求めることが可能であるというわけです。