Publish through API

Publish through API

BestFriendCZ
Advocate Advocate
4,378 Views
9 Replies
Message 1 of 10

Publish through API

BestFriendCZ
Advocate
Advocate

Hi,

I need again advice from knowledge programmers 😊. I have a drawing where i defind print settings layout… then i use the function for multiple publish. I was inspired function for multiple publish here:

 

https://forums.autodesk.com/t5/net/plot-dwg-to-pdf-for-multiple-layouts-in-c/td-p/5849145

 

All parameters which i sett are in layouts objects but function for public use another pc3 file (AutoCAD PDF (General Documentation).pc3) - no matter which pc3 file i sett. When i published manually then all is correct. How can i force publish layouts with my pc3 file through API.

 

...
0 Likes
Accepted solutions (1)
4,379 Views
9 Replies
Replies (9)
Message 2 of 10

BestFriendCZ
Advocate
Advocate

this is my current code:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System.Collections.Generic;
using System.IO;
namespace AutoCAD.Command
{
    public class Commands
    {

        [CommandMethod("NewDrawing", CommandFlags.Session)]
          public static void NewDrawing()
        {
            string strTemplatePath = "acad.dwt";
            DocumentCollection acDocMgr = Application.DocumentManager;
            Document acDoc = acDocMgr.Add(strTemplatePath);
        }




        [CommandMethod("PrintMultiSheetsPdf", CommandFlags.Session)]
        public void PrintMultiSheetsPdf()
        {
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;   //mother autocad document
                PromptResult promptResult = doc.Editor.GetString("\nEnter the parameter: ");  //hardcode user command from anothert side
                if (promptResult.Status != PromptStatus.OK)
                    return;
                if (promptResult.StringResult.Contains(";") != true)
                {
                    doc.Editor.WriteMessage($"Input parametr: {promptResult.StringResult} is invalid. Right format - (destination path;source file path).");
                    return;
                }
                string[] inputParametrs = promptResult.StringResult.Split(';');     //input parameters: destination path and source file path

                if (File.Exists(inputParametrs[1]) != true)
                {
                    doc.Editor.WriteMessage($"Source file: {inputParametrs[1]} does not exist.");
                    return;
                }

                if (!System.IO.Directory.Exists(inputParametrs[0]))
                    System.IO.Directory.CreateDirectory(inputParametrs[0]);

                bool isValidate = false;
                string PaperSize = "ISO full bleed A3 (420.00 x 297.00 MM)";
                string Plottername = "DWG To PDF.pc3";
                string PlotStyleName = "PDF files for instructions.ctb";
                CustomScale customScale = new CustomScale(1, 1);
                string PaperCode = string.Empty;
                int i = 0;
                bool UsePlotStyles = true;
                bool UseLineWeights = true;
                bool ScaleLineWeights = false;
                bool HidePaperspaceObjects = false;
                bool CenterPlot = true;
                foreach (string plotDevice in PlotSettingsValidator.Current.GetPlotDeviceList())    // check available printer, 
                {
                    if (Plottername.Trim().ToUpper() == plotDevice.Trim().ToUpper())
                    {
                        isValidate = true;
                        break;
                    }
                }
                if (isValidate == false)
                {
                    doc.Editor.WriteMessage($"Selected printer: {Plottername} is not installed on this computer. Contact your system administrator");
                    return;
                }
                using (PlotSettings acPlSet = new PlotSettings(true))    //try to find right paper value because it is no possible to set GetLocaleMediaName(this value is only show in UI)
                {
                    PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
                    acPlSetVdr.SetPlotConfigurationName(acPlSet, Plottername, null);
                    foreach (string mediaName in acPlSetVdr.GetCanonicalMediaNameList(acPlSet))
                    {
                        if (PaperSize.Trim().ToUpper() == acPlSetVdr.GetLocaleMediaName(acPlSet, i).Trim().ToUpper())
                        {
                            PaperCode = mediaName;
                            break;
                        }
                        i++;
                    }
                }
                if (PaperCode == string.Empty)
                {
                    doc.Editor.WriteMessage($"Selected papersize: {PaperSize} is not available on selected printer. Contact your system administrator");
                    return;
                }
                List<Layout> layouts = new List<Layout>();
                using (Database db = new Database(false, true))
                {
                    if (Functions.IsFileAvailable(new FileInfo(inputParametrs[1])) != true)
                    {
                        doc.Editor.WriteMessage($" File: {inputParametrs[1]} is already locked by some other process.");
                        return;
                    }
                    db.ReadDwgFile(inputParametrs[1], System.IO.FileShare.ReadWrite, true, ""); // open select DWG file
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        DBDictionary layoutDict = (DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
                        foreach (DBDictionaryEntry entry in layoutDict)
                        {
                            if (entry.Key.Trim().ToUpper() != "MODEL") // set all layouts except model
                            {
                                Layout acLayout = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
                                using (PlotSettings currentPlSet = new PlotSettings(acLayout.ModelType))
                                {
                                    currentPlSet.CopyFrom(acLayout);
                                    PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
                                    acPlSetVdr.SetPlotConfigurationName(currentPlSet, Plottername, PaperCode);
                                    acPlSetVdr.SetPlotPaperUnits(currentPlSet, PlotPaperUnit.Millimeters);
                                    acPlSetVdr.SetPlotWindowArea(currentPlSet, new Extents2d(10, 8.5, 430, 288.5));
                                    acPlSetVdr.SetPlotType(currentPlSet, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
                                    acPlSetVdr.SetPlotCentered(currentPlSet, CenterPlot);
                                    acPlSetVdr.SetPlotRotation(currentPlSet, PlotRotation.Degrees000);
                                    acPlSetVdr.SetPlotOrigin(currentPlSet, new Point2d(0, 0));
                                    currentPlSet.ShowPlotStyles = UsePlotStyles;
                                    try { acPlSetVdr.SetCurrentStyleSheet(currentPlSet, PlotStyleName); }
                                    catch
                                    {
                                        doc.Editor.WriteMessage($"AutoCAD does not contains file - {PlotStyleName} .");
                                        return;
                                    }
                                  
                                    currentPlSet.PlotHidden = HidePaperspaceObjects;
                                    currentPlSet.PrintLineweights = UseLineWeights;
                                    currentPlSet.ScaleLineweights = ScaleLineWeights;
                                    acPlSetVdr.SetCustomPrintScale(currentPlSet, customScale);
                                    acPlSetVdr.SetZoomToPaperOnUpdate(currentPlSet, true);    // Zoom to show the whole paper
                                    acLayout.UpgradeOpen();   // Update the layout
                                    acLayout.CopyFrom(currentPlSet);
                                }
                                layouts.Add(acLayout);
                            }
                        }
                        tr.Commit();
                    }
                    try  //try to delte old file
                    {
                        if (System.IO.File.Exists(Path.ChangeExtension(inputParametrs[1], "pdf")))
                            System.IO.File.Delete(Path.ChangeExtension(inputParametrs[1], "pdf"));
                    }
                    catch
                    {
                        doc.Editor.WriteMessage($"There is no possible delete old file - {Path.ChangeExtension(inputParametrs[1], "pdf")} .");
                        return;
                    }
                    doc.Editor.Regen();
                    db.SaveAs(inputParametrs[1], DwgVersion.Current);   //save modify print settings back to layout
                }
                layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder)); // Sort selected layouts to right order
                MultiSheetsPdf plotter = new MultiSheetsPdf(inputParametrs[0], layouts, inputParametrs[1]); //prepare plot
                plotter.Publish();  //plot selected laouys
            }
            catch { return; }
        }
    }

}
...
0 Likes
Message 3 of 10

