添加项目文件。
This commit is contained in:
506
Szmedi.RvKits/ModelManager/MaterialBatchViewModel.cs
Normal file
506
Szmedi.RvKits/ModelManager/MaterialBatchViewModel.cs
Normal file
@@ -0,0 +1,506 @@
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.Visual;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External.Handlers;
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using System.Windows.Controls;
|
||||
|
||||
using Szmedi.RvKits.Assists;
|
||||
|
||||
namespace Szmedi.RvKits.ModelManager;
|
||||
|
||||
public partial class MaterialBatchViewModel : ObservableObject
|
||||
{
|
||||
public MaterialBatchViewModel(UIApplication uiapp)
|
||||
{
|
||||
doc = uiapp.ActiveUIDocument.Document;
|
||||
var mats = new FilteredElementCollector(doc).OfClass(typeof(Material)).Cast<Material>();
|
||||
materials = new ObservableCollection<Material>(mats);
|
||||
this.uiapp = uiapp;
|
||||
materialHandler = new();
|
||||
}
|
||||
|
||||
private readonly ActionEventHandler materialHandler;
|
||||
private readonly Document doc;
|
||||
private readonly ObservableCollection<Material> materials;
|
||||
private readonly UIApplication uiapp;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isFloor = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isStructuralColumn = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isStructuralFraming = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isWall = true;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(FilteredList))]
|
||||
private string searchText;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(ApplyCustomMaterialCommand))]
|
||||
private Material selectedMaterial;
|
||||
|
||||
//[RelayCommand]
|
||||
//private void MaterialEdit()
|
||||
//{
|
||||
// RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.Materials);
|
||||
// // var ptr = WinIntPtr.FindWindow(null, "材质浏览器");
|
||||
// var mainWindowHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
|
||||
// if (mainWindowHandle != IntPtr.Zero)
|
||||
// {
|
||||
// IntPtr materialDialog = WinIntPtr.FindWindowEx(mainWindowHandle, IntPtr.Zero, null, null);
|
||||
// if (materialDialog != IntPtr.Zero)
|
||||
// {
|
||||
// if (uiapp.CanPostCommand(commandId))
|
||||
// {
|
||||
// Revit.Async.RevitTask.RunAsync(() =>
|
||||
// {
|
||||
// uiapp.PostCommand(commandId);
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
public IEnumerable<Material> FilteredList =>
|
||||
IsIllumMaterial == true
|
||||
? GetEmissiveMat(doc)
|
||||
: string.IsNullOrEmpty(SearchText)
|
||||
? materials
|
||||
: materials.Where(x => x.Name.Contains(SearchText));
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(FilteredList))]
|
||||
private bool? isIllumMaterial = false;
|
||||
|
||||
[RelayCommand(CanExecute = nameof(StandardCanRun))]
|
||||
private void ApplyStandardMaterial(ComboBoxItem item)
|
||||
{
|
||||
var materialName = item.Content.ToString();
|
||||
materialHandler.Raise(uiapp =>
|
||||
{
|
||||
try
|
||||
{
|
||||
#if REVIT2018
|
||||
var assetPropertyConcreteVersionGuid = "ACADGen-006";
|
||||
var assetPropertyMetalVersionGuid = "Metal-047"; //缎光
|
||||
// string assetPropertyMetalVersionGuid = "InvGen-028";//钢板
|
||||
#elif REVIT2019 || REVIT2020
|
||||
string assetPropertyConcreteVersionGuid = "Prism-1100"; //如果有贴图,前缀加上t_就是贴图的文件名
|
||||
string assetPropertyMetalVersionGuid = "Metal-047";
|
||||
#endif
|
||||
Material material = null;
|
||||
StandardCanRun = false;
|
||||
using (var tg = new TransactionGroup(doc, $"应用标准{materialName}材质"))
|
||||
{
|
||||
tg.Start();
|
||||
using (Transaction ts = new(doc, $"{materialName}材质创建"))
|
||||
{
|
||||
ts.Start();
|
||||
if (materialName == "混凝土")
|
||||
{
|
||||
material = CreateConcreteMaterial(
|
||||
uiapp,
|
||||
"混凝土,现场浇注",
|
||||
"混凝土",
|
||||
"混凝土 - 现场浇注",
|
||||
assetPropertyConcreteVersionGuid,
|
||||
new Color(192, 192, 192)
|
||||
);
|
||||
}
|
||||
else if (materialName == "钢")
|
||||
{
|
||||
material = CreateConcreteMaterial(uiapp, "金属,钢", "金属", "钢材", assetPropertyMetalVersionGuid, new Color(247, 247, 247));
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.RollBack();
|
||||
}
|
||||
ts.Commit();
|
||||
}
|
||||
ApplyMaterial(material);
|
||||
tg.Assimilate();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
StandardCanRun = true;
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanApplyCustomMaterial))]
|
||||
private void ApplyCustomMaterial(Material material)
|
||||
{
|
||||
materialHandler.Raise(_ =>
|
||||
{
|
||||
CustomCanRun = false;
|
||||
try
|
||||
{
|
||||
ApplyMaterial(material);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
CustomCanRun = true;
|
||||
});
|
||||
}
|
||||
|
||||
private void ApplyMaterial(Material material)
|
||||
{
|
||||
var framingCatId = Category.GetCategory(doc, BuiltInCategory.OST_StructuralFraming).Id;
|
||||
var columnCatId = Category.GetCategory(doc, BuiltInCategory.OST_StructuralColumns).Id;
|
||||
try
|
||||
{
|
||||
var elements = uiapp.ActiveUIDocument.Selection
|
||||
.PickElementsByRectangle(
|
||||
new FuncFilter(
|
||||
elem =>
|
||||
{
|
||||
var flag1 = IsFloor && elem is Floor;
|
||||
var flag2 = IsWall && elem is Wall wall && wall.WallType.Kind == WallKind.Basic;
|
||||
var flag3 = IsStructuralColumn &&
|
||||
elem is FamilyInstance &&
|
||||
elem.Category.Id == columnCatId;
|
||||
var flag4 = IsStructuralFraming &&
|
||||
elem is FamilyInstance &&
|
||||
elem.Category.Id == framingCatId;
|
||||
return flag1 || flag2 || flag3 || flag4;
|
||||
},
|
||||
(_, _) => true),
|
||||
"请框选元素");
|
||||
|
||||
using Transaction ts = new(doc, $"应用{material.Name}材质");
|
||||
ts.Start();
|
||||
foreach (var elem in elements)
|
||||
{
|
||||
if (elem is FamilyInstance framing && elem.Category.Id == framingCatId)
|
||||
{
|
||||
var param = framing.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
|
||||
param?.Set(material.Id);
|
||||
}
|
||||
else if (elem is Wall wall)
|
||||
{
|
||||
var structure = wall.WallType.GetCompoundStructure();
|
||||
structure.SetMaterialId(structure.StructuralMaterialIndex, material.Id);
|
||||
wall.WallType.SetCompoundStructure(structure);
|
||||
}
|
||||
else if (elem is Floor floor)
|
||||
{
|
||||
var structure = floor.FloorType.GetCompoundStructure();
|
||||
structure.SetMaterialId(structure.StructuralMaterialIndex, material.Id);
|
||||
floor.FloorType.SetCompoundStructure(structure);
|
||||
}
|
||||
else if (elem is FamilyInstance column && elem.Category.Id == columnCatId)
|
||||
{
|
||||
var param = column.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
|
||||
param?.Set(material.Id);
|
||||
}
|
||||
}
|
||||
ts.Commit();
|
||||
}
|
||||
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(ApplyStandardMaterialCommand))]
|
||||
private bool standardCanRun = true;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(ApplyCustomMaterialCommand))]
|
||||
private bool customCanRun = true;
|
||||
private bool CanApplyCustomMaterial(Material material)
|
||||
{
|
||||
return material is not null && CustomCanRun;
|
||||
}
|
||||
|
||||
private static List<Material> GetEmissiveMat(Document doc)
|
||||
{
|
||||
var materials = new FilteredElementCollector(doc).OfClass(typeof(Material)).ToElements().Cast<Material>();
|
||||
List<Material> emissiveMat = [];
|
||||
foreach (var material in materials)
|
||||
{
|
||||
if (doc.GetElement(material.AppearanceAssetId) is AppearanceAssetElement assetElem)
|
||||
{
|
||||
var asset = assetElem.GetRenderingAsset();
|
||||
#if REVIT2018
|
||||
var prop = asset["generic_self_illum_luminance"];
|
||||
#elif REVIT2020 || REVIT2019
|
||||
var prop = asset.FindByName("generic_self_illum_luminance");
|
||||
#endif
|
||||
var d = prop as AssetPropertyDouble;
|
||||
if (d?.Value > 0)
|
||||
{
|
||||
emissiveMat.Add(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
return emissiveMat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置材质颜色
|
||||
/// </summary>
|
||||
/// <param name="uiapp"></param>
|
||||
/// <param name="materialName"></param>
|
||||
/// <param name="materialCategoryClass"></param>
|
||||
/// <param name="appearanceAssetName"></param>
|
||||
/// <param name="assetPropertyVersionGuid"></param>
|
||||
/// <param name="shading">着色颜色</param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="cutPatternName"></param>
|
||||
/// <param name="surfacePatternName"></param>
|
||||
/// <returns></returns>
|
||||
private static Material CreateConcreteMaterial(
|
||||
UIApplication uiapp,
|
||||
string materialName,
|
||||
string materialCategoryClass,
|
||||
string appearanceAssetName,
|
||||
string assetPropertyVersionGuid,
|
||||
Color shading,
|
||||
Color color,
|
||||
string cutPatternName,
|
||||
string surfacePatternName
|
||||
)
|
||||
{
|
||||
Material material;
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
var materials = new FilteredElementCollector(doc)
|
||||
.OfClass(typeof(Material))
|
||||
.Cast<Material>()
|
||||
.Where(m => m.Name == materialName);
|
||||
var assets = uiapp.Application.GetAssets(AssetType.Appearance);
|
||||
|
||||
if (materials.Any())
|
||||
{
|
||||
material = materials.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
using Transaction ts = new(doc, $"新建{materialName}材质");
|
||||
ts.Start();
|
||||
var matId = Material.Create(doc, materialName);
|
||||
material = doc.GetElement(matId) as Material;
|
||||
ts.Commit();
|
||||
}
|
||||
|
||||
using (Transaction name = new(doc, $"定义{materialCategoryClass}材质"))
|
||||
{
|
||||
name.Start();
|
||||
if (material != null)
|
||||
{
|
||||
material.Color = shading;
|
||||
material.MaterialClass = materialCategoryClass;
|
||||
material.MaterialCategory = materialCategoryClass;
|
||||
var asset = assets.FirstOrDefault(a =>
|
||||
{
|
||||
var propStr = a.FindByName("VersionGUID") as AssetPropertyString;
|
||||
return propStr?.Value == assetPropertyVersionGuid;
|
||||
});
|
||||
AppearanceAssetElement appearanceAssetElement = null;
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
appearanceAssetName = $"{appearanceAssetName}({i})";
|
||||
if (AppearanceAssetElement.GetAppearanceAssetElementByName(doc, appearanceAssetName) == null)
|
||||
{
|
||||
appearanceAssetElement = AppearanceAssetElement.Create(doc, appearanceAssetName, asset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (appearanceAssetElement != null)
|
||||
{
|
||||
material.AppearanceAssetId = appearanceAssetElement.Id;
|
||||
}
|
||||
|
||||
var pattern1 = FillPatternElement.GetFillPatternElementByName(
|
||||
doc,
|
||||
FillPatternTarget.Drafting,
|
||||
cutPatternName
|
||||
);
|
||||
var pattern2 = FillPatternElement.GetFillPatternElementByName(
|
||||
doc,
|
||||
FillPatternTarget.Drafting,
|
||||
surfacePatternName
|
||||
);
|
||||
#if REVIT2018
|
||||
|
||||
material.CutPatternColor = color;
|
||||
material.SurfacePatternColor = color;
|
||||
if (pattern1 != null)
|
||||
{
|
||||
material.CutPatternId = pattern1.Id;
|
||||
}
|
||||
|
||||
if (pattern2 != null)
|
||||
{
|
||||
material.SurfacePatternId = pattern2.Id;
|
||||
}
|
||||
#else
|
||||
material.CutBackgroundPatternColor = color;
|
||||
material.CutForegroundPatternColor = color;
|
||||
material.SurfaceBackgroundPatternColor = color;
|
||||
material.SurfaceForegroundPatternColor = color;
|
||||
if (pattern1 != null)
|
||||
{
|
||||
material.CutBackgroundPatternId = pattern1.Id;
|
||||
material.CutForegroundPatternId = pattern1.Id;
|
||||
}
|
||||
|
||||
if (pattern2 != null)
|
||||
{
|
||||
material.SurfaceBackgroundPatternId = pattern2.Id;
|
||||
material.SurfaceForegroundPatternId = pattern2.Id;
|
||||
}
|
||||
#endif
|
||||
material.UseRenderAppearanceForShading = false;
|
||||
}
|
||||
|
||||
name.Commit();
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
private static Material CreateConcreteMaterial(
|
||||
UIApplication uiapp,
|
||||
string materialName,
|
||||
string materialCategoryClass,
|
||||
string appearanceAssetName,
|
||||
string assetPropertyVersionGuid,
|
||||
Color shadingColor
|
||||
)
|
||||
{
|
||||
Material material;
|
||||
var doc = uiapp.ActiveUIDocument.Document;
|
||||
var materials = new FilteredElementCollector(doc)
|
||||
.OfClass(typeof(Material))
|
||||
.Cast<Material>()
|
||||
.Where(m => m.Name == materialName);
|
||||
var assets = uiapp.Application.GetAssets(AssetType.Appearance);
|
||||
//获取或创建材质
|
||||
if (materials.Any())
|
||||
{
|
||||
material = materials.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
using SubTransaction ts = new(doc);
|
||||
ts.Start();
|
||||
var matId = Material.Create(doc, materialName);
|
||||
material = doc.GetElement(matId) as Material;
|
||||
ts.Commit();
|
||||
}
|
||||
//应用外观
|
||||
using (SubTransaction name = new(doc))
|
||||
{
|
||||
name.Start();
|
||||
if (material != null)
|
||||
{
|
||||
material.Color = shadingColor;
|
||||
material.MaterialClass = materialCategoryClass;
|
||||
material.MaterialCategory = materialCategoryClass;
|
||||
var asset = assets.FirstOrDefault(a =>
|
||||
{
|
||||
var propStr = a.FindByName("VersionGUID") as AssetPropertyString;
|
||||
return propStr?.Value == assetPropertyVersionGuid;
|
||||
});
|
||||
AppearanceAssetElement appearanceAssetElement = null;
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
appearanceAssetName = $"{appearanceAssetName}({i})";
|
||||
if (AppearanceAssetElement.GetAppearanceAssetElementByName(doc, appearanceAssetName) == null)
|
||||
{
|
||||
appearanceAssetElement = AppearanceAssetElement.Create(doc, appearanceAssetName, asset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (appearanceAssetElement != null)
|
||||
{
|
||||
material.AppearanceAssetId = appearanceAssetElement.Id;
|
||||
}
|
||||
material.UseRenderAppearanceForShading = false;
|
||||
}
|
||||
|
||||
name.Commit();
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CloseWin()
|
||||
{
|
||||
SendESCToRevit();
|
||||
}
|
||||
|
||||
private static void SendKeyToRevit(byte bVk, byte dwFlags)
|
||||
{
|
||||
var Revit = Autodesk.Windows.ComponentManager.ApplicationWindow;
|
||||
WinIntPtr.SetForegroundWindow(Revit);
|
||||
keybd_event(bVk, 0, dwFlags, 0);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
|
||||
|
||||
public static void SendESCToRevit()
|
||||
{
|
||||
SendKeyToRevit(0x1B, 0);
|
||||
SendKeyToRevit(0x1B, 2);
|
||||
}
|
||||
//private static void SetStructuralComponents(Material material)
|
||||
//{
|
||||
// var doc = material.doc;
|
||||
// var columns = new FilteredElementCollector(doc).QueryElementsByType(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralColumns);
|
||||
// var floors = new FilteredElementCollector(doc).QueryElementsByType(typeof(Floor)).OfCategory(BuiltInCategory.OST_Floors).Cast<Floor>().GroupBy(floor => floor.FloorType);
|
||||
// var framings = new FilteredElementCollector(doc).QueryElementsByType(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralFraming);
|
||||
// var walls = new FilteredElementCollector(doc).QueryElementsByType(typeof(Wall)).OfCategory(BuiltInCategory.OST_Walls).Cast<Wall>().Where(wall => wall.WallType.Kind == WallKind.Basic).GroupBy(wall => wall.WallType);
|
||||
// foreach (var column in columns)
|
||||
// {
|
||||
// var param = column.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
|
||||
// param?.Set(material.Id);
|
||||
// }
|
||||
|
||||
// foreach (var framing in framings)
|
||||
// {
|
||||
// var param = framing.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
|
||||
// param?.Set(material.Id);
|
||||
// }
|
||||
|
||||
// foreach (var wall in walls)
|
||||
// {
|
||||
// var structure = wall.Key.GetCompoundStructure();
|
||||
// structure.SetMaterialId(structure.StructuralMaterialIndex, material.Id);
|
||||
|
||||
// wall.Key.SetCompoundStructure(structure);
|
||||
// }
|
||||
|
||||
// foreach (var floor in floors)
|
||||
// {
|
||||
// var structure = floor.Key.GetCompoundStructure();
|
||||
// structure.SetMaterialId(structure.StructuralMaterialIndex, material.Id);
|
||||
// floor.Key.SetCompoundStructure(structure);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
Reference in New Issue
Block a user