欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

revit 2020 二次开发——在楼板上挖圆形洞(Create circle openning in floor)

程序员文章站 2022-07-12 14:57:36
...

一、思路

1)先创建圆形楼板(source floor),获取楼板的轮廓,根据轮廓在目标楼板上开洞。
2)删掉圆形楼板。

注意:创建目标楼板 和 在目标楼板上开圆形洞,尽量不要在一个事务中

二、图示

revit 2020 二次开发——在楼板上挖圆形洞(Create circle openning in floor)

三、代码

        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

相关标签: revit二次开发