Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvCivil/ModelSplitterCmd.cs

160 lines
5.2 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using System.IO;
using System.Text;
using System.Windows;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Nice3point.Revit.Toolkit.External;
2025-04-24 20:56:44 +08:00
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
2024-09-22 11:05:41 +08:00
/// <summary>
/// 按标高拆分成多个模型
/// </summary>
[Transaction(TransactionMode.Manual)]
public class ModelSplitterCmd : ExternalCommand
{
public override void Execute()
{
var result = MessageBox.Show("执行前请手动备份文件避免出现意外情况!", "模型拆分", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
return;
}
#region FilterExecute
var levels = Document
.OfClass<Level>()
.Cast<Level>()
.OrderBy(l => l.Elevation)
.ToList();
Dictionary<Level, Outline> levelOutlines = [];
//获取标高范围
for (var i = 0; i < levels.Count; i++)
{
var baseLevel = levels[i];
XYZ min = new(double.MinValue, double.MinValue, baseLevel.Elevation);
XYZ max;
Outline outline;
if (i < levels.Count - 1)
{
var topLevel = levels[i + 1];
max = new XYZ(double.MaxValue, double.MaxValue, topLevel.Elevation);
outline = new Outline(min, max);
}
else
{
max = new XYZ(double.MaxValue, double.MaxValue, double.MaxValue);
outline = new Outline(min, max);
}
levelOutlines.Add(baseLevel, outline);
}
StringBuilder sb = new();
//对比标高,得到实际分层位置
foreach (var keyPair in levelOutlines)
{
//得到在标高范围内的元素
BoundingBoxIsInsideFilter insideFilter = new(keyPair.Value);
LogicalOrFilter logicalOr = new(new ElementClassFilter(typeof(HostObject)), new ElementClassFilter(typeof(FamilyInstance)));
var insideCollector = Document.OfModelCollector()?.WherePasses(insideFilter).WherePasses(logicalOr).ToList();
if (insideCollector == null)
{
return;
}
2024-09-22 11:05:41 +08:00
var level = keyPair.Key;
var elemIds = insideCollector.Where(elem => elem.get_BoundingBox(null) != null)
.Select(elem => elem.Id)
.ToList();
foreach (var elementId in elemIds)
{
sb.AppendLine(elementId.ToString());
}
if (elemIds.Count == 0)
{
continue;
}
var folder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + $"\\{Document.Title}";
var fileName = $"{level.Name}.rvt";
var filePath = $"{folder}\\{fileName}";
var targetDocument = Application.NewProjectDocument(UnitSystem.Metric);
using (Transaction trans = new(targetDocument, "创建标高"))
{
trans.Start();
try
{
var targetLevel = Level.Create(targetDocument, level.Elevation);
ElementTransformUtils.CopyElements(Document, elemIds, targetDocument, null, new CopyPasteOptions());
//targetLevel.Name = level.Name;
trans.Commit();
}
catch (Exception ex)
{
ErrorMessage = ex.Message + sb;
Result = Result.Failed;
if (trans.GetStatus() == TransactionStatus.Started)
{
trans.RollBack();
}
targetDocument.Close(false);
return;
}
}
try
{
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
targetDocument.SaveAs($"{folder}\\{fileName}");
targetDocument.Close(false);
}
catch (Exception e)
{
ErrorMessage = e.Message;
Result = Result.Failed;
return;
}
using (Transaction trans = new(Document, "按标高分割文件"))
{
trans.Start();
try
{
Document.Delete(elemIds);
var mp = ModelPathUtils.ConvertUserVisiblePathToModelPath(filePath);
RevitLinkOptions options = new(true);
var linkType = RevitLinkType.Create(Document, mp, options);
var instance = RevitLinkInstance.Create(Document, linkType.ElementId, ImportPlacement.Origin);
trans.Commit();
}
catch (Exception ex)
{
ErrorMessage = ex.Message + sb;
Result = Result.Failed;
if (trans.GetStatus() == TransactionStatus.Started)
{
trans.RollBack();
}
return;
}
}
}
#endregion FilterExecute
}
}