Question to auto dimension beam width

Question to auto dimension beam width

Anonymous
Not applicable
2,537 Views
19 Replies
Message 1 of 20

Question to auto dimension beam width

Anonymous
Not applicable

Hello everyone, I have a requirement to mark the width of the beam in dwg.  But the question is that I need to select two lines separately, is not useful. So I would like to ask if there is a good way (lisp) to select all lines and automatically mark the width at the midpoint of the two lines (like picture below). Thanks for help.

0 Likes
Accepted solutions (1)
2,538 Views
19 Replies
Replies (19)
Message 2 of 20

Sea-Haven
Mentor
Mentor

This one is wrong 

SeaHaven_0-1635824543370.png

Complicated need to have a think same as the 1  marked the ends are trimmed on a angle. A simple fence solution drag over multiples would be easy but you would need to do 9 times.

 

Why not do the dims as you add the beams would be much easier. Are they meant to be concrete slab beams ?

0 Likes
Message 3 of 20

Anonymous
Not applicable

Thanks for answer. But I didn't understand your opinion. In my opinion, because the two lines don’t know each other.So even using ssget to choose all the beam line, but I don't know how to do the dims to all two lines to beam respectively.

Because I need to quickly know the width between each beam.There are no dims on the architecture picture originally, so I want this function to let me check each beam dims.

0 Likes
Message 4 of 20

ВeekeeCZ
Consultant
Consultant

try this one

 

(vl-load-com)

