Tangent Line From an Arc

Here’s a great LISP that should be incorporated with AutoCAD. After drawing an arc, we should be able to easily draw a line that is tangent from the arc. Well… until then here;s how…

(Written by Alan JT found @ the swamp.org)

~enjoy

(defun c:TLA (/ *error* ent arc)

;; draw Tangent Line from selected Arc's endpoint

;; Required subroutines: AT:GetSel

;; Alan J. Thompson, 12.14.10

(vl-load-com)

(defun *error* (msg)

(and (eq 4 (length ent)) arc (entdel (car arc)))

(if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,")))

(princ (strcat "\nError: " msg))

)

)

(if (setq ent (AT:GetSel nentselp

"\nSelect arc from which to draw tangent line: "

(lambda (x) (eq "ARC" (cdr (assoc 0 (entget (car x))))))

)

)

(progn

(if (eq 4 (length ent))

(vla-transformby

(vlax-ename->vla-object (car (setq arc (list (entmakex (entget (car ent))) (cadr ent)))))

(vlax-tmatrix (caddr ent))

)

(setq arc ent)

)

((lambda (points _dist _angle _angtos / ang pnt)

(if (< (_dist (cadr arc) (car points)) (_dist (cadr arc) (cadr points)))

(setq ang (_angtos (+ (/ pi 2.) (_angle (cdr (assoc 50 (entget (car arc)))))))

pnt (car points)

)

(setq ang (_angtos (+ (/ pi 2.) (_angle (cdr (assoc 51 (entget (car arc)))))))

pnt (cadr points)

)

)

(vl-cmdf "_.line" "_non" pnt (strcat "<" ang) PAUSE)

)

(mapcar (function (lambda (p) (trans p 0 1)))

(list (vlax-curve-getStartPoint (car arc)) (vlax-curve-getEndPoint (car arc)))

)

(lambda (a b) (distance (list (car a) (cadr a)) (list (car b) (cadr b))))

(lambda (a)

(if (zerop (getvar 'WORLDUCS))

(- a (angle '(0. 0. 0.) (trans (getvar 'UCSXDIR) 0 (trans '(0. 0. 1.) 1 0 T) T)))

a

)

)

(lambda (a) (angtos a (getvar 'aunits) 16))

)

)

)

(*error* nil)

(princ)

)

(defun AT:GetSel (meth msg fnc / ent good)

;; meth - selection method (entsel, nentsel, nentselp)

;; msg - message to display (nil for default)

;; fnc - optional function to apply to selected object

;; Ex: (AT:GetSel entsel "\nSelect arc: " (lambda (x) (eq (cdr (assoc 0 (entget (car x)))) "ARC")))

;; Alan J. Thompson, 05.25.10

(setvar 'errno 0)

(while (not good)

(setq ent (meth (cond (msg)

("\nSelect object: ")

)

)

)

(cond

((vl-consp ent)

(setq good (cond ((or (not fnc) (fnc ent)) ent)

((prompt "\nInvalid object!"))

)

)

)

((eq (type ent) 'STR) (setq good ent))

((setq good (eq 52 (getvar 'errno))) nil)

((eq 7 (getvar 'errno)) (setq good (prompt "\nMissed, try again.")))

)

)

)
Posted in AutoLISP, TIPS | Leave a comment

AutoLISP: Join MTEXT

I recently found this little routine and I am sure going to be using it. Heck, I could have used it for a while now.

It is simple. It joins MTEXT objects into a single MTEXT object.

Here’s how:

  • JMTX <enter> to start
  • Select the MTEXT objects to be joined. (Note: the order in which you select the MTEXT objects will determine the order the final MTEXT object.)
  • <enter> to finish
;; by Joe Burke at Autodesk Forums

;; Join mtext demo.

;; The order of selection determines the result.

;; The first mtext object selected is modified and

;; others are deleted.

(defun c:jmtx ( / e obj lst str)

(vl-load-com)

(while

(and

(setq e (car (entsel "\nSelect mtext: ")))

(setq obj (vlax-ename->vla-object e))

(equal "AcDbMText" (vlax-get obj 'ObjectName))

)

(setq lst (cons obj lst))

)

(setq obj (last lst))

(setq str (vlax-get obj 'TextString))

(foreach x (cdr (reverse lst))

(setq str (strcat str "\\P" (vlax-get x 'TextString)))

(vla-delete x)

)

(vlax-put obj 'TextString str)

(princ)

)


Posted in AutoLISP, Modifying, Text | 4 Comments

Change the 2012 Dynamic Input Display

With AutoCAD 2010 & 2011, the default setting when you had “Dynamic Input”enabled was awesome. When you select an object and then hover over a grip, it would show you the length, radius & angle. This feature saves me time from having to either pull a dimension or using the DISTANCE or LIST command. In AutoCAD 2012 however, this feature was disabled and I was not a happy camper. But my frustration and curiosity has payed off.

Here’s how to fix 2012:

  • Right-Click over DYN and Select “Settings”

  • Click the “Dynamic Input” tab & then check the check-box next to “Enable Dimension Input where available.” this is all you need to turn back on the dimensions & angles.
  • You can also change additional settings for Dynamic Input by clicking the “Settings” button.

Now when you select an object, you will see a great feature of Dynamic Input!!!!

Posted in BASICS, Customization, Dimensions, New in 2012, TIPS | 12 Comments

LENGTHEN lines at an angle

If you need to lengthen a line, especially if the line is at an angle other than horizontal or vertical, this command is for you. It will lengthen a line and keep it in the angles that it originally was. Usually, if you select a line that is at an angle and then click a grip to  lengthen it, you will not be able to keep the angle. (Note: in AutoCAD 2012 select a line and then hover over and endpoint grip and you will see the option for LENGTHEN.)

  • LENGTHEN <enter> or LEN <enter>

or on the ribbon:

  • Home Tab > Modify Panel > Lengthen button (in the drop-down) as seen below.
  • After starting the Lengthen command, notice that there are options in the command line.
  • DY <enter> to star the “dynamic” function of the lengthen command.
  • select the side of the line that you would like to lengthen or shorten.
  • after selecting the line, move your cursor in the desired direction and either click to end the “lengthening” or enter a number.
In the animated example, I lengthened and shortened the lines by six inches
Posted in Modifying, TIPS | 3 Comments

AutoLISP: Dynamic Star

This may sound simple, but if you needed to make a star, how would you do it?

Here’s an easy way.

DSTAR <enter> to start

Specify the number of points for the start

Specify the center (similar to a circle or polygon)

Specify the radius by typing in the radius or click with the mouse. Note: will not allow for OSNAPs on this click. This is because it uses the “grread” function.

~enjoy

;;; DSTAR (gile) 2009/03/09

;;; Draws a star polygon

;;; The user specify the number of brunches, the star center and a point vertex location.

(defun c:dstar (/ *error* makestar br imax ind cen loop gr star str pt)

;;;======================== LOCAL SUB ========================;;;

;; Local *error*

(defun *error* (msg)

(or (= msg "Function cancelled")

(princ (strcat "Error: " msg))

)

(and star (entdel star) (setq star nil))

(grtext)

(princ)

)

;; Creates the pline

(defun makestar (cen ang dist br ind / n zdir lst1 lst2)

(setq n (* 2 br)

zdir (trans '(0 0 1) 1 0 T)

)

(and (= (getvar "ORTHOMODE") 1) (setq ang (OrthoRound ang)))

(repeat br

(setq

lst1

(cons

(polar cen (+ ang (/ (* (setq n (- n 2)) pi) br)) dist)

lst1

)

)

)

(repeat br

(setq lst2

(cons (inters (nth n lst1)

(nth (rem (+ n br (- ind)) br) lst1)

(nth (rem (+ n (1- ind)) br) lst1)

(nth (setq n (rem (+ n (1- br)) br)) lst1)

)

lst2

)

)

)

(entmakex

(append

(list '(0 . "LWPOLYLINE")

'(100 . "AcDbEntity")

'(100 . "AcDbPolyline")

(cons 90 (* 2 br))

'(70 . 1)

(cons 38 (caddr (trans cen 1 zdir)))

(cons 210 zdir)

)

(mapcar

(function

(lambda (pt)

(cons 10 (trans pt 1 zdir))

)

)

(apply 'append

(apply 'mapcar (cons 'list (list lst1 lst2)))

)

)

)

)

)

;;;======================== MAIN ========================;;;

(or *StarPointNumber* (setq *StarPointNumber* 5))

(if (setq br (getint (strcat "\nSpecify the number of points: <"

(itoa *StarPointNumber*)

">: "

)

)

)

(setq *StarPointNumber* br)

(setq br *StarPointNumber*)

)

(if (< 4 br)

(progn

(setq imax (fix (/ (- br 0.5) 2))

ind imax

)

(initget 1)

(setq cen (getpoint "\nSpecify the star center: ")

loop T

)

(princ "\nSpecify a point vertex (or enter circle radius): ")

;; grread loop

(while (and (setq gr (grread T 12 0)) loop)

(and star (entdel star) (setq star nil))

(cond

;; Dragging

((= 5 (car gr))

(setq ang (angle cen (cadr gr))

dist (distance cen (cadr gr))

)

(if (/= 0 dist)

(setq star (makestar cen ang dist br ind))

)

(grtext -1 (strcat "Radius: " (rtos dist)))

)

;; Picked point = ends loop

((= 3 (car gr))

(makestar cen ang dist br ind)

(setq loop nil)

(grtext)

)

;; Right click = loops through available densities

((member (car gr) '(11 25))

(setq ind (+ 2 (rem (- (1+ ind) 2) (1- imax))))

)

;; Enter = reads the command line input

((equal gr '(2 13))

(cond

;; valid distance = ends loop

((and str (setq dist (distof str)) (< 0 dist))

(makestar cen ang dist br ind)

(setq loop nil)

(grtext)

)

;; valid point = ends loop

((and str (setq pt (str->pt str)))

(makestar cen (angle cen pt) (distance cen pt) br ind)

(setq loop nil)

(grtext)

)

;; invalid input

(T

(setq str nil)

(princ "\nInvalid point or distance. Specify a point vertex (or enter circle radius): ")

)

)

)

;; F8 = toggles orthomode

((equal gr '(2 15))

(setvar "ORTHOMODE" (boole 6 1 (getvar "ORTHOMODE")))

(princ (chr 8))

(princ (chr 32))

)

;; getting and printing command line input

(T

(if (= (cadr gr) 8) ;_ backspace

(or

(and str

(/= str "")

(setq str (substr str 1 (1- (strlen str))))

(princ (chr 8))

(princ (chr 32))

)

(setq str nil)

)

(or

(and str (setq str (strcat str (chr (cadr gr)))))

(setq str (chr (cadr gr)))

)

)

(and str (princ (chr (cadr gr))))

)

)

)

)

(prompt "\nThe number of points have to be greater than 4.")

)

(princ)

)

;;;======================== SUB ROUTINES ========================;;;

;; OrthoRound

;; Returns the angle rounded to pi/2

;;

;; Argument: an angle (radians)

(defun OrthoRound (ang)

(* (/ pi 2) (fix (/ (+ (/ pi 4) ang) (/ pi 2))))

)

;; STR2PT

;; Convert a string into a 3d point (input with grread)

;;

;; Argument: a string (ex: "25,63")

;; Return: a 3d point (ex (25.0 63.0 0.0) or nil if invalid string

(defun str2pt (str)

(setq str (mapcar 'read (str2lst str ",")))

(if (and (vl-every 'numberp str)

(< 1 (length str) 4)

)

(trans str 0 0)

)

)

;; STR2LST

;; Transforms a string with separator into a list of strings

;;

;; Arguments

;; str = the string

;; sep = the separator pattern

(defun str2lst (str sep / pos)

(if (setq pos (vl-string-search sep str))

(cons (substr str 1 pos)

(str2lst (substr str (+ (strlen sep) pos 1)) sep)

)

(list str)

)

)
Posted in AutoLISP, TIPS | Leave a comment

LISP: Unique Polyline Arrow

Here is a great routine to create unique arrows polyline arrows.

  • DPA <enter> to start
  • (Can specify if you want one arrow or an arrow on both ends)
  • Specify the width (I chose 5 for this example)
  • Pick the desired points Can also use ORTHO.
  • Right-click to end
~enjoy
(defun c:DPA (/ DrawEndArrowHead DrawStartArrowHead ActDoc CurSpc Dist ArSty Pt PtList StList Ang EndList
PtList+ PtList- oPt nPt tempPt oAng oAng+ oAng- oPt+ oPt- nPt+ nPt- cAng cAng+ cAng-
tempPt+ tempPt- ntemp+ ntemp- Pt+ Pt- PolyPtList *error* AlignX AlignY AlignZ DistX DistY DistZ)
(vl-load-com)
; Draw a polyline arrow, now shown as you move the cursor
(defun *error* (msg)
;(vl-bt)
(redraw)
(prompt (strcat "\n Error-> " msg))
)
;---------------------------------------------------------------------------------------------------------
(defun GetCurrentSpace (Doc / BlkCol SpaceList CurSpace ActSpace temp1)
; Returns the "block object" for the active space
; Thanks to Jeff Mishler
(if (= (getvar "cvport") 1)
(vla-get-PaperSpace Doc)
(vla-get-ModelSpace Doc)
)
)
;---------------------------------------------------------------------------------------------------------
(defun AlignX (pt1 pt2)
(list
(car pt1)
(cadr pt2)
(caddr pt2)
)
)
;---------------------------------------------------------------------------------------------------------
(defun AlignY (pt1 pt2)
(list
(car pt2)
(cadr pt1)
(caddr pt2)
)
)
;---------------------------------------------------------------------------------------------------------
(defun AlignZ (pt1 pt2)
(list
(car pt2)
(cadr pt2)
(caddr pt1)
)
)
;---------------------------------------------------------------------------------------------------------
(defun DrawEndArrowHead (Stpt CurPt ArrHeadDist ReturnPoints / Ang -Ang tempPt Ang+ Ang- Pt+ Pt-)
(setq Ang (angle StPt CurPt))
(setq -Ang (rem (+ Ang pi) (* pi 2.0)))
(setq tempPt (polar CurPt -Ang (* ArrHeadDist 2.0)))
(setq Ang+ (rem (+ Ang (* pi 0.5)) (* pi 2.0)))
(setq Ang- (rem (+ Ang (* pi 1.5)) (* pi 2.0)))
(setq Pt+ (polar tempPt Ang+ (* ArrHeadDist 0.5)))
(setq Pt- (polar tempPt Ang- (* ArrHeadDist 0.5)))
(grvecs
(list
1 Pt+ (polar Pt+ Ang+ (* ArrHeadDist 0.5))
1 (polar Pt+ Ang+ (* ArrHeadDist 0.5)) CurPt
1 CurPt (polar Pt- Ang- (* ArrHeadDist 0.5))
1 (polar Pt- Ang- (* ArrHeadDist 0.5)) Pt-
)
)
(if ReturnPoints
(list
(polar Pt+ Ang+ (* ArrHeadDist 0.5))
CurPt
(polar Pt- Ang- (* ArrHeadDist 0.5))
)
(list Pt+ Pt-)
)
)
;-------------------------------------------------------------------------------------------------------------------
(defun DrawStartArrowHead (StPt CurPt ArrHeadDist ReturnPoints / Ang -Ang tempPt Ang+ Ang- Pt+ Pt- Pt+2 Pt-2)
(setq Ang (angle CurPt StPt))
(setq -Ang (rem (+ Ang pi) (* pi 2.0)))
(setq tempPt (polar StPt -Ang (* ArrHeadDist 2.0)))
(setq Ang+ (rem (+ Ang (* pi 0.5)) (* pi 2.0)))
(setq Ang- (rem (+ Ang (* pi 1.5)) (* pi 2.0)))
(setq Pt+ (polar tempPt Ang+ (* ArrHeadDist 0.5)))
(setq Pt- (polar tempPt Ang- (* ArrHeadDist 0.5)))
(grvecs
(list
1 Pt+ (polar Pt+ Ang+ (* ArrHeadDist 0.5))
1 (polar Pt+ Ang+ (* ArrHeadDist 0.5)) StPt
1 StPt (polar Pt- Ang- (* ArrHeadDist 0.5))
1 (polar Pt- Ang- (* ArrHeadDist 0.5)) Pt-
)
)
(if ReturnPoints
(list
(polar Pt+ Ang+ (* ArrHeadDist 0.5))
StPt
(polar Pt- Ang- (* ArrHeadDist 0.5))
)
(list Pt- Pt+)
)
)
,-------------------------------------------------------------------------------------------------------------------
(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vla-EndUndoMark ActDoc)
(vla-StartUndoMark ActDoc)
(setq CurSpc (GetCurrentSpace ActDoc))
(initget "Single Double")
(setq Dist (getdist "\n Enter width [<Single>/Double arrow head]: "))
(if (= (type Dist) 'STR)
(progn
(setq ArSty Dist)
(setq Dist (getdist "\n Enter width: "))
)
(setq ArSty "Single")
)
(setq Pt (getpoint "\n Select starting point: "))
(setq PtList (list Pt))
(while
(and
PtList
Pt
ArSty
Dist
(not (prompt "\r Select next point [right click to exit / Undo]: "))
(not (vl-position (car (setq tempList (grread T 0))) '(11 25)))
)
(cond
((equal (car tempList) 2)
(cond
((equal (cadr tempList) 15)
(setvar "orthomode" (abs (1- (getvar "orthomode"))))
)
((and (> (length PtList) 1) (vl-position (cadr tempList) '(85 117)))
(setq PtList (cdr PtList))
(setq PtList+ (cdr PtList+))
(setq PtList- (cdr PtList-))
(redraw)
(if (= ArSty "Double")
(DrawStartArrowHead (last PtList) (nth (- (length PtList) 2) PtList) Dist nil)
(grdraw (car StList) (cadr StList) 1)
)
(setq EndList (DrawEndArrowHead (car PtList) (polar tempPt cAng (* Dist 2.0)) Dist nil))
(setq cnt 0)
(while (< (1+ cnt) (length PtList+))
(grdraw (nth cnt PtList+) (nth (1+ cnt) PtList+) 1)
(grdraw (nth cnt PtList-) (nth (1+ cnt) PtList-) 1)
(setq cnt (1+ cnt))
)
)
(t (print tempList))
)
)
((and (equal (length PtList) 1) (or (equal (car tempList) 5) (equal (car tempList) 3)))
(setq tempPt (cadr tempList))
(setq DistX (abs (- (car Pt) (car tempPt))))
(setq DistY (abs (- (cadr Pt) (cadr tempPt))))
(setq DistZ (abs (- (caddr Pt) (caddr tempPt))))
(if (equal (getvar "orthomode") 1)
(setq tempPt
(cond
((and (> DistX DistY) (> DistX DistZ))
(AlignY Pt tempPt)
)
((and (> DistY DistZ) (> DistY DistX))
(AlignX Pt tempPt)
)
((and (> DistZ DistX) (> DistZ DistY))
(AlignZ Pt tempPt)
)
)
)
)
(if (and tempPt (not (equal Pt tempPt 0.0001)))
(progn
(if (= ArSty "Double")
(setq StList (DrawStartArrowHead Pt tempPt Dist nil))
(progn
(setq Ang (angle Pt tempPt))
(setq StList
(list
(polar Pt (rem (+ Ang (* pi 0.5)) (* pi 2.0)) (* Dist 0.5))
(polar Pt (rem (+ Ang (* pi 1.5)) (* pi 2.0)) (* Dist 0.5))
)
)
)
)
(cond
((equal (car tempList) 5)
(redraw)
(if (= ArSty "Double")
(DrawStartArrowHead Pt tempPt Dist nil)
(grdraw (car StList) (cadr StList) 1)
)
(setq EndList (DrawEndArrowHead Pt tempPt Dist nil))
(grdraw (car StList) (car EndList) 1)
(grdraw (cadr StList) (cadr EndList) 1)
)
((equal (car tempList) 3)
(setq PtList+ (cons (car StList) PtList+))
(setq PtList- (cons (cadr StList) PtList-))
(setq PtList (cons tempPt PtList))
)
)
)
)
)
((and (> (length PtList) 1) (or (equal (car tempList) 5) (equal (car tempList) 3)))
(setq oPt (cadr PtList))
(setq nPt (car PtList))
(setq tempPt (cadr tempList))
(setq DistX (abs (- (car nPt) (car tempPt))))
(setq DistY (abs (- (cadr nPt) (cadr tempPt))))
(setq DistZ (abs (- (caddr nPt) (caddr tempPt))))
(if (equal (getvar "orthomode") 1)
(setq tempPt
(cond
((and (> DistX DistY) (> DistX DistZ))
(AlignY nPt tempPt)
)
((and (> DistY DistZ) (> DistY DistX))
(AlignX nPt tempPt)
)
((and (> DistZ DistX) (> DistZ DistY))
(AlignZ nPt tempPt)
)
)
)
)
(if (and tempPt (not (equal nPt tempPt 0.0001)))
(progn
(if (= ArSty "Double")
(setq StList (DrawStartArrowHead (last PtList) (nth (- (length PtList) 2) PtList) Dist nil))
(progn
(setq Ang (angle (last PtList) (nth (- (length PtList) 2) PtList)))
(setq StList
(list
(polar (last PtList) (rem (+ Ang (* pi 0.5)) (* pi 2.0)) (* Dist 0.5))
(polar (last PtList) (rem (+ Ang (* pi 1.5)) (* pi 2.0)) (* Dist 0.5))
)
)
)
)
(setq oAng (angle oPt nPt))
(setq oAng+ (rem (+ oAng (* pi 0.5)) (* pi 2.0)))
(setq oAng- (rem (+ oAng (* pi 1.5)) (* pi 2.0)))
(setq oPt+ (polar oPt oAng+ (* Dist 0.5)))
(setq oPt- (polar oPt oAng- (* Dist 0.5)))
(setq nPt+ (polar nPt oAng+ (* Dist 0.5)))
(setq nPt- (polar nPt oAng- (* Dist 0.5)))
(setq cAng (angle nPt tempPt))
(setq cAng+ (rem (+ cAng (* pi 0.5)) (* pi 2.0)))
(setq cAng- (rem (+ cAng (* pi 1.5)) (* pi 2.0)))
(if (equal (car tempList) 5)
(setq tempPt (polar tempPt (rem (+ cAng pi) (* pi 2.0)) (* Dist 2.0)))
)
(setq tempPt+ (polar tempPt cAng+ (* Dist 0.5)))
(setq tempPt- (polar tempPt cAng- (* Dist 0.5)))
(setq ntempPt+ (polar nPt cAng+ (* Dist 0.5)))
(setq ntempPt- (polar nPt cAng- (* Dist 0.5)))
(setq Pt+ (inters oPt+ nPt+ ntempPt+ tempPt+ nil))
(setq Pt- (inters oPt- nPt- ntempPt- tempPt- nil))
(if (and Pt+ Pt-)
(cond
((equal (car tempList) 5)
(redraw)
(if (= ArSty "Double")
(DrawStartArrowHead (last PtList) (nth (- (length PtList) 2) PtList) Dist nil)
(grdraw (car StList) (cadr StList) 1)
)
(setq EndList (DrawEndArrowHead (car PtList) (polar tempPt cAng (* Dist 2.0)) Dist nil))
(setq cnt 0)
(while (< (1+ cnt) (length PtList+))
(grdraw (nth cnt PtList+) (nth (1+ cnt) PtList+) 1)
(grdraw (nth cnt PtList-) (nth (1+ cnt) PtList-) 1)
(setq cnt (1+ cnt))
)
(grvecs
(list
1 (car PtList+) Pt+
1 Pt+ tempPt+
1 tempPt- Pt-
1 Pt- (car PtList-)
)
)
)
((equal (car tempList) 3)
(setq PtList+ (cons Pt+ PtList+))
(setq PtList- (cons Pt- PtList-))
(setq PtList (cons tempPt PtList))
)
)
)
)
)
)
)
)
(if (> (length PtList) 1)
(progn
(setq EndList (DrawEndArrowHead (cadr PtList) (car PtList) Dist nil))
(setq PtList+ (cons (car EndList) PtList+))
(setq PtList- (cons (cadr EndList) PtList-))
(setq EndPtList (DrawEndArrowHead (cadr PtList) (car PtList) Dist T))
(if (= ArSty "Double")
(progn
(setq StPtList (DrawStartArrowHead (last PtList) (nth (- (length PtList) 2) PtList) Dist T))
(setq tempPtList (append StPtList (append (reverse PtList+) (append EndPtList PtList-))))
)
(setq tempPtList (append (reverse PtList+) (append EndPtList PtList-)))
)
(foreach Pt (mapcar '(lambda (x) (trans x 1 0)) tempPtList)
(setq PolyPtList (cons (car Pt) PolyPtList))
(setq PolyPtList (cons (cadr Pt) PolyPtList))
)
(vla-put-Closed (vlax-invoke CurSpc 'AddLightWeightPolyline (reverse PolyPtList)) :vlax-true)
)
)
(redraw)
(vla-EndUndoMark ActDoc)
(princ)
)
Posted in AutoLISP, Leaders, TIPS | 11 Comments

AutoLISP: Copy Block with New Name

If you have ever needed to make an instance of a block unique so that it may have different geometry or whatever…. One way to do so is to open the the block in the Block Editor and then enter the command BSAVEAS. then close the Block Editor and then insert the newly named block.

But here’s a quick way to do it with LISP.

  • COPYBLOCK3 <enter> to star the LISP routine.
  • Select the block that is to be copied and given a new name.
  • Enter the new name for the copied block.
  • Place the newly named block copy.


~enjoy

;VVA

;make a copy of a block with a new name

;select block to copy

;enter new name unless anonymous block, then new name = ols name less *

;pick insertion point

(defun C:CopyBlock3 (/ *error* OldBlockName NewBlockName

rewind BlockName Info BlockInfo ent_name ent_info)

(defun *error* (Msg)

(cond

((or (not Msg)

(member Msg '("console break"

"Function cancelled"

"quit / exit abort"))))

((princ (strcat "\nError: " Msg)))

) ;cond

(princ)

) ;end error

(sssetfirst)

(setq OldBlockName (entsel "\nSelect Block to copy: "))

(while

(or

(null OldBlockName)

(/= "INSERT" (cdr (assoc 0 (entget (car OldBlockName)))))

)

(princ "\nSelection was not a block - try again...")

(setq OldBlockName (entsel "\nSelect Block to copy: "))

)

;block name

(setq OldBlockName (strcase (cdr (assoc 2 (entget (car OldBlockName))))))

(princ (strcat "\nSelected block name: " OldBlockName))

(if (= "*" (substr OldBlockName 1 1))

(setq NewBlockName (substr OldBlockName 2))

(setq NewBlockName (getstring T "\nEnter new block name: "))

)

(setq rewind T)

(while (setq Info (tblnext "BLOCK" rewind))

(setq BlockName (strcase (cdr (assoc 2 Info))))

(if (= OldBlockName BlockName)

(setq BlockInfo Info)

)

(setq rewind nil)

)

(if BlockInfo

(progn

(setq ent_name (cdr (assoc -2 BlockInfo)))

;header definition:

(entmake (list '(0 . "BLOCK")

(cons 2 NewBlockName)

'(70 . 2)

(cons 10 '(0 0 0))

)

)

;body definition:

(entmake (cdr (entget ent_name)))

(while (setq ent_name (entnext ent_name))

(setq ent_info (cdr (entget ent_name)))

(entmake ent_info)

)

;footer definition:

(entmake '((0 . "ENDBLK")))

(command "-INSERT" NewBlockName pause "1" "1" "0")

)

)

(*Error* nil)

(princ)

) ;end


Posted in AutoLISP, Blocks, Modifying, TIPS | 8 Comments

Copying LISP code from this Blog

I have been receiving questions about errors while copying AutoLISP code from the blog. unfortunately, I cannot make an attachment of the LISP file itself with WordPress who hosts this blog. I am currently looking for a good file host where I can upload the LISP files and then you can easily download the file. But in the meantime, this is how you copy code from the “code” section of my LISP posts.

Simply open a new session of windows “Notepad” or while you are in AutoCAD open the “Visual Lisp Editor” by either using the command VLISP <enter> or VLIDE <enter>.

While in this blog, hover your cursor over the “code area” (text area that has the LISP code). There will appear a couple of buttons (as seen in the picture below).

One allows you to copy all of the code (Minus the numbers that appear to the left) and then you can paste that into your active session of Notepad or Visual Lisp Editor.

The other allows you to see the “source code” which opens a little box that shows the code (minus the numbers that appear to the left). You can then highlight this code and copy & paste…

I hope this helps…

Posted in AutoLISP, TIPS | 2 Comments

AutoLISP: Block & Entity Color Change

Here is a 2-for-1 LISP routine that I know you’ll enjoy.

You can easily change Block colors or Entity colors.

  • BLCC <enter> Block Color Change

Or

  • ENCC <enter> Entity Color Change

  • Select a color from the “AutoCAD Color Index”

For BLCC (Block Color Change):

  • Select the blocks that you want to change the colors of and it will change the color of that block throughout the drawing.

For ENCC (Entity Color Change):

  • Select individual objects like lines & arcs. You can also change individual elements (like lines & arcs) within a block.

~enjoy

(defun c:blcc () (pl:block-color) (princ))

(defun c:encc () (pl:block-ent-color) (princ))

;;;get from Alaspher http://forum.dwg.ru/showthread.php?t=1036

;;; http://forum.dwg.ru/showpost.php?p=166220&postcount=18

(vl-load-com)

(defun pl:block-ent-color (/ adoc blocks color ent lays)

(setq adoc (vla-get-activedocument (vlax-get-acad-object))

lays (vla-get-layers adoc)

color (acad_colordlg 256)

)

(if color

(progn (setvar "errno" 0)

(vla-startundomark adoc)

(while (and (not (vl-catch-all-error-p

(setq ent (vl-catch-all-apply

(function nentsel)

'("\nSelect entity <Exit>:")

)

)

)

)

(/= 52 (getvar "errno"))

)

(if ent

(progn (setq ent (vlax-ename->vla-object (car ent))

lay (vla-item lays (vla-get-layer ent))

)

(if (= (vla-get-lock lay) :vlax-true)

(progn (setq layloc (cons lay layloc))

(vla-put-lock lay :vlax-false)

)

)

(vl-catch-all-apply (function vla-put-color) (list ent color))

(vla-regen adoc acallviewports)

)

(princ "\nNothing selection! Try again.")

)

)

(foreach i layloc (vla-put-lock i :vlax-true))

(vla-endundomark adoc)

)

)

(princ)

)

(defun pl:block-color (/ adoc blocks color ins lays)

(setq adoc (vla-get-activedocument (vlax-get-acad-object))

blocks (vla-get-blocks adoc)

lays (vla-get-layers adoc)

color (acad_colordlg 256)

)

(if color

(progn (setvar "errno" 0)

(vla-startundomark adoc)

(while (and (not (vl-catch-all-error-p

(setq ins (vl-catch-all-apply

(function entsel)

'("\nSelect block <Exit>:")

)

)

)

)

(/= 52 (getvar "errno"))

)

(if ins

(progn (setq ins (vlax-ename->vla-object (car ins)))

(if (= (vla-get-objectname ins) "AcDbBlockReference")

(if (vlax-property-available-p ins 'path)

(princ "\nThis is external reference! Try pick other.")

(progn (_pl:block-color blocks ins color lays)

(vla-regen adoc acallviewports)

)

)

(princ "\nThis isn't block! Try pick other.")

)

)

(princ "\nNothing selection! Try again.")

)

)

(vla-endundomark adoc)

)

)

(princ)

)

(defun _pl:block-color (blocks ins color lays / lay layfrz layloc)

(vlax-for e (vla-item blocks (vla-get-name ins))

(setq lay (vla-item lays (vla-get-layer e)))

(if (= (vla-get-freeze lay) :vlax-true)

(progn (setq layfrz (cons lay layfrz)) (vla-put-freeze lay :vlax-false))

)

(if (= (vla-get-lock lay) :vlax-true)

(progn (setq layloc (cons lay layloc)) (vla-put-lock lay :vlax-false))

)

(vl-catch-all-apply (function vla-put-color) (list e color))

(if (and (= (vla-get-objectname e) "AcDbBlockReference")

(not (vlax-property-available-p e 'path))

)

(_pl:block-color blocks e color lays)

)

(foreach i layfrz (vla-put-freeze i :vlax-true))

(foreach i layloc (vla-put-lock i :vlax-true))

)

)

(progn

(princ "\BLCC - Changes color of the chosen blocks")

(princ "\nENCC - Changes color of the chosen objects (may be element of the block)")

(princ))
Posted in AutoLISP, Blocks, Modifying, TIPS | 7 Comments

AutoLISP: Attribute to text (mtext)

Here is a rare LISP routine. there are plenty of routines out there that take an exploded attribute and turn it into either text or mtext. But this routine allows you to make mtext objects out from attributes without exploding any blocks.

To use this routine:

  • ATTMT <enter> to start
  • Specify the height that you want the mtext to be.
  • Select the blocks with attributes
  • <enter> to make the mtext objects and end the command

NOTE: The mtext that is made will show the tag and the tag value. So if you want a very fast way to extract data, this will save you a lot of time.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:;;;; written by Smirnoff

;;;;; found @ http://www.cadtutor.net/forum/showthread.php?56833-Display-ATTRIBUTES-as-Text-from-multiple-blocks&highlight=attmt

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun c:attmt(/ aDoc aSp oSiz bSet aLst cLst tStr nTxt bCtr Tags TextInsert)

; *****************************************************************************

; ADJUSTMENTS ;

; (Modify it to adjust for your own requirements) ;

; *****************************************************************************

(setq Tags T) ; - if T add tags to MText if Nil not

(setq TextInsert T) ; - Text insertion point. If T center of Bounding Box

; of block, if Nil Block insertion point.

; ******************************* END ADJUSTMENTS *****************************

(vl-load-com)

(defun GetBoundingCenter (vlaObj / blPt trPt cnPt)

(vla-GetBoundingBox vlaObj 'minPt 'maxPt)

(setq blPt(vlax-safearray->list minPt)

trPt(vlax-safearray->list maxPt)

cnPt(vlax-3D-point

(list

(+(car blPt)(/(-(car trPt)(car blPt))2))

(+(cadr blPt)(/(-(cadr trPt)(cadr blPt))2))

0.0

); end list

); end vlax-3D-point

); end setq

); end of GetBoundingCenter

(if(not attmt:Size)(setq attmt:Size(getvar "TEXTSIZE")))

(setq oSiz attmt:Size

attmt:Size(getreal(strcat "\nText size <"(rtos attmt:Size)">: ")))

(if(null attmt:Size)(setq attmt:Size oSiz))

(setq aDoc(vla-get-ActiveDocument(vlax-get-acad-object)))

(if(= 1(vla-get-ActiveSpace aDoc))

(setq aSp(vla-get-ModelSpace aDoc))

(setq aSp(vla-get-PaperSpace aDoc))

); end if

(princ "\n<<< Select text to extract attributes to MText >>> ")

(if(setq bSet(ssget '((0 . "INSERT"))))

(progn

(foreach b(mapcar 'vlax-ename->vla-object

(vl-remove-if 'listp

(mapcar 'cadr(ssnamex bSet))))

(setq aLst '()

tStr "") ; end setq

(if TextInsert

(setq bCtr(GetBoundingCenter b))

(setq bCtr(vla-get-InsertionPoint b))

); end if

(if(= :vlax-true(vla-get-HasAttributes b))

(progn

(setq aLst

(mapcar '(lambda (a)

(list (vla-get-TagString a)

(vla-get-TextString a)))

(vlax-safearray->list

(vlax-variant-value(vla-GetAttributes b)))))

(foreach i(reverse aLst)

(setq tStr(strcat tStr(if Tags(strcat(car i) ": ")"")(last i)"\\P"))

); end foreach

(if(/= "" tStr)

(progn

(setq nTxt(vla-AddMText aSp bCtr (* attmt:Size 30.0) tStr))

(vla-put-Height nTxt attmt:Size)

); end progn

); end if

); end progn

); end if

); end foreach

(vla-EndUndoMark aDoc)

); end progn

); end if

(princ)

); end of c:attmt
Posted in Attributes, AutoLISP, Blocks, Text, TIPS | 2 Comments