.NET

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

Bounding Boxes around Blocks.

392 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: 993
Registered: ‎04-27-2009
Message 2 of 3 (340 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 (321 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
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.