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 GetStairsCDM(Document doc, IList levels, View3D v3d) { List cdmStairs = new List(); var stairsLi = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Stairs).OfClass(typeof(Stairs)).ToElements(); //楼板类型及编号 Dictionary dicStairs = new Dictionary(); Dictionary 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 targetcdm = from d in cdmStairs where d.LevelId.Equals(levels[i].Id) && d.SymbolId.Equals(id) select d; //排序 //var li = targetcdm.ToList(); List 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 rstairs, Level level) { FilteredElementCollector levelcol = new FilteredElementCollector(doc).OfClass(typeof(Level)); Level leveltop = null; foreach (Level l in levelcol.Cast().Where(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 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 stairsPathIds =new FilteredElementCollector(doc).OfClass(typeof(StairsPathType)).ToElementIds(); //var plan = new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)).Cast().Where(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 bdryCurves = new List(); IList riserCurves = new List(); IList pathCurves = new List(); 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 bdryCurves = new List(); IList riserCurves = new List(); IList pathCurves = new List(); 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 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; } } }