Тема: Автоматизация печати в pdf AutoCAD C#
День добрый!
Словил интереснейший баг в процессе написания автоматизатора печати для AutoCad.
Идея такая - на чертеже на разных листах раскиданы динамические блоки - ГОСТовские рамки чертежа. Надо всё, что внутри рамочек, вывести постранично в PDF. Когда решал, как делать, показалось логичным распечатать каждую рамку, используя встроенный принтер "DWG To PDF.pc3". Тут-то и начались проблемы.
Беда в том, чертёж, на котором я тестирую, содержит три листа и суммарно 24 рамки на них. А получившаяся PDFка - три страницы, на каждой из которых выведен только один последний блок с каждого из листов. Никак не могу понять, что именно я делаю не так. Факт в том, что находит он все 24 рамки.
При создании кода пользовался примерами отсюда - http://through-the-interface.typepad.co … /plotting/
Буду благодарен любому совету/помощи. Идеи, в чём беда, у меня закончились =(
Вот код:
<code>using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Internal.Reactors;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Runtime;
using ACAD = Autodesk.AutoCAD.ApplicationServices.Application;
using ED = Autodesk.AutoCAD.EditorInput.Editor;
using ACADExtension;
namespace Plot2PDF
{
public class Program : IExtensionApplication
{
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
static extern int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
List<string> msgs = new List<string>();
public class GostBlk
{
public BlockReference BlockRef;
public Layout LayoutRef;
}
public void Terminate()
{
ApplicationEventManager cadWinEvnts = Autodesk.AutoCAD.Internal.Reactors.ApplicationEventManager.Instance();
//Form.Close();
msgs.Sort();
ED ed = ACAD.DocumentManager.MdiActiveDocument.Editor;
foreach (string msg in msgs)
{
ed.WriteMessage(msg);
}
}
public void Initialize()
{
}
static void GetGostStampCollection(Database db, Editor ed, Transaction tr, ref List<GostBlk> GostCol, ref List<Layout> LayList)
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId btrId in bt)
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
if (btr.IsLayout)
{
Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
if (!LayList.Contains(lo)) LayList.Add(lo);
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(lo.BlockTableRecordId, OpenMode.ForRead);
foreach (ObjectId objId in ms)
{
Entity ent = (Entity)tr.GetObject(objId, OpenMode.ForRead);
if (!ent.GetType().ToString().Contains("BlockReference")) continue;
BlockReference blk = (BlockReference)ent;
string Effn = ACADExtension.ACADExt.EffectiveName(blk);
if (!Effn.ToUpper().Contains("SHEETGOST")) continue;
GostBlk theBlk = new GostBlk();
theBlk.BlockRef = blk;
theBlk.LayoutRef = lo;
GostCol.Add(theBlk);
}
}
}
}
[CommandMethod("PlotToPdf")]
static public void MultiSheetPlot()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
List<GostBlk> BlocksToPlot = new List<GostBlk>();
List<Layout> LayList = new List<Layout>();
GetGostStampCollection(db, ed, tr, ref BlocksToPlot, ref LayList);
ed.WriteMessage("\nThe number of GOST stamps found: " + BlocksToPlot.Count + "\n\n");
if (BlocksToPlot.Count < 1) return;
if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
{
PlotEngine pe = PlotFactory.CreatePublishEngine();
using (pe)
{
PlotProgressDialog ppd = new PlotProgressDialog(false, BlocksToPlot.Count, true);
using (ppd)
{
int 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;
ppd.OnBeginPlot();
ppd.IsVisible = true;
pe.BeginPlot(ppd, null);
foreach (GostBlk gblk in BlocksToPlot)
{
ppd.StatusMsgString = "Plotting block " + numSheet.ToString() + " of " + BlocksToPlot.Count.ToString();
ppd.OnBeginSheet();
ppd.LowerSheetProgressRange = 0;
ppd.UpperSheetProgressRange = 100;
ppd.SheetProgressPos = 0;
PlotInfoValidator piv = new PlotInfoValidator();
piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
PlotPageInfo ppi = new PlotPageInfo();
PlotInfo pi = new PlotInfo();
BlockReference blk = gblk.BlockRef;
Layout lo = gblk.LayoutRef;
Extents3d ext = (Extents3d)blk.Bounds;
Point3d first = ext.MaxPoint;
Point3d second = ext.MinPoint;
ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 1)), rbTo = new ResultBuffer(new TypedValue(5003, 2));
double[] firres = new double[] { 0, 0, 0 };
double[] secres = new double[] { 0, 0, 0 };
acedTrans(first.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, firres);
acedTrans(second.ToArray(), rbFrom.UnmanagedObject, rbTo.UnmanagedObject, 0, secres);
Extents2d window = new Extents2d(firres[0], firres[1], secres[0], secres[1]);
// We need a PlotSettings object based on the layout settings which we then customize
PlotSettings ps = new PlotSettings(lo.ModelType);
LayoutManager.Current.CurrentLayout = lo.LayoutName;
pi.Layout = lo.Id;
ps.CopyFrom(lo);
// The PlotSettingsValidator helps create a valid PlotSettings object
PlotSettingsValidator psv = PlotSettingsValidator.Current;
psv.SetPlotWindowArea(ps, window);
psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
psv.SetUseStandardScale(ps, true);
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
psv.SetPlotCentered(ps, true); //StdScaleType.StdScale1To1
psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", "ISO_A3_(297.00_x_420.00_MM)");
pi.OverrideSettings = ps;
piv.Validate(pi);
if (numSheet == 1)
{
pe.BeginDocument(pi, doc.Name, null, 1, true, "c:\\multiblock");
}
pe.BeginPage(ppi, pi, (numSheet == BlocksToPlot.Count), null);
pe.BeginGenerateGraphics(null);
ppd.SheetProgressPos = 50;
pe.EndGenerateGraphics(null);
// Finish the sheet
pe.EndPage(null);
ppd.SheetProgressPos = 100;
ppd.PlotProgressPos += Convert.ToInt32(100 / BlocksToPlot.Count);
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.");
}
}
}
}
}</code>