BestFriendCZ
Advocate
Advocate

 

i tryed send here too my code but everytime was marked like spam and delete it

then i gave him to attachments

...
0 Likes
Message 4 of 10

SENL1362
Advisor
Advisor
Try set PlotType==PlotType.Window before setting the PlotWindowArea
0 Likes
Message 5 of 10

BestFriendCZ
Advocate
Advocate

Hi,

you have right... these parametrs are on wrong order... but I do not think it will  some change printer driver... for sure I tested and result is same...it is used AutoCAD PDF (General Documentation).pc3 and in layouts is set DWG to PDF.pc3

 

i think problem will be in function for multiple layouts print but relly dont know why this  function does not respect layout settings -mainly printer driver

 

function print is here:

using System.Collections.Generic;
using System.IO;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Publishing;

namespace AutoCAD.Command
{
    public abstract class PlotToFileConfig
    {
        private string dsdFile, dwgFile, outputDir, outputFile, plotType;
        private int sheetNum;
        private IEnumerable<Layout> layouts;
        private const string LOG = "publish.log";
        public PlotToFileConfig(string outputDir, IEnumerable<Layout> layouts, string plotType, string sourceFilePath)
        {
            this.dwgFile = sourceFilePath;
            this.outputDir = outputDir;
            this.dsdFile = Path.ChangeExtension(this.dwgFile, "dsd");
            this.layouts = layouts;
            this.plotType = plotType;
            string ext = plotType == "0" || plotType == "1" ? "dwf" : "pdf";
            this.outputFile = Path.Combine(
                this.outputDir,
                Path.ChangeExtension(Path.GetFileName(this.dwgFile), ext));
        }
        public void Publish()
        {
            if (TryCreateDSD())
            {
                object rememberBACKGROUNDPLOT = Application.GetSystemVariable("BACKGROUNDPLOT");
                object rememberHIDEPRECISION = (short)Application.GetSystemVariable("HIDEPRECISION");
                object remembertraynotify = (short)Application.GetSystemVariable("traynotify");

                try
                {
                    Application.SetSystemVariable("BACKGROUNDPLOT", 0);
                    Application.SetSystemVariable("HIDEPRECISION", 1);
                    Application.SetSystemVariable("traynotify", 0);
                    Publisher publisher = Application.Publisher;
                    PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);                
                    publisher.PublishDsd(this.dsdFile, plotDlg);
                    File.Delete(this.dsdFile);
                }
                catch (System.Exception exn)
                {
                    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
                    ed.WriteMessage("\nError: {0}\n{1}", exn.Message, exn.StackTrace);
                    throw;
                }
                finally
                {
                    Application.SetSystemVariable("BACKGROUNDPLOT", rememberBACKGROUNDPLOT);
                    Application.SetSystemVariable("HIDEPRECISION", rememberHIDEPRECISION);
                    Application.SetSystemVariable("traynotify", remembertraynotify);
                }
            }
        }
        private bool TryCreateDSD()
        {
            using (DsdData dsd = new DsdData())
            using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
            {
                if (dsdEntries == null || dsdEntries.Count <= 0) return false;
                this.sheetNum = dsdEntries.Count;
                dsd.SetDsdEntryCollection(dsdEntries);
                dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
                dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
                dsd.NoOfCopies = 1;
                dsd.DestinationName = this.outputFile;
                dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
                PostProcessDSD(dsd);
                return true;
            }
        }
        private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
        {
            DsdEntryCollection entries = new DsdEntryCollection();
            foreach (Layout layout in layouts)
            {
                DsdEntry dsdEntry = new DsdEntry();
                dsdEntry.DwgName = this.dwgFile;
                dsdEntry.Layout = layout.LayoutName;
                dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
                dsdEntry.Nps = layout.TabOrder.ToString();
                entries.Add(dsdEntry);
            }
            return entries;
        }
        private void PostProcessDSD(DsdData dsd)
        {
            string str, newStr;
            string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
            dsd.WriteDsd(tmpFile);
            using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
            using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
            {
                while (!reader.EndOfStream)
                {
                    str = reader.ReadLine();
                    if (str.Contains("Has3DDWF"))
                    {
                        newStr = "Has3DDWF=0";
                    }
                    else if (str.Contains("OriginalSheetPath"))
                    {
                        newStr = "OriginalSheetPath=" + this.dwgFile;
                    }
                    else if (str.Contains("Type"))
                    {
                        newStr = "Type=" + this.plotType;
                    }
                    else if (str.Contains("OUT"))
                    {
                        newStr = "OUT=" + this.outputDir;
                    }
                    else if (str.Contains("IncludeLayer"))
                    {
                        newStr = "IncludeLayer=TRUE";
                    }
                    else if (str.Contains("PromptForDwfName"))
                    {
                        newStr = "PromptForDwfName=FALSE";
                    }
                    else if (str.Contains("LogFilePath"))
                    {
                        newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
                    }
                    else
                    {
                        newStr = str;
                    }
                    writer.WriteLine(newStr);
                }
            }
            File.Delete(tmpFile);
        }
    }
    public class SingleSheetPdf : PlotToFileConfig
    {
        public SingleSheetPdf(string outputDir, IEnumerable<Layout> layouts, string sourceFilePath)
          : base(outputDir, layouts, "5", sourceFilePath) { }
    }
    public class MultiSheetsPdf : PlotToFileConfig
    {
        public MultiSheetsPdf(string outputDir, IEnumerable<Layout> layouts, string sourceFilePath)
         : base(outputDir, layouts, "6", sourceFilePath) { }
    }
}
...
0 Likes
Message 6 of 10

BestFriendCZ
Advocate
Advocate

little note😊
this driver... i mean AutoCAD PDF (General Documentation).pc3... is not use in any layouts..it doesn't set like default
and too it wasn't use during the last print
it's strange how this driver was choice

...
0 Likes
Message 7 of 10

BestFriendCZ
Advocate
Advocate

any idea?

...
0 Likes
Message 8 of 10

BestFriendCZ
Advocate
Advocate
Accepted solution

i found solution by change DSD file.

...
0 Likes
Message 9 of 10

BestFriendCZ
Advocate
Advocate


maybe it could help:

 

print multiple layout with your CP3 file

using System.Collections.Generic;
using System.IO;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Publishing;

namespace AutoCAD.Command
{
    public abstract class PlotToFileConfig
    {
        private string dsdFile, dwgFile, outputDir, outputFile, driver;
        private int sheetNum;
        private IEnumerable<Layout> layouts;
        public PlotToFileConfig(string outputDir, IEnumerable<Layout> layouts, string sourceFilePath, string driver)
        {
            this.dwgFile = sourceFilePath;
            this.outputDir = outputDir;
            this.dsdFile = Path.ChangeExtension(this.dwgFile, "dsd");
            this.layouts = layouts;
            this.driver = driver;
            string ext = "pdf";
            this.outputFile = Path.Combine(this.outputDir, Path.ChangeExtension(Path.GetFileName(this.dwgFile), ext));
        }
        public void Publish()
        {
            if (TryCreateDSD())
            {
                object rememberBACKGROUNDPLOT = Application.GetSystemVariable("BACKGROUNDPLOT");
                object rememberHIDEPRECISION = (short)Application.GetSystemVariable("HIDEPRECISION");
                object remembertraynotify = (short)Application.GetSystemVariable("traynotify");
                try
                {
                    Application.SetSystemVariable("BACKGROUNDPLOT", 0);     // user windows off
                    Application.SetSystemVariable("HIDEPRECISION", 1);      // issue all line visible on
                    Application.SetSystemVariable("traynotify", 0);     //print notify off
                    Publisher publisher = Application.Publisher;
                    using (DsdData dsdDataFile = new DsdData())
                    {
                        dsdDataFile.ReadDsd(this.dsdFile);      //change printer driver for all layouts  other settings is from separate layouts
                        PlotConfig acPlCfg = PlotConfigManager.SetCurrentConfig(this.driver);
                        Application.Publisher.PublishExecute(dsdDataFile, acPlCfg);
                    }
                    File.Delete(this.dsdFile);
                }
                catch (System.Exception exn)
                {
                    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
                    ed.WriteMessage($"\nError:{exn.Message}\n{exn.StackTrace}");
                    throw;
                }
                finally
                {
                    Application.SetSystemVariable("BACKGROUNDPLOT", rememberBACKGROUNDPLOT);
                    Application.SetSystemVariable("HIDEPRECISION", rememberHIDEPRECISION);
                    Application.SetSystemVariable("traynotify", remembertraynotify);
                }
            }
        }
        private bool TryCreateDSD()
        {
            using (DsdData dsd = new DsdData())
            using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
            {
                if (dsdEntries == null || dsdEntries.Count <= 0) return false;
                this.sheetNum = dsdEntries.Count;
                dsd.SetDsdEntryCollection(dsdEntries);
                dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
                dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
                dsd.NoOfCopies = 1;
                dsd.DestinationName = this.outputFile;
                PostProcessDSD(dsd);
                return true;
            }
        }
        private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
        {
            try
            {
                DsdEntryCollection entries = new DsdEntryCollection();
                foreach (Layout layout in layouts)
                {
                    DsdEntry dsdEntry = new DsdEntry();
                    dsdEntry.DwgName = this.dwgFile;
                    dsdEntry.Layout = layout.LayoutName;
                    dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
                    dsdEntry.Nps = layout.TabOrder.ToString();
                    entries.Add(dsdEntry);
                }
                return entries;
            }
            catch { return null; }
        }
        private void PostProcessDSD(DsdData dsd)
        {
            string str, newStr;
            string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
            dsd.WriteDsd(tmpFile);
            using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
            using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
            {
                while (!reader.EndOfStream)
                {
                    str = reader.ReadLine();
                    if (str.Contains("Has3DDWF"))
                    {
                        newStr = "Has3DDWF=0";
                    }
                    else if (str.Contains("OriginalSheetPath"))
                    {
                        newStr = "OriginalSheetPath=" + this.dwgFile;
                    }
                    else if (str.Contains("Type"))
                    {
                        newStr = "Type=" + "6";  // print multiple layouts to one file
                    }
                    else if (str.Contains("OUT"))
                    {
                        newStr = "OUT=" + this.outputDir;
                    }
                    else if (str.Contains("IncludeLayer"))
                    {
                        newStr = "IncludeLayer=TRUE";
                    }
                    else if (str.Contains("PromptForDwfName"))
                    {
                        newStr = "PromptForDwfName=FALSE";
                    }
                    else
                    {
                        newStr = str;
                    }
                    writer.WriteLine(newStr);
                }
            }
            File.Delete(tmpFile);
        }
    }
    public class MultiSheetsPdf : PlotToFileConfig
    {
        public MultiSheetsPdf(string outputDir, IEnumerable<Layout> layouts, string sourceFilePath, string driverAllLayouts)
         : base(outputDir, layouts, sourceFilePath, driverAllLayouts) { }
    }
}
...
0 Likes
Message 10 of 10

jmikel
Participant
Participant

Beware that the PostProcessDSD method tests are too generic.  The tests should be rewritten to include the "=" sign.  ie.   "OUT="  instead of "OUT".   

I had a client that named one of their files "SOUTH".  The related layout in the dsdentry did not plot because it tested true for that condition. 

 

 

0 Likes