410 lines
14 KiB
C#
410 lines
14 KiB
C#
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
using Autodesk.Revit.ApplicationServices;
|
|
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.DB.Visual;
|
|
|
|
namespace Sai.Toolkit.Revit.Assist;
|
|
|
|
public static class MaterialAssist
|
|
{
|
|
/// <summary>
|
|
/// 获取材质外观
|
|
/// </summary>
|
|
/// <param name="material"></param>
|
|
/// <returns></returns>
|
|
public static StringBuilder GetMaterialAppearanceInfo(this Material material)
|
|
{
|
|
var assetElem = material.Document.GetElement(material.AppearanceAssetId) as AppearanceAssetElement;
|
|
var asset = assetElem.GetRenderingAsset();
|
|
StringBuilder sb = new();
|
|
for (var i = 0; i < asset.Size; i++)
|
|
{
|
|
var prop = asset[i];
|
|
|
|
sb.Append($"属性名:{prop.Name};值类型:{prop.Type};值:");
|
|
switch (prop.Type)
|
|
{
|
|
case AssetPropertyType.Unknown:
|
|
break;
|
|
case AssetPropertyType.Properties:
|
|
break;
|
|
case AssetPropertyType.Boolean:
|
|
var propBool = prop as AssetPropertyBoolean;
|
|
sb.Append(propBool?.Value);
|
|
break;
|
|
case AssetPropertyType.Enumeration:
|
|
var propEnum = prop as AssetPropertyEnum;
|
|
sb.Append(propEnum?.Value);
|
|
break;
|
|
case AssetPropertyType.Integer:
|
|
var propInt = prop as AssetPropertyInteger;
|
|
sb.Append(propInt?.Value);
|
|
break;
|
|
case AssetPropertyType.Float:
|
|
break;
|
|
case AssetPropertyType.Double1:
|
|
var propDouble = prop as AssetPropertyDouble;
|
|
sb.Append(propDouble?.Value);
|
|
break;
|
|
case AssetPropertyType.Double2:
|
|
var propDouble2 = prop as AssetPropertyDoubleArray2d;
|
|
foreach (var d in propDouble2.Value)
|
|
{
|
|
sb.Append($"{d},");
|
|
}
|
|
break;
|
|
case AssetPropertyType.Double3:
|
|
var propDouble3 = prop as AssetPropertyDoubleArray3d;
|
|
foreach (var d in propDouble3?.GetValueAsDoubles())
|
|
{
|
|
sb.Append($"{d},");
|
|
}
|
|
break;
|
|
case AssetPropertyType.Double4:
|
|
var propDouble4 = prop as AssetPropertyDoubleArray4d;
|
|
|
|
foreach (var d in propDouble4?.GetValueAsDoubles())
|
|
{
|
|
sb.Append($"{d},");
|
|
}
|
|
break;
|
|
case AssetPropertyType.Double44:
|
|
break;
|
|
case AssetPropertyType.String:
|
|
var propStr = prop as AssetPropertyString;
|
|
sb.Append(propStr?.Value);
|
|
break;
|
|
case AssetPropertyType.Time:
|
|
break;
|
|
case AssetPropertyType.Distance:
|
|
break;
|
|
case AssetPropertyType.Asset:
|
|
break;
|
|
case AssetPropertyType.Reference:
|
|
break;
|
|
case AssetPropertyType.Longlong:
|
|
break;
|
|
case AssetPropertyType.ULonglong:
|
|
break;
|
|
case AssetPropertyType.List:
|
|
break;
|
|
case AssetPropertyType.Float3:
|
|
break;
|
|
}
|
|
sb.AppendLine();
|
|
}
|
|
return sb;
|
|
}
|
|
/// <summary>
|
|
/// 获取资产属性
|
|
/// </summary>
|
|
/// <param name="asset"></param>
|
|
/// <param name="name"></param>
|
|
/// <returns></returns>
|
|
public static AssetProperty FindByName(this Asset asset, string name)
|
|
{
|
|
#if REVIT2018
|
|
return asset[name];
|
|
#else
|
|
return asset.FindByName(name);
|
|
#endif
|
|
}
|
|
|
|
public static AssetProperty Get(this Asset asset, int index)
|
|
{
|
|
#if REVIT2018
|
|
return asset[index];
|
|
#else
|
|
return asset.Get(index);
|
|
#endif
|
|
}
|
|
|
|
#if REVIT2019 || REVIT2020
|
|
public static void ModifyAppearanceBitMap(this Material material, string bitmapPath)
|
|
{
|
|
using AppearanceAssetEditScope editScope = new(material.Document);
|
|
Asset editableAsset = editScope.Start(material.AppearanceAssetId);
|
|
AssetProperty assetProperty = editableAsset.FindByName("generic_diffuse");
|
|
Asset connectedAsset = assetProperty.GetConnectedProperty(0) as Asset;
|
|
if (connectedAsset?.Name == "UnifiedBitmapSchema")
|
|
{
|
|
AssetPropertyString path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString;
|
|
Debug.Assert(path != null, nameof(path) + " != null");
|
|
path.Value = bitmapPath;
|
|
}
|
|
|
|
editScope.Commit(true);
|
|
}
|
|
|
|
public static void ModifyAppearanceColor(Material material, string bitmapPath)
|
|
{
|
|
if (material != null)
|
|
{
|
|
Document doc = material.Document;
|
|
ElementId appearanceAssetId = material.AppearanceAssetId;
|
|
AppearanceAssetElement assetElem = doc.GetElement(appearanceAssetId) as AppearanceAssetElement;
|
|
using Transaction t2 = new(doc);
|
|
t2.Start("修改外观颜色");
|
|
using (AppearanceAssetEditScope editScope = new(assetElem.Document))
|
|
{
|
|
// returns an editable copy of the appearance asset
|
|
Asset editableAsset = editScope.Start(assetElem.Id);
|
|
// Diffuse image
|
|
AssetPropertyDoubleArray4d genericDiffuseProperty = editableAsset.FindByName("generic_diffuse") as AssetPropertyDoubleArray4d;
|
|
genericDiffuseProperty.SetValueAsColor(new Color(100, 100, 100));
|
|
editScope.Commit(true);
|
|
}
|
|
|
|
t2.Commit();
|
|
}
|
|
}
|
|
#endif
|
|
#if REVIT2019 || REVIT2020
|
|
public static void ChangeRenderingTexturePath(this Material mat, string texturePath)
|
|
{
|
|
using AppearanceAssetEditScope editScope = new(mat.Document);
|
|
Asset editableAsset = editScope.Start(mat.AppearanceAssetId);
|
|
|
|
//AssetProperty assetProperty = editableAsset["generic_diffuse"];
|
|
AssetProperty assetProperty = editableAsset.FindByName("generic_diffuse");
|
|
Asset connectedAsset = assetProperty.GetConnectedProperty(0) as Asset;
|
|
if (connectedAsset.Name == "UnifiedBitmapSchema")
|
|
{
|
|
AssetPropertyString path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString;
|
|
if (path.IsValidValue(texturePath))
|
|
{
|
|
path.Value = texturePath;
|
|
}
|
|
}
|
|
|
|
editScope.Commit(true);
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// 读取标准外观库
|
|
/// </summary>
|
|
/// <param name="uiapp"></param>
|
|
/// <returns></returns>
|
|
public static StringBuilder GetAssetsInfo(this Application app)
|
|
{
|
|
#if REVIT2018
|
|
var assets = app.get_Assets(AssetType.Appearance);
|
|
#else
|
|
var assets = app.GetAssets(AssetType.Appearance);
|
|
#endif
|
|
StringBuilder sb = new();
|
|
foreach (Asset asset in assets)
|
|
{
|
|
ReadAsset(asset, sb);
|
|
}
|
|
|
|
return sb;
|
|
}
|
|
/// <summary>
|
|
/// 读取资产
|
|
/// </summary>
|
|
/// <param name="asset"></param>
|
|
/// <param name="objWriter"></param>
|
|
public static void ReadAsset(this Asset asset, StringBuilder objWriter)
|
|
{
|
|
//string libName = "assetlibrary_base.fbx";
|
|
//string name = asset.Name;
|
|
objWriter.AppendLine($"{asset.Name}----{asset.LibraryName}");
|
|
for (var idx = 0; idx < asset.Size; idx++)
|
|
{
|
|
var prop = asset[idx];
|
|
ReadAssetProperty(prop, objWriter);
|
|
}
|
|
objWriter.AppendLine();
|
|
}
|
|
/// <summary>
|
|
/// 读取资产属性
|
|
/// </summary>
|
|
/// <param name="prop"></param>
|
|
/// <param name="objWriter"></param>
|
|
private static void ReadAssetProperty(this AssetProperty prop, StringBuilder objWriter)
|
|
{
|
|
switch (prop.Type)
|
|
{
|
|
// Retrieve the value from simple type property is easy.
|
|
// for example, retrieve bool property value.
|
|
case AssetPropertyType.Integer:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
var assetPropertyInt = prop as AssetPropertyInteger;
|
|
objWriter.AppendLine(assetPropertyInt.Name + "," + assetPropertyInt.Value);
|
|
break;
|
|
|
|
case AssetPropertyType.Distance:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
var assetPropertyDistance = prop as AssetPropertyDistance;
|
|
objWriter.AppendLine(assetPropertyDistance.Name + "," + assetPropertyDistance.Value);
|
|
|
|
break;
|
|
|
|
case AssetPropertyType.Double1:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var assetPropertyDouble = prop as AssetPropertyDouble;
|
|
objWriter.AppendLine(assetPropertyDouble.Name + "," + assetPropertyDouble.Value);
|
|
|
|
break;
|
|
|
|
case AssetPropertyType.Double2:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var assetPropertyDoubleArray2d = prop as AssetPropertyDoubleArray2d;
|
|
objWriter.AppendLine(" : " + assetPropertyDoubleArray2d.Name + "," + assetPropertyDoubleArray2d.Value);
|
|
break;
|
|
|
|
case AssetPropertyType.Double4:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var assetPropertyDoubleArray4d = prop as AssetPropertyDoubleArray4d;
|
|
objWriter.AppendLine(assetPropertyDoubleArray4d.Name + "," + assetPropertyDoubleArray4d.GetValueAsDoubles());
|
|
break;
|
|
|
|
case AssetPropertyType.String:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var val = prop as AssetPropertyString;
|
|
|
|
objWriter.AppendLine(val.Name + "," + val.Value);
|
|
break;
|
|
case AssetPropertyType.Boolean:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var boolProp = prop as AssetPropertyBoolean;
|
|
objWriter.AppendLine(boolProp.Name + "," + boolProp.Value);
|
|
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.Double44:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var transformProp = prop as AssetPropertyDoubleArray4d;
|
|
objWriter.AppendLine(transformProp.Name + "," + transformProp.GetValueAsDoubles());
|
|
break;
|
|
|
|
// The APT_List contains a list of sub asset properties with same type.
|
|
case AssetPropertyType.List:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var propList = prop as AssetPropertyList;
|
|
var subProps = propList.GetValue();
|
|
if (subProps.Count == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
switch (subProps[0].Type)
|
|
{
|
|
case (AssetPropertyType)4:
|
|
foreach (var subProp in subProps)
|
|
{
|
|
objWriter.Append("子属性集---");
|
|
objWriter.Append(',');
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), subProps[0].Type));
|
|
objWriter.Append(',');
|
|
|
|
var intProp = subProp as AssetPropertyInteger;
|
|
objWriter.AppendLine(intProp.Name + "," + intProp.Value);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case AssetPropertyType.Asset:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
var propAsset = prop as Asset;
|
|
ReadAsset(propAsset, objWriter);
|
|
break;
|
|
|
|
case AssetPropertyType.Reference:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
|
|
break;
|
|
default:
|
|
objWriter.Append(Enum.GetName(typeof(AssetPropertyType), prop.Type));
|
|
objWriter.Append(',');
|
|
objWriter.AppendLine("无类型" + prop.Type);
|
|
break;
|
|
}
|
|
|
|
// Get the connected properties.
|
|
// please notice that the information of many texture stores here.
|
|
if (prop.NumberOfConnectedProperties == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var connectedProp in prop.GetAllConnectedProperties())
|
|
{
|
|
// Note: Usually, the connected property is an Asset.
|
|
ReadAssetProperty(connectedProp, objWriter);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取材质贴图
|
|
/// </summary>
|
|
/// <param name="material"></param>
|
|
/// <param name="files">材质目录</param>
|
|
public static void GetTexture(this Material material, FileInfo[] files)
|
|
{
|
|
var doc = material.Document;
|
|
var appearance = doc.GetElement(material.AppearanceAssetId) as AppearanceAssetElement;
|
|
var asset = appearance.GetRenderingAsset();
|
|
|
|
#if REVIT2018
|
|
var p = asset["unifiedbitmap_Bitmap"] as AssetPropertyString;
|
|
//p.Value
|
|
|
|
#elif REVIT2019 || REVIT2020
|
|
AssetPropertyString val = asset.FindByName("unifiedbitmap_Bitmap") as AssetPropertyString;
|
|
if (val.Name == "unifiedbitmap_Bitmap" && val.Value.Contains("\\") && !File.Exists(val.Value))
|
|
{
|
|
FileInfo originalFile = new(val.Value);
|
|
foreach (var info in files)
|
|
{
|
|
if (info.Name == originalFile.Name)
|
|
{
|
|
val.Value = info.Name;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for (var i = 0; i < asset.Size; i++)
|
|
{
|
|
#if REVIT2018
|
|
//using (StreamWriter writer = new StreamWriter("F:\\纤维板.txt"))
|
|
//{
|
|
// ReadAsset(asset, writer);
|
|
//}
|
|
#elif REVIT2019 || REVIT2020
|
|
var prop = asset.Get(i);
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
}
|