RevitAPI: 如何获取某个材质参数?

我经常听到这样的问题:Asset里面有太多的参数,怎么才能知道哪个参数是我想要的?尤其是我们中国的用户,界面都是中文,而API基本都是英文,寻找对应关系就更难了。

开发人员可能走到这里就止步了:

private void CustomerApproach(Material material)
{
    ElementId appearanceId = material.AppearanceAssetId;
    AppearanceAssetElement appearanceElem = 
        RevitDoc.GetElement(appearanceId) as AppearanceAssetElement;
    Asset theAsset = appearanceElem.GetRenderingAsset();
    for (int idx = 0; idx < theAsset.Size; idx++)
    {
        //太多参数了,头晕了吧?
        AssetProperty ap = theAsset[idx];
    }
}

RevitAPI: 如何获取某个材质参数?_第1张图片

其实我也不知道答案,但是我们可以自己动手来探测一下,代码如下:

private void DumpAppearanceAssetProperties(Material material)
{
    ElementId appearanceId = material.AppearanceAssetId;
    AppearanceAssetElement appearanceElem = material.Document.
        GetElement(appearanceId) as AppearanceAssetElement;
    Asset theAsset = appearanceElem.GetRenderingAsset();
    List assets = new List();
    for (int idx = 0; idx < theAsset.Size; idx++)
    {
        AssetProperty ap = theAsset[idx];
        assets.Add(ap);
    }
    // order the properties!
    assets = assets.OrderBy(ap => ap.Name).ToList();
    for (int idx = 0; idx < assets.Count; idx++)
    {
        AssetProperty ap = assets[idx];
        Type type = ap.GetType();
        object apVal = null;
        try
        {
            // using .net reflection to get the value
            var prop = type.GetProperty("Value");
            if (prop != null && 
                prop.GetIndexParameters().Length == 0)
            {
                apVal = prop.GetValue(ap);
            }
            else
            {
                apVal = "";
            }
        }
        catch (Exception ex)
        {
            apVal = ex.GetType().Name + "-" + ex.Message;
        }

        if (apVal is DoubleArray)
        {
            var doubles = apVal as DoubleArray;
            apVal = doubles.Cast().Aggregate("", (s, d) => s + Math.Round(d,5) + ",");
        }
        Log(idx + " : [" + ap.Type + "] " + ap.Name + " = " + apVal);
    }
}

有人问就算输出这些参数,我也还是不知道哪个是我要的啊。因为结果看上去是这样的:

结果1:

