Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Automatic dimension

60 REPLIES 60
SOLVED
Reply
Message 1 of 61
larsr2866
14651 Views, 60 Replies

Automatic dimension

Hello everyone,

 

I did a bit of searching on this forum for automatic dimensions. I have found some interesting tips for automatic dimensions with selecting rectangles, but i'd try something else.

 

I made a screenshot for what i want to achieve. I want to automatically create 2 dimensions between the first lines/polylines/objects/... where i am clicking in. 

 

I hope it's clear on the screenshot i took ? (the red circle is the position i click, and at that position i would have a vertical en horizontal dimension between the first lines/plines.)

 

I don't know if there are options for this?

 

Thanks in advance.

Lars

dim.jpg

 

 
 
 
 
 
60 REPLIES 60
Message 21 of 61
Sea-Haven
in reply to: hak_vz

Just a suggestion wrote a auto dim like back in 1992 using fence option pick 1st point then use perp to end point so no need for hor or vert options as uses 2 pt angle, obviously if line work end is on a slope will get problems. Would it just not be look at angle and do a readable option. draw dim top or right etc. Use aligned not ver or hor.

Message 22 of 61
hak_vz
in reply to: larsr2866

@Sea-HavenCode is made according to @larsr2866 request. Angled dimensions are not considered. For some general solution your comment apply.

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 61
hak_vz
in reply to: larsr2866

@larsr2866Here is improved  code that takes into account undoing all created dims in case of wrong points selection and suppresses information "Dimension disassociated"   caused by DIMASSOC system variable.

 

(defun c:dimhorver_all 
	;author hak_vz  
	;https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5530556
	;Friday, September 3, 2021 
	(
	/ *error* mappend mklist flatten take pointlist3d sset->enameList get_intersections get_intersection_points
	adoc ss enameList pt line_hor line_hor_obj line_ver line_ver_obj i j ph pv eo int_pts sel old_dim_assoc
	)
	
	(defun *error* ( msg )
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
		(if (and adoc) (vla-endundomark adoc))
		(setvar 'cmdecho 1)
		(setvar 'DIMASSOC old_dim_assoc)
		(princ)
	)
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))
	(defun pointlist3d (lst / ret) (while lst (setq	ret (cons (take 3 lst) ret) lst (cdddr lst))) (reverse ret))
	(defun mappend (fn lst)(apply 'append (mapcar fn lst)))
	(defun mklist (x) (if (listp x) x (list x)))
	(defun flatten (exp)(mappend 'mklist exp))
	(defun sset->enameList (ss / i ret)
		; extracts elements name for all objects in a selection set into a list
		(if ss
			(repeat (setq i (sslength ss))
				(setq ret (cons (ssname ss (setq i (1- i))) ret))
			) ;_ end of repeat
		) ;_ end of if
	) ;_ end of defun
	(defun get_intersections	(obj1 obj2 / var)
		(setq var (vlax-variant-value (vla-intersectwith obj1 obj2 1)))
		(if (< 0 (vlax-safearray-get-u-bound var 1))(vlax-safearray->list var))
	)
	(defun get_intersection_points (obj1 obj2) (pointlist3d (get_intersections obj1 obj2)))
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))) 
	(setq ss (ssget '((0 . "LWPOLYLINE,LINE,CIRCLE,ELLIPSE"))))
	(setq enameList (sset->enameList ss))
	(initget 1 "H V B")
	(setq sel (getkword "\nDraw Horizontal, Vertical or Both dimensions <H V B> ?"))
	(cond 
		((= sel "H")
			(setq pt (getpoint "\nPick a point for horizontal dimensions position >"))
		)
		((= sel "V")
			(setq pt (getpoint "\nPick a point for vertical dimensions position >"))
		)
		((= sel "B")
			(setq ph (getpoint "\nPick a point for horizontal dimensions position >"))
			(setq pv (getpoint "\nPick a point for vertical dimensions position >"))
			(setq pt (list (car pv) (cadr ph)))
		)	
	)
	(setq old_dim_assoc (getvar 'DIMASSOC))
	(setvar 'DIMASSOC 1)
	(setvar 'cmdecho 0)
	(cond 
		((and pt)
			(vla-endundomark adoc)
			(vla-startundomark adoc)
			(setq line_ver
				(entmakex
					(list
						(cons 0 "XLINE")
						(cons 100 "AcDbEntity")
						(cons 100 "AcDbXline")
						(cons 10 (trans pt 1 0))
						(cons 11 '(0 1 0))
					)
				)
			)
			(setq line_ver_obj (vlax-ename->vla-object line_ver))
			(setq line_hor
				(entmakex
					(list
						(cons 0 "XLINE")
						(cons 100 "AcDbEntity")
						(cons 100 "AcDbXline")
						(cons 10 (trans pt 1 0))
						(cons 11 '(1 0 0))
					)
				)
			)
			(cond 
				((or (= sel "H")(= sel "B"))
					(setq line_hor_obj (vlax-ename->vla-object line_hor))
					(setq i -1)
					(while (< (setq i (1+ i)) (length enameList))
						(setq eo (vlax-ename->vla-object (nth i enameList)))
						(setq ipts (get_intersection_points line_hor_obj eo))
						
						(if (and ipts) (setq int_pts (cons ipts int_pts)))
					)
					(cond 
						((and int_pts)
							(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (car x)(car y)))))
							(setq j -1)
							(while (< (setq j (1+ j)) (1- (length int_pts)))
								(command "_.dimhorizontal" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
							)
						)
					)
					(setq int_pts nil)
				)
			)
			(cond 
				((or (= sel "V")(= sel "B"))
					(setq i -1)
					(while (< (setq i (1+ i)) (length enameList))
						(setq eo (vlax-ename->vla-object (nth i enameList)))
						(setq ipts (get_intersection_points line_ver_obj eo))
						(if (and ipts) (setq int_pts (cons ipts int_pts)))				
					)
					
					(cond 
						((and int_pts)
							(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (cadr x)(cadr y)))))
							(setq j -1)
							(while (< (setq j (1+ j)) (1- (length int_pts)))
								(command "_.dimvertical" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
							)
						)
					)
					(setq int_pts nil)
				)
			)
			(if (and eo)(vlax-release-object eo))
			(if (and line_hor_obj)(vlax-release-object line_hor_obj))
			(if (and line_ver_obj)(vlax-release-object line_ver_obj))	
			(entdel line_hor)
			(entdel line_ver)
			(vla-endundomark adoc)
		)
	)
	(setvar 'cmdecho 1)
	(setvar 'DIMASSOC old_dim_assoc)
(princ "\nDone!")
(princ)
)

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 24 of 61
larsr2866
in reply to: hak_vz

Okay, thanks for the update! 🙂 

Message 25 of 61
larsr2866
in reply to: hak_vz

This lisp is such a huge help for me! I have been using it for a couple days now 🙂

Also the choice between h, v, b works great!

 

I was just wondering if it could be possible to stay in the same command after selecting the objects and choosing the appropriate direction? So for example i can first put all the  horizontal dimensions (on the different positions), without selecting the same objects and choose horizontally every time?

 

Thanks in advance!

Message 26 of 61
hak_vz
in reply to: larsr2866

@larsr2866  I'll work on it in next few days. I hope it's possible since algorithm is complex.

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 27 of 61
hak_vz
in reply to: larsr2866


@larsr2866 wrote:

I was just wondering if it could be possible to stay in the same command after selecting the objects and choosing the appropriate direction? So for example I can first put all the  horizontal dimensions (on the different positions), without selecting the same objects and choose horizontally every time?


Here you have modified code that works this way.

(defun c:dimhorver_all 
	;author hak_vz  
	;https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5530556
	;Tuesday, September 7, 2021 
	(
	/ *error* mappend mklist flatten take pointlist3d sset->enameList get_intersections get_intersection_points
	adoc ss enameList pt line_hor line_hor_obj line_ver line_ver_obj i j k ph pv eo int_pts sel old_dim_assoc
	)
	
	(defun *error* ( msg )
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
		(if (and adoc) (vla-endundomark adoc))
		(setvar 'cmdecho 1)
		(setvar 'DIMASSOC old_dim_assoc)
		(princ)
	)
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))
	(defun pointlist3d (lst / ret) (while lst (setq	ret (cons (take 3 lst) ret) lst (cdddr lst))) (reverse ret))
	(defun mappend (fn lst)(apply 'append (mapcar fn lst)))
	(defun mklist (x) (if (listp x) x (list x)))
	(defun flatten (exp)(mappend 'mklist exp))
	(defun sset->enameList (ss / i ret)
		; extracts elements name for all objects in a selection set into a list
		(if ss
			(repeat (setq i (sslength ss))
				(setq ret (cons (ssname ss (setq i (1- i))) ret))
			) ;_ end of repeat
		) ;_ end of if
	) ;_ end of defun
	(defun get_intersections	(obj1 obj2 / var)
		(setq var (vlax-variant-value (vla-intersectwith obj1 obj2 1)))
		(if (< 0 (vlax-safearray-get-u-bound var 1))(vlax-safearray->list var))
	)
	(defun get_intersection_points (obj1 obj2) (pointlist3d (get_intersections obj1 obj2)))
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))) 
	(setq ss (ssget '((0 . "LWPOLYLINE,LINE,CIRCLE,ELLIPSE"))))
	(setq enameList (sset->enameList ss))
	(initget 1 "H V B")
	(setq sel (getkword "\nDraw Horizontal, Vertical or Both dimensions <H V B> ?"))
	(setq old_dim_assoc (getvar 'DIMASSOC))
	(setvar 'DIMASSOC 1)
	(setvar 'cmdecho 0)
	(setq k 1)
	(while 
			(and 
				(cond 
					((= sel "H")
						(setq pt (getpoint (strcat "\nPick " (itoa k)". point for horizontal dimensions position >")))
					)
					((= sel "V")
						(setq pt (getpoint (strcat "\nPick " (itoa k)". point for vertical dimensions position >")))
					)
					((= sel "B")
						(setq ph (getpoint (strcat "\nPick " (itoa k)". point for horizontal dimensions position >")))
						(setq pv (getpoint (strcat "\nPick " (itoa k)". point for vertical dimensions position >")))
						(setq pt (list (car pv) (cadr ph)))
					)	
				)
			)
				(vla-endundomark adoc)
				(vla-startundomark adoc)
				(setq line_ver
					(entmakex
						(list
							(cons 0 "XLINE")
							(cons 100 "AcDbEntity")
							(cons 100 "AcDbXline")
							(cons 10 (trans pt 1 0))
							(cons 11 '(0 1 0))
						)
					)
				)
				(setq line_ver_obj (vlax-ename->vla-object line_ver))
				(setq line_hor
					(entmakex
						(list
							(cons 0 "XLINE")
							(cons 100 "AcDbEntity")
							(cons 100 "AcDbXline")
							(cons 10 (trans pt 1 0))
							(cons 11 '(1 0 0))
						)
					)
				)
				(cond 
					((or (= sel "H")(= sel "B"))
						(setq line_hor_obj (vlax-ename->vla-object line_hor))
						(setq i -1)
						(while (< (setq i (1+ i)) (length enameList))
							(setq eo (vlax-ename->vla-object (nth i enameList)))
							(setq ipts (get_intersection_points line_hor_obj eo))
							
							(if (and ipts) (setq int_pts (cons ipts int_pts)))
						)
						(cond 
							((and int_pts)
								(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (car x)(car y)))))
								(setq j -1)
								(while (< (setq j (1+ j)) (1- (length int_pts)))
									(command "_.dimhorizontal" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
								)
							)
						)
						(setq int_pts nil)
					)
				)
				(cond 
					((or (= sel "V")(= sel "B"))
						(setq i -1)
						(while (< (setq i (1+ i)) (length enameList))
							(setq eo (vlax-ename->vla-object (nth i enameList)))
							(setq ipts (get_intersection_points line_ver_obj eo))
							(if (and ipts) (setq int_pts (cons ipts int_pts)))				
						)
						
						(cond 
							((and int_pts)
								(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (cadr x)(cadr y)))))
								(setq j -1)
								(while (< (setq j (1+ j)) (1- (length int_pts)))
									(command "_.dimvertical" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
								)
							)
						)
						(setq int_pts nil)
					)
				)
				(if (and eo)(vlax-release-object eo))
				(if (and line_hor_obj)(vlax-release-object line_hor_obj))
				(if (and line_ver_obj)(vlax-release-object line_ver_obj))	
				(entdel line_hor)
				(entdel line_ver)
				(vla-endundomark adoc)
				(setq k (1+ k))
		
	)
	(setvar 'cmdecho 1)
	(setvar 'DIMASSOC old_dim_assoc)
(princ "\nDone!")
(princ)
)

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 28 of 61
larsr2866
in reply to: hak_vz

Amazing! That's it! Thank you so much!

If you lived in Belgium, i would buy you many, many beers, because this is really helpfull! 🙂

Message 29 of 61
hak_vz
in reply to: larsr2866

Changing this code was not so complex as I thought and now it really works as it should and is most user friendly.

 

Unfortunately I'm not living in Belgium, but I like her beers. Luckily for me some of them are available in Croatian markets and pubs. Which one of these would you recommend? When we organize barbecues sometime we treat ourselves with crate of good beer.

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 61
larsr2866
in reply to: hak_vz

Definitely the Orval, la Chouffe and the Duvel! Great beers for a BBQ!  🙂 

Message 31 of 61
Anonymous
in reply to: larsr2866

When it's randomly scattered like that, ordinate dimensions can make it less of a mess... Also would be easier to implement. Also, the "sample figure" on the right hand side would be consideredInot-great drafting practice from what I was taught, as the dimensions should be drawn outside of the part outline, which here we'll imply as some invisible shape that can go around all the points 

Message 32 of 61
larsr2866
in reply to: hak_vz

Hello hak_vz,

 

I have 2 questions about this great lisp you helped me with.

 

- For the moment it works with horizontal and vertical, but would it be difficult to also make this work for an oblique one?

- Next question is that if it could be possible to omit all dimensions less than 0.5mm?

 

Hopefully you can help me?

 

Thanks in advance!

Grtz

Message 33 of 61
hak_vz
in reply to: larsr2866

Hi @larsr2866 

 

It is probably possible. I will try to update code during the weekend.

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 34 of 61
hak_vz
in reply to: larsr2866


@larsr2866 wrote:

Hello hak_vz,

 

- Next question is that if it could be possible to omit all dimensions less than 0.5mm?

Grtz


For oblique dimensions look through older posts.

I have updated code so now you can enter min distance to omit creation of dimension object.

 

 

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 35 of 61
larsr2866
in reply to: hak_vz

Sorry for the late reaction!

Thank you very much!

 

I have just been trying to make adjustments in this code for always omit the dimensions less than 0.5mm (without entering the min distance), but it doesn't work.

 

could you help me with this?

 

Thanks!

Message 36 of 61
hak_vz
in reply to: larsr2866


@larsr2866 wrote:

Sorry for the late reaction!

Thank you very much!

 

I have just been trying to make adjustments in this code for always omit the dimensions less than 0.5mm (without entering the min distance), but it doesn't work.

 

could you help me with this?

 

Thanks!


(defun c:dimhorver_limit
	;author hak_vz  
	;https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5530556
	;Tuesday, September 7, 2021 
	(
	/ *error* mappend mklist flatten take pointlist3d sset->enameList get_intersections get_intersection_points
	adoc ss enameList pt line_hor line_hor_obj line_ver line_ver_obj i j k ph pv eo int_pts sel old_dim_assoc
	do_ommit ommit
	)
	
	(defun *error* ( msg )
		(if (not (member msg '("Function cancelled" "quit / exit abort")))
			(princ)
		)
		(if (and adoc) (vla-endundomark adoc))
		(setvar 'cmdecho 1)
		(setvar 'DIMASSOC old_dim_assoc)
		(princ)
	)
	(defun take (amount lst / ret)(repeat amount (setq ret (cons (car lst) (take (1- amount) (cdr lst))))))
	(defun pointlist3d (lst / ret) (while lst (setq	ret (cons (take 3 lst) ret) lst (cdddr lst))) (reverse ret))
	(defun mappend (fn lst)(apply 'append (mapcar fn lst)))
	(defun mklist (x) (if (listp x) x (list x)))
	(defun flatten (exp)(mappend 'mklist exp))
	(defun sset->enameList (ss / i ret)
		; extracts elements name for all objects in a selection set into a list
		(if ss
			(repeat (setq i (sslength ss))
				(setq ret (cons (ssname ss (setq i (1- i))) ret))
			) ;_ end of repeat
		) ;_ end of if
	) ;_ end of defun
	(defun get_intersections	(obj1 obj2 / var)
		(setq var (vlax-variant-value (vla-intersectwith obj1 obj2 1)))
		(if (< 0 (vlax-safearray-get-u-bound var 1))(vlax-safearray->list var))
	)
	(defun get_intersection_points (obj1 obj2) (pointlist3d (get_intersections obj1 obj2)))
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))) 
	(setq ss (ssget '((0 . "LWPOLYLINE,LINE,CIRCLE,ELLIPSE"))))
	(setq enameList (sset->enameList ss))
	(initget 1 "H V B")
	(setq sel (getkword "\nDraw Horizontal, Vertical or Both dimensions <H V B> ?"))
	(setq ommit 0.5)
	(setq old_dim_assoc (getvar 'DIMASSOC))
	(setvar 'DIMASSOC 1)
	(setvar 'cmdecho 0)
	(setq k 1)
	(while 
			(and 
				(cond 
					((= sel "H")
						(setq pt (getpoint (strcat "\nPick " (itoa k)". point for horizontal dimensions position >")))
					)
					((= sel "V")
						(setq pt (getpoint (strcat "\nPick " (itoa k)". point for vertical dimensions position >")))
					)
					((= sel "B")
						(setq ph (getpoint (strcat "\nPick " (itoa k)". point for horizontal dimensions position >")))
						(setq pv (getpoint (strcat "\nPick " (itoa k)". point for vertical dimensions position >")))
						(setq pt (list (car pv) (cadr ph)))
					)	
				)
			)
				(vla-endundomark adoc)
				(vla-startundomark adoc)
				(setq line_ver
					(entmakex
						(list
							(cons 0 "XLINE")
							(cons 100 "AcDbEntity")
							(cons 100 "AcDbXline")
							(cons 10 (trans pt 1 0))
							(cons 11 '(0 1 0))
						)
					)
				)
				(setq line_ver_obj (vlax-ename->vla-object line_ver))
				(setq line_hor
					(entmakex
						(list
							(cons 0 "XLINE")
							(cons 100 "AcDbEntity")
							(cons 100 "AcDbXline")
							(cons 10 (trans pt 1 0))
							(cons 11 '(1 0 0))
						)
					)
				)
				(cond 
					((or (= sel "H")(= sel "B"))
						(setq line_hor_obj (vlax-ename->vla-object line_hor))
						(setq i -1)
						(while (< (setq i (1+ i)) (length enameList))
							(setq eo (vlax-ename->vla-object (nth i enameList)))
							(setq ipts (get_intersection_points line_hor_obj eo))
							
							(if (and ipts) (setq int_pts (cons ipts int_pts)))
						)
						(cond 
							((and int_pts)
								(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (car x)(car y)))))
								(setq j -1)
								(while (< (setq j (1+ j)) (1- (length int_pts)))
									(command "_.dimhorizontal" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
									(setq do (vlax-ename->vla-object (entlast)))
									(if (<= (vlax-get do 'Measurement ) ommit) (entdel (entlast)))
								)
								
							)
						)
						(setq int_pts nil)
					)
				)
				(cond 
					((or (= sel "V")(= sel "B"))
						(setq i -1)
						(while (< (setq i (1+ i)) (length enameList))
							(setq eo (vlax-ename->vla-object (nth i enameList)))
							(setq ipts (get_intersection_points line_ver_obj eo))
							(if (and ipts) (setq int_pts (cons ipts int_pts)))				
						)
						
						(cond 
							((and int_pts)
								(setq int_pts (vl-sort (flatten int_pts) '(lambda (x y) (< (cadr x)(cadr y)))))
								(setq j -1)
								(while (< (setq j (1+ j)) (1- (length int_pts)))
									(command "_.dimvertical" (nth j int_pts)(nth (1+ j) int_pts)(nth (1+ j) int_pts))
									(setq do (vlax-ename->vla-object (entlast)))
									(if (<= (vlax-get do 'Measurement ) ommit) (entdel (entlast)))
								)
							)
						)
						(setq int_pts nil)
					)
				)
				(if (and eo)(vlax-release-object eo))
				(if (and line_hor_obj)(vlax-release-object line_hor_obj))
				(if (and line_ver_obj)(vlax-release-object line_ver_obj))	
				(entdel line_hor)
				(entdel line_ver)
				(vla-endundomark adoc)
				(setq k (1+ k))
		
	)
	(setvar 'cmdecho 1)
	(setvar 'DIMASSOC old_dim_assoc)
(princ "\nDone!")
(princ)
)

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 37 of 61
larsr2866
in reply to: hak_vz

Super! Thanks again! 🙂

Message 38 of 61
sajansainju73
in reply to: hak_vz

Thanks for the code. I'd be grateful if you can adjust the code so that it can give aligned dimension also.

Message 39 of 61
hak_vz
in reply to: larsr2866

@sajansainju73 You can search through older posts in this forum or google for it. There are many solutions provided. I know for at least two or three but have no time too look for it. I guess @Kent1Cooper and @marko_ribar have provided some code for it. Reality is that each particular problem is specific. To create a code that

works perfectly for everyone is not possible. 

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 40 of 61
devitg
in reply to: sajansainju73

@sajansainju73 Please upload your sample dwg , how do you need the aligned dim to be 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


AutoCAD Beta