关闭

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

标签: Revit二次开发材质贴图
2822人阅读 评论(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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:32037次
    • 积分:364
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:7篇
    • 译文:0篇
    • 评论:17条
    最新评论