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