I'm developing on a W7 64bit machine using VS2010 and AutoCAD 2010. Using COM, I've converted a VBA application into an .exe that runs but it is very slow (much slower then the 32bit VBA code used to run). Since we produce a lot of DXFs out of our 3D application, we want the conversion to be automated (hence, no more running inside of AutoCAD).
The current version just references the AutoCAD 2010 Type Library and the AutoCADObjectdbx COMs.
For each DXF, the code does the following:
1. Adds new layers
2. Loops thru all entites (currently using a selectionset)
a. Changes the entity's layer based on a collection key and it's linetype to "bylayer"
b. For PolyLines and LWPolyLines, sets the constantwidth to 0
c. For all Text, changes the style to "SIMPLEX", the Scalefactor to 0.7 and looks for a special text value which
indicates the drawing scale ("dscale").
3. Sets the drawing's DIMSCALE and LTSCALE to a multiple of the "dscale"
4. Scales all entities by "dscale"
5. Purges All
7. Saves the drawing as a *.dwg file
8. Closes the drawing
9. Logs some statistics on each file converted.
It seems as most of the time is spent in Step 2. I can obviously do steps 2,3 & 4 by reading/modifying the DXF as a text file very fast. But I would rather keep all the processing inside of AutoCAD.
So here are my questions(based on using COM):
1. What additional references do I need work directly with the drawing's database?
2. Are the NET transaction examples under this category valid when going through COM?
I've zipped and attached the current project (VS2010 project) for possible reference
Slowness (compared to your previous VBA (in 32bit Acad) code is what you get when choosing COM automating Acad from external EXE app, because your EXE app and Acad run in different processes and the communication between your app and Acad must travel through process boundaries. It would not be surprise me if your EXE is 5, 10, 20 times slower than your previous VBA code running inside Acad when doing the same job.
If you insist of doing EXE app, your coice of speed thing up would be
1. Directctly manipulate DXF file as ACSII/TEXT file;
2. Use ObjectDBX to manipulate drawing (i.e. without opening the drawing in AutoCAD editor, but you still need a running Acad session). This way, the slowness caused by loading drawing file visually is eliminated. However, you will not be able to Zoom to Extents as you required.
To your questions:
1. You do not need other references. You cannot directly access drawing database exposed in .NET API. You only deal with ACAD COM object model
2. "Net Transaction"? if you refer to Database/Transaction exposed in .NET API, no, you cannot use it in EXE app. Well, if you go deep, you could do .NET DLL with .NET API and then expose it as COM, then call it from your external EXE. But, what is the point: you still automate it from external app/out-proccess, which is slow!
IMO, it is arguable that just because there are a lots of DXF file to provess then you must use EXE to automate AutoCAD.
With the all DXF/DWG manipulating done inside AutoCAD with .NET API, you still can automate entire process:
1. create an EXE, it only does one thing: start AutoCAD session and make sure the .NET DLL is netloaded (say, with specific acad.lsp).
2. Once the .NET dll loaded, it will take over the Acad session and start DXF processing inside AutoCAD until the batch process done and close Acad session (if you choose so). No out-prcess to the startup EXE, so no the slowness caused by cross-process communication.
Okay, so then I'll create a new class type project, reference in the ObjectARX files, and get the code running in AutoCAD. Then worry about starting AutoCAD and lauching the dll.
We have a comparable VBA program converting drawings according to a set of input rules read from a ini file using the flexibility of VB's dynamic interpretation.
We are rewriting this into C# using Reflection to convert and compile the rules into a DLL, this is supprisingly fast ( far less than 1 second).
Then this DLL will be loaded and executed dynamically and runs about as fast as a normal loaded .net project.
(First tests indicate an improved performance from 30 seconds to convert in VB to 1 second in C#. No need for a progress bar anymore)
This approach keeps the "flexibility" of VBA where users may change the input rules and it keeps the speed of .net preserved.
To show you the functionality here are a few input rules
All rules are applied on all entities
Rules are divided in "tests" and "settings" separated by ";"
Tests starts with ? and test the property of an entity i.e. ?layer=Adres test the layername of the entity for the pattern Adres. the value of a test is a regular expression.
Settings sets the property of an entity, i.e. Layer=0 puts the entity on layer "0".
When a test failed the rest of the line of the input rule will be skipped, i.e. ?Type=Text; only enititytype of Text will be matched and thus the rest of the line apply only on text entities "?TextHeight=>2;?TextHeight=<=3;Layer=Tekst25;Colo
To prevent conversion and compilation every time when the same input rules are used we calculate a checksum and add this to the DLL. So if the DLL exists and has the same checksum we can start the conversion without conversion and compilation of the DLL.
hope this also may help you to create a speedy program.
Thanks to all. I simply created a new project (Class DLL), added the ObjectArx 2010 references, Added the CommandMethod to show the main form and It runs at the same speed that it used to. in VBA (but faster cause I'm using a machine with more juice).
Now I'll just work on getting code to launch AutoCAD, netload the DLL, and run the init command to start processing.