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

猜你喜欢

转载自blog.csdn.net/hhhhhhenrik/article/details/105538329