Jump to content

Lines that touch


j_spawn_h

Recommended Posts

I was looking for a way to change a line type or any thing on the line by just swiping all the lines.

Lets say you have 3 lines.

line 1 is on a layer L1

line 2 is on layer L2

line 3 is on layer L10

both 1&2 touch line 3 some where some how. i would like to select all three and if 1 & 2 touch 3 change the layer of 3 to L3.

Link to comment
Share on other sites

Well, how would you select all three? Would you entsel line1 and line2 and check for a line that touches both? Or entsel line3 and check for corresponding lines that touches line3?

 

There needs to be a criterion to it.

Link to comment
Share on other sites

i am hoping just to select all of them with a window. I mainly wondering can the point where they all touch be recognized and can distinguished between the three, so i can use some type of if statement. Like if 1 & 2 touch 3 then do this to 3.

Link to comment
Share on other sites

(if
  (and
    (safearray-value (variant-value (vla-IntersectWith vla_line1 vla_line3 acExtendNone)))
    (safearray-value (variant-value (vla-IntersectWith vla_line2 vla_line3 acExtendNone)))
    )
  ; then do your thing here
  )

Thanks,

Jonathan Handojo

Link to comment
Share on other sites

  • 4 months later...

Well i have been messing with this for months now on and off and i just can not get it to work for me. i Guess just don't understand how it works. Could someone explain it to me? Does this work with me selecting multiply lines at one time?

Link to comment
Share on other sites

Fastsel selects the items now how do extract the info to use. I would like to say something like if line 1 with named layer 1 an line 2 named layer 2 if they are touching line 3 change the layer on line 3 from 3 to 4. I see what Jonathan has above but for the life of me i can not make it do what i need. I am sure its just me not knowing enough lisp or VLA.

Link to comment
Share on other sites

Maybe this will do it for you then:

 

The LISP routine will select lines from the first selection set intersecting all lines from the second selection set.

(defun c:ltouch ( / *error* adoc alllst i iter rtn ss ssall sstouch touchlst)
  (defun *error* (msg)
    (vla-EndUndoMark adoc)
    (princ (strcat "Error: " msg))
    )
  (setq adoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (vla-StartUndoMark adoc)

  ;; Start routine

  (setq ssall (ssget "_X" '((0 . "LINE,LWPOLYLINE")))
	;ssall (progn (princ "\nSelect all lines to process") (ssget '((0 . "LINE,LWPOLYLINE"))))
	
	; Uncomment above line and comment (or delete) the first line to select the lines to calculate.
	; Makes it faster to calculate only a few lines instead of every line in the drawing.
	sstouch (progn (princ "\nSelect lines to touch") (ssget '((0 . "LINE,LWPOLYLINE"))))
	)

  (if (and ssall sstouch)
    (progn
      (repeat (setq i (sslength sstouch))
	(ssdel (ssname sstouch (setq i (1- i))) ssall)
	)
      (setq alllst (JH:selset-to-list-vla ssall)
	    touchlst (JH:selset-to-list-vla sstouch)
	    rtn (mapcar 'vlax-vla-object->ename
			(vl-remove-if-not
			  '(lambda (x)
			     (vl-every
			       '(lambda (y)
				  (vlax-invoke y 'IntersectWith x acExtendNone)
				  )
			       touchlst
			       )
			     )
			  alllst
			  )
			)
	    )
      (sssetfirst nil ((lambda (x / ss) (setq ss (ssadd)) (mapcar '(lambda (y) (setq ss (ssadd y ss))) x) ss) rtn))
      )
    )

  ;; End routine
  
  (vla-EndUndoMark adoc)
  (princ)
  )

(defun JH:selset-to-list-vla (ss / i rtn)
  (if ss
    (repeat (setq i (sslength ss))
      (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn))
      )
    )
  rtn
  )

 

image.png.ad515f25a161e7f3711e75e9368ec566.png

 

Above is an example:

 

First selection set: All lines

Second selection set: Red lines

Returns: Selection in the above picture.

 

In your case, if you select line 1 and line 2, line 3 will be selected. Or if you select just line 3, line 1 and 2 will be selected.

Edited by Jonathan Handojo
JH:selset-to-list-vla modified
Link to comment
Share on other sites

8 hours ago, Jonathan Handojo said:

(defun JH:selset-to-list-vla (ss / rtn) (if ss (repeat (setq i (sslength ss)) (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn)) ) ) (reverse rtn) )

@Jonathan Handojo No need to reverse your return in 'JH:selset-to-list-vla' , you're 'adding items to the front of the list starting from the back. 🍻

Link to comment
Share on other sites

2 hours ago, ronjonp said:

@Jonathan Handojo No need to reverse your return in 'JH:selset-to-list-vla' , you're 'adding items to the front of the list starting from the back. 🍻

Whoops... you're right again! Ouch... giving people wrong routines, not good for me. Thanks

 

What else can I say man... it looks exactly like Lee's "selection set to list" function no matter how I would've want to write it without looking at his forum.

Edited by Jonathan Handojo
Link to comment
Share on other sites

On 4/17/2020 at 11:18 PM, ronjonp said:

(defun JH:selset-to-list-vla (ss / rtn) (if ss (repeat (setq i (sslength ss)) (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn)) ) ) (reverse rtn) )

 

On 4/18/2020 at 1:47 AM, Jonathan Handojo said:

e back

Thanks for your help. I see how this leave the 3rd line last but, now i can not figure out which variable is the correct one to use. I want to change the 3rd line layer properties.

I have tried using select, then last, the change

I tried every variable and it does not grab it. if you do not mind helping me out. Ill keep trying different things until then. Thanks again the help all ready. I am one step closer.

Link to comment
Share on other sites

3 hours ago, j_spawn_h said:

 

Thanks for your help. I see how this leave the 3rd line last but, now i can not figure out which variable is the correct one to use. I want to change the 3rd line layer properties.

I have tried using select, then last, the change

I tried every variable and it does not grab it. if you do not mind helping me out. Ill keep trying different things until then. Thanks again the help all ready. I am one step closer.

 

The routine above only selects the line, that's all. I don't really understand how your layer-changing criteria works. You simply keep saying "If line 1 is on L1, and line 2 is on L2, and line 3 somehow touches both lines, change to L3". What if "line 1 is on layer L4 and line 2 is on layer L1" or "line 1 is on layer L2 and line 2 is on layer L6"? Then where's line 3 changing to?

Link to comment
Share on other sites

With your routine it leaves the last line highlighted. How can i do any changes to that line with the more lisp routine. Maybe this will make more since. I posted what i was trying to do to your code. Key word trying... lol

(defun c:ltouch ( / *error* );adoc alllst i iter rtn ss ssall sstouch touchlst)
  (defun *error* (msg)
    (vla-EndUndoMark adoc)
    (princ (strcat "Error: " msg))
    )

  (setq adoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (vla-StartUndoMark adoc)

  ;; Start routine

  (setq ssall (ssget "_X" '((0 . "LINE,LWPOLYLINE")))
	;ssall (progn (princ "\nSelect all lines to process") (ssget '((0 . "LINE,LWPOLYLINE"))))
	
	; Uncomment above line and comment (or delete) the first line to select the lines to calculate.
	; Makes it faster to calculate only a few lines instead of every line in the drawing.
	sstouch (progn (princ "\nSelect lines to touch") (ssget '((0 . "LINE,LWPOLYLINE"))))
	)
 ; (8 . "S-FRM-ROOF,S-FRM-16RFTR,S-FRM-15RFTR,S-FRM-14RFTR,S-FRM-13RFTR,S-FRM-12RFTR,S-FRM-11RFTR,S-FRM-10RFTR,S-FRM-9RFTR,S-FRM-8RFTR,S-FRM-7RFTR,S-FRM-6RFTR,S-FRM-5RFTR,S-FRM-4RFTR,S-FRM-3RFTR,S-FRM-2RFTR,S-FRM-RDG"))

 (setq en (ssname sstouch 0))
(setq ed (entget en))
 
;(setq lyr (cdr (assoc 8 ed)))
  
  (if (= lyr "S-FRM-8RFTR")(setq ly2 8))
  (if (= lyr "S-FRM-16RFTR")(setq ly3 16))
  (if (and (= ly2 8)(= ly3 16))(setq lyr4 "S-FRM-8ROOF"))
			    
  (setq ln (if (and ssall sstouch)
    (progn
      (repeat (setq i (sslength sstouch))
	(ssdel (ssname sstouch (setq i (1- i))) ssall)
	)
      (setq alllst (JH:selset-to-list-vla ssall)
	    touchlst (JH:selset-to-list-vla sstouch)
	    rtn (mapcar 'vlax-vla-object->ename
			(vl-remove-if-not
			  '(lambda (x)
			     (vl-every
			       '(lambda (y)
				  (vlax-invoke y 'IntersectWith x acExtendNone)
				  )
			       touchlst
			       )
			     )
			  alllst
			  )
			)
	    )
      (sssetfirst nil ((lambda (x / ss) (setq ss (ssadd)) (mapcar '(lambda (y) (setq ss (ssadd y ss))) x) ss) rtn))
      )
    ))  ;; End routine
  
  ;(defun jh:highlightselsel ( / selset)
;(setq selset (ssget))
;(sssetfirst nil selset)
;)
  (command "change" "" "" "p" "la" lyr4 "")

  ;(setq lle (entlast))
  (vla-EndUndoMark adoc)

  ; (vlax-vla-object->ename obj)
  (princ)
  
  )



(defun JH:selset-to-list-vla (ss / rtn)
  (if ss (repeat (setq i (sslength ss))
	   (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn)) ) )
  (reverse rtn) ) 

 

Link to comment
Share on other sites

Hopefully this explanation is more clear. I don't know how you want to change your layers so I'll leave that to you.

 

(defun c:ltouch ( / *error* adoc alllst i iter rtn ss ssall sstouch touchlst)
    (defun *error* (msg)
	(vla-EndUndoMark adoc)
	(princ (strcat "Error: " msg))
	)
    (setq adoc (vla-get-ActiveDocument (vlax-get-acad-object)))
    (vla-StartUndoMark adoc)
    
    ;; Start routine
    
    (setq ssall (ssget "_X" '((0 . "LINE,LWPOLYLINE")))
	  ;ssall (progn (princ "\nSelect all lines to process") (ssget '((0 . "LINE,LWPOLYLINE"))))
	  
	  ; Uncomment above line and comment (or delete) the first line to select the lines to calculate.
	  ; Makes it faster to calculate only a few lines instead of every line.
	  sstouch (progn (princ "\nSelect lines to touch") (ssget '((0 . "LINE,LWPOLYLINE"))))
	  )
    
    (if (and ssall sstouch)
	(progn
	    (repeat (setq i (sslength sstouch))
		(ssdel (ssname sstouch (setq i (1- i))) ssall)
		)
	    (setq alllst (JH:selset-to-list-vla ssall)
		  touchlst (JH:selset-to-list-vla sstouch)
		  rtn (mapcar 'vlax-vla-object->ename		; <--- Returns the list of lines that satisfies the desired criteria
			      (vl-remove-if-not
				  '(lambda (x)
				       (vl-every
					   '(lambda (y)
						(vlax-invoke y 'IntersectWith x acExtendNone)
						)
					   touchlst
					   )
				       )
				  alllst
				  )
			      )
		  )
	    
	    ; rtn is a LIST of entities that matches the  described criteria.
	    
	    (setq rtnsel	; <--- This line converts that list to a selection set that you can use with (command) afterwards
		     ((lambda (x / ss)
			  (setq ss (ssadd))
			  (mapcar '(lambda (y) (setq ss (ssadd y ss)))
				  x)
			  ss
			  )
			 rtn
			 )
		  )
	    
	    ; Resume your commands here
	    
	    
	    ; Don't add anything below this line.
	    ; (sssetfirst nil rtnsel) 	; This one does a full selection of that set in the AutoCAD screen
	    )
	)
    
    ;; End routine
    
    (vla-EndUndoMark adoc)
    (princ)
    )

(defun JH:selset-to-list-vla (ss / i rtn)
    (if ss
	(repeat (setq i (sslength ss))
	    (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn))
	    )
	)
    rtn
    )

 

Link to comment
Share on other sites

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