首页 > 编程语言 >C# AutoCAD 图纸合并以及拆分

C# AutoCAD 图纸合并以及拆分

时间:2024-03-10 14:00:10浏览次数:23  
标签:AutoCAD C# Application dwg 拆分 dxf var using

拆分和合并非常常规的需求

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using Microsoft.VisualBasic.ApplicationServices;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Application = Autodesk.AutoCAD.ApplicationServices.Application;

namespace MyTestDll
{
    public class 拆分合并图纸
    {
        #region 拆分图纸

        [CommandMethod("CF", CommandFlags.Session)]
        public void 按块名称拆分图纸()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            //选择一个图框
            var acEd = acDoc.Editor;
            try
            {
                var peo = new PromptEntityOptions("选择一个图框块")
                {
                    AllowObjectOnLockedLayer = false,
                    AllowNone = false
                };
                peo.SetRejectMessage("选择一个图框块");
                peo.AddAllowedClass(typeof(BlockReference), true);
                var per = acEd.GetEntity(peo);
                if (per.Status != PromptStatus.OK)
                {
                    Application.ShowAlertDialog("选择图框失败!");
                    return;
                }
                List<string> fns = new List<string>();
                dynamic acadApp = Application.AcadApplication;
                //获取图块名称
                var blkName = string.Empty;
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    var blkref = per.ObjectId.GetObject(OpenMode.ForRead) as BlockReference;
                    var btr = acTrans.GetObject(blkref.IsDynamicBlock ? blkref.DynamicBlockTableRecord : blkref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                    acEd.WriteMessage(btr.Name);
                    var oids = btr.IsAnonymous ? btr.GetAnonymousBlockIds() : btr.GetBlockReferenceIds(false, false);
                    blkName = btr.Name;
                }
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    var bt = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    var btrMs = acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
                    foreach (ObjectId item in btrMs)
                    {
                        var ent = item.GetObject(OpenMode.ForRead) as Entity;
                        if (!(ent is BlockReference)) continue;
                        var blkref = ent as BlockReference;
                        var curBlkrefBtr = acTrans.GetObject(blkref.IsDynamicBlock ? blkref.DynamicBlockTableRecord : blkref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                        if (curBlkrefBtr.Name != blkName) continue;
                        var ext = blkref.GeometryExtentsBestFit();
                        var lower = new double[3] { ext.MinPoint.X, ext.MinPoint.Y, ext.MinPoint.Z };
                        var upper = new double[3] { ext.MaxPoint.X, ext.MaxPoint.Y, ext.MaxPoint.Z };
                        acadApp.ZoomExtents();
                        var psr = acEd.SelectCrossingWindow(ext.MinPoint, ext.MaxPoint);
                        acadApp.ZoomWindow(lower, upper);
                        Application.UpdateScreen();
                        acEd.Regen();
                        string newDocPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) +
                            $"\\{Path.GetFileNameWithoutExtension(acDoc.Name)}-{(curBlkrefBtr.IsAnonymous? "Anonymous" : blkName)}";
                        if (!Directory.Exists(newDocPath))
                            Directory.CreateDirectory(newDocPath);
                        var dwgfn = Path.Combine(newDocPath, $"{blkref.Handle}.dwg");
                        var oids_SaveAs = new List<ObjectId> { item };
                        if (psr.Status == PromptStatus.OK)
                        {
                            oids_SaveAs.AddRange(psr.Value.GetObjectIds());
                        }
                        SaveAsFile(acCurDb, dwgfn, DwgVersion.AC1027, true, oids_SaveAs.ToArray());
                        fns.Add(dwgfn);
                    }
                }
                if (fns.Count > 0)
                {
                    var doc = Application.DocumentManager.MdiActiveDocument;
                    foreach (var fn in fns)
                    {
                        var docOpen = Application.DocumentManager.Open(fn, false);
                        var dl = docOpen.LockDocument();
                        Application.DocumentManager.MdiActiveDocument = docOpen;
                        dynamic acadDoc = docOpen.GetAcadDocument();
                        acadApp.ZoomExtents();
                        Application.UpdateScreen();
                        docOpen.Editor.Regen();
                        acadDoc.Save();
                        Application.DocumentManager.MdiActiveDocument = doc;
                        dl.Dispose();
                        docOpen.CloseAndDiscard();
                    }
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(acadApp);
                    Application.ShowAlertDialog("拆分成功!");
                }
                else
                {
                    Application.ShowAlertDialog("拆分失败!");
                }
            }
            catch (System.Exception ex)
            {
                Application.ShowAlertDialog(ex.StackTrace);
            }
        }


        /// <summary>
        /// 将部分id另存为图纸.dwg/dxf
        /// </summary>
        /// <param name="db">当前数据库</param>
        /// <param name="filename">另存为的图纸名称,全路径,注意dxf和dwg格式均支持</param>
        /// <param name="IsDwgFormat">默认是dwg格式,如果是dxf格式请传入false</param>
        /// <param name="oids">需要导出的图元的id</param>
        private void SaveAsFile(Database db, string filename, DwgVersion ver = DwgVersion.AC1021,
            bool IsDwgFormat = true, params ObjectId[] oids)
        {
            var oidcols = new ObjectIdCollection();
            oids.ToList().ForEach(oid => oidcols.Add(oid));
            using (var newdb = new Database(true, false))
            {
                db.Wblock(newdb, oidcols, Point3d.Origin, DuplicateRecordCloning.Replace);
                var vtrOid = newdb.CurrentViewportTableRecordId;
                var pros = typeof(Database).GetProperties()
                    .Where(c => c.CanRead && c.CanWrite && (c.PropertyType == typeof(double) || c.PropertyType == typeof(bool) || c.PropertyType == typeof(int) || c.PropertyType == typeof(string)));
                foreach (var pi in pros)
                {
                    try
                    {
                        pi.SetValue(newdb, pi.GetValue(db));
                    }
                    catch (System.Exception)
                    {
                        continue;
                    }
                }
                if (IsDwgFormat)
                {
                    newdb.SaveAs(Path.ChangeExtension(filename, ".dwg"), ver);
                }
                else
                {
                    newdb.DxfOut(Path.ChangeExtension(filename, ".dxf"), 16, ver);
                }
            }
        }

        #endregion

        #region 合并图纸

        [CommandMethod("hbtz")]
        public void 合并图纸()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database db = acDoc.Database;
            Editor ed = acDoc.Editor;
            try
            {
                if (db.Filename != db.OriginalFileName)
                {
                    Application.ShowAlertDialog("请新建一张图再使用本命令!");
                    return;
                }
                if (Application.GetSystemVariable("DBMOD").ToString() != "0")
                {
                    Application.ShowAlertDialog("请新建一张图再使用本命令!");
                    return;
                }
                System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog()
                {
                    Title = "选择需要合并的图纸",
                    Multiselect = true,
                    Filter = "dwg files (*.dwg)|*.dwg"
                };

                if (ofd.ShowDialog() != DialogResult.OK)
                {
                    Application.ShowAlertDialog("打开图纸失败!");
                    return;
                }
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                    //BlockTableRecord ms = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
                    Point3d pnt_Base = Point3d.Origin;
                    var insPtDistance2OriPoint = 0.0;
                    for (int i = 0; i < ofd.FileNames.Length; i++)
                    {
                        var item = ofd.FileNames[i];
                        if (Path.GetFileNameWithoutExtension(item).EndsWith(" "))
                        {
                            Application.ShowAlertDialog($"文件名称末尾不可以包含空格\"{item}\"!\n\r");
                            continue;
                        }
                        try
                        {
                            var oid = ImportDrawingAsBlkstoCurDoc(db, item, true);
                            Extents3d ext = new Extents3d();
                            ext.AddBlockExtents(tr.GetObject(oid, OpenMode.ForRead) as BlockTableRecord);
                            var pt1 = Polar(pnt_Base.Add(ext.MinPoint.GetAsVector().Negate()),
                                0.0, insPtDistance2OriPoint);
                            var blkrefoid = InsertBlockref(bt[BlockTableRecord.ModelSpace], "0",
                                Path.GetFileNameWithoutExtension(item), pt1,
                                new Scale3d(1, 1, 1), 0,
                                br =>
                                        {
                                            br.ColorIndex = 0;
                                            br.ExplodeToOwnerSpace();
                                            br.Erase();
                                        });
                            insPtDistance2OriPoint += (ext.MaxPoint.X - ext.MinPoint.X) * 1.3;

                        }
                        catch (System.Exception)
                        {
                            ed.WriteMessage($"图纸 {Path.GetFileNameWithoutExtension(item)} 插入失败,请检查原始文件\n\r");
                            continue;
                        }
                    }

                    tr.Commit();
                }
                ed.Regen();
                dynamic acdApp = Application.AcadApplication;
                acdApp.ZoomExtents();
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(ex.StackTrace);
            }
        }

        /// <summary>
        /// 计算指定距离和角度的点
        /// </summary>
        /// <remarks>本函数仅适用于x-y平面</remarks>
        /// <param name="pt">基点</param>
        /// <param name="ang">角度,x轴正向逆时针弧度</param>
        /// <param name="len">距离</param>
        /// <returns>目标点</returns>
        public static Point3d Polar(Point3d pt, double ang, double len)
        {
            return pt + Vector3d.XAxis.RotateBy(ang, Vector3d.ZAxis) * len;
        }

        /// <summary>
        /// 将图纸作为一个块整个插入导数据库
        /// </summary>
        /// <param name="curDb"></param>
        /// <param name="FileName">图纸的完整路径,dxf或者dwg都可以</param>
        /// <returns></returns>
        /// 
        public static ObjectId ImportDrawingAsBlkstoCurDoc(Database curDb, string strFileName, bool reimport = false)
        {
            ObjectId btrid = ObjectId.Null;

            var BlkName = Path.GetFileNameWithoutExtension(strFileName);

            var fileext = Path.GetExtension(strFileName).ToLower();

            using (Transaction trans = curDb.TransactionManager.StartTransaction())
            {
                BlockTable bt = trans.GetObject(curDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                //if(!bt.Has(BlkName))
                //{
                if (File.Exists(strFileName))
                {
                    using (Database dwgdb = new Database(false, true))
                    {
                        switch (fileext)
                        {
                            case ".dwg":
                                dwgdb.ReadDwgFile(strFileName, System.IO.FileShare.Read, true, null);
                                break;
                            case ".dxf":
                                dwgdb.DxfIn(strFileName, null);
                                break;
                            default:
                                break;
                        }
                        dwgdb.CloseInput(true);
                        btrid = curDb.Insert(BlkName, dwgdb, reimport);
                        dwgdb.Dispose();
                        //SWH_CMD.Tools.GetEditor(db).Command("_.Attsync", "Name", BlkName);
                    }
                }
                trans.Commit();
                //}
                //else return bt[BlkName];
            }

            return btrid;
        }

        /// <summary>
        /// 插入块到图纸中
        /// </summary>
        /// <param name="spacdId">空间id</param>
        /// <param name="layer">图层</param>
        /// <param name="blkName">块名称</param>
        /// <param name="position">插入点</param>
        /// <param name="scale">比例</param>
        /// <param name="blkroAngle">旋转角度,弧度制</param>
        /// <returns></returns>
        private static ObjectId InsertBlockref(ObjectId spacdId, string layer, string blkName, Point3d position, Scale3d scale, double blkroAngle, Action<BlockReference> act = null)
        {
            ObjectId blkrefID;
            var db = spacdId.Database;
            var bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
            if (!bt.Has(blkName)) return ObjectId.Null;
            BlockTableRecord space = spacdId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
            blkrefID = bt[blkName];
            BlockTableRecord record = blkrefID.GetObject(OpenMode.ForRead) as BlockTableRecord;
            BlockReference br = new BlockReference(position, blkrefID);
            br.ScaleFactors = scale;
            br.Rotation = 0;
            space.AppendEntity(br);
            br.Layer = layer;

            //br.Color = Color.FromColorIndex(ColorMethod.ByAci, 0);

            if (record.HasAttributeDefinitions)
            {
                foreach (ObjectId id in record)
                {
                    var attdef = id.GetObject(OpenMode.ForRead) as AttributeDefinition;
                    if (attdef != null)
                    {
                        AttributeReference ar = new AttributeReference();
                        ar.SetAttributeFromBlock(attdef, br.BlockTransform);
                        ar.Position = attdef.Position.TransformBy(br.BlockTransform);
                        ar.Rotation = attdef.Rotation;
                        ar.AdjustAlignment(db);
                        ar.Layer = layer;
                        br.AttributeCollection.AppendAttribute(ar);
                        db.TransactionManager.AddNewlyCreatedDBObject(ar, true);
                    }
                }
            }
            if (act != null) act.Invoke(br);
            db.TransactionManager.AddNewlyCreatedDBObject(br, true);
            Matrix3d mt = Matrix3d.Rotation(blkroAngle, Vector3d.ZAxis, br.Position);
            br.TransformBy(mt);
            return br.ObjectId;
        }
        #endregion
    }


    public enum AcSaveAsType
    {
        ac2000_dwg = 12, //AutoCAD 2000 DWG (*.dwg) 
        ac2000_dxf = 13, //AutoCAD 2000 DXF (*.dxf) 
        ac2004_dwg = 24, //AutoCAD 2004 DWG (*.dwg) 
        ac2004_dxf = 25, //AutoCAD 2004 DXF (*.dxf) 
        ac2007_dwg = 36, //AutoCAD 2007 DWG (*.dwg) 
        ac2007_dxf = 37, //AutoCAD 2007 DXF (*.dxf) 
        ac2010_dwg = 48, //AutoCAD 2010 DWG (*.dwg) 
        ac2010_dxf = 49, //AutoCAD 2010 DXF (*.dxf) 
        ac2013_dwg = 60, //AutoCAD 2013 DWG (*.dwg) 
        ac2013_dxf = 61, //AutoCAD 2013 DXF (*.dxf) 
        ac2018_dwg = 64, //AutoCAD 2018 DWG (*.dwg) 
        ac2018_dxf = 65, //AutoCAD 2018 DXF (*.dxf) 
    }
}

 

