Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Assigning attributes to blocks using polyline to sequence order

68 REPLIES 68
Reply
Message 1 of 69
kirwan59
4737 Views, 68 Replies

Assigning attributes to blocks using polyline to sequence order

Does anybody know of a routine that will allow to draw a polyline through existing blocks, in the order the blocks should be numbered? Therefore when the sequence has been specified by the polyline then user to define the number system required, and the blocks are automatically numbered in the sequence of the polyine start to finish. Smiley Indifferent

68 REPLIES 68
Message 2 of 69
pbejse
in reply to: kirwan59


@kirwan59 wrote:

..... draw a polyline through existing blocks, in the order the blocks should be numbered? Therefore when the sequence has been specified by the polyline then user to define the number system required, and the blocks are automatically numbered in the sequence of the polyine start to finish. Smiley Indifferent


Will it keep the polyline?

What is your number system?

Mulitple attributes in one block?

 

Post a sample of your block.


 

Message 3 of 69
pbejse
in reply to: pbejse

Try this: <as a starting point>

 

(defun c:test (/ strt pt1 pt2 ptl blk)
(vl-load-com)
(setq strt (getint "\nStart Number:"))      
(setq pt1 (getpoint "\nPick point:") ptl (list pt1))
          (while (setq pt2 (getpoint pt1 "\nNext point"))(grdraw pt1 pt2 7)
            	          (setq  ptl (cons pt2 ptl) pt1 pt2)
                   )
      (if ptl (progn
		(entmakex (append (list (cons 0 "LWPOLYLINE")
		                          (cons 100 "AcDbEntity")
		                          (cons 100 "AcDbPolyline")
		                          (cons 90 (length ptl))
		                          )
		                    (mapcar (function (lambda (p) (cons 10 p))) ptl)))
		(foreach pts (reverse ptl)
                      (setq blk
	          	(vlax-invoke
	                      (vlax-get (vla-get-ActiveLayout
	                                               (vla-get-activedocument
	                                                     (vlax-get-acad-object)))
	                                         'Block)
	                                   'InsertBlock
	                                   pts
	                                   "BlockName"
	                                   1 1 1 0))
          	
          	(vla-put-textstring (car (vlax-invoke blk 'Getattributes)) (itoa strt))
          	(setq strt (1+ strt))
          )
                )
          )
      )

 

This code assume the block "blockname" is existing, only one attribute on the block, and the polyline will remain,

 

 

 

Message 4 of 69
stevor
in reply to: pbejse

Until Kinwan returns, my guess is that he has inserts with sequential attribute values, and wishes to track their location by/in forward or reverse order. We did this for interior design objects, for some reason. [defense contractor: reason was not in vogue.] Without an example of the att value format, the sort order algo is a guess.
S
Message 5 of 69
Kent1Cooper
in reply to: kirwan59


@kirwan59 wrote:

...a routine that will allow to draw a polyline through existing blocks, in the order the blocks should be numbered? .... the blocks are automatically numbered in the sequence of the polyine start to finish.


If you're only using the Polyline to determine the order, can you do it without that, and just let the order of selection of the Blocks govern?  This is a thread with a routine that numbers Block attributes in selection order, which you may be able to use as a starting point:

 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Block-Attribute-Incremental-Numbering...

 

Search the Discussion Group further -- sequential numbering routines are out there in a variety of formats [using Attributes vs. placing Text, with Attributes as Blocks are inserted or with pre-existing Blocks, selecting objects vs. just designating locations, using different numbering systems, etc., etc.].

Kent Cooper, AIA
Message 6 of 69
kirwan59
in reply to: stevor

Hi,

 

Just got back online. Basically I have a block ( a square) with an attribute called 'IDENTIFIER'. A number of these blocks will be placed in a drawing on a grid system. However, at this point I do not know where the start point of the numbering will begin and the direction of the sequence. This info will be given to me by the Project Manager later. I could lay from 200 to 600 blocks in one drawing. The number will either run top (T) to bottom (B), left (L) to right (R), or L to R, T to B, or B to T, L to R, etc. There are a number of ways the blocks will be numbered, however they will run in sequence, and will be contiguous. The numbering scheme could something like 01/TRA/001/A-D, 01/TRA/002/A-D,01/TRA/003/A-D......01/TRA/254/A-D,etc. where the number following 'TRA/' is incremented by 1. By using a pline draw through the blocks in the sequence that you want to order the attributes. Then the command would ask for the syntax that you require and would then automatically number the blocks in that sequence. I have found a numbering sequence LISP file called NUMINC see attached. Hopefully I can call on this procedure within my LISP file!

 

 

Message 7 of 69
Kent1Cooper
in reply to: kirwan59


@kirwan59 wrote:

.... The number will either run top (T) to bottom (B), left (L) to right (R), or L to R, T to B, or B to T, L to R, etc.  There are a number of ways the blocks will be numbered, however they will run in sequence, and will be contiguous. .... By using a pline draw through the blocks in the sequence that you want to order the attributes. .... 



I think the ordering part of it could be accomplished without the need to draw a Polyline, if it's always regular in some direction such as you describe.  This has a routine that does something like that for Text entities, based on insertion points: 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Subroutines-to-re-order-index-selecti...

It would need another argument and further code for the secondary direction of sorting [it sorts only in one direction, so if you call for Left to right, it groups columns but the order within each column may vary], but it could surely be adapted.

 

Just to clarify:  by "top to bottom, left to right", do you mean that the left-most column of Blocks would be numbered first, from top to bottom, and then the next column to its right would be numbered from top to bottom, etc.?

1  4  7

2  5  8

3  6  9

Or do you mean the top-most row would be numbered first, from left to right, then the next row below it from left to right?

1  2  3

4  5  6

7  8  9

 

To make it unambiguous, you could build something with prompts such as "First row or column to be numbered [T/B/L/R] :" followed by something like (if they typed T or B) "End to start numbering rows [L/R] :" or (if they typed L or R) "End to start numbering columns [T/B] :".

 

EDIT:

Or, come to think of it, since you talk about them always being contiguous, would it be a switchback situation, such as this?

1  2  3

6  5  4

7  8  9

or this?

1  6  7

2  5  8

3  4  9

 

In a case like those, the second prompt would ask for the end at which to start numbering that designated initial row or column, rather than all rows or columns.

Kent Cooper, AIA
Message 8 of 69
stevor
in reply to: kirwan59

Pbej was closer than I, so here is his routine, mod'd some.

It requires individual object selection for the sequence, and is without checks, etc.

 

 ; pbej: -Inserts +ss / 6sep11
 (Defun c:tb (/ strt pt1 pt2 ptl SS psp senl bns)    (vl-load-com)
   (textscr) (graphscr) (redraw)

  (setq strt (getint "\n Start Number:")  snr strt ) 
  (princ "\n Pick Starting Insert of Block: ")
  (While   (setq ss (ssget "_+.:E:S")) ;; (pp_"SS")
    (setq sen  (ssname  ss 0)    sp  (dxf_eu 10 (entget sen))
            senl (cons sen senl)   ptl (cons sp ptl) 
            psp sp   snr (1+ snr))
    (if psp (grdraw psp sp 1)) (gr_xdc sp 2 1)
    (if (not bns) (setq bns (dxf_ 2 (entget sen))  ) )
    (princ (strcat "\n Next Insert of " bns " for # " (itoa snr)))
  ) ; hope they were inserts, same block
  (If ptl    (progn  ; something was selected
    (Entmakex (append (list (cons 0 "LWPOLYLINE")  (cons 100 "AcDbEntity")
         (cons 100 "AcDbPolyline")  (cons 90 (length ptl))  )
            (mapcar (function (lambda (p) (cons 10 p))) ptl)) ; opt layer?
    )
    (Foreach sen  (reverse senl )
      (setq oen (vlax-ename->vla-object  sen))
      (vla-put-textstring (car (vlax-invoke oen  'Getattributes)) (itoa strt))
      (setq strt (1+ strt))
     )   ) (princ " NO selectees ")  )  (princ " done") (princ)  ) ; def

 

 ; return Ucs coords
 (DeFun dxf_EU (gn edL / vv )
  (if (and (setq vv (cdr (assoc gn edL)))
           (member gn (list 10 11  210 ))) ; others may exist!!!
    (trans vv (cdr (assoc -1 edl)) 1)  vv  )  )


 (DeFun dxf_  (gn edL  )  (cdr (assoc gn edL))    )

 

 

(c:tb) )

S
Message 9 of 69
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:

....
I think the ordering part of it could be accomplished without the need to draw a Polyline, if it's always regular in some direction such as you describe.  ....


The attached BlockSSSort.lsp [= Block Selection Set Sort] seems to do that, in limited testing.  But it does need it to be a regular sequence, such as top-to-bottom/left-to-right, not a meandering order.  And it assumes accurately aligned rows and columns as your description of a grid suggests [within the precision argument in the (equal) function, which you can adjust].

 

It leaves a list of Block entity names in sorted-in-both-directions-as-instructed order, in the blsort2 variable, and also returns that list.  [If the answer to my previous post's sequencing question is that it should be a switchback sequence, adjustments would need to be made.]

 

This way, you don't need to draw any Polyline, nor find the Blocks by looking around at the Polyline's vertices, nor select the Blocks in any particular order.  You can just designate the sort orders in the routine's arguments, and select the Blocks by any method(s) you prefer.

 

I'll leave to others, at least for the time being, the stepping through the sorted list and assigning the incremented text content to the Attribute [if that hasn't already been sufficiently addressed].

Kent Cooper, AIA
Message 10 of 69
kirwan59
in reply to: Kent1Cooper

Hi Kent, the problem is that the blocks could be inherant to the drawing when I receive it, this means I have no clue to what order the blocks were inserted. As to the number sequence and direction it can be either dependent upon how the Project Manager wants to start and complete numbering sequence. Hence why I suggested a polyline to determine the sequence I want to number in, this way the number system will follow the polyline numbering each block in the sequence of the polyline. This way if the numbering sequence does jump from one area to another, then jumps back again that I can still control the sequencing as the polyline will be the determining factor! Plus I don't want to be picking blocks manually to sequence, especially if I have 600 blocks to do on a level, have 5 levels to renumber ( that would be 3000 blocks!!!). The actual numbering identifier syntax can be dealt with by calling on the Numinc LISP file, so I don't see this being a problem. I can program but have never used LISP, and a bit limited to Visual C. I suppose the starting point is how could you program for a function to return a list of blocks, that run in sequence, that are touching a polyline. I would like to thank you guys for your assistance so far.

 

Kevin

Message 11 of 69
kirwan59
in reply to: Kent1Cooper

Hi Kent,

 

I have tried to use your BlockSSSort.lsp but it loads successfully (APPLOAD), but when I try to invoke the command I get

 

'Command: BSSS
Unknown command "BSSS".  Press F1 for help.'

 

Am I doing this correctly? I tried typing 'BSSS' and BlockSSSort and still got same message.

 

Kevin

Message 12 of 69
kirwan59
in reply to: stevor

Hi Stevor

 

I tried to run tb.lsp and got the following error

 

'Command: tb

 Start Number:01

 Pick Starting Insert of Block:
Select objects:
; error: too few arguments'

Message 13 of 69
pbejse
in reply to: kirwan59

The way i see it, there are two ways you can do this.

 

1. Draw a polyline for your sequence as preparation (in grid like format) until your project manager tells you the sequence.which means for all the possible sequence you have a pline passing thru those location. then invoke a routine to insert the block that increments automatically according to your numbering system.

 

2. Like Kents suggestion use a position sort routine. Blocks are already in place, then invoke the routine to increment the numbers based on the conditions your PM's decision.

 

Read the syntax in Kents lisp file found at the header.

 

 

 

 

 

 

 

 

 

 

Message 14 of 69
Kent1Cooper
in reply to: kirwan59


@kirwan59 wrote:

.... 

I have tried to use your BlockSSSort.lsp but it loads successfully (APPLOAD), but when I try to invoke the command I get

 

'Command: BSSS
Unknown command "BSSS".  Press F1 for help.'

 

Am I doing this correctly? ....


See the Usage note near the top of the file.  (BSSS "R" "B") or (BSSS "T" "L") or ....

Kent Cooper, AIA
Message 15 of 69
Kent1Cooper
in reply to: kirwan59


@kirwan59 wrote:

... the problem is that the blocks could be inherant to the drawing when I receive it, this means I have no clue to what order the blocks were inserted. As to the number sequence and direction it can be either dependent upon how the Project Manager wants to start and complete numbering sequence. ....  ...if the numbering sequence does jump from one area to another, then jumps back again that I can still control the sequencing as the polyline will be the determining factor! Plus I don't want to be picking blocks manually to sequence, especially if I have 600 blocks to do ....  ...the starting point is how could you program for a function to return a list of blocks, that run in sequence, that are touching a polyline. I....


To sort them with (BSSS), it doesn't matter whether the Blocks were already there or you put them in, or in what order they were inserted; they just need to be there to be selected.  The whole point of it is to sort them positionally regardless of insertion order or anything else.

 

It appears that this in Message 6:

"The number will either run top (T) to bottom (B), left (L) to right (R), or L to R, T to B, or B to T, L to R, etc."

is not always the case, but that's what I based my suggestion on.

 

I suspect that to find all Blocks that lie along a Polyline might be a challenge if they are not at the Polyline vertices, but maybe it's not insurmountable [see below].  If they're at the vertices, meaning that you would have to draw a Polyline with a vertex at each Block [presumably at its insertion point], I don't see that as being any less daunting than picking the Blocks manually in sequence, except that it would be easier to change the order later, with Pedit.

 

If:

a. the Blocks are small enough in relation to the spacing between rows and columns, and

b. there are not other kinds of things with insertion points [such as Text] around to complicate things, and

c. the Polyline doesn't go by any out-of-sequence Blocks when it jumps from one area to another,

then I guess it would be possible to run along the Polyline at smaller-than-Aperture-box increments, applying Osnap Insert, looking to find Blocks even if they're not all at vertices.  It might well depend on there being some element of the Block at its insertion point [not for example, a square with the insertion point at the center but no drawing entity there], so that once Osnap finds an insertion point, it can look with something like (ssget "C") for the Block that goes with it.

Kent Cooper, AIA
Message 16 of 69
kirwan59
in reply to: pbejse

This is Kent's header

 

(defun BSSS (first dir / bss bent blist blsort1 coord clist csort); = Block Selection Set Sort

 

I assume the routine is initialised by typing BSSS at the command prompt.

Message 17 of 69
kirwan59
in reply to: Kent1Cooper

Hi Kent

 

The way I see that the blockname will be generic to the drawing, therefore can be coded into the routine, so this way when drawing the polyline (pline), the program will only look for that block.

 

These blocks are usually on a 1.8 1.8m grid or a 2.4 x 2.4m grid system.

 

Kev

Message 18 of 69
stevor
in reply to: kirwan59

 

The BSSS is not  a command line function; it can be applied as it says in its comments:

 

;; Usage: (bsss "t" "l") sorts with top row first in left-to-right order, followed by rows below, also left

 

However, its output is a list of entity names, intended to be used by other code; just like Knet said.

 

Also, it may work better if another variable name is added to the local variable list, namely: blsort2.

 

Where is reads "blsort1 coord " make it "blsort1  blsort2  coord "

 

 

S
Message 19 of 69
Kent1Cooper
in reply to: stevor


@stevor wrote:

.... 

Also, it may work better if another variable name is added to the local variable list, namely: blsort2.

 

Where is reads "blsort1 coord " make it "blsort1  blsort2  coord "

.... 


I deliberately did not localize the blsort2 variable, so that the list, stored in a variable for access, would be available after the routine is finished.  But it would depend on how it might be incorporated into something larger.  Since it returns that list as well as storing it in that variable, things could be set up with that variable localized within this subroutine, if appropropriate in the larger context.  But I would be inclined to localize it at the level of the larger routine of which this might be a part, assuming that's the setup.

Kent Cooper, AIA
Message 20 of 69
Kent1Cooper
in reply to: kirwan59


@kirwan59 wrote:

This is Kent's header

 

(defun BSSS (first dir / bss bent blist blsort1 coord clist csort); = Block Selection Set Sort

 

I assume the routine is initialised by typing BSSS at the command prompt.


To elaborate a little on stevor's reply:

If it began with

(defun C:BSSS (/ ....)

with the C:, and with no arguments listed before the slash in the parentheses, then yes, you would invoke it by typing BSSS at the Command: prompt.  That's the way a "command"-type function is defined.

But without the C:, and with arguments listed before that slash, it's not a command-type but a "sub-routine"-type function, and needs to be used with its name in parentheses, with the argument values supplied, as in the Usage comment in the file.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost