ADN Open CIS
Сообщество программистов Autodesk в СНГ

21/03/2015

Как получить название свойства материала для изменения

Меня часто спрашивают, как получить то или иное свойство материала, которое нужно изменить программно. Так как этих свойство слишком много, то довольно тяжело найти именно то, что нужно изменить. Разработчики могу просто застрять на этом месте:

Код - C#: [Выделить]
  1. private void CustomerApproach(Material material)
  2. {
  3.     ElementId appearanceId = material.AppearanceAssetId;
  4.     AppearanceAssetElement appearanceElem =
  5.         RevitDoc.GetElement(appearanceId) as AppearanceAssetElement;
  6.     Asset theAsset = appearanceElem.GetRenderingAsset();
  7.     for (int idx = 0; idx < theAsset.Size; idx++)
  8.     {
  9.         ////Слишком много свойств. Как понять что именно мне нужно менять?
  10.         AssetProperty ap = theAsset[idx];
  11.     }
  12. }

Ну, я точно также не знаю ответа на этот вопрос, но мы можем сделать простой тест, например вот так:

Код - C#: [Выделить]
  1. private void DumpAppearanceAssetProperties(Material material)
  2. {
  3.     ElementId appearanceId = material.AppearanceAssetId;
  4.     AppearanceAssetElement appearanceElem = material.Document.
  5.         GetElement(appearanceId) as AppearanceAssetElement;
  6.     Asset theAsset = appearanceElem.GetRenderingAsset();
  7.     List<AssetProperty> assets = new List<AssetProperty>();
  8.     for (int idx = 0; idx < theAsset.Size; idx++)
  9.     {
  10.         AssetProperty ap = theAsset[idx];
  11.         assets.Add(ap);
  12.     }
  13.     // Сортируем свойства!
  14.     assets = assets.OrderBy(ap => ap.Name).ToList();
  15.     for (int idx = 0; idx < assets.Count; idx++)
  16.     {
  17.         AssetProperty ap = assets[idx];
  18.         Type type = ap.GetType();
  19.         object apVal = null;
  20.         try
  21.         {
  22.             // Используем рефлексию, чтобы получить значение
  23.             var prop = type.GetProperty("Value");
  24.             if (prop != null &&
  25.                 prop.GetIndexParameters().Length == 0)
  26.             {
  27.                 apVal = prop.GetValue(ap);
  28.             }
  29.             else
  30.             {
  31.                 apVal = "<No Value Property>";
  32.             }
  33.         }
  34.         catch (Exception ex)
  35.         {
  36.             apVal = ex.GetType().Name + "-" + ex.Message;
  37.         }
  38.  
  39.         if (apVal is DoubleArray)
  40.         {
  41.             var doubles = apVal as DoubleArray;
  42.             apVal = doubles.Cast<double>().Aggregate("", (s, d) => s + Math.Round(d,5) + ",");
  43.         }
  44.         Log(idx + " : [" + ap.Type + "] " + ap.Name + " = " + apVal);
  45.     }
  46. }

Вас все еще может мучать вопрос: если даже мы получим все свойства, мы все еще не можем понять, как найти то, что нам нужно. Ведь результат выглядит вот так:

Результат 1:

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

Чтож, давайте изменим какое-нибудь свойство и снова извлечем все значения. Например, я изменил свойства отражающей способности. Результат теперь такой:

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

Дальше все просто. Нужно всего лишь сравнить результаты.

 

Теперь очевидно, что свойства, которые мы изменили это:

  • generic_reflectivity_at_0deg
  • generic_reflectivity_at_90deg

Пара замечаний:

  • Я отсортировал свойства по названию, в противном случае был бы полный бардак и списки была бы не пригодны для сравнения
  • Если AssetProperty является AssetPropertyReference, то мы можем вызвать метод GetAllConnectedProperties() чтобы получить вложенные свойства.

Источник: http://adndevblog.typepad.com/aec/2015/03/revitapi-how-to-get-asset-properties-of-material-i-want.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=2582

Опубликовано 21.03.2015