皆様こんにちは
AMDlabの秋山です。
前回に引き続きZeroTouch Nodeの第4弾です。
今回は、ZeroTouch Nodeを使用して、Revitエレメント(コンポーネントファミリ)を配置する方法をお話していきます。
今回作成するノードは
1.壁ホストに窓配置
2.床ホストに家具配置
3.ホストなしで柱配置
の3つになります。
1.壁ホストに窓配置
以下が今回作成するコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
using Autodesk.DesignScript.Geometry; using Autodesk.Revit.DB; using Dynamo.Graph.Nodes; using RevitServices.Persistence; using RevitServices.Transactions; using Revit.Elements; using System; using System.Collections.Generic; using Autodesk.DesignScript.Runtime; namespace RevitCreation { public static class WindowPlacement { [IsVisibleInDynamoLibrary(true)] public static Revit.Elements.Element PlaceWindow( Revit.Elements.FamilyType windowTypeElement, Revit.Elements.Wall wallElement, Autodesk.DesignScript.Geometry.Point point, double sillHeightInMillimeters) { Document doc = DocumentManager.Instance.CurrentDBDocument; // Revit.Elements.FamilyType から Autodesk.Revit.DB.FamilySymbol に変換 var revitWindowType = windowTypeElement.InternalElement as Autodesk.Revit.DB.FamilySymbol; var revitWall = wallElement.InternalElement as Autodesk.Revit.DB.Wall; if (revitWindowType == null || revitWall == null || point == null) { throw new ArgumentException("Invalid WindowType, Wall, or Point provided."); } // 窓の位置をDynamoのPointからRevitのXYZに変換 XYZ windowPosition = new XYZ( UnitUtils.ConvertToInternalUnits(point.X, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(point.Y, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(point.Z, UnitTypeId.Millimeters) ); // 下枠高さをミリメートルからフィートに変換 double sillHeightInFeet = UnitUtils.ConvertToInternalUnits(sillHeightInMillimeters, UnitTypeId.Millimeters); TransactionManager.Instance.EnsureInTransaction(doc); // 窓の配置にはタイプをアクティブにする必要があります if (!revitWindowType.IsActive) { revitWindowType.Activate(); doc.Regenerate(); } // 窓を配置 Autodesk.Revit.DB.FamilyInstance window = doc.Create.NewFamilyInstance(windowPosition, revitWindowType, revitWall, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); // インスタンスパラメータとして下枠高さを設定 Autodesk.Revit.DB.Parameter sillHeightParam = window.LookupParameter("Sill Height"); if (sillHeightParam != null && !sillHeightParam.IsReadOnly) { sillHeightParam.Set(sillHeightInFeet); } TransactionManager.Instance.TransactionTaskDone(); // DynamoのRevitエレメントとして返す return window.ToDSType(true); } } } |
上記のコードを簡単に解説していきます。
まず初めに名前空間をインポートします。ライブラリやフレームワークの特定部分を参照するために記述します。
1 2 3 4 5 6 7 8 9 |
using Autodesk.DesignScript.Geometry; using Autodesk.Revit.DB; using Dynamo.Graph.Nodes; using RevitServices.Persistence; using RevitServices.Transactions; using Revit.Elements; using System; using System.Collections.Generic; using Autodesk.DesignScript.Runtime; |
クラスを定義します。
1 2 3 4 5 |
namespace RevitCreation { public static class WindowPlacement { [IsVisibleInDynamoLibrary(true)] |
メソッドの定義をします。
このメソッドは、指定された壁と位置に窓を配置します。
1 2 3 4 5 |
public static Revit.Elements.Element PlaceWindow( Revit.Elements.FamilyType windowTypeElement, Revit.Elements.Wall wallElement, Autodesk.DesignScript.Geometry.Point point, double sillHeightInMillimeters) |
次に、Revitエレメントを取得していきます。
Dynamoで受け取ったWindowTypeとWallをRevitAPIのオブジェクト(Autodesk.Revit.DB.FamilySymbolやAutodesk.Revit.DB.Wall)に変換します。
詳しくは前回の記事で説明しているので確認ください。
1 2 |
var revitWindowType = windowTypeElement.InternalElement as Autodesk.Revit.DB.FamilySymbol; var revitWall = wallElement.InternalElement as Autodesk.Revit.DB.Wall; |
次に、doc.Create.NewFamilyInstance()メソッドを使用して窓を配置します。このメソッドは様々な引数を設けることができますが、今回は窓の位置、窓のファミリタイプ、窓をホストする壁である赤枠を使用します。
こちらで詳細を確認できます。
1 2 |
// 窓を配置 Autodesk.Revit.DB.FamilyInstance window = doc.Create.NewFamilyInstance(windowPosition, revitWindowType, revitWall, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); |
コーディングが完了したら、Visual Studioでプロジェクトをビルドします。ビルドが成功すると、指定したプロジェクトフォルダ内の「bin\Debug」または「bin\Release」ディレクトリにDLLファイルが生成されます。
Dynamoを開き、[ファイル] タブから「ライブラリを読み込む」を選択し、生成したDLLファイルを選択してインポートします。
インポート後、新しいノード(カスタムノード)として「WindowPlacement.PlaceWindow」が利用可能になりましたので、配置してみます。
壁をホストに窓が配置されました。
続いては床をホストに家具を配置していきます。
2.床ホストに家具配置
以下が今回作成するコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
using Autodesk.DesignScript.Geometry; using Autodesk.Revit.DB; using Dynamo.Graph.Nodes; using RevitServices.Persistence; using RevitServices.Transactions; using Revit.Elements; using System; using Autodesk.DesignScript.Runtime; using Autodesk.Revit.DB.Structure; namespace RevitCreation { public static class FurniturePlacement { [IsVisibleInDynamoLibrary(true)] public static Revit.Elements.Element PlaceFurnitureOnFloor( Revit.Elements.FamilyType furnitureTypeElement, Revit.Elements.Element floorElement, Autodesk.DesignScript.Geometry.Point point) { Document doc = DocumentManager.Instance.CurrentDBDocument; // Revit.Elements.FamilyType から Autodesk.Revit.DB.FamilySymbol に変換 var revitFurnitureType = furnitureTypeElement?.InternalElement as Autodesk.Revit.DB.FamilySymbol; var revitFloor = floorElement?.InternalElement as Autodesk.Revit.DB.Floor; if (revitFurnitureType == null) { throw new ArgumentException("Invalid FurnitureType provided."); } if (revitFloor == null) { throw new ArgumentException("Invalid Floor provided."); } // 家具の位置をDynamoのPointからRevitのXYZに変換 XYZ furniturePosition = new XYZ( UnitUtils.ConvertToInternalUnits(point.X, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(point.Y, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(point.Z, UnitTypeId.Millimeters) ); TransactionManager.Instance.EnsureInTransaction(doc); // 家具ファミリの配置にはタイプをアクティブにする必要があります if (!revitFurnitureType.IsActive) { revitFurnitureType.Activate(); doc.Regenerate(); } // 家具ファミリを床にホストとして配置 Autodesk.Revit.DB.FamilyInstance furniture = doc.Create.NewFamilyInstance( furniturePosition, revitFurnitureType, revitFloor, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); TransactionManager.Instance.TransactionTaskDone(); // DynamoのRevitエレメントとして返す return furniture.ToDSType(true); } } } |
上記のコードを今回も簡単に解説していきます。窓の配置と内容が同じ箇所は省略します。
まず初めにクラスとメソッドの定義をします。
このメソッドは、家具を指定された床と位置に配置します。引数はDynamoのインプットになります。
1 2 3 4 5 6 7 8 9 |
namespace RevitCreation { public static class FurniturePlacement { [IsVisibleInDynamoLibrary(true)] public static Revit.Elements.Element PlaceFurnitureOnFloor( Revit.Elements.FamilyType furnitureTypeElement, Revit.Elements.Element floorElement, Autodesk.DesignScript.Geometry.Point point) |
次に家具を配置していきます。使用するメソッドは先ほどと同じもので、ホストとする対象を壁から床に変更します。
1 2 3 4 5 |
Autodesk.Revit.DB.FamilyInstance furniture = doc.Create.NewFamilyInstance( furniturePosition, revitFurnitureType, revitFloor, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); |
コーディングが完了したら、先ほど同様ビルドをし「FurniturePlacement.PlaceFurnitureOnFloor」を配置してみます。
床をホストに家具が配置されました。
最後にホストなしで柱を配置していきます。
3.ホストなしで柱配置
以下が今回作成するコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
using Autodesk.DesignScript.Geometry; using Autodesk.Revit.DB; using Dynamo.Graph.Nodes; using RevitServices.Persistence; using RevitServices.Transactions; using Revit.Elements; using System; using Autodesk.DesignScript.Runtime; using Autodesk.Revit.DB.Structure; namespace RevitCreation { public static class ColumnPlacement { [IsVisibleInDynamoLibrary(true)] public static Revit.Elements.Element PlaceColumn( Revit.Elements.FamilyType columnTypeElement, Revit.Elements.Level baseLevelElement, Revit.Elements.Level topLevelElement, Autodesk.DesignScript.Geometry.Point basePoint) { Document doc = DocumentManager.Instance.CurrentDBDocument; // Revit.Elements.FamilyType から Autodesk.Revit.DB.FamilySymbol に変換 var revitColumnType = columnTypeElement?.InternalElement as Autodesk.Revit.DB.FamilySymbol; var revitBaseLevel = baseLevelElement?.InternalElement as Autodesk.Revit.DB.Level; var revitTopLevel = topLevelElement?.InternalElement as Autodesk.Revit.DB.Level; if (revitColumnType == null) { throw new ArgumentException("Invalid ColumnType provided."); } if (revitBaseLevel == null) { throw new ArgumentException("Invalid Base Level provided."); } if (revitTopLevel == null) { throw new ArgumentException("Invalid Top Level provided."); } // 柱の基点をDynamoのPointからRevitのXYZに変換 XYZ columnBasePoint = new XYZ( UnitUtils.ConvertToInternalUnits(basePoint.X, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(basePoint.Y, UnitTypeId.Millimeters), UnitUtils.ConvertToInternalUnits(basePoint.Z, UnitTypeId.Millimeters) ); TransactionManager.Instance.EnsureInTransaction(doc); // 柱の配置にはタイプをアクティブにする必要があります if (!revitColumnType.IsActive) { revitColumnType.Activate(); doc.Regenerate(); } // 柱を配置 Autodesk.Revit.DB.FamilyInstance column = doc.Create.NewFamilyInstance( columnBasePoint, revitColumnType, revitBaseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column); // 柱の上部レベルを設定 Autodesk.Revit.DB.Parameter topLevelParam = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); if (topLevelParam != null && !topLevelParam.IsReadOnly) { topLevelParam.Set(revitTopLevel.Id); } TransactionManager.Instance.TransactionTaskDone(); // DynamoのRevitエレメントとして返す return column.ToDSType(true); } } } |
クラスとメソッドの定義をします。
このメソッドは、柱を指定された基準レベルと位置に配置し、設定した上部レベルまで伸ばします。
1 2 3 4 5 6 7 8 9 10 |
namespace RevitCreation { public static class ColumnPlacement { [IsVisibleInDynamoLibrary(true)] public static Revit.Elements.Element PlaceColumn( Revit.Elements.FamilyType columnTypeElement, Revit.Elements.Level baseLevelElement, Revit.Elements.Level topLevelElement, Autodesk.DesignScript.Geometry.Point basePoint) |
次に柱を配置していきます。使用するメソッドは先ほどと同じNewFamilyInstance()ですが引数が異なります。今回は赤枠のレベルを使用して基準レベルを設定します。
1 2 3 4 5 |
Autodesk.Revit.DB.FamilyInstance column = doc.Create.NewFamilyInstance( columnBasePoint, revitColumnType, revitBaseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column); |
次に上部レベルを設定します。
Autodesk.Revit.DB.ParameterというRevitのパラメータを扱うクラスのインスタンスをtopLevelParam という変数にし、 FAMILY_TOP_LEVEL_PARAM パラメータを格納します。
get_Parameter()メソッドはcolumn(柱のインスタンス)から特定のパラメータを取得するものです。
今回引数とするパラメータはビルトインパラメータ※1の1つですが、添付の様にRevitには多くのビルトインパラメータが存在します。その中から今回は赤枠のFAMILY_TOP_LEVEL_PARAM を使用します。
こちらで詳細を確認できます。
柱や壁などのRevit要素において、その上部がどのレベルまで到達するかを示すパラメータになります。
パラメータには読み込み専用のパラメータも存在するので読み込み可能なパラメータかどうかを判定をしています。
Revitのパラメータのプロパティ上でグレー表記になっているものは読み込みオンリーのパラメータです。
※1 ビルトインパラメータは組み込みパラメータとも呼ばれ、Revitに組み込まれている標準のパラメータのこと。
1 2 3 4 5 6 |
// 柱の上部レベルを設定 Autodesk.Revit.DB.Parameter topLevelParam = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); if (topLevelParam != null && !topLevelParam.IsReadOnly) { topLevelParam.Set(revitTopLevel.Id); } |
コーディングが完了したら、先ほど同様ビルドをし「ColumnPlacement.PlaceColumn」を配置してみます。
柱が作成されました。
今回は、ZeroTouch Nodeを使用して、Revitエレメント(コンポーネントファミリ)を配置する方法を説明しました。
次回は、第5弾で、ZeroTouch Nodeを使用してRevitドキュメント・パラメータを操作するお話をしていきます。
COMMENTS