关闭

Revit 二次开发获取元素的材质和外观信息以及贴图

标签: Revit二次开发材质贴图
4153人阅读 评论(4) 收藏 举报
分类:

最近群里的朋友们这个问题问的比较多,有必要写一篇文章介绍利用Revit 二次开发获取元素的材质和贴图的方法!


总体来说利用Revit API 获取元素的材质和贴图比较麻烦,而且有的材质还无法获取。总结一下思路如下:

1.假设我们已经得到元素,利用Element.GetMaterialIds 方法可以获得该元素所有材质的ElementId,注意这是一个集合!

2.将获取到的ElementId转化为Material对象。就能得到材质名,颜色,填充图形等等信息。

3.利用Material的AppearanceAssetId属性得到AppearanceAssetId

4.通过3取得的AppearanceAssetId取得AppearanceAssetElement。

5.AppearanceAssetElement.GetRenderingAsset()获得Asset。

这里需要注意,如果您的材质是欧特克材质库的材质,那么恭喜你,这个函数取得的Asset长度为0.也就是说,毛也没取到!怎么处理后面再说。

6.解析第5步取得的Asset,Revit二次开发里某个对象叫xxxSet,那么这个对象一定是个集合。所以需要一个循环把集合中每一个对象都拉出来分析。

这个集合里每一个对象都是一个AssetProperty。

7.AssetProperty 看见后面的Property就知道这是一个属性的集合,你也需要把每一个属性拉出来分析。

8.属性类型包括APT_Integer,APT_Distance等等等等,你需要为每一种写一套代码读取它的属性值

9.还有一种属性类型叫APT_Reference,看见Reference头晕不,这就说明这个属性引用了其它属性,碰上这种类型的,你还要做一个递归。

10.如果你找到了一个名字叫unifiedbitmap_Bitmap的属性,那么恭喜你,你找到了该元素的贴图路径。

11.下面回过头看第5步,如果是AppearanceAssetElement.GetRenderingAsset()集合获得空集合时。说明该材质使用了欧特克材质库的材质。

那么需要用Application.get_Assets获得欧特克材质库


写了这么多,直接上代码吧,不写注释是我的优良传统,弄不明白看上面的说明吧。

代码中objBll.InsertMaterialMx都是数据库操作,我把导出材质信息存入数据库中。大家可以无视

 public void ReadAsset(Asset asset, string strMaterialId, StreamWriter objWriter)
        {
            // Get the asset name, type and library name.
            string name = asset.Name;

            // travel the asset properties in the asset.
            for (int idx = 0; idx < asset.Size; idx++)
            {
                AssetProperty prop = asset[idx];
                ReadAssetProperty(prop, strMaterialId, name, objWriter);
            }
        }



 public void ReadAssetProperty(AssetProperty prop, string strMaterialId, string strName, StreamWriter objWriter)
        {
            var objBll = new RevitMaterialExportBll();

            switch (prop.Type)
            {
                // Retrieve the value from simple type property is easy.
                // for example, retrieve bool property value.
                    case AssetPropertyType.APT_Integer:
                    var AssetPropertyInt = prop as AssetPropertyInteger;
                    objWriter.WriteLine(AssetPropertyInt.Name + "= " + AssetPropertyInt.Value.ToString());
                    if (!objBll.CheckMaterialMxExists(strMaterialId, AssetPropertyInt.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, AssetPropertyInt.Name,GetDbData( AssetPropertyInt.Value), "APT_Integer");
                    }
                    break;

                case AssetPropertyType.APT_Distance:
                     var AssetPropertyDistance = prop as AssetPropertyDistance;
                     objWriter.WriteLine(AssetPropertyDistance.Name + "= " + AssetPropertyDistance.Value);
                     if (!objBll.CheckMaterialMxExists(strMaterialId, AssetPropertyDistance.Name))
                     {
                         objBll.InsertMaterialMx(strMaterialId, AssetPropertyDistance.Name, GetDbData(AssetPropertyDistance.Value), "AssetPropertyDistance");
                     }
                    break;

                case AssetPropertyType.APT_Double:
                    var AssetPropertyDouble = prop as AssetPropertyDouble;
                    objWriter.WriteLine(AssetPropertyDouble.Name + "= " + AssetPropertyDouble.Value.ToString());
                    if (!objBll.CheckMaterialMxExists(strMaterialId, AssetPropertyDouble.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, AssetPropertyDouble.Name, GetDbData(AssetPropertyDouble.Value), "AssetPropertyDouble");
                    }
                    break;

                case AssetPropertyType.APT_DoubleArray2d:
                    var AssetPropertyDoubleArray2d = prop as AssetPropertyDoubleArray2d;
                    objWriter.WriteLine(AssetPropertyDoubleArray2d.Name + "= " + AssetPropertyDoubleArray2d.Value.ToString());
                    break;

                case AssetPropertyType.APT_DoubleArray4d:
                    var AssetPropertyDoubleArray4d = prop as AssetPropertyDoubleArray4d;
                    objWriter.WriteLine(AssetPropertyDoubleArray4d.Name + "= " + AssetPropertyDoubleArray4d.Value.ToString());
                    if (!objBll.CheckMaterialMxExists(strMaterialId, AssetPropertyDoubleArray4d.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, AssetPropertyDoubleArray4d.Name, GetDbData(AssetPropertyDoubleArray4d.Value), "AssetPropertyDoubleArray4d");
                    }
                    break;

                case AssetPropertyType.APT_String:
                    AssetPropertyString val = prop as AssetPropertyString;
                    
                    objWriter.WriteLine(val.Name + "= " + val.Value);
                    if (!objBll.CheckMaterialMxExists(strMaterialId, val.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, val.Name, GetDbData(val.Value), "APT_String");
                    }
                    break;
                case AssetPropertyType.APT_Boolean:
                    AssetPropertyBoolean boolProp = prop as AssetPropertyBoolean;
                    objWriter.WriteLine(boolProp.Name + "= " + boolProp.Value.ToString());
                    if (!objBll.CheckMaterialMxExists(strMaterialId, boolProp.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, boolProp.Name, GetDbData(boolProp.Value), "APT_Boolean");
                    }
                    break;

                // When you retrieve the value from the data array property,
                // you may need to get which value the property stands for.
                // for example, the APT_Double44 may be a transform data.
                case AssetPropertyType.APT_Double44:
                    AssetPropertyDoubleArray4d transformProp = prop as AssetPropertyDoubleArray4d;
                    Autodesk.Revit.DB.DoubleArray tranformValue = transformProp.Value;
                    objWriter.WriteLine(transformProp.Name + "= " + transformProp.Value.ToString());
                    if (!objBll.CheckMaterialMxExists(strMaterialId, transformProp.Name))
                    {
                        objBll.InsertMaterialMx(strMaterialId, transformProp.Name, GetDbData(transformProp.Value), "APT_Double44");
                    }
                    break;

                // The APT_List contains a list of sub asset properties with same type.
                case AssetPropertyType.APT_List:
                    AssetPropertyList propList = prop 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;
                                int intValue = intProp.Value;
                                objWriter.WriteLine(intProp.Name + "= " + intProp.Value.ToString());
                            }
                            break;
                    }
                    break;

                case AssetPropertyType.APT_Asset:
                    Asset propAsset = prop as Asset;
                    ReadAsset(propAsset, strMaterialId, objWriter);
                    break;

                    case AssetPropertyType.APT_Reference:
                    
                    break;
                default:
                    objWriter.WriteLine("居然有啥都不是类型的" + prop.Type.ToString());
                    break;

            }

            // Get the connected properties.
            // please notice that the information of many texture stores here.
            if (prop.NumberOfConnectedProperties == 0)
                return;
            foreach (AssetProperty connectedProp in prop.GetAllConnectedProperties())
            {
                // Note: Usually, the connected property is an Asset.
                ReadAssetProperty(connectedProp, strMaterialId, strName, objWriter);
            }
        }

