.NET

.NET

Reply
Active Contributor
thenndral
Posts: 48
Registered: ‎04-01-2013
Message 1 of 5 (168 Views)
Accepted Solution

Open drawing in memory and get Particular layer entity count.

168 Views, 4 Replies
06-24-2014 12:13 AM

Hi,

I'm using AutoCAD2014 with C#.

I got this code snippet from Kean.Thanks Kean.

 

I would like to open drawing from memory and get the particular layer entites count and also entity count list will be calculated for "Model".
I dont know how to convert ed.SelectAll(sf) when open drawing in memory.

 

[CommandMethod("Layer_Entitycount")]
public void Entity_count()
{ 
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
string layerName = "0";
TypedValue[] tvs = new TypedValue[1];
tvs[0] = new TypedValue((int)DxfCode.LayerName, layerName);
SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = ed.SelectAll(sf);
int count = 0;
if (psr.Status == PromptStatus.OK)
count = psr.Value.Count;
if (psr.Status == PromptStatus.OK ||
psr.Status == PromptStatus.Error)
{
ed.WriteMessage("\nTotal Count: " + count);
}
}

 

Could you give me some suggestion/ideas.

 

Thanks in advance,
thenndral

 

Distinguished Contributor
mcicognani
Posts: 125
Registered: ‎12-01-2004
Message 2 of 5 (155 Views)

Re: Open drawing in memory and get Particular layer entity count.

06-24-2014 02:11 AM in reply to: thenndral

You shouls open the ModelSpace table and iterate through each entity, filtering for your layer name.

I'm not sure this is the fastest way, but cannot recall anything better right now...

 

Transaction tr = db.TransactionManager.StartTransaction();
 
try
{
    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
    BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

int n = 0;
foreach (ObjectId o in ms)
{
Entity ee = tr.GetObject(o, OpenMode.ForRead) as Entity;
if (ee == null) continue;

if (ee.Layer == "MyLayer") n++;
}
}
catch (System.Exception ex)
{
    MessageBox.Show("Error: " + ex.Message);
}
finally
{
    tr.Dispose();
}
Active Contributor
thenndral
Posts: 48
Registered: ‎04-01-2013
Message 3 of 5 (104 Views)

Re: Open drawing in memory and get Particular layer entity count.

07-01-2014 05:08 PM in reply to: mcicognani


Hi,

 

Thanks for your reply.

It helps to solve my issue.

 

Thanks again!

thenndral

Valued Mentor
KerryBrown
Posts: 269
Registered: ‎11-29-2008
Message 4 of 5 (94 Views)

Re: Open drawing in memory and get Particular layer entity count.

07-01-2014 08:31 PM in reply to: mcicognani

mcicognani,

I wonder if you could clarify a couple of things.

 

Why do you manually dispose rather than implement the conventional using paradigm?

 

Why do you need the try / catch statement ?

What error are you expecting ?

 

 Under what conditions would an objectID returned from an iteration of modelspace be null ?

 

Regards,

 

 

//-------------------------------------------------------

class keyThumper<T> : Lazy<T>;      another  Swamper

Distinguished Contributor
mcicognani
Posts: 125
Registered: ‎12-01-2004
Message 5 of 5 (80 Views)

Re: Open drawing in memory and get Particular layer entity count.

07-01-2014 11:35 PM in reply to: KerryBrown

Hi Kerry,

you may call it programmer's paranoia or just habit.

 

I learned to use the try/catch with manual transaction dispose() from the very early examples and to me that's the 'conventional' form.

It gives you more control on whatever exception may happen inside the execution block.

 

The example shown do not pose major risks, so you may simplify with the using() form, I agree, but I prefer this form for two reasons:

- the first is habit, like I said;

- the second is out of experience on the field.

 

Let me explain this: I work in a technical department in the building industry. We normally have an 'extended' workflow where drawing are received from a variety of sources, using different softwares and tools, and it's not uncommon that those drawings come with internal errors, some minimal, some more serious (I wonder how many of you people usually needs to Audit and/or Recover their drawings... for us is daily business).

You may say to set a protocol for incoming dwgs to pass them under mandatory recovery (I also developed an automation for this), but given the number of drawings and the time frame allowed, this is not always possible.

 

The result is that often our applications run on unstable drawings and I've seen a number of unexpected errors simply reading the database, and in this case, I want our application to handle this unexpected errors without hang AutoCAD.

Not a guarantee, more severe errors will hang AutoCAD nevertheless, but a lot of exceptions are handled correctly.

The using clause without catch will pass any exception up to the main application and in this case, AutoCAD will simply give a message and force the user to exit, this for sure.

 

This answers also your last question. Out of statistics I may say the more common 'unexpected' errors (what a nice oxymoro!) are:

- erased entities returned even is explicitely filtered out in the GetObject() function;

- invalid BlockTableRecords that throw exceptions simply iterating the BlockTable;

- invalid hatches, expecially if using non-standard shapes files;

 

If you give a look at my real working code, you'll find a lot of checks you would mark as useless, but nevertheless, sometimes they catch the fish ;-)

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.