格式刷的測試例子
寫了個顏色格式刷的例子,大佬們還有哪些地方需要改?
private static string GetPointOptionsMessage() => "\n选择图元或 [字典(D)/随层(S)] ";
private static readonly List<string> ignorePatterName = ["SOLID", "ANSI37", "ANSI31"];
private static readonly List<string> ignoreBlockName = ["Elevation", "ANSI37", "ANSI31"];
private static readonly Dictionary<List<int>, (string, short, short)> reflectDic = new(){
{ , (layers.DimLayer_Name,layers.DimLayer_Color,256) },
{ , (layers.DimLayer_Name,layers.DimLayer_Color,4) }
};
public static void BBest()
{
PromptSelectionOptions entOpts = new()
{
MessageForAdding = GetPointOptionsMessage()
};
PromptSelectionResult r1 = Env.Editor.GetSelection(entOpts);
if (r1.Status == PromptStatus.OK)
{
using DBTrans tr = new();
List<ObjectId> entWillBeSelected = [];
var ids = r1.Value.GetObjectIds().ToList();
for (int i = ids.Count - 1; i >= 0; i--)
{
var ent = (Entity)tr.GetObject(ids);
if (ent is Dimension dim)
{
if (dim.Layer == layers.DimLayer_Name && dim.ColorIndex == 256)
continue;
using (dim.ForWrite())
dim.SetProperty("0", layers.DimLayer_Name, layers.DimLayer_Color);
entWillBeSelected.Add(ent.ObjectId);
}
if (ent is Hatch hatch)
{
if (!ignorePatterName.Contains(hatch.PatternName))
continue;
using (hatch.ForWrite())
hatch.SetProperty("0", layers.EL_250_Name, layers.EL_250_Color);
entWillBeSelected.Add(ent.ObjectId);
}
if (ent is BlockReference brf)
{
#if Debug
Env.Printl($"块名:{brf.Name} ,图块:{brf.Layer}");
#endif
var btrId = brf.BlockTableRecord;
var btr = (BlockTableRecord)tr.GetObject(btrId);
if (btr.IsFromExternalReference)
{
Env.Printl($"块名:{brf.Name} ,来自外部块!");
continue;
}
foreach (var entId in btr)
{
//Env.Printl($"dxfname:{entId.ObjectClass.DxfName}");
var bent = (Entity)tr.GetObject(entId);
//using (bent.ForWrite())
// bent.ColorIndex = 1;
if (bent is Line or Polyline or Circle)
{
if (NewMethod(tr, entWillBeSelected, bent))
entWillBeSelected.Add(ent.ObjectId);
entWillBeSelected.Remove(bent.ObjectId);
}
}
tr.Editor?.Regen(); // 更新图纸
}
if (ent is Line or Polyline or Circle)
NewMethod(tr, entWillBeSelected, ent);
}
tr.Editor?.SetImpliedSelection(entWillBeSelected.ToArray());
}
}
private static bool NewMethod(DBTrans tr, List<ObjectId> entWillBeSelected, Entity ent, bool isChanged = false)
{
if (ent is Line or Polyline or Circle)
{
var color = tr.GetEntityColor(ent);
foreach (var key in reflectDic.Keys)
if (key.Contains(color))
{
#if Debug
Env.Printl($"类型:{ent.GetType().Name} ,包含:{color}");
var value = reflectDic;
Env.Printl($"字典:{value.Item1}、{value.Item2}、{value.Item3}");
#endif
if (ent.Layer != value.Item1)
{
isChanged = true;
entWillBeSelected.Add(ent.ObjectId);
using (ent.ForWrite())
{
ent.SetProperty("0", value.Item1, value.Item2);
ent.ColorIndex = value.Item3;
};
}
}
}
return isChanged;
}
namespace ArrowTools;
public static class AttributeBrushToos
{
/// <summary>
/// 获取实体的真实颜色值
/// </summary>
/// /// <remarks>
/// 备注:<br/>
/// 0x01 颜色Bylayer:返回图层颜色值<br/>
/// 0x02 颜色不随层:返回entity的颜色值<br/>
/// </remarks>
/// <param name="tr"></param>
/// <param name="ent"></param>
/// <returns>颜色真实值</returns>
public static int GetEntityColor<T>(this DBTrans tr, T ent) where T : Entity
{
int colorindex = ent.ColorIndex;
if (colorindex == 256)
{
var layerId = tr.LayerTable;
var layer = (LayerTableRecord)tr.GetObject(layerId);
colorindex = layer.Color.ColorIndex;
}
return colorindex;
}
}
本帖最后由 和尚777 于 2024-7-1 18:02 编辑
static HashSet<string> IgnorePatterName => ["SOLID", "ANSI37", "ANSI31"];
static (string, short, short) info => ("1", 1, 256);
static Dictionary<int, (string LayerName, short Color, short ColorIndex)> ReflectDic => new(){
{ 7, info },
{ 3, info },
{ 1, ("2",2,4) }
};
本帖最后由 你有种再说一遍 于 2024-6-30 03:37 编辑
foreach (var key in reflectDic.Keys)
if (key.Contains(color))
这个数据结构看起来就有问题,
遍历了keys,然后key是list又遍历了一次,所以时间复杂度是O(n*m),
完全没有利用好hash特性嘛.
不过由于数据量太少了,所以命中比求hash还快,hash还要跑个除法器...
看起来虽然奇怪的感觉,但是跑起来也不差.
就好像肛门虽然松了,但是痔疮又很好的弥补了这一点.
如果数据量大起来再讨论这个词典的意义吧.
hash值這個是我的盲區,得補下這部份內容了。寫的時候感覺遍歷了好多次怪怪的,這麼一說確實得改進下,判斷類型那里也改進下,判斷是不是curve就得了,不然還得arc 樣條曲線、橢圓、等挨個判斷太麻煩了。
private static bool NewMethod(DBTrans tr, List<ObjectId> entWillBeSelected, Entity ent, bool isChanged = false)
{
if (ent is Curve)
{
var color = tr.GetEntityColor(ent);
foreach (var key in reflectDic.Keys)
if (key.Contains(color))
{
#if Debug
Env.Printl($"类型:{ent.GetType().Name} ,包含:{color}");
var value = reflectDic;
Env.Printl($"字典:{value.Item1}、{value.Item2}、{value.Item3}");
#endif
if (ent.Layer != value.Item1)
{
isChanged = true;
entWillBeSelected.Add(ent.ObjectId);
using (ent.ForWrite())
{
ent.SetProperty("0", value.Item1, value.Item2);
ent.ColorIndex = value.Item3;
};
}
}
}
return isChanged;
} 本帖最后由 你有种再说一遍 于 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
有无效if请使用else if,想办法避免大括号,不建议使用ed.regen 你有种再说一遍 发表于 2024-6-30 03:13
这个数据结构看起来就有问题,
遍历了keys,然后key是list又遍历了一次,所以时间复杂度是O(n*m),
完全没 ...
大神优化下 moranyuyan 发表于 2024-7-1 09:42
大神优化下
这样说应该就懂了啊,只是箭头哥不懂hash结构,你也不懂吗 你有种再说一遍 发表于 2024-7-1 14:00
这样说应该就懂了啊,只是箭头哥不懂hash结构,你也不懂吗
不懂 moranyuyan 发表于 2024-7-1 16:14
不懂
那我好像不知道怎么告诉你好
页:
[1]