前几天公司要求按坐标打印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()函数,于是先要把此函数引入我们自己的工程,加入如下代码

  1. public partial class BlockSelectForm : Form
  2. {
  3. [DllImport("acad.exe",
  4. CallingConvention = CallingConvention.Cdecl,
  5. EntryPoint = "acedTrans")
  6. ]
  7. static extern int acedTrans(
  8. double[] point,
  9. IntPtr fromRb,
  10. IntPtr toRb,
  11. int disp,
  12. double[] result
  13. );
  14. ....
  1. private Extents2d Ucs2Dcs(Point3d objStart,Point3d objEnd)
  2.         {
  3.             ResultBuffer rbFrom =
  4.                 new ResultBuffer(new TypedValue(5003, 1)),
  5.                 rbTo =
  6.                 new ResultBuffer(new TypedValue(5003, 2));
  7.  
  8.             double[] firres = new double[] { 0, 0, 0 };
  9.             double[] secres = new double[] { 0, 0, 0 };
  1.             acedTrans(
  2.                 objStart.ToArray(),
  3.                 rbFrom.UnmanagedObject,
  4.                 rbTo.UnmanagedObject,
  5.                 0,
  6.                 firres
  7.             );
  8.  
  9.             acedTrans(
  10.                 objEnd.ToArray(),
  11.                 rbFrom.UnmanagedObject,
  12.                 rbTo.UnmanagedObject,
  13.                 0,
  14.                 secres
  15.             );
  16.  
  17.             Extents2d window =
  18.               new Extents2d(
  19.                 firres[0],
  20.                 firres[1],
  21.                 secres[0],
  22.                 secres[1]
  23.               );
  24.             return window;
  25.         }
  1.  

下面是打印函数代码

  1. private string PrintBMP(Point3d objStart, Point3d objEnd, string strPrintName, string strPaperName, string strStyleName,
  2. string strRotation)
  3. {
  4. // 打开文档数据库
  5. Document acDoc =Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  6. Database acCurDb = acDoc.Database;
  7. Extents2d objPoint = Ucs2Dcs(objStart, objEnd);
  8. string strFileName = string.Empty;
  9.  
  10. using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  11. {
  12. BlockTableRecord btr =
  13. (BlockTableRecord)acTrans.GetObject(
  14. acCurDb.CurrentSpaceId,
  15. OpenMode.ForRead
  16. );
  17.  
  18. Layout acLayout =
  19. (Layout)acTrans.GetObject(
  20. btr.LayoutId,
  21. OpenMode.ForRead
  22. );
  23.  
  24. // Get the PlotInfo from the layout
  25. PlotInfo acPlInfo = new PlotInfo();
  26. acPlInfo.Layout = btr.LayoutId;
  27.  
  28. // Get a copy of the PlotSettings from the layout
  29. PlotSettings acPlSet = new PlotSettings(acLayout.ModelType);
  30. acPlSet.CopyFrom(acLayout);
  31.  
  32. // Update the PlotSettings object
  33. PlotSettingsValidator acPlSetVdr = PlotSettingsValidator.Current;
  34.  
  35. acPlSetVdr.SetPlotWindowArea(acPlSet, objPoint);
  36. // Set the plot type
  37. acPlSetVdr.SetPlotType(acPlSet,
  38. Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
  39.  
  40. // Set the plot scale
  41. acPlSetVdr.SetUseStandardScale(acPlSet, true);
  42. acPlSetVdr.SetStdScaleType(acPlSet, StdScaleType.ScaleToFit);
  43.  
  44. // Center the plot
  45. acPlSetVdr.SetPlotCentered(acPlSet, true);
  46.  
  47. // Set the plot device to use
  48. acPlSetVdr.SetPlotConfigurationName(acPlSet, strPrintName,
  49. strPaperName);
  50.  
  51. acPlSetVdr.RefreshLists(acPlSet);
  52. acPlSetVdr.SetCurrentStyleSheet(acPlSet, strStyleName);
  53.  
  54. switch (strRotation)
  55. {
  56. case "0":
  57. acPlSetVdr.SetPlotRotation(acPlSet,PlotRotation.Degrees000);
  58. break;
  59. case "90":
  60. acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees090);
  61. break;
  62. case "180":
  63. acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees180);
  64. break;
  65. case "270":
  66. acPlSetVdr.SetPlotRotation(acPlSet, PlotRotation.Degrees270);
  67. break;
  68. }
  69.  
  70. // Set the plot info as an override since it will
  71. // not be saved back to the layout
  72. acPlInfo.OverrideSettings = acPlSet;
  73.  
  74. // Validate the plot info
  75. PlotInfoValidator acPlInfoVdr = new PlotInfoValidator();
  76. acPlInfoVdr.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
  77. acPlInfoVdr.Validate(acPlInfo);
  78.  
  79. // Check to see if a plot is already in progress
  80. if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
  81. {
  82. using (PlotEngine acPlEng = PlotFactory.CreatePublishEngine())
  83. {
  84. // Track the plot progress with a Progress dialog
  85. PlotProgressDialog acPlProgDlg = new PlotProgressDialog(false,
  86. 1,
  87. false);
  88.  
  89. using (acPlProgDlg)
  90. {
  91. // Define the status messages to display when plotting starts
  92. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.DialogTitle,
  93. "我们公司名,隐去了");
  94.  
  95. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage,
  96. "Cancel Job");
  97.  
  98. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage,
  99. "Cancel Sheet");
  100.  
  101. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption,
  102. "Sheet Set Progress");
  103.  
  104. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption,
  105. "正在生成" + acDoc.Name);
  106.  
  107. // Set the plot progress range
  108. acPlProgDlg.LowerPlotProgressRange = 0;
  109. acPlProgDlg.UpperPlotProgressRange = 100;
  110. acPlProgDlg.PlotProgressPos = 0;
  111.  
  112. // Display the Progress dialog
  113. acPlProgDlg.OnBeginPlot();
  114. acPlProgDlg.IsVisible = true;
  115.  
  116. // Start to plot the layout
  117. acPlEng.BeginPlot(acPlProgDlg, null);
  118.  
  119. string strTempPath = System.IO.Path.GetTempPath();
  120. strFileName = Path.Combine(strTempPath,
  121. acDoc.Name.Substring(acDoc.Name.LastIndexOf("\\")+1).Replace("dwg","")
  122. + DateTime.Now.ToString("yyyyMMddhhmmssfff") + "Compare" + ".bmp");
  123.  
  124. // Define the plot output
  125. acPlEng.BeginDocument(acPlInfo,
  126. acDoc.Name,
  127. null,
  128. 1,
  129. true,
  130. strFileName);
  131.  
  132. // Display information about the current plot
  133. acPlProgDlg.set_PlotMsgString(PlotMessageIndex.Status,
  134. "Plotting: " + acDoc.Name + " - " +
  135. acLayout.LayoutName);
  136.  
  137. // Set the sheet progress range
  138. acPlProgDlg.OnBeginSheet();
  139. acPlProgDlg.LowerSheetProgressRange = 0;
  140. acPlProgDlg.UpperSheetProgressRange = 100;
  141. acPlProgDlg.SheetProgressPos = 0;
  142.  
  143. // Plot the first sheet/layout
  144. PlotPageInfo acPlPageInfo = new PlotPageInfo();
  145. acPlEng.BeginPage(acPlPageInfo,
  146. acPlInfo,
  147. true,
  148. null);
  149.  
  150. acPlEng.BeginGenerateGraphics(null);
  151. acPlEng.EndGenerateGraphics(null);
  152.  
  153. // Finish plotting the sheet/layout
  154. acPlEng.EndPage(null);
  155. acPlProgDlg.SheetProgressPos = 100;
  156. acPlProgDlg.OnEndSheet();
  157.  
  158. // Finish plotting the document
  159. acPlEng.EndDocument(null);
  160.  
  161. // Finish the plot
  162. acPlProgDlg.PlotProgressPos = 100;
  163. acPlProgDlg.OnEndPlot();
  164. acPlEng.EndPlot(null);
  165. }
  166. }
  167. }
  168. }
  169. return strFileName;
  170. }

