您的位置:首页 > 其它

AutoCAD按坐标打印图纸

2013-10-29 22:23 344 查看
前几天公司要求按坐标打印DWG文件,中间走了不少弯路,好在已经搞定了,整理一下分享给大家,希望后来人少走弯路。

1. 设计需求:

公司的图纸用AutoCAD2010做成,通常一个项目的所有图纸都存放在一个DWG文件内,根据具体的子项不同,放在不同的块引用里,我要做的是找到每一个块引用,并把他打印到bmp文件里。

2.实现思路:

利用AutoCAD的.net API,找到符合条件的快引用,得到块引用左下角和右上角的点的坐标,把两点坐标框选的矩形区域发给打印机打印

3.遇到的问题

有的图纸打印没有问题,有的图纸打印出一张空白图。

4.解决问题(在这里向业界大牛Kean同志表示强烈的感谢,感谢他无私的帮助)

之所以有些图纸打印出白图是因为坐标体系的问题,AutoCAD中有很多种坐标体系,例如UCS世界坐标,DCS显示设备坐标,UCS用户坐标等等,除了UCS坐标其他各坐标体系都是UCS坐标推衍而来,UCS坐标是永远不变的。.net API取出的块引用坐标是UCS,而要向打印机输出坐标打印命令需要用DCS坐标。也就是说不把UCS转换为DCS,图纸就会打印出白图,碰巧打印出来的是因为UCS和DCS重合。

很遗憾,AutoCAD .net API并没有转换坐标的函数,幸运的是ObjectARX 中有acedTrans()函数,于是先要把此函数引入我们自己的工程,加入如下代码

public partial class BlockSelectForm : Form
{
[DllImport("acad.exe",
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "acedTrans")
]
static extern int acedTrans(
double[] point,
IntPtr fromRb,
IntPtr toRb,
int disp,
double[] result
);
....

private Extents2d Ucs2Dcs(Point3d objStart,Point3d objEnd)
{
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(
objStart.ToArray(),
rbFrom.UnmanagedObject,
rbTo.UnmanagedObject,
0,
firres
);

acedTrans(
objEnd.ToArray(),
rbFrom.UnmanagedObject,
rbTo.UnmanagedObject,
0,
secres
);

Extents2d window =
new Extents2d(
firres[0],
firres[1],
secres[0],
secres[1]
);
return window;
}


下面是打印函数代码

private string PrintBMP(Point3d objStart, Point3d objEnd, string strPrintName, string strPaperName, string strStyleName,
string strRotation)
{
// 打开文档数据库
Document acDoc =Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
Extents2d objPoint = Ucs2Dcs(objStart, objEnd);
string strFileName = string.Empty;

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
BlockTableRecord btr =
(BlockTableRecord)acTrans.GetObject(
acCurDb.CurrentSpaceId,
OpenMode.ForRead
);

Layout acLayout =
(Layout)acTrans.GetObject(
btr.LayoutId,
OpenMode.ForRead
);

// Get the PlotInfo from the layout
PlotInfo acPlInfo = new PlotInfo();
acPlInfo.Layout = btr.LayoutId;

// Get a copy of the PlotSettings from the layout
PlotSettings acPlSet = new PlotSettings(acLayout.ModelType);
acPlSet.CopyFrom(acLayout);

// Update the PlotSettings object
PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;

acPlSetVdr.SetPlotWindowArea(acPlSet, objPoint);
// Set the plot type
acPlSetVdr.SetPlotType(acPlSet,
Autodesk.AutoCAD.DatabaseServices.PlotType.Window);

// Set the plot scale
acPlSetVdr.SetUseStandardScale(acPlSet, true);
acPlSetVdr.SetStdScaleType(acPlSet, StdScaleType.ScaleToFit);

// Center the plot
acPlSetVdr.SetPlotCentered(acPlSet, true);

// Set the plot device to use
acPlSetVdr.SetPlotConfigurationName(acPlSet, strPrintName,
strPaperName);

acPlSetVdr.RefreshLists(acPlSet);
acPlSetVdr.SetCurrentStyleSheet(acPlSet, strStyleName);

switch (strRotation)
{
case "0":
acPlSetVdr.SetPlotRotation(acPlSet,PlotRotation.Degrees000);
break;
case "90":
acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees090);
break;
case "180":
acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees180);
break;
case "270":
acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees270);
break;
}

// Set the plot info as an override since it will
// not be saved back to the layout
acPlInfo.OverrideSettings = acPlSet;

// Validate the plot info
PlotInfoValidator acPlInfoVdr = new PlotInfoValidator();
acPlInfoVdr.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
acPlInfoVdr.Validate(acPlInfo);

// Check to see if a plot is already in progress
if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
{
using (PlotEngine acPlEng = PlotFactory.CreatePublishEngine())
{
// Track the plot progress with a Progress dialog
PlotProgressDialog acPlProgDlg = new PlotProgressDialog(false,
1,
false);

using (acPlProgDlg)
{
// Define the status messages to display when plotting starts
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.DialogTitle,
"我们公司名,隐去了");

acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage,
"Cancel Job");

acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage,
"Cancel Sheet");

acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption,
"Sheet Set Progress");

acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption,
"正在生成" + acDoc.Name);

// Set the plot progress range
acPlProgDlg.LowerPlotProgressRange = 0;
acPlProgDlg.UpperPlotProgressRange = 100;
acPlProgDlg.PlotProgressPos = 0;

// Display the Progress dialog
acPlProgDlg.OnBeginPlot();
acPlProgDlg.IsVisible = true;

// Start to plot the layout
acPlEng.BeginPlot(acPlProgDlg, null);

string strTempPath = System.IO.Path.GetTempPath();
strFileName = Path.Combine(strTempPath,
acDoc.Name.Substring(acDoc.Name.LastIndexOf("\\")+1).Replace("dwg","")
+ DateTime.Now.ToString("yyyyMMddhhmmssfff") + "Compare" + ".bmp");

// Define the plot output
acPlEng.BeginDocument(acPlInfo,
acDoc.Name,
null,
1,
true,
strFileName);

// Display information about the current plot
acPlProgDlg.set_PlotMsgString(PlotMessageIndex.Status,
"Plotting: " + acDoc.Name + " - " +
acLayout.LayoutName);

// Set the sheet progress range
acPlProgDlg.OnBeginSheet();
acPlProgDlg.LowerSheetProgressRange = 0;
acPlProgDlg.UpperSheetProgressRange = 100;
acPlProgDlg.SheetProgressPos = 0;

// Plot the first sheet/layout
PlotPageInfo acPlPageInfo = new PlotPageInfo();
acPlEng.BeginPage(acPlPageInfo,
acPlInfo,
true,
null);

acPlEng.BeginGenerateGraphics(null);
acPlEng.EndGenerateGraphics(null);

// Finish plotting the sheet/layout
acPlEng.EndPage(null);
acPlProgDlg.SheetProgressPos = 100;
acPlProgDlg.OnEndSheet();

// Finish plotting the document
acPlEng.EndDocument(null);

// Finish the plot
acPlProgDlg.PlotProgressPos = 100;
acPlProgDlg.OnEndPlot();
acPlEng.EndPlot(null);
}
}
}
}
return strFileName;
}

先写这么多了,欢迎交流吐槽,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: