NavisworksTransport/doc/working/LayerPreview_SmartTraversal_Requirements_Analysis.md

14 KiB
Raw Blame History

分层预览智能遍历需求分析

需求概述

新的分层处理逻辑需求

修改分层预览的业务逻辑,实现基于属性的智能停止遍历机制:

  1. 智能遍历逻辑:从一级节点开始,遍历每个节点查找指定的分层属性
  2. 分支停止机制:如果找到分层属性,记录下来作为一个分层,不再遍历其下级节点
  3. 深度递归控制:如果没找到,继续遍历其子节点,直到找到为止,遍历深度受到用户指定的遍历深度限制
  4. 智能检测特殊处理:使用一组候选的分层属性,对每个节点进行查找,按属性的评分(优先级)确定选择何种属性
  5. 自定义查找特殊处理:用指定的分层属性,在每个节点的"分层信息"属性类别中查找

现有架构分析

1. 当前遍历机制的局限性

现有实现方式

// 当前的两阶段处理方式
var allItems = GetAllModelItems(config.MaxDepth);  // 阶段1收集所有指定深度内的节点
var groups = strategy.GroupItems(allItems, config);  // 阶段2对所有节点进行属性分析和分组

存在的问题

  • 采用固定深度遍历,无法实现智能停止
  • 先收集所有节点,再统一分组,无法在遍历过程中动态决策
  • 核心问题:无法实现"找到属性就停止该分支遍历"的逻辑

需要的新逻辑

// 需要的边遍历边检查逻辑
foreach (一级节点) {
    if (节点有指定分层属性) {
        记录为分层,停止遍历该分支;
    } else {
        递归遍历子节点(深度限制);
    }
}

2. 现有策略接口的不足

当前IGroupingStrategy接口

public interface IGroupingStrategy
{
    Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config);
}

接口局限性

  • 只能处理预收集的节点集合
  • 无法在遍历过程中动态决策是否继续遍历
  • 不支持单节点的属性检查和分支控制

3. 属性检查机制的缺陷

现有策略类的问题

  • FloorAttributeStrategy仅检查特定的固定属性
  • 没有通用的"分层信息"属性类别检查机制
  • 不支持候选属性组和优先级评分
  • 缺乏多属性竞争选择逻辑

架构改造方案

1. 核心遍历算法重设计

新的智能遍历算法

public List<SplitPreviewResult> PreviewSplitWithSmartTraversal(
    SplitConfiguration config, ISmartGroupingStrategy strategy)
{
    var results = new List<SplitPreviewResult>();
    
    // 从每个模型的一级节点开始遍历
    foreach (Model model in document.Models)
    {
        foreach (ModelItem rootChild in model.RootItem.Children)
        {
            TraverseNodeWithAttributeCheck(rootChild, strategy, config, results, 1);
        }
    }
    
    return results;
}

private void TraverseNodeWithAttributeCheck(ModelItem node, 
    ISmartGroupingStrategy strategy, SplitConfiguration config, 
    List<SplitPreviewResult> results, int currentDepth)
{
    // 检查当前节点是否有分层属性
    var layerInfo = strategy.ExtractLayerInfo(node);
    
    if (layerInfo != null && layerInfo.IsValid)
    {
        // 找到分层属性,停止遍历该分支,添加到结果
        var layerResult = CreateLayerResult(layerInfo, node);
        results.Add(layerResult);
        return;  // 关键:停止该分支遍历
    }
    
    // 未找到属性且未达深度限制,继续遍历子节点
    if (currentDepth < config.MaxDepth && node.Children != null)
    {
        foreach (ModelItem child in node.Children)
        {
            TraverseNodeWithAttributeCheck(child, strategy, config, results, currentDepth + 1);
        }
    }
}

2. 新策略接口设计

ISmartGroupingStrategy接口

public interface ISmartGroupingStrategy
{
    string GroupTypeName { get; }
    
    /// <summary>
    /// 核心方法:检查单个节点的分层信息
    /// </summary>
    LayerInfo ExtractLayerInfo(ModelItem node);
    
    /// <summary>
    /// 支持候选属性组的智能检测
    /// </summary>
    LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates);
}

支持数据结构

