Jump to content

Scroll through Auto-Generated List in a Drawing


Recommended Posts

Posted

Hello Everybody,

I have a coring drawing have coring number for each core. The problem is that these core numbers are NOT in a sequence (as shown in screenshot below). Is there a suitable method to scroll through each core number in some order i.e. ascending or descending order e.g. core number 7 highlights or shows or anything else visual after core number 8 based on some key combination. Any solution will be helpful. 

 

image.thumb.png.8b00378e790a9e242b3b5115c59cbf1b.png

Posted

Okay instead of above i found one short-cut to pause at each core before the number is added to the coring. Actually i wanted to check various factors for each cores e.g. if the core is not duplicate, the numbering pattern (no pattern detected which is sad) and connection to other layers (not shown). Below is what i got and currently its helping me for my drawing. 

auto_numbering.thumb.gif.fb2efbf7d6621db8cb628032e310fb25.gif

Posted (edited)

Is this more or less what you want?

Test it on my DWG.

 

It searches all blocks called "CORING", which have an attribute called "ID". 

Obviously this needs to be adapted to fit your DWG.

Will you please upload a sample?  Or just tell me the blockname and tag of the ID, if you are using blocks with an attribute

 

Command LTC



;; Get Attribute Value  -  Lee Mac
;; Returns the value held by the specified tag within the supplied block, if present.
;; blk - [ent] Block (Insert) Entity Name
;; tag - [str] Attribute TagString
;; Returns: [str] Attribute value, else nil if tag is not found.
;; http://www.lee-mac.com/attributefunctions.html
(defun LM:getattributevalue ( blk tag / enx )
    (if (and (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk))))))
        (if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
            (cdr (assoc 1 (reverse enx)))
            (LM:getattributevalue blk tag)
        )
    )
)

;; there is a list of lists.  (list (list ID IND)) .  If holds a numeric ID (1 2 3 ...);
;; IND holds the index of the unsorted list
;; This function inseerts a new item, its position in the list depending on its ID.
(defun insert_sorted (lst_sorted id ind / lst_new inserted id_ i)
  (setq inserted nil)
  (setq lst_new (list))
  (if (= (length lst_sorted) 0)
    (progn
      ;; first item, so we insert it
      (setq lst_new (list (list
        id ind
      )))
    )
    (progn
      (setq i 0)
      ;; we loop through the existing list.  When the new ID is smaller than the ID in the list  => we insert the new item there
      (foreach item lst_sorted
        (setq id_ (nth 0 item))
        (if (and (= inserted nil) (< id id_)) (progn
          (setq lst_new (append lst_new (list (list
            id ind
          ))))
          (setq inserted T)
        ))
        ;; continue copying the items from lst_sorted to lst_new
        (setq lst_new (append lst_new (list (list
          (nth 0 item) (nth 1 item)
        ))))
        (setq i (+ i 1))
      )
      ;; if the item isn't inserted yet we add it to the end
      (if (= inserted nil)
        (setq lst_new (append lst_new (list (list
          id ind
        ))))
      )
    )
  )
  lst_new  
)
;; returns the index of the next found item
(defun find_next (list_sorted id / i result)
  (setq i 0)
  (setq result nil)
  (foreach item list_sorted
    (if (= id (nth 0 item))
      (setq result i)
    )
    (setq i (+ i 1))
  )
  result
)

(defun c:ltc ( / ss id ids list_sorted cur_int cur_ind)
  ;; a selection of all coring blocks
  (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 "CORING") )))
  ;; make a list of every ID of those blocks
  (setq i 0)
  (setq ids (list))
  (setq list_sorted (list))
  (repeat (sslength ss)
    (setq id (atoi (LM:getattributevalue (ssname ss i) "ID")))
    (setq ids (append ids (list id)))
    (setq list_sorted (insert_sorted list_sorted id i))
    (setq i (+ i 1))
  )
 
  (setq cur_int (getint "\nEnter ID to start with.  Or press Enter to start from 1.  Press Esc to exit the loop: "))
  (if (not cur_int)
    (setq cur_int 1)
  )
  ;; now select them in order
  (while (setq cur_ind (find_next list_sorted cur_int))
    ;; grip the block
    (sssetfirst nil (ssadd (ssname ss (nth 1 (nth cur_ind list_sorted)))))
    (getstring "\nPress Enter: ")
    (setq cur_int (+ cur_int 1))
  )
  (princ)
)

coring_loop_id.dwg

Edited by Emmanuel Delay
Posted

The block are more than likely numbered in the order they were inserted into the drawing. Perhaps you could select all, sort by coordinates, and renumber.

Posted (edited)

Lee-mac has a auto number lisp that has smarts built in like delete a number and it will renumber.

 

Going back a step how is the original core circles created are they from some form of data file csv txt etc. So add a pt number and read file.

 

Agree with dlanorh about sort.

Edited by BIGAL
Posted

I have attached the file here. It's part of my same problem where i needed to number the cores and then get their x and y coordinates. Fortunately this was excellently solved by Mr. Emmanuel. Now the issue is I have another layer of core numbering (original core numbering done MANUALLY) which needs to be co-related with the auto-generated numbers. I hope the file really helps to understand the situation. Solution given above by Emmanuel is really what i am looking for but needs some fine tuning. 

2nd floor.dwg

All my cores (auto-generated) are on the layer "Cores" and all are simple circle (not blocks). 

 

