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

如有不明白,请qq254033230询问。       

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

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

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

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

3)从CompoundStructureLayer中获得材料

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

        

Revit二次开发——读取构件的材料外观信息_第1张图片

       对于 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 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 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 listProperty=new List() ;
                    //for(int i=0;i listProperty = new List();
            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 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 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 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 list = new List();
            //通过连接字符串连接数据库
            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二次开发——读取构件的材料外观信息_第2张图片

你可能感兴趣的:(revit二次开发,C#)