<pre name="code" class="html">        private void ExportMaterialInfo(ExternalCommandData commandData)
        {
            var objDoc = commandData.Application.ActiveUIDocument.Document;
            var objApp = commandData.Application.Application;
            var collector = new FilteredElementCollector(objDoc);
            var objBll = new RevitMaterialExportBll();
            var classfilter = new ElementClassFilter(typeof(Material));
            collector.WherePasses(classfilter);
            var beamList = collector.ToElements();

            // 读取revit标准材质库
            var objlibraryAsset = objApp.get_Assets(AssetType.Appearance);

            //写入临时文件
            using (var objWriter = new StreamWriter(@"D:\aaa.txt"))
            {

                foreach (var objLoopItem in beamList)
                {
                    var objMaterial = objLoopItem as Material;
                    if (objMaterial != null)
                    {

                        var assetElementId = objMaterial.AppearanceAssetId;
                        var objMainColor = objMaterial.Color.Red + "," + objMaterial.Color.Green + "," +
                                           objMaterial.Color.Blue;
                        var objMaterialId = GetDbData(objMaterial.Id);

                        // 检查数据库中此材质是否存在
                        if (!objBll.CheckMaterialExists(objMaterialId))
                        {
                            objBll.InsertMaterial(objMaterialId, GetDbData(assetElementId), objMaterial.Name, objMainColor);
                        }

                        if (assetElementId != ElementId.InvalidElementId)
                        {
                            var objassetElement = objDoc.GetElement(assetElementId) as AppearanceAssetElement;
                            if (objassetElement != null)
                            {
                                var currentAsset = objassetElement.GetRenderingAsset();

                                // 检索不到材质外观时,为欧特克材质库材质
                                if (currentAsset.Size == 0)
                                {
                                    foreach (Asset objCurrentAsset in objlibraryAsset)
                                    {
                                        if (objCurrentAsset.Name == currentAsset.Name &&
                                            objCurrentAsset.LibraryName == currentAsset.LibraryName)
                                        {
                                            ReadAsset(objCurrentAsset, objMaterial.Id.ToString(), objWriter);
                                        }
                                    }
                                }
                                else
                                {
                                    ReadAssetProperty(currentAsset, objMaterial.Id.ToString(), objMaterial.Name,
                                        objWriter);
                                }
                            }

                        }

                    }
                }
                objWriter.Close();
            }
        }

最后附上一张保存进数据库系统的数据图片





大连智慧筑城科技发展有限公司    贝克汉鸭   QQ:2443485

0
0
查看评论

Revit二次开发入门--创建一个简单的程序

Revit二次开发
  • PC_Spider
  • PC_Spider
  • 2016-08-04 17:14
  • 7323

Revit二次开发从入门到精通学习之路, (含Revit二次开发教程下载)

Revit二次开发从入门到精通学习之路                      ...
  • JoeXiongjin
  • JoeXiongjin
  • 2011-02-09 14:23
  • 63851

Revit二次开发之Socket通信实现自动化处理任务(一)

本例将在Revit ExternalApplication中定义一个服务器,监听客户端发送的消息,解析消息内容,根据消息内容执行相应的命令
  • kennan3223
  • kennan3223
  • 2016-04-14 13:30
  • 1007

Revit二次开发--"Hello World"

1.Create a new project 选择新建项目中的C#–类库,建立项目名称为“HelloWorld”。 2.Add Reference 1)在revit的安装路径在找到 RevitAPI.dll 并添加。例如,安装路径为:D:\Learning Software\Revit\Rev...
  • Sabrina_TSM
  • Sabrina_TSM
  • 2015-11-23 19:04
  • 1799

Revit二次开发手记【1】

1.返回值(Execute方法)  1.1 Result.Succeeded        当返回值为当前函数时,操作正确,不弹出任何提示框。  1.2 Result.Cancelled 返回值为当前函数时,操作失败,r...
  • windlee09
  • windlee09
  • 2016-07-26 14:48
  • 758

revit二次开发获取墙的几何信息

revit二次开发获取墙的几何信息
  • niuge8905
  • niuge8905
  • 2016-11-03 00:36
  • 2446

revit二次开发里获得指定参数并修改

revit二次开发里获得指定参数并修改
  • niuge8905
  • niuge8905
  • 2016-11-01 12:27
  • 2768

如何开始Revit二次开发

做结构设计已经八年有余,心下思量,近几年建筑市场稍不景气,自身又不愿放弃所学专业,于是便看中专业相关,且发展有前景的BIM行业,因此自2015年开始学习和接触Revit,并在2016年开始学习Revit二次开发,为使得更多同仁可以对现下热门的BIM行业基础软件Revit有更深刻的认识,以及督促自己学...
  • yiyihuazi
  • yiyihuazi
  • 2017-04-23 21:44
  • 927

revit二次开发——从族实例中取得几何信息

1、可以从族实例中获得面、获得边、获得线、获得点,方法如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadi...
  • niuge8905
  • niuge8905
  • 2017-02-05 19:19
  • 1645

Revit二次开发--工具下载

Revit开发工具
  • PC_Spider
  • PC_Spider
  • 2017-04-28 15:37
  • 380
    个人资料
    • 访问:37331次
    • 积分:414
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:7篇
    • 译文:0篇
    • 评论:17条
    最新评论