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.