标签:AutoCAD,C#,Application,dwg,拆分,dxf,var,using
From: https://www.cnblogs.com/NanShengBlogs/p/18064110

相关文章

  • 在Docker中,Docker配置文件在哪里以及如何修改?
    Docker的主要配置文件通常位于Linux系统的/etc/docker/目录下,关键的配置文件是daemon.json。这个文件用于配置Docker守护进程(DockerDaemon)的各项参数,包括但不限于数据存储位置、网络设置、日志配置、信任代理等。查找和修改Docker配置文件的步骤如下:定位配置文件:Docker的......
  • 在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
    在Docker中,你可以通过多种方式来控制容器对系统资源(如CPU和内存)的使用份额,以确保容器不会过度消耗宿主机的资源,并与其他容器公平地共享资源。以下是一些常用的方法:一.控制CPU资源CPU份额(CPUShares):Docker使用CPU份额来分配CPU时间。默认情况下,所有容器具有相同的CPU份额,这意......
  • 在Linux中,发现CPU负载过大,接下来怎么办?
    在Linux系统中,如果发现CPU负载过高,遵循以下步骤进行故障排查和解决:1.监控与确认问题使用top或htop命令实时查看当前CPU使用情况,并找出占用CPU较高的进程:top或者htop#需要先安装htop工具在top中按1可以看到每个单独的CPU核心的负载情况。使用ps或psaux......
  • 在Linux中,如何获取CPU的总核心数?
    在Linux中,可以通过几种不同的命令来获取CPU的总核心数。具体如下:查看物理CPU个数:可以通过查看/proc/cpuinfo文件来获取物理CPU的个数。使用以下命令:cat/proc/cpuinfo|grep"physicalid"|sort-u|wc-l这个命令会显示物理CPU的个数。查看每个物理CPU的核数:同样,可......
  • 在Linux中,如何查看占用CPU最多的进程?
    在Linux中,有多种方法可以查看占用CPU最多的进程。以下是几种常用的方法:使用top命令:top命令是Linux中常用的性能分析工具,可以实时显示系统中各个进程的资源占用情况,包括CPU使用率。打开终端,输入top命令,按下回车键。top命令会显示出当前系统中CPU使用率最高的进程列表。默认情......
  • 第03章_基本的SELECT语句
    第03章_基本的SELECT语句讲师:尚硅谷-宋红康(江湖人称:康师傅)官网:http://www.atguigu.com1.SQL概述1.1SQL背景知识1946年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖。在这几十年里,无数的技术、产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰......
  • ARC083 vp记录
    有操作的操作场,考场过了ABC(3/4)A.SugarWater题意:一个杯子,可以容纳\(F\)克糖水,一开始是空的。每次操作:加入\(100A\)克水加入\(100B\)克水加入\(C\)克糖加入\(D\)克糖每\(100\)克水最多溶解\(E\)克糖,求任意次操作后完全溶解的糖水中的最大含糖量,以......
  • [转帖]Oracle 常规坏块处理方法
    收到业务反馈,查看erp请求时遇到报错,一看居然是坏块。。。-_-|| alert日志中也出现相关报错,但还好只有一个坏块一、有备份的处理方法这一般就非常简单,rman有坏块修复功能Recoverdatafile19block44;如有必要,可同时修复多个文件多个块Recoverdatafile19block44d......
  • [ABC219E] Moat 题解
    [ABC219E]Moat题解思路解析一眼看到输入数据只有\(4\)行\(4\)列,直接想到状压枚举。可以直接枚举所有护城河所包含起来的格子,判断是否连通以及判断是否包含住了所有村庄。判断连通我选择用洪水填充,随便选一个包含着的格子,若可以通过当前格移动到所有被包含格就说明连通。以......
  • ABC219 复盘
    ABC219复盘[ABC219A]AtCoderQuiz2思路解析直接判断\(x\)属于的区间然后输出即可。时间复杂度:直接判断,\(O(1)\)。code#include<bits/stdc++.h>usingnamespacestd;intx;intmain(){ cin>>x; if(x<40)cout<<40-x; //直接判断即可 elseif(x>=40&&a......