拆分和合并非常常规的需求
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