• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Valued Contributor
    Posts: 81
    Registered: ‎11-13-2006
    Accepted Solution

    PLOTDATE field value updates via PLOT but not when plotted via API

    290 Views, 11 Replies
    01-10-2013 03:41 PM

    A client has specified that we include a "PlotDate" field in lieu of regular attribute in their title block.  This is formatted to contain, what else, but the date and time.

     

    When our users enter the PLOT command, this field gets automatically updated to the current date and time, resulting in a plot with a plot stamp.

     

    However, when we use our custom Batch Plot utility (VB.NET API), the drawings get plotted but the PlotDate field does NOT get updated.  I have found that fields of this type do not get updated via events like other fields, but rather when you call the UPDATEFIELD command.  However, the PLOT command itself must be doing something similar, as evidenced by the fact that the value of the field changes upon each PLOT.

     

    How would I go about "updating/refreshing" a "PlotDate" field when plotting a file via the API?

    Please use plain text.
    ADN Support Specialist
    Balaji_Ram
    Posts: 351
    Registered: ‎03-21-2011

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-16-2013 10:16 PM in reply to: spanqy

    Hello Mark,

     

    Here is a sample code to plot to PDF and the sample AutoCAD 2013 drawing that I am using which has a PlotDate field. The code to do the plotting is mostly from Kean's blog post.

    After the plotting using this command, the field does get updated. Can you please see how this differs from what you are trying ?

     

    [CommandMethod("GenPdf")]
    public void GenPdf()
    {
        try
        {
            PlotExtents("DWG To PDF.pc3", "ISO_expand_A4_(210.00_x_297.00_MM)", "monochrome.ctb", @"C:\Temp\Test.pdf");
        }
        catch (System.Exception e)
        {
            e.GetBaseException().ToString();
        }
    }
    
    // Plotting progress based on 
    // http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-multi.html
    static public void PlotExtents(string printer, string format, string styleSheet, string pdfFilePath)
    {
        try
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
    
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);
                Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
    
                PlotInfo pi = new PlotInfo();
                pi.Layout = btr.LayoutId;
    
                PlotSettings ps = new PlotSettings(lo.ModelType);
                PlotConfigInfo pci = new PlotConfigInfo();
    
                ps.CopyFrom(lo);
                ps.PlotPlotStyles = true;
    
                PlotSettingsValidator psv = PlotSettingsValidator.Current;
                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                psv.SetDefaultPlotConfig(ps);
    
                psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents);
                psv.SetUseStandardScale(ps, true);
                psv.SetPlotCentered(ps, true);
                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
    
    
                ////PS-PlotRotation
                Extents2d extent2d = ps.PlotPaperMargins;
                if (extent2d.MaxPoint.Y > extent2d.MaxPoint.X)
                {
                    psv.SetPlotRotation(ps, PlotRotation.Degrees000);
                }
                else
                {
                    psv.SetPlotRotation(ps, PlotRotation.Degrees090);
                }
    
                try
                {
                    psv.SetPlotConfigurationName(ps, printer, null);
                    psv.SetPlotConfigurationName(ps, printer, format);
                    psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);
                }
                catch (System.Exception e)
                {
                    e.GetBaseException().ToString();
                }
    
                psv.GetCanonicalMediaNameList(ps);
                pi.OverrideSettings = ps;
    
                PlotInfoValidator piv = new PlotInfoValidator();
                piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                piv.Validate(pi);
    
                if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
                {
                    using (PlotEngine pe = PlotFactory.CreatePublishEngine())
                    {
                        PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
                        using (ppd)
                        {
                            ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "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;
    
                            ppd.OnBeginPlot();
                            ppd.IsVisible = true;
                            ppd.OnBeginPlot();
                            ppd.IsVisible = true;
                            pe.BeginPlot(ppd, null);
    
                            pe.BeginDocument(pi, doc.Name, null, 1, true, pdfFilePath);
    
                            ppd.OnBeginSheet();
                            ppd.LowerSheetProgressRange = 0;
                            ppd.UpperSheetProgressRange = 100;
                            ppd.SheetProgressPos = 0;
    
                            PlotPageInfo ppi = new PlotPageInfo();
                            pe.BeginPage(ppi, pi, true, null);
                            pe.BeginGenerateGraphics(null);
                            ppd.SheetProgressPos = 50;
                            pe.EndGenerateGraphics(null);
    
                            pe.EndPage(null);
                            ppd.SheetProgressPos = 100;
                            ppd.OnEndSheet();
    
                            pe.EndDocument(null);
    
                            ppd.PlotProgressPos = 100;
                            ppd.OnEndPlot();
    
                            pe.EndPlot(null);
                        }
                    }
                }
                else
                {
                    ed.WriteMessage("\nCannot plot. System is busy plotting another one.");
                }
    
                tr.Commit();
            }
        }
        catch (System.Exception e)
        {
            // Display the error message here.
        }
    }
    }

     

     

     



    Balaji
    Developer Technical Services
    Autodesk Developer Network

    Please use plain text.
    Valued Contributor
    Posts: 81
    Registered: ‎11-13-2006

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 10:54 AM in reply to: Balaji_Ram

    Balaji,
    I too originally got my code from Keans blog and have tweaked it to my use.
    There were only a few lines from your post that I did not have in mine so I added them in the following manner:

    1. Added 1st missing line
    2. Test plotted my drawing - Bad results
    3. Added 2nd missing line, leaving 1st line
    4. Test plotted my drawing - Bad results
    5. etc.

    Even with all the missing lines added, I could not produce output where the field updated.
    I was beginning to think that maybe it was an issue with my own drawing but everytime I issue the PLOT command in it, the field updates.

    Next I turned my attention to your posted file (Test.dwg)
    The first thing I had to do though was save it down to 2010 format using DWG TrueView/DWG Convert.
    My post on the subscription site notes that we use the 2012 Infrastructure Suite.

    Once I did that, I first used my original code to plot it out in Civil 2012 and once again the field did not update.
    I then re-applied the missing lines from your post and re-plotted, but once again the field did not update.

    This leads me to believe that perhaps it is an issue with 2012 that was fixed in 2013?
    Can you try creating a similar drawing in 2012 (2010 format) then test your API code on it?

    Thanks

    Mark

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 02:18 PM in reply to: spanqy

    You create Batch Plot utility. I will ask three naive question.
    1. Do you switch WorkingDatabase to the Database which plotting?
    2. Do you save Database after plotting?

    3. Code of Balaji (as is without your's changes) working as expected or no with AutoCAD 2012?


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 81
    Registered: ‎11-13-2006

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 02:55 PM in reply to: Alexander.Rivilis

    Update: It works in 2012 with the 2010 format.  I just tested another app I have that produces single plots of the current drawing - It is a sort of simplified version of the PLOT command for use mainly by our non-CAD staff.  Plotting Balaji's drawing with it just produced a plot with the PlotDate field updated.

     

    I am going to compare this code carefully with my Batch Plot code.

     

    Your comment regarding WorkingDatabase is resonating in my mind - I am not setting this currently in the BatchPlot nor the app mentioned above, but it DOES make sense to do so while in batch mode...will re-post efforts.

     

    Thanks

    Please use plain text.
    Valued Contributor
    Posts: 81
    Registered: ‎11-13-2006

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 04:22 PM in reply to: spanqy

    I compared the code of each app and they are a match, which is what I expected because I built the BatchPlot app off of the other one.

    I really think this is an issue with the WorkingDatabase and the "Batch" nature of my app.
    I can't post all my code but here is what I think is relevant:

    'This is sub that loops and processes each selected drawing:

     

    Private Sub MySub()
        Dim dwg As Document = Nothing
        For Each dwgFile In files
            'open the drawing
            dwg = Application.DocumentManager.Open(dwgFile, True)
    
    '--TRIED THIS LINE WITHOUT SUCCESS
            'HostApplicationServices.WorkingDatabase = dwg.Database
    
    '--TRIED THIS LINE WITHOUT SUCCESS
            'Application.DocumentManager.MdiActiveDocument = dwg		
    
    	MyPlottingFunction()
    
    	dwg.CloseAndDiscard()
        Next
    End Sub

     This is the function that handles the plotting:

     

    Private Function MyPlottingFunction()
        Try
    '--HAVE CONFIRMED HERE VIA db.FileName PROPERTY THAT WorkingDatabase IS SET TO CURRENTLY OPEN/ACTIVE DRAWING
            Using db As Database = HostApplicationServices.WorkingDatabase	
                Using tr As Transaction = db.TransactionManager.StartTransaction
    
                    Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)
                    Dim objLayout As Layout = tr.GetObject(btr.LayoutId, OpenMode.ForRead)
                    Dim pi As PlotInfo = New PlotInfo
                    pi.Layout = btr.LayoutId
    
    	        ...
                    ...
    	    End Using
    	End Using
        Catch
            ...
        End Try
    End Function

     In the "MyPlottingFunction" above I even tried this:

     

    Dim db As Database = dwg.Database     'dwg PASSED IN AS BYREF PARAM (MY ORIG CODE)

     

    And this:

     

    HostApplicationServices.WorkingDatabase = db    'db PASSED IN AS BYREF PARAM

     

    I once struggeled with a batch application that was not setting my variables to the "active" drawing and found the solution was to add the Session attribute to the CommandMethod like this:

     

        <CommandMethod("BP", CommandFlags.Session)> _
            Public Sub Main()

     

    I have had this setting in my BatchPlot app from the begining however.  Stumped!

    Please use plain text.
    ADN Support Specialist
    Balaji_Ram
    Posts: 351
    Registered: ‎03-21-2011

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 10:12 PM in reply to: spanqy

    Hello Mark,

     

    I have tried making the command run in the "Session" context, but it still worked ok in AutoCAD 2012.

     

    Have you tried not opening the drawing using "Application.DocumentManager.Open(dwgFile, True)" and having your code plot the drawing which is already open in the editor ?

     

    Sorry, I am not sure what else might be causing this issue.

    You may try isolating chunks of your code at a time and narrow down on the cause.



    Balaji
    Developer Technical Services
    Autodesk Developer Network

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-17-2013 10:22 PM in reply to: spanqy

    spanqy wrote:
    ...
    dwg.CloseAndDiscard()
    ...

    My second question was: 2. Do you save Database after plotting?
    You DO NOT save dwg-file after ploting and that is why PLOTDATE is not changed.

     


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 81
    Registered: ‎11-13-2006

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-21-2013 08:05 AM in reply to: spanqy

    Saving would not work.  The application is a batch plotter only, which never makes any changes to a drawing.

     

    In any case, I don't completely agree.  We are not trying to save the updated "PlotDate" field in the drawing itself.  We only wish to have the current date/time show up in the output plot (hard copy or pdf).  This is what happens when we PLOT a drawing - the drawing could be saved (or not), just as long as the output contains the date/time of the plotting operation.  Sorry for the confusion.

     

     

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: PLOTDATE field value updates via PLOT but not when plotted via API

    01-22-2013 08:07 AM in reply to: spanqy
    using System;
    using System.Collections.Generic;
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.PlottingServices;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.EditorInput;
    
    [assembly: CommandClass(typeof(Rivilis.PDFPlot))]
    
    namespace Rivilis
    {
    
      public class PDFPlot
      {
        [CommandMethod("GenPdf", CommandFlags.Session)]
        public void GenPdf()
        {
          string[] files = { "C:\\FieldPlot1.dwg", "C:\\FieldPlot2.dwg", "C:\\FieldPlot3.dwg" }; // Test files with PLOTDATE field
          object oldBgPlot = Application.GetSystemVariable("BACKGROUNDPLOT");
          Application.SetSystemVariable("BACKGROUNDPLOT", 0);
          Document oldDoc = Application.DocumentManager.MdiActiveDocument;
          Database oldDb = HostApplicationServices.WorkingDatabase;
          try {
            foreach (string file in files) {
              Document doc = Application.DocumentManager.Open(file, true);
              Application.DocumentManager.MdiActiveDocument = doc;
              HostApplicationServices.WorkingDatabase = doc.Database;
              using (DocumentLock docloc = doc.LockDocument()) {
                PlotExtents("DWG To PDF.pc3", "ISO_expand_A4_(210.00_x_297.00_MM)", "monochrome.ctb", file + ".pdf");
              }
              doc.CloseAndDiscard();
            }
            Application.DocumentManager.MdiActiveDocument = oldDoc;
            HostApplicationServices.WorkingDatabase = oldDb;
            Application.SetSystemVariable("BACKGROUNDPLOT", oldBgPlot);
          }
          catch (System.Exception e) {
            System.Windows.Forms.MessageBox.Show(
              e.ToString(),
              "Error",
              System.Windows.Forms.MessageBoxButtons.OK,
              System.Windows.Forms.MessageBoxIcon.Error);
          }
        }
    
        // Plotting progress based on 
        // http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-multi.html
        static public void PlotExtents(string printer, string format, string styleSheet, string pdfFilePath)
        {
    
          Document doc = Application.DocumentManager.MdiActiveDocument;
          Editor ed = doc.Editor;
          Database db = doc.Database;
          try {
            using (Transaction tr = db.TransactionManager.StartTransaction()) {
              BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);
              Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
    
              PlotInfo pi = new PlotInfo();
              pi.Layout = btr.LayoutId;
    
              PlotSettings ps = new PlotSettings(lo.ModelType);
              PlotConfigInfo pci = new PlotConfigInfo();
    
              ps.CopyFrom(lo);
              ps.PlotPlotStyles = true;
    
              PlotSettingsValidator psv = PlotSettingsValidator.Current;
              psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
              psv.SetDefaultPlotConfig(ps);
    
              psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents);
              psv.SetUseStandardScale(ps, true);
              psv.SetPlotCentered(ps, true);
              psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
    
    
              ////PS-PlotRotation
              Extents2d extent2d = ps.PlotPaperMargins;
              if (extent2d.MaxPoint.Y > extent2d.MaxPoint.X) {
                psv.SetPlotRotation(ps, PlotRotation.Degrees000);
              }
              else {
                psv.SetPlotRotation(ps, PlotRotation.Degrees090);
              }
    
              try {
                psv.SetPlotConfigurationName(ps, printer, null);
                psv.SetPlotConfigurationName(ps, printer, format);
                psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);
              }
              catch (System.Exception e) {
                e.GetBaseException().ToString();
              }
    
              psv.GetCanonicalMediaNameList(ps);
              pi.OverrideSettings = ps;
    
              PlotInfoValidator piv = new PlotInfoValidator();
              piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
              piv.Validate(pi);
    
              if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting) {
                using (PlotEngine pe = PlotFactory.CreatePublishEngine()) {
                  PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
                  using (ppd) {
                    ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "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;
    
                    ppd.OnBeginPlot();
                    ppd.IsVisible = true;
                    ppd.OnBeginPlot();
                    ppd.IsVisible = true;
                    pe.BeginPlot(ppd, null);
    
                    pe.BeginDocument(pi, doc.Name, null, 1, true, pdfFilePath);
    
                    ppd.OnBeginSheet();
                    ppd.LowerSheetProgressRange = 0;
                    ppd.UpperSheetProgressRange = 100;
                    ppd.SheetProgressPos = 0;
    
                    PlotPageInfo ppi = new PlotPageInfo();
                    pe.BeginPage(ppi, pi, true, null);
                    pe.BeginGenerateGraphics(null);
                    ppd.SheetProgressPos = 50;
                    pe.EndGenerateGraphics(null);
    
                    pe.EndPage(null);
                    ppd.SheetProgressPos = 100;
                    ppd.OnEndSheet();
    
                    pe.EndDocument(null);
    
                    ppd.PlotProgressPos = 100;
                    ppd.OnEndPlot();
    
                    pe.EndPlot(null);
                  }
                }
              }
              else {
                ed.WriteMessage("\nCannot plot. System is busy plotting another one.");
              }
    
              tr.Commit();
            }
          }
          catch (System.Exception e) {
            // Display the error message here.
            System.Windows.Forms.MessageBox.Show(
              e.ToString(),
              "Error",
              System.Windows.Forms.MessageBoxButtons.OK,
              System.Windows.Forms.MessageBoxIcon.Error);
          }
        }
      }
    }
    

     This code was tested with AutoCAD 2012 and seems to work as expected.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.