jkchenliang 发表于 2025-9-17 19:31:02

一个用包围盒转化cad为png格式的方法

namespace DWGScreenshot
{
    public class Commands
    {
      /// <summary>
      /// 截图指定的 DWG 文件(不打开文件,直接读取包围盒)
      /// 使用方法:在 CAD 命令行输入 DWGSHOT
      /// </summary>
      
      public void ScreenshotDWG()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            // 1. 获取 DWG 文件路径
            PromptStringOptions pso = new PromptStringOptions("\n输入 DWG 文件路径: ");
            pso.AllowSpaces = true;
            PromptResult pr = ed.GetString(pso);

            if (pr.Status != PromptStatus.OK)
                return;

            string dwgPath = pr.StringResult.Trim('"');

            if (!File.Exists(dwgPath))
            {
                ed.WriteMessage($"\n文件不存在: {dwgPath}");
                return;
            }

            try
            {
                // 2. 读取 DWG 文件并计算包围盒(不打开文件)
                Extents3d? bounds = GetDWGBounds(dwgPath);

                if (!bounds.HasValue)
                {
                  ed.WriteMessage($"\n无法获取文件包围盒: {dwgPath}");
                  return;
                }

                // 3. 扩大包围盒 5mm
                double expansion = 5.0; // 5mm
                Point3d minPoint = new Point3d(
                  bounds.Value.MinPoint.X - expansion,
                  bounds.Value.MinPoint.Y - expansion,
                  bounds.Value.MinPoint.Z
                );
                Point3d maxPoint = new Point3d(
                  bounds.Value.MaxPoint.X + expansion,
                  bounds.Value.MaxPoint.Y + expansion,
                  bounds.Value.MaxPoint.Z
                );

                ed.WriteMessage($"\n原始包围盒: ({bounds.Value.MinPoint.X:F2}, {bounds.Value.MinPoint.Y:F2}) - ({bounds.Value.MaxPoint.X:F2}, {bounds.Value.MaxPoint.Y:F2})");
                ed.WriteMessage($"\n扩大后包围盒: ({minPoint.X:F2}, {minPoint.Y:F2}) - ({maxPoint.X:F2}, {maxPoint.Y:F2})");

                // 4. 先打开文件
                Application.DocumentManager.Open(dwgPath, false);
                Document newDoc = Application.DocumentManager.MdiActiveDocument;


                // 5. 缩放到扩大后的包围盒
                Point3d P1 = new Point3d(
                   bounds.Value.MinPoint.X,
                   bounds.Value.MinPoint.Y,
                   bounds.Value.MinPoint.Z
               );
                Point3d P2 = new Point3d(
                  bounds.Value.MaxPoint.X,
                  bounds.Value.MaxPoint.Y,
                  bounds.Value.MaxPoint.Z
                );
                var line = new Line(minPoint, maxPoint);
                Env.Editor.ZoomObject(line, 50);
                System.Threading.Thread.Sleep(500); // 500毫秒延迟

                // 6. 输出 PNG - 使用 Editor.Command 同步执行
                string outputPath = Path.ChangeExtension(dwgPath, ".png");

                // 方法1:使用 Editor.Command 同步执行(推荐)
                newDoc.Editor.Command("PNGOUT", outputPath, "ALL", "");


                // 或者方法2:使用 acedCmd(需要 P/Invoke)
                // string pngCommand = $"PNGOUT\n\"{outputPath}\"\nALL\n\n";
                // newDoc.SendStringToExecute(pngCommand, false, false, false);
                // System.Threading.Thread.Sleep(2000); // 等待2秒

                // 或者方法3:直接选择所有对象后执行
                // newDoc.Editor.Command("_SELECT", "ALL", "");
                // SelectionSet ss = newDoc.Editor.SelectAll().Value;
                // newDoc.Editor.Command("PNGOUT", outputPath, ss, "");

                ed.WriteMessage($"\n截图已保存到: {outputPath}");
            }
            catch (Exception ex)
            {
                ed.WriteMessage($"\n错误: {ex.Message}");
            }
      }

      /// <summary>
      /// 获取 DWG 文件的包围盒(不打开文件)
      /// </summary>
      private Extents3d? GetDWGBounds(string dwgPath)
      {
            Extents3d? result = null;

            // 创建临时数据库读取 DWG
            using (Database sourceDb = new Database(false, true))
            {
                try
                {
                  // 读取 DWG 文件
                  sourceDb.ReadDwgFile(dwgPath, FileOpenMode.OpenForReadAndAllShare, true, "");

                  using (Transaction trans = sourceDb.TransactionManager.StartTransaction())
                  {
                        // 获取模型空间
                        BlockTable bt = trans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                        BlockTableRecord ms = trans.GetObject(bt, OpenMode.ForRead) as BlockTableRecord;

                        // 计算所有实体的包围盒
                        foreach (ObjectId id in ms)
                        {
                            Entity entity = trans.GetObject(id, OpenMode.ForRead) as Entity;
                            if (entity != null && entity.Visible)
                            {
                              try
                              {
                                    Extents3d entityExtents = entity.GeometricExtents;

                                    if (!result.HasValue)
                                    {
                                        result = entityExtents;
                                    }
                                    else
                                    {
                                        // 合并包围盒
                                        result = new Extents3d(
                                          new Point3d(
                                                Math.Min(result.Value.MinPoint.X, entityExtents.MinPoint.X),
                                                Math.Min(result.Value.MinPoint.Y, entityExtents.MinPoint.Y),
                                                Math.Min(result.Value.MinPoint.Z, entityExtents.MinPoint.Z)
                                          ),
                                          new Point3d(
                                                Math.Max(result.Value.MaxPoint.X, entityExtents.MaxPoint.X),
                                                Math.Max(result.Value.MaxPoint.Y, entityExtents.MaxPoint.Y),
                                                Math.Max(result.Value.MaxPoint.Z, entityExtents.MaxPoint.Z)
                                          )
                                        );
                                    }
                              }
                              catch
                              {
                                    // 忽略没有几何范围的实体
                              }
                            }
                        }

                        trans.Commit();
                  }
                }
                catch
                {
                  return null;
                }
            }

            return result;
      }
    }
}

不一样地设计 发表于 2025-9-18 10:23:19

感谢楼主分享!!
页: [1]
查看完整版本: 一个用包围盒转化cad为png格式的方法