modify lisp to delete an option or add 2

modify lisp to delete an option or add 2

jtm2020hyo
Collaborator Collaborator
1,435 Views
13 Replies
Message 1 of 14

modify lisp to delete an option or add 2

jtm2020hyo
Collaborator
Collaborator

bbl.lsp (attached) connected selected block with the nearest block with same name or blocks with the same layer, limited just to block between 0 grade to 180 grades respect to individual block rotation.

What I need is delete that angular option Or add 2 option like "restrict angle to since 0 to 180 grades" or "360, no restrictions"

(defun C:BBL5 (/);;Put Temp Variables here.....
(vl-load-com)
(command "CMDECHO" 0)
(setq SB_lst nil)
(setq SB_A_lst nil)
(setq NB_lst nil)
;(Setq SB_Name (cdr (assoc 2 (setq Data (entget (setq PBP (car(entsel "\nSelect a block(For Block Name) from which you want to draw line to Nearby Block (Other than Selected block)"))))))))
;(if (= :vlax-true (vla-get-IsDynamicBlock (vlax-ename->vla-object PBP)))
;	(Setq SB_Name (vla-get-Effectivename (vlax-ename->vla-object (cdr (assoc -1 Data)))))
;)
(princ "\nSelect a blocks from which you want to draw line to Nearby Block (Other than Selected block)")
(Setq selectionset_SB (ssget))
(initget 1 "Block Layer")
(setq NBO (getkword "\nSelect Nearest Objects by [Block Name/Layer Name]: "))
(if (= NBO "Block")
	(progn
		(princ "BLOCK")
		(Setq NSB (cdr (assoc 2 (setq Data1 (entget (setq PBP1 (car(entsel "\nSelect a Nearby Block upto which you want to draw line...."))))))))
		(if (= :vlax-true (vla-get-IsDynamicBlock (vlax-ename->vla-object PBP1)))
			(Setq NSB (vla-get-Effectivename (vlax-ename->vla-object (cdr (assoc -1 Data1)))))
		)
		(Setq selectionset_NB (BLOCKSSET NSB))
	)
	(progn
		(princ "LAYER")
		(Setq NSBL (cdr (assoc 8 (entget(car(entsel "\nSelect a Object for Layer which contain Nearby Block upto which you want to draw line...."))))))
		(Setq selectionset_NB (ssget "_A" (list '(0 . "INSERT") (cons 8 NSBL))))
	)
)
(repeat (setq N (sslength selectionset_SB))
	(setq BP_Block (cdr (assoc 10 (entget (ssname selectionset_SB (setq N (- N 1)))))))
	(setq SB_lst (cons BP_Block SB_lst))
	(setq A_Block (cdr (assoc 50 (entget (ssname selectionset_SB N)))))
	(setq SB_A_lst (cons A_Block SB_A_lst))
)
(repeat (setq N (sslength selectionset_NB))
	(setq BP_Block (cdr (assoc 10 (entget (ssname selectionset_NB (setq N (- N 1)))))))
	(setq NB_lst (cons BP_Block NB_lst))
)
(repeat (setq N (length SB_lst))
	(setq BP_SB (nth (setq N (- N 1)) SB_lst))
	(setq A_SB (nth N SB_A_lst))
	(setq DIS_lst nil)
	(repeat (setq N1 (length NB_lst))
		(setq BP_NB (nth (setq N1 (- N1 1)) NB_lst))
	    	(setq PD (distance BP_SB BP_NB))
		(setq DIS_lst (cons PD DIS_lst))
	)
(setq DIS_lst_Sort (vl-sort DIS_lst '<))
(setq LO 0)
   (while (< LO (length DIS_lst_Sort))
	(setq LDP (vl-position (nth LO DIS_lst_Sort) DIS_lst))
	(setq NP (nth LDP NB_lst))
	(setq LA (angle BP_SB NP))
	(setq LO (+ 1 LO))
	(if (and (> A_SB pi)(<= LA (- (+ A_SB pi) (* 2 pi)))) (setq LA (+ LA (* 2 pi))))
	(if (and(>= LA A_SB)(<= LA (+ A_SB pi)))
	    (progn
		(command "_.pline" "_none" BP_SB "_none" NP "")
		(setq LO (length DIS_lst_Sort))
	    )
	)
   )
)
(command "CMDECHO" 1)
(princ)
)
(defun BlockSSET (blname / sset ss-dyn num ent effname)
(vl-load-com) 
  (if (not (setq sset (ssget "X" (list (cons 2 blname))))) (setq sset (ssadd)))
  (if (setq ss-dyn (ssget "X" (list (cons 2 "`*U*"))))
      (progn
           (setq num 0)
           (repeat (sslength ss-dyn)
             (setq ent (ssname ss-dyn num))
             (setq effname (vla-get-EffectiveName (vlax-ename->vla-object ent)))
              (if (= blname effname)
                  (ssadd ent sset)
              )
             (setq num (1+ num))
           )
      )
  )
sset
)
0 Likes
Accepted solutions (2)
1,436 Views
13 Replies
Replies (13)
Message 2 of 14

jtm2020hyo
Collaborator
Collaborator

here drawings with regular blocks and dynamic blocks here I need to test code.

 

all block should connect pink blocks.

I find the solution I will leave it here.

0 Likes
Message 3 of 14

ronjonp
Mentor
Mentor

Did THIS not help? Your 2.dwg is confusing. You want the pink blocks connected but in reality there are many more blocks that are rotated within 0-180 degrees?

image.png

 

Message 4 of 14

dbhunia
Advisor
Advisor

Hi 

 

For......

 


@jtm2020hyo wrote:

........................
What I need is delete that angular option Or add 2 option like "restrict angle to since 0 to 180 grades" or "360, no restrictions"

.......................


 

Try this.............(For 0 to 180 degree use "1" and for 360 degree use "3").... Lightly tested......in AutoCAD 2007

 

Can not test your drawing till tomorrow ......... personally I use AutoCAD 2007........

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
0 Likes
Message 5 of 14

3wood
Advisor
Advisor

You don't need modify the lisp.

The only thing you need to do is either use QSELECT to select blocks with certain name and in a certain rotation range first, or use FILTER to set up such a rule and save the rule so you can use it later.

Once you selected blocks matching these rules, then you can use a lisp to link them together. 

Message 6 of 14

Kent1Cooper
Consultant
Consultant

@3wood wrote:

.... either use QSELECT to select blocks with certain name and in a certain rotation range first, or use FILTER to set up such a rule .... 


 

I don't think that's the idea.  If I remember from the other thread that resulted in the code in Message 1, the rotation question is not about the absolute  rotation [findable with things like FILTER] of "starting" Blocks from  which to draw Lines, but rather a relative  thing -- to find which of the possible "target" Blocks to  which to draw a Line is closest to the starting Block, but only  if it's within the 0- to 180-degree range in direction from the starting Block relative to the starting Block's own rotation.  For example, in this image, the left side of which is from their sample drawing:

BBL5.PNG

On the left side I first picked the "TDN" Block, then under the Block Name option for potential targets, I picked on the S Block above.  That is actually closer  to TDN's insertion point than the S Block to the right, but it drew the Line to the one on the right, because that's the closest S Block within the angle range relative to TDN's rotation, and the one above is not within that range.

Then I Copied the Blocks over for the right side of the image, where I turned TDN to a rotation of 0 to show its native orientation, so I could see what the 0- to 180-degree range is from its point of view, and did the same again.  Although for the Block Name source I picked on the S Block to the right, it drew the Line to the one above, which in that case is within the angle range relative to TDN's rotation.

I think what they're looking for is the option to remove that 0- to 180-degree relative angle range limitation, so that in either  case in the image, it would draw the Line to the S Block above, which is the closest one when their directions from TDN, relative to TDN's rotation, are ignored.

 

@jtm2020hyo, is my interpretation correct?

Kent Cooper, AIA
Message 7 of 14

jtm2020hyo
Collaborator
Collaborator

@dbhunia wrote:

Hi 

 

For......

 


@jtm2020hyo wrote:

........................
What I need is delete that angular option Or add 2 option like "restrict angle to since 0 to 180 grades" or "360, no restrictions"

.......................


 

Try this.............(For 0 to 180 degree use "1" and for 360 degree use "3").... Lightly tested......in AutoCAD 2007

 

Can not test your drawing till tomorrow ......... personally I use AutoCAD 2007........

 

-------

 

I received an error when I try to select a (pink) block by name or by layer.

 

I tested files with AutoCAD 2018 student license.

 

Files tested Attached

 

image.png

 

 

 

Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
; error: Function cancelled
Command: BBL
Select a blocks from which you want to draw line to Nearby Block (Other than Selected block)
Select objects: p
190 found
Select objects:
Select Nearest Objects by [Block Name/Layer Name]: L
LAYER
Select a Object for Layer which contain Nearby Block upto which you want to draw line....
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 180
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.

 

 

 

0 Likes
Message 8 of 14

dbhunia
Advisor
Advisor
Accepted solution

Hi

 


@jtm2020hyo wrote:

 

..............

 

Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
; error: Function cancelled
Command: BBL
Select a blocks from which you want to draw line to Nearby Block (Other than Selected block)
Select objects: p
190 found
Select objects:
Select Nearest Objects by [Block Name/Layer Name]: L
LAYER
Select a Object for Layer which contain Nearby Block upto which you want to draw line....
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 180
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.

 

First what is this "P" for....... you have to select block (As you requested previously .....)

 

And change this line...

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [180/360]: "))

to....

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [1 for 180 /3 for 360]: "))

 

And Try .............(For 0 to 180 degree use "1" and for 360 degree use "3")


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 9 of 14

Kent1Cooper
Consultant
Consultant

@dbhunia wrote:

.... 

And change this line...

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [180/360]: "))

to....

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [1 for 180 /3 for 360]: "))

And Try .............(For 0 to 180 degree use "1" and for 360 degree use "3")


 

That issue is because of this line in the code:
    (initget 1 "1 3")

which in the (getkword) function means only 1 or 3 will be accepted as keywords, so this prompt:
    (setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [180/360]: "))

shouldn't say [180/360], because those are not acceptable inputs.  When the options are only numerical, you can't do the capitalized-abbreviation-letter thing that you can with alphabetic-character options.

 

You could expand the prompt as suggested to make it clear what to type, or if people would be willing to type all three digits, you could just keep the prompt as it was, and change the (initget) string argument to look for input that way:
    (initget 1 "180 360")

 But they would need to always type all three digits -- no single-number abbreviations.

 

EDIT:

 

Alternatively, you could do it with letters, such as this way:

    (initget 1 "Front All")

    (setq ROA (getkword "\nConnect Blocks in Front only or All around [Front/All]: "))

 

Then people could type just the first letter, or include any amount more, of the word they want, in any case or case combination, and the return will be the related full word from the (initget) string argument, in the case combination in which it appears there, which of course would then be what later code checks for, rather than for "180" or "360."

 

Kent Cooper, AIA
Message 10 of 14

jtm2020hyo
Collaborator
Collaborator

@Kent1Cooper wrote:

@3wood wrote:

.... either use QSELECT to select blocks with certain name and in a certain rotation range first, or use FILTER to set up such a rule .... 


 

I don't think that's the idea.  If I remember from the other thread that resulted in the code in Message 1, the rotation question is not about the absolute  rotation [findable with things like FILTER] of "starting" Blocks from  which to draw Lines, but rather a relative  thing -- to find which of the possible "target" Blocks to  which to draw a Line is closest to the starting Block, but only  if it's within the 0- to 180-degree range in direction from the starting Block relative to the starting Block's own rotation.  For example, in this image, the left side of which is from their sample drawing:

BBL5.PNG

On the left side I first picked the "TDN" Block, then under the Block Name option for potential targets, I picked on the S Block above.  That is actually closer  to TDN's insertion point than the S Block to the right, but it drew the Line to the one on the right, because that's the closest S Block within the angle range relative to TDN's rotation, and the one above is not within that range.

Then I Copied the Blocks over for the right side of the image, where I turned TDN to a rotation of 0 to show its native orientation, so I could see what the 0- to 180-degree range is from its point of view, and did the same again.  Although for the Block Name source I picked on the S Block to the right, it drew the Line to the one above, which in that case is within the angle range relative to TDN's rotation.

I think what they're looking for is the option to remove that 0- to 180-degree relative angle range limitation, so that in either  case in the image, it would draw the Line to the S Block above, which is the closest one when their directions from TDN, relative to TDN's rotation, are ignored.

 

@jtm2020hyo, is my interpretation correct?




yes. you explained better than me.

here an image as a reference.

image.png

 

0 Likes
Message 11 of 14

jtm2020hyo
Collaborator
Collaborator

@dbhunia wrote:

Hi

 


@jtm2020hyo wrote:

 

..............

 

Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
Connect Blocks within 180 or 360 Degree [180/360]: *Cancel*
; error: Function cancelled
Command: BBL
Select a blocks from which you want to draw line to Nearby Block (Other than Selected block)
Select objects: p
190 found
Select objects:
Select Nearest Objects by [Block Name/Layer Name]: L
LAYER
Select a Object for Layer which contain Nearby Block upto which you want to draw line....
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 180
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.
Connect Blocks within 180 or 360 Degree [180/360]: 360
Invalid option keyword.

 

First what is this "P" for....... you have to select block (As you requested previously .....)

 

And change this line...

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [180/360]: "))

to....

(setq ROA (getkword "\nConnect Blocks within 180 or 360 Degree [1 for 180 /3 for 360]: "))

 

And Try .............(For 0 to 180 degree use "1" and for 360 degree use "3")



Your code work perfectly. but when selected block their  and we use the "layer" option generate a 0 length polyline if both blocks have same name layer.

image.png

 

Can we have 2 options more?
we already have link to nearest by "name" and "layer", what i think we need is "none" (to select any nearest with any name block and any a name layer) and "name with layer" (to link with any nearest kind of block specific that have a selected name and layer ).

If my request not possible thanks anyway.

 

 

0 Likes
Message 12 of 14

dbhunia
Advisor
Advisor
Accepted solution

Hi

 

For......

 


@jtm2020hyo wrote:

..................................


Your code work perfectly. but when selected block their  and we use the "layer" option generate a 0 length polyline if both blocks have same name layer.

image.png

 ..................................


 

Try this......

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 13 of 14

jtm2020hyo
Collaborator
Collaborator

@dbhunia wrote:

Hi

 

For......

 


@jtm2020hyo wrote:

..................................


Your code work perfectly. but when selected block their  and we use the "layer" option generate a 0 length polyline if both blocks have same name layer.

image.png

 ..................................


 

Try this......

 

 


until now work perfectly. thanks as always.



0 Likes
Message 14 of 14

jtm2020hyo
Collaborator
Collaborator

@dbhunia wrote:

Hi

 

For......

 


@jtm2020hyo wrote:

..................................


Your code work perfectly. but when selected block their  and we use the "layer" option generate a 0 length polyline if both blocks have same name layer.

image.png

 ..................................


 

Try this......

 

 


 

 

I was testing your code and I found that "connect by layer" option have a error when layer name has the prefix character "#".

 

Second.

I need add an option to undo (control+z) the whole lisp when I have a error, and not individually(is pretty hard).  

 

 

 

 Edit; I have a last request.

I request you to add a option called "Connect to any block with any layer option" to connect selected blocks with any nearest block counting blocks with same name and same layer like selected blocks and too between selected block if they are the nearest block.

 

This last request will help to find a solution to another issue called "lisp to create the smallest polyline that connect all selected blocks"

 

 

 

 

 

0 Likes