(defun c:DimBeamWidth ( / s l e)

  (if (and (setq s (ssget '((0 . "LINE"))))													; select LINEs
	   (setq l (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))										; list of lines
	   (setq l (mapcar '(lambda (e) (list e (mapcar '/ (mapcar '+ (cdr (assoc 10 (entget e))) (cdr (assoc 11 (entget e)))) '(2 2)))) l))	; list of '(line (mid-point))
	   )
    (while (and (setq e (car l))														; foreach line
		(setq l (cdr l)))														; remove line from the rest of list
      (setq l (vl-sort l '(lambda (e1 e2) (< (distance (cadr e) (cadr e1)) (distance (cadr e) (cadr e2))))))					; sort the rest by min dist between mid-points
      (command "_.dimaligned" "_non" (trans (cadr e) 0 1) "_non" (trans (vlax-curve-getclosestpointto (caar l) (cadr e)) 0 1) "_non" "@")	; dimali line to the closest one
      (setq l (cdr l))))															; remove closest one from list
  (princ)
  )

 

0 Likes
Message 5 of 20

Anonymous
Not applicable

Thanks for your lisp.It works great but has some bugs like picture below.Is there any solution to fix this question?

This is my dwg file. 

0 Likes
Message 6 of 20

ВeekeeCZ
Consultant
Consultant
Accepted solution

Well, as matter of fact, all issues are caused by drawing flaws or violations against presuppositions. I've marked them in your drawing. Once there is some issue, it spreads like an infection to the surrounding area. One issue can cause 10 others. So for that matter I've added a maximum diameter limit, to skip the issue and stop spreading.

Also could be an issue if more pips are parallel (or just close) and some of them has diameter >= wall distance. 

And of course, the routine works with LINEs only, not polylines.

That's all I can do. Read (at least) the notes in code, they will help you understand the algorithm. It's not magic.

HTH

 

(vl-load-com)

(defun c:DimBeamWidth ( / s l e m)

  (if (and (setq s (ssget '((0 . "LINE"))))													; select LINEs
	   (setq m (getint "\nMax diameter limit: "))
	   (setq l (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))										; list of lines
	   (setq l (mapcar '(lambda (e) (list e (mapcar '/ (mapcar '+ (cdr (assoc 10 (entget e))) (cdr (assoc 11 (entget e)))) '(2 2)))) l))	; list of '(line (mid-point))
	   )
    (while (and (setq e (car l))														; foreach line
		(setq l (cdr l)))														; remove line from the rest of list
      (setq l (vl-sort l '(lambda (e1 e2) (< (distance (cadr e) (cadr e1)) (distance (cadr e) (cadr e2))))))					; sort the rest by min dist between mid-points
      (if (< (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e))) m)
	(progn
	  (command "_.dimaligned" "_non" (trans (cadr e) 0 1) "_non" (trans (vlax-curve-getclosestpointto (caar l) (cadr e)) 0 1) "_non" "@")	; dimali line to the closest one
	  (setq l (cdr l))))))															; remove closest one from list
  (princ)
  )

 

0 Likes
Message 7 of 20

Anonymous
Not applicable

This LISP is very awesome. In this case, it works very nice. I will try more dwg file to test whether to deal with any situation. I will try to realize your lisp code later. Let me thank you again to express my gratitude.

0 Likes
Message 8 of 20

Anonymous
Not applicable

I have some question to ask you.I read your code can you help me to confirm that I understand the logic right or not.

1.select all the lines 2.get the midpoint of all lines 3. find each midpoint to midpoint distance and dimaligned the minimum pairs 4.remove lines which have been completed until  no two midpoints distance greater than the limit.

I test a dwg file(try.dwg is below) and found some questions. In Q1.(picture below) I marked the midpoints for each lines.Limit I set 100. I don't understand that why 17.5 this label be produced,but the parallel lines don't have dim. In Q2. the minimum distance is 25,but the parallel lines don't have dim and appears 81.9996 larger distance.These questions are not the same as the  code's logic I understand.Please let me know where the problem is. 

THX

0 Likes
Message 9 of 20

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

I have some question to ask you.I read your code can you help me to confirm that I understand the logic right or not.

1.select all the lines OK

2.get the midpoint of all lines OK

3. for the first line of selection set get mid-to-mid distance to all the rest, get the closest one.

3. find each midpoint to midpoint distance and dimaligned the minimum pairs

4. remove both lines if were were dimed, or the line which does not have its pair within the limit.

4.remove lines which have been completed until  no two midpoints distance greater than the limit.

 

I test a dwg file(try.dwg is below) and found some questions. In Q1.(picture below) I marked the midpoints for each lines.I don't understand that why 17.5 this label be produced,but the parallel lines don't have dim. In Q2. the minimum distance is 25,but the parallel lines don't have dim and appears 81.9996 larger distance.These questions are not the same as the  code's logic I understand.Please let me know where the problem is. 

THX


 

So it's not all to all comparison but first to all. So if the first one is supposed to be single, it does not know that, so it steels the closest line (within the limit) from the closest pair. It does not check parallelity at all.

0 Likes
Message 10 of 20

Anonymous
Not applicable

I have a better understanding of code logic,but I still have some questions to ask you.First, you said it is first to all,so all the lines are paired in pairs according to the system’s own order?

Q01. distance between pt1 to pt2 is 184.25. Limit I set 100,it shouldn't be found pt2 in theory.I wonder if it is the distance from point to line instead of point to point?

Q02.up and down 35 width lines have been dimmed,those lines are removed based on your code.But I don't know why 17.5 will be appeared, the line on 35 width upper line should be removed.If the distance from the midpoint of line B exceeds the limit.

That's my questions.Please tell me if  I do not understand the code's problem or other problems.THX

Message 11 of 20

ВeekeeCZ
Consultant
Consultant

I see, good catch! Thanks. It was my bad. 

 

The thing is that once we found the closest line (by min mid-mid dist) we put DIMALG from mid of first one to the CLOSEST point of the second line, so we can perpendicularly dim a diameter. Which was good...

...if I haven't used this mid-closestpoint dist for the limit condition. It should be mid-mid dist.

 

I guess it would solve both issues.

 

(vl-load-com)

(defun c:DimBeamWidth ( / s l e m)

  (if (and (setq s (ssget '((0 . "LINE"))))													; select LINEs
	   (setq m (getint "\nMax diameter limit: "))
	   (setq l (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))										; list of lines
	   (setq l (mapcar '(lambda (e) (list e (mapcar '/ (mapcar '+ (cdr (assoc 10 (entget e))) (cdr (assoc 11 (entget e)))) '(2 2)))) l))	; list of '(line (mid-point))
	   )
    (while (and (setq e (car l))														; foreach line
		(setq l (cdr l)))														; remove line from the rest of list
      (setq l (vl-sort l '(lambda (e1 e2) (< (distance (cadr e) (cadr e1)) (distance (cadr e) (cadr e2))))))					; sort the rest by min dist between mid-points
      (if (< (distance (cadr e) (cadar l)) m)
	(progn
	  (command "_.dimaligned" "_non" (trans (cadr e) 0 1) "_non" (trans (vlax-curve-getclosestpointto (caar l) (cadr e)) 0 1) "_non" "@")	; dimali line to the closest point of closest line
	  (setq l (cdr l))))))															; remove closest one from list
  (princ)
  )

 

Edit: Thinking of it a little more... not sure if I have done the right thing. If the drawing is without flaws, IMHO the original code would work better. See the case from msg 2. When lines are shifted, the max limit is not "diameter" but mid-mid distance. So it was just thinking...

In general, don't like the idea to build the code robust enough to eat up all the flaws unless it's necessary.

 

BTW the order depends on the way it was selected. You can select it one-be-one or with fence option, that way it follows this order. With any type of window/crossing selection, it follows the order of creation.

Message 12 of 20

Anonymous
Not applicable

I probably understand what you said, I will study to understand which way is better and more suitable for my picture.Thank you so much.

0 Likes
Message 13 of 20

Anonymous
Not applicable

I think the order part can be optimized. If distance between mid to mid equal to mid to the CLOSEST point and lower than the limit, these lines should have first priority.After complete first group lines dims and remove them from list , do the remaining lines by original command you write before. I think that is a way to reduce the occurrence of errors by order's problem. Please help me to modify the code in this part, i tried to fix it but didn't work. Also, can you add a limit that distance should be larger than zero and lower than setting m value to avoid overlapping of some line segments.Sorry to bother you so much. if I have the ability, I will modify it myself, but I am a beginner to lisp.Thank you so much.I can't thank you enough.

0 Likes
Message 14 of 20

ВeekeeCZ
Consultant
Consultant

Ok, try this one then.

 

(vl-load-com)

(defun c:DimBeamWidth ( / s l k e m)

  (if (and (setq s (ssget '((0 . "LINE"))))													; select LINEs
	   (setq m (getint "\nMax diameter limit: "))
	   (setq l (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))										; list of lines
	   (setq l (mapcar '(lambda (e) (list e (mapcar '/ (mapcar '+ (cdr (assoc 10 (entget e))) (cdr (assoc 11 (entget e)))) '(2 2)))) l))	; list of '(line (mid-point))
	   )
    (while (and (setq e (car l))														; foreach line
		(setq l (cdr l)))														; remove first line from the list
      (setq l (vl-sort l '(lambda (e1 e2) (< (distance (cadr e) (cadr e1)) (distance (cadr e) (cadr e2))))))					; sort the rest by min mid-mid dist
      (if (equal (distance (cadr e) (cadar l))													; if eq mid-mid dist
		 (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e)))								;    to mid-closestpnt
		 1e-6)
	(progn
	  (command "_.dimaligned" "_non" (trans (cadr e) 0 1) "_non" (trans (vlax-curve-getclosestpointto (caar l) (cadr e)) 0 1) "_non" "@")	; dimali line to the closest one
	  (setq l (cdr l)))															; remove closest one from list
	(setq k (cons e k)))))															; else add the line to new list for second round.

  (if (setq l k)
    (while (and (setq e (car l))														; foreach line
		(setq l (cdr l)))														; remove line from the rest of list
      (setq l (vl-sort l '(lambda (e1 e2) (< (distance (cadr e) (cadr e1)) (distance (cadr e) (cadr e2))))))					; sort the rest by min dist between mid-points
      (if (< (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e))) m)
	(progn
	  (command "_.dimaligned" "_non" (trans (cadr e) 0 1) "_non" (trans (vlax-curve-getclosestpointto (caar l) (cadr e)) 0 1) "_non" "@")
	  (setq l (cdr l))))))
  (princ)
  )
0 Likes
Message 15 of 20

Sea-Haven
Mentor
Mentor

John Unden posted an interesting method of selecting using pickbox and just making it bigger till it picks say 2 lines, the control pt would be the mid of a line. May do the find much faster compared to closestpointto.

0 Likes
Message 16 of 20

Anonymous
Not applicable

I think your code is not my mean.

First group:

  1. (distance (cadr e) (cadar l) equal to (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e))
  2. (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e)) must be lager than zero and smaller than the limit m

If 1 and 2 establish at the same time, do the dims for these lines. After doing dims remove these lines(group 1 successful lines).The rest lines that are not marked remain to the second group.

Second group;

  1. (distance (cadr e) (vlax-curve-getclosestpointto (caar l) (cadr e)) must be lager than zero and smaller than the limit m

The rest lines do the dims.

Please help me to modify. Thank you so much.

0 Likes
Message 17 of 20

Anonymous
Not applicable
Thanks for answering, is there a related link?
0 Likes
Message 18 of 20

ВeekeeCZ
Consultant
Consultant

I think you're smart enough to know it must have come ... it's in your hands from now on. Or at least not in mine any more.

Best of luck.

0 Likes
Message 19 of 20

Sea-Haven
Mentor
Mentor

Send a private mail to John Unden I thought I saved his code.

0 Likes
Message 20 of 20

john.uhden
Mentor
Mentor

Private mail is a bad idea unless you are asking for my address to send me money.  Most all conversations about forum topics should be posted publicly within the forum.

Anyway, here it is...

 

(defun @OnePick (p filter / *error* pb ss)
  (defun *error* (err)
    (setvar "pickbox" pb)
    (princ)
  )
  (setq pb (getvar "pickbox"))
  (while (not ss)
    (setq ss (ssget p filter))
    (if (not ss)(setvar "pickbox" (1+ (getvar "pickbox"))))
  )
  (sssetfirst nil ss)
  (*error* nil)
)

 

Its intended use was to successfully select an Mtext with one pick even if that pick were in a gap between lines and/or characters.  The size of the pickbox determines how much territory an entsel or nentsel or ssget will cover.  The bigger the pickbox the less likelihood of missing.

The shortcoming is that when using ssget and one point AutoCAD is looking for only one entity, so using this function will not help you select multiple entities.  To select multiple entities with one pick you would have to use the Crossing option and spreading out the corners until successful.

John F. Uhden

0 Likes