Find position of a nested block from a BlockReference

Find position of a nested block from a BlockReference

Anonymous
Not applicable
1,949 Views
2 Replies
Message 1 of 3

Find position of a nested block from a BlockReference

Anonymous
Not applicable

Hi, I've been struggling to do this for a few days now, im hoping someone can shed some light.

 

Here's what i'm trying to accomplish:

 

Using C# .NET, I have two blocks that I want to insert chained next to each other. A specific point on end of the first one touches a point on the start of the second one. The blocks happen to be dynamic blocks. 

 

Here's how i'm trying to do it:

 

I have put a nested block (circle) in the first block that I have named "PINK_DOT". You can see the circle in the screenshot below. I think I can insert the first block, then get the modelspace position of the nested (PINK_DOT) block from the BlockReference. I can then use the modelspace position of the  PINK_DOT block as the insertion point for my second block.

 

My procedure is as follows:

 

1) I insert the first block using it's BlockName, and then set the blocks visibility state, to the one i want. This gives me the BlockReference for the insertion.

2) I would like to find the position of the PINK_DOT block that I have nested in the BlockReference that was just inserted.

3) I will then use that position as the insertion point for the second block.

 

Here is the code im using to get the Point3d of the block named "PINK_DOT". The first block has already been inserted into modelspace. I start by getting the BlockReference from the first block from the ObjectId

        var blockReference =  m_trans.GetObject(objectId, mode, false, true) as BlockReference;
if (blockReference.Visible == true) { BlockTableRecord blockTableRecord = m_trans.GetObject(blockReference.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord; foreach (ObjectId oid in blockTableRecord) { DBObject brDbo = m_trans.GetObject(oid, OpenMode.ForRead, false, true); if (brDbo is BlockReference && ((Autodesk.AutoCAD.DatabaseServices.BlockReference)brDbo).Visible == true) { BlockReference possibleInsertionPoint = (BlockReference)brDbo; if (possibleInsertionPoint.Name == "PINK_DOT") { return possibleInsertionPoint.Position; } } } }

Problems:

 

1. The above code ends up returning {0,0,0} for the modelspace position which isn't correct.

 

2. I want to insert the first block multiple times and be able to get the modelspaceposition of it's PINK_DOT for each of them. Im concerned about being able to keep track of which BlockReference, I'm grabbing the PINK_DOT for. I could do this easily if I could get the Point3d for the PINK_DOT given a BlockReference. 

 

Summary:

 

In Computer Science terminology im trying to write an implementation for this method (where the Objectid is a reference to a DynamicBlock that has been inserted):

 

Point3d GetPositionOfNestedBlock(ObjectId objectId, string nestedBlockName)
{
//Please help implement me :)
}

 

0 Likes
1,950 Views
2 Replies
Replies (2)
Message 2 of 3

SRSDS
Advisor
Advisor

I'm no expert but can you give this a try.

return possibleInsertionPoint.TransformBy(brDbo.BlockTransform);

Blocks have their own coordinate system. 0,0 is possibly where the Pink_Dot is placed inside your block.

myPoint.TransformBy(br.BlockTransform.Inverse) converts a point in ModelSpace to the block coordinate system.

 

Again, I'm no expert but maybe this gives you some ideas and keywords use for a search.

0 Likes
Message 3 of 3

_gile
Consultant
Consultant

Hi,

 

Here's an  example which returns a boolean and uses an out parameter because Point3d is a value type and the position may not be found.

 

        bool TryGetPositionOfNestedBlock(ObjectId objectId, string nestedBlockName, out Point3d position)
        {
            var brClass = RXObject.GetClass(typeof(BlockReference));
            if (!objectId.IsNull && objectId.ObjectClass == brClass)
            {
                using (var tr = objectId.Database.TransactionManager.StartOpenCloseTransaction())
                {
                    var br = (BlockReference)tr.GetObject(objectId, OpenMode.ForRead);
                    var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
                    foreach (ObjectId id in btr)
                    {
                        if (id.ObjectClass == brClass)
                        {
                            var nestedBr = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                            if (nestedBr.Name == nestedBlockName)
                            {
                                position = nestedBr.Position.TransformBy(br.BlockTransform);
                                return true;
                            }
                        }
                    }
                    tr.Commit();
                }
            }
            position = Point3d.Origin;
            return false;
        }

using

Point3d position;
if (TryGetPositionOfNestedBlock(brId, "PINK_DOT", out position)
{
// do your stuff using position
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes