修改了分层导出的bug,提高了性能。
This commit is contained in:
parent
c098fb9b1f
commit
468b3ef0e6
@ -690,7 +690,7 @@ namespace NavisworksTransport
|
||||
OnStatusChanged("正在准备分层...");
|
||||
|
||||
// 优先从缓存获取分层结果,避免重复检测
|
||||
string cacheKey = GenerateCacheKey(config);
|
||||
string cacheKey = GenerateSmartTraversalCacheKey(config);
|
||||
var previewResults = GetFromCache(config.Strategy, cacheKey);
|
||||
|
||||
if (previewResults == null || previewResults.Count == 0)
|
||||
@ -741,7 +741,7 @@ namespace NavisworksTransport
|
||||
try
|
||||
{
|
||||
// 实现具体的分层保存逻辑
|
||||
await ProcessSingleLayerAsync(preview, config, cancellationToken);
|
||||
await ProcessSingleLayerAsync(preview, config, cancellationToken, i + 1, layersToSave.Count);
|
||||
successCount++;
|
||||
LogManager.Info($"[分层管理器] 分层 {preview.LayerName} 处理成功 ({successCount}/{layersToSave.Count})");
|
||||
}
|
||||
@ -802,7 +802,7 @@ namespace NavisworksTransport
|
||||
OnStatusChanged("正在准备分层...");
|
||||
|
||||
// 优先从缓存获取分层结果,避免重复检测
|
||||
string cacheKey = GenerateCacheKey(config);
|
||||
string cacheKey = GenerateSmartTraversalCacheKey(config);
|
||||
var previewResults = GetFromCache(config.Strategy, cacheKey);
|
||||
|
||||
if (previewResults == null || previewResults.Count == 0)
|
||||
@ -847,7 +847,7 @@ namespace NavisworksTransport
|
||||
try
|
||||
{
|
||||
// 同步处理单个分层
|
||||
ProcessSingleLayer(preview, config);
|
||||
ProcessSingleLayer(preview, config, i + 1, layersToSave.Count);
|
||||
successCount++;
|
||||
LogManager.Info($"[分层管理器] 分层 {preview.LayerName} 处理成功 ({successCount}/{layersToSave.Count})");
|
||||
}
|
||||
@ -1078,7 +1078,8 @@ namespace NavisworksTransport
|
||||
/// </summary>
|
||||
private List<SplitPreviewResult> PreviewSplitWithSmartTraversal(SplitConfiguration config, IGroupingStrategy strategy)
|
||||
{
|
||||
var results = new List<SplitPreviewResult>();
|
||||
// 使用字典按楼层名分组,自动合并同名楼层
|
||||
var layerGroups = new Dictionary<string, SplitPreviewResult>();
|
||||
|
||||
try
|
||||
{
|
||||
@ -1089,7 +1090,7 @@ namespace NavisworksTransport
|
||||
if (document?.Models?.Count == 0)
|
||||
{
|
||||
LogManager.Warning("[SimplifiedModelSplitter] 当前文档没有模型");
|
||||
return results;
|
||||
return new List<SplitPreviewResult>();
|
||||
}
|
||||
|
||||
// 从每个模型的一级节点开始智能遍历
|
||||
@ -1101,34 +1102,47 @@ namespace NavisworksTransport
|
||||
foreach (ModelItem rootChild in model.RootItem.Children)
|
||||
{
|
||||
processedTopNodes++;
|
||||
TraverseAndRecord(rootChild, strategy, config, results, 1);
|
||||
|
||||
// 统一使用 TraverseAndRecord 处理所有节点
|
||||
// 它会自动检测节点是否有楼层属性并正确处理
|
||||
TraverseAndRecord(rootChild, strategy, config, layerGroups, 1);
|
||||
|
||||
// 每处理10个顶级节点记录一次进度
|
||||
if (processedTopNodes % 10 == 0)
|
||||
{
|
||||
LogManager.Info($"[分层管理器] 已处理 {processedTopNodes} 个顶级节点,找到 {results.Count} 个分层");
|
||||
LogManager.Info($"[分层管理器] 已处理 {processedTopNodes} 个顶级节点,找到 {layerGroups.Count} 个分层");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[分层管理器] ========== 智能遍历完成 ==========");
|
||||
LogManager.Info($"[分层管理器] 处理了 {processedTopNodes} 个顶级节点,识别到 {results.Count} 个{strategy.GroupTypeName}分层");
|
||||
LogManager.Info($"[分层管理器] 处理了 {processedTopNodes} 个顶级节点,识别到 {layerGroups.Count} 个{strategy.GroupTypeName}分层");
|
||||
|
||||
// 将字典转换为列表返回
|
||||
var results = new List<SplitPreviewResult>(layerGroups.Values);
|
||||
|
||||
// 记录每个分层的详细信息
|
||||
foreach (var layer in results)
|
||||
{
|
||||
var rootNodes = layer.Metadata["RootNodes"] as List<ModelItem>;
|
||||
LogManager.Info($"[分层管理器] 楼层 '{layer.LayerName}': {rootNodes?.Count ?? 0} 个分支, {layer.Items.Count} 个节点");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[分层管理器] 智能遍历失败: {ex.Message}", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归遍历节点并记录分层结果的核心方法
|
||||
/// 递归遍历节点并记录分层结果的核心方法(支持同名楼层合并)
|
||||
/// </summary>
|
||||
private void TraverseAndRecord(ModelItem node, IGroupingStrategy strategy,
|
||||
SplitConfiguration config, List<SplitPreviewResult> results, int currentDepth)
|
||||
SplitConfiguration config, Dictionary<string, SplitPreviewResult> layerGroups, int currentDepth)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1146,11 +1160,54 @@ namespace NavisworksTransport
|
||||
LogManager.Info($"[分层管理器] 智能检测到属性类型: '{attributeName}', 值: '{attributeValue}'");
|
||||
}
|
||||
|
||||
// 创建轻量化预览结果,停止该分支遍历
|
||||
var layerResult = CreateLayerResult(layerValue, node, strategy.GroupTypeName, config.Strategy, detectedAttributeName);
|
||||
results.Add(layerResult);
|
||||
// 清理楼层名称
|
||||
string sanitizedLayerName = SanitizeLayerName(layerValue);
|
||||
|
||||
// 检查是否已存在该楼层的结果
|
||||
if (!layerGroups.ContainsKey(sanitizedLayerName))
|
||||
{
|
||||
// 第一次遇到这个楼层名,创建新结果
|
||||
layerGroups[sanitizedLayerName] = new SplitPreviewResult
|
||||
{
|
||||
LayerName = sanitizedLayerName,
|
||||
LayerAttribute = GetAttributeDescription(config.Strategy, layerValue, null),
|
||||
Items = new ModelItemCollection(),
|
||||
Metadata = new Dictionary<string, object>
|
||||
{
|
||||
["RootNodes"] = new List<ModelItem>(), // 存储多个根节点
|
||||
["BranchCount"] = 0,
|
||||
["GroupType"] = strategy.GroupTypeName,
|
||||
["TraversalMode"] = "SmartTraversal",
|
||||
["DetectedAttributeName"] = detectedAttributeName
|
||||
}
|
||||
};
|
||||
LogManager.Info($"[分层管理器] 创建新楼层分组: '{sanitizedLayerName}'");
|
||||
}
|
||||
|
||||
// 获取现有楼层结果
|
||||
var layerResult = layerGroups[sanitizedLayerName];
|
||||
|
||||
// 展开并添加当前节点的所有子节点
|
||||
LogManager.Info($"[分层管理器] 开始展开节点树: {node.DisplayName}");
|
||||
var expandedNodes = ExpandNodeTree(node);
|
||||
LogManager.Info($"[分层管理器] 节点树展开完成,共 {expandedNodes.Count} 个节点");
|
||||
|
||||
// 添加到楼层的节点集合
|
||||
foreach (var item in expandedNodes)
|
||||
{
|
||||
layerResult.Items.Add(item);
|
||||
}
|
||||
|
||||
// 记录这个分支的根节点
|
||||
var rootNodes = layerResult.Metadata["RootNodes"] as List<ModelItem>;
|
||||
rootNodes.Add(node);
|
||||
|
||||
// 更新分支计数和节点计数
|
||||
layerResult.Metadata["BranchCount"] = rootNodes.Count;
|
||||
layerResult.Metadata["ExpandedNodeCount"] = layerResult.Items.Count;
|
||||
|
||||
LogManager.Info($"[分层管理器] 合并到楼层 '{sanitizedLayerName}',现有 {rootNodes.Count} 个分支,共 {layerResult.Items.Count} 个节点");
|
||||
|
||||
LogManager.Info($"[分层管理器] 找到{strategy.GroupTypeName}分层: '{layerValue}' 于节点 '{node.DisplayName}' (深度{currentDepth})");
|
||||
return; // 关键:停止遍历该分支
|
||||
}
|
||||
|
||||
@ -1159,7 +1216,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
foreach (ModelItem child in node.Children)
|
||||
{
|
||||
TraverseAndRecord(child, strategy, config, results, currentDepth + 1);
|
||||
TraverseAndRecord(child, strategy, config, layerGroups, currentDepth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1169,6 +1226,51 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 展开节点树,收集所有子节点
|
||||
/// </summary>
|
||||
private ModelItemCollection ExpandNodeTree(ModelItem rootNode)
|
||||
{
|
||||
var allNodes = new ModelItemCollection();
|
||||
allNodes.Add(rootNode);
|
||||
|
||||
// 使用队列进行广度优先遍历,收集所有子节点
|
||||
var nodesToProcess = new Queue<ModelItem>();
|
||||
nodesToProcess.Enqueue(rootNode);
|
||||
int totalNodes = 1; // 包括根节点
|
||||
|
||||
try
|
||||
{
|
||||
while (nodesToProcess.Count > 0)
|
||||
{
|
||||
var current = nodesToProcess.Dequeue();
|
||||
|
||||
// 遍历当前节点的所有子节点
|
||||
if (current.Children != null && current.Children.Count() > 0)
|
||||
{
|
||||
foreach (ModelItem child in current.Children)
|
||||
{
|
||||
allNodes.Add(child);
|
||||
nodesToProcess.Enqueue(child);
|
||||
totalNodes++;
|
||||
|
||||
// 每处理1000个节点记录一次进度
|
||||
if (totalNodes % 1000 == 0)
|
||||
{
|
||||
LogManager.Info($"[分层管理器] 已展开 {totalNodes} 个节点...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[分层管理器] 展开节点树时出现异常: {ex.Message},将使用部分展开的结果");
|
||||
}
|
||||
|
||||
return allNodes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建轻量化分层预览结果 - 只包含必要信息,不做统计计算
|
||||
/// </summary>
|
||||
@ -1177,12 +1279,55 @@ namespace NavisworksTransport
|
||||
/// </summary>
|
||||
private SplitPreviewResult CreateLayerResult(string layerValue, ModelItem rootNode, string groupTypeName, SplitStrategy strategy, string detectedAttributeName = null)
|
||||
{
|
||||
// 性能优化:展开并缓存完整的节点树,避免导出时重复遍历
|
||||
var allNodes = new ModelItemCollection();
|
||||
allNodes.Add(rootNode);
|
||||
|
||||
// 使用队列进行广度优先遍历,收集所有子节点
|
||||
var nodesToProcess = new Queue<ModelItem>();
|
||||
nodesToProcess.Enqueue(rootNode);
|
||||
int totalNodes = 1; // 包括根节点
|
||||
|
||||
LogManager.Info($"[分层管理器] 开始展开节点树: {rootNode.DisplayName}");
|
||||
|
||||
try
|
||||
{
|
||||
while (nodesToProcess.Count > 0)
|
||||
{
|
||||
var current = nodesToProcess.Dequeue();
|
||||
|
||||
// 遍历当前节点的所有子节点
|
||||
if (current.Children != null && current.Children.Count() > 0)
|
||||
{
|
||||
foreach (ModelItem child in current.Children)
|
||||
{
|
||||
allNodes.Add(child);
|
||||
nodesToProcess.Enqueue(child);
|
||||
totalNodes++;
|
||||
|
||||
// 每处理1000个节点记录一次进度
|
||||
if (totalNodes % 1000 == 0)
|
||||
{
|
||||
LogManager.Info($"[分层管理器] 已展开 {totalNodes} 个节点...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[分层管理器] 展开节点树时出现异常: {ex.Message},将使用部分展开的结果");
|
||||
}
|
||||
|
||||
LogManager.Info($"[分层管理器] 节点树展开完成,共 {totalNodes} 个节点");
|
||||
|
||||
var metadata = new Dictionary<string, object>
|
||||
{
|
||||
["LayerValue"] = layerValue,
|
||||
["RootNodeReference"] = rootNode,
|
||||
["GroupType"] = groupTypeName,
|
||||
["TraversalMode"] = "SmartTraversal" // 标记使用智能遍历
|
||||
["TraversalMode"] = "SmartTraversal",
|
||||
["ExpandedNodeCount"] = totalNodes // 记录展开的节点数量,便于性能监控
|
||||
};
|
||||
|
||||
// 如果检测到了具体的属性类型,保存到元数据中
|
||||
@ -1195,7 +1340,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
LayerName = SanitizeLayerName(layerValue),
|
||||
LayerAttribute = GetAttributeDescription(strategy, layerValue, metadata),
|
||||
Items = new ModelItemCollection { rootNode }, // 只保存根节点引用
|
||||
Items = allNodes, // 保存完整的节点集合,而不只是根节点
|
||||
Metadata = metadata
|
||||
};
|
||||
}
|
||||
@ -1203,7 +1348,7 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 处理单个分层(异步版本)
|
||||
/// </summary>
|
||||
private async Task ProcessSingleLayerAsync(SplitPreviewResult preview, SplitConfiguration config, CancellationToken cancellationToken)
|
||||
private async Task ProcessSingleLayerAsync(SplitPreviewResult preview, SplitConfiguration config, CancellationToken cancellationToken, int currentIndex = 0, int totalCount = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1241,7 +1386,7 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 处理单个分层(同步版本)
|
||||
/// </summary>
|
||||
private void ProcessSingleLayer(SplitPreviewResult preview, SplitConfiguration config)
|
||||
private void ProcessSingleLayer(SplitPreviewResult preview, SplitConfiguration config, int currentIndex = 0, int totalCount = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1272,22 +1417,46 @@ namespace NavisworksTransport
|
||||
LogManager.Info($"[分层管理器] 垃圾回收完成,当前内存: {GC.GetTotalMemory(false) / 1024 / 1024} MB");
|
||||
}
|
||||
|
||||
// 更新状态:正在导出
|
||||
string progressInfo = (currentIndex > 0 && totalCount > 0) ? $" ({currentIndex}/{totalCount})" : "";
|
||||
OnStatusChanged($"正在导出{progressInfo}: {preview.LayerName}...");
|
||||
|
||||
// 使用TryExportToNwd API导出分层
|
||||
bool success = ExportLayerToNwd(preview, outputPath, config);
|
||||
|
||||
if (success)
|
||||
{
|
||||
LogManager.Info($"[分层管理器] 分层 {preview.LayerName} 导出成功: {outputPath}");
|
||||
|
||||
// 获取文件大小信息
|
||||
string fileSizeInfo = "";
|
||||
try
|
||||
{
|
||||
if (File.Exists(outputPath))
|
||||
{
|
||||
var fileInfo = new FileInfo(outputPath);
|
||||
double sizeMB = fileInfo.Length / (1024.0 * 1024.0);
|
||||
fileSizeInfo = $" ({sizeMB:F1}MB)";
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// 更新状态:导出成功
|
||||
string successProgressInfo = (currentIndex > 0 && totalCount > 0) ? $" ({currentIndex}/{totalCount})" : "";
|
||||
OnStatusChanged($"导出成功{successProgressInfo}: {preview.LayerName}{fileSizeInfo}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Error($"[分层管理器] 分层 {preview.LayerName} 导出失败");
|
||||
string failProgressInfo = (currentIndex > 0 && totalCount > 0) ? $" ({currentIndex}/{totalCount})" : "";
|
||||
OnStatusChanged($"导出失败{failProgressInfo}: {preview.LayerName}");
|
||||
throw new InvalidOperationException($"分层 {preview.LayerName} 导出失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[分层管理器] 同步处理分层失败 {preview.LayerName}: {ex.Message}");
|
||||
OnStatusChanged($"处理失败: {preview.LayerName} - {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@ -1658,98 +1827,34 @@ namespace NavisworksTransport
|
||||
|
||||
try
|
||||
{
|
||||
// 采用智能隐藏策略:只操作顶级节点,避免遍历所有项目
|
||||
var allTopLevelItems = new List<ModelItem>();
|
||||
// 直接使用预览结果中的项目,这些已经是展开的完整节点树
|
||||
// 不添加任何祖先路径,让 IsolateSpecificItems 自己处理
|
||||
var itemsToIsolate = preview.Items;
|
||||
|
||||
// 只获取顶级节点,不遍历全部项目
|
||||
foreach (Model model in document.Models)
|
||||
LogManager.Info($"[分层管理器] 准备隔离显示 {itemsToIsolate.Count} 个节点");
|
||||
|
||||
// 使用 VisibilityManager.IsolateSpecificItems 隔离显示
|
||||
// 这个方法会使用缓存优化,效率更高
|
||||
var isolateResult = VisibilityManager.IsolateSpecificItems(itemsToIsolate);
|
||||
|
||||
if (!isolateResult.Success)
|
||||
{
|
||||
foreach (ModelItem topLevelItem in model.RootItem.Children)
|
||||
{
|
||||
allTopLevelItems.Add(topLevelItem);
|
||||
}
|
||||
throw new InvalidOperationException($"隔离显示失败: {isolateResult.Message}");
|
||||
}
|
||||
|
||||
LogManager.Info($"[分层管理器] 收集到 {allTopLevelItems.Count} 个顶级节点");
|
||||
|
||||
// 智能隐藏策略:如果顶级节点包含要导出的项目,则保持可见;否则隐藏整个顶级分支
|
||||
var itemsToHide = new ModelItemCollection();
|
||||
int hiddenCount = 0;
|
||||
|
||||
foreach (ModelItem topLevelItem in allTopLevelItems)
|
||||
{
|
||||
bool shouldKeepTopLevel = false;
|
||||
|
||||
// 检查这个顶级节点本身是否在导出列表中
|
||||
foreach (ModelItem exportItem in itemsToExport)
|
||||
{
|
||||
if (topLevelItem.Equals(exportItem))
|
||||
{
|
||||
shouldKeepTopLevel = true;
|
||||
LogManager.Info($"[分层管理器] 顶级节点 {topLevelItem.DisplayName} 本身被选中,保持可见");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果顶级节点本身不在导出列表中,检查是否有任何导出项是它的后代
|
||||
if (!shouldKeepTopLevel)
|
||||
{
|
||||
foreach (var exportItem in itemsToExport)
|
||||
{
|
||||
var current = exportItem;
|
||||
while (current != null)
|
||||
{
|
||||
if (current == topLevelItem)
|
||||
{
|
||||
shouldKeepTopLevel = true;
|
||||
LogManager.Info($"[分层管理器] 顶级节点 {topLevelItem.DisplayName} 包含导出项目,保持可见");
|
||||
break;
|
||||
}
|
||||
current = current.Parent;
|
||||
}
|
||||
if (shouldKeepTopLevel) break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果这个顶级节点不需要保持可见,则隐藏它
|
||||
if (!shouldKeepTopLevel)
|
||||
{
|
||||
try
|
||||
{
|
||||
itemsToHide.Add(topLevelItem);
|
||||
hiddenCount++;
|
||||
LogManager.Info($"[分层管理器] 隐藏顶级节点: {topLevelItem.DisplayName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[分层管理器] 添加隐藏项目失败: {topLevelItem.DisplayName} - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行隐藏操作
|
||||
if (itemsToHide.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
document.Models.SetHidden(itemsToHide, true);
|
||||
LogManager.Info($"[分层管理器] 成功隐藏 {hiddenCount} 个顶级节点,保留导出项目可见");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[分层管理器] 隐藏操作失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
LogManager.Info($"[分层管理器] 隔离显示成功: {isolateResult.Message}");
|
||||
LogManager.Info($"[分层管理器] 隐藏了 {isolateResult.HiddenCount} 个项目,保持 {isolateResult.TotalCount - isolateResult.HiddenCount} 个项目可见");
|
||||
|
||||
// 创建导出选项
|
||||
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
|
||||
{
|
||||
ExcludeHiddenItems = true, // 只导出可见项目
|
||||
EmbedXrefs = false,
|
||||
PreventObjectPropertyExport = false
|
||||
EmbedXrefs = config?.ExportOptions?.EmbedXrefs ?? false,
|
||||
PreventObjectPropertyExport = config?.ExportOptions?.PreventObjectPropertyExport ?? false
|
||||
};
|
||||
|
||||
LogManager.Info($"[分层管理器] 开始调用ExportToNwd API(主线程)");
|
||||
LogManager.Info($"[分层管理器] 导出选项: ExcludeHiddenItems=true, EmbedXrefs={exportOptions.EmbedXrefs}, PreventObjectPropertyExport={exportOptions.PreventObjectPropertyExport}");
|
||||
|
||||
// 在主线程中执行导出
|
||||
document.ExportToNwd(outputPath, exportOptions);
|
||||
@ -1795,6 +1900,109 @@ namespace NavisworksTransport
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归处理节点可见性 - 精细化控制每个节点
|
||||
/// </summary>
|
||||
private void ProcessNodeVisibility(ModelItem node, HashSet<ModelItem> exportItemsSet,
|
||||
ModelItemCollection itemsToHide,
|
||||
ref int processedCount, ref int hiddenCount)
|
||||
{
|
||||
if (node == null) return;
|
||||
|
||||
processedCount++;
|
||||
|
||||
// 检查当前节点是否在导出集合中
|
||||
bool shouldExport = exportItemsSet.Contains(node);
|
||||
|
||||
if (shouldExport)
|
||||
{
|
||||
// 这个节点要导出,不隐藏
|
||||
// 继续处理其子节点(可能有些子节点不需要导出)
|
||||
if (node.Children != null)
|
||||
{
|
||||
foreach (ModelItem child in node.Children)
|
||||
{
|
||||
ProcessNodeVisibility(child, exportItemsSet, itemsToHide,
|
||||
ref processedCount, ref hiddenCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检查是否有任何子节点需要导出
|
||||
bool hasExportChild = HasExportDescendant(node, exportItemsSet);
|
||||
|
||||
if (hasExportChild)
|
||||
{
|
||||
// 有子节点需要导出,继续递归处理子节点
|
||||
// 但不隐藏当前节点(因为需要保持结构)
|
||||
if (node.Children != null)
|
||||
{
|
||||
foreach (ModelItem child in node.Children)
|
||||
{
|
||||
ProcessNodeVisibility(child, exportItemsSet, itemsToHide,
|
||||
ref processedCount, ref hiddenCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 当前节点及其所有子节点都不需要导出,隐藏整个分支
|
||||
try
|
||||
{
|
||||
itemsToHide.Add(node);
|
||||
hiddenCount++;
|
||||
|
||||
if (hiddenCount <= 10 || hiddenCount % 1000 == 0)
|
||||
{
|
||||
LogManager.Debug($"[分层管理器] 隐藏节点: {node.DisplayName}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[分层管理器] 添加隐藏节点失败: {ex.Message}");
|
||||
}
|
||||
// 不需要继续递归子节点,因为整个分支都隐藏了
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查节点是否有需要导出的后代
|
||||
/// </summary>
|
||||
private bool HasExportDescendant(ModelItem node, HashSet<ModelItem> exportItemsSet)
|
||||
{
|
||||
if (node?.Children == null || node.Children.Count() == 0)
|
||||
return false;
|
||||
|
||||
// 使用队列进行广度优先搜索,避免深度递归
|
||||
var queue = new Queue<ModelItem>();
|
||||
foreach (ModelItem child in node.Children)
|
||||
{
|
||||
queue.Enqueue(child);
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
|
||||
if (exportItemsSet.Contains(current))
|
||||
{
|
||||
return true; // 找到需要导出的后代
|
||||
}
|
||||
|
||||
if (current.Children != null)
|
||||
{
|
||||
foreach (ModelItem child in current.Children)
|
||||
{
|
||||
queue.Enqueue(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前可见性状态(参考"保存当前选择项"的方法)
|
||||
|
||||
@ -186,7 +186,8 @@ namespace NavisworksTransport
|
||||
private static string GenerateDocumentId(Document document)
|
||||
{
|
||||
if (document == null) return "empty";
|
||||
return $"{document.FileName}_{document.Models?.Count ?? 0}_{document.CurrentSelection?.SelectedItems?.Count ?? 0}";
|
||||
// 移除选中项计数,只保留文件名和模型数(选中项变化不应触发缓存清除)
|
||||
return $"{document.FileName}_{document.Models?.Count ?? 0}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -430,7 +430,8 @@ namespace NavisworksTransport.UI.WPF.Commands
|
||||
EstimatedSize = "0 KB", // 不再显示文件大小
|
||||
Status = "就绪", // 保持UI兼容性
|
||||
IsSelectedForSave = result.IsSelectedForSave,
|
||||
Items = result.Items
|
||||
Items = result.Items,
|
||||
Metadata = result.Metadata // 复制元数据,包含RootNodes等优化信息
|
||||
}).ToList();
|
||||
|
||||
LogManager.Info($"[PreviewSplitCommand] 预览完成,共 {previewItems.Count} 个分层");
|
||||
|
||||
@ -110,6 +110,12 @@ namespace NavisworksTransport.UI.WPF.Models
|
||||
/// </summary>
|
||||
public ModelItemCollection Items { get; set; } = new ModelItemCollection();
|
||||
|
||||
/// <summary>
|
||||
/// 元数据字典
|
||||
/// 存储额外信息,如RootNodes等优化数据
|
||||
/// </summary>
|
||||
public System.Collections.Generic.Dictionary<string, object> Metadata { get; set; } = new System.Collections.Generic.Dictionary<string, object>();
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
|
||||
@ -1373,7 +1373,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LayerName = item.LayerName,
|
||||
LayerAttribute = item.LayerAttribute,
|
||||
Items = item.Items,
|
||||
IsSelectedForSave = item.IsSelectedForSave
|
||||
IsSelectedForSave = item.IsSelectedForSave,
|
||||
Metadata = item.Metadata // 重要:复制元数据,包含RootNodes等优化信息
|
||||
}).ToList();
|
||||
|
||||
LogManager.Info($"[LayerManagementViewModel] 开始执行分层,输出目录: {selectedDirectory}");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user