Revit二次開發——讀取構件的材料外觀資訊
阿新 • • 發佈:2019-02-05
如有不明白,請qq254033230詢問。
revit讀取材料的外觀資訊不能通過lookup來搞定,所以讀取起來稍微有點麻煩。但是在revit二次開發的官方基礎教程裡有相關的解釋。
這裡就以一個牆體為例,讀取牆體材料的所有外觀資訊(如下圖)。這裡主要針對autodesk的官方材料庫來說的。對於非官方材料庫的,下面的程式碼裡被註釋掉的可以參考一下。其實讀取材料的原理比較簡單,過程如下:
1)獲取材料的ID,ICollection<ElementId> matId = elem.GetMaterialIds(true);
2)// 讀取revit標準材質庫
AssetSet objlibraryAsset = revitApp.get_Assets(AssetType.Appearance);
3)從CompoundStructureLayer中獲得材料
4)分兩種情況讀取材料。
對於 APT_Asset和APT_Reference這兩種型別還需要再次遞迴。具體程式碼如下:
這其中還有一個往資料庫中讀取材料性質的類,這個類有兩個作用:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Utility; using System.IO; namespace 讀取牆體材料 { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)] [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] public class MyClass : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Document revitDoc = commandData.Application.ActiveUIDocument.Document; //取得文件 Application revitApp = commandData.Application.Application; //取得應用程式 UIDocument uiDoc = commandData.Application.ActiveUIDocument; Selection sel = uiDoc.Selection; Reference ref1 = sel.PickObject(ObjectType.Element, "選擇一個族例項"); Element elem = revitDoc.GetElement(ref1); // 讀取revit標準材質庫 AssetSet objlibraryAsset = revitApp.get_Assets(AssetType.Appearance); Wall wall = elem as Wall; ICollection<ElementId> matId = elem.GetMaterialIds(true); #region 從elementId中獲得材料,這種方法獲得的是主材 //foreach (var item in matId) //{ // TaskDialog.Show("REVIT", item.ToString()); // Material mat2 = revitDoc.GetElement(item) as Material; //從elementId中獲得材料 //} #endregion #region 從CompoundStructureLayer中獲得材料,這種方法可以獲得與該元素相關的全部材料 WallType wallType = wall.WallType; CompoundStructure compoundStructure = wallType.GetCompoundStructure(); IList<CompoundStructureLayer> layers = compoundStructure.GetLayers(); ReadAssetProperty readAssetProperty = new ReadAssetProperty(); foreach (var item in layers) { Material mat2 = revitDoc.GetElement(item.MaterialId) as Material; // TaskDialog.Show("REVIT", mat2.Name.ToString()+ mat2.Id); ElementId assetElementId = mat2.AppearanceAssetId; if(assetElementId!=ElementId.InvalidElementId) { //獲取外觀元素 AppearanceAssetElement appearanceAssetElement = revitDoc.GetElement(assetElementId) as AppearanceAssetElement; //讀寫外觀元素 Asset currentAsset = appearanceAssetElement.GetRenderingAsset(); // TaskDialog.Show("revit", currentAsset.AssetType.ToString() + ";" + currentAsset.LibraryName.ToString() // + ";" + currentAsset.Title.ToString()+";" + currentAsset.Size.ToString()); ////外觀子元素 //IList<AssetProperty> listProperty=new List<AssetProperty>() ; //for(int i=0;i<currentAsset.Size;i++) //{ // listProperty.Add(currentAsset[i]); //} //string info = ""; //foreach(var item2 in listProperty) //{ // info += item2.Name.ToString()+ "\n"; //} //TaskDialog.Show("revit", info); ReadAsset(currentAsset, objlibraryAsset, readAssetProperty, assetElementId.ToString()); } } #endregion Form1 form = new Form1(); form.ShowDialog(); return Result.Succeeded; } public void ReadAsset(Asset currentAsset, AssetSet objlibraryAsset, ReadAssetProperty readAssetProperty,string matId) { //歐特克的外觀子元素 IList<AssetProperty> listProperty = new List<AssetProperty>(); if (currentAsset.Size == 0) { foreach (Asset objCurrentAsset in objlibraryAsset) { if (objCurrentAsset.Name == currentAsset.Name && objCurrentAsset.LibraryName == currentAsset.LibraryName) { for (int i = 0; i < objCurrentAsset.Size; i++) { listProperty.Add(objCurrentAsset[i]); } foreach (var item2 in listProperty) { ReadAutodeskAssetProperty(item2, readAssetProperty, objlibraryAsset,matId); } } } } else { for (int i = 0; i < currentAsset.Size; i++) { listProperty.Add(currentAsset[i]); } foreach (var item2 in listProperty) { ReadAutodeskAssetProperty(item2, readAssetProperty, objlibraryAsset, matId); } } } public void ReadAutodeskAssetProperty(AssetProperty assetProperty, ReadAssetProperty readAssetProperty, AssetSet objlibraryAsset, string matId) { switch (assetProperty.Type) { case AssetPropertyType.APT_Integer: var assetPropertyInt = assetProperty as AssetPropertyInteger; if(readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyInt.Value.ToString()); } break; case AssetPropertyType.APT_Distance: var assetPropertyDistance = assetProperty as AssetPropertyDistance; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyDistance.Value.ToString()); } break; case AssetPropertyType.APT_Double: var assetPropertyDouble = assetProperty as AssetPropertyDouble; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyDouble.Value.ToString()); } break; case AssetPropertyType.APT_DoubleArray2d: var assetPropertyDoubleArray2d = assetProperty as AssetPropertyDoubleArray2d; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyDoubleArray2d.Value.ToString()); } break; case AssetPropertyType.APT_DoubleArray4d: var assetPropertyDoubleArray4d = assetProperty as AssetPropertyDoubleArray4d; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { string value4d = assetPropertyDoubleArray4d.Value.get_Item(0).ToString() + "," + assetPropertyDoubleArray4d.Value.get_Item(1).ToString() + "," + assetPropertyDoubleArray4d.Value.get_Item(2).ToString() + "," + assetPropertyDoubleArray4d.Value.get_Item(3).ToString(); readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), value4d); } break; case AssetPropertyType.APT_String: var assetPropertyString = assetProperty as AssetPropertyString; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyString.Value); } break; case AssetPropertyType.APT_Boolean: var assetPropertyBoolean = assetProperty as AssetPropertyBoolean; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyBoolean.Value.ToString()); } break; case AssetPropertyType.APT_Double44: var assetPropertyDouble44 = assetProperty as AssetPropertyDoubleArray4d; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), assetPropertyDouble44.Value.ToString()); } break; case AssetPropertyType.APT_List: AssetPropertyList propList = assetProperty as AssetPropertyList; IList<AssetProperty> subProps = propList.GetValue(); if (subProps.Count == 0) break; switch (subProps[0].Type) { case AssetPropertyType.APT_Integer: foreach (AssetProperty subProp in subProps) { AssetPropertyInteger intProp = subProp as AssetPropertyInteger; if (readAssetProperty.CheckMaterialMxExists(matId, assetProperty.Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, assetProperty.Name, assetProperty.Type.ToString(), intProp.Value.ToString()); } } break; } break; case AssetPropertyType.APT_Asset: var assetPropertyAsset = assetProperty as Asset; ReadAsset(assetPropertyAsset, objlibraryAsset, readAssetProperty,matId); break; case AssetPropertyType.APT_Reference: var assetPropertyReference = assetProperty as AssetPropertyReference; IList<AssetProperty> listProperty2 = assetPropertyReference.GetAllConnectedProperties(); foreach (var item3 in listProperty2) { var AssetProperty3 = item3 as Asset; for (int i = 0; i < AssetProperty3.Size; i++) { switch (AssetProperty3[i].Type) { case AssetPropertyType.APT_Integer: var assetPropertyInt2 = AssetProperty3[i] as AssetPropertyInteger; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyInt2.Value.ToString()); } break; case AssetPropertyType.APT_Distance: var assetPropertyDistance2 = AssetProperty3[i] as AssetPropertyDistance; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyDistance2.Value.ToString()); } break; case AssetPropertyType.APT_Double: var assetPropertyDouble2 = AssetProperty3[i] as AssetPropertyDouble; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyDouble2.Value.ToString()); } break; case AssetPropertyType.APT_DoubleArray2d: var assetPropertyDoubleArray2d2 = AssetProperty3[i] as AssetPropertyDoubleArray2d; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyDoubleArray2d2.Value.ToString()); } break; case AssetPropertyType.APT_DoubleArray4d: var assetPropertyDoubleArray4d2 = AssetProperty3[i] as AssetPropertyDoubleArray4d; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyDoubleArray4d2.Value.ToString()); } break; case AssetPropertyType.APT_String: var assetPropertyString2 = AssetProperty3[i] as AssetPropertyString; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyString2.Value.ToString()); } break; case AssetPropertyType.APT_Boolean: var assetPropertyBoolean2 = AssetProperty3[i] as AssetPropertyBoolean; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyBoolean2.Value.ToString()); } break; case AssetPropertyType.APT_Double44: var assetPropertyDouble442 = AssetProperty3[i] as AssetPropertyDoubleArray4d; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), assetPropertyDouble442.Value.ToString()); } break; case AssetPropertyType.APT_List: AssetPropertyList propList2 = AssetProperty3[i] as AssetPropertyList; IList<AssetProperty> subProps2 = propList2.GetValue(); if (subProps2.Count == 0) break; switch (subProps2[0].Type) { case AssetPropertyType.APT_Integer: foreach (AssetProperty subProp in subProps2) { AssetPropertyInteger intProp2 = subProp as AssetPropertyInteger; if (readAssetProperty.CheckMaterialMxExists(matId, AssetProperty3[i].Name)) { readAssetProperty.ReadAssetPropertyFromRevit(matId, AssetProperty3[i].Name, AssetProperty3[i].Type.ToString(), intProp2.Value.ToString()); } } break; } break; } } } break; default: //info += assetProperty.Name + ";" + assetProperty.Type.ToString() + "\n"; break; } } } }
1)把材料放到資料庫裡
2)檢查資料庫裡是否已經存在該材料的資訊
其中下面這句程式碼是資料庫的連結地址,依據個人的電腦不同而改變。
private string str = "Data Source=USER-20161016YA\\MEDICINE;Initial Catalog=MyMaterials;Integrated Security=True";
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 讀取牆體材料 { public class ReadAssetProperty { private string str = "Data Source=USER-20161016YA\\MEDICINE;Initial Catalog=MyMaterials;Integrated Security=True"; public void ReadAssetPropertyFromRevit(string materialId ,string paramName, string type,string value) { int n = -1; //連線資料庫 using (SqlConnection con = new SqlConnection(str)) { //string sql = string.Format("insert into MaterialFormRevit(MaterialId,ParamName, MatType, Value) values('{0}','{1}','{2}',{3})", 1,paramName, type, value); string sql = string.Format("insert into MaterialFormRevit(MaterialId,ParamName, MatType, Value) values('{0}','{1}','{2}','{3}')", materialId, paramName, type, value); using (SqlCommand cmd = new SqlCommand(sql, con)) { con.Open(); n = cmd.ExecuteNonQuery(); } } //string msg = n > 0 ? "操作成功" : "操作失敗"; //LoadData();//重新整理資料 } public bool CheckMaterialMxExists(string strMaterialId, string paramName) { bool flag = false; SqlConnection mycon = new SqlConnection(str); //查詢此編號是否存在 mycon.Open(); SqlCommand mycmd = new SqlCommand("select MaterialId from MaterialFormRevit where MaterialId='" + strMaterialId + "'AND ParamName='" + paramName + "'", mycon); SqlDataReader mysdr = mycmd.ExecuteReader(); if (mysdr.HasRows) { flag = false; } else { flag = true; } mysdr.Close(); mycon.Close(); return flag; } } }
其中中間過渡屬性的材料如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 讀取牆體材料
{
public class Depart
{
private int _MaterialId;
private string _ParamName;
private string _Type;
private string _Value;
public int MaterialId
{
get
{
return _MaterialId;
}
set
{
_MaterialId = value;
}
}
public string ParamName
{
get
{
return _ParamName;
}
set
{
_ParamName = value;
}
}
public string Type
{
get
{
return _Type;
}
set
{
_Type = value;
}
}
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
}
}
}
}
最後Form的程式碼如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace 讀取牆體材料
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string str = "Data Source=USER-20161016YA\\MEDICINE;Initial Catalog=MyMaterials;Integrated Security=True";
private void Form1_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
List<Depart> list = new List<Depart>();
//通過連線字串連線資料庫
using (SqlConnection con = new SqlConnection(str))
{
//拼接sql語句
string sql = "select * from MaterialFormRevit";
//準備執行sql語句的物件
using (SqlCommand cmd = new SqlCommand(sql, con))
{
con.Open();//開啟資料庫
//準備讀資料
using (SqlDataReader reader = cmd.ExecuteReader())
{
//判斷是否有資料(有沒有行)
if (reader.HasRows)
{
//讀取每一行
while (reader.Read())
{
Depart dk = new Depart();//建立部門物件
// dk.MaterialId= Convert.ToInt32(reader["MaterialId"]);
dk.MaterialId =Convert.ToInt32(reader["MaterialId"].ToString()) ;
dk.ParamName = reader["ParamName"].ToString();
dk.Type = reader["MatType"].ToString();
dk.Value = reader["Value"].ToString();
list.Add(dk);//新增到集合中
}//end while
}//end if
}// end sqldatareader
}//end using
}//end using
dgv.AutoGenerateColumns = false;//禁止自動生成列
dgv.DataSource = list;//繫結資料
//dgv.SelectedRows[0].Selected = false;//禁止被選中
}
}
}
最後結果如圖: