明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 549|回复: 9

[【IFoxCAD】] 格式刷的測試例子

[复制链接]
发表于 2024-6-30 02:21:17 | 显示全部楼层 |阅读模式


寫了個顏色格式刷的例子,大佬們還有哪些地方需要改?

  1.     private static string GetPointOptionsMessage() => "\n选择图元或 [字典(D)/随层(S)] ";

  2.     private static readonly List<string> ignorePatterName = ["SOLID", "ANSI37", "ANSI31"];
  3.     private static readonly List<string> ignoreBlockName = ["Elevation", "ANSI37", "ANSI31"];
  4.     private static readonly Dictionary<List<int>, (string, short, short)> reflectDic = new(){
  5.         { [3,7], (layers.DimLayer_Name,layers.DimLayer_Color,256) },
  6.         { [1], (layers.DimLayer_Name,layers.DimLayer_Color,4) }
  7.     };
  8.     [CommandMethod("B`")]
  9.     public static void BBest()
  10.     {
  11.         PromptSelectionOptions entOpts = new()
  12.         {
  13.             MessageForAdding = GetPointOptionsMessage()
  14.         };

  15.         PromptSelectionResult r1 = Env.Editor.GetSelection(entOpts);
  16.         if (r1.Status == PromptStatus.OK)
  17.         {
  18.             using DBTrans tr = new();
  19.             List<ObjectId> entWillBeSelected = [];

  20.             var ids = r1.Value.GetObjectIds().ToList();
  21.             for (int i = ids.Count - 1; i >= 0; i--)
  22.             {
  23.                 var ent = (Entity)tr.GetObject(ids);


  24.                 if (ent is Dimension dim)
  25.                 {
  26.                     if (dim.Layer == layers.DimLayer_Name && dim.ColorIndex == 256)
  27.                         continue;

  28.                     using (dim.ForWrite())
  29.                         dim.SetProperty("0", layers.DimLayer_Name, layers.DimLayer_Color);
  30.                     entWillBeSelected.Add(ent.ObjectId);
  31.                 }

  32.                 if (ent is Hatch hatch)
  33.                 {
  34.                     if (!ignorePatterName.Contains(hatch.PatternName))
  35.                         continue;

  36.                     using (hatch.ForWrite())
  37.                         hatch.SetProperty("0", layers.EL_250_Name, layers.EL_250_Color);
  38.                     entWillBeSelected.Add(ent.ObjectId);
  39.                 }

  40.                 if (ent is BlockReference brf)
  41.                 {
  42. #if Debug
  43.                     Env.Printl($"块名:{brf.Name} ,图块:{brf.Layer}");
  44. #endif
  45.                     var btrId = brf.BlockTableRecord;
  46.                     var btr = (BlockTableRecord)tr.GetObject(btrId);

  47.                     if (btr.IsFromExternalReference)
  48.                     {
  49.                         Env.Printl($"块名:{brf.Name} ,来自外部块!");
  50.                         continue;
  51.                     }

  52.                     foreach (var entId in btr)
  53.                     {
  54.                         //Env.Printl($"dxfname:  {entId.ObjectClass.DxfName}");
  55.                         var bent = (Entity)tr.GetObject(entId);
  56.                         //using (bent.ForWrite())
  57.                         //    bent.ColorIndex = 1;

  58.                         if (bent is Line or Polyline or Circle)
  59.                         {
  60.                             if (NewMethod(tr, entWillBeSelected, bent))
  61.                                 entWillBeSelected.Add(ent.ObjectId);

  62.                             entWillBeSelected.Remove(bent.ObjectId);
  63.                         }

  64.                     }

  65.                     tr.Editor?.Regen(); // 更新图纸
  66.                 }

  67.                 if (ent is Line or Polyline or Circle)
  68.                     NewMethod(tr, entWillBeSelected, ent);

  69.             }

  70.             tr.Editor?.SetImpliedSelection(entWillBeSelected.ToArray());

  71.         }
  72.     }

  73.     private static bool NewMethod(DBTrans tr, List<ObjectId> entWillBeSelected, Entity ent, bool isChanged = false)
  74.     {
  75.         if (ent is Line or Polyline or Circle)
  76.         {
  77.             var color = tr.GetEntityColor(ent);

  78.             foreach (var key in reflectDic.Keys)
  79.                 if (key.Contains(color))
  80.                 {
  81. #if Debug
  82.                     Env.Printl($"类型:{ent.GetType().Name} ,包含:{color}");
  83.                     var value = reflectDic[key];
  84.                     Env.Printl($"字典:{value.Item1}、{value.Item2}、{value.Item3}");
  85. #endif
  86.                     if (ent.Layer != value.Item1)
  87.                     {
  88.                         isChanged = true;
  89.                         entWillBeSelected.Add(ent.ObjectId);
  90.                         using (ent.ForWrite())
  91.                         {
  92.                             ent.SetProperty("0", value.Item1, value.Item2);
  93.                             ent.ColorIndex = value.Item3;
  94.                         };
  95.                     }

  96.                 }
  97.         }

  98.         return isChanged;
  99.     }



  1. namespace ArrowTools;
  2. public static class AttributeBrushToos
  3. {
  4.     /// <summary>
  5.     /// 获取实体的真实颜色值
  6.     /// </summary>
  7.     ///   /// <remarks>
  8.     /// 备注:<br/>
  9.     /// 0x01 颜色Bylayer:返回图层颜色值<br/>
  10.     /// 0x02 颜色不随层:返回entity的颜色值<br/>
  11.     /// </remarks>
  12.     /// <param name="tr"></param>
  13.     /// <param name="ent"></param>
  14.     /// <returns>颜色真实值</returns>
  15.     public static int GetEntityColor<T>(this DBTrans tr, T ent) where T : Entity
  16.     {
  17.         int colorindex = ent.ColorIndex;
  18.         if (colorindex == 256)
  19.         {
  20.             var layerId = tr.LayerTable[ent.Layer];
  21.             var layer = (LayerTableRecord)tr.GetObject(layerId);
  22.             colorindex = layer.Color.ColorIndex;
  23.         }

  24.         return colorindex;
  25.     }
  26. }

