找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 366|回复: 0

[每日一码] 转换ADT到ACAD

[复制链接]

已领礼包: 6个

财富等级: 恭喜发财

发表于 2021-1-20 21:06:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
  1. using System;
  2. using System.Security;
  3. using System.Runtime.InteropServices;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. using System.IO;
  8. using System.Diagnostics;
  9. using System.Globalization;
  10. using System.Windows.Forms;

  11. using Autodesk.AutoCAD.ApplicationServices;
  12. using Autodesk.AutoCAD.Runtime;
  13. using Autodesk.AutoCAD.Geometry;
  14. using Autodesk.AutoCAD.DatabaseServices;
  15. using Autodesk.AutoCAD.EditorInput;
  16. using Autodesk.AutoCAD.Colors;
  17. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  18. using System.Text;

  19. [assembly: CommandClass(typeof(DwgConversion.ConvertClass))]

  20. namespace DwgConversion
  21. {
  22.     /// <summary>
  23.     /// Summary description for ConvertClass.
  24.     /// </summary>
  25.     public class ConvertClass
  26.     {
  27.         public ConvertClass()
  28.         {
  29.             //
  30.             // TODO: Add constructor logic here
  31.             //
  32.         }

  33.         // constants variables
  34.         const int RTNORM = 5100;
  35.         const int RTCAN = -5002;
  36.         const short RTSTR = 5005;
  37.         const string prefixConvert = "CONVERTED-";
  38.         const string prefixAcad = "ACAD-";
  39.         const string prefixBackup = "BACKUP-";
  40.         const string layerPlan = "0-PLAN";
  41.         const string layerDash = "0-DASH";
  42.         const string layerText = "0-TEXT";
  43.         const short layerPlanColorIndex = 7;
  44.         const short layerDashColorIndex = 6;
  45.         const short layerTextColorIndex = 2;
  46.         const string layerDashLineTypeName = "Hidden";

  47.         [SuppressUnmanagedCodeSecurity]
  48.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  49.         extern static int acedCmd(IntPtr resbuf);

  50.         // not used
  51.         //[DllImport("acdb17.dll", EntryPoint = "?acdbSaveAs2000@@YA?AW4ErrorStatus@Acad@@PAVAcDbDatabase@@PB_W@Z", CharSet = CharSet.Auto)]
  52.         //static extern bool acdbSaveAs2000(IntPtr pDb, string fileName);
  53.         //public static void SaveDatabaseAs2000(Database db, string fileName)
  54.         //{
  55.         //    acdbSaveAs2000(db.UnmanagedObject, fileName);
  56.         //}

  57.         [DllImport("user32.dll")]
  58.         public static extern System.IntPtr SetFocus(System.IntPtr hwnd);


  59.         static public void insertDWG(string dwgPath)
  60.         {
  61.             Database db = HostApplicationServices.WorkingDatabase;
  62.             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  63.             Editor ed = doc.Editor;
  64.             using (Transaction tr = db.TransactionManager.StartTransaction())
  65.             {
  66.                 try
  67.                 {
  68.                     string dwgName = HostApplicationServices.Current.FindFile(dwgPath, db, FindFileHint.Default);
  69.                     Database insertDB = new Database(false, false);
  70.                     insertDB.ReadDwgFile(dwgName, System.IO.FileShare.Read, true, "");
  71.                     ObjectId BlkId = db.Insert(dwgName, insertDB, false);
  72.                     insertDB.Dispose();
  73.                     BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;
  74.                     BlockReference bref = new BlockReference(new Point3d(0, 0, 0), BlkId);
  75.                     btr.AppendEntity(bref);
  76.                     tr.AddNewlyCreatedDBObject(bref, true);
  77.                     bref.ExplodeToOwnerSpace();
  78.                     bref.Erase();
  79.                     tr.Commit();
  80.                 }
  81.                 catch {}
  82.             }
  83.         }

  84.         static public void createNewLayer(string layerName, short colorIndex, string linetypeName)
  85.         {
  86.             Database db = HostApplicationServices.WorkingDatabase;
  87.             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  88.             Editor ed = doc.Editor;
  89.             using (Transaction tr = db.TransactionManager.StartTransaction())
  90.             {
  91.                 LayerTable LT = tr.GetObject(db.LayerTableId, OpenMode.ForWrite, false) as LayerTable;
  92.                 if (!LT.Has(layerName))
  93.                 {
  94.                     LayerTableRecord LTRec = new LayerTableRecord();
  95.                     LTRec.Name = layerName;
  96.                     LT.Add(LTRec);
  97.                     tr.AddNewlyCreatedDBObject(LTRec, true);

  98.                     LTRec.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByLayer, colorIndex);
  99.                     LinetypeTable tbl = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead, false) as LinetypeTable;

  100.                     if (!tbl.Has(linetypeName))
  101.                         db.LoadLineTypeFile(linetypeName, "acad.lin");

  102.                     ObjectId LineTypeId = tbl[linetypeName];
  103.                     if (LineTypeId.IsNull)
  104.                         LineTypeId = db.ContinuousLinetype;
  105.                     LTRec.LinetypeObjectId = LineTypeId;
  106.                 }
  107.                 tr.Commit();
  108.             }
  109.         }

  110.         static public void createNewLayer(string layerName, short colorIndex)
  111.         {
  112.             Database db = HostApplicationServices.WorkingDatabase;
  113.             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  114.             Editor ed = doc.Editor;
  115.             using (Transaction tr = db.TransactionManager.StartTransaction())
  116.             {
  117.                 LayerTable LT = tr.GetObject(db.LayerTableId, OpenMode.ForWrite, false) as LayerTable;
  118.                 if (!LT.Has(layerName))
  119.                 {
  120.                     LayerTableRecord LTRec = new LayerTableRecord();
  121.                     LTRec.Name = layerName;
  122.                     LT.Add(LTRec);
  123.                     tr.AddNewlyCreatedDBObject(LTRec, true);
  124.                     LTRec.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByLayer, colorIndex);
  125.                 }
  126.                 tr.Commit();
  127.             }
  128.         }


  129.         [CommandMethod("DWGCONVERT")]
  130.         static public void dwgconvert()
  131.         {
  132.             Database db = HostApplicationServices.WorkingDatabase;
  133.             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  134.             Editor ed = doc.Editor;

  135.             string dwgname = (string)AcadApp.GetSystemVariable("DWGNAME");
  136.             string dwgprefix = (string)AcadApp.GetSystemVariable("DWGPREFIX");

  137.             // backup the original drawing
  138.             System.IO.File.Copy(doc.Name, dwgprefix + prefixBackup + dwgname, true);

  139.             // drawing converted name
  140.             string dwgConvertName = prefixAcad + dwgname;

  141.             ResultBuffer cmdlist = new ResultBuffer();
  142.             cmdlist.Add(new TypedValue(RTSTR, "_.-EXPORTTOAUTOCAD"));
  143.             cmdlist.Add(new TypedValue(RTSTR, "_Format"));
  144.             cmdlist.Add(new TypedValue(RTSTR, "2000"));
  145.             cmdlist.Add(new TypedValue(RTSTR, "_Type"));
  146.             cmdlist.Add(new TypedValue(RTSTR, "_Insert"));
  147.             cmdlist.Add(new TypedValue(RTSTR, "_Prefix"));
  148.             cmdlist.Add(new TypedValue(RTSTR, prefixAcad));
  149.             cmdlist.Add(new TypedValue(RTSTR, ""));
  150.             cmdlist.Add(new TypedValue(RTSTR, ""));
  151.             cmdlist.Add(new TypedValue(RTSTR, "_.ERASE"));
  152.             cmdlist.Add(new TypedValue(RTSTR, "ALL"));
  153.             cmdlist.Add(new TypedValue(RTSTR, ""));

  154.             // current system variables status
  155.             object o_cmdecho = AcadApp.GetSystemVariable("CMDECHO");
  156.             object o_textstyle = AcadApp.GetSystemVariable("TEXTSTYLE");
  157.             AcadApp.SetSystemVariable("CMDECHO", (object)0);

  158.             int status = acedCmd(cmdlist.UnmanagedObject);

  159.             // insert the converted drawing
  160.             insertDWG(dwgprefix + dwgConvertName);

  161.             // erase the ACAD- auxiliary drawing
  162.             System.IO.File.Delete(dwgprefix + dwgConvertName);

  163.             // start applying the standards
  164.             TypedValue[] filterValue; SelectionFilter filter; PromptSelectionResult res;

  165.             // select all the insert items if any
  166.             filterValue = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "INSERT") };
  167.             filter = new SelectionFilter(filterValue);
  168.             res = ed.SelectAll(filter);
  169.             if (res.Status == PromptStatus.OK && res.Value.Count > 0)
  170.             {
  171.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  172.                 {
  173.                     // open the block table record to add the exploded parts
  174.                     BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;

  175.                     // create layers
  176.                     createNewLayer(layerPlan, layerPlanColorIndex);
  177.                     createNewLayer(layerDash, layerDashColorIndex, layerDashLineTypeName);
  178.                     createNewLayer(layerText, layerTextColorIndex);

  179.                     foreach (ObjectId id in res.Value.GetObjectIds())
  180.                     {
  181.                         BlockReference blk = tr.GetObject(id, OpenMode.ForWrite, false) as BlockReference;
  182.                         if (blk != null)
  183.                         {
  184.                             DBObjectCollection entitySet = new DBObjectCollection();
  185.                             blk.Explode(entitySet);
  186.                             blk.Erase(); // get rid of the block
  187.                             blk.Dispose();

  188.                             // the main blocks were exploded append them to the drawing
  189.                             foreach (Entity entity in entitySet)
  190.                             {
  191.                                 btr.AppendEntity(entity);
  192.                                 tr.AddNewlyCreatedDBObject(entity, true);
  193.                             }

  194.                             // new entities - convert them to the right layer
  195.                             foreach (Entity entity in entitySet)
  196.                             {
  197.                                 // sort the entities and apply the layer changes
  198.                                 if (entity.Linetype.ToUpper().Equals("CONTINUOUS"))
  199.                                     entity.Layer = layerPlan;
  200.                                 else if (!entity.GetType().Name.Contains("Dimension") || !entity.GetType().Name.Contains("Hatch"))
  201.                                     entity.Layer = layerDash;
  202.                                 if (entity.GetType().Name == "DBText" || entity.GetType().Name == "MText")
  203.                                     entity.Layer = layerText;

  204.                                 // start sorting block references
  205.                                 if (entity.GetType().Name == "BlockReference")
  206.                                 {
  207.                                     // first if nested blocks are found extract their
  208.                                     // attributes and convert them to text entities
  209.                                     BlockReference block = entity as BlockReference; // entity is a block do the cast
  210.                                     Autodesk.AutoCAD.DatabaseServices.AttributeCollection attributes = block.AttributeCollection;
  211.                                     if (attributes.Count != 0)
  212.                                     {
  213.                                         foreach (ObjectId objid in attributes)
  214.                                         {
  215.                                             AttributeReference att = tr.GetObject(objid, OpenMode.ForWrite, false) as AttributeReference;
  216.                                             try
  217.                                             {
  218.                                                 ObjectId txtid = att.TextStyle;
  219.                                                 TextStyleTableRecord textStyle = tr.GetObject(txtid, OpenMode.ForRead, false) as TextStyleTableRecord;

  220.                                                 object textstylename = textStyle.Name;
  221.                                                 AcadApp.SetSystemVariable("TEXTSTYLE", textstylename);
  222.                                             }
  223.                                             catch {}

  224.                                             DBText text = new DBText();
  225.                                             text.Position = att.Position;
  226.                                             text.TextString = att.TextString;
  227.                                             text.Height = att.Height;
  228.                                             text.WidthFactor = att.WidthFactor;
  229.                                             text.Layer = layerText;
  230.                                             btr.AppendEntity(text);
  231.                                             tr.AddNewlyCreatedDBObject(text, true);
  232.                                         }
  233.                                     }

  234.                                     // explode the block and pass the non attributes
  235.                                     // to the standards and erase the att def's
  236.                                     DBObjectCollection entitySet1 = new DBObjectCollection();
  237.                                     block.Explode(entitySet1);
  238.                                     block.Erase(); // get rid of the block
  239.                                     block.Dispose();
  240.                                     foreach (Entity entity1 in entitySet1) // append the exploded entities to the drawing
  241.                                     {
  242.                                         if (entity1.GetType().Name == "AttributeDefinition") // ignore att def's
  243.                                             continue; // it is an att def move to the next item

  244.                                         // add the exploded entities to the drawing
  245.                                         btr.AppendEntity(entity1);
  246.                                         tr.AddNewlyCreatedDBObject(entity1, true);

  247.                                         // sort the entities and do the layer changes
  248.                                         if (entity1.Linetype.ToUpper().Equals("CONTINUOUS"))
  249.                                             entity1.Layer = layerPlan;
  250.                                         else if (!entity1.GetType().Name.Contains("Dimension") || !entity1.GetType().Name.Contains("Hatch"))
  251.                                             entity1.Layer = layerDash;
  252.                                     }
  253.                                     entitySet1.Clear();
  254.                                 }
  255.                             }
  256.                             entitySet.Clear();
  257.                         }
  258.                     }
  259.                     tr.Commit();
  260.                 }
  261.             }

  262.             // erase dimensions and hatch's
  263.             filterValue = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "DIMENSION,HATCH") };
  264.             filter = new SelectionFilter(filterValue);
  265.             res = ed.SelectAll(filter);
  266.             if (res.Status == PromptStatus.OK && res.Value.Count > 0)
  267.             {
  268.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  269.                 {
  270.                     foreach (ObjectId id in res.Value.GetObjectIds())
  271.                     {
  272.                         Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
  273.                         if (ent != null)
  274.                             ent.Erase();
  275.                     }
  276.                     tr.Commit();
  277.                 }
  278.             }

  279.             // save the drawing to a new one using exporttoautocad
  280.             // I need to use this approach - any other I tried did not work
  281.             // like SaveAs() or SaveDatabaseAs2000()
  282.             ResultBuffer cmdlist1 = new ResultBuffer();
  283.             cmdlist1.Add(new TypedValue(RTSTR, "_.-EXPORTTOAUTOCAD"));
  284.             cmdlist1.Add(new TypedValue(RTSTR, "_Format"));
  285.             cmdlist1.Add(new TypedValue(RTSTR, "2000"));
  286.             cmdlist1.Add(new TypedValue(RTSTR, "_Type"));
  287.             cmdlist1.Add(new TypedValue(RTSTR, "_Insert"));
  288.             cmdlist1.Add(new TypedValue(RTSTR, "_Prefix"));
  289.             cmdlist1.Add(new TypedValue(RTSTR, prefixConvert));
  290.             cmdlist1.Add(new TypedValue(RTSTR, ""));
  291.             cmdlist1.Add(new TypedValue(RTSTR, ""));

  292.             status = acedCmd(cmdlist1.UnmanagedObject);

  293.             // converted drawing name output
  294.             string dwgConvertFinalName = dwgprefix + prefixConvert + dwgname;

  295.             // command -exporttoautocad appears that cannot be cancel, once it is called
  296.             if (status == RTNORM || status == RTCAN)
  297.             {
  298.                 // return system variables to their original status
  299.                 AcadApp.SetSystemVariable("CMDECHO", o_cmdecho);
  300.                 AcadApp.SetSystemVariable("TEXTSTYLE", o_textstyle);
  301.             }

  302.             string caption = "DWGConvert - New drawing created @";
  303.             MessageBox.Show(dwgConvertFinalName, caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
  304.             SetFocus(Autodesk.AutoCAD.ApplicationServices.Application.MainWindow.Handle);
  305.             //AcadApp.ShowAlertDialog(dwgConvertFinalName); // this approach does not have a focus problem
  306.         }

  307.     }
  308. }



论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-16 23:51 , Processed in 0.269656 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表