Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

how to select certain objects in a block reference in model space using c#

Anonymous

how to select certain objects in a block reference in model space using c#

Anonymous
Not applicable

 I am working on a project that a user should select the border lines of the block reference. However, when I hover my mouse onto the block reference, the whole block is selected.  I just want to select a line of the block reference?

 

PromptEntityOptions options = new PromptEntityOptions(message);
 options.SetRejectMessage("\n selected target is not supported");
 options.AddAllowedClass(typeof(Line), true);
PromptEntityResult result = ed.GetEntity(options);

 

 I do not want to explode the block reference and recombine them.

0 Likes
Reply
Accepted solutions (2)
3,984 Views
11 Replies
Replies (11)

_gile
Mentor
Mentor
Accepted solution

Hi,

 

You could use the Editor.GetNestedEntity() method to get the line.

The objectId is the one the line within the block definition.

 

            using (var tr = db.TransactionManager.StartTransaction())
            {
                PromptNestedEntityResult result;
                while (true)
                {
                    result = ed.GetNestedEntity("\nSelect a line within a block reference: ");

                    // user cancelled
                    if (result.Status != PromptStatus.OK)
                    {
                        return;
                    }

                    // check if the selected object is a line
                    if (result.ObjectId.ObjectClass.DxfName == "LINE")
                    {
                        // check if the line is nested
                        if (result.GetContainers().Length == 0)
                        {
                            ed.WriteMessage("\nThe selected line is not nested in a block reference.");
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        ed.WriteMessage("\nThe selected entity is not a line.");
                    }
                }

                // open the line of the block defintion 
                var line = (Line)tr.GetObject(result.ObjectId, OpenMode.ForRead);

                // compute the transformation matrix from the containers
                var xform = result.GetContainers()
                    .Select(id => (BlockReference)tr.GetObject(id, OpenMode.ForRead))
                    .Select(br => br.BlockTransform)
                    .Aggregate((m1, m2) => m2 * m1);

                // transform the line start and ensd points
                var startPoint = line.StartPoint.TransformBy(xform);
                var endPoint = line.EndPoint.TransformBy(xform);
                ed.WriteMessage($"\nStart point: {startPoint}\nEnd point: {endPoint}");
                tr.Commit();
            }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

norman.yuan
Mentor
Mentor
Accepted solution

Because BlockReference is a SINGLE entity, your code, which only allows to select a Line, obviously does not work. To programmatically select something inside a block definition that is presented/visible in a BlockReference, you use PromptNestedEntityOptions/Editor.GetNestedEntity()/PromptNestedEntityResult to find out what is selected. However, if you want to provide visual hint on what is selected (such as highlight), it would be up to you to do that, which is not a trivial task. 

 

These 2 articles might be what you want, or at least, helpful:

 

https://drive-cad-with-code.blogspot.com/2019/08/select-multiple-nested-entities-1.html 

https://drive-cad-with-code.blogspot.com/2019/08/selecting-multiple-nested-entities-2-of.html

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes

Anonymous
Not applicable

why should I transform the start point and end point of the line? Is the coodinates of the start point and end point of the line different from the ones in WCS?

0 Likes

_gile
Mentor
Mentor

@Anonymous wrote:

why should I transform the start point and end point of the line? Is the coodinates of the start point and end point of the line different from the ones in WCS?


As I said, PromptNestedResult.ObjectId returns the ObjectId of the line in the block definition (BlockTableRecord), so we have to transform its coordinates with the BlockReference.BlockTransform transformation matrix* to get the WCS coordinates.

 

* more accurately with the combination of all transformations of all containers in case of nested blocks.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

Anonymous
Not applicable

Thanks a lot

0 Likes

Anonymous
Not applicable

I really appreciate your solution since your code works.  But I have one more question, If the entity I want to select is nested in the block reference of another block reference (the block reference depth is two), then your program will prompt that "the entity your selected is not a line". So is there a way to select a line nested in two or more block references?

 

0 Likes

_gile
Mentor
Mentor

@Anonymous wrote:

I really appreciate your solution since your code works.  But I have one more question, If the entity I want to select is nested in the block reference of another block reference (the block reference depth is two), then your program will prompt that "the entity your selected is not a line". So is there a way to select a line nested in two or more block references?

 


Did you try it ?

result.ObjectId should return the ObjectId of the line and result.GetContainers() should return an array of two containers.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

Anonymous
Not applicable

Yes, I have already tried it. When I move the cursor over a line (then I l clicked )nested in a block reference which is nested in another block reference. The editor says "the  entity you selected is not a line"

0 Likes

Anonymous
Not applicable

I am sorry, I just find that What I selected is another entity(wipeout)  which I created to combine with the original block reference. I will move the wipeout under the original blocke reference.

 

Actually I am working on a project in which user can select the edges of a block reference, then the addin can create (by the coordinates of the edges)and combine a wipeout with the block reference to make the block reference move over other entites.

0 Likes

Anonymous
Not applicable

I find that the original block reference is moved to anther place and the wipeout I create is placed on the original place. I think it is the coordinates conversion problem. GetNestedEntity works as you say

0 Likes

Anonymous
Not applicable

I find out why the original block reference is moved to another position:

     line.TransformBy(xform);

 

    line.StartPoint.TransformBy(xform);

    line.EndPoint.TransformBy(xform);

After I replace the code, it works.

 

 A wipeout is created and moved under the orginal block reference (the original block reference overlaps the wipeout and they are in a new block reference).

 

However I run my code again, I use GetNestedEntity to select the edges of the new block reference, the objectId is the wipeout, maybe this time GetNestedEntity can not get the upper line.

 

Thank you for your code. It helps me a lot

0 Likes