优化三角形提取性能 - 实现批量COM Selection创建
问题分析: - 当前逐个ModelItem创建COM Selection(290次) - 从290个模型项提取776140个三角形耗时较长 - COM对象创建/销毁开销大 优化方案: 1. 新增 GeometryHelper.ExtractTrianglesBatch 方法 - 批量创建COM Selection(290次 → 1次) - 一次性提取所有模型项的三角形 - 添加进度日志(每100个片段输出一次) 2. 修改 NavisworksToDMesh3Converter.ConvertFromModelItems - 从逐个调用 ExtractTriangles 改为批量调用 ExtractTrianglesBatch - 添加详细的耗时统计(毫秒和秒) - 添加 System.Linq 引用支持ToList() 3. 保留原有 ExtractTriangles 方法 - 向后兼容单个模型项提取场景 - 用于小规模提取或特殊场景 预期效果: - COM Selection创建:290次 → 1次 - 预计性能提升:50-70% - 日志更详细,便于性能分析 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2e9b9fe2b3
commit
51be24161d
@ -124,7 +124,104 @@ namespace NavisworksTransport
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提取三角形
|
||||
/// 批量提取三角形(优化版本)
|
||||
/// </summary>
|
||||
/// <param name="modelItems">模型项集合</param>
|
||||
/// <returns>三角形集合</returns>
|
||||
public static List<Triangle3D> ExtractTrianglesBatch(IEnumerable<ModelItem> modelItems)
|
||||
{
|
||||
var triangles = new List<Triangle3D>();
|
||||
|
||||
ComApi.InwOpSelection comSelection = null;
|
||||
try
|
||||
{
|
||||
// 批量转换为 COM 选择 - 性能优化关键
|
||||
var modelCollection = new ModelItemCollection();
|
||||
int itemCount = 0;
|
||||
foreach (var item in modelItems)
|
||||
{
|
||||
modelCollection.Add(item);
|
||||
itemCount++;
|
||||
}
|
||||
|
||||
LogManager.Info($"[批量提取] 开始批量提取 {itemCount} 个模型项的三角形");
|
||||
|
||||
var comState = ComStateManager.GetState();
|
||||
comSelection = ComApiBridge.ToInwOpSelection(modelCollection);
|
||||
|
||||
LogManager.Debug($"[批量提取] COM 选择创建成功,路径数: {comSelection.Paths().Count}");
|
||||
|
||||
// 获取所有片段
|
||||
var allFragments = GetAllFragments(comSelection);
|
||||
LogManager.Info($"[批量提取] 获取到 {allFragments.Count} 个片段");
|
||||
|
||||
try
|
||||
{
|
||||
int processedFragments = 0;
|
||||
foreach (var fragmentInfo in allFragments)
|
||||
{
|
||||
try
|
||||
{
|
||||
var callback = new OptimizedGeometryCallback(fragmentInfo.TransformMatrix);
|
||||
fragmentInfo.Fragment.GenerateSimplePrimitives(
|
||||
ComApi.nwEVertexProperty.eNORMAL,
|
||||
callback);
|
||||
|
||||
var fragmentTriangles = callback.GetTriangles();
|
||||
triangles.AddRange(fragmentTriangles);
|
||||
processedFragments++;
|
||||
|
||||
// 每处理100个片段输出一次进度
|
||||
if (processedFragments % 100 == 0)
|
||||
{
|
||||
LogManager.Debug($"[批量提取] 已处理 {processedFragments}/{allFragments.Count} 个片段,累计三角形: {triangles.Count}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[批量提取] 处理片段失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[批量提取] 片段处理完成,共提取 {triangles.Count} 个三角形");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 释放所有片段COM对象
|
||||
foreach (var fragmentInfo in allFragments)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fragmentInfo.Fragment != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(fragmentInfo.Fragment);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[批量提取] 释放片段COM对象失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[批量提取] 提取三角形失败: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 释放COM对象,避免内存泄漏
|
||||
if (comSelection != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(comSelection);
|
||||
}
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提取三角形(单个模型项)
|
||||
/// </summary>
|
||||
/// <param name="modelItem">模型项</param>
|
||||
/// <returns>三角形集合</returns>
|
||||
@ -146,7 +243,7 @@ namespace NavisworksTransport
|
||||
|
||||
LogManager.Debug($"COM 选择创建成功,路径数: {comSelection.Paths().Count}");
|
||||
|
||||
// 获取所有片段(已移除错误的去重逻辑)
|
||||
// 获取所有片段
|
||||
var allFragments = GetAllFragments(comSelection);
|
||||
LogManager.Debug($"获取到 {allFragments.Count} 个片段");
|
||||
|
||||
@ -208,7 +305,7 @@ namespace NavisworksTransport
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有片段(移除错误的去重逻辑)
|
||||
/// 获取所有片段
|
||||
/// </summary>
|
||||
/// <param name="selection">COM 选择</param>
|
||||
/// <returns>所有片段信息集合</returns>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisworksTransport.Utils;
|
||||
using g4;
|
||||
@ -138,33 +139,18 @@ namespace NavisworksTransport
|
||||
|
||||
LogManager.Info("[DMesh3转换] 开始从 ModelItem 批量提取和转换");
|
||||
|
||||
// 收集所有三角形
|
||||
var allTriangles = new List<Triangle3D>();
|
||||
int itemCount = 0;
|
||||
|
||||
// 批量提取所有三角形 - 性能优化
|
||||
var extractStopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
try
|
||||
{
|
||||
itemCount++;
|
||||
var triangles = GeometryHelper.ExtractTriangles(item);
|
||||
var itemsList = items.ToList();
|
||||
int itemCount = itemsList.Count;
|
||||
|
||||
if (triangles != null && triangles.Count > 0)
|
||||
{
|
||||
allTriangles.AddRange(triangles);
|
||||
LogManager.Debug($"[DMesh3转换] 从 {item.DisplayName} 提取了 {triangles.Count} 个三角形");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[DMesh3转换] 从 ModelItem {item.DisplayName} 提取几何体失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
LogManager.Info($"[DMesh3转换] 共 {itemCount} 个模型项,使用批量提取方式");
|
||||
|
||||
var allTriangles = GeometryHelper.ExtractTrianglesBatch(itemsList);
|
||||
|
||||
extractStopwatch.Stop();
|
||||
LogManager.Info($"[DMesh3转换] 从 {itemCount} 个模型项共提取 {allTriangles.Count} 个三角形,耗时: {extractStopwatch.ElapsedMilliseconds} ms");
|
||||
LogManager.Info($"[DMesh3转换] 从 {itemCount} 个模型项共提取 {allTriangles.Count} 个三角形,耗时: {extractStopwatch.ElapsedMilliseconds} ms ({extractStopwatch.Elapsed.TotalSeconds:F2}秒)");
|
||||
|
||||
// 转换为 DMesh3
|
||||
return Convert(allTriangles);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user