获取块内实体 封装

using System;

using System.Collections.Generic;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

namespace CadTools

{

/// <summary>

/// 嵌套实体拾取结果

/// </summary>

public class NestedPickResult

{

/// <summary>

/// 最终命中的实体ID

/// </summary>

public ObjectId EntityId;

/// <summary>

/// 最终命中的实体

/// </summary>

public Entity Entity;

/// <summary>

/// 从外到内的块路径

/// </summary>

public List<ObjectId> BlockPath = new List<ObjectId>();

/// <summary>

/// 累计变换矩阵

/// </summary>

public Matrix3d Transform = Matrix3d.Identity;

}

public static class NestedEntityHelper

{

/// <summary>

/// 按点获取最深层嵌套实体

/// </summary>

/// <param name="db">数据库</param>

/// <param name="pt">世界坐标点</param>

/// <param name="tol">命中容差</param>

/// <returns></returns>

public static NestedPickResult 按点获取最深层嵌套实体(

this Database db,

Point3d pt,

double tol = 1.0)

{

if (db == null)

return null;

NestedPickResult result = null;

using (Transaction tr = db.TransactionManager.StartTransaction())

{

BlockTable bt =

(BlockTable)tr.GetObject(

db.BlockTableId,

OpenMode.ForRead);

BlockTableRecord ms =

(BlockTableRecord)tr.GetObject(

btBlockTableRecord.ModelSpace,

OpenMode.ForRead);

FindInBlock(

tr,

ms,

pt,

Matrix3d.Identity,

new List<ObjectId>(),

tol,

ref result);

tr.Commit();

}

return result;

}

/// <summary>

/// 递归扫描块

/// </summary>

private static bool FindInBlock(

Transaction tr,

BlockTableRecord btr,

Point3d worldPt,

Matrix3d currentTransform,

List<ObjectId> path,

double tol,

ref NestedPickResult result)

{

bool found = false;

foreach (ObjectId id in btr)

{

Entity ent =

tr.GetObject(id, OpenMode.ForRead) as Entity;

if (ent == null)

continue;

// 先处理块参照

BlockReference br = ent as BlockReference;

if (br != null)

{

Matrix3d newTransform =

currentTransform * br.BlockTransform;

BlockTableRecord childBtr;

try

{

ObjectId btrId =

br.IsDynamicBlock

? br.DynamicBlockTableRecord

: br.BlockTableRecord;

childBtr =

(BlockTableRecord)tr.GetObject(

btrId,

OpenMode.ForRead);

}

catch

{

continue;

}

if (!PointInsideEntityExtents(

br,

worldPt,

currentTransform,

tol))

{

continue;

}

List<ObjectId> newPath =

new List<ObjectId>(path);

newPath.Add(br.ObjectId);

if (FindInBlock(

tr,

childBtr,

worldPt,

newTransform,

newPath,

tol,

ref result))

{

found = true;

}

}

// 当前实体命中检测

if (EntityHitTest(

ent,

worldPt,

currentTransform,

tol))

{

result = new NestedPickResult();

result.EntityId = ent.ObjectId;

result.Entity = ent;

result.BlockPath =

new List<ObjectId>(path);

result.Transform =

currentTransform;

found = true;

}

}

return found;

}

/// <summary>

/// 实体命中测试

/// </summary>

private static bool EntityHitTest(

Entity ent,

Point3d worldPt,

Matrix3d transform,

double tol)

{

try

{

if (!PointInsideEntityExtents(

ent,

worldPt,

transform,

tol))

{

return false;

}

Curve curve = ent as Curve;

if (curve != null)

{

Curve clone =

curve.GetTransformedCopy(transform)

as Curve;

Point3d closest =

clone.GetClosestPointTo(

worldPt,

false);

double dist =

closest.DistanceTo(worldPt);

clone.Dispose();

return dist <= tol;

}

return true;

}

catch

{

return false;

}

}

/// <summary>

/// 包围盒快速过滤

/// </summary>

private static bool PointInsideEntityExtents(

Entity ent,

Point3d pt,

Matrix3d transform,

double tol)

{

try

{

Extents3d ext = ent.GeometricExtents;

ext.TransformBy(transform);

return

pt.X >= ext.MinPoint.X - tol &&

pt.X <= ext.MaxPoint.X + tol &&

pt.Y >= ext.MinPoint.Y - tol &&

pt.Y <= ext.MaxPoint.Y + tol &&

pt.Z >= ext.MinPoint.Z - tol &&

pt.Z <= ext.MaxPoint.Z + tol;

}

catch

{

return false;

}

}

}

}

相关推荐
我才是银古2 天前
大坐标、镜像与弦高:.NET CSG 库的工程笔记
3d·cad·csg
笨蛋©3 天前
[实战] 扫描图纸转DXF:2026年制造业数字化图纸处理与GD&T识别实操指南
ai·数字化·cad·质量管理·制造业
笨蛋©3 天前
2026制造业质量数字化:Infra CONVERT 中国代理技术支持下的检验计划自动化实战
ai·数字化·cad·质量管理·制造业
我才是银古6 天前
AI 啃 DWG图纸:从二维到三维
ai·cad·dwg
笨蛋©9 天前
[实战] 2026年工程图纸扫描转DXF的精度控制与数字化质量管理流程
ai·数字化·cad·质量管理·制造业
广州智造11 天前
Radioss复合材料使用的单元属性
前端·设计·cad·建模·cae·radioss
:mnong12 天前
几何内核“四大金刚“:ACIS、Parasolid、CGM、Open CASCADE 核心特征深度解析
c++·cad·cax
逸模20 天前
POC验证:怎么在不踩坑的前提下试一个新工具?
cad·revit·设计图·翻模·si标准
️公子21 天前
从经验到程序:线束制造数字化的组装工作台、CAD 与轻量 MES 架构拆解
智能制造·cad·数字化转型·mes·线束·工业软件
逸模1 个月前
开店前先在电脑里试一遍,这叫数字孪生
cad·revit·设计图·翻模·si标准