先写这么多了,欢迎交流吐槽,

AutoCAD按坐标打印图纸的更多相关文章

  1. 如何在CAD中批量打印图纸?这种方法你要知道

    CAD图纸都是使用CAD制图软件进行设计出来的,图纸的格式均为dwg格式的,不方便进行使用.就需要将图纸进行打印出来.多张CAD图纸如果一张一张进行打印速度就会非常的慢,那就可以使用CAD中的批量打印 ...

  2. CAD打印图纸要怎么操作?简单方法分享给你

    大家日常生活中多多少少的都接触到过CAD文件,CAD图是借助CAD制图软件来进行绘制完成的.唯一的困惑就是CAD图纸的格式大多数均为dwg格式的,查看起来不是那么的方便?所以很多设计师们都会选择将图纸 ...

  3. autocad.net-图片打印合成

    调用打印程序“PublishToWeb JPG.pc3”进行图片打印,该打印驱动程序中内置了很多的打印方案,在同尺寸的打印方案下,数据范围越大打印出来的清晰度就越差,内置的尺寸不一定都满足,在又要通过 ...

  4. Excel控制AutoCad进行坐标标注

    做过工程测绘,平面设计,使用过Autocad制图的朋友们,都经常要在CAD上标注点或者线的坐标,CAD自身的标注功能,并不能同时标注X和Y坐标,,要同时标注X和Y坐标,可以使用南方CASS软件,或者一 ...

  5. AutoCAD如何设置A0A1图纸

    可以从网上下载相应的图纸模板,下载之后可以发现有相应的文字和模板文件   随后我们新建并找到这个dwt文件模板(比如要做一个A1的模板)   随后即可发现模板的样式,包括每种颜色的粗细,颜色和明细栏等 ...

  6. CAD中解决打印图纸模糊而且有的字体深浅不一的方法

    按圈圈中选择打印样式

  7. AutoCAD图形打印出图片 C#

    这几天搞cad二次开发,用的是C#语言,目前在网上找到的资料比较少.弄了两天,才做出怎样实现打印出图片.首先得在AutoCAD软件界面下,设置打印机的页面设置和打印机设备名称一样(以防打印不出来).即 ...

  8. objectARX2010及其以上版本使用publish打印(发布)图纸,后台布局打印图纸例子浅析

    AutoCAD 2010版本开始新增了一个发布图纸的功能,可以后台打印图纸,以下是ADN官方博客例子浅析 原文地址 https://adndevblog.typepad.com/autocad/201 ...

  9. 用Python来控制Autocad的打印------以Pycomcad为例

    from pycomcad import * #以pycomcad作为接口库为例 import win32com acad=Autocad() 打印最重要的设置都在上面的界面中,下面对这些个界面,用P ...

