/// <summary> /// 自定义方法,用递归找到包含贴图信息:Asset包含的AssetProperty有多种类型,其中Asset、Properties /// 和Reference这三种必须递归处理。贴图信息的AssetProperty名字是unifiedbitmap_Bitmap,类型是String。 /// </summary> /// <param name="ap"></param> /// <returns></returns> private Autodesk.Revit.DB.Visual.Asset FindTextureAsset(AssetProperty ap) { Autodesk.Revit.DB.Visual.Asset result = null; if (ap.Type == AssetPropertyType.Asset) { if (!IsTextureAsset(ap as Autodesk.Revit.DB.Visual.Asset)) { for (int i = 0; i < (ap as Autodesk.Revit.DB.Visual.Asset).Size; i++) { if (null != FindTextureAsset((ap as Autodesk.Revit.DB.Visual.Asset)[i])) { result = FindTextureAsset((ap as Autodesk.Revit.DB.Visual.Asset)[i]); break; } } } else { result = ap as Autodesk.Revit.DB.Visual.Asset; } return(result); } else { for (int j = 0; j < ap.NumberOfConnectedProperties; j++) { if (null != FindTextureAsset(ap.GetConnectedProperty(j))) { result = FindTextureAsset(ap.GetConnectedProperty(j)); } } return(result); } }
public static string GetStringValueFromAsset(AssetProperty assetProp, out double scaleX, out double scaleY) { scaleX = 1.0; scaleY = 1.0; if (assetProp == null) return string.Empty; if (assetProp.NumberOfConnectedProperties < 1) return string.Empty; var connectedAsset = assetProp.GetConnectedProperty(0) as Asset; if (connectedAsset == null) return string.Empty; double x, y; string res = string.Empty; GetMapNameAndScale(connectedAsset, out res, out x, out y); if (string.IsNullOrEmpty(res)) return string.Empty; scaleX = x; scaleY = y; return res; }
private string FindTexturePathInAssetProperty(AssetProperty assetProperty) { AssetPropertyType type = assetProperty.Type; if (type != AssetPropertyType.String) //String = 11,非字符串类型,判定为Asset类型。 { if (type == AssetPropertyType.Asset) //Asset = 15 { string text = FindTexturePathInAsset(assetProperty as Asset); if (text.Length > 0) { return(text); } } } else if (assetProperty.Name == "unifiedbitmap_Bitmap") { return((assetProperty as AssetPropertyString).Value.ToString()); } for (int i = 0; i < assetProperty.NumberOfConnectedProperties; i++) { string text2 = FindTexturePathInAssetProperty(assetProperty.GetConnectedProperty(i)); if (text2.Length > 0) { return(text2); } } return(""); }
void ChangeRenderingTexturePath(Document doc) { // As there is only one material in the sample // project, we can use FilteredElementCollector // and grab the first result Material mat = new FilteredElementCollector(doc).OfClass(typeof(Material)).FirstElement() as Material; // Fixed path for new texture // Texture included in sample files string texturePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "new_texture.png"); using (Transaction t = new Transaction(doc)) { t.Start("Changing material texture path"); using (AppearanceAssetEditScope editScope = new AppearanceAssetEditScope(doc)) { Asset editableAsset = editScope.Start(mat.AppearanceAssetId); // Getting the correct AssetProperty AssetProperty assetProperty = editableAsset["generic_diffuse"]; Asset connectedAsset = assetProperty.GetConnectedProperty(0) as Asset; // Getting the right connected Asset if (connectedAsset.Name == "UnifiedBitmapSchema") { AssetPropertyString path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString; if (path.IsValidValue(texturePath)) { path.Value = texturePath; } } editScope.Commit(true); } TaskDialog.Show("Material texture path", "Material texture path changed to:\n" + texturePath); t.Commit(); t.Dispose(); } }
/// <summary> /// 更改外观 /// </summary> /// <param name="material"></param> /// <param name="bumpmapImageFilepath"></param> public static void ChangeRenderingTexturePath(Material mat, Document doc, string texturePath, double x, double y) { using (AppearanceAssetEditScope editScope = new AppearanceAssetEditScope(doc)) { Asset editableAsset = editScope.Start(mat.AppearanceAssetId); #if VERSION2018 AssetProperty assetProperty = editableAsset["generic_diffuse"]; #else // VERSION2019 AssetProperty assetProperty = editableAsset.FindByName("generic_diffuse"); #endif Asset connectedAsset = assetProperty.GetConnectedProperty(0) as Asset; /*if (connectedAsset == null) * { * * // Add a new default connected asset * assetProperty.AddConnectedAsset("UnifiedBitmap"); * connectedAsset = assetProperty.GetSingleConnectedAsset(); * }*/ if (connectedAsset.Name == "UnifiedBitmapSchema") { // TaskDialog.Show("Tip", "成功"); AssetPropertyString path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString; AssetPropertyBoolean scalelock = connectedAsset.FindByName(UnifiedBitmap.TextureScaleLock) as AssetPropertyBoolean; scalelock.Value = false; AssetPropertyDistance sizeY = connectedAsset.FindByName(UnifiedBitmap.TextureRealWorldScaleY) as AssetPropertyDistance; sizeY.Value = y; AssetPropertyDistance sizeX = connectedAsset.FindByName(UnifiedBitmap.TextureRealWorldScaleX) as AssetPropertyDistance; sizeX.Value = x; if (path.IsValidValue(texturePath)) { path.Value = texturePath; } else { throw new Exception("找不到文件:" + texturePath); //TaskDialog.Show("Tip", "文件路径错误"); } } editScope.Commit(true); } }
private Asset FindTextureAsset(AssetProperty assetProperty) { //查找纹理贴图资源 //获取资源属性的数据类型。 AssetPropertyType type = assetProperty.Type; if (type.Equals(AssetPropertyType.Asset)) { try { Asset asset = assetProperty as Asset; if (IsTextureAsset(asset)) { Asset result = asset; return(result); } for (int i = 0; i < asset.Size; i++) { Asset asset2 = FindTextureAsset(asset.Get(i)); if (asset2 != null) { Asset result = asset2; return(result); } } } catch (Exception) { } } if (assetProperty.Name.IndexOf("bump", StringComparison.OrdinalIgnoreCase) < 0 && assetProperty.Name.IndexOf("opacity", StringComparison.OrdinalIgnoreCase) < 0 && assetProperty.Name.IndexOf("shader", StringComparison.OrdinalIgnoreCase) < 0 && assetProperty.Name.IndexOf("pattern", StringComparison.OrdinalIgnoreCase) < 0 && assetProperty.Name.IndexOf("_map", StringComparison.OrdinalIgnoreCase) < 0 && assetProperty.Name.IndexOf("transparency", StringComparison.OrdinalIgnoreCase) < 0) { for (int j = 0; j < assetProperty.NumberOfConnectedProperties; j++) { Asset asset3 = FindTextureAsset(assetProperty.GetConnectedProperty(j)); if (asset3 != null) { return(asset3); } } } return(null); }
// 定义修改贴图路径的方法 public string ChangeRenderingTexturePath(Document doc, Material mat, string newPath) { try { using (Transaction t = new Transaction(doc)) { t.Start("更改贴图位置"); using (AppearanceAssetEditScope editScope = new AppearanceAssetEditScope(doc)) { Asset editableAsset = editScope.Start(mat.AppearanceAssetId); // Getting the correct AssetProperty AssetProperty assetProperty = editableAsset.FindByName("generic_diffuse"); if (assetProperty is null) { assetProperty = editableAsset.FindByName("masonrycmu_color"); } Asset connectedAsset = assetProperty.GetConnectedProperty(0) as Asset; // getting the right connected Asset if (connectedAsset.Name == "UnifiedBitmapSchema") { AssetPropertyString path = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString; if (path.IsValidValue(newPath)) { path.Value = newPath; } } editScope.Commit(true); } t.Commit(); t.Dispose(); } return(mat.Name); } catch (Exception) { TaskDialog.Show("错误提示!!!", "材质【" + mat.Name + "】的贴图更改失败,请手动更改材质贴图"); return(null); } }
void FindTextureBitmapPaths(Document doc) { // Find materials FilteredElementCollector fec = new FilteredElementCollector(doc); fec.OfClass(typeof(Material)); IEnumerable <Material> targetMaterials = fec.Cast <Material>().Where <Material>(mtl => targetMaterialNames.Contains(mtl.Name)); foreach (Material material in targetMaterials) { // Get appearance asset for read ElementId appearanceAssetId = material .AppearanceAssetId; AppearanceAssetElement appearanceAssetElem = doc.GetElement(appearanceAssetId) as AppearanceAssetElement; Asset asset = appearanceAssetElem .GetRenderingAsset(); // Walk through all first level assets to find // connected Bitmap properties. Note: it is // possible to have multilevel connected // properties with Bitmaps in the leaf nodes. // So this would need to be recursive. int size = asset.Size; for (int assetIdx = 0; assetIdx < size; assetIdx++) { //AssetProperty aProperty = asset[assetIdx]; // 2018 AssetProperty aProperty = asset.Get(assetIdx); // 2019 if (aProperty.NumberOfConnectedProperties < 1) { continue; } // Find first connected property. // Should work for all current (2018) schemas. // Safer code would loop through all connected // properties based on the number provided. Asset connectedAsset = aProperty .GetConnectedProperty(0) as Asset; // We are only checking for bitmap connected assets. if (connectedAsset.Name == "UnifiedBitmapSchema") { // This line is 2018.1 & up because of the // property reference to UnifiedBitmap // .UnifiedbitmapBitmap. In earlier versions, // you can still reference the string name // instead: "unifiedbitmap_Bitmap" //AssetPropertyString path = connectedAsset[ // 2018 // UnifiedBitmap.UnifiedbitmapBitmap] // as AssetPropertyString; AssetPropertyString path = connectedAsset // 2019 .FindByName(UnifiedBitmap.UnifiedbitmapBitmap) as AssetPropertyString; // This will be a relative path to the // built -in materials folder, addiitonal // render appearance folder, or an // absolute path. TaskDialog.Show("Connected bitmap", String.Format("{0} from {2}: {1}", aProperty.Name, path.Value, connectedAsset.LibraryName)); } } } }
public static List <TextureBundle> GetTextureBundles(Document doc, out List <string> paths) { if (_bundleCache.ContainsKey(doc.PathName)) { paths = _texturePathCache[doc.PathName]; return(_bundleCache[doc.PathName]); } _texturePathCache.Add(doc.PathName, new List <string>()); // Find materials FilteredElementCollector fec = new FilteredElementCollector(doc).OfClass(typeof(Material)); // Convert materials to bundles List <TextureBundle> bundles = new List <TextureBundle>(); foreach (var m in fec.Cast <Material>()) { try { var bundle = new TextureBundle(m); ElementId appearanceAssetId = m.AppearanceAssetId; AppearanceAssetElement appearanceAssetElem = doc.GetElement(appearanceAssetId) as AppearanceAssetElement; if (appearanceAssetElem == null) { continue; } Asset asset = appearanceAssetElem .GetRenderingAsset(); if (asset == null) { continue; } for (int assetIdx = 0; assetIdx < asset.Size; assetIdx++) { AssetProperty aProperty = asset[assetIdx]; if (aProperty.NumberOfConnectedProperties < 1) { continue; } Asset connectedAsset = aProperty .GetConnectedProperty(0) as Asset; // See if there is a path associated. #if REVIT2018 || REVIT2019 || REVIT2020 // This line is 2018.1 & up because of the // property reference to UnifiedBitmap // .UnifiedbitmapBitmap. In earlier versions, // you can still reference the string name // instead: "unifiedbitmap_Bitmap" AssetPropertyString path = connectedAsset[ UnifiedBitmap.UnifiedbitmapBitmap] as AssetPropertyString; #else AssetPropertyString path = connectedAsset["unifiedbitmap_Bitmap"] as AssetPropertyString; #endif // If there is no asset path, nothing to pursue (Empty field) if (path == null || String.IsNullOrEmpty(path.Value)) { continue; } // See what kind of texture it is. if (TryGetTextureTypeFromAssetName(connectedAsset.Name, out var t)) { // This will be a relative path to the // built -in materials folder, addiitonal // render appearance folder, or an // absolute path. string assetName = Path.GetFileNameWithoutExtension(path.Value); // Ensure that we have a valid texture path. if (RevitTextures.ContainsKey(assetName)) { bundle.TexturePaths.Add(t, new SafenedFilename(RevitTextures[assetName])); } else { //Logger.LogError( // $"Found asset outisde of Revit material lib: {path.Value}. Could not add to export" // ); } } } // Return the bundle we created. bundles.Add(bundle); } catch (Exception e) { //Logger.LogException("Error in bundle creation: ", e); } } var bundleList = bundles.Where(b => b != null).ToList(); _bundleCache.Add(doc.PathName, bundleList); paths = _texturePathCache[doc.PathName]; return(bundleList); }
/// <summary> /// 获取属性说明 /// text = assetProperty.Name + ": " + assetProperty.Type.ToString() + " " + 属性值 + "CONNECTED START\n" + 多个assetProperty + "CONNECTED END\n" /// </summary> /// <param name="assetProperty"></param> /// <returns></returns> public string GetPropertyDescription(AssetProperty assetProperty) { string text = assetProperty.Name + ": " + assetProperty.Type.ToString() + " "; //数值代表变量类型。获取属性值并加入字符串末尾。 switch (assetProperty.Type) { case AssetPropertyType.Boolean: text += (assetProperty as AssetPropertyBoolean).Value.ToString(); break; case AssetPropertyType.Enumeration: text += (assetProperty as AssetPropertyEnum).Value.ToString(); break; case AssetPropertyType.Integer: text += (assetProperty as AssetPropertyInteger).Value.ToString(); break; case AssetPropertyType.Float: text += (assetProperty as AssetPropertyFloat).Value.ToString(); break; case AssetPropertyType.Double1: text += (assetProperty as AssetPropertyDouble).Value.ToString(); break; case AssetPropertyType.Double2: text += (assetProperty as AssetPropertyDoubleArray2d).Value.ToString(); break; case AssetPropertyType.Double3: text += (assetProperty as AssetPropertyDoubleArray3d).GetValueAsDoubles().ToString(); break; case AssetPropertyType.Double4: text += (assetProperty as AssetPropertyDoubleArray4d).GetValueAsDoubles().ToString(); break; case AssetPropertyType.Double44: text += (assetProperty as AssetPropertyDoubleMatrix44).Value.ToString(); break; case AssetPropertyType.String: text += (assetProperty as AssetPropertyString).Value.ToString(); break; case AssetPropertyType.Distance: text += (assetProperty as AssetPropertyDistance).Value.ToString(); break; case AssetPropertyType.Asset: text = text + "\n" + GetAssetDescription(assetProperty as Asset); break; case AssetPropertyType.Longlong: text += (assetProperty as AssetPropertyInt64).Value.ToString(); break; case AssetPropertyType.ULonglong: text += (assetProperty as AssetPropertyUInt64).Value.ToString(); break; case AssetPropertyType.Float3: text += (assetProperty as AssetPropertyFloatArray).GetValue().ToString(); break; } //添加换行。 text += "\n"; //当前连接的属性数。 if (assetProperty.NumberOfConnectedProperties > 0) { text += "CONNECTED START\n"; } for (int i = 0; i < assetProperty.NumberOfConnectedProperties; i++) { text = text + " " + GetPropertyDescription(assetProperty.GetConnectedProperty(i)); } if (assetProperty.NumberOfConnectedProperties > 0) { text += "CONNECTED END\n"; } return(text); }