private const string TemplatePath = @"C:\Users\xiaobai\AppData\Local\Autodesk\AutoCAD 2024\R24.3\chs\Template\acadiso.dwt";
[CommandMethod("ExportDrawingFrames")]
public void ExportDrawingFrames()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database srcDb = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = srcDb.TransactionManager.StartTransaction())
{
string outputDir = "输出路径";
if (string.IsNullOrEmpty(outputDir))
outputDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
BlockTable bt = (BlockTable)tr.GetObject(srcDb.BlockTableId, OpenMode.ForRead);
int exportedCount = 0;
foreach (ObjectId btrId in bt)
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
if (!IsDrawingFrameBlock(btr.Name))
continue;
try
{
string dwgPath = Path.Combine(outputDir, btr.Name + ".dwg");
ExportBlockToDwg(btr, dwgPath);
exportedCount++;
ed.WriteMessage("\n已导出图框: {0}", dwgPath);
}
catch (System.Exception ex)
{
ed.WriteMessage("\n导出失败 - 图框: {0}, 错误: {1}", btr.Name, ex.Message);
}
}
tr.Commit();
ed.WriteMessage("\n导出完成! 共导出 {0} 个图框", exportedCount);
}
}
private bool IsDrawingFrameBlock(string blockName)
{
return System.Text.RegularExpressions.Regex.IsMatch(
blockName, @"^A\d+(-[\d\.]+)?V?$");
}
private void ExportBlockToDwg(BlockTableRecord srcBtr, string dwgPath)
{
Database dstDb = new Database(false, true);
dstDb.ReadDwgFile(TemplatePath, FileShare.Read, true, null);
try
{
using (Transaction dstTr = dstDb.TransactionManager.StartTransaction())
{
BlockTable dstBt = (BlockTable)dstTr.GetObject(
dstDb.BlockTableId, OpenMode.ForWrite);
BlockTableRecord dstMs = (BlockTableRecord)dstTr.GetObject(
dstBt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
ObjectIdCollection srcIds = new ObjectIdCollection();
srcIds.Add(srcBtr.ObjectId);
IdMapping idMap = new IdMapping();
dstDb.WblockCloneObjects(srcIds, dstBt.ObjectId, idMap,
DuplicateRecordCloning.Replace, false);
ObjectId dstBtrId = idMap[srcBtr.ObjectId].Value;
BlockReference br = new BlockReference(Point3d.Origin, dstBtrId);
dstMs.AppendEntity(br);
dstTr.AddNewlyCreatedDBObject(br, true);
SetPreviewFromBlock(dstDb, srcBtr, dstTr);
dstTr.Commit();
}
dstDb.SaveAs(dwgPath, DwgVersion.Current);
}
finally
{
dstDb.Dispose();
}
}
private void SetPreviewFromBlock(Database db, BlockTableRecord btr, Transaction tr)
{
Extents3d extents = GetBlockExtents(btr);
var limitMin = extents.MinPoint.TransformBy(Matrix3d.Displacement(-extents.MinPoint.GetAsVector()));
var limitMax = extents.MaxPoint.TransformBy(Matrix3d.Displacement(-extents.MinPoint.GetAsVector()));
var bestBt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
db.Limmax = new Point2d(limitMax.X, limitMax.Y);
db.Limmin = new Point2d(limitMin.X, limitMin.Y);
db.ThumbnailBitmap = ExtractThumbnails(tr, bestBt);
}
private Extents3d GetBlockExtents(BlockTableRecord btr)
{
Extents3d extents = new Extents3d();
foreach (ObjectId entId in btr)
{
Entity ent = entId.GetObject(OpenMode.ForRead) as Entity;
if (ent != null && !ent.IsErased)
{
try
{
extents.AddExtents(ent.GeometricExtents);
}
catch
{
}
}
}
return extents;
}
public static Bitmap ExtractThumbnails(Transaction tr, BlockTable bt)
{
try
{
var btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
var imgsrc = CMLContentSearchPreviews.GetBlockTRThumbnail(btr);
var image = ImageSourceToGDI(imgsrc as System.Windows.Media.Imaging.BitmapSource);
return new Bitmap(image);
}
catch
{
return null;
}
}
private static System.Drawing.Image ImageSourceToGDI(System.Windows.Media.Imaging.BitmapSource src)
{
int width = src.PixelWidth;
int height = src.PixelHeight;
var bmp = new System.Drawing.Bitmap(width, height);
var rect = new System.Drawing.Rectangle(0, 0, width, height);
var data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
src.CopyPixels(new System.Windows.Int32Rect(0, 0, width, height), data.Scan0, data.Stride * height, data.Stride);
bmp.UnlockBits(data);
return bmp;
}