319 lines
16 KiB
C#
319 lines
16 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|