Optimizing Interop Plotting to PDF - C#
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Like many here before, I am needing to essentially batch plot a set of drawings to PDF. I originally thought I would be using ObjectARX to do this but then found that ObjectARX projects are typically addins for AutoCAD. My second thought was to take advantage of accoreconsole but I am not sure my use case fits necessarily works since accoreconsole expects a script to do anything. This would probably be my preferred method of saving my drawings to PDF so if there is a way to use accoreconsole I am open to suggestion.
So far I have functional code that sends a set of drawings to AutoCAD through COM and gives me PDF files. I have a few problems however:
- I cannot figure out how to prevent the resulting PDF from being opened.
- Once all of the drawings are processed and I quit AutoCAD, the first file processed asks if I want to save changes. What type of object to I need for "object SaveChanges" when calling Close() on a document?
- The process is relatively slow. To process 32 files takes around 2 minutes. I am using a single instance of AutoCAD so the slowdown shouldn't be occurring there. Obviously using Interop is never going to be the quickest but maybe there's a way to speed this up?
Code for reference:
static void Main(string[] args) { Type acType = Type.GetTypeFromProgID("AutoCAD.Application.23"); AutoCAD.AcadApplication acApp = null; //new AutoCAD.AcadApplication(); try { acApp = (AutoCAD.AcadApplication)Marshal.GetActiveObject("AutoCAD.Application"); } catch { acApp = new AutoCAD.AcadApplication(); //AutoCAD.AcadApplication acApp = (AutoCAD.AcadApplication)Activator.CreateInstance(acType, true); } acApp.Visible = false; AutoCAD.AcadDocument acDoc = null; string dwgDir = @"H:\Development\C#\Misc\44OP-257468\44OP-257468\MDT\"; var dwgs = Directory.EnumerateFiles(dwgDir, "*.dwg"); foreach (var dwg in dwgs) { FileInfo dwgInfo = new FileInfo(dwg); string outputFile = String.Format("G:\\temp\\{0}.pdf", dwgInfo.Name); acDoc = acApp.Documents.Open(dwg); while (!acApp.GetAcadState().IsQuiescent) { System.Threading.Thread.Sleep(25); } acDoc.ActiveSpace = AutoCAD.Common.AcActiveSpace.acModelSpace; var acPlotCfg = acDoc.PlotConfigurations; acPlotCfg.Add("PDF", true); // If second parameter is not true, exception is caused by acDoc.ActiveLayout.CopyFrom(PlotConfig); AutoCAD.Common.AcadPlotConfiguration PlotConfig = acPlotCfg.Item("PDF"); PlotConfig.ConfigName = "DWG To PDF.pc3"; PlotConfig.CanonicalMediaName = "ANSI_expand_A_(8.50_x_11.00_Inches)"; PlotConfig.PlotHidden = true; PlotConfig.StandardScale = AutoCAD.Common.AcPlotScale.acScaleToFit; PlotConfig.PlotType = AutoCAD.Common.AcPlotType.acExtents; PlotConfig.PaperUnits = AutoCAD.Common.AcPlotPaperUnits.acInches; PlotConfig.PlotRotation = AutoCAD.Common.AcPlotRotation.ac90degrees; PlotConfig.CenterPlot = false; PlotConfig.PlotWithLineweights = true; PlotConfig.PlotWithPlotStyles = true; //PlotConfig.StyleSheet = "acad.ctb"; PlotConfig.RefreshPlotDeviceInfo(); acDoc.ActiveLayout.CopyFrom(PlotConfig); // Need to have this or resulting PDF does not seem to apply the PlotConfig. acDoc.SetVariable("BACKGROUNDPLOT", 0); acDoc.Plot.QuietErrorMode = true; acDoc.Plot.PlotToFile(outputFile, PlotConfig.ConfigName); acDoc.Close(false, null); Console.WriteLine(String.Format("PDF Created For: {0}", dwgInfo.Name)); } acApp.Quit(); Console.WriteLine("Done"); Console.ReadLine(); }
One thought I had that may or may not have any performance benefit at all would be to create an ObjectARX add-in that builds on the concepts of this example code. My thought is that perhaps I could send the add-in a list of drawings, output folder and filenames, and page orientation information and handle the plot that way.
Another thought would be to automate accoreconsole as I mentioned above. This *may* be the best option as I could spawn a bunch of instances and process files concurrently.
Any direction of which way to go is much appreciated.