0 : [APT_String] AdvancedUIDefinition = Mats/Generic/GenericAdvancedUI.xml 
1 : [APT_String] AssetLibID = AD121259-C03E-4A1D-92D8-59A22B4807AD 
2 : [APT_String] assettype = materialappearance 
3 : [APT_String] BaseSchema = GenericSchema 
4 : [APT_String] category = :Concrete:Default:Miscellaneous 
5 : [APT_Boolean] color_by_object = False 
6 : [APT_Integer] common_Shared_Asset = 1 
7 : [APT_DoubleArray4d] common_Tint_color = 0.315,0.315,0.315,1, 
8 : [APT_Boolean] common_Tint_toggle = False 
9 : [APT_String] description = Generic material. 
10 : [APT_String] ExchangeGUID =  
11 : [APT_Boolean] generic_ao_details = True 
12 : [APT_Double] generic_ao_distance = 4 
13 : [APT_Boolean] generic_ao_on = False 
14 : [APT_Integer] generic_ao_samples = 16 
15 : [APT_Boolean] generic_backface_cull = False 
16 : [APT_Double] generic_bump_amount = 9.39325797868605E-275 
17 : [APT_DoubleArray4d] generic_bump_map = 0,0,0,1, 
18 : [APT_Double] generic_cutout_opacity = 1 
19 : [APT_DoubleArray4d] generic_diffuse = 0.51353,0.52278,0.47005,1, 
20 : [APT_Double] generic_diffuse_image_fade = 1 
21 : [APT_Double] generic_glossiness = 0 
22 : [APT_Boolean] generic_is_metal = False 
23 : [APT_Integer] generic_refl_depth = 0 
24 : [APT_Integer] generic_reflection_glossy_samples = 12 
25 : [APT_Double] generic_reflectivity_at_0deg = 0.5 
26 : [APT_Double] generic_reflectivity_at_90deg = 0.5 
27 : [APT_Integer] generic_refr_depth = -1 
28 : [APT_Integer] generic_refraction_glossy_samples = 12 
29 : [APT_Double] generic_refraction_index = 1 
30 : [APT_Double] generic_refraction_translucency_weight = 0 
31 : [APT_Boolean] generic_roundcorners_allow_different_materials = False 
32 : [APT_Double] generic_roundcorners_radius = 0 
33 : [APT_Double] generic_self_illum_color_temperature = 6500 
34 : [APT_DoubleArray4d] generic_self_illum_filter_map = 1,1,1,1, 
35 : [APT_Double] generic_self_illum_luminance = 0 
36 : [APT_Double] generic_transparency = 0 
37 : [APT_Double] generic_transparency_image_fade = 1 
38 : [APT_Boolean] Hidden = False 
39 : [APT_String] ImplementationGeneric =  
40 : [APT_String] ImplementationMentalRay = Mats/Generic/MentalImage.xml 
41 : [APT_String] ImplementationOGS = Mats/Generic/OGS.xml 
42 : [APT_String] ImplementationPreview = Mats/Generic/PreviewColor.xml 
43 : [APT_String] keyword =  
44 : [APT_String] localname = Generic 
45 : [APT_String] localtype = Appearance 
46 : [APT_Integer] mode = 4 
47 : [APT_DoubleArray2d] PatternOffset = 0,0, 
48 : [APT_Integer] revision = 1 
49 : [APT_Integer] SchemaVersion = 4 
50 : [APT_String] swatch = Swatch-Cube 
51 : [APT_String] thumbnail = C:/Users/lua.ADS/AppData/Local/Temp/MaterialThumbnails_PID_1434/73c06a00Smooth Precast Structural.png 
52 : [APT_String] UIDefinition = Mats/Generic/GenericUI.xml 
53 : [APT_String] UIName = Smooth Precast Structural 
54 : [APT_Integer] version = 2 
55 : [APT_String] VersionGUID = B1E74BC9-150D-4CB2-BFF1-376BEAD5FEAE 

别急,我们修改一下我们感兴趣的几个属性,再输出一次,例如我更改了Reflectivity下面的两个属性,结果如下:

0 : [APT_String] AdvancedUIDefinition = Mats/Generic/GenericAdvancedUI.xml 
1 : [APT_String] AssetLibID = AD121259-C03E-4A1D-92D8-59A22B4807AD 
2 : [APT_String] assettype = materialappearance 
3 : [APT_String] BaseSchema = GenericSchema 
4 : [APT_String] category = :Concrete:Default:Miscellaneous 
5 : [APT_Boolean] color_by_object = False 
6 : [APT_Integer] common_Shared_Asset = 1 
7 : [APT_DoubleArray4d] common_Tint_color = 0.315,0.315,0.315,1, 
8 : [APT_Boolean] common_Tint_toggle = False 
9 : [APT_String] description = Generic material. 
10 : [APT_String] ExchangeGUID =  
11 : [APT_Boolean] generic_ao_details = True 
12 : [APT_Double] generic_ao_distance = 4 
13 : [APT_Boolean] generic_ao_on = False 
14 : [APT_Integer] generic_ao_samples = 16 
15 : [APT_Boolean] generic_backface_cull = False 
16 : [APT_Double] generic_bump_amount = 9.39325797868605E-275 
17 : [APT_DoubleArray4d] generic_bump_map = 0,0,0,1, 
18 : [APT_Double] generic_cutout_opacity = 1 
19 : [APT_DoubleArray4d] generic_diffuse = 0.51353,0.52278,0.47005,1, 
20 : [APT_Double] generic_diffuse_image_fade = 1 
21 : [APT_Double] generic_glossiness = 0 
22 : [APT_Boolean] generic_is_metal = False 
23 : [APT_Integer] generic_refl_depth = 0 
24 : [APT_Integer] generic_reflection_glossy_samples = 12 
25 : [APT_Double] generic_reflectivity_at_0deg = 0.2 
26 : [APT_Double] generic_reflectivity_at_90deg = 0.96 
27 : [APT_Integer] generic_refr_depth = -1 
28 : [APT_Integer] generic_refraction_glossy_samples = 12 
29 : [APT_Double] generic_refraction_index = 1 
30 : [APT_Double] generic_refraction_translucency_weight = 0 
31 : [APT_Boolean] generic_roundcorners_allow_different_materials = False 
32 : [APT_Double] generic_roundcorners_radius = 0 
33 : [APT_Double] generic_self_illum_color_temperature = 6500 
34 : [APT_DoubleArray4d] generic_self_illum_filter_map = 1,1,1,1, 
35 : [APT_Double] generic_self_illum_luminance = 0 
36 : [APT_Double] generic_transparency = 0 
37 : [APT_Double] generic_transparency_image_fade = 1 
38 : [APT_Boolean] Hidden = False 
39 : [APT_String] ImplementationGeneric =  
40 : [APT_String] ImplementationMentalRay = Mats/Generic/MentalImage.xml 
41 : [APT_String] ImplementationOGS = Mats/Generic/OGS.xml 
42 : [APT_String] ImplementationPreview = Mats/Generic/PreviewColor.xml 
43 : [APT_String] keyword =  
44 : [APT_String] localname = Generic 
45 : [APT_String] localtype = Appearance 
46 : [APT_Integer] mode = 4 
47 : [APT_DoubleArray2d] PatternOffset = 0,0, 
48 : [APT_Integer] revision = 1 
49 : [APT_Integer] SchemaVersion = 4 
50 : [APT_String] swatch = Swatch-Cube 
51 : [APT_String] thumbnail = C:/Users/lua.ADS/AppData/Local/Temp/MaterialThumbnails_PID_1434/70db4100Smooth Precast Structural(7).png 
52 : [APT_String] UIDefinition = Mats/Generic/GenericUI.xml 
53 : [APT_String] UIName = Smooth Precast Structural 
54 : [APT_Integer] version = 2 
55 : [APT_String] VersionGUID = E5E10B97-7ED0-4EE5-B64B-314565517119 

你知道该怎么办了吧!

没错,比较一下两次输出的结果。下面是比较结果:

RevitAPI: 如何获取某个材质参数?_第2张图片


现在是不是很明显了,就是下面两个属性:

generic_reflectivity_at_0deg

generic_reflectivity_at_90deg


注意:

  • 我把所有的AssetProperty放在一个列表里面,然后对它进行名字排序,这样名字就不会乱了。
  • 使用了.net的反射技术,对AssetProperty没有进行向下转型,直接调用Value属性获得参数的值。
  • 如果AssetProperty可以转型为AssetPropertyReference,那么我们可以调用GetAllConnectedProperties()方法递归获取它下面的子属性。
  • 程序的Bug: 代码第17行AssetProperty ap = assets[idx];获取到AssetProperty之后,我们就开始读取它的Value了,而实际上它不止有Value,还可能有ConnectedProperties,所以,我们这里除了读取Value之外,还需要判断(NumberOfConnectedProperties>0)它有没有ConnectedProperties,如果有,那就调用GetAllConnectedProperties()获取它相关的子节点,这里可能有你需要的重要数据哦!bug fix就交给读者您吧~

我使用的比较工具是BeyondCompare,是可以免费试用的软件。



你可能感兴趣的:(RevitAPI,Material)