- 积分
- 5977
- 明经币
- 个
- 注册时间
- 2016-10-12
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 wang2006zhi 于 2025-2-14 12:01 编辑
 - [CommandMethod("W_TKPL")]
- public static void BlockSame()
- {
- using var tr = new DBTrans();
- if (!Env.Editor.GetSelRect(out Rect selRec))
- return;
- //过滤块实体
- var fil = OpFilter.Build(e => e.Dxf(0) != "INSERT");
- if (!Env.Editor.SelIds(out List<ObjectId> ids, selRec.GetPointCollection(), fil))
- return;
- //选取种子集
- if (!Env.Editor.GetEnts(out List<Entity> entsTemp, msg: "请选择要基准集:", fil: fil))
- return;
- //种子集四叉树数据
- var oneGrop = new List<CadEntity>();
- for (int i = entsTemp.Count - 1; i >= 0; i--)
- {
- var ent = entsTemp;
- var cadEnt = new CadEntity(ent.ObjectId, ent.GetRect());
- oneGrop.Add(cadEnt);
- }
- // 种子集外包
- var rectStart = oneGrop.GetCesRect();
- // 参考种子
- var ceSeed = oneGrop[0];
- // 种子集相同的类似集
- var oneSameGrop = new List<List<CadEntity>> { oneGrop };
- //创建一个CAD进度条
- using var pm = new ProgressMeter();
- //添加提示语言
- pm.Start($"正在构建{ids.Count}条四叉树数据...");
- //设置总进度
- pm.SetLimit(ids.Count);
- //构造四叉树数据
- var treeRoot = new QuadTree<CadEntity>(AppX.InfoRect);
- //参考种子集
- var cesSeed = new List<CadEntity>();
- for (int i = ids.Count - 1; i >= 0; i--)
- {
- pm.MeterProgress();
- var id = ids;
- var ent = id.GetObject<Entity>();
- if (ent==null)
- continue;
- var cadEnt = new CadEntity(id, ent.GetRect())
- {
- IsUsed = false,
- IsSeed = false
- };
- if (ceSeed.IsSameEnt(cadEnt))
- {
- cadEnt.IsSeed = true;
- cesSeed.Add(cadEnt);
- }
- treeRoot.Insert(cadEnt);
- }
- pm.Stop();
-
- // #region 原始方案
- // //查找相同种子集
- // treeRoot.ForEach(nodes =>
- // {
- // foreach (var ceTemp in nodes.Contents)
- // {
- // if (!ceTemp.IsGetRect(out Rect recTemp,ceSeed,rectStart))
- // continue;
- // // 用相对外包搜索实体
- // var oneGropTemp = treeRoot.Query(recTemp.Expand(10), QuadTreeSelectMode.Contains);
- // if (!oneGropTemp.Any())
- // continue;
- // //过滤掉与种子集不同的实体
- // var cesSearchTemp = new List<CadEntity>();
- // foreach (var ceOld in oneGrop)
- // {
- // foreach (var ceNew in oneGropTemp)
- // {
- // if (!ceNew.IsUsed && ceNew.IsSameEnt(ceOld))
- // cesSearchTemp.Add(ceNew);
- // }
- // }
- //
- // // 与种子集数目相同时看为一组
- // if (cesSearchTemp.Count != oneGrop.Count)
- // continue;
- // var oneSame = new List<CadEntity>();
- // foreach (var ce in cesSearchTemp)
- // {
- // oneSame.Add(ce);
- // ce.IsUsed = true;
- // }
- // oneSameGrop.Add(oneSame);
- // }
- // return
- // false;
- // });
- // #endregion
- #region 新方案
-
- //添加提示语言
- pm.Start($"正在查找{cesSeed.Count}条可能相同的数据...");
- //设置总进度
- pm.SetLimit(cesSeed.Count);
- //根据种子ceSeed查找相同种子集
- for (int i = cesSeed.Count - 1; i >= 0; i--)
- {
- pm.MeterProgress();
- var ceTemp = cesSeed;
- if (!ceTemp.IsGetRect(out Rect recTemp, ceSeed, rectStart))
- continue;
- // 用相对外包搜索实体
- var oneGropTemp = treeRoot.Query(recTemp.Expand(10), QuadTreeSelectMode.Contains);
- if (!oneGropTemp.Any())
- continue;
- //过滤掉与种子集不同的实体
- //与种子集可能相同的集
- var cesSearchTemp = new List<CadEntity>();
- for (int j = oneGrop.Count - 1; j >= 0; j--)
- {
- var ceOld = oneGrop[j];
- for (int k = oneGropTemp.Count - 1; k >= 0; k--)
- {
- var ceNew = oneGropTemp[k];
- if (!ceNew.IsUsed && ceNew.IsSameEnt(ceOld))
- cesSearchTemp.Add(ceNew);
- }
- }
-
- // 与种子集数目相同时看为一组
- if (cesSearchTemp.Count != oneGrop.Count)
- continue;
- var oneSame = new List<CadEntity>();
- foreach (var ce in cesSearchTemp)
- {
- oneSame.Add(ce);
- ce.IsUsed = true;
- }
- oneSameGrop.Add(oneSame);
- }
- pm.Stop();
- #endregion
-
- // 种子集块
- var blkName = "HesiBlk_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
- var btrId = entsTemp.MakeBlock(blkName);
- //插入块并删除相似集
- //添加提示语言
- pm.Start($"正在插入{oneSameGrop.Count}个图块...");
- //设置总进度
- pm.SetLimit(oneSameGrop.Count);
- oneSameGrop.ForEach(oneSameEs =>
- {
- pm.MeterProgress();
- var pt = GetCesRect(oneSameEs).CenterPoint.Point3d();
- var bId = tr.CurrentSpace.InsertBlock(pt.Ucs2Wcs(), btrId);
- if (bId.GetObject<Entity>() is not BlockReference brf)
- return;
- brf.Layer = "0";
- brf.Draw();
- oneSameEs.ForEach(x => x.ObjectId.GetObject<Entity>()?.ForWrite(e => e.Erase(true)));
- });
- pm.Stop();
-
- Env.Editor.WriteMessage($"\n共插入{oneSameGrop.Count}个图块!");
- }
- private class CadEntity(ObjectId objectId, Rect box) : QuadEntity(box)
- {
- /// <summary>
- /// ObjectId
- /// </summary>
- public readonly ObjectId ObjectId = objectId;
- /// <summary>
- /// 是否已经用过
- /// </summary>
- public bool IsUsed;
- /// <summary>
- /// 是否种子
- /// </summary>
- public bool IsSeed;
- /// <summary>
- /// 大小比对
- /// </summary>
- /// <param name="other"></param>
- /// <returns></returns>
- public int CompareTo(CadEntity? other)
- {
- if (other == null)
- return -1;
- return GetHashCode() ^ other.GetHashCode();
- }
- public override int GetHashCode()
- {
- return (base.GetHashCode(), objectId.GetHashCode()).GetHashCode();
- }
- /// <summary>
- /// 判断外包大小是否相等
- /// </summary>
- /// <param name="other"></param>
- /// <returns></returns>
- private bool IsSameSize(CadEntity other)
- {
- if (ObjectId.Equals(other.ObjectId))
- return false;
- if (Width.IsEqual(other.Width) && Height.IsEqual(other.Height))
- return true;
- return false;
- }
- /// <summary>
- /// 判断两实体是否相同
- /// </summary>
- /// <param name="other"></param>
- /// <returns></returns>
- public bool IsSameEnt(CadEntity other)
- {
- if (!IsSameSize(other))
- return false;
- var entL = ObjectId.GetObject<Entity>();
- var entR = other.ObjectId.GetObject<Entity>();
- if (entR != null && entL != null && entL.IsSameEnt(entR))
- return true;
- return false;
- }
- }
- /// <summary>
- /// 获取集合的边界
- /// </summary>
- /// <param name="ces">四叉树数据集</param>
- /// <returns></returns>
- private static Rect GetCesRect(this List<CadEntity> ces)
- {
- var xMin = ces.Min(x => x.X);
- var yMin = ces.Min(x => x.Y);
- var tMax = ces.Max(x => x.Top);
- var rMax = ces.Max(x => x.Right);
- return new Rect(xMin, yMin, rMax, tMax);
- }
- /// <summary>
- /// 根据nRect中的某一个种子nCe是否成功获取到新的相对Rect
- /// </summary>
- /// <param name="nCe">种子</param>
- /// <param name="nRect">新得的Rect</param>
- /// <param name="oCe">原始种子</param>
- /// <param name="oRect">原始Rect</param>
- /// <returns></returns>
- private static bool IsGetRect(this CadEntity nCe, out Rect nRect, CadEntity oCe, Rect oRect)
- {
- nRect = oRect;
- if (!nCe.IsSeed)
- return false;
- if (nCe.IsUsed)
- return false;
- var vec = nCe.CenterPoint - oCe.CenterPoint;
- nRect = new Rect(oRect.MinPoint + vec, oRect.MaxPoint + vec);
- return true;
- }
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|