您的位置:首页 > 其它

Driving a basic AutoCAD plot using .NET

2007-10-15 14:00 357 查看
I just missed my connecting flight in Chicago, so have 3 hours to pass until the next, and decided to post some code I finally got around to writing on the plane from Zurich.
I've had a few requests for code showing how to plot using the .NET API in AutoCAD. There's an existing ObjectARX (C++) sample on the SDK, under samples/editor/AsdkPlotAPI, but there isn't a publicly posted .NET version right now.

Here's the C# code I put together. Please bear in mind that it was written during less than ideal coding conditions, and I haven't spent a substantial amount of time going through it... it seems to work fine for me, but do post a comment if you have trouble with it.

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.PlottingServices;

namespace PlottingApplication
{
public class PlottingCommands
{
[CommandMethod("simplot")]
static public void SimplePlot()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;

Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
// We'll be plotting the current layout

BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForRead
);
Layout lo =
(Layout)tr.GetObject(
btr.LayoutId,
OpenMode.ForRead
);

// We need a PlotInfo object
// linked to the layout

PlotInfo pi = new PlotInfo();
pi.Layout = btr.LayoutId;

// 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 DWF PC3, as
// for today we're just plotting to file

psv.SetPlotConfigurationName(
ps,
"DWF6 ePlot.pc3",
"ANSI_A_(8.50_x_11.00_Inches)"
);

// We need to link the PlotInfo to the
// PlotSettings and then validate it

pi.OverrideSettings = ps;
PlotInfoValidator piv =
new PlotInfoValidator();
piv.MediaMatchingPolicy =
MatchingPolicy.MatchEnabled;
piv.Validate(pi);

// A PlotEngine does the actual plotting
// (can also create one for Preview)

if (PlotFactory.ProcessPlotState ==
ProcessPlotState.NotPlotting)
{
PlotEngine pe =
PlotFactory.CreatePublishEngine();
using (pe)
{
// Create a Progress Dialog to provide info
// and allow thej user to cancel

PlotProgressDialog ppd =
new PlotProgressDialog(false, 1, true);
using (ppd)
{
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-output"
);

// Which contains a single sheet

ppd.OnBeginSheet();

ppd.LowerSheetProgressRange = 0;
ppd.UpperSheetProgressRange = 100;
ppd.SheetProgressPos = 0;

PlotPageInfo ppi = new PlotPageInfo();
pe.BeginPage(
ppi,
pi,
true,
null
);
pe.BeginGenerateGraphics(null);
pe.EndGenerateGraphics(null);

// Finish the sheet
pe.EndPage(null);
ppd.SheetProgressPos = 100;
ppd.OnEndSheet();

// 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."
);
}
}
}
}
}

A few comments on the code: I chose to plot to a file using the standard DWF plot driver/PC3 file, mainly as it avoids having to second-guess what printers/plotters everyone uses. :-) The SDK sample populates comboboxes in a dialog to allow selection of the device and the media size, but I've just gone with a choice that should work on all systems.

Here's what you should see when you launch the SIMPLOT command:





The output file should be created in "c:/test-output.dwf".

I added a simple check to fail gracefully when another plot is in progress... as this code will drive either a foreground or a background plot (depending on the value of the BACKGROUNDPLOT system variable), there's clear scope for failure if the code doesn't check via PlotFactory.ProcessPlotState (or handle the exception if another plot is already happening when you call PlotFactory.CreatePublishEngine()).

Now that I'm online I've found there's quite a similar code sample to the ADN site (also converted from the original SDK sample, I suspect):

How to plot using AutoCAD's .NET Managed API?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: