miki969696

revit api楼梯创建

 

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;

namespace StairsCreation
{
    [Transaction(TransactionMode.Manual)]
    public class CreateStairsCommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            UIDocument uiDoc = uiApp.ActiveUIDocument;
            Document doc = uiDoc.Document;

            try
            {
                // 获取或创建标高0和4000
                Level levelBottom = GetOrCreateLevel(doc, 0, "Level 0");
                Level levelTop = GetOrCreateLevel(doc, 4000, "Level 4000");

                if (levelBottom == null || levelTop == null)
                {
                    TaskDialog.Show("错误", "创建标高时发生错误。");
                    return Result.Failed;
                }

                // 创建楼梯
                ElementId stairsId = CreateStairs(doc, levelBottom, levelTop);

                if (stairsId != null)
                {
                    TaskDialog.Show("成功", "楼梯已成功创建!");
                    return Result.Succeeded;
                }
                else
                {
                    TaskDialog.Show("失败", "创建楼梯时发生错误。");
                    return Result.Failed;
                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
                return Result.Failed;
            }
        }

        private ElementId CreateStairs(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();

                    // 创建楼梯草图梯段
                    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);

                    // 边界曲线
                    bdryCurves.Add(Line.CreateBound(pnt1, pnt2));
                    bdryCurves.Add(Line.CreateBound(pnt3, pnt4));

                    // 梯级曲线
                    // 计算实际需要的踏步数量(考虑总高度4000)
                    double totalHeight = levelTop.Elevation - levelBottom.Elevation;
                    double riserHeight = 200; // 假设踏步高度为200
                    int riserNum = (int)Math.Round(totalHeight / riserHeight);
                    riserNum = Math.Max(1, riserNum); // 确保至少有一个踏步

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

                    // 楼梯路径曲线
                    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);

                    // 添加直梯段
                    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;

                    // 在梯段之间添加平台
                    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);

                    landingLoop.Append(Line.CreateBound(p1, p2));
                    landingLoop.Append(Line.CreateBound(p2, p3));
                    landingLoop.Append(Line.CreateBound(p3, p4));
                    landingLoop.Append(Line.CreateBound(p4, p1));

                    StairsLanding newLanding = StairsLanding.CreateSketchedLanding(
                        document, newStairsId, landingLoop, newRun1.TopElevation);

                    stairsTrans.Commit();
                }

                // 提交楼梯编辑范围,处理可能的失败
                newStairsScope.Commit(new StairsFailurePreprocessor());
            }

            return newStairsId;
        }

        // 根据标高获取或创建Level元素
        private Level GetOrCreateLevel(Document doc, double elevation, string levelName)
        {
            // 先尝试查找现有标高
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            collector.OfClass(typeof(Level));

            foreach (Level level in collector)
            {
                // 考虑浮点精度问题,使用容差比较
                if (Math.Abs(level.Elevation - elevation) < 0.001)
                {
                    return level;
                }
            }

            // 如果没有找到,创建新标高
            using (Transaction trans = new Transaction(doc, "Create Level"))
            {
                trans.Start();

                Level newLevel = Level.Create(doc, elevation);
                newLevel.Name = levelName;

                trans.Commit();
                return newLevel;
            }
        }
    }

    // 楼梯创建失败处理器
    public class StairsFailurePreprocessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
            foreach (FailureMessageAccessor fma in failureMessages)
            {
                // 接受所有警告
                if (fma.GetSeverity() == FailureSeverity.Warning)
                {
                    failuresAccessor.DeleteWarning(fma);
                }
                else // 对于错误,尝试修复或取消
                {
                    return FailureProcessingResult.ProceedWithRollBack;
                }
            }
            return FailureProcessingResult.Continue;
        }
    }
}

 

 

posted on 2025-10-31 21:24  sswsswssw1996  阅读(0)  评论(0)    收藏  举报

导航