- 积分
- 10908
- 明经币
- 个
- 注册时间
- 2015-8-18
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
发表于 2024-8-6 17:46:03
|
显示全部楼层
本帖最后由 你有种再说一遍 于 2024-8-7 02:42 编辑
还得接着优化,考虑使用线程安全邻接表和多线程并行,
因为这样才可以把每次识别一条改为多条,提高吞吐量.
写c#重点是一次性完成全部并且尽可能在一秒内,
而不是像lisp一点一点的处理.
本次的优化建议:
- [CommandMethod(nameof(Tt222))]
- public void Tt222() {
- using var tr = new DBTrans();
- while (true) {
- var sw = Stopwatch.StartNew();
- // 链式选择,选择图元对象作为起点种子.
- if (!Env.Editor.SelEnt(out ObjectId lineId)) return;
- // 创建一个队列用于存储待处理的线段...
- 此处储存line有问题,应该改为id,
- 一是储存图元的信息熵巨大,Entity和Entity比较会进入内部逻辑而不是id这样的数值比较.
- 二是不利于后续删除,
- 三是改为多事务的话,Entity跨事务会错乱,甚至有人不小心在跨事务进行写模式.
- // 创建一个列表用于存储符合条件的线段
- var sellines = new HashSet<LineType>();
- var line = lineId.ToEntity();
- var lineType=new LineType(
- line.ObjectId,line.StartPoint,line.EndPoint);
- var queue = new Queue<LineType>();
- queue.Enqueue(lineType);
- // 只要队列不为空就继续循环
- while (queue.Any()) {
- // 不要做无畏的转换,Hash容器可以保证唯一,选择与起点和终点相关的实体加入...按理来说这里用一个ssget就够了...
- HashSet<ObjectId> ids=[];
- var a=Env.Editor.SelEnts(ids);
- if (!a) return;
- var b=Env.Editor.SelEnts(ids);
- if (!b) return;
- // 取出种子线段
- var t = queue.Dequeue();
- foreach (var id in ids) {
- // 当前线段与遍历线段相同则跳过
- if (t.ObjectId==id) continue;
- // 已经添加过该线段则跳过
- var iLine = id.ToEntity();
- var iType=new LineType(
- iLine.ObjectId,iLine.StartPoint,iLine.EndPoint);
- if (sellines.Contains(iType)) continue;
- // 有链接关系
- if (t.IsLink(iType)) {
- sellines.Add(iType);
- queue.Enqueue(iType);
- }
- }
- }
- // 结果列表为空则跳过
- if (!sellines.Any()) continue;
- // 对结果列表中的每个线段执行操作
- sellines.ForEach(id => {
- var ent = id.ToEntity();
- using (ent.ForWrite()) {
- // 切换线段的颜色索引
- ent!.ColorIndex = ent.ColorIndex == 1 ? 2 : 1;
- // 绘制线段
- ent.Draw();
- }
- });
- // 停止计时
- sw.Stop();
- // 输出操作所用的时间
- Env.Editor.WriteMessage($"\n {nameof(Tt222)}用时{sw.Elapsed.TotalMilliseconds}毫秒");
- }
- }
- public class LineType {
- public ObjectId ObjectId;
- public Point3d StartPoint;
- public Point3d EndPoint;
- // 构造函数
- public LineType(ObjectId objectId, Point3d startPoint, Point3d endPoint) {
- ObjectId = objectId;
- StartPoint = startPoint;
- EndPoint = endPoint;
- }
- // IsLink方法
- public bool IsLink(LineType lineB, Tolerance? tol = null) {
- if (tol == null) {
- tol = new Tolerance(1, 1); // 默认容差值
- }
- return
- StartPoint.IsEqualTo(lineB.StartPoint, tol) ||
- StartPoint.IsEqualTo(lineB.EndPoint, tol) ||
- EndPoint.IsEqualTo(lineB.StartPoint, tol) ||
- EndPoint.IsEqualTo(lineB.EndPoint, tol);
- }
- // 使用hashset或者dictionary重写下面
- // GetHashCode方法
- public override int GetHashCode() {
- unchecked { // 允许溢出,避免不必要的异常处理
- return ObjectId.GetHashCode()
- ^= StartPoint.GetHashCode()
- ^= EndPoint.GetHashCode();
- }
- }
- // Equals方法
- public override bool Equals(object obj) {
- return obj is LineType other
- && ObjectId.Equals(other.ObjectId)
- && StartPoint.Equals(other.StartPoint)
- && EndPoint.Equals(other.EndPoint);
- }
- }
- }
|
|