发表于 2024-7-1 18:00:34 | 显示全部楼层
本帖最后由 和尚777 于 2024-7-1 18:02 编辑
  1.   static HashSet<string> IgnorePatterName => ["SOLID", "ANSI37", "ANSI31"];
  2.   static (string, short, short) info => ("1", 1, 256);
  3.   static Dictionary<int, (string LayerName, short Color, short ColorIndex)> ReflectDic => new(){
  4.         { 7, info },
  5.         { 3, info },
  6.         { 1, ("2",2,4) }
  7.    };
复制代码

回复 支持 1 反对 0

使用道具 举报

发表于 2024-6-30 03:13:36 | 显示全部楼层
本帖最后由 你有种再说一遍 于 2024-6-30 03:37 编辑

  1. foreach (var key in reflectDic.Keys)
  2.                 if (key.Contains(color))

这个数据结构看起来就有问题,
遍历了keys,然后key是list又遍历了一次,所以时间复杂度是O(n*m),
完全没有利用好hash特性嘛.
不过由于数据量太少了,所以命中比求hash还快,hash还要跑个除法器...

看起来虽然奇怪的感觉,但是跑起来也不差.
就好像肛门虽然松了,但是痔疮又很好的弥补了这一点.
如果数据量大起来再讨论这个词典的意义吧.
 楼主| 发表于 2024-6-30 13:43:35 | 显示全部楼层
hash值這個是我的盲區,得補下這部份內容了。寫的時候感覺遍歷了好多次怪怪的,這麼一說確實得改進下,判斷類型那里也改進下,判斷是不是curve就得了,不然還得arc 樣條曲線、橢圓、等挨個判斷太麻煩了。

  1.     private static bool NewMethod(DBTrans tr, List<ObjectId> entWillBeSelected, Entity ent, bool isChanged = false)
  2.     {
  3.         if (ent is Curve)
  4.         {
  5.             var color = tr.GetEntityColor(ent);

  6.             foreach (var key in reflectDic.Keys)
  7.                 if (key.Contains(color))
  8.                 {
  9. #if Debug
  10.                     Env.Printl($"类型:{ent.GetType().Name} ,包含:{color}");
  11.                     var value = reflectDic[key];
  12.                     Env.Printl($"字典:{value.Item1}、{value.Item2}、{value.Item3}");
  13. #endif
  14.                     if (ent.Layer != value.Item1)
  15.                     {
  16.                         isChanged = true;
  17.                         entWillBeSelected.Add(ent.ObjectId);
  18.                         using (ent.ForWrite())
  19.                         {
  20.                             ent.SetProperty("0", value.Item1, value.Item2);
  21.                             ent.ColorIndex = value.Item3;
  22.                         };
  23.                     }

  24.                 }
  25.         }

  26.         return isChanged;
  27.     }
发表于 2024-6-30 16:53:33 | 显示全部楼层
本帖最后由 你有种再说一遍 于 2024-6-30 19:05 编辑
箭头_Row 发表于 2024-6-30 13:43
hash值這個是我的盲區,得補下這部份內容了。寫的時候感覺遍歷了好多次怪怪的,這麼一說確實得改進下,判斷 ...

去看jdk1.8的HashMap,然后再回来对比一下c#的.
微软实际上做得比较简单,想想求余数就是一个圈,这个圈就是数组大小,hashcode%array.length=位置.
这样就能映射到数组内部了,所以它是O(1)


【动画讲解-hashMap底层实现原理-哔哩哔哩】 https://b23.tv/OYilf4o


你用的时候记住了,最适合的情况是string,
只要看到string就上hash结构,
Hashset<string>,Dictionary<string>.
你不需要List<string>,虽然浪费了些许内存,但是速度快,还能明确它是唯一不重复的意思.

而且List的Contains也是遍历来得,不要以为写了一个方法就掩盖了for...如果是有序的,还得自己实现二分法搜索.当然了,为了O(1)直接hash,value多点就多点,空间换时间.


话外题:
再深入想想,你会发现字符串可以排序,也就是在节约内存和磁盘的情况下,可以利用前缀二分法的方式来实现,
例如ES数据库.
https://b23.tv/FMG1dwQ


发表于 2024-7-1 09:23:54 | 显示全部楼层
有无效if请使用else if,想办法避免大括号,不建议使用ed.regen
发表于 2024-7-1 09:42:38 | 显示全部楼层
你有种再说一遍 发表于 2024-6-30 03:13
这个数据结构看起来就有问题,
遍历了keys,然后key是list又遍历了一次,所以时间复杂度是O(n*m),
完全没 ...

大神优化下
发表于 2024-7-1 14:00:44 | 显示全部楼层

这样说应该就懂了啊,只是箭头哥不懂hash结构,你也不懂吗
发表于 2024-7-1 16:14:07 | 显示全部楼层
你有种再说一遍 发表于 2024-7-1 14:00
这样说应该就懂了啊,只是箭头哥不懂hash结构,你也不懂吗

不懂
发表于 2024-7-1 16:17:56 | 显示全部楼层

那我好像不知道怎么告诉你好
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-9-8 10:59 , Processed in 0.240506 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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