Jump to content

Lisp Help...


Recommended Posts

Posted (edited)

It can vary depending on the design of the frame, but the project I am working on includes 4 different types of panels in each frame. I want to create a LISP routine that counts panels based on their attributes and the values input by the user. For example, if there are 2 clear glass panels (GL3 & GL5) at the bottom and 2 spandrel panels (SP5) at the top of frame 5, I want the LISP to filter through the drawing and count how many panels of each type are in frame 5.

I’m not sure if I’m making sense, but there are many different frames, and for each frame, I sometimes need to know how many SP5 panels are in each one.

Therefore, I’d like to create a LISP routine that can filter and give me the result I need.

 

I tried making one but I am getting an error as following:

 

            CPF

            288 blocks selected.; error: bad association list: (-1 . <Entity name: 21d9963f3d0>)

 

I created a command CPF and when I tested it I am getting an error. How can I modify this lisp to make it work?

It would be beneficial if I can get a list of which types of panels are in frame x. 

(defun tostr (x)
  (cond
    ((stringp x) x)
    ((numberp x) (itoa x))
    (t "None")
  )
)

(defun GetBlockAttribute (blk attName)
  (setq attValue nil)
  
  ;; Ensure the entity is a block reference and exists
  (if (and blk (eq (cdr (assoc 0 (entget blk))) "INSERT"))
    (progn
      (setq blkData (entget blk))  ;; Retrieve block data
      
      ;; Loop through the block data to find the attribute
      (foreach ent blkData
        (if (and (assoc 0 ent)
                 (equal (cdr (assoc 0 ent)) "ATTRIB")  ;; Ensure it's an attribute
                 (assoc 2 ent) (equal (cdr (assoc 2 ent)) attName)) ;; Matching attribute name
          (progn
            (if (assoc 1 ent)
              (setq attValue (cdr (assoc 1 ent)))  ;; Retrieve the value of the attribute
            )
          )
        )
      )
      
      ;; Debugging output for attributes
      (if attValue
        (princ (strcat "\nAttribute " attName " found: " attValue))
        (princ (strcat "\nAttribute " attName " not found.")))
    )
    (princ (strcat "\nInvalid block entity: " (tostr blk)))  ;; Error if not a block reference
  )
  attValue
)

(defun update-panel-count (panelData panelType panelValue)
  (setq panelCount (assoc panelType panelData))
  (if (and panelValue (not (= panelValue "None"))) ;; Check if panel value is valid
    (if panelCount
      (progn
        (setq newCount (+ (cdr panelCount) 1))
        (setq panelData (subst (cons panelType newCount) panelCount panelData))
      )
      (setq panelData (cons (cons panelType 1) panelData))
    )
  )
  panelData
)

(defun c:CPF (/ ss blk i frameNumber panel1 panel2 panel3 panel4 
                   panelCounts frameData panelData)
  ;; Ensure we're selecting blocks only
  (setq ss (ssget "X" '((0 . "INSERT"))))  ;; Only select blocks (INSERT)
  
  ;; Check if selection set is empty
  (if (not ss)
    (progn
      (princ "\nNo blocks selected.")
      (exit)
    )
  )
  
  (princ (strcat "\n" (itoa (sslength ss)) " blocks selected."))
  (setq i 0)
  
  ;; Initialize panelCounts to track panel types for each frame
  (setq panelCounts '())
  
  ;; Loop through the selection set and extract attributes
  (while (< i (sslength ss))
    (setq blk (ssname ss i))
    
    ;; Ensure it's a valid block reference
    (if (eq (cdr (assoc 0 (entget blk))) "INSERT")
      (progn
        ;; Get attributes by name (exactly "FRAME_NUMBER", "PANEL_1", etc.)
        (setq frameNumber (GetBlockAttribute blk "FRAME_NUMBER"))
        (setq panel1      (GetBlockAttribute blk "PANEL_1"))
        (setq panel2      (GetBlockAttribute blk "PANEL_2"))
        (setq panel3      (GetBlockAttribute blk "PANEL_3"))
        (setq panel4      (GetBlockAttribute blk "PANEL_4"))
        
        ;; Debugging: Check the retrieved attribute values
        (princ (strcat "\nBlock " (itoa i) ": "))
        (princ (strcat " FRAME: " (tostr frameNumber)))
        (princ (strcat " PANEL_1: " (tostr panel1)))
        (princ (strcat " PANEL_2: " (tostr panel2)))
        (princ (strcat " PANEL_3: " (tostr panel3)))
        (princ (strcat " PANEL_4: " (tostr panel4)))
        
        ;; Process only if all attributes are found and are not "None"
        (if (and frameNumber panel1 panel2 panel3 panel4)
          (progn
            ;; Check if frame number exists in panelCounts
            (setq frameData (assoc frameNumber panelCounts))
            
            (if frameData
              (progn
                ;; Update panel data
                (setq panelData (cdr frameData))
                (setq panelData (update-panel-count panelData "PANEL_1" panel1))
                (setq panelData (update-panel-count panelData "PANEL_2" panel2))
                (setq panelData (update-panel-count panelData "PANEL_3" panel3))
                (setq panelData (update-panel-count panelData "PANEL_4" panel4))
                
                ;; Update the panelCounts list with new panel data
                (setq panelCounts (subst (cons frameNumber panelData) frameData panelCounts))
              )
              ;; If frameData doesn't exist, create new entry for frame number
              (setq panelCounts (cons (cons frameNumber (list (cons "PANEL_1" 1)
                                                              (cons "PANEL_2" 1)
                                                              (cons "PANEL_3" 1)
                                                              (cons "PANEL_4" 1)))
                                      panelCounts))
            )
          )
          ;; Debugging: If attributes are missing, print a message
          (princ (strcat "\nError: Missing or invalid attribute(s) for block " (itoa i)))
        )
      )
      ;; If the entity is not a block reference, print a warning
      (princ (strcat "\nSkipping non-block entity at index " (itoa i)))
    )
    
    (setq i (1+ i))
  )
  
  ;; Output the panel count summary
  (princ "\nPanel Count Summary:")
  (foreach frame panelCounts
    (setq frameNumber (car frame))
    (setq panelData (cdr frame))
    (princ (strcat "\nFrame " (tostr frameNumber) ":"))
    (foreach panel panelData
      (princ (strcat "\n  " (car panel) " - " (tostr (cdr panel))))))

  (princ)
)


 

Edited by SLW210
Added Code Tags!!
Posted

In the future please place your code in Code Tags. (<> in the editor toolbar)

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...