TellmeRevitPluging/Services/RevitService.cs

1011 lines
39 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using RevitHttpControl.Models;
namespace RevitHttpControl.Services
{
/// <summary>
/// Revit API 操作服务
/// </summary>
public static class RevitService
{
/// <summary>
/// 获取当前文档信息
/// </summary>
/// <returns>当前文档信息</returns>
public static CurrentDocumentInfo GetCurrentDocumentInfo()
{
var documentInfo = new CurrentDocumentInfo
{
IsOpen = false,
FileName = null,
FilePath = null
};
try
{
// 尝试获取当前活动文档信息
if (App.Instance != null)
{
// 通过队列执行获取文档信息的操作
var docInfoResult = new CurrentDocumentInfo
{
IsOpen = false,
FileName = null,
FilePath = null
};
var completed = false;
Exception executionException = null;
App.Instance.EnqueueCommand(uiApp =>
{
try
{
System.Diagnostics.Debug.WriteLine("RevitService: Getting document info...");
var activeDoc = uiApp.ActiveUIDocument?.Document;
if (activeDoc != null)
{
System.Diagnostics.Debug.WriteLine($"RevitService: Found active document: {activeDoc.Title}");
docInfoResult.IsOpen = true;
// 处理文档路径
var pathName = activeDoc.PathName;
if (!string.IsNullOrEmpty(pathName))
{
docInfoResult.FileName = Path.GetFileName(pathName);
docInfoResult.FilePath = pathName;
System.Diagnostics.Debug.WriteLine($"RevitService: Document path: {pathName}");
}
else
{
// 对于未保存的文档使用Title
docInfoResult.FileName = activeDoc.Title;
docInfoResult.FilePath = null;
System.Diagnostics.Debug.WriteLine($"RevitService: Unsaved document: {activeDoc.Title}");
}
}
else
{
System.Diagnostics.Debug.WriteLine("RevitService: No active document found");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"RevitService: Exception getting document info: {ex.Message}");
executionException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待3秒
var timeout = DateTime.Now.AddSeconds(3);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(50);
}
if (!completed)
{
System.Diagnostics.Debug.WriteLine("RevitService: Timeout waiting for document info");
return documentInfo; // 返回默认值
}
if (executionException != null)
{
System.Diagnostics.Debug.WriteLine($"RevitService: Execution failed: {executionException.Message}");
return documentInfo; // 返回默认值
}
return docInfoResult;
}
else
{
System.Diagnostics.Debug.WriteLine("RevitService: App.Instance is null");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"RevitService: Outer exception: {ex.Message}");
}
return documentInfo;
}
/// <summary>
/// 获取元素统计数量
/// </summary>
/// <param name="type">统计类型</param>
/// <returns>元素数量</returns>
public static int GetElementCount(StatsType type)
{
try
{
var count = 0;
var completed = false;
Exception capturedException = null;
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc != null)
{
var collector = new FilteredElementCollector(doc);
var category = GetBuiltInCategory(type);
count = collector.OfCategory(category).Count();
}
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待5秒
var timeout = DateTime.Now.AddSeconds(5);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(50);
}
if (capturedException != null)
throw capturedException;
return count;
}
catch (Exception ex)
{
throw new InvalidOperationException($"获取 {type} 统计数据失败: {ex.Message}", ex);
}
}
/// <summary>
/// 异步获取元素统计数量
/// </summary>
/// <param name="type">统计类型</param>
/// <param name="taskId">任务ID</param>
/// <param name="taskManager">任务管理器</param>
public static void GetElementCountAsync(StatsType type, Guid taskId, TaskManager taskManager)
{
try
{
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc != null)
{
var collector = new FilteredElementCollector(doc);
var category = GetBuiltInCategory(type);
var count = collector.OfCategory(category).Count();
// 构建完整的统计响应
var statsResponse = new SyncStatsResponse
{
ElementType = type.ToString(),
Count = count,
Details = new StatsDetails
{
TypeName = GetStatsTypeDisplayName(type),
TypeId = (int)category
}
};
// 将完整结果存储到任务管理器
taskManager.CompleteTask(taskId, statsResponse);
}
else
{
taskManager.FailTask(taskId, "没有打开的文档");
}
}
catch (Exception ex)
{
taskManager.FailTask(taskId, ex.Message);
}
});
}
catch (Exception ex)
{
taskManager.FailTask(taskId, ex.Message);
}
}
/// <summary>
/// 统计类型到 BuiltInCategory 的映射
/// </summary>
/// <param name="type">统计类型</param>
/// <returns>对应的 BuiltInCategory</returns>
public static BuiltInCategory GetBuiltInCategory(StatsType type)
{
switch (type)
{
case StatsType.Wall:
return BuiltInCategory.OST_Walls;
case StatsType.Door:
return BuiltInCategory.OST_Doors;
case StatsType.Window:
return BuiltInCategory.OST_Windows;
case StatsType.Floor:
return BuiltInCategory.OST_Floors;
case StatsType.Ceiling:
return BuiltInCategory.OST_Ceilings;
case StatsType.Roof:
return BuiltInCategory.OST_Roofs;
case StatsType.Column:
return BuiltInCategory.OST_Columns;
case StatsType.Beam:
return BuiltInCategory.OST_StructuralFraming;
case StatsType.Furniture:
return BuiltInCategory.OST_Furniture;
case StatsType.Room:
return BuiltInCategory.OST_Rooms;
default:
throw new ArgumentException($"不支持的统计类型: {type}");
}
}
/// <summary>
/// 获取元素统计详细信息
/// </summary>
/// <param name="type">统计类型</param>
/// <returns>详细统计信息</returns>
public static SyncStatsResponse GetElementStatsDetail(StatsType type)
{
try
{
var count = 0;
var completed = false;
Exception capturedException = null;
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc != null)
{
var collector = new FilteredElementCollector(doc);
var category = GetBuiltInCategory(type);
count = collector.OfCategory(category).Count();
}
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待5秒
var timeout = DateTime.Now.AddSeconds(5);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(50);
}
if (capturedException != null)
throw capturedException;
// 构建完整的响应
return new SyncStatsResponse
{
ElementType = type.ToString(),
Count = count,
Details = new StatsDetails
{
TypeName = GetStatsTypeDisplayName(type),
TypeId = (int)GetBuiltInCategory(type)
}
};
}
catch (Exception ex)
{
throw new InvalidOperationException($"获取 {type} 统计数据失败: {ex.Message}", ex);
}
}
/// <summary>
/// 获取统计类型的中文显示名称
/// </summary>
/// <param name="type">统计类型</param>
/// <returns>中文名称</returns>
public static string GetStatsTypeDisplayName(StatsType type)
{
switch (type)
{
case StatsType.Wall:
return "墙体";
case StatsType.Door:
return "门";
case StatsType.Window:
return "窗";
case StatsType.Floor:
return "楼板";
case StatsType.Ceiling:
return "天花板";
case StatsType.Roof:
return "屋顶";
case StatsType.Column:
return "柱";
case StatsType.Beam:
return "梁";
case StatsType.Furniture:
return "家具";
case StatsType.Room:
return "房间";
default:
return type.ToString();
}
}
/// <summary>
/// 快速获取模型总览信息
/// </summary>
/// <returns>模型总览信息</returns>
public static ModelOverviewResponse GetModelOverview()
{
try
{
ModelOverviewResponse overview = null;
var completed = false;
Exception capturedException = null;
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc == null)
{
throw new InvalidOperationException("没有打开的文档");
}
// 1. 项目基本信息
var filePath = doc.IsWorkshared ?
(doc.GetWorksharingCentralModelPath()?.ToString() ?? "中心文件路径未知") :
(!string.IsNullOrEmpty(doc.PathName) ? doc.PathName : "未保存");
// 获取文件大小
long fileSizeBytes = 0;
string fileSizeDisplay = "未知";
try
{
if (!string.IsNullOrEmpty(doc.PathName) && System.IO.File.Exists(doc.PathName))
{
var fileInfo = new System.IO.FileInfo(doc.PathName);
fileSizeBytes = fileInfo.Length;
fileSizeDisplay = FormatFileSize(fileSizeBytes);
}
else if (doc.IsWorkshared)
{
var centralPath = doc.GetWorksharingCentralModelPath();
if (centralPath != null)
{
var centralPathString = centralPath.ToString();
if (!string.IsNullOrEmpty(centralPathString) && System.IO.File.Exists(centralPathString))
{
var fileInfo = new System.IO.FileInfo(centralPathString);
fileSizeBytes = fileInfo.Length;
fileSizeDisplay = FormatFileSize(fileSizeBytes);
}
}
}
else
{
fileSizeDisplay = "未保存";
}
}
catch
{
fileSizeDisplay = "无法获取";
}
var projectInfo = new Models.ProjectInfo
{
Name = string.IsNullOrEmpty(doc.Title) ? "未命名项目" : doc.Title,
FilePath = filePath,
RevitVersion = uiApp.Application.VersionName,
IsCentralFile = doc.IsWorkshared,
Status = doc.IsModified ? "已修改" : "已保存",
FileSizeBytes = fileSizeBytes,
FileSizeDisplay = fileSizeDisplay,
PolygonCount = CalculatePolygonCountFast(doc, maxElements: 200, maxMilliseconds: 1200),
FeatureCount = CalculateFeatureCount(doc)
};
// 2. 快速统计主要构件(批量获取避免多次调用)
var elementCounts = new ElementCounts
{
Walls = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).Count(),
Doors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Doors).Count(),
Windows = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).Count(),
Floors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).Count(),
Ceilings = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Ceilings).Count(),
Columns = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Columns).Count(),
Beams = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).Count(),
Rooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).Count()
};
// 3. 模型组织结构信息
var structure = new ModelStructure
{
Levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).Count(),
FloorPlans = new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)).Count(),
Views3D = new FilteredElementCollector(doc).OfClass(typeof(View3D)).Count(),
Elevations = new FilteredElementCollector(doc).OfClass(typeof(View))
.Cast<View>().Count(v => v.ViewType == ViewType.Elevation),
Sections = new FilteredElementCollector(doc).OfClass(typeof(ViewSection)).Count(),
Sheets = new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)).Count()
};
// 4. 模型层级信息
var hierarchy = new ModelHierarchy
{
Levels = new List<LevelInfo>(),
Groups = new FilteredElementCollector(doc).OfClass(typeof(Group)).Count(),
Worksets = doc.IsWorkshared ? new FilteredWorksetCollector(doc).Count() : 0,
Phases = new FilteredElementCollector(doc).OfClass(typeof(Phase)).Count(),
DesignOptions = new FilteredElementCollector(doc).OfClass(typeof(DesignOption)).Count()
};
// 获取楼层详细信息
var levels = new FilteredElementCollector(doc)
.OfClass(typeof(Level))
.Cast<Level>()
.OrderBy(l => l.Elevation)
.ToList();
foreach (var level in levels)
{
hierarchy.Levels.Add(new LevelInfo
{
Name = level.Name,
Elevation = level.Elevation * 304.8 // 转换为毫米
});
}
// 5. 链接文件统计
var links = new LinkFiles
{
RevitLinks = new LinkCategory(),
CadLinks = new LinkCategory(),
PointClouds = 0,
Images = 0
};
// Revit链接统计
// 使用OfClass确保只获取RevitLinkInstance类型的元素
var revitLinkInstances = new FilteredElementCollector(doc)
.OfClass(typeof(RevitLinkInstance))
.Cast<RevitLinkInstance>();
links.RevitLinks.Total = revitLinkInstances.Count();
links.RevitLinks.Loaded = revitLinkInstances.Count(link => link.GetLinkDocument() != null);
links.RevitLinks.Unloaded = links.RevitLinks.Total - links.RevitLinks.Loaded;
// CAD链接统计
var cadLinkTypes = new FilteredElementCollector(doc)
.OfClass(typeof(CADLinkType))
.Cast<CADLinkType>();
links.CadLinks.Total = cadLinkTypes.Count();
// CAD链接状态检查通过实例检查
var cadInstances = new FilteredElementCollector(doc)
.OfClass(typeof(ImportInstance))
.Cast<ImportInstance>();
var loadedCadCount = 0;
foreach (var cadType in cadLinkTypes)
{
var hasInstance = cadInstances.Any(inst => inst.GetTypeId() == cadType.Id);
if (hasInstance) loadedCadCount++;
}
links.CadLinks.Loaded = loadedCadCount;
links.CadLinks.Unloaded = links.CadLinks.Total - links.CadLinks.Loaded;
// 点云链接
links.PointClouds = new FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_PointClouds).Count();
// 图像链接
links.Images = new FilteredElementCollector(doc)
.OfClass(typeof(ImageType)).Count();
// 生成链接文件总结
var totalLinks = links.RevitLinks.Total + links.CadLinks.Total + links.PointClouds + links.Images;
var loadedLinks = links.RevitLinks.Loaded + links.CadLinks.Loaded + links.PointClouds + links.Images;
links.Summary = totalLinks > 0 ?
$"{totalLinks}个链接文件,{loadedLinks}个已加载" :
"无链接文件";
// 组装总览响应
overview = new ModelOverviewResponse
{
Project = projectInfo,
Elements = elementCounts,
Structure = structure,
Hierarchy = hierarchy,
Links = links,
GeneratedAt = DateTime.Now
};
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待10秒因为信息较多
var timeout = DateTime.Now.AddSeconds(10);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(50);
}
if (capturedException != null)
throw capturedException;
if (!completed)
throw new TimeoutException("获取模型总览信息超时");
return overview;
}
catch (Exception ex)
{
throw new InvalidOperationException($"获取模型总览失败: {ex.Message}", ex);
}
}
/// <summary>
/// 格式化文件大小显示
/// </summary>
/// <param name="bytes">文件大小(字节)</param>
/// <returns>格式化的文件大小字符串</returns>
private static string FormatFileSize(long bytes)
{
const long KB = 1024;
const long MB = KB * 1024;
const long GB = MB * 1024;
if (bytes >= GB)
{
return $"{bytes / (double)GB:F1} GB";
}
else if (bytes >= MB)
{
return $"{bytes / (double)MB:F1} MB";
}
else if (bytes >= KB)
{
return $"{bytes / (double)KB:F1} KB";
}
else
{
return $"{bytes} 字节";
}
}
/// <summary>
/// 计算模型面片总数(基于可三角化几何)
/// </summary>
/// <param name="doc">Revit文档</param>
/// <returns>面片总数</returns>
private static long CalculatePolygonCountFast(Document doc, int maxElements, int maxMilliseconds)
{
long totalTriangles = 0;
var processedElements = 0;
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
try
{
var options = new Options
{
ComputeReferences = false,
IncludeNonVisibleObjects = false,
DetailLevel = ViewDetailLevel.Medium
};
var elements = new FilteredElementCollector(doc)
.WhereElementIsNotElementType()
.Where(e => e.Category != null && e.Category.CategoryType == CategoryType.Model);
foreach (var element in elements)
{
if (processedElements >= maxElements || stopwatch.ElapsedMilliseconds >= maxMilliseconds)
{
break;
}
GeometryElement geometry = null;
try
{
geometry = element.get_Geometry(options);
}
catch
{
continue;
}
if (geometry == null)
continue;
totalTriangles += CountTrianglesFromGeometry(geometry);
processedElements++;
}
}
catch
{
// 忽略计算异常并返回已累计值
}
return totalTriangles;
}
/// <summary>
/// 统计模型特征数(按模型类别去重)
/// </summary>
/// <param name="doc">Revit文档</param>
/// <returns>模型特征数</returns>
private static int CalculateFeatureCount(Document doc)
{
try
{
return new FilteredElementCollector(doc)
.WhereElementIsNotElementType()
.Where(e => e.Category != null && e.Category.CategoryType == CategoryType.Model)
.Select(e => e.Category.Id.IntegerValue)
.Distinct()
.Count();
}
catch
{
return 0;
}
}
/// <summary>
/// 递归统计几何中的三角面片数量
/// </summary>
/// <param name="geometry">几何对象集合</param>
/// <returns>三角面片数量</returns>
private static long CountTrianglesFromGeometry(GeometryElement geometry)
{
long triangles = 0;
foreach (var obj in geometry)
{
if (obj is Solid solid && solid.Faces != null && solid.Faces.Size > 0)
{
foreach (Face face in solid.Faces)
{
try
{
var mesh = face.Triangulate();
if (mesh != null)
triangles += mesh.NumTriangles;
}
catch
{
// 忽略单个面三角化失败
}
}
continue;
}
if (obj is Mesh meshObj)
{
triangles += meshObj.NumTriangles;
continue;
}
if (obj is GeometryInstance instance)
{
try
{
var instanceGeometry = instance.GetInstanceGeometry();
if (instanceGeometry != null)
triangles += CountTrianglesFromGeometry(instanceGeometry);
}
catch
{
// 忽略单个实例解析失败
}
}
}
return triangles;
}
/// <summary>
/// 获取文档文件大小(字节)
/// </summary>
private static long GetDocumentFileSize(Document doc)
{
try
{
if (doc == null)
return 0;
if (!string.IsNullOrEmpty(doc.PathName) && File.Exists(doc.PathName))
return new FileInfo(doc.PathName).Length;
if (doc.IsWorkshared)
{
var centralPath = doc.GetWorksharingCentralModelPath();
var centralPathString = centralPath?.ToString();
if (!string.IsNullOrEmpty(centralPathString) && File.Exists(centralPathString))
return new FileInfo(centralPathString).Length;
}
}
catch
{
// 忽略文件大小获取异常,保持分析结果可用
}
return 0;
}
/// <summary>
/// 基于真实文件大小和可删除比例填充动态估算信息
/// </summary>
private static void ApplyDynamicSizeEstimate(Document doc, ShellAnalyzeResponse response)
{
if (doc == null || response?.Analysis == null)
return;
var summary = response.Analysis;
var originalSize = GetDocumentFileSize(doc);
if (originalSize <= 0)
return;
var removeRatio = summary.TotalElements > 0
? Math.Max(0.0, Math.Min(1.0, summary.RemoveElements / (double)summary.TotalElements))
: 0.0;
var estimatedOptimizedBytes = (long)Math.Round(originalSize * (1.0 - removeRatio));
if (estimatedOptimizedBytes < 0)
estimatedOptimizedBytes = 0;
summary.OriginalSize = FormatFileSize(originalSize);
summary.EstimatedOptimizedSize = FormatFileSize(estimatedOptimizedBytes);
summary.EstimatedReduction = $"{(removeRatio * 100.0):F1}%";
}
/// <summary>
/// 分析薄壳优化方案
/// </summary>
/// <param name="mode">优化模式</param>
/// <returns>分析结果</returns>
public static ShellAnalyzeResponse AnalyzeShellOptimization(ShellOptimizeMode mode)
{
ShellAnalyzeResponse result = null;
Exception capturedException = null;
bool completed = false;
try
{
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc == null)
throw new InvalidOperationException("没有打开的Revit文档");
var analyzer = new ShellAnalyzer();
result = analyzer.AnalyzeModel(doc, mode);
ApplyDynamicSizeEstimate(doc, result);
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待30秒分析可能需要较长时间
var timeout = DateTime.Now.AddSeconds(30);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(100);
}
if (capturedException != null)
throw capturedException;
if (!completed)
throw new TimeoutException("薄壳分析超时");
return result;
}
catch (Exception ex)
{
throw new InvalidOperationException($"薄壳分析失败: {ex.Message}", ex);
}
}
/// <summary>
/// 执行薄壳优化(同步)
/// </summary>
/// <param name="mode">优化模式</param>
/// <param name="backupOriginal">是否备份原文件</param>
/// <returns>执行结果</returns>
public static ShellOptimizeResult ExecuteShellOptimization(ShellOptimizeMode mode, bool backupOriginal = true)
{
ShellOptimizeResult result = null;
Exception capturedException = null;
bool completed = false;
try
{
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc == null)
throw new InvalidOperationException("没有打开的Revit文档");
var optimizer = new ShellOptimizer();
result = optimizer.ExecuteOptimization(doc, mode, backupOriginal);
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待5分钟删除操作可能需要较长时间
var timeout = DateTime.Now.AddMinutes(5);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(200);
}
if (capturedException != null)
throw capturedException;
if (!completed)
throw new TimeoutException("薄壳优化执行超时");
return result;
}
catch (Exception ex)
{
throw new InvalidOperationException($"薄壳优化执行失败: {ex.Message}", ex);
}
}
/// <summary>
/// 按类别执行自定义删除(同步)
/// </summary>
public static ShellOptimizeResult ExecuteShellOptimizationByCategories(IEnumerable<int> categoryIds, bool backupOriginal = true)
{
ShellOptimizeResult result = null;
Exception capturedException = null;
bool completed = false;
try
{
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc == null)
throw new InvalidOperationException("没有打开的Revit文档");
var optimizer = new ShellOptimizer();
result = optimizer.ExecuteOptimizationByCategories(doc, categoryIds, backupOriginal);
}
catch (Exception ex)
{
capturedException = ex;
}
finally
{
completed = true;
}
});
// 等待命令执行完成最多等待5分钟
var timeout = DateTime.Now.AddMinutes(5);
while (!completed && DateTime.Now < timeout)
{
System.Threading.Thread.Sleep(200);
}
if (capturedException != null)
throw capturedException;
if (!completed)
throw new TimeoutException("自定义类别删除执行超时");
return result;
}
catch (Exception ex)
{
throw new InvalidOperationException($"自定义类别删除执行失败: {ex.Message}", ex);
}
}
/// <summary>
/// 执行薄壳优化(异步)
/// </summary>
/// <param name="mode">优化模式</param>
/// <param name="backupOriginal">是否备份原文件</param>
/// <param name="taskId">任务ID</param>
/// <param name="taskManager">任务管理器</param>
public static void ExecuteShellOptimizationAsync(ShellOptimizeMode mode, bool backupOriginal, Guid taskId, TaskManager taskManager)
{
try
{
App.Instance.EnqueueCommand(uiApp =>
{
try
{
var doc = uiApp.ActiveUIDocument?.Document;
if (doc == null)
{
taskManager.FailTask(taskId, "没有打开的Revit文档");
return;
}
var optimizer = new ShellOptimizer();
// 更新任务状态为进行中
taskManager.SetTaskRunning(taskId);
// 执行优化
var result = optimizer.ExecuteOptimization(doc, mode, backupOriginal);
// 设置任务完成
taskManager.CompleteTask(taskId, result);
}
catch (Exception ex)
{
taskManager.FailTask(taskId, $"薄壳优化执行失败: {ex.Message}");
}
});
}
catch (Exception ex)
{
taskManager.FailTask(taskId, $"启动薄壳优化任务失败: {ex.Message}");
}
}
}
}