.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to count entities on a layer within a block reference?

8 REPLIES 8
Reply
Message 1 of 9
edweberg
2228 Views, 8 Replies

How to count entities on a layer within a block reference?

Greetings.  I need some code suggestions:

 

I have a piece of code which I've been using and I've been asked to ammend its functionality.  I can't share the code in full for IP reasons, but I'll describe where I'm at.

 

My code looks at each block reference and performs a function based on what it finds in a set of attributes, then goes on to the next block reference.

So, I have Block Reference open for read, and this is where I need to do the following:

 

Within the block reference that is currently open for read I need to count how many entities (specifically line segments) are on a specific layer.  "How many line segments are on layer "Layer1".  "  That's what I need to find. 

 

Once I get that number I can incorporate it into the rest of the application and I know how to do that.  I just don't know how to count the number of lines in the current block reference on Layer1.

 

Thanks so much for any help you brilliant folks can send my way.

 

Erik

 

8 REPLIES 8
Message 2 of 9
dgorsman
in reply to: edweberg

You can start by backing up a little: block references don't have lines, circles, or any other graphic entities except for attribute references.  That's why its called a block REFERENCE - it refers back to the block definition.  Doesn't matter if there is 1 or 100, the contents are still the same as defined in the block definition.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


Message 3 of 9
SENL1362
in reply to: dgorsman

Except that you can use the Standard Selection methodes to select from Block:: (Modelspace|Paperspace) but (unfortunately) not from Block_X

Message 4 of 9
SENL1362
in reply to: SENL1362

Something like this might help to get you started

...

BlockReference blkRef = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
int nrOfEnts = 0;

foreach (ObjectId blkEntId in blk)
{
Entity blkEnt = (Entity)tr.GetObject(blkEntId, OpenMode.ForRead);
string myEntSearchVars=string.Format("{0},{1}",blkEnt.GetRXClass().DxfName,blkEnt.Layer);

if (Regex.IsMatch(myEntSearchVars, ".*LINE,the-layer-name$", RegexOptions.IgnoreCase))
nrOfEnts++;
}

..

 

 

Message 5 of 9
SENL1362
in reply to: SENL1362

If you are familiar with Dynamic/LINQ style of programming, then this is even shorter:

dynamic blk= blkRef.BlockTableRecord
var entsOnLayerX = ((IEnumerable<dynamic>)blk).Where(ent => Regex.IsMatch(ent.Layer,"the-layer-name",RegexOptions.IgnoreCase);

Message 6 of 9
fieldguy
in reply to: edweberg

You could / should check for block references within block references (nested).  There are recursion examples on this forum.

Message 7 of 9
cdinten
in reply to: edweberg

i think what you would like to do is counting lines inside a block,not a block reference.you can recurse each block, and use selection filter,Editor.SelectAll(SelectionFilter),then get the PromptSelectionResult.Count
Message 8 of 9
edweberg
in reply to: edweberg

I've worked with all of the comments here over the last few days, and I appreciate all of the help you are offering.  I wasn't able to convert the C# code to VB.NET, but I did try to glean some bits I recognized.  What I understand is that I need to open the block definition itself (not the block reference) to get at the information about line segments nested within the block.  I have opened the Block Table for read and for the block that is being iterated, opened the Block Table Record, trying to get at the entities within the block definition.  Not working.  I'm sure it is some convoluted misunderstanding on my part of the relationship between Block Reference, Block Table, Block Table Record, Block Definition and Entities.  Can someone please straighten me out in a way that clarifies what seems to me to be a very serpentine set of relationships.  I apologize up front for not already being an expert at this; in our department I'm actually the one who knows most about it.  Sad, right?  Anyway...

 

I've chopped out the bit of the program which is the crux of what I'm trying to do.  The formatting didn't copy over from Visual Studio into this form.  So items are not tabbed over the way the are in the real code.  Sorry...

 

Where it's getting hung up is "For Each myEntity As Entity In myBTR"

It says "Value of ...ObjectID cannot be converted to ...Entity

So, how do I get at entities within a block definition to assess what layer they are on?  The Block Table Record is the block definition, isn't it? 

 

Any help is greatly appreciated.  Thank you all so much.

 

'See if the block contains an Entity Code attribute

'See if the block contains an BayZone attribute; this includes nearest column zone (grid zone)

Dim EntityCode AsInteger= 0

Dim BAYZ AsInteger= 0

Dim myCount AsInteger

 

ForEach myAttRef As AttRef In GetAttributes(BRefID)

 

If myAttRef.attTag.ToString = "ENTITY_CODE" Then

EntityCode = 1

 

'In the block definition for this block, see how many lines are on layer "A-EQPM-FDPL"

'Open Block Table for Read; Done above...

'Open Block Table Record for Read

Dim acObjID As ObjectId

Dim myBTR As BlockTableRecord = myTrans.GetObject(acObjID, OpenMode.ForRead)

 

'Count how many line segments are on Layer "A-EQPM-FDPL"

'Look at each entity in the block definition and assess whether it is on the target layer

'No nested blocks; just look in top level block definition

 

myCount = 0

ForEach myEntity As Entity In myBTR

 

If myEntity.Layer.Contains("A-EQPM-FDPL") Then

myCount = myCount + 1

EndIf

Next

ElseIf myAttRef.attTag.ToString = "BAY_ZONE"Then

BAYZ = 1

EndIf

Next

Message 9 of 9
Gary_J_Orr
in reply to: edweberg

you're getting close... just need to realize that what you are returning are entity ID's, so you need to get that object, then do your test (the only point that you missed on attempting to convert from the C# example that was posted earlier):

 

ForEach myEntityID As ObjectID In myBTR

 Dim myEntity As Entity = myTrans.GetObject(myEntityID, OpenMode.ForRead)

If myEntity.Layer.Contains("A-EQPM-FDPL") Then

myCount = myCount + 1

...

 

this is off the top of my head so... but it should point you in the right direction.

G

 

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost