LISP - automatic coordinate dimensions for a free closed polyline

LISP - automatic coordinate dimensions for a free closed polyline

Anonymous
Not applicable
11,187 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,188 Views
31 Replies
Replies (31)
Message 21 of 32

ВeekeeCZ
Consultant
Consultant

Just a quick code... as to show how such a thing could be quite simply done. No ambition to fill up all your reqs.

 

(vl-load-com)

(defun c:QDimo (/ *error* doc ds dc s l i e d)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (if dc (setvar 'dimscale dc))
    (if ds (command-s "_.DIMSTYLE" "_R" ds))
    (vla-endundomark doc)
    (princ))
  
  (if (and (setq s (ssget '((0 . "LWPOLYLINE"))))
	   (setq l (entlast))
	   (setq ds (getvar 'dimstyle)
		 dc (getvar 'dimscale))
	   (not (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object)))))
	   (or (tblsearch "DIMSTYLE" "AM_ISO_35mm")
	       (prompt "\nError: DimStyle 'AM_ISO_35mm' does not found it the drawing."))
	   (vl-cmdf "_.DIMSTYLE" "_R" "AM_ISO_35mm")
	   (setvar 'dimscale (if c:amscarea (c:amscarea) dc))
	   )
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i))))
      (vla-getboundingbox (vlax-ename->vla-object e) 'p 'r)
      (setq p (vlax-safearray->list p))
      (setq r (vlax-safearray->list r))
      (command "_.QDIM" e "" "_O" (mapcar '+ p '(-60 10)))
      (command "_.QDIM" e "" "_O" (mapcar '+ r '(-10 60)))))
  (while (setq l (entnext l))
    (setq d (entget l))
    (entmod (subst (cons 10 p) (assoc 10 d) d)))
  (*error* "end")
  )

 

Message 22 of 32

hak_vz
Advisor
Advisor
Accepted solution

@Anonymous wrote:

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 have added a line that converts all ordinate dimensions to annotative and it now uses current annotative scale that you set before you use a AUTODIM.

In my case dims are not associative since they are generated from points and are not connected to object

Coordinates y are different but result shown is correct since  In my code I exploit only x coord that is defined by a direction of bounding box segment, that is either horizontal or vertical.

Before command starts it will change ucs to world.

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 23 of 32

Anonymous
Not applicable

@hak_vz ,

 

many thanks for your help and inspiration. I tested now in a pure Autocad, it works. But not so good in Autocad Mechanical - the vertical dimensions (Y axis) are stil head down. Maybe thiis will be explained over time.

 

Your help showed me the way, thank you very much

Message 24 of 32

avinash00002002
Collaborator
Collaborator

Hi

How do you resolve this issue I have plenty of times done setting, and some modification in lisp file but no sucess.

 

if you send me.

 

Avinash

0 Likes
Message 25 of 32

Anonymous
Not applicable

Hi @avinash00002002,

 

ATTENTION - it only works in AutoCAD Mechanical!

After several attempts, I finally chose the recommended combination of LISP and macro command.

 

It's not perfect, but for now it's enough for me. If someone suggests a better method or optimization, thank you in advance.

 

LISP see attachement.

 

Diesel macro (with DIMSTYLE-definition at the start, with Power-Erase function at the end):

^C^C-dimstyle;h;AM_ISO_35mm_Feldhöhen_5mm;^C^C^CDimAutoOrdinateMECH;\AMAUTODIM;!aadObj1;;!aad0V;!aad0H;_v;!aadPVL;;_h;!aadPHO;;DimAutoOrdinateMECH;\AMAUTODIM;_p;;!aad0V;!aad0H;_v;!aadPVR;;_h;!aadPHU;;^C^C_ampowererase;

0 Likes
Message 26 of 32

CADaSchtroumpf
Advisor
Advisor

@Anonymous  a écrit :

It's not perfect, but for now it's enough for me. If someone suggests a better method or optimization, thank you in advance.


Hello
I'm not sure if this will meet your need, but I suggest the following.
It uses the dimension style and the current layer, so choose them wisely.
If the result is not convincing (extension line crosses the polyline), undo, reverse the polyline and start over.

(defun c:DIMORD_POLY_CONTINUE ( / sel ent lo_pt l_pt minpt maxpt off_dim l_cr lst q_pt n count EDGE0 EDGE1 EDGE2 EDGE3)
	(princ "\nSelect a LWPOLYLINE : ")
	(while (not (setq sel (ssget "_+.:E:S" '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))))
	(setq
		ent (ssname sel 0)
		lo_pt (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget ent)))
		l_pt (mapcar '(lambda (z) (trans z 0 1)) lo_pt)
		minpt (list (eval (append '(min) (mapcar 'car l_pt))) (eval (append '(min) (mapcar 'cadr l_pt))))
		maxpt (list (eval (append '(max) (mapcar 'car l_pt))) (eval (append '(max) (mapcar 'cadr l_pt))))
	)
	(initget 7)
	(setq off_dim (getdist (car l_pt) "\nOffset for dimension: "))
	(setvar "CMDECHO" 0)
	(command "_.UNDO" "_begin")
	(command "_.UCS" "_3p" "_none" minpt "_none" (list (car maxpt) (cadr minpt)) "_none" (list (car minpt) (cadr maxpt)))
	(setq
		l_pt (mapcar '(lambda (z) (trans z 0 1)) lo_pt)
		minpt (list (eval (append '(min) (mapcar 'car l_pt))) (eval (append '(min) (mapcar 'cadr l_pt))))
		maxpt (list (eval (append '(max) (mapcar 'car l_pt))) (eval (append '(max) (mapcar 'cadr l_pt))))
		l_cr
		(list
			(list (car minpt) (cadr minpt))
			(list (car maxpt) (cadr minpt))
			(list (car maxpt) (cadr maxpt))
			(list (car minpt) (cadr maxpt))
		)
	)
	(foreach e l_cr (setq q_pt (cons (vl-position (apply 'min (setq lst (mapcar '(lambda (x) (distance e x)) l_pt))) lst) q_pt)))
	(setq q_pt (append q_pt (list (car q_pt))) n 0)
	(repeat 4
		(setq count 0)
		(repeat (1+ (- (if (> (car q_pt) (cadr q_pt)) (+ (length lst) (cadr q_pt)) (cadr q_pt)) (car q_pt)))
			(set (read (strcat "EDGE" (itoa n))) (cons (nth (rem (+ (car q_pt) count) (length lst)) l_pt) (eval (read (strcat "EDGE" (itoa n))))))
			(setq count (1+ count))
		)
		(set (read (strcat "EDGE" (itoa n))) (vl-sort (eval (read (strcat "EDGE" (itoa n)))) '(lambda (e1 e2) (if (zerop (rem n 2)) (< (car e1) (car e2)) (< (cadr e1) (cadr e2))))))
		(set (read (strcat "EDGE" (itoa n)))
			(if (or (eq n 0) (eq n 3))
				(append (list (nth n l_cr)) (eval (read (strcat "EDGE" (itoa n)))) (list (nth (rem (1+ n) 4) l_cr)))
				(append (list (nth (rem (1+ n) 4) l_cr)) (eval (read (strcat "EDGE" (itoa n)))) (list (nth n l_cr)))
			)
		)
		(setq n (1+ n) q_pt (cdr q_pt))
	)
	(setq n 0)
	(repeat 4
		(while (eval (read (strcat "EDGE" (itoa n))))
			(command "_.DIMORDINATE" "_none" (car (eval (read (strcat "EDGE" (itoa n))))))
			(if (zerop (rem n 2))
				(command "_X" "_none" (list (caar (eval (read (strcat "EDGE" (itoa n))))) (if (zerop n) (+ (cadr maxpt) off_dim) (- (cadr minpt) off_dim))))
				(command "_Y" "_none" (list (if (eq n 1) (+ (car maxpt) off_dim) (- (car minpt) off_dim)) (cadar (eval (read (strcat "EDGE" (itoa n)))))))
			)
			(set (read (strcat "EDGE" (itoa n))) (cdr (eval (read (strcat "EDGE" (itoa n))))))
		)
		(setq n (1+ n) l_cr (cdr l_cr))
	)
	(command "_.UCS" "_previous")
	(command "_.UNDO" "_end")
	(setvar "CMDECHO" 1)
	(prin1)
)
Message 27 of 32

Anonymous
Not applicable

@CADaSchtroumpf ,

 

very good, another solution 👍👍

0 Likes
Message 28 of 32

avinash00002002
Collaborator
Collaborator

I tries so much times for no result please see my attached dwg. can you just update for me.

0 Likes
Message 29 of 32

hak_vz
Advisor
Advisor

@avinash00002002 

 

Try attached lisp to auto dimension "baseplate" i.e closed polyline with straight line edges  and circles (holes) inside. If you need to dimension baseplate with circular edges, open new post.

 

 

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 30 of 32

hak_vz
Advisor
Advisor

@avinash00002002 

Here is edited version that will autodim baseplate with blocks placed inside not circles as I stated in previous reply. Block can represent any mechanical element like nuts and bolts, or whatever you like. Previous version was tailored for a OP that looked to autodim blocks named "H2". As a result it didn't work in general case. Drawing should be created in 1 : 1 scale and dimensions are unitless (decimal system).

 

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 31 of 32

avinash00002002
Collaborator
Collaborator

Hi!

Please see my drawing with ellipse marked in red. the dimension are not coming on the dimension line as other dimensions. 

another thing is if two block in one line in horizontal or vertical all dimensions are duplicated. please see overlapping  dimensions.

I tried to remove duplicate dimensions and horizontal dimensions is on above line but not succeed.

 

Avinash

0 Likes
Message 32 of 32

hak_vz
Advisor
Advisor

@avinash00002002 

 

My code is created to work with decimal units and it then creates correct result.

 

 

Untitled.png

 

In case when you have more then one block along same line you'll receive duplicate dimensions. Simply delete what is duplicate, and transfer dimension line to opposite side if needed. It's complicate to code in all possible situations.

Unfortunately settings that you use in your drawing, are responsible for result you receive, used dim style and similar. You have measurement scale factor set to 4 and similar.

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.