Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/27/2025 in all areas

  1. sample of this import traceback import re from pyrx import Db, Ed, Ge, Ap, Rx, Gs def extract_num(s: str): match = re.search(r'\d+', s) if match: return int(match.group()) return -1 @Ap.Command() def doit(): try: # select db = Db.curDb() filter = [(Db.DxfCode.kDxfStart, "TEXT,LWPOLYLINE")] ps, ss = Ed.Editor.select(filter) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) texts = [Db.Text(id) for id in ss.objectIds(Db.Text.desc())] plines = [Db.Polyline(id) for id in ss.objectIds(Db.Polyline.desc())] # make kdtree & list of points pntmap = {} plpoints = [] for pl in plines: plpoints.append(pl.getStartPoint()) plpoints.append(pl.getEndPoint()) pntmap[pl.getStartPoint()] = pl pntmap[pl.getEndPoint()] = pl # search closest pline results = [] tree = Ge.Point3dTree(plpoints) for text in texts: idxs, _ = tree.knnSearch(text.position(), 1) pl: Db.Polyline = pntmap[plpoints[idxs[0]]] results.append([text.textString(), pl.getDistAtParam(pl.getEndParam())]) # format mtext results = sorted(results, key=lambda x: extract_num(x[0])) buffer = "{:<6}\t{}\\P".format("S.No", "Length Ft") buffer += "".join(f"{sno:<6}\t {plen:>.2f}\\P" for sno, plen in results) # make mtext, add to currentSpace ps, pnt = Ed.Editor.getPoint("\nPick Text Position") mt = Db.MText() mt.setDatabaseDefaults(db) mt.setLocation(pnt) mt.setContents(buffer) cs = db.currentSpace(Db.OpenMode.kForWrite) cs.appendAcDbEntity(mt) except Exception as err: traceback.print_exception(err)
    1 point
  2. I don't tend to annotative dims as much as perhaps I should but will see what I can dig out
    1 point
  3. @devitg sample dwg upload for reference @GLAVCVS It may not function correctly, possibly due to the direction(clockwise or counterclockwise) of the arc or because it does not meet the point on the arc. mb.dwg
    1 point
  4. Filters Instead of creating a dedicated ResultBuffer class like in .NET, I decided to build a wrapper for Python’s built in types. Throughout the API, resbuf* or ResultBuffer are simply a list of tuples, in the format of a group code and a value typedValues = [(TYPE, VALUE)] Depending on the context the group code may be a Lisp type code, or in the case of selection sets, DXF codes. Here are two possible formats # long format filter = [ (Db.DxfCode.kDxfStart, "TEXT,LWPOLYLINE,LINE"), (Db.DxfCode.kDxfOperator, "<OR"), (Db.DxfCode.kDxfLayerName, "0"), (Db.DxfCode.kDxfLayerName, "8"), (Db.DxfCode.kDxfOperator, "OR>"), ] # short format filter = [ (0, "TEXT,LWPOLYLINE,LINE"), (-4, "<OR"), (8, "Layer1"), (8, "Layer2"), (8, "Layer3"), (-4, "OR>"), ]
    1 point
  5. SelectionSet class methods class SelectionSet: def add(self, id: Db.ObjectId, /) -> None: ... def adsname(self, /) -> Db.AdsName: ... def clear(self, /) -> None: ... def hasMember(self, id: Db.ObjectId, /) -> bool: ... def objectIdArray(self, desc: Rx.RxClass = Db.Entity, /) -> Db.ObjectIdArray: ... def objectIds(self, desc: Rx.RxClass = Db.Entity, /) -> list[Db.ObjectId]: ... def remove(self, id: Db.ObjectId, /) -> None: ... def size(self, /) -> int: ... def ssNameX(self, val: int = 0, /) -> list: ... def ssSetFirst(self, /) -> bool: ... def ssXform(self, xform: Ge.Matrix3d, /) -> Ed.PromptStatus: ... def toList(self, /) -> list[Db.ObjectId]: ... Note, ObjectIdArray is basically the same as list[Db.ObjectId], but the memory is allocated in C++ instead of Python. There may be performance reasons to choose one of the the other, but for now, they can be used interchangeably
    1 point
  6. Lets say we want only lines and arcs, but still want to use AcDbCurve class, pass a list of descriptions # returns a PromptStatus and a SelectionSet class ps, ss = Ed.Editor.select([(8, "0")]) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) curves = [Db.Curve(id) for id in ss.objectIds([Db.Line.desc(),Db.Arc.desc()])] for curve in curves: print(curve.getDistAtParam(curve.getEndParam()))
    1 point
  7. Support derived types, Lets say you want to get all the objects in the set that are derived from AcDbCurve, to do some sort of base class operation (AcDb2dPolyline, AcDb3dPolyline, AcDbArc, AcDbCircle, AcDbEllipse, AcDbLeader, AcDbLine, AcDbPolyline, AcDbRay, AcDbSpline, AcDbXline) # returns a PromptStatus and a SelectionSet class ps, ss = Ed.Editor.select([(8, "0")]) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) curves = [Db.Curve(id) for id in ss.objectIds(Db.Curve.desc())] for curve in curves: print(curve.getDistAtParam(curve.getEndParam()))
    1 point
  8. The real power is post filtering entity types, for example, we want the selection set to filter the visual selection set on screen, but then we want to separate out objects by type. SelectionSet.objectIds() method is overloaded to take an entity class description and returns the types that match. it does not open the object, so it’s extremely fast #returns a PromptStatus and a SelectionSet class ps, ss = Ed.Editor.select([(0, "TEXT,LWPOLYLINE,LINE")]) if ps != Ed.PromptStatus.eOk: raise RuntimeError("Selection Error! {}: ".format(ps)) # create a list of entites ant are opened for read texts = [Db.Text(id) for id in ss.objectIds(Db.Text.desc())] lines = [Db.Line(id) for id in ss.objectIds(Db.Line.desc())] plines = [Db.Polyline(id) for id in ss.objectIds(Db.Polyline.desc())] for text in texts: pass # do something for line in lines: pass # do something for pline in plines: pass # do something
    1 point
  9. The SelectionSet class is an enumerable collection of ObjectIds, example #returns a PromptStatus and a SelectionSet class ps, ss = Ed.Editor.select() for id in ss: ent = Db.Entity(id) print(ent.isA().dxfName())
    1 point
  10. SelectionSet filters can also be inline Ed.Editor.select([(0, "TEXT,LWPOLYLINE,LINE")])
    1 point
  11. Entmake text style. (entmake '((0 . "STYLE") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord") (2 . "style name here") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 1.0) (3 . "Arial.ttf") (4 . "") ) ) use setvar for dimstyles nothing will be outputted to command prompt. (setvar 'DIMADEC 2) (setvar 'DIMALT "off") I think @Steven P has dug into this more.
    1 point
  12. A version also for closed polylines. Minimally tested... centerPline_v2.LSP
    1 point
  13. This is kind of close, I split each line into some number of segments, then use closest point. Simplify reduces the number of segments, but changes the precision. Not sure if you can do this in lisp import traceback from pyrx import Db, Ed, Ge, Ap, Rx, Gs @Ap.Command() def centline(): try: ps1, id1, _ = Ed.Editor.entSel("\nPick 1") ps2, id2, _ = Ed.Editor.entSel("\nPick 2") pl1 = Db.Polyline(id1) pl2 = Db.Polyline(id2) crv1 = pl1.getAcGeCurve() crv2 = pl2.getAcGeCurve() #divide into eq segs segs = max(pl1.numVerts(), pl2.numVerts()) * 2 smp1, _ = crv1.getSamplePoints(segs) smp2, _ = crv2.getSamplePoints(segs) spl1 = pl1.getSplitCurves(smp1) spl2 = pl2.getSplitCurves(smp2) pnts = [] pnts.append(pl1.getStartPoint() + (pl2.getStartPoint() - pl1.getStartPoint()) * 0.5) for l, r in zip(spl1, spl2): cl = l.getAcGeCurve() cr = r.getAcGeCurve() poc1, poc2 = cl.getClosestPointsTo(cr) p1 = poc1.point3d() p2 = poc2.point3d() pnts.append(p1 + (p2 - p1) * 0.5) pnts.append(pl1.getEndPoint() + (pl2.getEndPoint() - pl1.getEndPoint()) * 0.5) db = Db.curDb() cs = db.currentSpace(Db.OpenMode.kForWrite) npl = Db.Polyline(pnts) npl.setLayer("0") npl.setColorIndex(3) cs.appendAcDbEntity(npl) except Exception as err: traceback.print_exception(err) drawing AxisExample_dan.dwg
    1 point
  14. I used a similar approach here, the user wanted to set the elevation of the contour lines to the nearest label. This is where KD-Trees really start to shine as they can handle millions of points, with millions of searches
    1 point
  15. Yep, easier too, since there would be not need to format the string for MText. Even though Python has robust string operations, it’s still weird to get it perfect https://docs.python.org/3/library/string.html I was just following along the original sample. The part I wanted to illustrate was, using a hashmap for mapping points to objects, and using the KD-Tree to do the spatial search I wrote the same KD-Tree and map for AutoLISP, I’m just really bad at lisp, so it’s hard for me to make samples lol https://github.com/CEXT-Dan/ads_geo
    1 point
  16. It will require more modification than just extending the bulge list - you also need to calculate the positions of the additional vertices. However, I really liked your suggestion (and it's also consistent with my existing Box Text program), and so I've updated the program to Version 1.3 to incorporate a new Filleted Rectangle textbox option (you may need to refresh the page to view the new version). Enjoy!
    1 point
  17. here's something in Python, if you can find anything in lisp
    1 point
  18. A dimension style can have a prefix and or a suffix so create a style with suffix ".
    1 point
×
×
  • Create New...