Autolisp program acts differently depending on how zoomed in I am.

Autolisp program acts differently depending on how zoomed in I am.

tamas.halasz
Enthusiast Enthusiast
1,104 Views
10 Replies
Message 1 of 11

Autolisp program acts differently depending on how zoomed in I am.

tamas.halasz
Enthusiast
Enthusiast

Hello good people. 
Is it me or just autocad being autocad? Im trying to insert a block where 2 certain polylines meet.

Just to test i put a command "_zoom" before the insertions happen, and the problem went away, but it makes the program run slower, and not very elegant of a solution i guess.  How should i get around this ideally?

Thanks everyone!

(vl-load-com)
(defun c:SWPNT (/ ss i ent firstPnt lastPnt)
  (setq ss (ssget  '((0 . "*POLYLINE,LINE")(8 . "*swept_tee*"))))
  (setq i 0)

  (repeat (sslength ss)
    (setq ent (vlax-ename->vla-object (ssname ss i)))
    (setq firstPnt (vlax-curve-getStartPoint ent))
    (setq lastPnt (vlax-curve-getEndPoint ent))
    ;(command "_zoom" "_C" lastPnt 300); IF i leave this in, things work as intended
    (cond ((ssget "_C" firstPnt firstPnt '((0 . "*POLYLINE,LINE") (8 . "*alep_s*") (-4 . "<not")(8 . "*swept_tee*")(-4 . "not>")))
	   (entmakex (list (cons 0 "INSERT") (cons 2 "sweptee_point") (cons 10 firstPnt)(cons 8 "_alep_swept_tee_pont")))
	   );cond
	  ((ssget "_C" lastPnt lastPnt '((0 . "*POLYLINE,LINE") (8 . "*alep_s*") (-4 . "<not")(8 . "*swept_tee*")(-4 . "not>")))
	   (entmakex (list (cons 0 "INSERT") (cons 2 "sweptee_point") (cons 10 lastPnt)(cons 8 "_alep_swept_tee_pont")))
	   );cond
	  );cond legvége
    (setq i (+ 1 i))
    );repeat
  );defun

0 Likes
Accepted solutions (1)
1,105 Views
10 Replies
Replies (10)
Message 2 of 11

Sea-Haven
Mentor
Mentor
Accepted solution

2 answers, it is a known bug that at times objects will snap to wrong spot, this has been a problem for like 30 years and using ZOOM C fixes it, the other that may simply fix it is (setvar 'osmode 0) this turns snap off. 

Message 3 of 11

tamas.halasz
Enthusiast
Enthusiast
Thank you for your answer, wasn't aware of this being a several decade issue. But at least a license doesn't cost 2k USD a year. 😄
I turned snapp off while testing thinking it might be the issue, did not help. Zoom C it is then. 🙂
0 Likes
Message 4 of 11

pbejse
Mentor
Mentor

@tamas.halasz wrote:

Hello good people. 
Is it me or just autocad being autocad? Im trying to insert a block where 2 certain polylines meet.

Just to test i put a command "_zoom" before the insertions happen, and the problem went away, but it makes the program run slower, and not very elegant of a solution i guess.  How should i get around this ideally?

Thanks everyone!


It's not just you @tamas.halasz .  It is a known bug with Zoom level and ssget.

There could be way to do this without the "zoom" using "_X" with point filter instead of "C"

Would you mind posting a sample drawing?

 

Message 5 of 11

tamas.halasz
Enthusiast
Enthusiast

Thank you for your answer. Cant wait to see your solution to this problem. 🙂

0 Likes
Message 6 of 11

pbejse
Mentor
Mentor

@tamas.halasz wrote:

Thank you for your answer. Cant wait to see your solution to this problem. 🙂


Initial test looks promising,  What i did is. reverse the selection process. "_alep_s_DIGI_geod" before "*_swept_tee_*"  Zoom  doesnt factor in anyway with the selection.

 

Only thing is it would be ideal if the startpoint/endpoint of the "*_swept_tee_*"  Lines/Polylines are exactly or near a vertex of a polyline. 

We may have to use brute-force approach

 

 

 

 

 

 

0 Likes
Message 7 of 11

tamas.halasz
Enthusiast
Enthusiast

Yes, polylines sometimes dont even touch, in those cases i don't want to insert a block. My tought process was to check if either ends of a polyline (swept_tee_geod) touches another one on the other layer, and if the end of the polyline is not exactly on the other polyline just do not insert. After inserting the blocks i would see where the two layers dont meet, because of the missing block. 

0 Likes
Message 8 of 11

pbejse
Mentor
Mentor

This here is the failed attempt. using the concept of ssget "_X" with point filter, should  work both ways either selecting  "*swept_tee*" first or the  "_alep_s*"  BUT like i said on my previous post, ideally the the endpoint/starpoint of the  "*swept_tee*" polylines are placed exactly on  a vetex of the target polyline.   So its a hit   and a miss.

(defun c:SWPNT (/ _Allpoints ss i ent pathOfSsgetC )
  (defun _Allpoints (en / param lst)
    (if	en
      (if (eq (setq param (vlax-curve-getEndParam en)) (fix param))
	(repeat	(setq param (1+ (fix param)))
	  (setq	lst (cons (vlax-curve-getPointAtParam
			    en
			    (setq param (1- param))
			  )
			  lst
		    )
	  )
	)
	(list (vlax-curve-getStartPoint en)
	      (vlax-curve-getEndPoint en)
	)
      )
    )
  )
  (if
    (setq ss "_X" (ssget '((0 . "*POLYLINE,LINE") (8 . "*swept_tee*")))
    )
     (repeat (Setq i (sslength ss))
       (setq ent (vlax-ename->vla-object (ssname ss (Setq i (1- i)))))
       (Setq pathOfSsgetC (_Allpoints ent))
       (foreach	p pathOfSsgetC
	 (if (and
	       (setq f (ssget "_X"
			      (append
				'((0 . "*POLYLINE,LINE")(8 . "_alep_s*") (-4 . "<not")
				  (8 . "*swept_tee*") (-4 . "not>")
				 )
				(list (cons 10 p))
			      )
		       )
	       )
	     )
	     (entmakex (list (cons 0 "INSERT")
			     (cons 2 "sweptee_point")
			     (cons 10 p)
			     (cons 8 "_alep_swept_tee_pont")
		       )
	     )
	 )
       )
     )
  )
  (princ)
)

Command: SWPNT

 

This one used the brute force approach ( from an old code modified to work on your requirements )

(defun c:SWPNtBF (/ _Sort MainLine_lst ssi ent Swept_tee_lst HeyImHere f)
;;;		pBe Jul 2021 | Aug 2015		;;;
  (defun _Sort (l sym)
    (car
      (vL-sort l '(lambda (a b) (< (sym a) (sym b))))
    )
  )
  (if (and
	(tblsearch "BLOCK" "sweptee_point")
	(setq ss (ssget  "_X" '((0 . "*POLYLINE,LINE") (8 . "_alep_s*"))))
      )
    (progn
      (repeat (setq i (sslength ss))
	(setq ent (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
	(if (wcmatch (vla-get-layer ent) "*swept_tee*")
	  (setq	Swept_tee_lst
		 (cons
		   (list (vlax-curve-getStartPoint ent)
			 (vlax-curve-getEndPoint ent)
		   )
		   Swept_tee_lst
		 )
	  )
	  (setq MainLine_lst (cons ent MainLine_lst))
	)
      )
      (While (setq a (Car Swept_tee_lst))
	(setq HeyImHere
	       (mapcar '(lambda	(e)
			  (setq	d
				 (mapcar
				   '(lambda (p)
				      (list
					(distance (vlax-curve-getClosestPointTo e p) p)
					p
				      )
				    )
				   a
				 )
			  )
			  (list (_Sort d car) e)
			)
		       MainLine_lst
	       )
	)
	(setq f (_Sort HeyImHere caar))
	(entmakex (list	(cons 0 "INSERT")
			(cons 2 "sweptee_point")
			(cons 10 (cadar f))
			(cons 8 "_alep_swept_tee_pont")
		  )
	)
	(setq Swept_tee_lst (Cdr Swept_tee_lst))
      )
    )
  )
  (princ)
) 

Command: SWPNTBF 

 

HTH

 

0 Likes
Message 9 of 11

Owackenreuther
Advocate
Advocate

I've encountered a similar issue in a different LISP file but setting the 'osmode variable to 0 did not resolve it for me. I don't think that ZOOM C is an option because the user selects a 2 point bounding box used in ssget.

 

I couldn't find any further documentation on this issue. Do you know of any sources or other solutions?

0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

@Owackenreuther wrote:

.... a similar issue in a different LISP file but setting the 'osmode variable to 0 did not resolve it ....


May we see the "different LISP file"?

Kent Cooper, AIA
0 Likes
Message 11 of 11

Owackenreuther
Advocate
Advocate

@Kent1Cooper, I'm not sure if I'm allowed to share the LISP file externally. However, I believe that I've identified the issue source. LISP file includes a sub-routine that uses a near OSNAP.

0 Likes