public class LayerInfo
{
    public bool IsValid { get; set; }
    public string LayerName { get; set; }
    public string AttributeName { get; set; }
    public string AttributeValue { get; set; }
    public int Priority { get; set; }  // 用于智能检测的优先级
    public string CategoryName { get; set; }  // 属性类别
}

public class AttributeCandidate
{
    public string AttributeName { get; set; }
    public string CategoryName { get; set; }  // 如"分层信息"
    public int Priority { get; set; }  // 优先级评分
    public Func<string, string> ValueProcessor { get; set; }  // 值处理函数
}

3. 智能检测策略实现

SmartLayerDetectionStrategy类

public class SmartLayerDetectionStrategy : ISmartGroupingStrategy
{
    private readonly List<AttributeCandidate> _candidates = new List<AttributeCandidate>
    {
        // 按优先级排序的候选属性
        new AttributeCandidate { AttributeName = "楼层", CategoryName = "分层信息", Priority = 10 },
        new AttributeCandidate { AttributeName = "Floor", CategoryName = "Identity Data", Priority = 9 },
        new AttributeCandidate { AttributeName = "Level", CategoryName = "Constraints", Priority = 8 },
        new AttributeCandidate { AttributeName = "分区", CategoryName = "分层信息", Priority = 7 },
        new AttributeCandidate { AttributeName = "Zone", CategoryName = "Identity Data", Priority = 6 },
        new AttributeCandidate { AttributeName = "子系统", CategoryName = "分层信息", Priority = 5 },
        new AttributeCandidate { AttributeName = "System Type", CategoryName = "Mechanical", Priority = 4 },
        // ... 更多候选属性
    };
    
    public LayerInfo ExtractLayerInfo(ModelItem node)
    {
        return ExtractBestLayerInfo(node, _candidates);
    }
    
