using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Visual; using Autodesk.Revit.UI; using Nice3point.Revit.Toolkit.External; using System; using System.Linq; using System.Text; namespace Szmedi.RvKits.ModelManager { /// /// 2020材质才支持修改 /// [Transaction(TransactionMode.Manual)] public class MaterialResolveCmd : ExternalCommand { public override void Execute() { FolderBrowserDialog dialog = new() { Multiselect = false }; if (!dialog.ShowDialog()) { Result = Result.Cancelled; return; } var newPath = dialog.SelectedPath; DirectoryInfo directory = new(newPath); var files = directory.GetFiles(); var materialList = new FilteredElementCollector(Document).OfClass(typeof(Material)).Cast(); using Transaction trans = new(Document, "材质处理"); try { trans.Start(); foreach (var material in materialList) { if (material.Name == "8+12mm水泥色水泥纤维板") { var appearance = Document.GetElement(material.AppearanceAssetId) as AppearanceAssetElement; var asset = appearance?.GetRenderingAsset(); if (appearance == null) { break; } #if REVIT2018 var p = asset["unifiedbitmap_Bitmap"] as AssetPropertyString; //p.Value #elif REVIT2019 || REVIT2020 if (asset.FindByName("unifiedbitmap_Bitmap") is not AssetPropertyString val) { break; } if (val.Name == "unifiedbitmap_Bitmap" && val.Value.Contains("\\") && !File.Exists(val.Value)) { var originalFile = new FileInfo(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 } } } trans.Commit(); } catch (Exception ex) { ErrorMessage = ex.Message; if (trans.GetStatus() == TransactionStatus.Started) { trans.RollBack(); } Result = Result.Failed; } } #if REVIT2019||REVIT2020 public void ModifyAppearanceBitMap(Document doc, Material material, string bitmapPath) { using (var editScope = new AppearanceAssetEditScope(doc)) { var editableAsset = editScope.Start(material.AppearanceAssetId); var assetProperty = editableAsset.FindByName("generic_diffuse"); var connectedAsset = assetProperty.GetConnectedProperty(0) as Asset; if (connectedAsset.Name == "UnifiedBitmapSchema") { var path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString; path.Value = bitmapPath; } editScope.Commit(true); } } public void ModifyAppearanceColor(Document doc, Material material, string bitmapPath) { if (material != null) { var appearanceAssetId = material.AppearanceAssetId; var assetElem = doc.GetElement(appearanceAssetId) as AppearanceAssetElement; doc.Invoke( _ => { using var editScope = new AppearanceAssetEditScope(assetElem.Document); // returns an editable copy of the appearance asset var editableAsset = editScope.Start(assetElem.Id); // Diffuse image var genericDiffuseProperty = editableAsset.FindByName("generic_diffuse") as AssetPropertyDoubleArray4d; genericDiffuseProperty.SetValueAsColor(new Color(100, 100, 100)); editScope.Commit(true); }, "修改外观颜色"); } } #endif public void ReadAsset(Asset asset, StringBuilder objWriter) { // Get the asset name, type and library name. var name = asset.Name; // travel the asset properties in the asset. for (var idx = 0; idx < asset.Size; idx++) { var prop = asset[idx]; ReadAssetProperty(prop, name, objWriter); } } public void ReadAssetProperty(AssetProperty prop, string strName, StringBuilder objWriter) { switch (prop.Type) { // Retrieve the value from simple type property is easy. // for example, retrieve bool property value. case (AssetPropertyType)4: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var assetPropertyInt = prop as AssetPropertyInteger; objWriter.AppendLine(assetPropertyInt.Name + "= " + assetPropertyInt.Value); break; case (AssetPropertyType)14: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var assetPropertyDistance = prop as AssetPropertyDistance; objWriter.AppendLine(assetPropertyDistance.Name + "= " + assetPropertyDistance.Value); break; case (AssetPropertyType)6: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var assetPropertyDouble = prop as AssetPropertyDouble; objWriter.AppendLine(assetPropertyDouble.Name + "= " + assetPropertyDouble.Value); break; case (AssetPropertyType)7: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var assetPropertyDoubleArray2d = prop as AssetPropertyDoubleArray2d; objWriter.AppendLine(assetPropertyDoubleArray2d.Name + "= " + assetPropertyDoubleArray2d.Value); break; case (AssetPropertyType)9: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var assetPropertyDoubleArray4d = prop as AssetPropertyDoubleArray4d; objWriter.AppendLine(assetPropertyDoubleArray4d.Name + "= " + assetPropertyDoubleArray4d.GetValueAsDoubles()); break; case (AssetPropertyType)11: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var val = prop as AssetPropertyString; objWriter.AppendLine(val.Name + "= " + val.Value); break; case (AssetPropertyType)2: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); 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)10: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var transformProp = prop as AssetPropertyDoubleArray4d; var tranformValue = transformProp.GetValueAsDoubles(); objWriter.AppendLine(transformProp.Name + "= " + transformProp.GetValueAsDoubles()); break; // The APT_List contains a list of sub asset properties with same type. case (AssetPropertyType)19: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); 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.AppendLine("子属性-------------------------------子属性"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), subProps[0].Type)); var intProp = subProp as AssetPropertyInteger; var intValue = intProp.Value; objWriter.AppendLine(intProp.Name + "= " + intProp.Value.ToString()); } break; } break; case (AssetPropertyType)15: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); var propAsset = prop as Asset; ReadAsset(propAsset, objWriter); break; case (AssetPropertyType)16: objWriter.AppendLine("参照-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); break; default: objWriter.AppendLine("-------------------------------"); objWriter.AppendLine(Enum.GetName(typeof(AssetPropertyType), prop.Type)); 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, strName, objWriter); } } } }