Files
CDMUtility/CDMUtil/Utility/StairsUtil.cs

319 lines
16 KiB
C#
Raw Normal View History

2026-02-23 14:35:54 +08:00
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using CDM.Interop.Revit.CDMComponent;
using CDM.Interop.Revit.RevitCompoent;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CDM.Interop.Revit.Utility
{
class StairsUtil : Utility
{
public static List<CDMStairs> GetStairsCDM(Document doc, IList<Element> levels, View3D v3d)
{
List<CDMStairs> cdmStairs = new List<CDMStairs>();
var stairsLi = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Stairs).OfClass(typeof(Stairs)).ToElements();
//楼板类型及编号
Dictionary<ElementId, string> dicStairs = new Dictionary<ElementId, string>();
Dictionary<ElementId, string> dictLevelId_LevelCodes = GetDictLevelId_LevelCodes(doc);
int num = 1;
for (int i = 0; i < stairsLi.Count; i++)
{
ElementId stairstypeId = stairsLi[i].GetTypeId();
try
{
dicStairs.Add(stairstypeId, string.Format("00{0}", num));
num += 1;
}
catch (Exception)
{
continue;
}
}
foreach (Stairs stair in stairsLi)
{
CDMStairs cdmStair = new CDMStairs(doc, v3d, stair);
////通过out将获取到的值复制给cdm的类型id,out参数必须在函数内初始化值
dicStairs.TryGetValue(stair.GetTypeId(), out cdmStair.CategoryCode);
dictLevelId_LevelCodes.TryGetValue(cdmStair.LevelId, out cdmStair.LevelCode);
cdmStairs.Add(cdmStair);
}
for (int i = 0; i < levels.Count(); i++)
{
for (int j = 0; j < dicStairs.Count; j++)
{
ElementId id = dicStairs.ElementAt(j).Key;
//归类cdm中同标高同类型
IEnumerable<CDMStairs> targetcdm = from d in cdmStairs
where d.LevelId.Equals(levels[i].Id) && d.SymbolId.Equals(id)
select d;
//排序
//var li = targetcdm.ToList();
List<CDMStairs> li = targetcdm.OrderByDescending(p => p.Yw).ThenBy(p => p.Xl).ToList();
for (int k = 0; k < li.Count; k++)
{
if (k > 8)
{
if (k > 98)
{
li[k].LevelComponentCode = string.Format("{0}", k + 1);
}
else
{
li[k].LevelComponentCode = string.Format("0{0}", k + 1);
}
}
else
{
li[k].LevelComponentCode = string.Format("00{0}", k + 1);
}
}
}
}
return cdmStairs;
}
public static void PlaceStairs(Document doc, List<RevitStairs> rstairs, Level level)
{
FilteredElementCollector levelcol = new FilteredElementCollector(doc).OfClass(typeof(Level));
Level leveltop = null;
foreach (Level l in levelcol.Cast<Level>().Where<Level>(l => l.ProjectElevation > 0))
{
if (l.ProjectElevation > 0)
{
leveltop = l;
break;
}
}
if (rstairs == null || level == null)
{
return;
}
//CreateSampleStairs(doc, level, leveltop);
CreateStairs(doc, rstairs, level, leveltop);
}
private static void CreateStairs(Document doc, List<RevitStairs> rstairses, Level levelBottom, Level levelTop)
{
using (TransactionGroup transG = new TransactionGroup(doc, "创建楼梯"))
{
transG.Start();
foreach (var rstairs in rstairses)
{
using (StairsEditScope newStairsScope = new StairsEditScope(doc, "新建楼梯"))
{
ElementId stairsId = newStairsScope.Start(levelBottom.Id, levelTop.Id);
var stairs = doc.GetElement(stairsId) as Stairs;
var typeid = doc.GetElement(stairsId).GetTypeId();
var stairsType = doc.GetElement(typeid) as StairsType;
using (Transaction stairsTrans = new Transaction(doc, "添加梯段和平台到楼梯"))
{
stairsTrans.Start();
stairs.get_Parameter(BuiltInParameter.STAIRS_BASE_LEVEL_PARAM).Set(levelBottom.Id);
stairs.get_Parameter(BuiltInParameter.STAIRS_TOP_LEVEL_PARAM).Set(levelBottom.Id);
stairs.get_Parameter(BuiltInParameter.STAIRS_BASE_OFFSET).Set(rstairs.BaseElevation);
stairs.get_Parameter(BuiltInParameter.STAIRS_TOP_OFFSET).Set(rstairs.TopElevation);
if (stairsType.get_Parameter(BuiltInParameter.STAIRS_ATTR_MINIMUM_TREAD_DEPTH).AsDouble() > rstairs.ThreadDepth)
{
stairsType.get_Parameter(BuiltInParameter.STAIRS_ATTR_MINIMUM_TREAD_DEPTH).Set(rstairs.ThreadDepth);
}
stairs.get_Parameter(BuiltInParameter.STAIRS_ACTUAL_TREAD_DEPTH).Set(rstairs.ThreadDepth);
stairs.get_Parameter(BuiltInParameter.STAIRS_DESIRED_NUMBER_OF_RISERS).Set(rstairs.GetNumberOfRisers(rstairs.Runs));
doc.GetElement(stairsType.RunType).get_Parameter(BuiltInParameter.STAIRS_RUNTYPE_STRUCTURAL_DEPTH).Set(rstairs.Runs[0].Thickness / 304.8);
doc.GetElement(stairsType.LandingType).get_Parameter(BuiltInParameter.STAIRS_LANDINGTYPE_THICKNESS).Set(rstairs.Landing.Thickness / 304.8);
#region
StairsRun run1 = CreateStairsSketchedRun(doc, rstairs.Runs[0], rstairs.Runs[0].RelativeBaseElevation / 304.8, stairsId);
//run1.BaseElevation = rstairs.Runs[0].BaseElevation;
//run1.TopElevation = rstairs.Runs[0].TopELevation;
StairsRun run2 = CreateStairsSketchedRun(doc, rstairs.Runs[1], rstairs.Runs[1].RelativeBaseElevation / 304.8, stairsId);
//run2.BaseElevation = rstairs.Runs[1].BaseElevation;
//run2.TopElevation = rstairs.Runs[1].TopELevation;
StairsLanding newLanding = StairsLanding.CreateSketchedLanding(doc, stairsId, rstairs.Landing.GetCurves(), rstairs.Landing.RelativeElevation / 304.8);
//newLanding.BaseElevation = rstairs.Landing.Elevation / 304.8;
#endregion
#region
//StairsRun newRun1 = StairsRun.CreateStraightRun(doc, stairsId, rstairs.Runs[0].LocationLine, StairsRunJustification.Center);
//newRun1.ActualRunWidth = rstairs.Runs[0].Width / 304.8;
//newRun1.TopElevation = rstairs.Runs[0].RelativeTopELevation / 304.8;
//newRun1.BaseElevation = rstairs.Runs[0].RelativeBaseElevation / 304.8;
//StairsRun newRun2 = StairsRun.CreateStraightRun(doc, stairsId, rstairs.Runs[1].LocationLine, StairsRunJustification.Center);
//newRun2.ActualRunWidth = rstairs.Runs[1].Width / 304.8;
//newRun2.TopElevation = rstairs.Runs[1].RelativeTopELevation / 304.8;
//newRun2.BaseElevation = rstairs.Runs[1].RelativeBaseElevation / 304.8;
//添加休息平台
//LinkElementId stairsLinkId = new LinkElementId(stairsId);
//ICollection<ElementId> stairsPathIds =new FilteredElementCollector(doc).OfClass(typeof(StairsPathType)).ToElementIds();
//var plan = new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)).Cast<ViewPlan>().Where<ViewPlan>(v => v.GenLevel.ProjectElevation == 0).FirstOrDefault();
//StairsPath.Create(doc, stairsLinkId, typeid, plan.Id);
#endregion
stairsTrans.Commit();
}
// 编辑模式提交的时产生的错误处理
newStairsScope.Commit(new StairsFailurePreprocessor());
}
}
using(Transaction trans=new Transaction(doc, "删除栏杆"))
{
trans.Start();
var ids = new FilteredElementCollector(doc).OfClass(typeof(Railing)).ToElementIds();
foreach (var id in ids)
{
doc.Delete(id);
}
trans.Commit();
}
transG.Assimilate();
}
}
private static StairsRun CreateStairsSketchedRun(Document doc, RevitStairsRun rstairsrun, double levelBottom, ElementId stairsId)
{
IList<Curve> bdryCurves = new List<Curve>();
IList<Curve> riserCurves = new List<Curve>();
IList<Curve> pathCurves = new List<Curve>();
Line locationline = rstairsrun.LocationLine;
Line l1 = locationline.CreateOffset(rstairsrun.Width / 2 / 304.8, new XYZ(0, 0, 1)) as Line;
Line l2 = locationline.CreateOffset(-rstairsrun.Width / 2 / 304.8, new XYZ(0, 0, 1)) as Line;
// boundaries
bdryCurves.Add(l1);
bdryCurves.Add(l2);
// riser curves
int riserNum = rstairsrun.NumberOfRisers - 1;
for (int ii = 0; ii <= riserNum; ii++)
{
XYZ end0 = l1.Evaluate(ii / (double)riserNum, true);
XYZ end1 = l2.Evaluate(ii / (double)riserNum, true);
//XYZ end0 = (l1.GetEndPoint(0) + l1.GetEndPoint(1)) * ii / (double)riserNum;
//XYZ end1 = (l2.GetEndPoint(0) + l2.GetEndPoint(1)) * ii / (double)riserNum;
//XYZ end2 = new XYZ(end1.X, 10, 0);
riserCurves.Add(Line.CreateBound(end0, end1));
}
//stairs path curves
pathCurves.Add(locationline);
StairsRun newRun = StairsRun.CreateSketchedRun(doc, stairsId, levelBottom, bdryCurves, riserCurves, pathCurves);
return newRun;
}
private static ElementId CreateSampleStairs(Document document, Level levelBottom, Level levelTop)
{
ElementId newStairsId = null;
using (StairsEditScope newStairsScope = new StairsEditScope(document, "New Stairs"))
{
newStairsId = newStairsScope.Start(levelBottom.Id, levelTop.Id);
using (Transaction stairsTrans = new Transaction(document, "Add Runs and Landings to Stairs"))
{
stairsTrans.Start();
// Create a sketched run for the stairs
IList<Curve> bdryCurves = new List<Curve>();
IList<Curve> riserCurves = new List<Curve>();
IList<Curve> pathCurves = new List<Curve>();
XYZ pnt1 = new XYZ(0, 0, 0);
XYZ pnt2 = new XYZ(15, 0, 0);
XYZ pnt3 = new XYZ(0, 10, 0);
XYZ pnt4 = new XYZ(15, 10, 0);
// boundaries
bdryCurves.Add(Line.CreateBound(pnt1, pnt2));
bdryCurves.Add(Line.CreateBound(pnt3, pnt4));
// riser curves
const int riserNum = 20;
for (int ii = 0; ii <= riserNum; ii++)
{
XYZ end0 = (pnt1 + pnt2) * ii / (double)riserNum;
XYZ end1 = (pnt3 + pnt4) * ii / (double)riserNum;
XYZ end2 = new XYZ(end1.X, 10, 0);
riserCurves.Add(Line.CreateBound(end0, end2));
}
//stairs path curves
XYZ pathEnd0 = (pnt1 + pnt3) / 2.0;
XYZ pathEnd1 = (pnt2 + pnt4) / 2.0;
pathCurves.Add(Line.CreateBound(pathEnd0, pathEnd1));
StairsRun newRun1 = StairsRun.CreateSketchedRun(document, newStairsId, levelBottom.Elevation, bdryCurves, riserCurves, pathCurves);
// Add a straight run
Line locationLine = Line.CreateBound(new XYZ(20, -5, newRun1.TopElevation), new XYZ(35, -5, newRun1.TopElevation));
StairsRun newRun2 = StairsRun.CreateStraightRun(document, newStairsId, locationLine, StairsRunJustification.Center);
newRun2.ActualRunWidth = 10;
// Add a landing between the runs
CurveLoop landingLoop = new CurveLoop();
XYZ p1 = new XYZ(15, 10, 0);
XYZ p2 = new XYZ(20, 10, 0);
XYZ p3 = new XYZ(20, -10, 0);
XYZ p4 = new XYZ(15, -10, 0);
Line curve_1 = Line.CreateBound(p1, p2);
Line curve_2 = Line.CreateBound(p2, p3);
Line curve_3 = Line.CreateBound(p3, p4);
Line curve_4 = Line.CreateBound(p4, p1);
landingLoop.Append(curve_1);
landingLoop.Append(curve_2);
landingLoop.Append(curve_3);
landingLoop.Append(curve_4);
StairsLanding newLanding = StairsLanding.CreateSketchedLanding(document, newStairsId, landingLoop, newRun1.TopElevation);
stairsTrans.Commit();
}
// A failure preprocessor is to handle possible failures during the edit mode commitment process.
newStairsScope.Commit(new StairsFailurePreprocessor());
}
return newStairsId;
}
}
class StairsFailurePreprocessor : IFailuresPreprocessor
{
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
{
IList<FailureMessageAccessor> listFma = failuresAccessor.GetFailureMessages();
if (listFma.Count == 0)
return FailureProcessingResult.Continue;
foreach (FailureMessageAccessor fma in listFma)
{
// 如果是错误,则尝试解决
if (fma.GetSeverity() == FailureSeverity.Error)
{
// 模拟手动单击"删除连接"按钮
if (fma.HasResolutions())
failuresAccessor.ResolveFailure(fma);
}
// 如果是警告,则禁止弹框
if (fma.GetSeverity() == FailureSeverity.Warning)
{
//failuresAccessor.DeleteAllWarnings();
failuresAccessor.DeleteWarning(fma);
}
}
return FailureProcessingResult.ProceedWithCommit;
// Use default failure processing
//return FailureProcessingResult.Continue;
}
}
}