Driving a multi-sheet AutoCAD plot using .NET

转载 2007年10月15日 14:01:00
Somewhat symmetrically I’m posting this from Chicago airport, once again, but thankfully I’m now on my way home. It was a busy week of meetings, but I did get the chance to put together some code that extended the last post into the realm of multi-sheet plot jobs.

The following code took some work, but I finally managed to iron out the obvious wrinkles and put together an approach to plot multiple sheets into a single document. The standard DWF6 driver doesn’t appear to support multiple sheet jobs (directly, at least), so I chose to use the DWFx driver that I probably downloaded and installed from here.

I haven’t “diffed” and colour-coded the changed lines with the previous post, as there ended up being quite a lot of swapping around etc., but you should be able to perform that comparison yourself, if you so wish.

Here’s the C# code:

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.PlottingServices;


namespace PlottingApplication

{

  public class PlottingCommands

  {

    [CommandMethod("mplot")]

    static public void MultiSheetPlot()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      Database db = doc.Database;


      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId,

            OpenMode.ForRead

          );


        PlotInfo pi = new PlotInfo();

        PlotInfoValidator piv =

          new PlotInfoValidator();

        piv.MediaMatchingPolicy =

          MatchingPolicy.MatchEnabled;


        // A PlotEngine does the actual plotting

        // (can also create one for Preview)


        if (PlotFactory.ProcessPlotState ==

            ProcessPlotState.NotPlotting)

        {

          PlotEngine pe =

            PlotFactory.CreatePublishEngine();

          using (pe)

          {

            // Create a Progress Dialog to provide info

            // and allow thej user to cancel


            PlotProgressDialog ppd =

              new PlotProgressDialog(false, 1, true);

            using (ppd)

            {

              ObjectIdCollection layoutsToPlot =

                new ObjectIdCollection();


              foreach (ObjectId btrId in bt)

              {

                BlockTableRecord btr =

                  (BlockTableRecord)tr.GetObject(

                    btrId,

                    OpenMode.ForRead

                  );

                if (btr.IsLayout &&

                    btr.Name.ToUpper() !=

                      BlockTableRecord.ModelSpace.ToUpper())

                {

                  layoutsToPlot.Add(btrId);

                }

              }


              int numSheet = 1;


              foreach (ObjectId btrId in layoutsToPlot)

              {

                BlockTableRecord btr =

                  (BlockTableRecord)tr.GetObject(

                    btrId,

                    OpenMode.ForRead

                  );

                Layout lo =

                  (Layout)tr.GetObject(

                    btr.LayoutId,

                    OpenMode.ForRead

                  );


                // We need a PlotSettings object

                // based on the layout settings

                // which we then customize


                PlotSettings ps =

                  new PlotSettings(lo.ModelType);

                ps.CopyFrom(lo);


                // The PlotSettingsValidator helps

                // create a valid PlotSettings object


                PlotSettingsValidator psv =

                  PlotSettingsValidator.Current;


                // We'll plot the extents, centered and

                // scaled to fit


                psv.SetPlotType(

                  ps,

                Autodesk.AutoCAD.DatabaseServices.PlotType.Extents

                );

                psv.SetUseStandardScale(ps, true);

                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);

                psv.SetPlotCentered(ps, true);


                // We'll use the standard DWFx PC3, as

                // this supports multiple sheets


                psv.SetPlotConfigurationName(

                  ps,

                  "DWFx ePlot (XPS Compatible).pc3",

                  "ANSI_A_(8.50_x_11.00_Inches)"

                );


                // We need a PlotInfo object

                // linked to the layout


                pi.Layout = btr.LayoutId;


                // Make the layout we're plotting current


                LayoutManager.Current.CurrentLayout =

                  lo.LayoutName;


                // We need to link the PlotInfo to the

                // PlotSettings and then validate it


                pi.OverrideSettings = ps;

                piv.Validate(pi);


                if (numSheet == 1)

                {

                  ppd.set_PlotMsgString(

                    PlotMessageIndex.DialogTitle,

                    "Custom Plot Progress"

                  );

                  ppd.set_PlotMsgString(

                    PlotMessageIndex.CancelJobButtonMessage,

                    "Cancel Job"

                  );

                  ppd.set_PlotMsgString(

                    PlotMessageIndex.CancelSheetButtonMessage,

                    "Cancel Sheet"

                  );

                  ppd.set_PlotMsgString(

                    PlotMessageIndex.SheetSetProgressCaption,

                    "Sheet Set Progress"

                  );

                  ppd.set_PlotMsgString(

                    PlotMessageIndex.SheetProgressCaption,

                    "Sheet Progress"

                  );

                  ppd.LowerPlotProgressRange = 0;

                  ppd.UpperPlotProgressRange = 100;

                  ppd.PlotProgressPos = 0;


                  // Let's start the plot, at last


                  ppd.OnBeginPlot();

                  ppd.IsVisible = true;

                  pe.BeginPlot(ppd, null);


                  // We'll be plotting a single document


                  pe.BeginDocument(

                    pi,

                    doc.Name,

                    null,

                    1,

                    true, // Let's plot to file

                    "c://test-multi-sheet"

                  );

                }


                // Which may contain multiple sheets


                ppd.StatusMsgString =

                  "Plotting " +

                  doc.Name.Substring(

                    doc.Name.LastIndexOf("//") + 1

                  ) +

                  " - sheet " + numSheet.ToString() +

                  " of " + layoutsToPlot.Count.ToString();


                ppd.OnBeginSheet();


                ppd.LowerSheetProgressRange = 0;

                ppd.UpperSheetProgressRange = 100;

                ppd.SheetProgressPos = 0;


                PlotPageInfo ppi = new PlotPageInfo();

                pe.BeginPage(

                  ppi,

                  pi,

                  (numSheet == layoutsToPlot.Count),

                  null

                );

                pe.BeginGenerateGraphics(null);

                ppd.SheetProgressPos = 50;

                pe.EndGenerateGraphics(null);


                // Finish the sheet

                pe.EndPage(null);

                ppd.SheetProgressPos = 100;

                ppd.OnEndSheet();

                numSheet++;

              }


              // Finish the document


              pe.EndDocument(null);


              // And finish the plot


              ppd.PlotProgressPos = 100;

              ppd.OnEndPlot();

              pe.EndPlot(null);

            }

          }

        }

        else

        {

          ed.WriteMessage(

            "/nAnother plot is in progress."

          );

        }

      }

    }

  }

}

The output of the MPLOT command will be created in “c:/test-multi-sheet.dwfx”, which can then be viewed using Autodesk Design Review 2008 or the XPS viewer that ships with Windows Vista or from here for Windows XP.

Update

I spent some more time looking at this code and noticed a minor issue... We need to tell the plot dialog that we're working with multiple sheets in its constructor. So we first need to count the sheets and then create the dialog. Here's the modified section of code:

          PlotEngine pe =

            PlotFactory.CreatePublishEngine();

          using (pe)

          {

            // Collect all the paperspace layouts

            // for plotting

            ObjectIdCollection layoutsToPlot =

              new ObjectIdCollection();

            foreach (ObjectId btrId in bt)

            {

              BlockTableRecord btr =

                (BlockTableRecord)tr.GetObject(

                  btrId,

                  OpenMode.ForRead

                );

              if (btr.IsLayout &&

                  btr.Name.ToUpper() !=

                    BlockTableRecord.ModelSpace.ToUpper())

              {

                layoutsToPlot.Add(btrId);

              }

            }

            // Create a Progress Dialog to provide info

            // and allow thej user to cancel

            PlotProgressDialog ppd =

              new PlotProgressDialog(

                false,

                layoutsToPlot.Count,

                true

              );

            using (ppd)

            {

This now leads to the plot progress dialog showing multiple progress bars:

Multisheet_plot_progress

 

Previewing and plotting multiple sheets in AutoCAD using .NET

This was a fun one to work on. The code in this post combines and extends upon techniques shown in t...
  • sdphg
  • sdphg
  • 2007年10月15日 14:04
  • 939

Driving a multi-sheet AutoCAD plot using .NET

Somewhat symmetrically I’m posting this from Chicago airport, once again, but thankfully I’m now on ...
  • sdphg
  • sdphg
  • 2007年10月15日 14:01
  • 1256

各种PDF转换问题(三).将AutoCAD图纸转为PDF文档

目前国内企业生产的自动化程度并不是很高,大多数都无法使用三维图直接进行加工生产,所以二维图对于大多数企业来说,仍然是最根本的生产依据。那么,在企业中,二维图转PDF就是一个很重要的小步骤,因为后续的打...
  • super_admi
  • super_admi
  • 2014年09月06日 16:17
  • 6240

Driving a basic AutoCAD plot using .NET

I just missed my connecting flight in Chicago, so have 3 hours to pass until the next, and decided t...
  • sdphg
  • sdphg
  • 2007年10月15日 14:00
  • 1335

Altium Designer-Net has no driving source警告消除的方法

1.其实这个警告原因是: 你图中有一个器件的管脚有属性(如I/O),并且这个管脚设定了驱动源,                     你先从元件库中,找到这个管脚,把管脚的属性 改成下面图片 ...
  • u013385925
  • u013385925
  • 2016年04月16日 14:40
  • 3506

AutoCAD按坐标打印图纸

前几天公司要求按坐标打印DWG文件,中间走了不少弯路,好在已经搞定了,整理一下分享给大家,希望后来人少走弯路。     1. 设计需求:          公司的图纸用AutoCAD2010做成,通常...
  • beckhans
  • beckhans
  • 2013年10月29日 11:02
  • 3539

将AutoCAD的dwg图纸转换为pdf

在三维CAD设计软件中,二维图转PDF一般是一个软件的内置功能,所以这些软件一般都会直接提供一个API,来实现转PDF的功能。如PROE的TOOLKIT库,NX的NXOpen库(注意不是C库,而是C+...
  • Larry_666
  • Larry_666
  • 2018年03月19日 09:06
  • 50

Altium Designer 消除Net has no driving source警告的方法

在进行原理图编译的时候提示警告:Net has no driving source  如下图: 解决方法:点击Place----Directives-----No ERC(不进行电气规则检查) ...
  • yueniaoshi
  • yueniaoshi
  • 2012年08月01日 20:23
  • 57968

Deep Learning and Autonomous Driving

https://handong1587.github.io/deep_learning/2015/10/09/dl-and-autonomous-driving.html Jump ...
  • mydear_11000
  • mydear_11000
  • 2017年07月26日 18:23
  • 763

Plotting a window from AutoCAD using .NET

This post extends this previous post that dealt with driving a single-sheet AutoCAD plot by adding s...
  • sdphg
  • sdphg
  • 2007年10月15日 14:10
  • 1480
收藏助手
不良信息举报
您举报文章:Driving a multi-sheet AutoCAD plot using .NET
举报原因:
原因补充:

(最多只允许输入30个字)