XiCAD 내부에서 사용하는 보조함수입니다.
번외로...
Lisp 강좌를 할 수는 없지만.. 돌아다니는 Lisp 함수를 가져다 사용할 때 "저장된 변수를 버려야 한다는 것" 만 지켜도 수많은 오류와 원인모를 다운 현상을 크게 줄일 수 있습니다.
예를 들어, 아래와 같은 함수가 있다고 할 때
(defun c:t3 ( / )
(setvar 'CMDECHO 0)
(setq ds (getvar "dimscale")
a (* ds 1)
)
(if (setq ss (ssget))
(command "_.CHANGE" ss "" "_P" "_LT" "CENTER" "_S" a "")
)
(setvar 'CMDECHO 1)
(princ)
)
내용 중에 setq 로 시작하는 것은, 변수이름을 지정해서 거기에 특정 내용을 담겠다는 뜻입니다.
위에서
(setq ds (getvar "dimscale"))
이 것은 ds 라는 변수에 dimscale 담겠다는 뜻이 됩니다.
이 기록된 변수가 프로그램이 종료된 뒤 사라지게 해야 한다는 의미입니다.
맨 위에 보면...
(defun c:t3 ( / ) 이 있는데...
dufun : 실행함수의 정의
c:t3 : 실행함수의 이름 t3 라는 명령어로 작동됨
( / ) : 입력 변수와 버릴 변수의 정의
즉, 위에서 / 기호 뒤쪽에 사용된 변수이름을 넣어 주면,
해당 변수는 명령어가 종료되면 그 값이 사라집니다.
이 것이 되지 않으면, ds 라는 변수가 계속 컴에 남아 있게 되어,
고질적인 문제를 야기합니다.
다른 함수에서 ds 를 사용할 경우, 전혀 엉뚱한 결과가 나오기 때문입니다.
그래서, 위의 함수를 올바르게 수정하면 아래와 같습니다.
(defun c:t3 ( / ds a ss )
(setvar 'CMDECHO 0)
(setq ds (getvar "dimscale")
a (* ds 1)
)
(if (setq ss (ssget))
(command "_.CHANGE" ss "" "_P" "_LT" "CENTER" "_S" a "")
)
(setvar 'CMDECHO 1)
(princ)
)
비록 Lisp 의 내용도 모르고 수정할 줄도 몰라도... 이 변수를 버리게 하는 내용은 알고 있어야 합니다.
[XiCAD의 함수 구조]
XiCAD 에서 제공하는 기능은 기본적으로 아래와 같은 구조로 만들어져 있습니다.
(defun c:xxx ( / )
(xi:StartS)
(if .......
(progn
(xi:StartUndo xi_acDoc)
.....................
(xi:EndUndo xi_acDoc)
)
)
(xi:EndS)
)
(xi:StartS) 는 아래 내용을 담고 있습니다.
(setvar 'cmdecho 0) ;; command 명령어를 사용할 때, 반환을 화면에 표시하지 않게 하는 변수
또한 아래 변수를 저장했다고, 함수가 끝나면 다시 돌려 놓는 기능이 있습니다.
이 변수는 함수 중간에 변경이 되더라도 함수 시작시의 값으로 반환됩니다.
이는 함수 중간에 에러가 있더라도 같습니다.
(setq cu_osm (getvar 'OSMODE)
cu_lay (getvar 'CLAYER)
cu_pea (getvar 'PEDITACCEPT)
cu_frd (getvar 'FILLETRAD)
cu_lts (getvar 'LTSCALE)
cu_cpm (getvar 'COPYMODE)
)
즉 아래와 같이 OSMODE 가 변경 되더라도 원래 값으로 돌아갑니다.
(defun c:xxx ( / p1 p2 )
(xi:StartS)
(if
(and
(setq p1 (getpoint "\n 한 쪽 점 지정: "))
(setq p2 (getpoint p1 "\n 다른 점 지정: "))
)
(progn
(xi:StartUndo xi_acDoc)
(setvar 'osmode 0)
(command "_.line" p1 p2 "")
(xi:EndUndo xi_acDoc)
)
)
(xi:EndS)
)
또한 아래 변수를 정의합니다.
(setq xi_acApp (vlax-get-acad-object)
xi_acDocs (vla-get-documents xi_acApp)
xi_acDoc (vla-get-activedocument xi_acApp)
xi_acSpc (vlax-get-property xi_acDoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace))
xi_acLayouts (vla-get-layouts xi_acDoc)
xi_acLayout (vla-get-ActiveLayout xi_acDoc)
xi_acUtil (vla-get-utility xi_acDoc)
xi_acBlks (vla-get-blocks xi_acDoc)
xi_acLays (vla-get-Layers xi_acDoc)
)
(xi:EndS) 는 아래 내용을 담고 있습니다.
(setvar 'cmdecho 1) ;; 다시 화면에서 표시하는 것으로 설정하고 끝냄
(princ) ;; Lisp 로딩시 자잘한 반환 표시를 억제
[객체 정보 보기]
- info : 객체의 DXF 값을 표시합니다.
- infon : 블럭 내부 객체의 DXF 값을 표시합니다.
- dump : 객체의 Object 정보를 표시합니다.
- dumpn : 블럭 내부 객체의 Object 정보를 표시합니다.
- dumps : 문자 모양의 Object 정보를 표시합니다.
- dumpl : 레이어의 Object 정보를 표시합니다.
- dumpf : 글꼴의 Object 정보를 표시합니다.
[xi:AutoFixNum]
숫자로 된 문자열의 앞쪽에 "0" 을 지정된 갯수 만큼 추가 합니다.
(xi:AutoFixNum str num)
str : 숫자로 된 문자열, 예) "3"
num : 문자열의 갯수, 정수
반환: 문자열
(xi:AutoFixNum "5" 3) → "005"
[xi:Boundingbox]
객체의 사각 테두리 좌표를 반환
(xi:Boundingbox obj)
obj : vla-object
반환 : 사각형 좌표 리스트
(xi:Boundingbox (vlax-ename->vla-object (car (entsel "\n테두리를 얻을 객체 선택:"))))
→ ((-42000.0 0.0) (0.0 0.0) (0.0 29700.0) (-42000.0 29700.0))
[xi:Clockwise-p]
세 점의 진행 방향이 시계방향인지의 판단
(xi:Clockwise-p p1 p2 p3)
p1 : WCS point 좌표
p2 : WCS point 좌표
p3 : WCS point 좌표
반환 : 시계방향: T, 반시계방향: nil
(if
(and
(setq pt1 (getpoint "\n 첫번째 점 지정"))
(setq pt2 (getpoint "\n 두번째 점 지정"))
(setq pt3 (getpoint "\n 세번째 점 지정"))
)
(if (xi:Clockwise-p pt1 pt2 pt3)
(list pt1 pt2 pt3)
(list pt3 pt2 pt1)
)
)
[xi:EffectiveName]
동적블럭 등 무명블럭의 실제 블럭 이름을 반환
(xi:EffectiveName ent)
ent : Entity
반환 : 블럭의 실제 이름, 문자열
(if (setq sel (entsel "\n 블럭 지정: "))
(prompt (xi:EffectiveName (car sel)))
)
[xi:Comma]
숫자로 된 문자열에 천단위 콤마를 넣음
(xi:Comma num dec)
num : 숫자나 숫자로된 문자열
dec : 소숫점 자릿수, 정수
반환 : 천단위 콤마가 들어간 숫자로 된 문자열 반환
(xi:Comma 3235.2 3) → "3,235.200"
[xi:Copy]
선택한 Entity 또는 Selection Set 을 복사하거나 이동 함
(xi:Copy ents p1 p2 CopyOrMove)
ents : 원본 객체, ssest, entity 모두 가능
p1 : 기준 점
p2 : 복사 점
CopyOrMove : Move T, copy nil
반환 : Selection Set
(if
(and
(setq ss (ssget))
(setq pt1 (getpoint "\n 복사 기준점 지정: "))
(setq pt2 (getpoint "\n 목표 점 지정: "))
)
(progn
(setq ss1 (xi:Copy ss pt1 pt2 nil))
(sssetfirst nil ss1)
)
)
[xi:EditBox1]
문자를 입력받기 위한 대화상자, 기존 문자를 미리 입력할 수 있음
(xi:EditBox1 title msg string nil focus)
title : 대화상자 상부에 나오는 제목
msg : 입력칸 앞에 나오는 문장
string : 대화상장의 입력칸에 미리 적힐 문장
nil : xicad 내부에서 사용하기 위한 변수로써 입력하지 않음
focus : 문자 입력칸을 활성화할지 여부
반환 : 입력된 문자열
(setq txt (xi:EditBox1 "문장 기록" "새로운 문장: " "" nil T))
[xi:EditBox2]
문자열을 입력받기 위한 대화상자, 문자열 두 개를 동시에 입력 가능함
(xi:EditBox2 title msg1 msg2 string1 string2 flag)
title : 대화상자 상단의 제목
msg1 : 첫번째 칸의 제목, 문자열
msg2 : 두번째 칸의 제목, 문자열
string1 : 첫번째 칸에 들어갈 문자, 문자열
string2 : 두번째 칸에 들어갈 문자, 문자열
flag : 포커스 칸의 번호, 정수, 1: 첫번째 칸, 2: 두번째 칸
반환 : (list string1 string2)
(xi:EditBox2 "문자입력" "기존문자" "수정문자" "가나다" "" 2)
[xi:entsel]
entsel 과 결과가 동일하나 객체의 종류를 미리 지정할 수 있음
(xi:entsel string enttype nil)
stiring : 명령 구문, 문자열
enttype : 선택할 객체 종류, 문자열 와일드카드 허용
nil : xicad 내부에서 사용하는 변수, 입력하지 않음
반환 : (ename point)
(if (setq sel (xi:entsel "\n>> 객체 선택: " "*TEXT.*DIMESION" nil))
(progn
(setq ent (car sel))
(setq enx (entget ent))
(setq str (cdr (assoc 1 enx)))
(prompt (strcat "문자내용: " str))
)
)
[xi:Colinear-p]
세 점이 같은 선상에 있는지의 여부를 판단
(xi:Colinear-p p1 p2 p3)
p1, p2 p3 : point
반환: T or nil
(if
(and
(setq pt0 (getpoint "\n 첫번째 점 지정"))
(setq pt1 (getpoint "\n 두번째 점 지정"))
(setq pt2 (getpoint "\n 세번째 점 지정"))
)
(xi:Colinear-p pt0 pt1 pt2)
)
[xi:Erase]
Erase 명령어와 동일한 기능이나, 프로그램 종류와 버전을 타지 않음
(xi:Erase ss)
ss : Select Set, Ent, Obj 모두 가능
반환: nil
(if (setq ss (ssget ":L"))
(progn
(xi:erase ss)
(prompt (strcat "\n " (itoa (sslength ss)) " 개의 객체 삭제됨."))
)
)
[xi:FileNameAutoNum]
파일을 저장하거나 Wblock 등을 연속으로 만들 때, 파일 이름에 일련번호를 자동으로 붙이는 함수. 또한 기존 폴더에 동일한 이름의 파일이 있다면, 자동으로 번호를 건너 띄어서 이름을 반환
(xi:FileNameAutoNum folder fixnum filename extention startnum)
folder : 폴더 경로명
fixnum : 숫자의 갯수, 2→01, 3→001
filename : 파일 이름
extention : 확장자
startnum : 시작번호
반환: 파일명.확장자
(if
(and
(setq filename "test")
(setq filename (xi:FileNameAutoNum (getvar 'DWGPREFIX) 3 filename ".dwg" 1))
)
filename
)
[xi:FixAngle]
수평선의 각도를 읽으면, 선의 각도가 0 도일 때, 0에 수렴하는 숫자이거나, 2pi 에 가까운 두가지 형태로 나타나게 되는데, 이 것을 모두 0 도로 맞추어 주는 함수입니다.
또한 각도 계산을 할 때, 2pi 를 넘는 각도의 결과값이 나오면, 이 것을 2pi 이내의 결과로 만들어 줍니다.
(rtos (xi:FixAngle 7.85398163) 2 8) → "1.57079632"
(if
(and
(setq pt1 (getpoint "\n>> 첫번째 점 지정"))
(setq pt2 (getpoint "\n>> 두번째 점 지정"))
)
(setq ang (xi:FixAngle (angle pt1 pt2)))
)
[xi:Get3pCen]
세 점으로 세 점의 중심점과 이 세점을 지나는 원의 반경을 얻습니다.
(xi:Get3pCen p1 p2 p3)
p1, p2, p3 : 포인트
반환: (중심점 반경)
(if
(and
(setq pt1 (getpoint "\n>> 첫번째 점 지정"))
(setq pt2 (getpoint "\n>> 두번째 점 지정"))
(setq pt3 (getpoint "\n>> 세번째 점 지정"))
(setq result (xi:Get3pCen pt1 pt2 pt3))
)
(xi:MakeCircle (car result) (cadr result) nil)
)
[객체 생성]
3D 폴리선
(xi:Make3DPoly lst cls lay)
lst : 점리스트
cls : 닫힘 여부, 닫힘: T, 열림: nil
lay : 켜, nil : 현재켜로 입력
호
(xi:MakeArc p1 p2 p3 lay)
p1 : 호의 시작점
p2 : 호 상의 임의점
p3 : 호의 끝점
lay : 켜, nil : 현재켜로 입력
원
(xi:MakeCircle pt rad lay)
pt : 중심점
rad : 반지름
lay : 켜, nil : 현재켜로 입력
치수 (선형치수)
(xi:MakeDim p1 p2 p3 sca sty lay)
p1 : 치수보조선 시작점
p2 : 치수보조선 끝점
p3 : 치수블럭 위치
sca : 치수축척
sty : 치수모양, nil : 현재 치수모양으로 입력
lay : 켜, nil : 현재켜로 입력
블럭 생성
(xi:MakeInsert bn base ss lay)
bn : 블럭 이름 (특수문자 허용하지 않음)
base : 삽입점
ss : 선택 세트
lay : 켜, nil : 현재켜로 입력
폴리선
(xi:MakeLWPoly lst cls lay)
lst : 점리스트
cls : 닫힘 여부 0: 열림, 1: 닫힘
lay : 켜, nil : 현재켜로 입력
켜
(xi:MakeLayer ln ltyp col plot desc)
ln : 켜 이름 (특수문자 허용하지 않음)
ltyp : 선종류, nil : Continueous 로 입력
col : 색
plot : 출력여부, 0: 출력되지않음. 1: 출력됨
desc : 설명글
지시선
(xi:MakeLeader pt1 pt2 pt3 lay)
p1 : 지시선 시작점
p2 : 지지선 끝점
p3 : 문자 시작점
lay : 켜, nil : 현재켜로 입력
선
(xi:MakeLine pt1 pt2 lay)
p1 : 시작점
p2 : 끝점
lay : 켜, nil : 현재켜로 입력
단행문자
(xi:MakeText str pt ro ht just sty lay)
str : 문장
pt : 삽입점
ro : 각도
ht : 문자 높이
just : 문자정렬, L,C,R,TL, TC, TR, ML, MC, MR, BL, BC, BR
sty : 문자모양, nil : 현재 문자모양으로 입력
lay : 켜, nil : 현재켜로 입력
다행문자
(xi:MakeMText str pt ro ht just sty lay wide)
str : 문장
pt : 삽입점
ro : 각도
ht : 문자 높이
just : 문자정렬, TL, TC, TR, ML, MC, MR, BL, BC, BR
sty : 문자모양
lay : 켜
wide : 영역의 폭 (문자높이x가장 긴 문자열갯수)
...