Jump to content

Python for AutoLISP Users part 1:


Recommended Posts

Posted

I thought I might write some samples to help guide lisp users that are interested in trying out Python.

 

Long time lisp users will feel right at home using result buffers (DXF Lists). In PyRx, it’s wrappers around the old school C ADS functions, I.e. ads_entget, yay, like driving an F-150 with a toilet bowl plunger as the gear shift. In Python, most of these old functions reside in Db.Core

 

The resbuf* linked lists are wrapped into a list of tuples.. does this output look familiar?

 

from pyrx import Ap, Db, Ed, Ge

@Ap.Command()
def doit0() -> None:
    
    #entsel with a filter
    ps, id, _ = Ed.Editor.entSel("\nPick it: ", Db.Line.desc())
    if ps != Ed.PromptStatus.eOk:
        raise RuntimeError("oof {}:".format(ps))

    #get the result buffer 
    rb = Db.Core.entGet(id)
    print(rb)
    # [
    # (-1, PyDb.ObjectId(1de8bf954d0)), 
    # (0, 'LINE'), 
    # (330, PyDb.ObjectId(1de8bf9a1f0)), 
    # (5, '265'), 
    # (100, 'AcDbEntity'),
    # (67, 0), 
    # (410, 'Model'), 
    # (8, '0'), 
    # (100, 'AcDbLine'),
    # (10, PyGe.Point3d(0.00000000000000,0.00000000000000,0.00000000000000)), 
    # (11, PyGe.Point3d(100.00000000000000,100.00000000000000,0.00000000000000)),
    # (210, PyGe.Point3d(0.00000000000000,0.00000000000000,1.00000000000000))
    # ]

 

Posted

In Python, there isn’t an assoc function, we can iterate through and search for a DXF code

 

from pyrx import Ap, Db, Ed, Ge


@Ap.Command()
def doit1() -> None:
    
    # entsel with a filter
    ps, id, _ = Ed.Editor.entSel("\nPick it: ", Db.Line.desc())
    if ps != Ed.PromptStatus.eOk:
        raise RuntimeError("oof {}:".format(ps))

    # get the result buffer 
    rb = Db.Core.entGet(id)

    # 1. Analog to Lisp: (assoc 8 rb) -> Returns the full pair (8, "LayerName")
    dxf_code, value = next((item for item in rb if item[0] == 8), None)
    
    # 2. Extract just the value safely
    if dxf_code:
        print(f"The layer is: {value}")

 

Posted

In Python, tuples are immutable, so if we want to modify the list, you have to replace it. In this sample we modify the start and end of a line

 

from pyrx import Ap, Db, Ed, Ge

@Ap.Command()
def doit3() -> None:
    
    #entsel with a filter
    ps, id, _ = Ed.Editor.entSel("\nPick it: ", Db.Line.desc())
    if ps != Ed.PromptStatus.eOk:
        raise RuntimeError("oof {}:".format(ps))

    #get the result buffer 
    rb = Db.Core.entGet(id)

    # Loop through the result buffer list and modify matching DXF codes
    for i, item in enumerate(rb):
        dxf_code = item[0]
        if dxf_code == 10:
            rb[i] = (10, Ge.Point3d(0, 0, 0))
        elif dxf_code == 11:
            rb[i] = (11, Ge.Point3d(100, 100, 0))

    # Apply changes back to the AutoCAD database
    Db.Core.entMod(rb)

 

Posted

This might be better example, maybe similar to the COND expression?

 

from pyrx import Ap, Db, Ed, Ge

@Ap.Command()
def doit4() -> None:
    ps, id, _ = Ed.Editor.entSel("\nPick it: ", Db.Line.desc())
    if ps != Ed.PromptStatus.eOk:
        raise RuntimeError("oof {}:".format(ps))
    
    #get the result buffer 
    rb = Db.Core.entGet(id)
    
    # Process the result buffer using structural pattern matching
    updated_rb = []
    for item in rb:
        match item:
            case (10, _):
                updated_rb.append((10, Ge.Point3d(0, 0, 0)))
            case (11, _):
                updated_rb.append((11, Ge.Point3d(100, 100, 0)))
            case _:
                updated_rb.append(item)
         
    # Apply changes back to the AutoCAD database       
    Db.Core.entMod(updated_rb)

 

Posted (edited)

And top it off with entMake

 

from pyrx import Ap, Db, Ed, Ge

@Ap.Command()
def doit5() -> None:
    Db.Core.entMake([(0 , "LINE"),(10, Ge.Point3d(0, 0, 0)),(11, Ge.Point3d(100, 100, 0))]) 

 

Edited by Danielm103

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...