Revit二次开发——读取构件的材料外观信息

来源:建筑界编辑:黄子俊发布时间:2020-03-22 19:39:15

[摘要]        revit读取材料的外观信息不能通过lookup来搞定,所以读取起来稍微有点麻烦。但是在revit二次开发的官方基础教程里有相关

     

  revit读取材料的外观信息不能通过lookup来搞定,所以读取起来稍微有点麻烦。但是在revit二次开发的官方基础教程里有相关的解释。

         这里就以一个墙体为例,读取墙体材料的所有外观信息(如下图)。这里主要针对autodesk的官方材料库来说的。对于非官方材料库的,下面的代码里被注释掉的可以参考一下。其实读取材料的原理比较简单,过程如下:

1)获取材料的ID,ICollection<ElementId> matId = elem.GetMaterialIds(true); 

2)// 读取revit标准材质库  
            AssetSet objlibraryAsset = revitApp.get_Assets(AssetType.Appearance);

3)从CompoundStructureLayer中获得材料

4)分两种情况读取材料。

        

Revit二次开发——读取构件的材料外观信息

       对于 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-20161016YAMEDICINE;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-20161016YAMEDICINE;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-20161016YAMEDICINE;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;//禁止被选中 } }}

最后结果如图:

Revit二次开发——读取构件的材料外观信息

构件,外观,读取

延展阅读

相关文章