Get coordinate from block by C.#

Get coordinate from block by C.#

anhtrung
Advocate Advocate
5,367 Views
10 Replies
Message 1 of 11

Get coordinate from block by C.#

anhtrung
Advocate
Advocate

Hi everybody,

 

I have a grid into block and want to get coordinate from this grid, but i want to select Block and then read grid into Block, and then define location on the model, or anyway other, can everybody see image and file .DWG below. 

I'm using by C.#

2019-08-10_9-03-40.png

 

 

 

Accepted solutions (1)
5,368 Views
10 Replies
Replies (10)
Message 2 of 11

_gile
Consultant
Consultant

Hi,

 

You should provide more details on how yo want to get these coordintes and show what you have tried so far.

Anyway, you always can transform coordinates from the block defnition (BlockTableRecord) into block reference coordinates using the transformation matrix returned by BlockReference.BlockTransform property.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 11

anhtrung
Advocate
Advocate

it's that mean i have a block, and i want get all coordinates into this block, you can open attached file.

 

0 Likes
Message 4 of 11

_gile
Consultant
Consultant

You should be able to get inspired by this little sample.

 

using System.Collections.Generic;
using System.Linq;

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;

namespace GetCoordinatesFromBlockSample
{
    public class Commands
    {
        [CommandMethod("GETCOORDINATESFROMBLOCK")]
        public static void GetCoordinatesFromBlock()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var options = new PromptEntityOptions("\nSelect block reference: ");        
            options.SetRejectMessage("\nSelected object is not a block reference.");
            options.AddAllowedClass(typeof(BlockReference), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                // get the selected block reference
                var blockReference = result.ObjectId.GetObject<BlockReference>();

                // get the block definition
                var blockDefinition = blockReference.BlockTableRecord.GetObject<BlockTableRecord>();

                // collect the polyline vertices in the block definition and transform them as the block reference
                var points =
                    blockDefinition                                             // from the block definition
                    .GetObjects<Polyline>()                                     // get app polylines
                    .SelectMany(pl => pl.GetVertices())                         // collect the polylines vertices
                    .Distinct()                                                 // remove duplicated points
                    .Select(p => p.TransformBy(blockReference.BlockTransform))  // transform each point as the block reference
                    .OrderByDescending(p => p.Y)                                // order points by Y descending
                    .ThenBy(p => p.X);                                          // then by X

                // print the points coordinates on the command mine and add a red circle on each one
                var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                foreach (var pt in points)
                {
                    ed.WriteMessage($"\n{pt:0.00}");
                    var circle = new Circle() { Center = pt, Radius = 2.0, ColorIndex = 1 };
                    space.AppendEntity(circle);
                    tr.AddNewlyCreatedDBObject(circle, true);
                }

                tr.Commit();
            }
        }
    }

    static class ExtensionMethods
    {
        // opens the ObjecId in the specified mode
        public static T GetObject<T>(this ObjectId id, OpenMode mode = OpenMode.ForRead) where T : DBObject =>
            (T)id.GetObject(mode);

        // gets all the the objects of type T in the BlockTable record
        public static IEnumerable<T> GetObjects<T>(this BlockTableRecord btr, OpenMode mode = OpenMode.ForRead) where T : Entity
        {
            var rxClass = RXObject.GetClass(typeof(T));
            foreach (ObjectId id in btr)
            {
                if (id.ObjectClass.IsDerivedFrom(rxClass))
                    yield return id.GetObject<T>(mode);
            }
        }

        // gets the polyline vertices
        public static IEnumerable<Point3d> GetVertices(this Polyline pline)
        {
            for (int i = 0; i < pline.NumberOfVertices; i++)
            {
                yield return pline.GetPoint3dAt(i);
            }
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 11

anhtrung
Advocate
Advocate

@_gile 

Thanks for your sharing code, but they have a error when i copy into my visual, i don't know why it's that. You can see attached image below.

2019-08-28_10-53-05.png

Help me please.

 

 

0 Likes
Message 6 of 11

_gile
Consultant
Consultant

Using the lambda operator (=>) for single statement returned value came with C#6 (visual Studio 2015).

For prior C# versions,  just use the standard return keyword and braces.

Replace:

        // opens the ObjecId in the specified mode
        public static T GetObject<T>(this ObjectId id, OpenMode mode = OpenMode.ForRead) where T : DBObject =>
            (T)id.GetObject(mode); 

with:

        // opens the ObjecId in the specified mode
        public static T GetObject<T>(this ObjectId id, OpenMode mode = OpenMode.ForRead) where T : DBObject
            { return (T)id.GetObject(mode); }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 11

anhtrung
Advocate
Advocate

it's still error you can see attached image below.

2019-08-28_13-38-24.png

 

0 Likes
Message 8 of 11

anhtrung
Advocate
Advocate

@_gile 

Thanks for your support, but i see a lot of problem when i copy it into my code. can you send help me your file ?

thanks so much.2019-08-28_14-09-22.png

 

0 Likes
Message 9 of 11

_gile
Consultant
Consultant
Accepted solution

Try this way, without any extension method.

        // gets the polyline vertices
        public static IEnumerable<Point3d> GetVertices(Polyline pline)
        {
            for (int i = 0; i < pline.NumberOfVertices; i++)
            {
                yield return pline.GetPoint3dAt(i);
            }
        }

        [CommandMethod("GETCOORDINATESFROMBLOCK")]
        public static void GetCoordinatesFromBlock()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var options = new PromptEntityOptions("\nSelect block reference: ");
            options.SetRejectMessage("\nSelected object is not a block reference.");
            options.AddAllowedClass(typeof(BlockReference), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                // get the selected block reference
                var blockReference = (BlockReference)tr.GetObject(result.ObjectId, OpenMode.ForRead);

                // get the block definition
                var blockDefinition = (BlockTableRecord)tr.GetObject(blockReference.BlockTableRecord, OpenMode.ForRead);

                // collect the polyline vertices in the block definition and transform them as the block reference
                var points =
                    blockDefinition                                             // from the block definition
                    .Cast<ObjectId>()                                           // get all polylines
                    .Where(id => id.ObjectClass.DxfName == "LWPOLYLINE")
                    .Select(id => (Polyline)tr.GetObject(id, OpenMode.ForRead))
                    .SelectMany(pl => GetVertices(pl))                          // collect the polylines vertices
                    .Distinct()                                                 // remove duplicated points
                    .Select(p => p.TransformBy(blockReference.BlockTransform))  // transform each point as the block reference
                    .OrderByDescending(p => p.Y)                                // order points by Y descending
                    .ThenBy(p => p.X);                                          // then by X

                // print the points coordinates on the command line and add a red circle on each one
                var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                foreach (var pt in points)
                {
                    ed.WriteMessage($"\n{pt:0.00}");
                    var circle = new Circle() { Center = pt, Radius = 1.0, ColorIndex = 1 };
                    space.AppendEntity(circle);
                    tr.AddNewlyCreatedDBObject(circle, true);
                }

                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 11

anhtrung
Advocate
Advocate

it's great with me. i can use it now.

Thanks for your the enthusiastic support

 

0 Likes
Message 11 of 11

Anonymous
Not applicable

Thank you very much! I did not immediately come across your post and spent a lot of time) I do not use AutoCAD as my main activity. I was trying to pull the text out of the blocks and drag them into model space so that I could just select all the text in the same programmatic way. When cloning to a layer from a block, I got some kind of offsets. What I just did not do to compensate for the difference) It turned out that everything had already been done and it was necessary to transform the position. But it came to the implementation of Graham scan to correctly sort the points ... and everything turned out to be in vain)

0 Likes