明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 491|回复: 1

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

[复制链接]
发表于 2025-9-17 19:31:02 | 显示全部楼层 |阅读模式
namespace DWGScreenshot
{
    public class Commands
    {
        /// <summary>
        /// 截图指定的 DWG 文件(不打开文件,直接读取包围盒)
        /// 使用方法:在 CAD 命令行输入 DWGSHOT
        /// </summary>
        [CommandMethod("eee")]
        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[BlockTableRecord.ModelSpace], 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 | 显示全部楼层
感谢楼主分享!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-11-26 10:32 , Processed in 0.261609 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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