整理代码
This commit is contained in:
304
ShrlAlgoToolkit.RevitAddins/RvCivil/SplitComsByLevelCmd.cs
Normal file
304
ShrlAlgoToolkit.RevitAddins/RvCivil/SplitComsByLevelCmd.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using System.Windows;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.IFC;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
using ShrlAlgo.RvKits.Windows;
|
||||
using ShrlAlgo.Toolkit.Core.Assist;
|
||||
|
||||
namespace ShrlAlgo.RvKits.RvCivil;
|
||||
|
||||
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
||||
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
||||
public class SplitComsByLevelCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
var instances = Document.OfCollector().OfClass(typeof(FamilyInstance)).Cast<FamilyInstance>().ToList();
|
||||
var errors = new List<MessageModel>();
|
||||
using (TransactionGroup tg = new(Document, "按标高拆分墙、柱"))
|
||||
{
|
||||
tg.Start();
|
||||
//墙打断
|
||||
using (Transaction trans = new(Document, "楼层分割打断构件"))
|
||||
{
|
||||
trans.Start();
|
||||
|
||||
var walls = Document.OfCollector().OfClass(typeof(Wall)).Cast<Wall>().ToList();
|
||||
var structuralColumns = Document.OfCollector()
|
||||
.OfClass(typeof(FamilyInstance))
|
||||
.OfCategory(BuiltInCategory.OST_StructuralColumns)
|
||||
.Cast<FamilyInstance>()
|
||||
.ToList();
|
||||
var columns = Document.OfCollector()
|
||||
.OfClass(typeof(FamilyInstance))
|
||||
.OfCategory(BuiltInCategory.OST_Columns)
|
||||
.Cast<FamilyInstance>()
|
||||
.ToList();
|
||||
var elemToSplitIds = new List<ElementId>();
|
||||
foreach (var wall in walls)
|
||||
{
|
||||
//得到墙的包围框
|
||||
var canModify = true;
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
if (instance.Host != null && instance.Host.Id == wall.Id)
|
||||
{
|
||||
errors.Add(new MessageModel(wall, "有族基于当前墙无法拆分"));
|
||||
canModify = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ExporterIFCUtils.HasElevationProfile(wall))
|
||||
{
|
||||
canModify = false;
|
||||
errors.Add(new MessageModel(wall, "轮廓被修改无法拆分"));
|
||||
}
|
||||
|
||||
var needToDelete = false;
|
||||
if (canModify)
|
||||
{
|
||||
needToDelete = SplitWallByLevel(Document, wall, ActiveView);
|
||||
}
|
||||
|
||||
if (needToDelete)
|
||||
{
|
||||
elemToSplitIds.Add(wall.Id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var column in structuralColumns)
|
||||
{
|
||||
var canModify = true;
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
if (instance.Host != null && instance.Host.Id == column.Id)
|
||||
{
|
||||
errors.Add(new MessageModel(column, "有族基于当前结构柱,无法拆分"));
|
||||
canModify = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var needToDelete = false;
|
||||
if (canModify)
|
||||
{
|
||||
needToDelete = SplitColumnByLevel(Document, column, ActiveView);
|
||||
}
|
||||
|
||||
if (needToDelete)
|
||||
{
|
||||
elemToSplitIds.Add(column.Id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var column in columns)
|
||||
{
|
||||
var canModify = true;
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
if (instance.Host != null && instance.Host.Id == column.Id)
|
||||
{
|
||||
errors.Add(new MessageModel(column, "有族基于当前柱,无法拆分"));
|
||||
canModify = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var needToDelete = false;
|
||||
if (canModify)
|
||||
{
|
||||
needToDelete = SplitColumnByLevel(Document, column, ActiveView);
|
||||
}
|
||||
|
||||
if (needToDelete)
|
||||
{
|
||||
elemToSplitIds.Add(column.Id);
|
||||
}
|
||||
}
|
||||
|
||||
Document.Delete(elemToSplitIds);
|
||||
trans.Commit();
|
||||
}
|
||||
|
||||
tg.Assimilate();
|
||||
}
|
||||
|
||||
if (errors.Any())
|
||||
{
|
||||
WinDialogHelper.ShowModeless<MessageWin>(new MessageViewModel(UiDocument, errors, "未解决错误"));
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("处理完成", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool SplitColumnByLevel(Document document, FamilyInstance column, View view)
|
||||
{
|
||||
var wallBox = column.get_BoundingBox(view);
|
||||
var minZ = wallBox.Min.Z;
|
||||
var maxZ = wallBox.Max.Z;
|
||||
var allLevels = document
|
||||
.OfClass<Level>()
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.OrderBy(o => o.Elevation)
|
||||
.ToList();
|
||||
var toSplit = document
|
||||
.OfClass<Level>()
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.Where(l => l.Elevation - minZ > 0.0001 && maxZ - l.Elevation > 0.0001)
|
||||
.OrderBy(o => o.Elevation)
|
||||
.ToList();
|
||||
|
||||
if (toSplit.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var n = allLevels.FindIndex(l => l.Id == toSplit[0].Id);
|
||||
var minLevel = allLevels[0];
|
||||
if (n > 0)
|
||||
{
|
||||
minLevel = allLevels[n - 1]; //存在更低的标高时,取此标高作为底标高约束
|
||||
}
|
||||
|
||||
var translation = XYZ.BasisZ;
|
||||
|
||||
var bottomEleIds = ElementTransformUtils.CopyElement(document, column.Id, translation);
|
||||
var minWall = document.GetElement(bottomEleIds.FirstOrDefault()) as FamilyInstance;
|
||||
//底部约束
|
||||
minWall.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(minLevel.Id);
|
||||
minWall.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(minZ - minLevel.Elevation);
|
||||
minWall.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(toSplit[0].Id);
|
||||
minWall.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(0);
|
||||
|
||||
var maxLevel = toSplit.Last();
|
||||
var m = allLevels.FindIndex(l => l.Id == toSplit.Last().Id);
|
||||
if (m < allLevels.Count - 1)
|
||||
{
|
||||
maxLevel = allLevels[m + 1]; //存在更高的标高
|
||||
}
|
||||
|
||||
var topEleIds = ElementTransformUtils.CopyElement(document, column.Id, translation);
|
||||
var maxWall = document.GetElement(topEleIds.FirstOrDefault()) as FamilyInstance;
|
||||
|
||||
maxWall.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(toSplit.Last().Id);
|
||||
maxWall.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(0);
|
||||
maxWall.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(maxLevel.Id);
|
||||
maxWall.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(maxZ - maxLevel.Elevation);
|
||||
|
||||
for (var i = 0; i < toSplit.Count - 1; i++)
|
||||
{
|
||||
var baseLevel = toSplit[i];
|
||||
var topLevel = toSplit[i + 1];
|
||||
var eleIds = ElementTransformUtils.CopyElement(document, column.Id, translation);
|
||||
var wallCopy = document.GetElement(eleIds.FirstOrDefault()) as FamilyInstance;
|
||||
wallCopy.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(baseLevel.Id);
|
||||
wallCopy.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(0);
|
||||
|
||||
wallCopy.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(topLevel.Id);
|
||||
wallCopy.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(0);
|
||||
//if (i == levelsToSplit.Count - 2 && maxZ < maxLevel.Bottom)
|
||||
//{
|
||||
// wallCopy.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(maxZ - maxLevel.Bottom);
|
||||
//}
|
||||
//Wall.Create(document, curve, wall.WallType.ViewId, levels[i].ViewId, 100, 100, false, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切分墙体
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
/// <param name="wall"></param>
|
||||
/// <param name="view">三维视图</param>
|
||||
/// <returns></returns>
|
||||
private static bool SplitWallByLevel(Document doc, Wall wall, View view)
|
||||
{
|
||||
var wallBox = wall.get_BoundingBox(view);
|
||||
var minZ = wallBox.Min.Z;
|
||||
var maxZ = wallBox.Max.Z;
|
||||
var allLevels = new FilteredElementCollector(doc)
|
||||
.OfClass(typeof(Level))
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.OrderBy(o => o.Elevation)
|
||||
.ToList();
|
||||
var toSplit = new FilteredElementCollector(doc)
|
||||
.OfClass(typeof(Level))
|
||||
.OfCategory(BuiltInCategory.OST_Levels)
|
||||
.Cast<Level>()
|
||||
.Where(l => l.Elevation - minZ > 0.0001 && maxZ - l.Elevation > 0.0001)
|
||||
.OrderBy(o => o.Elevation)
|
||||
.ToList();
|
||||
|
||||
if (toSplit.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var n = allLevels.FindIndex(l => l.Id == toSplit[0].Id);
|
||||
var minLevel = allLevels[0];
|
||||
if (n > 0)
|
||||
{
|
||||
minLevel = allLevels[n - 1]; //存在更低的标高时,取此标高作为底标高约束
|
||||
}
|
||||
|
||||
var translation = XYZ.BasisZ;
|
||||
var bottomEleIds = ElementTransformUtils.CopyElement(doc, wall.Id, translation);
|
||||
var minWall = doc.GetElement(bottomEleIds.FirstOrDefault()) as Wall;
|
||||
//底部约束
|
||||
minWall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(minLevel.Id);
|
||||
minWall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(minZ - minLevel.Elevation);
|
||||
minWall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(toSplit[0].Id);
|
||||
minWall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(0);
|
||||
|
||||
//Wall.Create(doc, (wall.Location as LocationCurve).Curve, wall.WallType.Id, minLevel.Id, minLevel.Bottom - minZ, minZ - minLevel.Bottom, wall.Flipped, Convert.ToBoolean(wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger()));
|
||||
|
||||
var maxLevel = toSplit.Last();
|
||||
var m = allLevels.FindIndex(l => l.Id == toSplit.Last().Id);
|
||||
if (m < allLevels.Count - 1)
|
||||
{
|
||||
maxLevel = allLevels[m + 1]; //存在更高的标高
|
||||
}
|
||||
|
||||
var topEleIds = ElementTransformUtils.CopyElement(doc, wall.Id, translation);
|
||||
doc.Regenerate();
|
||||
var maxWall = doc.GetElement(topEleIds.FirstOrDefault()) as Wall;
|
||||
|
||||
maxWall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(toSplit.Last().Id);
|
||||
maxWall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(0);
|
||||
maxWall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(maxLevel.Id);
|
||||
maxWall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(maxZ - maxLevel.Elevation);
|
||||
|
||||
for (var i = 0; i < toSplit.Count - 1; i++)
|
||||
{
|
||||
var baseLevel = toSplit[i];
|
||||
var topLevel = toSplit[i + 1];
|
||||
var eleIds = ElementTransformUtils.CopyElement(doc, wall.Id, translation);
|
||||
doc.Regenerate();
|
||||
var wallCopy = doc.GetElement(eleIds.FirstOrDefault()) as Wall;
|
||||
wallCopy.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(baseLevel.Id);
|
||||
wallCopy.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(0);
|
||||
|
||||
wallCopy.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(topLevel.Id);
|
||||
wallCopy.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(0);
|
||||
//if (i == levelsToSplit.Count - 2 && maxZ < maxLevel.Bottom)
|
||||
//{
|
||||
// wallCopy.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(maxZ - maxLevel.Bottom);
|
||||
//}
|
||||
//Wall.Create(document, curve, wall.WallType.ViewId, levels[i].ViewId, 100, 100, false, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user