LISP - automatic coordinate dimensions for a free closed polyline

LISP - automatic coordinate dimensions for a free closed polyline

Anonymous
Not applicable
11,297 Views
31 Replies
Message 1 of 32

LISP - automatic coordinate dimensions for a free closed polyline

Anonymous
Not applicable

Dear community,

 

I'm workin on Autocad Mechanical 2018 and I am looking for a LISP for automatic coordinate dimensioning for a free closed polyline. I found many LISPs and tested them all, unfortunately they either only work for orthogonal objects (base plate) or they only have linear dimensions.

 

The coordinate dimensions should look like this:

- UCS set to world

- with specific dimension style "AM_ISO_35mm"

- at each vertex of the polyline
- scale by scaling area (AMSCAREA) in which you are currently dimensioning

- zero points (starting points) - see example

- the polyline must remain a polyline, because it is important for further use

 

The double coordinate dimensions (e.g. right / left and top / bottom) will be removed later manually (via power-delete)

 

An example:

Sketch.png

 

Many thanks in advance for your support

0 Likes
Accepted solutions (1)
11,298 Views
31 Replies
Replies (31)
Message 2 of 32

ВeekeeCZ
Consultant
Consultant

No dwg, no help.

Message 3 of 32

Anonymous
Not applicable

here one example

0 Likes
Message 4 of 32

ВeekeeCZ
Consultant
Consultant

Those arrows are made automatically too? (don't have AM)

 

Because I thought that those are made by dim style...

0 Likes
Message 5 of 32

Anonymous
Not applicable

yes, automatically according to my (privat) dim style in Mechanical

0 Likes
Message 6 of 32

ВeekeeCZ
Consultant
Consultant

Great. Then I'm lost at this point. 

Consider posting this into the AM forums.

0 Likes
Message 7 of 32

hak_vz
Advisor
Advisor

Some three months ago I have created a script to automatically delete overlapping dimensions . Actually @ВeekeeCZ  has helped me at one point. I'll try to use some parts of that script to create dims the way you like. At the moment I'm half a way done,  so I won't post anything until I have something to show.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 8 of 32

Anonymous
Not applicable

Hi @hak_vz ,

 

many thanks in advance. 

0 Likes
Message 9 of 32

hak_vz
Advisor
Advisor

Here is first part of the code, just to show my idea. It creates bounding box around dimensioning object, and creates perpendicular lines from polyline vertexes to four segments. It removes all lines that intersect with object. I will tomorrow update code to create dimensions over those lines and to remove them from a drawing. Option is not to delete intersecting lines and then you can erase them with your code.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 10 of 32

Sea-Haven
Mentor
Mentor

My idea pick

pline get co-ords straight forward.

make 2 list X & Y then sort

Get min point x and y this is bottom left 

Draw Vertical lines x + foreach Y, length

Draw Horizontal lines Y + foreach x, length

Draw hor text

Draw ver text

 

Take mid point of X & Y do left right up down no need to clean up.

 

Time for a coffee !

 

 

; pline co-ords example
(defun getcoords (ent)
  (vlax-safearray->list
    (vlax-variant-value
      (vlax-get-property
    (vlax-ename->vla-object ent)
    "Coordinates"
      )
    )
  )
)

(setq co-ords (getcoords (car (entsel "\nPlease pick pline"))))
(co-ords2xy)
(princ co-ords)
(setq plent (entsel "\nPick rectang"))
(if plent (setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (car plent))))))

 

 

 

0 Likes
Message 11 of 32

hak_vz
Advisor
Advisor

Try this. I have tried to do something else,  but then used method you use  in your sample.

At the end erase bounding box lines, match dim style properties rotate text and remove duplicates.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 12 of 32

Anonymous
Not applicable

Hi @hak_vz ,

 

I just tested it, unfortunately the command is interrupted relatively shortly after the start, bevore the bounding box is completed. The box will not close automatically, the drop-down menu will be displayed only.

 

1_selecting polyline.png

 

2_set dimensions offset.png

 

3_error after dimensions offset.png

 

