Revit 2020 secondary development-Create circle openning in floor

1. Ideas

1) First create a circular floor (source floor), obtain the contour of the floor, and make a hole in the target floor according to the contour.
2) Delete the circular floor slab.

Note: Create a target floor and open a circular hole on the target floor. Try not to do it in one transaction

Second, the icon

Insert picture description here

Three, the code

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

Four, references

Create a Floor with an Opening or Complex Boundary

Guess you like

Origin blog.csdn.net/hhhhhhenrik/article/details/105538329