In AutoCAD, the bounding box of an entity is a minimal orthogonal rectangle that enclose the entity. With .NET API, one can get the bounding box of an entity with Entity.GeometricExtents property, which is an Extents3d structure. With COM API, one can call AcadEntity.GetBoundingBox(minPoint, maxPoint) to obtain the bounding box's minimum point (lower-left corner) and maximum point (the upper-right corner).
There was an interesting question asked recently in the AutoCAD VBA discussion forum. The OP wanted to get the bounding box of an entity as it appears in an UCS. Obviously, depending on the transformation of an UCS from WCS (World Coordinate System), the appeared bounding box in current UCS would be different from the Bounding Box calculated with .NET API/COM API, as shown in the pictures below.
The bounding box of an Hatch entity obtained through API (Entity.GeometricExtents, or AcadEntity.GetBoundingBox()), is shown in red:
using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using CadApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(UcsToWcsTest.MyCommands))] namespace UcsToWcsTest { public class MyCommands { [CommandMethod("GetUcsBox")] public static void RunCommand() { var dwg = CadApp.DocumentManager.MdiActiveDocument; var ed = dwg.Editor; var entId = SelectEntity(ed); if (entId.IsNull) { ed.WriteMessage("\n*Cancel*"); return; } GetUcsBoundingBox(entId, ed); } private static ObjectId SelectEntity(Editor ed) { var res = ed.GetEntity("\nSelect an entity:"); if (res.Status == PromptStatus.OK) return res.ObjectId; else return ObjectId.Null; } private static void GetUcsBoundingBox(ObjectId entId, Editor ed) { var db = entId.Database; Extents3d bound; using (var tran = db.TransactionManager.StartTransaction()) { var space = (BlockTableRecord)tran.GetObject( db.CurrentSpaceId, OpenMode.ForWrite); var ent = (Entity)tran.GetObject(entId, OpenMode.ForRead); using (var entCopy = ent.Clone() as Entity) { entCopy.TransformBy(ed.CurrentUserCoordinateSystem.Inverse()); bound = entCopy.GeometricExtents; } tran.Commit(); } var pt = bound.MinPoint; ed.WriteMessage($"\nFirst corner: {PointToString(pt)}"); pt = new Point3d(bound.MinPoint.X,bound.MaxPoint.Y, bound.MinPoint.Z); ed.WriteMessage($"\nSecond corner: {PointToString(pt)}"); pt = bound.MaxPoint; ed.WriteMessage($"\nThird corner: {PointToString(pt)}"); pt = new Point3d(bound.MaxPoint.X, bound.MinPoint.Y, bound.MinPoint.Z); ed.WriteMessage($"\nFourth corner: {PointToString(pt)}"); } private static string PointToString(Point3d pt) { var x = Converter.DistanceToString(pt.X); var y= Converter.DistanceToString(pt.Y); return $"({x}, {y})"; } } }
Noted that I used a copy of the entity for the calculation, so that the real entity is not changed/transformed. Otherwise it would need to be transformed back.
See the video click below for the effect of the code execution.
Since the aforementioned question was asked in AutoCAD VBA forum, then, how can we find out the appeared bounding box in UCS with VBA code? Well, unlike AutoCAD .NET API's support to solve this problem, it is a bit complicated with VBA/AutoCAD COM API, or at least, not straightforward. Because I have posted the VBA code in the VBA discussion forum, go to here to take a look, if interested in:
https://forums.autodesk.com/t5/vba/lisp-code-to-vba-code-conversion/td-p/11561281
No comments:
Post a Comment