Ejemplo n.º 1
0
        /// <summary>
        /// Return a rotated bounding box around
        /// the origin in the XY plane.
        /// We cannot just rotate the min and max points,
        /// because the rotated max point may easily end
        /// up being 'smaller' in some coordinate than the
        /// min. To work around that, we extract all four
        /// bounding box corners, rotate each of them and
        /// determine new min and max values from those.
        /// </summary>
        private static BoundingBoxXYZ RotateBoundingBox(
            BoundingBoxXYZ b,
            Transform t)
        {
            double height = b.Max.Z - b.Min.Z;

            // Four corners: lower left, lower right,
            // upper right, upper left:

            XYZ[] corners = Util.GetBottomCorners(b);

            XyzComparable[] cornersTransformed
                = corners.Select <XYZ, XyzComparable>(
                      p => new XyzComparable(t.OfPoint(p)))
                  .ToArray();

            b.Min  = cornersTransformed.Min();
            b.Max  = cornersTransformed.Max();
            b.Max += height * XYZ.BasisZ;

            return(b);
        }
        /// <summary>
        /// 获取当前模型指定视图内的所有最外层的墙体
        /// Get all the outermost walls in the
        /// specified view of the current model
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="view">视图,默认是当前激活的视图
        /// View, default is currently active view</param>
        public static List <ElementId> GetOutermostWalls(
            Document doc,
            View view = null)
        {
            double offset = Util.MmToFoot(1000);

            if (view == null)
            {
                view = doc.ActiveView;
            }

            #region Obsolete code using wall location line instad of bounding box
            //获取顶点 最小x,最大y ; 最大x,最小y

#if BEFORE_USING_BOUNDING_BOX
            List <Wall> wallList = new FilteredElementCollector(doc)
                                   .OfClass(typeof(Wall))
                                   .Cast <Wall>()
                                   .ToList();

            double maxX = -1D;
            double minX = -1D;
            double maxY = -1D;
            double minY = -1D;

            wallList.ForEach((wall) =>
            {
                Curve curve = (wall.Location as LocationCurve).Curve;
                XYZ xyz1    = curve.GetEndPoint(0);
                XYZ xyz2    = curve.GetEndPoint(1);

                double _minX = Math.Min(xyz1.X, xyz2.X);
                double _maxX = Math.Max(xyz1.X, xyz2.X);
                double _minY = Math.Min(xyz1.Y, xyz2.Y);
                double _maxY = Math.Max(xyz1.Y, xyz2.Y);

                if (curve.IsCyclic)
                {
                    Arc arc        = curve as Arc;
                    double _radius = arc.Radius;
                    //粗略对x和y 加/减
                    _maxX += _radius;
                    _minX -= _radius;
                    _maxY += _radius;
                    _minY += _radius;
                }

                if (minX == -1)
                {
                    minX = _minX;
                }
                if (maxX == -1)
                {
                    maxX = _maxX;
                }
                if (maxY == -1)
                {
                    maxY = _maxY;
                }
                if (minY == -1)
                {
                    minY = _minY;
                }

                if (_minX < minX)
                {
                    minX = _minX;
                }
                if (_maxX > maxX)
                {
                    maxX = _maxX;
                }
                if (_maxY > maxY)
                {
                    maxY = _maxY;
                }
                if (_minY < minY)
                {
                    minY = _minY;
                }
            });
            double     minX   = bb.Min.X - offset;
            double     maxX   = bb.Max.X + offset;
            double     minY   = bb.Min.Y - offset;
            double     maxY   = bb.Max.Y + offset;
            CurveArray curves = new CurveArray();
            Line       line1  = Line.CreateBound(new XYZ(minX, maxY, 0), new XYZ(maxX, maxY, 0));
            Line       line2  = Line.CreateBound(new XYZ(maxX, maxY, 0), new XYZ(maxX, minY, 0));
            Line       line3  = Line.CreateBound(new XYZ(maxX, minY, 0), new XYZ(minX, minY, 0));
            Line       line4  = Line.CreateBound(new XYZ(minX, minY, 0), new XYZ(minX, maxY, 0));
            curves.Append(line1);
            curves.Append(line2);
            curves.Append(line3);
            curves.Append(line4);
#endif // BEFORE_USING_BOUNDING_BOX
            #endregion // Obsolete code using wall location line instad of bounding box

            BoundingBoxXYZ bb = GetBoundingBoxAroundAllWalls(
                doc, view);

            XYZ voffset = offset * (XYZ.BasisX + XYZ.BasisY);
            bb.Min -= voffset;
            bb.Max += voffset;

            XYZ[] bottom_corners = Util.GetBottomCorners(
                bb, 0);

            CurveArray curves = new CurveArray();
            for (int i = 0; i < 4; ++i)
            {
                int j = i < 3 ? i + 1 : 0;
                curves.Append(Line.CreateBound(
                                  bottom_corners[i], bottom_corners[j]));
            }

            using (TransactionGroup group
                       = new TransactionGroup(doc))
            {
                Room newRoom = null;

                group.Start("Find Outermost Walls");

                using (Transaction transaction
                           = new Transaction(doc))
                {
                    transaction.Start(
                        "Create New Room Boundary Lines");

                    SketchPlane sketchPlane = SketchPlane.Create(
                        doc, view.GenLevel.Id);

                    ModelCurveArray modelCaRoomBoundaryLines
                        = doc.Create.NewRoomBoundaryLines(
                              sketchPlane, curves, view);

                    // 创建房间的坐标点 -- Create room coordinates

                    double d     = Util.MmToFoot(600);
                    UV     point = new UV(bb.Min.X + d, bb.Min.Y + d);

                    // 根据选中点,创建房间 当前视图的楼层 doc.ActiveView.GenLevel
                    // Create room at selected point on the current view level

                    newRoom = doc.Create.NewRoom(view.GenLevel, point);

                    if (newRoom == null)
                    {
                        string msg = "创建房间失败。";
                        TaskDialog.Show("xx", msg);
                        transaction.RollBack();
                        return(null);
                    }

                    RoomTag tag = doc.Create.NewRoomTag(
                        new LinkElementId(newRoom.Id),
                        point, view.Id);

                    transaction.Commit();
                }

                //获取房间的墙体 -- Get the room walls

                List <ElementId> ids
                    = RetrieveWallsGeneratingRoomBoundaries(
                          doc, newRoom);

                group.RollBack(); // 撤销

                return(ids);
            }
        }
