revit 2020 二次開發——在樓板上挖圓形洞(Create circle openning in floor)

一、思路

1)先創建圓形樓板(source floor),獲取樓板的輪廓,根據輪廓在目標樓板上開洞。
2)刪掉圓形樓板。

注意:創建目標樓板 和 在目標樓板上開圓形洞,儘量不要在一個事務中

二、圖示

在這裏插入圖片描述

三、代碼

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try {
                UIDocument uiDoc = commandData.Application.ActiveUIDocument;
                Document doc = uiDoc.Document;
                Selection sel = uiDoc.Selection;
                Autodesk.Revit.Creation.Application acreation = commandData.Application.Application.Create;
                Autodesk.Revit.Creation.Document dcreation = doc.Create;

                double l = 5;
                double w = 10;

                double x0 = 0;
                double y0 = 0;
                double z0 = 1;

                XYZ p_s0 = new XYZ(x0, y0, z0);
                XYZ p_s1 = new XYZ(x0, y0 + w, z0);
                XYZ p_s2 = new XYZ(x0 + l, y0 + w, z0);
                XYZ p_s3 = new XYZ(x0 + l, y0, z0);

                Line l_s0 = Line.CreateBound(p_s0, p_s1);
                Line l_s1 = Line.CreateBound(p_s1, p_s2);
                Line l_s2 = Line.CreateBound(p_s2, p_s3);
                Line l_s3 = Line.CreateBound(p_s3, p_s0);

                CurveArray fProfile = new CurveArray();
                fProfile.Append(l_s0);
                fProfile.Append(l_s1);
                fProfile.Append(l_s2);
                fProfile.Append(l_s3);

                //1)創建目標樓板
                Floor targetfloor = CreateTargetFloor(doc, fProfile);

                Transaction ts = new Transaction(doc, "createopenning");
                ts.Start();
                //2)創建圓形樓板
                XYZ center = new XYZ(2.5, 5, z0);
                Floor ciclefloor = CreateCircleFloor(doc, z0, center);

                //3)獲取圓形樓板輪廓,並開洞
                CreateOpening(doc, ciclefloor, targetfloor);
                ts.Commit();

                return Result.Succeeded;
            } catch (Exception ex) {
                var r = 0;
                return Result.Succeeded;

            }

        }
       
        private Floor CreateTargetFloor(Document doc, CurveArray fProfile)
        {
            Transaction ts = new Transaction(doc, "createfloor");
            ts.Start();

            var floor = doc.Create.NewFloor(fProfile, true);
            ts.Commit();
            return floor;
        }

        private Floor CreateCircleFloor(Document doc,double z,XYZ center)
        {
           

            double radius = 2;
            Arc arc1 = Arc.Create(Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0)), radius, 0, Math.PI);
            Arc arc2 = Arc.Create(Plane.CreateByNormalAndOrigin(new XYZ(0, 0, 1), new XYZ(0, 0, 0)), radius, Math.PI, Math.PI * 2);
            CurveArray profile = new CurveArray();
            profile.Append(arc1);
            profile.Append(arc2);
            var floor = doc.Create.NewFloor(profile, false);
            //創建的圓弧位於原點,需要移動到開洞中心
            ElementTransformUtils.MoveElement(doc, floor.Id, center);
            
            return floor;
        }

        private void CreateOpening(Document doc, Floor sourceFloor, Floor destFloor)
        {
           
            var floorGeometryElement = sourceFloor.get_Geometry(new Options());
            foreach (var geometryObject in floorGeometryElement) {
                var floorSolid = geometryObject as Solid;
                if (floorSolid == null)
                    continue;

                var topFace = GetTopFace(floorSolid);
                if (topFace == null)
                    throw new NotSupportedException(
                      "Floor does not have top face");
                if (topFace.EdgeLoops.IsEmpty)
                    throw new NotSupportedException(
                      "Floor top face does not have edges");

				//圓形樓板的外輪廓
                EdgeArray ea = topFace.EdgeLoops.get_Item(0);
                CurveArray openingCurveArray = new CurveArray();

                foreach (Edge edge in ea) {
                    var edgeCurve = edge.AsCurve();
                    openingCurveArray.Append(edgeCurve);
                }
                var opening = sourceFloor.Document.Create.NewOpening(destFloor, openingCurveArray, true);
                destFloor.Document.Delete(sourceFloor.Id);
            }
         
        }
        const double _eps = 1.0e-9;
        private static PlanarFace GetTopFace(Solid solid)
        {
            PlanarFace topFace = null;
            FaceArray faces = solid.Faces;
            foreach (Face f in faces) {
                PlanarFace pf = f as PlanarFace;
                if (null != pf && (Math.Abs(pf.FaceNormal.X - 0) < _eps && Math.Abs(pf.FaceNormal.Y - 0) < _eps)) {
                    if ((null == topFace)|| (topFace.Origin.Z < pf.Origin.Z)) {
                        topFace = pf;
                    }
                }
            }
            return topFace;
        }

四、參考文獻

Create a Floor with an Opening or Complex Boundary

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章