    public LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates)
    {
        LayerInfo bestMatch = null;
        int highestPriority = -1;
        
        // 遍历所有候选属性,找到优先级最高的有效属性
        foreach (var candidate in candidates)
        {
            var value = GetAttributeValue(node, candidate.CategoryName, candidate.AttributeName);
            if (!string.IsNullOrEmpty(value) && candidate.Priority > highestPriority)
            {
                bestMatch = new LayerInfo
                {
                    IsValid = true,
                    LayerName = candidate.ValueProcessor?.Invoke(value) ?? value,
                    AttributeName = candidate.AttributeName,
                    AttributeValue = value,
                    Priority = candidate.Priority,
                    CategoryName = candidate.CategoryName
                };
                highestPriority = candidate.Priority;
            }
        }
        
        return bestMatch ?? new LayerInfo { IsValid = false };
    }
    
    private string GetAttributeValue(ModelItem node, string categoryName, string attributeName)
    {
        try
        {
            // 实现Navisworks属性检查逻辑
            foreach (PropertyCategory category in node.PropertyCategories)
            {
                if (category.DisplayName == categoryName)
                {
                    foreach (DataProperty property in category.Properties)
                    {
                        if (property.DisplayName == attributeName)
                        {
                            return property.Value.ToDisplayString();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            LogManager.Warning($"获取属性值失败: {ex.Message}");
        }
        
        return null;
    }
}

4. 自定义属性检查策略

CustomAttributeStrategy类

public class CustomAttributeStrategy : ISmartGroupingStrategy
{
    private readonly string _targetAttributeName;
    private readonly string _targetCategoryName;
    
    public string GroupTypeName => $"自定义属性({_targetAttributeName})";
    
    public CustomAttributeStrategy(string attributeName, string categoryName = "分层信息")
    {
        _targetAttributeName = attributeName;
        _targetCategoryName = categoryName;
    }
    
    public LayerInfo ExtractLayerInfo(ModelItem node)
    {
        var value = GetAttributeValue(node, _targetCategoryName, _targetAttributeName);
        
        if (!string.IsNullOrEmpty(value))
        {
            return new LayerInfo
            {
                IsValid = true,
                LayerName = value,
                AttributeName = _targetAttributeName,
                AttributeValue = value,
                Priority = 1,
                CategoryName = _targetCategoryName
            };
        }
        
        return new LayerInfo { IsValid = false };
    }
    
    public LayerInfo ExtractBestLayerInfo(ModelItem node, List<AttributeCandidate> candidates)
    {
        // 对于自定义策略,只检查指定的单个属性
        return ExtractLayerInfo(node);
    }
    
    private string GetAttributeValue(ModelItem node, string categoryName, string attributeName)
    {
        // 与智能检测策略相同的实现
        // ...
    }
}

5. 遍历结果处理

CreateLayerResult方法设计

private SplitPreviewResult CreateLayerResult(LayerInfo layerInfo, ModelItem rootNode)
{
    // 收集该节点下的所有子项
    var allChildItems = new ModelItemCollection();
    CollectAllDescendants(rootNode, allChildItems);
    
    return new SplitPreviewResult
    {
        LayerName = SanitizeLayerName(layerInfo.LayerName),
        ItemCount = allChildItems.Count,
        EstimatedFileSize = EstimateFileSize(allChildItems.Count),
        Status = "就绪",
        Items = allChildItems,
        Metadata = new Dictionary<string, object>
        {
            ["AttributeName"] = layerInfo.AttributeName,
            ["AttributeValue"] = layerInfo.AttributeValue,
            ["CategoryName"] = layerInfo.CategoryName,
            ["Priority"] = layerInfo.Priority,
            ["RootNodeName"] = rootNode.DisplayName
        }
    };
}

private void CollectAllDescendants(ModelItem rootNode, ModelItemCollection collection)
{
    // 添加根节点本身
    collection.Add(rootNode);
    
    // 递归添加所有后代节点
    if (rootNode.Children != null)
    {
        foreach (ModelItem child in rootNode.Children)
        {
            CollectAllDescendants(child, collection);
        }
    }
}

配置和UI适配

1. 分层策略配置

新的策略类型枚举

public enum SmartSplitStrategy
{
    SmartLayerDetection,      // 智能检测
    CustomFloorAttribute,     // 自定义楼层属性
    CustomZoneAttribute,      // 自定义分区属性
    CustomSystemAttribute,    // 自定义系统属性
    CustomAttribute          // 完全自定义属性
}

2. UI配置选项

智能检测配置

  • 候选属性优先级设置
  • 属性类别选择
  • 值处理规则配置

自定义查找配置

  • 属性名称输入
  • 属性类别选择(默认"分层信息"
  • 值过滤规则

兼容性考虑

1. 向后兼容

保留现有接口

  • 现有的IGroupingStrategy接口和实现类保持不变
  • SimplifiedModelSplitterManager中增加新的智能遍历方法
  • UI层提供策略选择开关

渐进式迁移

public List<SplitPreviewResult> PreviewSplit(SplitConfiguration config)
{
    // 根据配置选择使用新的智能遍历还是传统方式
    if (config.UseSmartTraversal)
    {
        return PreviewSplitWithSmartTraversal(config, CreateSmartStrategy(config));
    }
    else
    {
        // 保留原有的实现逻辑
        return PreviewSplitTraditional(config);
    }
}

2. 性能考虑

优化策略

  • 属性检查缓存机制
  • 早期终止优化(找到高优先级属性立即停止)
  • 内存管理优化(避免大量节点同时加载)

实施复杂度评估

高复杂度任务

  1. 核心遍历算法重写:需要完全重新设计遍历逻辑
  2. 属性检查机制实现涉及Navisworks API的深度使用
  3. 测试验证:需要大量的模型测试和边界情况验证

中等复杂度任务

  1. 新策略接口和实现类:相对标准的面向对象设计
  2. UI适配:在现有界面基础上增加配置选项

低复杂度任务

  1. 配置管理:基于现有的配置系统扩展
  2. 日志和错误处理基于现有的LogManager扩展

结论

现有架构评估

  • 不满足新需求:当前的"先收集后分组"模式无法实现智能停止遍历
  • 需要重大改造:核心算法、策略接口、属性检查机制都需要重新设计
  • 改造工作量大预计需要重写30%以上的核心代码

建议实施策略

  1. 并行开发:新旧算法并存,确保系统稳定性
  2. 分阶段验证:先实现基础功能,再逐步完善高级特性
  3. 充分测试:准备多种类型的测试模型,验证各种边界情况
  4. 性能监控:关注新算法的性能表现,必要时进行优化

预期收益

  • 更精确的分层:基于实际属性内容而非固定深度
  • 更高的效率:避免不必要的深度遍历
  • 更灵活的配置:支持多种属性检查策略
  • 更好的用户体验:提供智能化的分层建议