随机推荐

  1. 动态定义数组 .xml

    pre{ line-height:1; color:#3c3c3c; background-color:#d2c39b; font-size:16px;}.sysFunc{color:#627cf6; ...

  2. erase() 返回的是删除此元素之后的下一个元素的迭代器 .xml

    pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...

  3. 插入排序 --- 排序算法 --- 算法 --- java

    设数组为a[0…n-1]. 1.      初始时,a[0]自成1个有序区,无序区为a[1..n-1].令i=1 2.      将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间 ...

  4. DOM笔记(八):JavaScript执行环境和垃圾收集

    一.执行环境 在有关于JavaScript对象或者this的指向问题时,脱离不了的另外一个概念就是执行环境,即上下文环境.执行环境在JavaScript是一个 很重要的概念,因为它定义了变量或函数有权 ...

  5. BITED-Windows8应用开发学习札记之三:如何在Win8应用中实现数据绑定

    在微软官方提供的资源中,我们可以看到SampleDataSource.cs已经拥有了定义好了相应的数据结构以及实现类: 建立本地数据 由于我们已经有数据以及相应的数据类,我们需要做的仅仅是将数据放进数 ...

  6. Home vs2013

        Microsoft Visual Studio Ultimate 2013 版本 12.0.30110.00 Update 1 Microsoft .NET Framework 版本 4.5. ...

  7. MVC中过虑特殊字符检测

    [ValidateInput(false)] [HttpPost] public ActionResult Modify(Models.BlogArticle model) { //...... } ...

  8. jQuery Callback 函数

    @(编程) Callback 函数在当前动画 100% 完成之后执行. jQuery 动画的问题 许多 jQuery 函数涉及动画.这些函数也许会将 speed 或 duration 作为可选参数. ...

  9. Win7系统下利用U盘安装Ubuntu14.04麒麟版

    转自http://www.360doc.cn/article/14743053_335473181.html 重要提示:在采用u盘安装ubuntu分区时,所有磁盘一定要全部设置成逻辑分区,包括根目录/ ...

  10. 帮你选处理器:CPU T9500-p9500-T9400-T9300-p8700对比分析!

    许多人对处理器是P和T开头含混不清,不甚了解,也怪英特尔的处理器型号实在是太过复杂.这需要具体型号来看的.让我们先来看看英特尔的官方解释吧 T: Mobile Highly Performance-- ...