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;
|
||
}
|
||
}
|
||
|
||
} |