Again thankful to all for the support. I have to repeat this tedious process for over 22 other drawings so want to perfect it on one and then re-use on the others. 

 

Posted (edited)

Happy with this?

 

I expect your text objects all on layer "0" and color 200 (purple).  As long as you keep it this way, and don't draw any other text objects on layer "0" and color 200, it should work

 

Feel free to adapt this zoom level

 

  (setq zoomlevel 100)  ;; feel free to adapt.

 

I see that there are two sets of numbers (130 on top, 118 on the bottom part), so I'll let you select the objects first (don't worry about selecting other objects, they get filtered out)

 

Command LTC

 

EDIT: Oh yes, using this routine I can see that you're missing number 47 and 113 on the bottom part

 


;; there is a list of lists.  (list (list ID IND)) .  If holds a numeric ID (1 2 3 ...);
;; IND holds the index of the unsorted list
;; This function inseerts a new item, its position in the list depending on its ID.
(defun insert_sorted (lst_sorted id ind / lst_new inserted id_ i)
  (setq inserted nil)
  (setq lst_new (list))
  (if (= (length lst_sorted) 0)
    (progn
      ;; first item, so we insert it
      (setq lst_new (list (list
        id ind
      )))
    )
    (progn
      (setq i 0)
      ;; we loop through the existing list.  When the new ID is smaller than the ID in the list  => we insert the new item there
      (foreach item lst_sorted
        (setq id_ (nth 0 item))
        (if (and (= inserted nil) (< id id_)) (progn
          (setq lst_new (append lst_new (list (list
            id ind
          ))))
          (setq inserted T)
        ))
        ;; continue copying the items from lst_sorted to lst_new
        (setq lst_new (append lst_new (list (list
          (nth 0 item) (nth 1 item)
        ))))
        (setq i (+ i 1))
      )
      ;; if the item isn't inserted yet we add it to the end
      (if (= inserted nil)
        (setq lst_new (append lst_new (list (list
          id ind
        ))))
      )
    )
  )
  lst_new  
)
;; returns the index of the next found item
(defun find_next (list_sorted id / i result)
  (setq i 0)
  (setq result nil)
  (foreach item list_sorted
    (if (= id (nth 0 item))
      (setq result i)
    )
    (setq i (+ i 1))
  )
  result
)

(defun c:ltc ( / ss id ids list_sorted cur_int cur_ind obj zoomlevel)
  (setq zoomlevel 100)  ;; feel free to adapt
  ;; (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 "CORING") )))

  (princ "\nSelect objects: ")
  (setq ss (ssget (list (cons 0 "TEXT") (cons 8 "0")  (cons 62 200) )))
  
  (princ "\nCoring texts found: ")
  (princ (sslength ss))
 
  ;; make a list of every ID of those blocks
  (setq i 0)
  (setq ids (list))
  (setq list_sorted (list))
  (repeat (sslength ss)
    ;;(setq id (atoi (LM:getattributevalue (ssname ss i) "ID")))
    (setq id (atoi (cdr (assoc 1 (entget (ssname ss i))))))
    (setq ids (append ids (list id)))
    (setq list_sorted (insert_sorted list_sorted id i))
    (setq i (+ i 1))
  )
 
  (setq cur_int (getint "\nEnter ID to start with.  Or press Enter to start from 1.  Press Esc to exit the loop: "))
  (if (not cur_int)
    (setq cur_int 1)
  )
  ;; now select them in order
  (while (setq cur_ind (find_next list_sorted cur_int))
    ;; grip the block
    (setq obj (ssname ss (nth 1 (nth cur_ind list_sorted))))
    (command "ZOOM" "OBject" obj "")
    (command "ZOOM" zoomlevel)
    (sssetfirst nil (ssadd obj))
    (getstring "\nPress Enter: ")
    (setq cur_int (+ cur_int 1))
  )
  (princ)
)

Edited by Emmanuel Delay
Posted

As usual many thanks Mr. Emmanuel. This worked like a charm. I am also having a look at lee-mac library which is excellent for numbering. Now the last but not least part (if possible) as i have meeting tomorrow with consultant and he MAY ask is that why the numbering is so RANDOM i.e. numbering starts just anywhere in my selection of cores and then just continues purely randomly. Is there any way to make it bit more regular (like starting from bottom left and continuing in some logical fashion) or there is no way around?

 

Below is amazing gif showing the working of above code and its just perfect. 😍

 

auto_numbering.thumb.gif.a95efe094fbdaf4da6c701e9768ddf38.gif

Posted (edited)

All my cores (auto-generated)

 

Where are they coming from ? if made by some other software then creation order should be correct.

 

Re last number its easy It searches all blocks called "CORING" or text, which have an attribute called "ID".  Just go through all IDS find biggest.

 

As already mentioned you can sort the circle centres there are a few different patterns you can sort on like lower left.

 


; sorts on 1st two items
(setq lst (vl-sort lst '(lambda (x y)
(cond
((= (cadr x)(cadr y))
(< (car x)(car y)))
((< (cadr x)(cadr y)))
))))

Edited by BIGAL
Posted
15 hours ago, BIGAL said:

Re last number its easy It searches all blocks called "CORING" or text, which have an attribute called "ID".  Just go through all IDS find biggest.

 

 

Already the solution is provided by Mr. Emmanuel. Thanks for your and his efforts. 

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