Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Microsoft to release source for .NET Framework Libraries | Main | Plotting a window from AutoCAD using .NET »

    October 09, 2007

    Allowing selection of an AutoCAD plot device and media name using .NET

    A comment came in on this previous post regarding how best to know whether a media name is valid during your plot configuration.

    There are a few approaches, other than the one I chose of hardcoding the device and media names. The first is to implement a user interface of some kind which allows the user to select the device and media names. Another approach for setting the media name is to use PlotSettingsValidator.SetClosestMediaName() to choose the media name that most closely matches the paper size you desire.

    Today I'll focus on the first option, although I'm only going to implement a basic, command-line user interface. It should be straightforward to extend this to implement a WinForm with comboboxes for the device and media names.

    I implemented a simple function called ChooseDeviceAndMedia() which queries the current device list, allows selection from it, and then gets the media name list and allows selection from that. I chose not to worry about displaying locale-specific names, for now - I'll leave that for a future post (let me know if you're interested :-).

    Here's the function integrated into the C# code from this previous post, which defines a command called MPLOT:

    using Autodesk.AutoCAD.Runtime;

    using Autodesk.AutoCAD.ApplicationServices;

    using Autodesk.AutoCAD.DatabaseServices;

    using Autodesk.AutoCAD.EditorInput;

    using Autodesk.AutoCAD.Geometry;

    using Autodesk.AutoCAD.PlottingServices;

    using System.Collections.Specialized;


    namespace PlottingApplication

    {

      public class PlottingCommands

      {

        static public string[] ChooseDeviceAndMedia()

        {

          Document doc =

            Application.DocumentManager.MdiActiveDocument;

          Editor ed = doc.Editor;


          // Assign default return values


          string devname = "", medname = "";


          PlotSettingsValidator psv =

            PlotSettingsValidator.Current;


          // Let's first select the device


          StringCollection devlist =

            psv.GetPlotDeviceList();


          for (int i = 0; i < devlist.Count; i++)

          {

            ed.WriteMessage(

              "\n{0} {1}",

              i + 1,

              devlist[i]

            );

          }

          PromptIntegerOptions opts =

            new PromptIntegerOptions(

              "\nEnter number of device to select: "

            );

          opts.LowerLimit = 1;

          opts.UpperLimit = devlist.Count;


          PromptIntegerResult pir =

            ed.GetInteger(opts);

          if (pir.Status == PromptStatus.OK)

          {

            devname = devlist[pir.Value - 1];

            ed.WriteMessage(

              "\nSelected: {0}\n",

              devname

            );


            // Now let's select the media


            PlotSettings ps = new PlotSettings(true);

            using (ps)

            {

              // We should refresh the lists,

              // in case setting the device impacts

              // the available media


              psv.SetPlotConfigurationName(

                ps,

                devname,

                null

              );

              psv.RefreshLists(ps);


              StringCollection medlist =

                psv.GetCanonicalMediaNameList(ps);


              for (int i = 0; i < medlist.Count; i++)

              {

                ed.WriteMessage(

                  "\n{0} {1}",

                  i + 1,

                  medlist[i]

                );

              }

              opts.Message =

                "\nEnter number of media to select: ";

              opts.LowerLimit = 1;

              opts.UpperLimit = medlist.Count;


              pir = ed.GetInteger(opts);

              if (pir.Status == PromptStatus.OK)

              {

                medname = medlist[pir.Value - 1];

                ed.WriteMessage(

                  "\nSelected: {0}\n",

                  medname

                );

              }

            }

          }

          return new string[2] { devname, medname };

        }


        [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)

            {

              string[] devmed = ChooseDeviceAndMedia();


              // Only proceed if we have values for both


              if (devmed[0] != "" && devmed[1] != "")

              {

                string devname = devmed[0];

                string medname = devmed[1];


                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)

                  {

                    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,

                        devname,

                        medname

                      );


                      // 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 contains multiple sheets


                      ppd.set_PlotMsgString(

                        PlotMessageIndex.SheetName,

                        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++;

                      ppd.PlotProgressPos +=

                        (100 / layoutsToPlot.Count);

                    }


                    // 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."

              );

            }

          }

        }

      }

    }

    Here's what I see at the command-line when I run the MPLOT command on my system (items 7-18 below are network printers in various Autodesk offices):

    Command: MPLOT


    1 None

    2 SnagIt 8

    3 PDF-XChange 3.0

    4 Microsoft XPS Document Writer

    5 Microsoft Office Live Meeting Document Writer

    6 Adobe PDF

    7 \\adscctps1\cctprn000

    8 \\adsneups2\neuprn304

    9 \\adsneups2\neuprn306

    10 \\adsneups2\neuprn307

    11 \\adsneups2\neuprn317

    12 \\banhpa001\banprn001

    13 \\beihpa001\BEIPRN002

    14 \\beihpa001\BEIPRN003

    15 \\farhpa001\FARPRN101

    16 \\pra-pc61237\Xerox WorkCentre Pro 35 PCL6

    17 \\tokhpa001\tokprn401

    18 \\tokhpa001\tokprn402

    19 Default Windows System Printer.pc3

    20 DWF6 ePlot.pc3

    21 DWFx ePlot (XPS Compatible).pc3

    22 DWG To PDF.pc3

    23 PublishToWeb JPG.pc3

    24 PublishToWeb PNG.pc3

    Enter number of device to select: 22


    Selected: DWG To PDF.pc3


    1 ISO_expand_A0_(841.00_x_1189.00_MM)

    2 ISO_A0_(841.00_x_1189.00_MM)

    3 ISO_expand_A1_(841.00_x_594.00_MM)

    4 ISO_expand_A1_(594.00_x_841.00_MM)

    5 ISO_A1_(841.00_x_594.00_MM)

    6 ISO_A1_(594.00_x_841.00_MM)

    7 ISO_expand_A2_(594.00_x_420.00_MM)

    8 ISO_expand_A2_(420.00_x_594.00_MM)

    9 ISO_A2_(594.00_x_420.00_MM)

    10 ISO_A2_(420.00_x_594.00_MM)

    11 ISO_expand_A3_(420.00_x_297.00_MM)

    12 ISO_expand_A3_(297.00_x_420.00_MM)

    13 ISO_A3_(420.00_x_297.00_MM)

    14 ISO_A3_(297.00_x_420.00_MM)

    15 ISO_expand_A4_(297.00_x_210.00_MM)

    16 ISO_expand_A4_(210.00_x_297.00_MM)

    17 ISO_A4_(297.00_x_210.00_MM)

    18 ISO_A4_(210.00_x_297.00_MM)

    19 ARCH_expand_E1_(30.00_x_42.00_Inches)

    20 ARCH_E1_(30.00_x_42.00_Inches)

    21 ARCH_expand_E_(36.00_x_48.00_Inches)

    22 ARCH_E_(36.00_x_48.00_Inches)

    23 ARCH_expand_D_(36.00_x_24.00_Inches)

    24 ARCH_expand_D_(24.00_x_36.00_Inches)

    25 ARCH_D_(36.00_x_24.00_Inches)

    26 ARCH_D_(24.00_x_36.00_Inches)

    27 ARCH_expand_C_(24.00_x_18.00_Inches)

    28 ARCH_expand_C_(18.00_x_24.00_Inches)

    29 ARCH_C_(24.00_x_18.00_Inches)

    30 ARCH_C_(18.00_x_24.00_Inches)

    31 ANSI_expand_E_(34.00_x_44.00_Inches)

    32 ANSI_E_(34.00_x_44.00_Inches)

    33 ANSI_expand_D_(34.00_x_22.00_Inches)

    34 ANSI_expand_D_(22.00_x_34.00_Inches)

    35 ANSI_D_(34.00_x_22.00_Inches)

    36 ANSI_D_(22.00_x_34.00_Inches)

    37 ANSI_expand_C_(22.00_x_17.00_Inches)

    38 ANSI_expand_C_(17.00_x_22.00_Inches)

    39 ANSI_C_(22.00_x_17.00_Inches)

    40 ANSI_C_(17.00_x_22.00_Inches)

    41 ANSI_expand_B_(17.00_x_11.00_Inches)

    42 ANSI_expand_B_(11.00_x_17.00_Inches)

    43 ANSI_B_(17.00_x_11.00_Inches)

    44 ANSI_B_(11.00_x_17.00_Inches)

    45 ANSI_expand_A_(11.00_x_8.50_Inches)

    46 ANSI_expand_A_(8.50_x_11.00_Inches)

    47 ANSI_A_(11.00_x_8.50_Inches)

    48 ANSI_A_(8.50_x_11.00_Inches)

    Enter number of media to select: 35


    Selected: ANSI_D_(34.00_x_22.00_Inches)

    Effective plotting area:  15.29 wide by 20.60 high

    Effective plotting area:  13.29 wide by 17.31 high


    Plotting viewport 2.


    Plotting viewport 1.

    Regenerating layout.

    Regenerating model.

    Effective plotting area:  15.69 wide by 20.60 high

    Effective plotting area:  15.69 wide by 20.59 high


    Plotting viewport 2.


    Plotting viewport 1.

    Regenerating layout.

    Regenerating model.

    Effective plotting area:  15.69 wide by 20.60 high

    Effective plotting area:  15.69 wide by 20.59 high


    Plotting viewport 2.


    Plotting viewport 1.

    Regenerating layout.

    Regenerating model.

    Effective plotting area:  15.69 wide by 20.60 high

    Effective plotting area:  14.07 wide by 18.34 high


    Plotting viewport 2.


    Plotting viewport 1.

    Regenerating layout.

    Regenerating model.

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200e54ef40c308833

    Listed below are links to weblogs that reference Allowing selection of an AutoCAD plot device and media name using .NET:

    Comments

    Definitely helps, but why am i getting single page dwfs? the layout loop i am doing is the same as yours.

    I can get a dsd publish to do multiple page dwfs, though.

    Overall, your site and the .net discussion group has helped a lot, i would say i have learned 40 to 60 % of the api from them.

    As I mentioned in the original multi-sheet post, I believe the DWF6 driver is not actually multi-sheet. Which is why I chose the DWFx driver to demonstrate the technique.

    The Publish API may be the way to go, if you need to create multi-page DWF6 files (I haven't looked into it myself, as yet).

    Kean

    How does one get the plotter name.
    Your example gives the Device name (.pc3)
    I was looking for something like the page setup manager gives.
    eg.
    Device name: HP4500.PC3
    Plotter: HP Desginjet 4500

    You should be able to get this via the PlotConfig's Comment property. The device would need to be loaded first, from what I can tell, but then the PlotConfigManager should provide access via the CurrentConfig.

    Good luck,

    Kean

    Thanks Kean,

    Unfortunately if the device is not avaliable it takes quite a few seconds to load the info.

    AutoCAD’s page setup manager does not appear to have to load the device in order to get the info.

    I suspect AutoCAD just does it at a different time. I don't know of a magic way to get around this delay, I'm afraid.

    Kean

    Hi Kean,

    Reactivating this topic.. Hope you read it, and maybe can help me.

    I'm working on a App to plot in PLT, PDF or DWF. The choice is made by user selection (Windows Form + Radio Button).

    I'm having problem with the MediaName.
    Although I've manually included the medias manually in the .PC3 file (for the three devices), things still don't work..
    For PLT (using HP-750C), thats OK, but I had to use your piece of code to list medianames, because the name I've created is not the same. I've created someting like: A0, A1, A0L, etc... But in medianame listing it apears like: UserDefinedMetric (900.00 x 2500.00MM), UserDefinedMetric (900.00 x 2000.00MM), etc...

    For DWF, no matter the medianame, it gives me an "eInvalidInput", and breaks...

    For PDF, although the custom sizes i've created, even in medianame listing, it just don't appear...

    If I set the BACKGROUNDPLOT=0, it doesn't plot... If set to 2, then it takes long, but generates the files...

    Hope you can help me...

    Thank you very much!

    Felipe,
    SP-Brazil

    Hi Felipe,

    The kind of troubleshooting you need is beyond what I can provide, I'm afraid. The ADN team will be able to help, if you're a member, otherwise I suggest trying the the discussion groups.

    Regards,

    Kean

    Thanks Kean,

    An workaround that I choose using is plotting via `doc.SendStringToExecute(command "._plot" "Y" ... ... )`

    The only issue I've found was that both PDF and DWF are "auto-plot-to-file", but not the PLT via HP750C.pc3. So I've set a global variable "bool autoplottofile", so that depending of the device i'm using, the command will have an "parameter" diference.

    But no problems with delay, medianames, etc..

    Hope this helps..

    Thanks!

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search