897 lines
32 KiB
C#
897 lines
32 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using Autodesk.Navisworks.Api;
|
||
using NavisApplication = Autodesk.Navisworks.Api.Application;
|
||
|
||
namespace NavisworksTransport
|
||
{
|
||
/// <summary>
|
||
/// 模型分层拆分对话框
|
||
/// </summary>
|
||
public partial class ModelSplitterDialog : Form
|
||
{
|
||
#region 私有字段
|
||
|
||
private ModelSplitterManager _splitterManager;
|
||
private FloorDetector _floorDetector;
|
||
private AttributeGrouper _attributeGrouper;
|
||
private List<ModelSplitterManager.SplitResult> _previewResults;
|
||
private bool _isProcessing = false;
|
||
|
||
// UI控件
|
||
private ComboBox _strategyComboBox;
|
||
private ComboBox _attributeComboBox;
|
||
private TextBox _outputDirectoryTextBox;
|
||
private Button _browseDirectoryButton;
|
||
private TextBox _fileNamePatternTextBox;
|
||
private CheckBox _includeEmptyLayersCheckBox;
|
||
private CheckBox _createSubDirectoriesCheckBox;
|
||
private CheckBox _generateReportCheckBox;
|
||
private ListView _previewListView;
|
||
private ProgressBar _progressBar;
|
||
private Label _statusLabel;
|
||
private Button _previewButton;
|
||
private Button _executeButton;
|
||
private Button _cancelButton;
|
||
private Button _helpButton;
|
||
|
||
// 高级设置控件
|
||
private NumericUpDown _elevationToleranceNumeric;
|
||
private NumericUpDown _minFloorHeightNumeric;
|
||
private ComboBox _fileFormatComboBox;
|
||
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
|
||
public ModelSplitterDialog()
|
||
{
|
||
InitializeComponent();
|
||
InitializeManagers();
|
||
LoadInitialData();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 初始化方法
|
||
|
||
private void InitializeComponent()
|
||
{
|
||
this.Text = "模型分层拆分工具";
|
||
this.Size = new Size(800, 720);
|
||
this.StartPosition = FormStartPosition.CenterParent;
|
||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||
this.MaximizeBox = false;
|
||
this.MinimizeBox = false;
|
||
this.ShowInTaskbar = false;
|
||
|
||
CreateControls();
|
||
LayoutControls();
|
||
AttachEventHandlers();
|
||
}
|
||
|
||
private void CreateControls()
|
||
{
|
||
// 分层策略
|
||
var strategyLabel = new Label
|
||
{
|
||
Text = "分层策略:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8, FontStyle.Bold)
|
||
};
|
||
|
||
_strategyComboBox = new ComboBox
|
||
{
|
||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
_strategyComboBox.Items.AddRange(new object[]
|
||
{
|
||
"按楼层分层",
|
||
"按自定义属性分层",
|
||
"按类别分层",
|
||
"按高程范围分层"
|
||
});
|
||
_strategyComboBox.SelectedIndex = 0;
|
||
|
||
// 属性选择
|
||
var attributeLabel = new Label
|
||
{
|
||
Text = "分层属性:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8, FontStyle.Bold)
|
||
};
|
||
|
||
_attributeComboBox = new ComboBox
|
||
{
|
||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
|
||
// 输出目录
|
||
var outputLabel = new Label
|
||
{
|
||
Text = "输出目录:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8, FontStyle.Bold)
|
||
};
|
||
|
||
_outputDirectoryTextBox = new TextBox
|
||
{
|
||
Font = new Font("微软雅黑", 8),
|
||
Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "NavisworksSplit")
|
||
};
|
||
|
||
_browseDirectoryButton = new Button
|
||
{
|
||
Text = "浏览...",
|
||
Font = new Font("微软雅黑", 8),
|
||
Size = new Size(80, 25)
|
||
};
|
||
|
||
// 文件命名模式
|
||
var patternLabel = new Label
|
||
{
|
||
Text = "文件命名:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8, FontStyle.Bold)
|
||
};
|
||
|
||
_fileNamePatternTextBox = new TextBox
|
||
{
|
||
Font = new Font("微软雅黑", 8),
|
||
Text = "{ProjectName}_{LayerName}"
|
||
};
|
||
|
||
// 选项设置
|
||
_includeEmptyLayersCheckBox = new CheckBox
|
||
{
|
||
Text = "包含空分层",
|
||
Font = new Font("微软雅黑", 8),
|
||
AutoSize = true
|
||
};
|
||
|
||
_createSubDirectoriesCheckBox = new CheckBox
|
||
{
|
||
Text = "创建子目录",
|
||
Font = new Font("微软雅黑", 8),
|
||
AutoSize = true,
|
||
Checked = true
|
||
};
|
||
|
||
_generateReportCheckBox = new CheckBox
|
||
{
|
||
Text = "生成报告",
|
||
Font = new Font("微软雅黑", 8),
|
||
AutoSize = true,
|
||
Checked = true
|
||
};
|
||
|
||
// 高级设置
|
||
var toleranceLabel = new Label
|
||
{
|
||
Text = "高程容差(m):",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
|
||
_elevationToleranceNumeric = new NumericUpDown
|
||
{
|
||
Font = new Font("微软雅黑", 8),
|
||
DecimalPlaces = 1,
|
||
Minimum = 0.1m,
|
||
Maximum = 10.0m,
|
||
Value = 0.5m,
|
||
Increment = 0.1m
|
||
};
|
||
|
||
var floorHeightLabel = new Label
|
||
{
|
||
Text = "最小楼层高度(m):",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
|
||
_minFloorHeightNumeric = new NumericUpDown
|
||
{
|
||
Font = new Font("微软雅黑", 8),
|
||
DecimalPlaces = 1,
|
||
Minimum = 1.0m,
|
||
Maximum = 20.0m,
|
||
Value = 2.5m,
|
||
Increment = 0.5m
|
||
};
|
||
|
||
var formatLabel = new Label
|
||
{
|
||
Text = "文件格式:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
|
||
_fileFormatComboBox = new ComboBox
|
||
{
|
||
DropDownStyle = ComboBoxStyle.DropDownList,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
_fileFormatComboBox.Items.AddRange(new object[] { "nwd", "nwf", "nwc" });
|
||
_fileFormatComboBox.SelectedIndex = 0;
|
||
|
||
// 预览列表
|
||
var previewLabel = new Label
|
||
{
|
||
Text = "分层预览:",
|
||
AutoSize = true,
|
||
Font = new Font("微软雅黑", 8, FontStyle.Bold)
|
||
};
|
||
|
||
_previewListView = new ListView
|
||
{
|
||
View = System.Windows.Forms.View.Details,
|
||
FullRowSelect = true,
|
||
GridLines = true,
|
||
Font = new Font("微软雅黑", 8)
|
||
};
|
||
_previewListView.Columns.Add("分层名称", 150);
|
||
_previewListView.Columns.Add("元素数量", 80);
|
||
_previewListView.Columns.Add("输出文件", 200);
|
||
_previewListView.Columns.Add("状态", 100);
|
||
|
||
// 进度和状态
|
||
_progressBar = new ProgressBar
|
||
{
|
||
Visible = false
|
||
};
|
||
|
||
_statusLabel = new Label
|
||
{
|
||
Text = "就绪",
|
||
Font = new Font("微软雅黑", 8),
|
||
ForeColor = System.Drawing.Color.DarkBlue,
|
||
AutoSize = true
|
||
};
|
||
|
||
// 按钮
|
||
_previewButton = new Button
|
||
{
|
||
Text = "预览分层",
|
||
Font = new Font("微软雅黑", 8),
|
||
Size = new Size(100, 30)
|
||
};
|
||
|
||
_executeButton = new Button
|
||
{
|
||
Text = "开始拆分",
|
||
Font = new Font("微软雅黑", 8),
|
||
Size = new Size(100, 30),
|
||
Enabled = false
|
||
};
|
||
|
||
_cancelButton = new Button
|
||
{
|
||
Text = "取消",
|
||
Font = new Font("微软雅黑", 8),
|
||
Size = new Size(80, 30),
|
||
DialogResult = DialogResult.Cancel
|
||
};
|
||
|
||
_helpButton = new Button
|
||
{
|
||
Text = "帮助",
|
||
Font = new Font("微软雅黑", 8),
|
||
Size = new Size(80, 30)
|
||
};
|
||
|
||
// 添加所有控件到窗体
|
||
this.Controls.AddRange(new Control[]
|
||
{
|
||
strategyLabel, _strategyComboBox,
|
||
attributeLabel, _attributeComboBox,
|
||
outputLabel, _outputDirectoryTextBox, _browseDirectoryButton,
|
||
patternLabel, _fileNamePatternTextBox,
|
||
_includeEmptyLayersCheckBox, _createSubDirectoriesCheckBox, _generateReportCheckBox,
|
||
toleranceLabel, _elevationToleranceNumeric,
|
||
floorHeightLabel, _minFloorHeightNumeric,
|
||
formatLabel, _fileFormatComboBox,
|
||
previewLabel, _previewListView,
|
||
_progressBar, _statusLabel,
|
||
_previewButton, _executeButton, _cancelButton, _helpButton
|
||
});
|
||
}
|
||
|
||
private void LayoutControls()
|
||
{
|
||
int margin = 15;
|
||
int currentY = margin;
|
||
int labelHeight = 20;
|
||
int controlHeight = 25;
|
||
int spacing = 8;
|
||
|
||
// 分层策略
|
||
var strategyLabel = this.Controls.OfType<Label>().First(l => l.Text == "分层策略:");
|
||
strategyLabel.Location = new Point(margin, currentY);
|
||
currentY += labelHeight + 5;
|
||
|
||
_strategyComboBox.Location = new Point(margin, currentY);
|
||
_strategyComboBox.Size = new Size(200, controlHeight);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 属性选择
|
||
var attributeLabel = this.Controls.OfType<Label>().First(l => l.Text == "分层属性:");
|
||
attributeLabel.Location = new Point(margin, currentY);
|
||
currentY += labelHeight + 5;
|
||
|
||
_attributeComboBox.Location = new Point(margin, currentY);
|
||
_attributeComboBox.Size = new Size(200, controlHeight);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 输出目录
|
||
var outputLabel = this.Controls.OfType<Label>().First(l => l.Text == "输出目录:");
|
||
outputLabel.Location = new Point(margin, currentY);
|
||
currentY += labelHeight + 5;
|
||
|
||
_outputDirectoryTextBox.Location = new Point(margin, currentY);
|
||
_outputDirectoryTextBox.Size = new Size(500, controlHeight);
|
||
_browseDirectoryButton.Location = new Point(margin + 510, currentY);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 文件命名
|
||
var patternLabel = this.Controls.OfType<Label>().First(l => l.Text == "文件命名:");
|
||
patternLabel.Location = new Point(margin, currentY);
|
||
currentY += labelHeight + 5;
|
||
|
||
_fileNamePatternTextBox.Location = new Point(margin, currentY);
|
||
_fileNamePatternTextBox.Size = new Size(300, controlHeight);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 选项设置
|
||
_includeEmptyLayersCheckBox.Location = new Point(margin, currentY);
|
||
_createSubDirectoriesCheckBox.Location = new Point(margin + 120, currentY);
|
||
_generateReportCheckBox.Location = new Point(margin + 240, currentY);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 高级设置 - 第一行
|
||
var toleranceLabel = this.Controls.OfType<Label>().First(l => l.Text == "高程容差(m):");
|
||
toleranceLabel.Location = new Point(margin, currentY);
|
||
_elevationToleranceNumeric.Location = new Point(margin + 120, currentY);
|
||
_elevationToleranceNumeric.Size = new Size(80, controlHeight);
|
||
|
||
var floorHeightLabel = this.Controls.OfType<Label>().First(l => l.Text == "最小楼层高度(m):");
|
||
floorHeightLabel.Location = new Point(margin + 220, currentY);
|
||
_minFloorHeightNumeric.Location = new Point(margin + 370, currentY);
|
||
_minFloorHeightNumeric.Size = new Size(80, controlHeight);
|
||
currentY += controlHeight + spacing;
|
||
|
||
// 文件格式
|
||
var formatLabel = this.Controls.OfType<Label>().First(l => l.Text == "文件格式:");
|
||
formatLabel.Location = new Point(margin, currentY);
|
||
_fileFormatComboBox.Location = new Point(margin + 100, currentY);
|
||
_fileFormatComboBox.Size = new Size(100, controlHeight);
|
||
currentY += controlHeight + spacing * 2;
|
||
|
||
// 预览列表
|
||
var previewLabel = this.Controls.OfType<Label>().First(l => l.Text == "分层预览:");
|
||
previewLabel.Location = new Point(margin, currentY);
|
||
currentY += labelHeight + 5;
|
||
|
||
_previewListView.Location = new Point(margin, currentY);
|
||
_previewListView.Size = new Size(750, 200);
|
||
currentY += 200 + spacing;
|
||
|
||
// 进度条和状态
|
||
_progressBar.Location = new Point(margin, currentY);
|
||
_progressBar.Size = new Size(500, 20);
|
||
_statusLabel.Location = new Point(margin + 510, currentY + 2);
|
||
currentY += 25 + spacing;
|
||
|
||
// 按钮
|
||
_helpButton.Location = new Point(margin, currentY);
|
||
_previewButton.Location = new Point(this.Width - 320, currentY);
|
||
_executeButton.Location = new Point(this.Width - 210, currentY);
|
||
_cancelButton.Location = new Point(this.Width - 100, currentY);
|
||
}
|
||
|
||
private void AttachEventHandlers()
|
||
{
|
||
_strategyComboBox.SelectedIndexChanged += OnStrategyChanged;
|
||
_attributeComboBox.SelectedIndexChanged += OnAttributeChanged;
|
||
_browseDirectoryButton.Click += OnBrowseDirectory;
|
||
_previewButton.Click += OnPreviewClick;
|
||
_executeButton.Click += OnExecuteClick;
|
||
_helpButton.Click += OnHelpClick;
|
||
this.FormClosing += OnFormClosing;
|
||
}
|
||
|
||
private void InitializeManagers()
|
||
{
|
||
try
|
||
{
|
||
_splitterManager = new ModelSplitterManager();
|
||
_floorDetector = new FloorDetector();
|
||
_attributeGrouper = new AttributeGrouper();
|
||
|
||
// 订阅事件
|
||
_splitterManager.ProgressChanged += OnSplitterProgressChanged;
|
||
_splitterManager.StatusChanged += OnSplitterStatusChanged;
|
||
_splitterManager.LayerProcessed += OnLayerProcessed;
|
||
_splitterManager.SplitCompleted += OnSplitCompleted;
|
||
_splitterManager.ErrorOccurred += OnSplitterError;
|
||
|
||
LogManager.Info("[ModelSplitterDialog] 管理器初始化完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 管理器初始化失败: {ex.Message}");
|
||
MessageBox.Show($"初始化失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void LoadInitialData()
|
||
{
|
||
try
|
||
{
|
||
// 加载可用属性
|
||
LoadAvailableAttributes();
|
||
|
||
// 设置默认值
|
||
UpdateAttributeComboBox();
|
||
|
||
UpdateStatusLabel("就绪 - 请选择分层策略并点击预览");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 加载初始数据失败: {ex.Message}");
|
||
UpdateStatusLabel($"初始化错误: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 事件处理方法
|
||
|
||
private void OnStrategyChanged(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
UpdateAttributeComboBox();
|
||
ClearPreview();
|
||
_executeButton.Enabled = false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 策略变更处理失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void OnAttributeChanged(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
ClearPreview();
|
||
_executeButton.Enabled = false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 属性变更处理失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void OnBrowseDirectory(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
using (var dialog = new FolderBrowserDialog())
|
||
{
|
||
dialog.Description = "选择输出目录";
|
||
dialog.SelectedPath = _outputDirectoryTextBox.Text;
|
||
|
||
if (dialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
_outputDirectoryTextBox.Text = dialog.SelectedPath;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 浏览目录失败: {ex.Message}");
|
||
MessageBox.Show($"浏览目录失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void OnPreviewClick(object sender, EventArgs e)
|
||
{
|
||
if (_isProcessing) return;
|
||
|
||
try
|
||
{
|
||
_isProcessing = true;
|
||
_previewButton.Enabled = false;
|
||
UpdateStatusLabel("正在生成预览...");
|
||
|
||
var config = GetCurrentConfiguration();
|
||
if (!ValidateConfiguration(config))
|
||
return;
|
||
|
||
// 使用同步方法,避免异步复杂性(.NET Framework 4.6兼容)
|
||
_previewResults = _splitterManager.PreviewSplit(config);
|
||
|
||
UpdatePreviewList(_previewResults);
|
||
_executeButton.Enabled = _previewResults.Count > 0;
|
||
|
||
UpdateStatusLabel($"预览完成 - 识别到 {_previewResults.Count} 个分层");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 预览失败: {ex.Message}");
|
||
MessageBox.Show($"预览失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
UpdateStatusLabel("预览失败");
|
||
}
|
||
finally
|
||
{
|
||
_isProcessing = false;
|
||
_previewButton.Enabled = true;
|
||
}
|
||
}
|
||
|
||
private void OnExecuteClick(object sender, EventArgs e)
|
||
{
|
||
if (_isProcessing) return;
|
||
|
||
try
|
||
{
|
||
var result = MessageBox.Show(
|
||
$"确定要开始分层拆分吗?\n\n将生成 {_previewResults.Count} 个文件到:\n{_outputDirectoryTextBox.Text}",
|
||
"确认拆分", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (result != DialogResult.Yes)
|
||
return;
|
||
|
||
_isProcessing = true;
|
||
_executeButton.Enabled = false;
|
||
_previewButton.Enabled = false;
|
||
_progressBar.Visible = true;
|
||
|
||
var config = GetCurrentConfiguration();
|
||
|
||
// 使用同步方法,避免异步复杂性(.NET Framework 4.6兼容)
|
||
// 在后台线程中执行拆分操作
|
||
var backgroundWorker = new BackgroundWorker();
|
||
backgroundWorker.DoWork += (s, args) =>
|
||
{
|
||
try
|
||
{
|
||
var task = _splitterManager.ExecuteSplitAsync(config);
|
||
task.Wait(); // 等待异步任务完成
|
||
args.Result = task.Result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
args.Result = ex;
|
||
}
|
||
};
|
||
|
||
backgroundWorker.RunWorkerCompleted += (s, args) =>
|
||
{
|
||
try
|
||
{
|
||
if (args.Result is Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
|
||
var results = args.Result as List<ModelSplitterManager.SplitResult>;
|
||
if (results != null)
|
||
{
|
||
ShowCompletionDialog(results);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 执行拆分失败: {ex.Message}");
|
||
MessageBox.Show($"拆分失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
finally
|
||
{
|
||
_isProcessing = false;
|
||
_executeButton.Enabled = true;
|
||
_previewButton.Enabled = true;
|
||
_progressBar.Visible = false;
|
||
}
|
||
};
|
||
|
||
backgroundWorker.RunWorkerAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 执行拆分失败: {ex.Message}");
|
||
MessageBox.Show($"拆分失败: {ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
_isProcessing = false;
|
||
_executeButton.Enabled = true;
|
||
_previewButton.Enabled = true;
|
||
_progressBar.Visible = false;
|
||
}
|
||
}
|
||
|
||
private void OnHelpClick(object sender, EventArgs e)
|
||
{
|
||
string helpText = @"模型分层拆分工具使用说明:
|
||
|
||
1. 分层策略:
|
||
- 按楼层:根据楼层属性自动分层
|
||
- 按自定义属性:根据指定属性值分层
|
||
- 按类别:根据模型元素类别分层
|
||
- 按高程范围:根据Z坐标范围分层
|
||
|
||
2. 操作步骤:
|
||
- 选择分层策略和相关参数
|
||
- 设置输出目录和文件命名规则
|
||
- 点击'预览分层'查看分层结果
|
||
- 确认无误后点击'开始拆分'
|
||
|
||
3. 注意事项:
|
||
- 确保有足够的磁盘空间
|
||
- 拆分过程中请勿关闭Navisworks
|
||
- 建议先在小模型上测试
|
||
|
||
4. 文件命名变量:
|
||
- {ProjectName}: 项目名称
|
||
- {LayerName}: 分层名称
|
||
- {DateTime}: 当前时间";
|
||
|
||
MessageBox.Show(helpText, "帮助", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
|
||
private void OnFormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
if (_isProcessing)
|
||
{
|
||
var result = MessageBox.Show("拆分正在进行中,确定要关闭吗?", "确认关闭",
|
||
MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||
|
||
if (result == DialogResult.No)
|
||
{
|
||
e.Cancel = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 管理器事件处理
|
||
|
||
private void OnSplitterProgressChanged(object sender, ProgressChangedEventArgs e)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new Action(() => OnSplitterProgressChanged(sender, e)));
|
||
return;
|
||
}
|
||
|
||
_progressBar.Value = Math.Min(100, Math.Max(0, e.ProgressPercentage));
|
||
}
|
||
|
||
private void OnSplitterStatusChanged(object sender, string status)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new Action(() => OnSplitterStatusChanged(sender, status)));
|
||
return;
|
||
}
|
||
|
||
UpdateStatusLabel(status);
|
||
}
|
||
|
||
private void OnLayerProcessed(object sender, ModelSplitterManager.SplitResult result)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new Action(() => OnLayerProcessed(sender, result)));
|
||
return;
|
||
}
|
||
|
||
// 更新预览列表中对应项的状态
|
||
UpdatePreviewItemStatus(result);
|
||
}
|
||
|
||
private void OnSplitCompleted(object sender, List<ModelSplitterManager.SplitResult> results)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new Action(() => OnSplitCompleted(sender, results)));
|
||
return;
|
||
}
|
||
|
||
UpdateStatusLabel($"拆分完成 - 成功: {results.Count(r => r.Success)}, 失败: {results.Count(r => !r.Success)}");
|
||
}
|
||
|
||
private void OnSplitterError(object sender, Exception ex)
|
||
{
|
||
if (InvokeRequired)
|
||
{
|
||
Invoke(new Action(() => OnSplitterError(sender, ex)));
|
||
return;
|
||
}
|
||
|
||
UpdateStatusLabel($"错误: {ex.Message}");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 辅助方法
|
||
|
||
private void LoadAvailableAttributes()
|
||
{
|
||
try
|
||
{
|
||
var document = NavisApplication.ActiveDocument;
|
||
if (document?.Models?.Count > 0)
|
||
{
|
||
var allItems = document.Models.RootItemDescendantsAndSelf;
|
||
|
||
// 转换为ModelItemCollection
|
||
var itemCollection = new ModelItemCollection();
|
||
itemCollection.AddRange(allItems);
|
||
|
||
// 加载楼层属性
|
||
var floorAttributes = _floorDetector.GetAvailableFloorAttributes(itemCollection);
|
||
|
||
// 加载所有属性
|
||
var allAttributes = _attributeGrouper.GetAvailableAttributes(itemCollection);
|
||
|
||
// 合并并去重
|
||
var combinedAttributes = floorAttributes.Union(allAttributes).OrderBy(a => a).ToList();
|
||
|
||
_attributeComboBox.Items.Clear();
|
||
_attributeComboBox.Items.AddRange(combinedAttributes.ToArray());
|
||
|
||
if (combinedAttributes.Count > 0)
|
||
{
|
||
_attributeComboBox.SelectedIndex = 0;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"[ModelSplitterDialog] 加载属性失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void UpdateAttributeComboBox()
|
||
{
|
||
var strategy = GetSelectedStrategy();
|
||
_attributeComboBox.Enabled = (strategy == ModelSplitterManager.SplitStrategy.ByFloor ||
|
||
strategy == ModelSplitterManager.SplitStrategy.ByCustomAttribute);
|
||
}
|
||
|
||
private ModelSplitterManager.SplitStrategy GetSelectedStrategy()
|
||
{
|
||
switch (_strategyComboBox.SelectedIndex)
|
||
{
|
||
case 0: return ModelSplitterManager.SplitStrategy.ByFloor;
|
||
case 1: return ModelSplitterManager.SplitStrategy.ByCustomAttribute;
|
||
case 2: return ModelSplitterManager.SplitStrategy.ByCategory;
|
||
case 3: return ModelSplitterManager.SplitStrategy.ByElevation;
|
||
default: return ModelSplitterManager.SplitStrategy.ByFloor;
|
||
}
|
||
}
|
||
|
||
private ModelSplitterManager.SplitConfiguration GetCurrentConfiguration()
|
||
{
|
||
return new ModelSplitterManager.SplitConfiguration
|
||
{
|
||
Strategy = GetSelectedStrategy(),
|
||
AttributeName = _attributeComboBox.Text,
|
||
OutputDirectory = _outputDirectoryTextBox.Text,
|
||
FileNamePattern = _fileNamePatternTextBox.Text,
|
||
IncludeEmptyLayers = _includeEmptyLayersCheckBox.Checked,
|
||
CreateSubDirectories = _createSubDirectoriesCheckBox.Checked,
|
||
GenerateReport = _generateReportCheckBox.Checked,
|
||
ElevationTolerance = (double)_elevationToleranceNumeric.Value,
|
||
MinFloorHeight = (double)_minFloorHeightNumeric.Value
|
||
};
|
||
}
|
||
|
||
private bool ValidateConfiguration(ModelSplitterManager.SplitConfiguration config)
|
||
{
|
||
if (string.IsNullOrEmpty(config.OutputDirectory))
|
||
{
|
||
MessageBox.Show("请指定输出目录", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return false;
|
||
}
|
||
|
||
if ((config.Strategy == ModelSplitterManager.SplitStrategy.ByFloor ||
|
||
config.Strategy == ModelSplitterManager.SplitStrategy.ByCustomAttribute) &&
|
||
string.IsNullOrEmpty(config.AttributeName))
|
||
{
|
||
MessageBox.Show("请选择分层属性", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return false;
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(config.FileNamePattern))
|
||
{
|
||
MessageBox.Show("请指定文件命名模式", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private void UpdatePreviewList(List<ModelSplitterManager.SplitResult> results)
|
||
{
|
||
_previewListView.Items.Clear();
|
||
|
||
foreach (var result in results)
|
||
{
|
||
var item = new ListViewItem(result.LayerName);
|
||
item.SubItems.Add(result.ItemCount.ToString());
|
||
item.SubItems.Add(Path.GetFileName(result.OutputFilePath));
|
||
item.SubItems.Add("待处理");
|
||
item.Tag = result;
|
||
|
||
_previewListView.Items.Add(item);
|
||
}
|
||
}
|
||
|
||
private void UpdatePreviewItemStatus(ModelSplitterManager.SplitResult result)
|
||
{
|
||
foreach (ListViewItem item in _previewListView.Items)
|
||
{
|
||
if (item.Tag is ModelSplitterManager.SplitResult itemResult &&
|
||
itemResult.LayerName == result.LayerName)
|
||
{
|
||
item.SubItems[3].Text = result.Success ? "完成" : "失败";
|
||
item.ForeColor = result.Success ? System.Drawing.Color.Green : System.Drawing.Color.Red;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ClearPreview()
|
||
{
|
||
_previewListView.Items.Clear();
|
||
_previewResults = null;
|
||
}
|
||
|
||
private void UpdateStatusLabel(string status)
|
||
{
|
||
_statusLabel.Text = status;
|
||
_statusLabel.Refresh();
|
||
}
|
||
|
||
private void ShowCompletionDialog(List<ModelSplitterManager.SplitResult> results)
|
||
{
|
||
int successCount = results.Count(r => r.Success);
|
||
int failCount = results.Count(r => !r.Success);
|
||
|
||
string message = $"分层拆分完成!\n\n成功: {successCount} 个文件\n失败: {failCount} 个文件\n\n";
|
||
|
||
if (successCount > 0)
|
||
{
|
||
message += $"文件已保存到: {_outputDirectoryTextBox.Text}\n\n";
|
||
}
|
||
|
||
message += "是否打开输出目录?";
|
||
|
||
var result = MessageBox.Show(message, "拆分完成",
|
||
MessageBoxButtons.YesNo, MessageBoxIcon.Information);
|
||
|
||
if (result == DialogResult.Yes && Directory.Exists(_outputDirectoryTextBox.Text))
|
||
{
|
||
System.Diagnostics.Process.Start("explorer.exe", _outputDirectoryTextBox.Text);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |