.NET

.NET

Reply
Valued Contributor
spanqy
Posts: 90
Registered: ‎11-13-2006
Message 1 of 12 (792 Views)
Accepted Solution

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

792 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?

ADN Support Specialist
Balaji_Ram
Posts: 692
Registered: ‎03-21-2011
Message 2 of 12 (753 Views)

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

Valued Contributor
spanqy
Posts: 90
Registered: ‎11-13-2006
Message 3 of 12 (738 Views)

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

Moderator
Alexander.Rivilis
Posts: 1,406
Registered: ‎04-09-2008
Message 4 of 12 (729 Views)

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

Valued Contributor
spanqy
Posts: 90
Registered: ‎11-13-2006
Message 5 of 12 (725 Views)

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

Valued Contributor
spanqy
Posts: 90
Registered: ‎11-13-2006
Message 6 of 12 (722 Views)

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!

ADN Support Specialist
Balaji_Ram
Posts: 692
Registered: ‎03-21-2011
Message 7 of 12 (711 Views)

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

Moderator
Alexander.Rivilis
Posts: 1,406
Registered: ‎04-09-2008
Message 8 of 12 (706 Views)

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

Valued Contributor
spanqy
Posts: 90
Registered: ‎11-13-2006
Message 9 of 12 (683 Views)

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.

 

 

Moderator
Alexander.Rivilis
Posts: 1,406
Registered: ‎04-09-2008
Message 10 of 12 (662 Views)

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

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.