Working With Environment Variables Through Autolisp
Working With Environment Variables Through Autolisp
This sample follows that same trend and uses the Shell object to manipulate environment variables that are
maintained by the OS. Below are three, yes I said three different examples of using the Shell object. The
first shows how to expand environment variables in a string. This can be great for building file paths or
getting information about the OS or PC.
+++++++++++++++++++++++++++++++++
tried writing a routine that creates a dual offset of a line and gives the option of erasing the original, I
would like to get it if you choose not to erase the original that it will change the layer automatically.
:;;MULTIPLE OFFSET OF LINES WITH OPTIONAL REMOVAL OF ORIGINAL LINE
(defun c:moffset (/ ent dist obj kwrd)
(vl-load-com)
(while (not ent)
(if (eq (setq ent (car (entsel "\n Please select line to multi-offset: "))) nil)
(princ "\nTHe object you have chosen is not a line! Please select a line to multi-offset: ")))
(initget (+ 1 2 4 64))
(setq dist (getdist "\nEnter offset distance from centerline: "))
(initget (+ 2 4) "Yes No")
(setq kwrd (getkword "\nDo you wish to put selected line on Centerlines layer? [Yes/No] : "))
(if (/= kwrd "No")(setq kwrd "Yes"))
(setq obj (vlax-ename->vla-object ent))
(vla-offset obj dist)
(vla-offset obj (* dist -1))
(if (eq kwrd "Yes")(vlax-put-property ent 'Layer Centerlines))
(princ)
)
++++++++++++++++++++++++++
i mean by just clicking the POLYLINE & it will automatically gets all the X & Y coordinates (i mean all the corners) &
put it automatically on the TABLE.
(defun c:tabord(/ aCen cAng cCen cPl cRad cReg
fDr it lCnt lLst mSp pCen pT1
pT2 ptLst R tHt tLst vlaPl vlaTab
vLst cTxt oldCol nPl clFlg *error*)
(vl-load-com)
(defun Extract_DXF_Values(Ent Code)
(mapcar 'cdr
(vl-remove-if-not
'(lambda(a)(=(car a)Code))
(entget Ent)))
); end of
(defun *error*(msg)
(setvar "CMDECHO" 1)
(princ)
); end of *error*
(if
(and
(setq cPl(entsel "\nSelect LwPoliline > "))
(= "LWPOLYLINE"(car(Extract_DXF_Values(car cPl)0)))); end and
(progn
(setq vlaPl(vlax-ename->vla-object(car cPl))
ptLst(mapcar 'append
(setq vLst(Extract_DXF_Values(car cPl)10))
(mapcar 'list(Extract_DXF_Values(car cPl)42)))
lLst '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
"N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z")
r 2 lCnt 0
tLst '((1 0 "Point")(1 1 "X")(1 2 "Y")(1 3 "Radius"))
mSp(vla-get-ModelSpace
(vla-get-ActiveDocument
(vlax-get-acad-object)))
tHt(getvar "TEXTSIZE")
); end setq
(setvar "CMDECHO" 0)
(foreach vert ptLst
(setq vert(trans vert 0 1)
tLst(append tLst
(list(list r 0 (nth lCnt lLst))
(list r 1(rtos(car vert)2 4))
(list r 2(rtos(cadr vert)2 4))
(list r 3 ""))))
(if(and
(/= 0.0(last vert))
(setq pt1(vlax-curve-GetPointAtParam vlaPl lCnt))
(setq pt2(vlax-curve-GetPointAtParam vlaPl(1+ lCnt)))
); end and
(setq r(1+ r)
cRad(abs(/(distance pt1 pt2)
2(sin(/(* 4(atan(abs(last vert))))2))))
aCen(vlax-curve-GetPointAtParam vlaPl(+ 0.5 lCnt))
fDr(vlax-curve-getFirstDeriv vlaPl
(vlax-curve-getParamAtPoint vlaPl aCen))
pCen(trans
(polar aCen(-(if(minusp(last vert)) pi(* 2 pi))
(atan(/(car fDr)(cadr fDr))))cRad)0 1)
tLst(append tLst(list
(list r 0 "center")
(list r 1(rtos(car pCen)2 4))
(list r 2(rtos(cadr pCen)2 4))
(list r 3(rtos cRad 2 4))))
); end setq
); end if
(setq r(1+ r) lCnt(1+ lCnt))
); end foreach
(setq vlaTab(vla-AddTable mSp (vlax-3D-point '(0 0 0))
(+ 1(/(length tLst)4)) 4 (* 3 tHt)(* 18 tHt)))
(foreach i tLst
(vl-catch-all-apply 'vla-SetText(cons vlaTab i))
(vla-SetCellTextHeight vlaTab(car i)(cadr i)tHt)
(vla-SetCellAlignment vlaTab(car i)(cadr i)acMiddleCenter)
); end foreach
(vla-DeleteRows vlaTab 0 1)
(princ "\n<<< Place Table >>> ")
(command "_.copybase" (trans '(0 0 0)0 1)(entlast) "")
(command "_.erase" (entlast) "")
(command "_.pasteclip" pause)
(if(= :vlax-true(vla-get-Closed vlaPl))
(progn
(setq nPl(vla-Copy vlaPl))
(command "_.region" (entlast) "")
(setq cCen(vlax-get(setq cReg
(vlax-ename->vla-object(entlast)))'Centroid))
(vla-Delete cReg)
(setq clFlg T)
); end progn
); end if
(setq lCnt 0)
(foreach v vLst
(if clFlg
(setq cAng(angle cCen(trans v 0 1))
iPt(polar v cAng (* 2 tHt)))
(setq fDr(vlax-curve-getFirstDeriv vlaPl
(vlax-curve-getParamAtPoint vlaPl v))
iPt(trans
(polar v(-(* 2 pi)(atan(/(car fDr)(cadr fDr))))
(* 2 tHt))0 1)
); end if
); end if
(setq cTxt(vla-AddText mSp(nth lCnt lLst)
(vlax-3d-point iPt) tHt)
lCnt(1+ lCnt)
); end setq
(setq oldCol(getvar "CECOLOR"))
(setvar "CECOLOR" "1")
(command "_.circle" v (/ tHt 3))
(setvar "CECOLOR" oldCol)
); end foreach
(setvar "CMDECHO" 1)
); end progn
(princ "\n<!> It isn't LwPolyline! Quit. <!> ")
); end if
(princ)
); end of c:tabord
Regions don't have normals, alas -- no (210 ...) code, anyway. They seem to be treated as super-thin 3Dsolids, always
in the WCS regardless of 3d rotation, rather than planar objects like polylines or ellipses.
You can get the normal using ActiveX:
With actDoc already set with (vla-get-activedocument ...), and newOrig set to the WCS coordinates of the point
picked on the region, this sets the current UCS to the plane of the selected region:
( (eq entype "REGION" )
(setq normal (vlax-get obj 'Normal))
(setq regUCS ;;create UCS parallel to the region
(vla-add
(vla-get-usercoordinateSystems actdoc)
(vlax-3D-point (trans '(0 0 0) normal 0))
(vlax-3D-point (trans '(1 0 0) normal 0))
(vlax-3d-point (trans '(0 1 0) normal 0))
"zztemp02"))
(vla-put-origin regUCS (vlax-3d-point newOrig 0 1)) ;;move
UCS origin to point picked on region
(vla-put-activeUCS actDoc regUCS) ;;update UCS
...
+++++++++++++++++++++++
I'm drawing a circle on Y-Z plane.
My questions about this are:
1) How to write it in the code;
2) What is the best way to do this,
for example
a) draw a circle on X-Y plane normally then do 3drotate;
b) rotate the view to Y-Z plane then draw circle;
c) ...
(vla-put-Normal
(vla-addCircle
(vla-get-ModelSpace
(vla-get-ActiveDocument
(vlax-get-acad-object))))
(vlax-3d-point '(0. 10. 20.)) 5.); WCS coordinates
(vlax-3d-point '(1. 0. 0.))) ; Normal
Another way, shoud be to use a transformation matrix to transform a circle drawn in WCS plane to YZ
plane.
(setq circle
(vla-addCircle
(vla-get-ModelSpace
(vla-get-ActiveDocument
(vlax-get-acad-object)))
(vlax-3d-point '(10. 20. 0.)); WCS point
5.))
If you don't want to use the command method (rotating UCS), the simpler way is the one told by Tim: using
210 DXF code.
The 210 DXF code is the object 'extrusion direction' IOW: the normal of its plane.
The normal vector of YZ plane is 1.0, 0.0, 0.0 So, using entmake to draw a circle in YZ plane, which center
is 10.0, 20.0, 0.0 (about this plane, IOW: expressed in OCS coordinates) and radius = 5.0, you just have to
specify the 210 DXF code in the entmake list.
(entmake
'((0 . "CIRCLE") (8 . "Calque1")
(10 10. 20. 0.) ; OCS coordinates
(40 . 5.) (210 1. 0. 0.) ; Normal
)