本帖最后由 你有种再说一遍 于 2024-6-6 19:54 编辑
给你一个c#代码看看,主要这个map在lisp上面实现困难,所以不建议用lisp做这个功能...
这里的代码还有两个优化的地方.
一个缺少并行.
一个如果在画图的时候就加入集合,岂不是0秒获取.
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.Runtime;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace 统计块参照分类
- {
- public class Class1
- {
-
- [CommandMethod("test2")]
- public void BlkRefCount2()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- var acDocEd = doc.Editor;
- var db = doc.Database;
- Dictionary<string, int> map = new Dictionary<string, int>();
- Stopwatch stopwatch = new Stopwatch();
- stopwatch.Start();
- using (Transaction trans = db.TransactionManager.StartTransaction())
- {
- BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//BlockTableId 一定是ok
- foreach (ObjectId btrObjId in bt)//遍历所有的块表记录,不是当前块表 db.CurrentSpaceId,因为布局中也可能会有块
- {
- if (!btrObjId.IsOk()) continue;
- BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrObjId, OpenMode.ForRead);
- foreach (ObjectId obj in btr)
- {
- if (!obj.IsOk()) continue;
- Entity ent = (Entity)trans.GetObject(obj, OpenMode.ForRead);
- if (ent is BlockReference blkref)
- {
- var name = blkref.GetBlockName();
- if (!map.ContainsKey(name))
- {
- map.Add(name, 0);
- }
- map[name]++;
- }
- }
- }
- }
- stopwatch.Stop();
- TimeSpan elapsed = stopwatch.Elapsed;
- double elapsedMillisecondsDouble = stopwatch.ElapsedMilliseconds;
- double microsecondsFraction = (elapsedMillisecondsDouble - Math.Truncate(elapsedMillisecondsDouble)) * 1000; // 获取毫秒的小数部分并转换为微秒
- acDocEd.WriteMessage($"程序运行了 {stopwatch.Elapsed.Hours:00}:{stopwatch.Elapsed.Minutes:00}:{stopwatch.Elapsed.Seconds:00}.{elapsedMillisecondsDouble:0.000} 秒\n");
- foreach (var pair in map)
- {
- acDocEd.WriteMessage($"Name: {pair.Key}, Count: {pair.Value}\n");
- }
- }
- }
- public static partial class BlockHelper
- {
- /// <summary>
- /// 动态块真实块名获取
- /// </summary>
- /// <param name="brRec">块参照</param>
- /// <returns>成功返回:块的真实名称,失败返回:null</returns>
- // 1.块的Z比例是0就会令动态块变成普通块,那么导致判断动态块失效
- // 2.brRec.IsDynamicBlock 如果是动态块这句会报错:eInvalidObjectId
- // 重复空格执行上次报这个错误,应该在所有GetObject位置写.Dispose();
- public static string GetBlockName(this BlockReference blkref)
- {
- string blockName = string.Empty;
- if (blkref.DynamicBlockTableRecord.IsOk())
- {
- // 动态块表记录可以获取 动态块名 也可以获取 普通块名
- var btRec = blkref.DynamicBlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
- blockName = btRec.Name;
- btRec.Dispose();
- }
- return blockName;
- }
- }
- public static partial class EntityEdit
- {
- /// <summary>
- /// id有效,未被删除
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- public static bool IsOk(this ObjectId id)
- {
- return !id.IsNull && id.IsValid && !id.IsErased && !id.IsEffectivelyErased && id.IsResident;
- }
- }
- }
|