For example I have a folder that contains two drawings, the drawing1 has a line, the drawing2 has a circle, and then I wanted to create a command to count the total number of entities in the two drawings, of course, the result here is 2,
I only know use the follow statement to aeecss the current drawing
Document acDoc = Application.DocumentManager.MdiActiveDocument;
And then use the getSelection() method, but I can only select the entities in only one drawing at the same time by mouse, and then count them, but how can I deal with multiple drawings
I have two ideas:
The first: open all the drawings, and then execute a command, and finally get 2
The second: execute a command, and then return 2, It will count the all drawings in a folder which is specified.
I do not know which one will be better, but any help much appreciative, very thanks.
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
If you really need to know is some simple information, such as how may entities in drawing, say, ModelSpace, then you can do it quickly with side database (that is you do not need to open the drawing in AuutoCAD editor, which takes time),
You do these:
1. get a folder path;
2. get a list of drawing file name;
For each drawing file,
4. create a side database and read the dwg file into it;
5. open the modelspace BlockTableRecord;
6. iterrate through the BlockTableRecord to get entity count, you can count only particular type of entity; or count entities based on its properties, such as layer, color, linetype...
7. dispose the side database
Norman Yuan
Hi
uh...It's a magic, I didn't know I can create a side database and read the dwg file into it until now, so that the information of multiple drawings are merged together, I can search in it, it will be great.
But I do not know what mean of side database, or how to achieve the process as you said, can you give me a simple sample code? just solve the above problem will be ok.
Really, really appreciate
Well, using a side database to access information in a drawing is very basic/well known way when using AutoCAD .NET API. You probably have already seen it in this forum.
Anyway, here is a piece quick code sample, which is just directly off my head, not compiled/tested in VS:
public int FileLineEntityCount(string[] dwgFiles)
{
int lineCount=0;
foreach (var dwgFile in dwgFiles)
{
using (Database db=new Database(false, true))
{
db.ReadDwgFile(dwgFile, FileShare.Read,true,null);
using (Transaction tran=db.TransactionManager.StartTransaction())
{
BlockTable bt=(BlockTable)tran.GteObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord model=(BlockTableRecord)tran.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForRead);
foreach (ObjectId id in model)
{
if (id.ObjectClass.DxfName.ToUpper()=="LINE") lineCount++;
}
tran.commit()
}
}
}
return lineCount;
}
Norman Yuan
Thank you very much, I think I probably understand the use of side database, I have create a command, this command is used to copy the graphic that frequently used to the left side of drawing,
Most of the graphics can be copied correctly, only AlignedDimension not copied correctly, I do not know why, I find it really copied, but it's invisible.
I guess I should use acCurDb.WblockCloneObjects() incorrectly,I feel the acBlkTblRec.ObjectId is not good, but I do not know how to modify, or is there exsit another better way to achieve this function like this command, can you help me?
Here is my code
class Sidebar { [CommandMethod("SD")] static public void createSidebar() { Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; using (DocumentLock doclock = acDoc.LockDocument()) { Database sideDb = new Database(false, true); sideDb.ReadDwgFile(@"D:\AutocadCommandCollectionNew\Data\Drawing\Sidebar.dwg", System.IO.FileShare.ReadWrite, true, ""); ObjectIdCollection sideDataBaseObjectcIds = new ObjectIdCollection(); using (Transaction sideTrans = sideDb.TransactionManager.StartTransaction()) { BlockTable sideBlkTbl = sideTrans.GetObject(sideDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord sideBlkTblRec = sideTrans.GetObject(sideBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; foreach (ObjectId id in sideBlkTblRec) { Entity entityObj = sideTrans.GetObject(id, OpenMode.ForRead) as Entity; if (entityObj != null) { sideDataBaseObjectcIds.Add(id); } } sideTrans.Abort(); } using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; IdMapping acIdMap = new IdMapping(); acCurDb.WblockCloneObjects(sideDataBaseObjectcIds,acBlkTblRec.ObjectId,acIdMap,DuplicateRecordCloning.Ignore,false); acTrans.Commit(); } } } }
Thank you very much as always.
I find a very strange thing, at first I execute the above command, AlignedDimension is invisible, as follow
Then I select any block, open the block editor, without any modification, and then close block editor, AlignedDimension will be visible ...as follow
What is the problem?
See changes in the code, just a quick shot though
static public void createSidebar() { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor acEd = acDoc.Editor; try { using (DocumentLock doclock = acDoc.LockDocument()) { using (Transaction acTrans = acDoc.TransactionManager.StartTransaction()) { Database sideDb = new Database(false, true); sideDb.ReadDwgFile(@"D:\AutocadCommandCollectionNew\Data\Drawing\Sidebar.dwg", System.IO.FileShare.ReadWrite, true, ""); // sideDb.ReadDwgFile(@"C:\Test\3DBlock.dwg", System.IO.FileShare.ReadWrite, true, ""); ObjectIdCollection sideDataBaseObjectcIds = new ObjectIdCollection(); using (Transaction sideTrans = sideDb.TransactionManager.StartTransaction()) { BlockTableRecord sideBlkTblRec = (BlockTableRecord)sideTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite); // BlockTable sideBlkTbl = sideTrans.GetObject(sideDb.BlockTableId, OpenMode.ForRead) as BlockTable; // BlockTableRecord sideBlkTblRec = sideTrans.GetObject(sideBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; foreach (ObjectId id in sideBlkTblRec) { Entity entityObj = sideTrans.GetObject(id, OpenMode.ForRead) as Entity; if (entityObj != null) { sideDataBaseObjectcIds.Add(id); } } // sideTrans.Abort();// Do not use Abort inside: try { catch {} } code block } // BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; BlockTableRecord acBlkTblRec = (BlockTableRecord)acTrans.GetObject(sideDb.CurrentSpaceId, OpenMode.ForWrite); IdMapping acIdMap = new IdMapping(); acCurDb.WblockCloneObjects(sideDataBaseObjectcIds, acBlkTblRec.ObjectId, acIdMap, DuplicateRecordCloning.Ignore, false); acTrans.Commit(); acEd.Regen(); } } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message + "\nFound " + ex.StackTrace); } finally { } }
Hi,
Your code has a little problem, I made some modify, then it able to run, the new code as follow
[CommandMethod("SD")] static public void createSidebar() { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor acEd = acDoc.Editor; try { using (DocumentLock doclock = acDoc.LockDocument()) { using (Transaction acTrans = acDoc.TransactionManager.StartTransaction()) { Database sideDb = new Database(false, true); sideDb.ReadDwgFile(@"D:\AutocadCommandCollectionNew\Data\Drawing\Sidebar.dwg", System.IO.FileShare.ReadWrite, true, ""); // sideDb.ReadDwgFile(@"C:\Test\3DBlock.dwg", System.IO.FileShare.ReadWrite, true, ""); ObjectIdCollection sideDataBaseObjectcIds = new ObjectIdCollection(); using (Transaction sideTrans = sideDb.TransactionManager.StartTransaction()) { //BlockTableRecord sideBlkTblRec = (BlockTableRecord)sideTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite); BlockTable sideBlkTbl = sideTrans.GetObject(sideDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord sideBlkTblRec = sideTrans.GetObject(sideBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; foreach (ObjectId id in sideBlkTblRec) { Entity entityObj = sideTrans.GetObject(id, OpenMode.ForRead) as Entity; if (entityObj != null) { sideDataBaseObjectcIds.Add(id); } } // sideTrans.Abort();// Do not use Abort inside: try { catch {} } code block } // BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; BlockTableRecord acBlkTblRec = (BlockTableRecord)acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite); IdMapping acIdMap = new IdMapping(); acCurDb.WblockCloneObjects(sideDataBaseObjectcIds, acBlkTblRec.ObjectId, acIdMap, DuplicateRecordCloning.Ignore, false); acTrans.Commit(); acEd.Regen(); } } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { Application.ShowAlertDialog(ex.Message + "\nFound " + ex.StackTrace); } finally { } }
But the results did not change, at first I execute this command complied by your code, AlignedDimension is invisible, then I select any block, open the block editor, without any modification, and then close block editor, AlignedDimension will be visible as before.
I read your code, and find the only difference between before is the more acEd.Regen (); but this does not work,
The attachment has the drawing that I want to copy to current drawing, it contain the above-mentioned AlignedDimension, Maybe you can download it, and save it to D:\AutocadCommandCollectionNew\Data\Drawing\Sidebar.dwg, then has a test.
Best wishes for you
I've tested your last code with this file ,
seems to me all is good, I didn't find any problem,
See attached picture after executing a command SD:
Hi hallex,
You are missing something. please see the follow picture
I can ensure the AligedDimension is copied, but they are invisible, but if I choose any block and open the block editor, without any modify and close the block editor, they will be visible, this is weird, maybe you should test again.
Thanks for your help.
Test as is, It's working in A2014:
[CommandMethod("SD")] static public void createSidebar() { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor acEd = acDoc.Editor; AnnotativeStates anno; try { using (DocumentLock doclock = acDoc.LockDocument()) { using (Transaction acTrans = acDoc.TransactionManager.StartTransaction()) { Database sideDb = new Database(false, true); sideDb.ReadDwgFile(@"D:\AutocadCommandCollectionNew\Data\Drawing\Sidebar.dwg", System.IO.FileShare.ReadWrite, true, ""); // sideDb.ReadDwgFile(@"C:\Test\Trusted\Sidebar.dwg", System.IO.FileShare.ReadWrite, true, ""); ObjectIdCollection sideDataBaseObjectcIds = new ObjectIdCollection(); using (Transaction sideTrans = sideDb.TransactionManager.StartTransaction()) { //BlockTableRecord sideBlkTblRec = (BlockTableRecord)sideTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite); BlockTable sideBlkTbl = sideTrans.GetObject(sideDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord sideBlkTblRec = sideTrans.GetObject(sideBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; anno = sideBlkTblRec.Annotative; foreach (ObjectId id in sideBlkTblRec) { Entity entityObj = sideTrans.GetObject(id, OpenMode.ForRead) as Entity; if (entityObj != null) { sideDataBaseObjectcIds.Add(id); } } // sideTrans.Abort();// Do not use Abort inside: try { catch {} } code block } // BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; BlockTableRecord acBlkTblRec = (BlockTableRecord)acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite); IdMapping acIdMap = new IdMapping(); acCurDb.WblockCloneObjects(sideDataBaseObjectcIds, acBlkTblRec.ObjectId, acIdMap, DuplicateRecordCloning.Replace,false); if (anno == AnnotativeStates.True) acBlkTblRec.Annotative = anno; acEd.UpdateScreen(); acEd.UpdateTiledViewportsFromDatabase(); acTrans.Commit(); // Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();//optional } } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message + "\nFound " + ex.StackTrace); } finally { } }
Happy Easter to you
Uh, I think finally find the problem, please so the picture
It looks like if a drawing that already exists the metioned AlignedDimension, so it can not copy correctly.
I take some more test to this AlignedDimension, it include some BlockReferences, if I explode it, It will no longer appear above problem,
System default quick demension, although it does not contain BlockReference, but contains a solid line, there will be the same problem.
Maybe this information is useful to you.
For this problem, you helped me several times, but I think this is the last step to solve it, then the program should be ok.
Very grateful to you.
I find some more information, if a new blank drawing contain any demension entity, whatever it is the default standard demension style or custom ISO-L and ISO-R demension style, then execute this command, the all demension of the souce drawing won't display properly, but run _bedit command, open any block editor, without any modification and close, they will display.
I have test the above code in the AutoCAD 2010 & 2012, and it has the some problem, if the drawing exsiting some demension entity, then execute this command, the demension entityies that copyied from the source drawing won't display properly, but they are actually copied, just need open any block editor and close or save the drawing and reopen it, the demension will display.
I hope someone can help me, very thanks.