Find nearby objects with Python
Find nearby objects with Python
A quick example on using cad-pyrx kdtree’s to do a radius search. This is a drawing of a sprinkler system, where the parts are inserted as blocks. The goal is to find all the components within a given radius and list them
from pyrx import Db, Ed, Ge, Ap, Rx, Gs
# create a new command in BricsCAD
@Ap.Command()
def doit():
try:
# get modelspace
db = Db.curDb()
model = db.modelSpace()
# get all the block BlockReference
refs = [Db.BlockReference(id) for id in model.objectIds(Db.BlockReference.desc())]
# list and map the positions
allmid = []
pnt_ref_map = {}
for ref in refs:
mid = ref.getGeomExtents().midPoint()
pnt_ref_map[mid] = ref
allmid.append(mid)
# create a kdtree
tree = Ge.Point3dTree(allmid)
# search sphere 6"
rad = 6
# positions we will search from
targets = [ref.position() for ref in refs if ref.getBlockName() == "SPK-51-112-1-160-PW"]
for pnt in targets:
indexs, dists = tree.radiusSearch(pnt, rad * rad)
print("\ngroup")
for idx, dist in zip(indexs, dists):
if dist == 0:
continue
if allmid[idx] in pnt_ref_map:
pnt_ref_map[allmid[idx]].highlight()
print(pnt_ref_map[allmid[idx]].getBlockName())
except Exception as err:
print(err)
Comments
-
Here’s another example, I want to find all the computers located near a phone
import traceback from pyrx import Ap, Ax, Db, Ed, Ge, Gi, command # radiusSearch @command def doit(): db = Db.curDb() phones, computers = getBlocks(db) result = [] # create the tree of phone locations phonePoints = Ge.Point3dArray() for phone in phones: phonePoints.append(phone[1]) phoneTree = Ge.Point3dTree(phonePoints) # search for nerby phones for computer in computers: idxs, _ = phoneTree.radiusSearch(computer[1], 50 * 50)# sqrd if len(idxs) == 0: print("no phone") continue for idx in idxs: result.append((computer, phones[idx])) for cpu, phn in result: Ed.Core.grDraw(cpu[1], phn[1], 2, 0) # helper, store the id and position def getBlocks(db: Db.Database): phones = [] computers = [] model = Db.BlockTableRecord(db.modelSpaceId()) refs = [Db.BlockReference(id) for id in model.objectIds(Db.BlockReference.desc())] for ref in refs: if ref.getBlockName() == "COMPUTER": computers.append((ref.objectId(), ref.position())) elif ref.getBlockName() == "FNPHONE": phones.append((ref.objectId(), ref.position())) return phones, computers0 -
Could not resist, did a "where is" for staff similar method to yours, but added their staff photo to the desk. Used the phone number, a phone block, as the name of the image. Also added a Grid so found me at 5th floor "A1", yes was multiple floors.
For non Pyhton, use SSget "WP" PTS, just make a list of points based on a centre point and a radius. Very easy using (Polar cenpt rad ang). Just keep incrementing ang with small increments. Say (setq inc (/ (* 2 pi) 20)
1 -
Sure, you could do this with lisp, the 3D (r3) search might be hard, also performance might become an issue at scale. I used nanoflann, if your interested in the performance characteristics https://github.com/jlblancoc/nanoflann
My source is here
0




