- 积分
- 5816
- 明经币
- 个
- 注册时间
- 2016-10-12
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
[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
|