.NET

Reply
Valued Contributor
GrzesiekGP
Posts: 67
Registered: ‎02-03-2012
Message 1 of 3 (419 Views)

Bounding Boxes around Blocks.

419 Views, 2 Replies
04-03-2013 10:16 AM

Hey!

 

I have question - we have two lines which are crossing.

Now I want to find bounding box as shown on the picture.

 

Do we have some special methods (in AC) which can help me or I must find bounding points manually?

 

Thanks.

*Expert Elite*
norman.yuan
Posts: 1,064
Registered: ‎04-27-2009
Message 2 of 3 (367 Views)

Re: Bounding Boxes around Blocks.

04-04-2013 08:10 AM in reply to: GrzesiekGP

Since the picture you show is in a twisted angle, we need to clarify it first (that might be why people seem unwilling to reply to this seemd simple question.

 

I assume the entities (line, or block reference...) you as interested in getting their bounding box are drawn normally in World Coordinate. The picture you show is just a twist view. And also, by "Bounding Box" we mean it is an rectangle with X axis as 0 degree and Y axis as 90 degree, which just big enough to cover the said entities.

 

So, it is very simple: each entity has a property GeometricExtents property, which is Extents3d type. Therefore, as long as your code get to the entities in interest, you will know each entitiy's bounding box. if there are multiple entities in interest, you simply aggreagate each entity's bounding box. Following code will draw the bounding box of selected entities:

 

    public class MyCommands
    {
        [CommandMethod("GetBound")]
        public static void RunGetBound()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            ObjectId[] entIds = SelectEntities(ed);
            if (entIds != null)
            {
                DrawBoundBox(dwg, entIds);
            }

            Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
        }

        private static ObjectId[] SelectEntities(Editor ed)
        {
            PromptSelectionOptions opt = new PromptSelectionOptions();
            opt.MessageForAdding = "Select:";
            PromptSelectionResult res = ed.GetSelection(opt);
            if (res.Status == PromptStatus.OK)
            {
                return res.Value.GetObjectIds();
            }
            else
            {
                return null;
            }
        }

        private static void DrawBoundBox(Document dwg, ObjectId[] entIds)
        {
            using (Transaction tran = dwg.TransactionManager.StartTransaction())
            {
                Extents3d ext = GetBoundBox(entIds, tran);
                Polyline poly = DrawPolygon(ext);

                BlockTableRecord space = tran.GetObject(
                    dwg.Database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                space.AppendEntity(poly);
                tran.AddNewlyCreatedDBObject(poly, true);

                tran.Commit();
            }
        }

        private static Extents3d GetBoundBox(ObjectId[] entIds, Transaction tran)
        {
            Extents3d ex = new Extents3d();

            foreach (var id in entIds)
            {
                Entity ent = tran.GetObject(id, OpenMode.ForRead) as Entity;
                ex.AddExtents(ent.GeometricExtents);
            }

            return ex;
        }

        private static Polyline DrawPolygon(Extents3d ext)
        {
            Polyline pl = new Polyline(4);

            pl.AddVertexAt(0, new Point2d(ext.MinPoint.X, ext.MinPoint.Y), 0.0, 0.0, 0.0);
            pl.AddVertexAt(1, new Point2d(ext.MinPoint.X, ext.MaxPoint.Y), 0.0, 0.0, 0.0);
            pl.AddVertexAt(2, new Point2d(ext.MaxPoint.X, ext.MaxPoint.Y), 0.0, 0.0, 0.0);
            pl.AddVertexAt(3, new Point2d(ext.MaxPoint.X, ext.MinPoint.Y), 0.0, 0.0, 0.0);
            pl.Closed = true;
            pl.SetDatabaseDefaults();

            return pl;
        }
    }

 

 

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 3 of 3 (348 Views)

Re: Bounding Boxes around Blocks.

04-05-2013 11:35 AM in reply to: GrzesiekGP

Try this code, quick and dirty though, but it should work,

you can simplify them to your needs

        [CommandMethod("BBO")]
        public void testBlockBound()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            //Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            BlockReference clon = null;

            doc.TransactionManager.EnableGraphicsFlush(true);
            try
            {
                PromptEntityOptions peo = new PromptEntityOptions("\nSelect block: ");

                peo.SetRejectMessage("Only a block instance !");

                peo.AddAllowedClass(typeof(BlockReference), false);

                PromptEntityResult per = ed.GetEntity(peo);

                if (per.Status != PromptStatus.OK) return;

                ObjectId id = per.ObjectId;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);

                    if (ent == null) return;

                    BlockReference bref = ent as BlockReference;

                    if (bref == null) return;

                     clon = bref.Clone() as BlockReference;

                    clon.Rotation = 0;

                    clon.TransformBy(ed.CurrentUserCoordinateSystem);

                    tr.TransactionManager.QueueForGraphicsFlush();

                    Extents3d ext = clon.GeometryExtentsBestFit(ed.CurrentUserCoordinateSystem);

                    ext.TransformBy(ed.CurrentUserCoordinateSystem);

                    Polyline pl = new Polyline(4);

                    Point3d p1 = ext.MinPoint.TransformBy(ed.CurrentUserCoordinateSystem);

                    Point3d p3 = ext.MaxPoint.TransformBy(ed.CurrentUserCoordinateSystem);

                    Point3d p2 = new Point3d(p3.X, p1.Y, p1.Z).TransformBy(ed.CurrentUserCoordinateSystem);

                    Point3d p4 = new Point3d(p1.X, p3.Y, p1.Z).TransformBy(ed.CurrentUserCoordinateSystem);

                    pl.AddVertexAt(0, new Point2d(p1.X, p1.Y), 0.0, 0.0, 0.0);

                    pl.AddVertexAt(1, new Point2d(p2.X, p2.Y), 0.0, 0.0, 0.0);

                    pl.AddVertexAt(2, new Point2d(p3.X, p3.Y), 0.0, 0.0, 0.0);

                    pl.AddVertexAt(3, new Point2d(p4.X, p4.Y), 0.0, 0.0, 0.0);

                    pl.Closed = true;

                    pl.ColorIndex = 121;

                    pl.TransformBy(ed.CurrentUserCoordinateSystem);

                    Matrix3d rot = Matrix3d.Rotation(bref.Rotation, bref.Normal.GetNormal(), bref.Position);

                    pl.TransformBy(rot);

                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                    btr.AppendEntity(pl);

                    tr.AddNewlyCreatedDBObject(pl, true);

                    tr.TransactionManager.QueueForGraphicsFlush();

                    doc.TransactionManager.FlushGraphics();

                    tr.Commit();

                }
            }
            catch (System.Exception e)
            {
                ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                if (!clon.IsDisposed) clon.Dispose();//optional
            }
        }

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.