1. 程式人生 > >Revit二次開發——讀取構件的材料外觀資訊

Revit二次開發——讀取構件的材料外觀資訊

如有不明白,請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;//禁止被選中

        }
    }
}


最後結果如圖: