Files
CDMUtility/CDMUtil/Utility/StairsUtil.cs
2026-02-23 14:35:54 +08:00

319 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}