Ejemplo n.º 3
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            Element e = Util.SelectSingleElement(
                uidoc, "an element");

            if (null == e)
            {
                message = "No element selected";
                return(Result.Failed);
            }

            // Trying to call this property returns the
            // compile time error: Property, indexer, or
            // event 'BoundingBox' is not supported by
            // the language; try directly calling
            // accessor method 'get_BoundingBox( View )'

            //BoundingBoxXYZ b = e.BoundingBox[null];

            View v = null;

            BoundingBoxXYZ b = e.get_BoundingBox(v);

            if (null == b)
            {
                v = commandData.View;
                b = e.get_BoundingBox(v);
            }

            if (null == b)
            {
                Util.InfoMsg(
                    Util.ElementDescription(e)
                    + " has no bounding box.");
            }
            else
            {
                using (Transaction tx = new Transaction(doc))
                {
                    tx.Start("Draw Model Line Bounding Box Outline");

                    Debug.Assert(b.Transform.IsIdentity,
                                 "expected identity bounding box transform");

                    string in_view = (null == v)
            ? "model space"
            : "view " + v.Name;

                    Util.InfoMsg(string.Format(
                                     "Element bounding box of {0} in "
                                     + "{1} extends from {2} to {3}.",
                                     Util.ElementDescription(e),
                                     in_view,
                                     Util.PointString(b.Min),
                                     Util.PointString(b.Max)));

                    Creator creator = new Creator(doc);

                    creator.DrawPolygon(new List <XYZ>(
                                            Util.GetBottomCorners(b)));

                    Transform rotation = Transform.CreateRotation(
                        XYZ.BasisZ, 60 * Math.PI / 180.0);

                    b = RotateBoundingBox(b, rotation);

                    Util.InfoMsg(string.Format(
                                     "Bounding box rotated by 60 degrees "
                                     + "extends from {0} to {1}.",
                                     Util.PointString(b.Min),
                                     Util.PointString(b.Max)));

                    creator.DrawPolygon(new List <XYZ>(
                                            Util.GetBottomCorners(b)));

                    tx.Commit();
                }
            }
            return(Result.Succeeded);
        }