#region Namespaces
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using OfficeOpenXml;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using OfficeOpenXml.Style;
using RoomInfo;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
#endregion
//当ソフトにはEPPlus4.5.3.3を使用しています。これはLGPLライセンスです。著作権はEPPlus Software社です。
namespace Seigousei
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
//電気モデルから動力、コンセント電源を全て抽出する
//機械モデルから機械設備機器を全て抽出して、電源種別、消費電力など抽出
//電気と機械で、機器番号、機器名、電気種別、容量を比較する。
//整合状態を判定し不整合箇所を黄色セルにしてExcelに出力する
//条件***************
//電気設備で対象とする[ファミリ名,シンボル名]
string[] elecTarget = new string[] { "20301_鍵付コンセント_露出型_200V", "20308_ジョイントボックス_強電用" };
//電気対象要素のリスト
List<ElecEquip> elecInstances = new List<ElecEquip>();
//機械設備で対象とするファミリ名とシンボル名
string[] mechTarget = new string[] { "07052_PAC-CK4_室内機_カセット形(4方向)", "07062_ACP-FRV(J)_室内機_床置(露出)立形(直吹)" };
//機械対象要素のリスト
List<MechEquip> mechInstances = new List<MechEquip>();
//*******************
//電気インスタンスを全て抽出する
FilteredElementCollector elecCol = new FilteredElementCollector(doc)
.OfClass(typeof(FamilyInstance))
.OfCategory(BuiltInCategory.OST_ElectricalFixtures);
//電気の対象ファミリ、タイプを絞る
for (int i = 0; i < elecTarget.Length; i++)
{
//Querryで要素絞る
var query = from element in elecCol.Cast<FamilyInstance>()
where (element.Symbol.Family.Name == elecTarget[i])
select element;
//抽出したものをリストにする
List<FamilyInstance> elecFamilyInstances = query.ToList<FamilyInstance>();
foreach(FamilyInstance elecInstance in elecFamilyInstances)
{
ElecEquip eEquip = new ElecEquip(elecInstance);
elecInstances.Add(eEquip);
}
}
//機械設備機器を全て抽出する
//インスタンスを全て抽出する
FilteredElementCollector mechCol = new FilteredElementCollector(doc)
.OfClass(typeof(FamilyInstance))
.OfCategory(BuiltInCategory.OST_MechanicalEquipment);
//機械の対象ファミリ、タイプを絞る
for (int i = 0; i < mechTarget.Length; i++)
{
//Querryで要素絞る
var query = from element in mechCol.Cast<FamilyInstance>()
where (element.Symbol.Family.Name == mechTarget[i])
select element;
//抽出したものをリストにする
List<FamilyInstance> mechFamilyInstances = query.ToList<FamilyInstance>();
foreach (FamilyInstance mechInstance in mechFamilyInstances)
{
MechEquip mEquip = new MechEquip(mechInstance);
mechInstances.Add(mEquip);
}
}
//電気と機械で、機器番号、機器名、電気種別、容量を比較する。
//「機器記号」をキーとして機械と電気の対応関係を確認する
//表形式のデータを扱うためにDataTableを作成する
var datatable = new DataTable("tblData");
//列名、型を設定する
datatable.Columns.Add("M 記号", typeof(string));//0
datatable.Columns.Add("M ファミリ名", typeof(string));//1
datatable.Columns.Add("M タイプ名", typeof(string));//2
datatable.Columns.Add("M 極数", typeof(int));//3
datatable.Columns.Add("M 相", typeof(int));//4
datatable.Columns.Add("M 電圧", typeof(double));//5
datatable.Columns.Add("M 消費電力_冷房", typeof(double));//6
datatable.Columns.Add("M 消費電力_暖房", typeof(double));//7
datatable.Columns.Add("M 位置座標", typeof(string));//8
datatable.Columns.Add("E 記号", typeof(string));//9
datatable.Columns.Add("E ファミリ名", typeof(string));//10
datatable.Columns.Add("E タイプ名", typeof(string));//11
datatable.Columns.Add("E 極数", typeof(int));//12
datatable.Columns.Add("E 相", typeof(int));//13
datatable.Columns.Add("E 電圧", typeof(double));//14
datatable.Columns.Add("E 皮相電力", typeof(double));//15
datatable.Columns.Add("E 位置座標", typeof(string));//16
datatable.Columns.Add("距離mm", typeof(double));//17
//機器リストからテーブル入力
foreach (MechEquip eqp in mechInstances)
{
var row = datatable.NewRow();
//機械設備のデータ入力 、パラメータが存在しない場合のエラーをもっと考慮する必要ある
if (eqp.Kigou != null) { row[0] = eqp.Kigou; } else { row[0] = DBNull.Value; }
if (eqp.Family != null) { row[1] = eqp.Family; } else { row[1] = DBNull.Value; }
if (eqp.Type != null) { row[2] = eqp.Type; } else { row[2] = DBNull.Value; }
if (eqp.Pole != null) { row[3] = eqp.Pole; } else { row[3] = DBNull.Value; }
if (eqp.Phase != null) { row[4] = eqp.Phase; } else { row[4] = DBNull.Value; }
row[5] = Math.Round(UnitUtils.ConvertFromInternalUnits(KUtil.tryDouble(eqp.Voltage), UnitTypeId.Volts), 0);
row[6] = Math.Round(UnitUtils.ConvertFromInternalUnits(KUtil.tryDouble(eqp.ReibouShouhidenryoku), UnitTypeId.Watts), 0);
row[7] = Math.Round(UnitUtils.ConvertFromInternalUnits(KUtil.tryDouble(eqp.DanbouShouhidenryoku), UnitTypeId.Watts), 0);
row[8] = eqp.Loation.ToString();
//対応する電気があったらデータを代入、パラメータが存在しない場合のエラーをもっと考慮する必要ある、対応ないものの処理考慮必要
foreach (ElecEquip elecEquip in elecInstances)
{
if(elecEquip.Kigou != null)
{
if (elecEquip.Kigou == eqp.Kigou)
{
if (elecEquip.Kigou != null) { row[9] = elecEquip.Kigou; } else { row[9] = DBNull.Value; }
if (elecEquip.Family != null) { row[10] = elecEquip.Family; } else { row[10] = DBNull.Value; }
if (elecEquip.Type != null) { row[11] = elecEquip.Type; } else { row[11] = DBNull.Value; }
if (elecEquip.Pole != null) { row[12] = elecEquip.Pole; } else { row[12] = DBNull.Value; }
if (elecEquip.Phase != null) { row[13] = elecEquip.Phase; } else { row[13] = DBNull.Value; }
row[14] = UnitUtils.ConvertFromInternalUnits(KUtil.tryDouble(elecEquip.Voltage), UnitTypeId.Volts);
row[15] = Math.Round(UnitUtils.ConvertFromInternalUnits(KUtil.tryDouble(elecEquip.Hisoudenryoku), UnitTypeId.Watts), 0);
row[16] = elecEquip.Loation.ToString();
row[17] = Distance(row[8].ToString(), row[16].ToString());//距離
}
}
}
datatable.Rows.Add(row);
}
//次に、室一覧をExcelに保存するためのダイアログを開く
System.Windows.Forms.SaveFileDialog saveFileDialog = KUtil.SaveExcel();
String filename = saveFileDialog.FileName;
//保存ファイル名が正常に入力されていればExcel保存実行
if (filename != "")
{
//ユーザーが指定したExcelファイル名でファイルストリームを取得する
FileStream fs = (FileStream)saveFileDialog.OpenFile();
//ExcelPackageを作成する
using (ExcelPackage package = new ExcelPackage(fs))
{
//ExcelのワークシートにRoomsという名称のシートを作る
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Seigousei");
//Excelの一番左上の位置A1からDataTableを一気に流し込む
worksheet.Cells["A1"].LoadFromDataTable(datatable, true);
//データの範囲を取得する
int maxRow = worksheet.Dimension.Rows;
int maxColomun = worksheet.Dimension.Columns;
//整合性をチェックする、違うところはセルを黄色にする
for (int i = 2; i <= maxRow; i++)//インデックスに注意 データは2行目から存在する
{
//Pole
if (worksheet.Cells[i, 4].Value.ToString() != worksheet.Cells[i, 13].Value.ToString())
{
CellColor(worksheet, i, 13, System.Drawing.Color.Yellow);
}
//相
if (worksheet.Cells[i, 5].Value != worksheet.Cells[i, 14].Value)
{
CellColor(worksheet, i, 14, System.Drawing.Color.Yellow);
}
//電圧
if (worksheet.Cells[i, 6].Value.ToString() != worksheet.Cells[i, 15].Value.ToString())
{
CellColor(worksheet, i, 15, System.Drawing.Color.Yellow);
}
//電力
double reibouWatt = Convert.ToDouble(worksheet.Cells[i, 7].Value.ToString());
double danbouWatt = Convert.ToDouble(worksheet.Cells[i, 8].Value.ToString());
double denkiShouhi = Convert.ToDouble(worksheet.Cells[i, 16].Value.ToString());
if (Math.Max(reibouWatt, danbouWatt) != denkiShouhi)
{
CellColor(worksheet, i, 16, System.Drawing.Color.Yellow);
}
//距離
if (Convert.ToDouble(worksheet.Cells[i, 18].Value.ToString()) > 3000 )
{
CellColor(worksheet, i, 18, System.Drawing.Color.Yellow);
}
}
//列幅はオートフィットさせる。最後に実行したほうがよい
for (int i = 0; i < maxColomun; i++)
{
worksheet.Column(i + 1).AutoFit();
worksheet.Column(i + 1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
}
//Excel編集の終了 Excelファイルを保存する
package.Save();
//正常時にメッセージを出す
TaskDialog.Show("正常終了", "Excel出力は正常終了。この後Excelファイルを開きます。");
//確認のためにExcelを起動して保存したファイルを開く
Process process = new Process();
process.StartInfo.FileName = "excel.exe";
process.StartInfo.Arguments = saveFileDialog.FileName;
process.Start();
}
}
return Result.Succeeded;
}
//Excelのセルに着色する
private void CellColor(ExcelWorksheet sheet, int row, int col, System.Drawing.Color color)
{
sheet.Cells[row , col].Style.Fill.PatternType = ExcelFillStyle.Solid;
sheet.Cells[row , col].Style.Fill.BackgroundColor.SetColor(color);
}
//2点間の距離を計算する
private double Distance(string obj1, string obj2)
{
double distance;
obj1 = obj1.Trim().Replace("(", "").Replace(")", "");
obj2 = obj2.Trim().Replace("(", "").Replace(")", "");
string[] obj11 = obj1.Split(',');
double x1 = double.Parse(obj11[0]);double y1 = double.Parse(obj11[1]);double z1 = double.Parse(obj11[2]);
string[] obj21 = obj2.Split(',');
double x2 = double.Parse(obj21[0]);double y2 = double.Parse(obj21[1]);double z2= double.Parse(obj21[2]);
distance = Math.Sqrt(Math.Abs(x1 - x2)* Math.Abs(x1 - x2) + Math.Abs(y1 - y2) * Math.Abs(y1 - y2)+ Math.Abs(z1 - z2) * Math.Abs(z1 - z2));
distance = UnitUtils.ConvertFromInternalUnits(distance, UnitTypeId.Millimeters);//ミリメーター
distance = Math.Round(distance);
return distance;
}
}
public class MechEquip
{
public FamilyInstance Instance { private set; get; }
public XYZ Loation { private set; get; }
public string Kigou { private set; get; }
public string Family { private set; get; }
public string Type { private set; get; }
public string Pole { private set; get; }
public string Phase { private set; get; }
public string Voltage { private set; get; }
public string ReibouShouhidenryoku { private set; get; }
public string DanbouShouhidenryoku { private set; get; }
public MechEquip(FamilyInstance instance)
{
//パラメータは値が無い場合にはnullになる
//ファミリとタイプ
FamilySymbol familySymbol = instance.Symbol;
Family family = familySymbol.Family;
//インスタンス
this.Instance = instance;
//現在のエレメントの位置
this.Loation = KUtil.GetElementLocation(instance);
//機械設備のKM機器記号
this.Kigou = KUtil.ShowParameter(instance, "記号");
//ファミリ名
this.Family = family.Name;
//タイプ名
this.Type = familySymbol.Name;
//以下はファミリシンボル(タイプ)から抽出する(タイプパラメータのため)
//極数
this.Pole = KUtil.ShowParameter(familySymbol, "極数");
//相
this.Phase = KUtil.ShowParameter(familySymbol, "相");
//電圧
this.Voltage = KUtil.ShowParameter(familySymbol, "電圧");
//機械設備の電気 消費電力 冷房時
this.ReibouShouhidenryoku = KUtil.ShowParameter(familySymbol, "消費電力_冷房");
//機械設備の電気 消費電力 暖房時
this.DanbouShouhidenryoku = KUtil.ShowParameter(familySymbol, "消費電力_暖房");
}
}
public class ElecEquip
{
public FamilyInstance Instance { private set; get; }
public XYZ Loation { private set; get; }
public string Kigou { private set; get; }
public string Family { private set; get; }
public string Type { private set; get; }
public string Pole { private set; get; }
public string Phase { private set; get; }
public string Voltage { private set; get; }
public string Hisoudenryoku { private set; get; }
public ElecEquip(FamilyInstance instance)
{
//パラメータは値が無い場合にはnullになる
//ファミリとタイプ
FamilySymbol familySymbol = instance.Symbol;
Family family = familySymbol.Family;
//インスタンス
this.Instance = instance;
//現在のエレメントの位置
this.Loation = KUtil.GetElementLocation(instance);
//電気設備のKM機器記号
this.Kigou = KUtil.ShowParameter(instance, "記号");
//ファミリ名
this.Family = family.Name;
//タイプ名
this.Type = familySymbol.Name;
//電気設備の電気 極数
this.Pole = KUtil.ShowParameter(familySymbol, "極数");
//電気設備の相
this.Phase = KUtil.ShowParameter(familySymbol, "相");
//電気設備の電圧
this.Voltage = KUtil.ShowParameter(familySymbol, "電圧");
//電気設備の消費電力(皮相電力)
this.Hisoudenryoku = KUtil.ShowParameter(instance, "皮相電力");
}
}
}
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
namespace RoomInfo
{
public static class KUtil
{
//壁の線分(Curve)を抽出するための関数。連続した2マス以上の線分を見つける
public static IList<Curve> FindContinuousOnes(int[,] array, int a)
{
//結果として返す変数
IList<Curve> curves = new List<Curve>();
//行列のサイズを取得
int rows = array.GetLength(0);
int cols = array.GetLength(1);
// 横方向の連続を確認
for (int i = 0; i < rows; i++)
{
double startOffsetX = 0;
double endOffsetX = 0;
int start = -1;
for (int j = 0; j < cols; j++)
{
if (array[i, j] == a && start == -1)
{
// 連続の開始点を記録
start = j;
if (j >0)
{
if (a == 2 && array[i, j - 1] == 1)//******内壁を追跡中に左が外壁1だったら1つ減じる。(i-1>=0とする)
{
startOffsetX = -1;
}
}
}
else if (array[i, j] != a && start != -1)
{
// 連続が終了した場合
if (j - start > 1) // 2つ以上の連続のみ出力
{
//"横方向の連続はデータ配列上で: ({i}, {start}) から ({i}, {j - 1})"
//Revitモデル上では行はY軸、列はX軸にあたるので入れ替え。さらにY軸は大小の方向が逆なので
//最大値からiを引いている
//XYZ startPoint = new XYZ(i, start, 0);
//XYZ endPoint = new XYZ(i, j - 1, 0);
if (a == 2 && array[i, j] == 1)//******内壁を追跡中に右が外壁だったら1つ増やす。
{
endOffsetX = 1;
}
XYZ startPoint = new XYZ(start+ startOffsetX, -i , 0);
XYZ endPoint = new XYZ((j - 1)+ endOffsetX, -i, 0);
Line line = Line.CreateBound(startPoint, endPoint);
curves.Add(line);
startOffsetX = 0;//オフセットのリセット
endOffsetX = 0;
}
start = -1; // 開始点をリセット
}
}
// 行末まで連続が続いた場合の処理
if (start != -1 && cols - start > 1) // 行末までの連続が2つ以上の場合
{
//"横方向の連続はデータ配列上で: ({i}, {start}) から ({i}, {cols - 1})");
//Revitモデル上では行はY軸、列はX軸にあたるので入れ替え。さらにY軸は大小の方向が逆なので
//最大値からiを引いている
//XYZ startPoint = new XYZ(i, start, 0);
//XYZ endPoint = new XYZ(i, cols - 1, 0);
XYZ startPoint = new XYZ(start , -i, 0);
XYZ endPoint = new XYZ((cols - 1) , -i, 0);
Line line = Line.CreateBound(startPoint, endPoint);
curves.Add(line);
}
}
// 縦方向の連続を確認
for (int j = 0; j < cols; j++)
{
double startOffsetY = 0;
double endOffsetY = 0;
int start = -1;
for (int i = 0; i < rows; i++)
{
if (array[i, j] == a && start == -1)
{
// 連続の開始点を記録
start = i;
if (i > 0)
{
if (a == 2 && array[i-1, j] == 1)//******内壁を追跡中に上が外壁1だったら1つ減じる。(i-1>=0とする)
{
startOffsetY = -1;
}
}
}
else if (array[i, j] != a && start != -1)
{
// 連続が終了した場合
if (i - start > 1) // 2つ以上の連続のみ出力
{
//{start}, {j}) から ({i - 1}, {j})
//Revitモデル上では行はY軸、列はX軸にあたるので入れ替え。さらにY軸は大小の方向が逆なので
//最大値からiを引いている
//XYZ startPoint = new XYZ(start, j, 0);
//XYZ endPoint = new XYZ(i - 1, j, 0);
if (a == 2 && array[i, j] == 1)//******内壁を追跡中に下が外壁だったら1つ増やす。
{
endOffsetY = 1;
}
XYZ startPoint = new XYZ(j , -start- startOffsetY, 0);//方向が逆であることに注意
XYZ endPoint = new XYZ(j , -(i - 1) - endOffsetY, 0);//同上
Line line = Line.CreateBound(startPoint, endPoint);
curves.Add(line);
}
start = -1; // 開始点をリセット
}
}
// 列末まで連続が続いた場合の処理
if (start != -1 && rows - start > 1) // 列末までの連続が2つ以上の場合
{
//"横方向の連続はデータ配列上で: ({start}, {j}) から ({rows - 1}, {j})");
//Revitモデル上では行はY軸、列はX軸にあたるので入れ替え。さらにY軸は大小の方向が逆なので
//最大値からiを引いている
//XYZ startPoint = new XYZ(start, j, 0);
//XYZ endPoint = new XYZ(rows - 1, j, 0);
XYZ startPoint = new XYZ(j , -start , 0);
XYZ endPoint = new XYZ(j , -(rows - 1), 0);
Line line = Line.CreateBound(startPoint, endPoint);
curves.Add(line);
}
}
return curves;
}
//Excelファイルを読むためのダイアログを表示する
public static string OpenExcel()
{
string fileName = "";
//OpenFileDialog
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Title = "ファイル選択";
openFileDialog.Filter = "ExcelFiles | *.xls;*.xlsx;*.xlsm";
//初期表示フォルダはデスクトップ
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
//ファイル選択ダイアログを開く
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
fileName = openFileDialog.FileName;
}
}
return fileName;
}
public static SaveFileDialog SaveExcel()
{
//Excelファイルに保存するためにファイル名をユーザーにきくダイアログを表示する
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "ExcelFiles | *.xls;*.xlsx;*.xlsm";
saveFileDialog.Title = "EXCELファイル保存";
saveFileDialog.ShowDialog();
//ユーザーがファイル拡張子入れない場合にはxlsになってしまう。あとで開くときに警告が出るのであらかじめxlsxに変更しておく
//filenameはユーザーが何も入れずにキャンセルボタンを押すと空になってしまう。
String filename = saveFileDialog.FileName;
//半角空白が含まれているとExcelアプリ起動時にファイルが見つからないエラーが出る場合あるので半角空白をアンダースコアに置き換える■
filename = filename.Replace(" ", "_");
if (filename.IndexOf("xlsx") < 0)
{
//SaveFileDialogオブジェクトのFileName属性も変更しておく
saveFileDialog.FileName = filename.Split('.')[0] + ".xlsx";
}
return saveFileDialog;
}
//ミリメーターを内部単位に変換する
public static double CVmmToInt(double x)
{
return UnitUtils.ConvertToInternalUnits(x, UnitTypeId.Millimeters);
}
//内部単位をミリメーターに変換する
public static double CVintTomm(double x)
{
return UnitUtils.ConvertFromInternalUnits(x, UnitTypeId.Millimeters);
}
//窓やドアを取り付ける
public static void CreateWindowAndDoor(UIDocument uidoc, Document doc, string fsFamilyName,
string fsName, string levelName, double xCoord, double yCoord, double offset)
{
// LINQ 指定のファミリシンボルを探して取得する
FamilySymbol familySymbol = (from fs in new FilteredElementCollector(doc).
OfClass(typeof(FamilySymbol)).
Cast<FamilySymbol>()
where (fs.Family.Name == fsFamilyName && fs.Name == fsName)
select fs).First();
// LINQ 指定のレベルを取得する
Level level = (from lvl in new FilteredElementCollector(doc).
OfClass(typeof(Level)).
Cast<Level>()
where (lvl.Name == levelName)
select lvl).First();
// 座標mmを内部単位に変換する
double x = xCoord;
double y = yCoord;
XYZ xyz = new XYZ(x, y, level.Elevation+ offset);
//部材を挿入する壁で、最も近いホスト壁を取得する
//壁を全部取得する
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfClass(typeof(Wall));
//当該レベルにある壁だけ抽出する。リストにする
List<Wall> walls = collector.Cast<Wall>().Where(wl => wl.LevelId == level.Id).ToList();
Wall wall = null;
//距離の初期値を最大値にしておく
double distance = double.MaxValue;
//壁を全部調べて、最も近いホスト壁を抽出する
foreach (Wall w in walls)
{
//壁のカーブからの最短直線距離を測る
double proximity = (w.Location as LocationCurve).Curve.Distance(xyz);
//これまでの値よりも小さい場合には、より接近した壁だと思われるので、その壁をホスト候補とする
if (proximity < distance)
{
distance = proximity;
wall = w;
}
}
// Create window.
//using (Transaction t = new Transaction(doc, "Create window and door"))
//{
//t.Start();
if (!familySymbol.IsActive)
{
//ファミリシンボルがアクティブではないので、アクティブにする
familySymbol.Activate();
doc.Regenerate();
}
// 部材の配置
// ホストであるwallを指定しない場合には部材はホストなし
FamilyInstance window = doc.Create.NewFamilyInstance(xyz, familySymbol, wall, level,StructuralType.NonStructural);
//t.Commit();
//}
//string prompt = "部材は配置されました";
//TaskDialog.Show("Revit", prompt);
}
//目的のレベル(階)を探して返す
public static Level GetLevel(Document doc, string levelName)
{
Level result = null;
//エレメントコレクターの作成
FilteredElementCollector collector = new FilteredElementCollector(doc);
//レベルを全て検出する
ICollection<Element> collection = collector.OfClass(typeof(Level)).ToElements();
//目的のレベルを探す
foreach (Element element in collection)
{
Level level = element as Level;
if (null != level)
{
if (level.Name == levelName)
{
result = level;
}
}
}
return result;
}
//床作成のための外壁座標を取得する(数字が入っているセルの座標を取得する)
public static SortedDictionary<int, XYZ> FindFloorLine(string[,] array)
{
//自動ソートされるディクショナリ
var dict = new SortedDictionary<int, XYZ>();
//行列のサイズを取得
int rows = array.GetLength(0);
int cols = array.GetLength(1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
int numeric;
if (int.TryParse(array[i, j], out numeric))
{
//dict.Add(numeric, new XYZ(i, j, 0));
dict.Add(numeric, new XYZ(j , -i, 0));
}
}
}
return dict;
}
//床のためのカーブを作る
public static IList<XYZ> FindSymbolPosition(string[,] array, string symbol)
{
//自動ソートされるディクショナリ
var result = new List<XYZ>();
//行列のサイズを取得
int rows = array.GetLength(0);
int cols = array.GetLength(1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if(array[i, j] != null)
{
//シンボルと一致したらリストに入れる
if (array[i, j].Equals(symbol))
{
result.Add(new XYZ(j, -i, 0));
}
}
}
}
return result;
}
public static void CreateColumn(Document doc, String levelName1,string levelName2,string columnFamilyName, string columnSymbolName,double x,double y)
{
string message = null;
try
{
// 柱のファミリとタイプを取得
FilteredElementCollector collector = new FilteredElementCollector(doc);
FamilySymbol columnSymbol = collector
.OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>()
.FirstOrDefault(q => q.Name == columnSymbolName && q.Family.Name == columnFamilyName);
if (columnSymbol == null)
{
message = "指定された柱のファミリまたはタイプが見つかりません。";
}
// レベルを取得
Level level1 = GetLevel(doc, levelName1);
Level level2 = GetLevel(doc, levelName2);
if (level1 == null || level2 == null)
{
message = "指定されたレベルが見つかりません。";
}
// トランザクションを開始
//using (Transaction trans = new Transaction(doc, "Place Column"))
//{
//trans.Start();
// ファミリシンボルをアクティブにする
if (!columnSymbol.IsActive)
{
columnSymbol.Activate();
}
// 柱を作成
XYZ location = new XYZ(x, y, 0);
FamilyInstance column = doc.Create.NewFamilyInstance(location, columnSymbol, level1, Autodesk.Revit.DB.Structure.StructuralType.Column);
// 上部の拘束を設定
Parameter topLevelParam = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
if (topLevelParam != null && !topLevelParam.IsReadOnly)
{
topLevelParam.Set(level2.Id);
}
//trans.Commit();
//}
}
catch (Exception ex)
{
message = ex.Message;
}
if (message != null)
{
TaskDialog.Show("Error", message);
}
}
public static void CreateGrids(Document doc)
{
double y1 = -100;
double y2 = 30;
double[] x = {2,34,74,114,147 };
string[] symbX = {"1","2","3","4","5" };
double x1 = -30;
double x2 = 180;
double[] y = { -2, -33, -66 };
string[] symbY = { "A", "B", "C"};
for (int i = 0; i < x.Length; i++)
{
XYZ start = new XYZ(x[i], y1, 0);
XYZ end = new XYZ(x[i], y2, 0);
Line line = Line.CreateBound(start, end);
Grid grid = Grid.Create(doc, line);
grid.Name = symbX[i];
}
for (int i = 0; i < y.Length; i++)
{
XYZ start = new XYZ(x1, y[i], 0);
XYZ end = new XYZ(x2, y[i], 0);
Line line = Line.CreateBound(start, end);
Grid grid = Grid.Create(doc, line);
grid.Name = symbY[i];
}
}
public static bool SetParameterInt(Element elem, string header, int val)
{
IList<Parameter> parameters = new List<Parameter>();
parameters = elem.GetOrderedParameters();
foreach (Parameter param in parameters)
{
string name = param.Definition.Name;
if (name.Equals(header))
{
param.Set(val);
return true;
}
}
return false;
}
public static bool SetParameterDouble(Element elem, string header, double val)
{
IList<Parameter> parameters = new List<Parameter>();
parameters = elem.GetOrderedParameters();
foreach (Parameter param in parameters)
{
string name = param.Definition.Name;
if (name.Equals(header))
{
param.Set(val);
return true;
}
}
return false;
}
public static string ShowParameter(Element elem, string name)
{
IList<Parameter> parameters = new List<Parameter>();
parameters = elem.GetOrderedParameters();
foreach (Parameter param in parameters)
{
string paramName = param.Definition.Name;
if (paramName.Equals(name))
{
return ParameterToString(param);
}
}
return null;
}
public static double tryDouble(string st)
{
double result;
try
{
result = double.Parse(st);
return result;
}
catch (Exception e)
{
string dummy = e.Message;
return 0.0;
}
}
public static int tryInt(string st)
{
int result;
try
{
result = int.Parse(st);
return result;
}
catch (Exception e)
{
string dummy = e.Message;
return 0;
}
}
public static XYZ GetElementLocation(Element e)
{
XYZ p = null;
var loc = e.Location;
if (null != loc)
{
if (loc is LocationPoint lp)
{
p = lp.Point;
}
}
return p;
}
public static string ParameterToString(Parameter param)
{
string val = null;
if (param == null)
{
return val;
}
switch (param.StorageType)
{
case StorageType.Double:
double dVal = param.AsDouble();
val = dVal.ToString();
break;
case StorageType.Integer:
int iVal = param.AsInteger();
val = iVal.ToString();
break;
case StorageType.String:
string sVal = param.AsString();
val = sVal;
break;
case StorageType.ElementId:
ElementId idVal = param.AsElementId();
val = idVal.IntegerValue.ToString();
break;
case StorageType.None:
break;
default:
break;
}
return val;
}
}
}