Optimizing Interop Plotting to PDF - C#

Optimizing Interop Plotting to PDF - C#

grindstaffp
Observer Observer
2,879 Views
3 Replies
Message 1 of 4

Optimizing Interop Plotting to PDF - C#

grindstaffp
Observer
Observer

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:

  1. I cannot figure out how to prevent the resulting PDF from being opened.
  2. 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?
  3. 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.

0 Likes
2,880 Views
3 Replies
Replies (3)
Message 2 of 4

_gile
Consultant
Consultant

Did you try using the Core Console?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 4

grindstaffp
Observer
Observer

I have used the core console and manually created a pdf running through the PLOT command but I am unsure of how to automate the use of core console without providing it a script to run. If I want to provide different output directories based on a given project I don't know a way to do that.

Any pointers?

0 Likes
Message 4 of 4

_gile
Consultant
Consultant

If the use of .bat file(s) (as in the Kean example) does not suit you, you can call AutoLISP expressions from the script file or, if you prefer, create a custom .NET command (with only references to accoremgd.dll and acbdmgd.dll), NETLOAD it and run it from the script.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes