Publishing a Sheet Set using VB.Net

Publishing a Sheet Set using VB.Net

Anonymous
Not applicable
1,423 Views
3 Replies
Message 1 of 4

Publishing a Sheet Set using VB.Net

Anonymous
Not applicable

Hi Everyone!

 

I am trying to create a custom publish to plotter script using VB.Net. I'm have a very limited knowledge in VB.Net Programming and I'm trying to learn the basics. I would like to ask if someone here have created a custom script that performs the same function as the built-in Publish to Plotter command in the Sheet Set Manager of AutoCAD 2015? The requirements that I need for the code is as shown:

 

1. Loop thru the sheet set

2. Print each drawing layout found in the sheet set using a custom page layout.

3. Save in a specified folder.

 

Basically, the code acts similar as the Publish to Plotter command wherein it publishes the drawing layout individually (multiple sheets) rather than a single sheet PDF.

 

I want to create this custom script since the Publish to Plotter or the Publish using Dialog Box outputs the drawing a bit blurred since the override uses the default DWG to PDF.pc3. The custom plotter that I will use is the Adobe PDF.pc3 but this can't be used as override for publishing.

 

I searched all over the internet and also asked our local Autodesk support in my country and no one was able to help me 🙂 I'm looking forward to anyone's help.

 

Thanks!

Jeremiah

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

Anonymous
Not applicable

The key of what you want to do is working with Application.Publisher object, its PublishExecute() method and the DsdData object you need to pass to it.

I couldn't retrieve the original post from where I started, but I remember was posted in Autodesk's DevBlog...

So far I could only find this link to Kean's blog, that can also be a start: http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-multi.html

 

Anyway, I'm also posting my code, that has been thought mostly to print multiple files, with multiple layouts, into a single PDF file.

The list of files can be retrieved from your SheetSet, and you can change the plot configuration to print to single files instead of a multipage PDF.

Also, I never tried other drivers, so I cannot say if it works with Adobe driver...

 

Just my cent:

 

static public void BatchPublishCmd(List<String> docsToPlot, String szOutputFile)
{
    short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT");

    Application.SetSystemVariable("BACKGROUNDPLOT", 0);

    // retrieve plot configuration from project settings
    string szPlotterName = csSettings.plt_Plotter;
    string szStyle = csSettings.plt_Stile;
    string szMedia = csSettings.plt_Formato;
    string szScala = csSettings.plt_Scala;
    bool bCentrapagina = csSettings.plt_bCentraPagina;

    if (szMedia.ToLower().StartsWith("auto")) szMedia = "";         // if not specified, allow for automatic selection of media
    StdScaleType eScale = ConvertScaleToType(szScala);


    DsdEntryCollection collection = new DsdEntryCollection();

    foreach (String filename in docsToPlot)
    {
        // read file without loading in graphics window
        Database db = new Database(false, true);
        db.ReadDwgFile(filename, FileShare.ReadWrite, true, "");

        string docName = Path.GetFileNameWithoutExtension(filename);

        using (Transaction Tx = db.TransactionManager.StartTransaction())
        {
             ObjectIdCollection layoutIds = GetLayoutIds(db);

             foreach (ObjectId layoutId in layoutIds)
             {
                 Layout lo = Tx.GetObject(layoutId, OpenMode.ForWrite) as Layout;

                 Point3d pMin = lo.Extents.MinPoint;
                 Point3d pMax = lo.Extents.MaxPoint;

                 PlotSettingsValidator psv = PlotSettingsValidator.Current;
                 PlotSettings ps = new PlotSettings(lo.ModelType);
                 ps.CopyFrom(lo);

                 // assegna stile di stampa, se presente
                  _SetPlotStyle(szStyle, ps, psv);

                 ps.ScaleLineweights = false;

                 psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents);
                 psv.SetUseStandardScale(ps, true);
                 psv.SetStdScaleType(ps, eScale);
                 psv.SetPlotCentered(ps, bCentrapagina);
                 //psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);

                 bool bPaperIsLandscape;
                 bool bAreaIsLandscape;

                 if (lo.ModelType) bAreaIsLandscape = (db.Extmax.X - db.Extmin.X) > (db.Extmax.Y - db.Extmin.Y) ? true : false;
                 else bAreaIsLandscape = (lo.Extents.MaxPoint.X - lo.Extents.MinPoint.X) > (lo.Extents.MaxPoint.Y - lo.Extents.MinPoint.Y) ? true : false;

                 // find best media
                 szMedia = _PlotSetMedia(szPlotterName, szMedia, lo, ps, psv);

                 // find best rotation
                 bPaperIsLandscape = (ps.PlotPaperSize.X > ps.PlotPaperSize.Y) ? true : false;
                 if (bPaperIsLandscape != bAreaIsLandscape) psv.SetPlotRotation(ps, PlotRotation.Degrees270);

                 // save plot info back to layout, will be needed later when publishing
                 ps.PlotSettingsName = lo.LayoutName + "_plot";
                 ps.PrintLineweights = true;
                 ps.AddToPlotSettingsDictionary(db);

                 Tx.AddNewlyCreatedDBObject(ps, true);
                 psv.RefreshLists(ps);

                 lo.CopyFrom(ps);

                 // write info for publishing list
                 DsdEntry entry = new DsdEntry();

                 entry.DwgName = filename;
                 entry.Layout = lo.LayoutName;
                 entry.Title = docName + "_" + lo.LayoutName;
                 entry.NpsSourceDwg = entry.DwgName;
                 entry.Nps = ps.PlotSettingsName;

                 collection.Add(entry);
            }

             Tx.Commit();
        }

        db.RetainOriginalThumbnailBitmap = true;
        db.SaveAs(filename, true, DwgVersion.Current, db.SecurityParameters);
   }

    DsdData dsd = new DsdData();

    dsd.SheetType = (szPlotterName.ToUpperInvariant().Contains("PDF") ? SheetType.MultiPdf : SheetType.MultiDwf);
    dsd.ProjectPath = csSettings.m_szTempFolder;
    dsd.DestinationName = szOutputFile;
    dsd.IsHomogeneous = false;

    if (File.Exists(dsd.DestinationName)) File.Delete(dsd.DestinationName);

    dsd.SetDsdEntryCollection(collection);

     string dsdFile = csSettings.m_szTempFolder + "\\dsdData.dsd";
     if (File.Exists(dsdFile)) File.Delete(dsdFile);

     //Workaround to avoid promp for dwf file name
     //set PromptForDwfName=FALSE in dsdData
     //using StreamReader/StreamWriter

     dsd.WriteDsd(dsdFile);

     StreamReader sr = new StreamReader(dsdFile);
     string str = sr.ReadToEnd();
     sr.Close();

     str = str.Replace("PromptForDwfName=TRUE", "PromptForDwfName=FALSE");
     str = str.Replace("PromptForPdfName=TRUE", "PromptForPdfName=FALSE");

     System.IO.StreamWriter sw = new System.IO.StreamWriter(dsdFile);
     sw.Write(str);
     sw.Close();

     dsd.ReadDsd(dsdFile);
     File.Delete(dsdFile);

     PlotConfig plotConfig = PlotConfigManager.SetCurrentConfig(szPlotterName);

     Publisher publisher = Application.Publisher;
     publisher.PublishExecute(dsd, plotConfig);

     //reset the background plot value
     Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot);
}

private static ObjectIdCollection GetLayoutIds(Database db)
{
    ObjectIdCollection layoutIds = new ObjectIdCollection();

     using (Transaction Tx = db.TransactionManager.StartTransaction())
     {
         DBDictionary layoutDic = Tx.GetObject(db.LayoutDictionaryId, OpenMode.ForRead, false) as DBDictionary;

         foreach (DBDictionaryEntry entry in layoutDic)
         {
             Layout lay = (Layout)Tx.GetObject(entry.Value, OpenMode.ForRead);
             if (lay.ModelType) continue;

             // check for empty layouts, to be ignored
             BlockTableRecord btr = (BlockTableRecord)Tx.GetObject(lay.BlockTableRecordId, OpenMode.ForRead);

              // count entities in layout, keep only if there is more than 2 entities
              int count = 0;
              foreach (ObjectId o in btr)
              {
                  if (++count > 2) break;
              }

              if (count > 2) layoutIds.Add(entry.Value);
        }

        // if there are no valid layout, add modelspace as Layout object
        if (layoutIds.Count == 0)
        {
           foreach (DBDictionaryEntry entry in layoutDic)
           {
                Layout lay = (Layout)Tx.GetObject(entry.Value, OpenMode.ForRead);
                if (lay.ModelType)
                            layoutIds.Add(entry.Value);
            }
        }
    }

    return layoutIds;
}

private static void _SetPlotStyle(String szStyle, PlotSettings ps, PlotSettingsValidator psv)
{
    if (szStyle.Length > 0)
    {
        System.Collections.Specialized.StringCollection sc = psv.GetPlotStyleSheetList();
        foreach (String szStyleFullName in sc)
        {
            if (System.IO.Path.GetFileName(szStyleFullName) == szStyle)
            {
                psv.SetCurrentStyleSheet(ps, szStyleFullName);
                break;
            }
        }
    }
}

private static String _PlotSetMedia(String szPlotterName, String szMedia, Layout lo, PlotSettings ps, PlotSettingsValidator psv)
{
    if (szMedia.Length > 0)
    {
        // set current plotter
        psv.SetPlotConfigurationName(ps, szPlotterName, null);
        psv.RefreshLists(ps);

        System.Collections.Specialized.StringCollection v = psv.GetCanonicalMediaNameList(ps);
        String szCanonicalName = "", szTmp;

        // find media by canonical name                
        foreach (String s in v)
        {
            if (s == szMedia)
            {
                 szCanonicalName = szMedia;
                 break;
            }
            else
            {
                // check local name, if applicable
                szTmp = psv.GetLocaleMediaName(ps, s);
                if (szTmp == szMedia)
                {
                    szCanonicalName = s;
                    break;
                }
            }
        }

        psv.SetPlotConfigurationName(ps, szPlotterName, szCanonicalName);                         
        psv.SetPlotRotation(ps, PlotRotation.Degrees000);
    }
    else
    {
        // media not selected, choose the best from plot size (choose your strategy here)
        if (lo.ModelType) szMedia = FindBestFormat(ps, psv, szPlotterName, lo.Database.Extmin, lo.Database.Extmax);
        else szMedia = FindBestFormat(ps, psv, szPlotterName, lo.Extents.MinPoint, lo.Extents.MaxPoint);
    }
    return szMedia;
}
0 Likes
Message 3 of 4

Anonymous
Not applicable

Thanks @Anonymous! I'll try your code by tweaking the values that I need and give you my feedback 🙂

0 Likes
Message 4 of 4

Anonymous
Not applicable

In AutoCAD there is options to set vector quality, bookmarks, layer information, etc... How do we set all this pragmatically?

 

Thanks,

0 Likes