0 Likes
Message 13 of 32

hak_vz
Advisor
Advisor

Here is the latest version and I guess it will work ok.

In case of error please skim through code and check if all switches are ok wherever you see (command .....), since you're using German version.

Error you describe arises since switch "c" don't work in German version.

 

I can not replicate this error in English version.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 14 of 32

hak_vz
Advisor
Advisor

Here is my finalized code.

 

(defun c:autodim ()
(defun pointlist2d (lst / ret)(while lst (setq ret (cons (list (car lst)(cadr lst)) ret) lst (cddr lst))) (reverse ret))

(defun LM:boundingbox ( obj / a b lst )
    (if
        (and
            (vlax-method-applicable-p obj 'getboundingbox)
            (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'a 'b))))
            (setq lst (mapcar 'vlax-safearray->list (list a b)))
        )
        (mapcar '(lambda ( a ) (mapcar '(lambda ( b ) ((eval b) lst)) a))
           '(
                (caar   cadar)
                (caadr  cadar)
                (caadr cadadr)
                (caar  cadadr)
            )
        )
    )
)
(defun perperdicular_from_point_to_line (lin1 lin2 p / x1 y1 x2 y2 x3 y3 k m n ret)
;returns point on a line (line1 line2) as a perpendicular projection from point p
	(mapcar 'set '(x1 x2 x3) (mapcar 'car (list lin1 lin2 p)))
	(mapcar 'set '(y1 y2 y3) (mapcar 'cadr (list lin1 lin2 p)))
	(setq 
		m (-(*(- y2 y1) (- x3 x1))(*(- x2 x1) (- y3 y1)))
		n (+(* (- y2 y1)(- y2 y1))(*(- x2 x1)(- x2 x1)))
	)
	(cond 
		((/= n 0.0) 
			(setq 
				k (/ m n)
				ret (list(- x3 (* k(- y2 y1)))(+ y3 (* k(- x2 x1))))
			)
		)
	)
	ret
)
(defun getintersections	(obj1 obj2 / var)
     ; from RonJonP
     (setq var (vlax-variant-value (vla-intersectwith obj1 obj2 2)))
     (if (< 0 (vlax-safearray-get-u-bound var 1))
	  (vlax-safearray->list var)
     ) ;_ end of if
) ;_ end of defun

(defun init ( / e ent off plobj pts bbox p1 p2 p3 p4 k1 k2 k3 k4 uc_list po a b c i segs uc te to int)
    (setq e (car(entsel "\nSelect polyline to autodim >")))
    (if (not (setq off (getreal "\nDimensions offset from object <20>"))) (setq off 20))
    (cond 
        ((and e)
            (setq plobj (vlax-ename->vla-object e))
            (setq pts (pointlist2d(vlax-get plobj 'Coordinates)))
            (setq bbox (LM:boundingbox plobj))
            (command "_.pline" "_non" (car bbox) "_non"  (cadr bbox) "_non"  (caddr bbox) "_non"  (cadddr bbox) "c")
            (setq p1 (car bbox) p2 (cadr bbox) p3(cadddr bbox) p4 p1)
            (setq k1 (cadr bbox) k2 (caddr bbox) k3 (caddr bbox) k4 (cadddr bbox))
            (setq uc_list (list (list p1 k1)(list p2 k2)(list p3 k3)(list p4 k4)))
            (setq po (entlast))
            (setq a (car bbox) b (mapcar '+ (car bbox) (list 0 (* -1 off))) c (distance a b))
            (command "_.offset" "_non" c (entlast) "_non" a "_non" b "")
            (setq e (entlast))
            (setq bo (vlax-ename->vla-object e))
            (setq bbox (LM:boundingbox  bo))
            (entdel po)
            (setq i 0 segs (list))
            (while (< i 3)
                (setq a (nth i bbox) b (nth (+ i 1) bbox))
                (if (> (car a) (car b)) (setq c a a b b c))
                (setq segs (append segs (list(list a b))))
                (setq i (+ i 1))
            )
            (setq segs (append segs (list(list (car bbox)(last bbox)))))
            (entdel e)
            (setq i 0)
            (foreach seg segs
                (setq uc (nth i uc_list))
                (command "_.ucs" "w")
                (command "_.ucs" "_3p" (car uc)(cadr uc) "")
                (command "_.line" "_non" (trans (car seg) 0 1) "_non" (trans(cadr seg)0 1) "")
                (setq te (entlast))
                (foreach pt pts
                    (setq proj (perperdicular_from_point_to_line (trans(car seg)0 1) (trans(cadr seg)0 1) (trans pt 0 1)))
                    (command "_.line" "_non" (trans pt 0 1) "_non" proj "")
                    (setq to (vlax-ename->vla-object (entlast)))
                    (setq int (getintersections to plobj))
                    (entdel (entlast))
                    (command "_.dimordinate" "_non" (trans pt 0 1) "_non" proj)
                    (if (or (= i 1) (= i 3))
                        (progn
                            (setq ent (entget(entlast)))
                            (setq ent (subst (cons 53 4.71238898)(assoc 53 ent)  ent))
                            (entmod ent)
                        
                        )
                    )
                )
                (setq i (+ i 1))
                (entdel te)
            )
      
        )
    )
)
(setvar 'cmdecho 0)
(vla-endundomark (vla-get-ActiveDocument (vlax-get-acad-object)))
(vla-startundomark (vla-get-ActiveDocument (vlax-get-acad-object)))
(init)
(command "ucs" "w")
(vla-endundomark (vla-get-ActiveDocument (vlax-get-acad-object)))
(setvar 'cmdecho 1)
(princ)
)
(princ "\n Type Autodim to dimension an polyline ")
(princ)

If you find this usable, select this as final solution.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 15 of 32

ВeekeeCZ
Consultant
Consultant

I knew this would be possible... nice, easy and quick! Just using built-in QDIM command.

See HERE 

 

 
Message 16 of 32

Anonymous
Not applicable

Hi @hak_vz ,

 

 

These things have occurred during testig: 

- UCS has turned 90 ° counterclockwise (X is vertical, Y is negativ horizontally), then the vertical dimensions "on the head"

AutoDimTest.png

 

- how can you set a specific user dimension style (e.g. "AM_ISO_Plate" or similar)

 

- i work in scalling areas (M1:15 for assembly, M1:5 for details), where the dim style takes over the scale from the scaling area. How can you set a temporare global dim factor M1:5 (for the details) in the scaling area? Now it use a global dim scale factor.

 

Many thanks for your help in advance, your LISP will save a lot of sleepless nights 😊

(and i can learn something new about it)

0 Likes
Message 17 of 32

Anonymous
Not applicable

@ВeekeeCZ ,

 

i know QDIM very good - was my tool until now, but this is not suitable for a work with 50+ details :-).

 

Thanks to the community, we can protect our eyes 😎

0 Likes
Message 18 of 32

hak_vz
Advisor
Advisor

My code works as follow:

1) It creates a bounding box around dim object

2) It moves in cc direction and creates ordinate dims

All the time it works in direction of bounding box side and takes her as a x direction

so for horizontal ordinate dim lines it rotates text for 270 deg

 

It should not change usc direction, and actually in each iteration **** first changes ucs to world

Before you use the code use command DIMSIZE to set scaling

 

In acad 2014 it all works ok

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 19 of 32

Anonymous
Not applicable

I tested it in AutoCAD Mechanical 2018, without good result (see DWG example in my previous post).

 

When I use QDIM for ordinate dimension and compare it with AUTODIM possibilities, the properties of both dimension methodes are difficult, especially for vertical dimension (by "_list" command):

 

Properties              QDIM          AUTODIM

associative             yes              no

type                         Y axis          X axis

 

All the vertical dimensions have wrong type (should be Y axis)

 

I try to understand why it is so and what can I do differently. But no idea.

 

 

0 Likes
Message 20 of 32

hak_vz
Advisor
Advisor

I'll have to change my algorithm.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes