using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections.Generic;
namespace Plot1
{
public class Commands : IExtensionApplication
{
[DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
static extern int acedTrans13(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
static extern int acedTrans12(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result);
static int acedTrans(double[] point, IntPtr fromRb, IntPtr toRb, int disp, double[] result)
{
return Autodesk.AutoCAD.ApplicationServices.Application.Version.Major > 12 ?
acedTrans13(point, fromRb, toRb, disp, result) :
acedTrans12(point, fromRb, toRb, disp, result);
}
[CommandMethod("PlotPDF", CommandFlags.Session)]
public void PlotPDF()
{
string line = @"D:\autocad\qq.dwg";
short bgp = (short)Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("BACKGROUNDPLOT");
Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0);
Document curDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(line, false);
if (curDoc != doc)
{
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument = doc;
}
using (DocumentLock docLock = doc.LockDocument())
{
Database db = doc.Database;
// A PlotEngine does the actual plotting
// (can also create one for Preview)
if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
{
PlotEngine pe = PlotFactory.CreatePublishEngine();
using (pe)
{
using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// 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()) || (btr.IsLayout && btr.Name.ToUpper() == BlockTableRecord.ModelSpace.ToUpper()))
{
layoutsToPlot.Add(btr.LayoutId);
}
}
SortWithTabOrder(ref layoutsToPlot);
// Create a Progress Dialog to provide info
// and allow the user to cancel
PlotProgressDialog ppd = new PlotProgressDialog(false, layoutsToPlot.Count, true);
using (ppd)
{
int numSheet = 1;
foreach (ObjectId layoutId in layoutsToPlot)
{
PlotInfo pi = new PlotInfo();
PlotInfoValidator piv = new PlotInfoValidator();
piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
Layout lo = (Layout)tr.GetObject(layoutId, OpenMode.ForRead);
// Make the layout we're plotting current
LayoutManager.Current.SetCurrentLayoutId(lo.ObjectId);
// 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;//текущий доk
// 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);
PlotRotation Rot = PlotRotation.Degrees000;
if ((lo.Limits.MaxPoint.X < lo.Limits.MaxPoint.Y))
{
Rot = PlotRotation.Degrees090;
}
psv.SetPlotRotation(ps, Rot);
// We'll use the standard DWFx PC3, as
// this supports multiple sheets
psv.SetPlotConfigurationName(ps, "DWG To PDF.pc3", null);
psv.RefreshLists(ps);
// We need a PlotInfo object
// linked to the layout
pi.Layout = lo.Id;
// 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, "Обработка документа");
ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "Отмена");
ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "Отмена листа");
ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Обработка слоёв");
ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Обработка листа");
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, "d:\\test-multi-sheet");
}
// Which may contain multiple sheets
ppd.StatusMsgString = "Обработка " + doc.Name.Substring(doc.Name.LastIndexOf("\\") + 1) + " - страница " + numSheet.ToString() + " из " + 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);
}
tr.Commit();
}
}
}
else
{
MessageBox.Show("Принтер занят");
}
}
Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
if (curDoc != doc)
{
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument = curDoc;
doc.CloseAndDiscard();
}
}
/// <summary>
/// Сортируем листы в том порядке, в котором они в AutoCAD
/// </summary>
/// <param name="ids"></param>
void SortWithTabOrder(ref ObjectIdCollection ids)
{
if (ids.Count == 0) return;
SortedDictionary<int, ObjectId> tab = new SortedDictionary<int, ObjectId>();
using (Transaction tr = ids[0].Database.TransactionManager.StartTransaction())
{
foreach (ObjectId id in ids)
{
Layout layout = tr.GetObject(id, OpenMode.ForRead) as Layout;
tab[layout.TabOrder] = id;
}
tr.Commit();
}
ids.Clear();
foreach (KeyValuePair<int, ObjectId> pair in tab)
{
ids.Add(pair.Value);
}
}
public void Initialize() { }
public void Terminate() { }
}
}