Is there a way to check if a block is inserted at a point, or at many points?

Is there a way to check if a block is inserted at a point, or at many points?

jamieq
Collaborator Collaborator
1,863 Views
7 Replies
Message 1 of 8

Is there a way to check if a block is inserted at a point, or at many points?

jamieq
Collaborator
Collaborator

I wrote a program that inserts blocks at midpoints of lines, and it works great. However, some of these lines have blocks inserted at one end of them. I am looking for a way to check if there is a block inserted at either end of each line in my selection set. If there is, then that line is skipped. I've put together some code, and it works, but it has to process a lot of information and has taken a program that executed in less than a second and now takes up to 30 seconds (or likely more if there were more objects in the selection set) to run. 

 

This is the code I used to collect the insertion points of all the blocks:

(defun GetCaps ( / cpss cplst cpt i)
(setq i 0 cplst nil)
(if (setq cpss (ssget "A" (list (cons 0 "insert")(cons 2 "CAP")(cons 410 "Model"))))
(while (not (= i (sslength cpss)))
	(setq cpt (cdr (assoc 10 (entget (ssname cpss i)))))
	(setq cplst (append cplst (list cpt)))
	(setq i (1+ i))
)
nil)
cplst
)

 

Then I put this into my existing code to evaluate against that list:

(setq mch 0)
(foreach x (GetCaps)(if (or (equal x p1)(equal x p2))(setq mch 1)))
(if (= mch 0)
	(progn
		....
	)
)

 

This works. But it takes so long it isn't tenable. Any help that would make this run quick is much appreciated!

0 Likes
Accepted solutions (1)
1,864 Views
7 Replies
Replies (7)
Message 2 of 8

Moshe-A
Mentor
Mentor

Jamie,

 

first in the (getCaps) function use the (cons) function to build the list of points

cause it turns out that (cons) is faster then (append)

 

second in checking point do not use (foreach) cause each iterator (step) you are checking against all points

instead use (while) to stop the loop on success or even better use (vl-some)

 

and don't forget to eliminate duplicate points.

 

Moshe

 

0 Likes
Message 3 of 8

dlanorh
Advisor
Advisor

I only see a list of block insertion points being created. It would be better to combine all three things together.
After generating the list of block insertion points, query this list with the end coords of each line using (member). If there is a match skip, if there isn't insert a block at the midpoint.

 

A slightly more efficient sub would be

(defun GetCaps ( / cpss cplst i)
  (setq i 0 cplst nil)
  (if (setq cpss (ssget "X" (list (cons 0 "insert")(cons 2 "CAP")(cons 410 "Model"))))
    (repeat (sslength cpss)
      (setq cplst (cons (cdr (assoc 10 (entget (ssname cpss i)))) cplst)
            i (1+ i)
      )
    )
  )  
cplst
)

The more conditional checks you have the slower it will run

I am not one of the robots you're looking for

0 Likes
Message 4 of 8

jamieq
Collaborator
Collaborator

Thanks for the replies. I'm definitely going to consider them when writing code in the future. I actually found a way to accomplish this in another thread.

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/check-if-block-exists-on-specific-po...

 

With that code, instead of compiling a list of all the insertion points of block name CAP and then having to compare the end points of every line in the selection set to that list, now it runs a tiny ssget crossing around each endpoint and checks if there's block inserted there. Program runs just as fast as before.

 

Again, thanks for the help!! I appreciate learning from all the community members here. 

0 Likes
Message 5 of 8

Moshe-A
Mentor
Mentor
Accepted solution

and here is the code to do it

 

note that you do to not call (getCaps) more than 1 time

the (vl-some) function stop the loop as soon as the predicate-function  return not nil (e.g a positive value) and returns that value to the caller, it only return nil if the predicate-function  [(lambda) in this case] does not find a match.

 

does this help you?

moshe

 

(setq lst (getCaps))

(if (check_points p1 p2)
 (prompt "found.")
 (prompt "not found.")
)

(defun check_points (p1 p2)
 (vl-some
  '(lambda (pt)
    (or (equal pt p1 0.01) (equal pt p2 0.01))
   )
  lst
 )
)
Message 6 of 8

jamieq
Collaborator
Collaborator

Interesting. I'm going to make a test with this code and see which works faster. I have another program that could definitely use this. Thank you!!

0 Likes
Message 7 of 8

jamieq
Collaborator
Collaborator

So I decided to add another dimension to my program, and check to see if a block is inserted at the middle of the line as well. I used the code from the link above for the caps, but then used your check_points code for the midpoint block. It was still taking a couple of second. I then dropped the other code and modded yours to check a single point, and now every run through it does three checks with the check_points sub. INSTANT!! It worked instantly!! No delays. It is exactly what I was looking for. Thank you so much!!!

0 Likes
Message 8 of 8

Moshe-A
Mentor
Mentor

welcome, glad i was helpful Smiley LOL

 

 

0 Likes