DCL로 H-Beam 단면을 그리는 LISP 개발하기
DCL (Dialogue Control Language)로
H-Beam 단면을 그려주는 LISP을 개발해보자!
H형강 단면의 경우 실무에서 정말 많이 활용되지만, 막상 CAD로 그리려고 하면 원하는 단면형상이 없기 마련이다. 그래서 이번 실무용 LISP은 H형강의 단면을 원하는 규격대로 그릴 수 있는 LISP을 제작해 볼 것이다.
<목차>
① H-Beam 대화상자 UI 기획
② DCL 코드
③ DCL ↔ LSP 연동해보기
④ SLD 제작
⑤ H-Beam 단면을 그리기 위한 함수 정리
⑥ 최종 LSP 코드
⑦ LISP 실행
① H-Beam 대화상자 UI 기획
먼저, 어떤 대화상자 UI로 H-Beam 단면을 선택하고 적용하면 좋을지 개략적으로 기획한다. H형강 단면의 규격 선택을 좀 더 용이하게 하기 위해, 팝업리스트의 형태로 원하는 H-Beam 규격을 선택한 뒤 단면을 삽입하는 방식으로 UI를 만들어보고자 한다
② DCL 코드
위에서 기획한대로 UI를 구현하기 위해, 아래와 같은 DCL 코드를 작성한다.
(*DCL 코드를 작성하는 법에 대해서는, 나중에 좀 더 자세히 다루어 보고자 한다)
HBeam : dialog
{label="H-Beam";
width = 35; height = 15;
//(텍스트) H-Beam 규격 선택
: text
{
label = "Please select the size of H-Beam.";
alignment = left;
}
: text
{
label = "H X B X t1 X t2";
alignment = left;
}
//(팝업리스트) H-Beam 규격
: popup_list
{
key = "HSizeList";
//label = "SIZE (HxBxt1xt2) : ";
fixed_width_font = false;
width = 20;
value = "";
}
//(이미지) H-Beam 규격 이미지
: image
{
key = "SectionImg";
width = 15; height = 10; color = 0;
aspect_ratio = 1;
alignment = centered;
is_enabled = false;
is_tap_stop= false;
}
//(버튼) 확인,취소
: row{
: button { //확인버튼
key = "accept";
label = "Insert(I)";
is_tab_stop = true;
is_cancel = false;
is_default = true;
mnemonic = "I";
}
: button { //취소버튼
key = "cancel";
label = "Cancel(C)";
is_cancel = true;
is_default = false;
mnemonic = "C";
}
}
}
③ DCL ↔ LSP 연동해보기
위에서 작성한 DCL코드와 LSP코드를 서로 연동시키기 위한
연습코드를 작성해 보자.
▼ 연습코드를 보려면, 아래 "더보기"를 클릭하세요
(defun C:HBeam ( / dcl_id )
(setq HSizeList (list "100X50X5X7" "100X100X6X8" "125X60X6X8" "125X125X6.5X9"))
(setq dcl_id (load_dialog "H-Beam.dcl"))
(if(not (new_dialog "HBeam" dcl_id))
(progn
(alert "The H-Beam.dcl file could not be loaded!")
(exit)
)
)
(start_list "HSizeList" 3)
(mapcar add_list HSizeList)
(end_list)
//슬라이드 이미지
(setq ix (dimx_tile "SectionImg")
iy (dimy_tile "SectionImg"))
(start_image "SectionImg")
(slide_image 0 0 ix iy "SecImg")
(end_image)
//확인,취소 변수 저장
(action_tile "cancel" "(setq ddiag 1)(done_dialog)")
(action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
(start_dialog)
(unload_dialog dcl_id)
(if (= ddiag 1)
(princ "\n Canceled.\n")
)
(if (= ddiag 2)
(progn
(princ (strcat "You selected " myHSize))
)
)
(princ)
)
(defun saveVars()
(setq sStr1 (get_tile "HSizeList"))
(if (= sStr1 "")
(setq myHSize "Nothing")
(setq myHSize (nth (atoi sStr1) HSizeList))
)
)
위 코드로 CAD에서 HBeam 명령을 입력하면, 아래와 같은 대화상자가 생성된다. (이미지가 검은 바탕인 이유는, 아직 DCL코드의 H-Beam 규격 이미지로 사용될 "SecImg" SLD파일이 없기 때문이다)

그리고 Insert(I) 버튼을 클릭하면,
(if (= ddiag 2)
(progn
(princ (strcat "You selected " myHSize))
)
위 코드에서 설정한 것에 의해 다음과 같은 문구를 출력한다.

④ SLD 제작
SLD는 SLIDE의 줄임말로, AutoCAD에서 개발한 이미지 확장자이다. 이 SLD파일을 활용해야만 LISP 대화상자에 이미지를 삽입할 수 있다.
▼ 관련 설명을 더 보려면, 아래 "더보기"를 클릭하세요
SLD파일은 AutoCAD에서 "MSLIDE (Make SLIDE)" 명령을 통해 만들 수 있는데, 여기서 주의할 점은 화면상에 보이는 객체 그대로 이미지 파일을 만들어 준다는 점이다. 예를 들어, 아래와 같은 CAD 화면에서 MSLIDE 명령으로 SLD 파일을 만들면 화면에서 보이는 만큼의 비율로 이미지를 만들어 준다.

※ SLD 파일 생성예시 (VSLIDE 명령으로 생성될 SLD파일의 이미지를 미리보기할 수 있다)

그리고 또 SLB(SLide liBrary)라고 하는 확장자도 있는데, 이 SLB파일은 여러 개의 SLD 파일이 묶인 것이다. SLB파일을 활용하면, 마치 라이브러리처럼 SLD 파일을 불러와 사용할 수 있다.
※ DCL, SLD "지원 파일 검색 경로"에 추가하기
LSP에서 DCL,SLD 파일을 사용하기 위해선, CAD의 "지원 파일 검색 경로"에 DCL,SLD 파일의 경로를 추가해야만 한다. 지원 파일 검색 경로는 CAD에서 옵션(Options) 명령을 실행한 후, [파일] > [추가] 버튼에서 추가할 수 있다.
⑤ H-Beam 단면을 그리기 위한 함수 정리
H-Beam 단면을 그리는 LSP 코드에는 다음과 같은 3가지 함수가 사용된다.
▼ 함수 코드를 보려면, 아래 "더보기"를 클릭하세요
1. ExtractValuesBetweenX : H-Beam 규격 "100X50X5X7"에서 'X'문자를 기준으로 h,b,t1,t2 추출
(defun ExtractValuesBetweenX (HSizeList)
(setq cnt 1)
(setq len (strlen HSizeList))
(setq XLists '())
(setq SizeLists '())
(repeat len ;문자열 길이만큼 반복
(if(= "X" (substr HSizeList cnt 1)) ;문자열에서 'X'이 있는지 검사
(setq XLists (append XLists (list cnt))) ;X가 있는 위치 리스트 ex) (4 8 11)
)
(setq cnt (1+ cnt))
)
;x2-x1 사이값, t1
(setq t1 (- (nth 1 XLists) (nth 0 XLists)))
;x3-x2 사이값, t2
(setq t2 (- (nth 2 XLists) (nth 1 XLists)))
;전체문자열 개수-x3, t3
(setq t3 (- (1+ len) (nth 2 XLists)))
(setq x1 (substr HSizeList 1 (1- (nth 0 XLists))))
(setq x2 (substr HSizeList (+ (nth 0 XLists) 1) (1- t1)))
(setq x3 (substr HSizeList (+ (nth 1 XLists) 1) (1- t2)))
(setq x4 (substr HSizeList (+ (nth 2 XLists) 1) t3))
(setq SizeLists (list x1 x2 x3 x4))
(princ)
)
2. RadToDeg : Radian을 Degree로 변환하여 주는 함수
(defun RadToDeg(a)(* PI (/ a 180.0)))
3. HBeamfunction : 위 함수를 활용하여 실제 H-Beam 단면을 작성하는 코드
(defun C:HBeamfunction ()
(setq myHSize "100X50X5X7")
(setq osmode (getvar "OSMODE"))
(setvar "OSMODE" 0)
(ExtractValuesBetweenX myHSize) ;return SizeLists (list h,b,t1,t2)
//H빔 규격: hxbxt1xt2xr
(setq h (atoi (nth 0 SizeLists))
b (atoi (nth 1 SizeLists))
t1 (atoi (nth 2 SizeLists))
t2 (atoi (nth 3 SizeLists))
;r (atoi (nth 4 SizeLists))
)
//H빔 규격/2
(setq half_h(/ h 2))
(setq half_b(/ b 2))
(setq half_t1(/ t1 2))
(setq half_t2(/ t2 2))
//H-Beam Top point
(setq p1 (getpoint "\nSpecify the location point of the H-Beam.")
p2 (polar p1 (RadToDeg 0) half_b)
p3 (polar p2 (RadToDeg 270) t2)
p4 (polar p3 (RadToDeg 180) (- half_b half_t1))
p5 (polar p4 (RadToDeg 270) (- h (* t2 2)))
p6 (polar p5 (RadToDeg 0) (- half_b half_t1))
p7 (polar p6 (RadToDeg 270) t2)
p8 (polar p7 (RadToDeg 180) b)
p9 (polar p8 (RadToDeg 90) t2)
p10 (polar p9 (RadToDeg 0) (- half_b half_t1))
p11 (polar p10 (RadToDeg 90) (- h (* t2 2)))
p12 (polar p11 (RadToDeg 180) (- half_b half_t1))
p13 (polar p12 (RadToDeg 90) t2)
)
(command "pline" "_none" p1
"_none" p2
"_none" p3
"_none" p4
"_none" p5
"_none" p6
"_none" p7
"_none" p8
"_none" p9
"_none" p10
"_none" p11
"_none" p12
"_none" p13
"c")
(setvar "OSMODE" osmode)
(princ)
)
⑥ 최종 LSP 코드
(defun C:HBeam ( / dcl_id )
(setq HSizeList
(list "100X50X5X7" "100X100X6X8" "125X60X6X8" "125X125X6.5X9"
"148X100X6X9" "150X75X5X7" "150X150X7X10" "175X90X5X8"
"175X175X7.5X11" "194X150X6X9" "198X99X4.5X7" "200X100X5.5X8"
"200X200X8X12" "200X204X12X12" "244X175X7X11" "248X124X5X8"
"250X125X6X9" "250X255X14X14" "250X260X9X14" "298X149X5.5X8"
"294X200X8X12" "294X302X12X12" "300X150X6.5X9" "300X300X10X15"
"300X305X15X15" "340X250X9X14" "344X348X10X16" "346X174X6X9"
"350X175X7X11" "350X350X12X19" "388X402X15X15" "390X300X10X16"
"394X398X11X18" "396X199X7X11" "400X200X8X13" "400X400X13X21"
"400X408X21X21" "414X405X18X28" "428X407X20X35" "440X300X11X18"
"446X199X8X12" "450X200X9X14" "458X417X30X50" "482X300X11X15"
"488X300X11X18" "496X199X9X14" "498X432X45X70" "500X200X10X16"
"506X201X11X19" "582X300X12X17" "588X300X12X20" "594X302X14X23"
"596X199X10X15" "600X200X11X17" "606X201X12X20" "692X300X13X20"
"700X300X13X24" "792X300X14X22" "800X300X14X26" "890X299X15X23"
"900X300X16X28" "912X302X18X34"))
(setq dcl_id (load_dialog "H-Beam.dcl"))
(if(not (new_dialog "HBeam" dcl_id))
(progn
(alert "The H-Beam.dcl file could not be loaded!")
(exit)
)
)
(start_list "HSizeList" 3)
(mapcar add_list HSizeList)
(end_list)
//슬라이드 이미지
(setq ix (dimx_tile "SectionImg")
iy (dimy_tile "SectionImg"))
(start_image "SectionImg")
(slide_image 0 0 ix iy "SecImg")
(end_image)
//확인,취소 변수 저장
(action_tile "cancel" "(setq ddiag 1)(done_dialog)")
(action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
(start_dialog)
(unload_dialog dcl_id)
(if (= ddiag 1)
(princ "\n Canceled.\n")
)
(if (= ddiag 2)
(progn
(setq osmode (getvar "OSMODE"))
(setvar "OSMODE" 0)
(ExtractValuesBetweenX myHSize)
//return SizeLists (list h,b,t1,t2)
//H빔 규격: hxbxt1xt2
(setq h (atoi (nth 0 SizeLists))
b (atoi (nth 1 SizeLists))
t1 (atoi (nth 2 SizeLists))
t2 (atoi (nth 3 SizeLists))
)
//H빔 규격/2
(setq half_h(/ h 2))
(setq half_b(/ b 2))
(setq half_t1(/ t1 2))
(setq half_t2(/ t2 2))
//H-Beam Top point
(setq p1 (getpoint "\nSpecify the location point of the H-Beam.")
p2 (polar p1 (RadToDeg 0) half_b)
p3 (polar p2 (RadToDeg 270) t2)
p4 (polar p3 (RadToDeg 180) (- half_b half_t1))
p5 (polar p4 (RadToDeg 270) (- h (* t2 2)))
p6 (polar p5 (RadToDeg 0) (- half_b half_t1))
p7 (polar p6 (RadToDeg 270) t2)
p8 (polar p7 (RadToDeg 180) b)
p9 (polar p8 (RadToDeg 90) t2)
p10 (polar p9 (RadToDeg 0) (- half_b half_t1))
p11 (polar p10 (RadToDeg 90) (- h (* t2 2)))
p12 (polar p11 (RadToDeg 180) (- half_b half_t1))
p13 (polar p12 (RadToDeg 90) t2)
)
(command "pline" "_none" p1
"_none" p2
"_none" p3
"_none" p4
"_none" p5
"_none" p6
"_none" p7
"_none" p8
"_none" p9
"_none" p10
"_none" p11
"_none" p12
"_none" p13
"c")
(setvar "OSMODE" osmode)
(princ)
)
)
)
(defun saveVars()
(setq sStr1 (get_tile "HSizeList"))
(if (= sStr1 "")
(setq myHSize "Nothing")
(setq myHSize (nth (atoi sStr1) HSizeList))
)
)
(defun ExtractValuesBetweenX (HSizeList)
(setq cnt 1)
(setq len (strlen HSizeList))
(setq XLists '())
(setq SizeLists '())
//문자열 길이만큼 반복
(repeat len
//문자열에서 'X'이 있는지 검사
(if(= "X" (substr HSizeList cnt 1))
//X가 있는 위치 리스트 ex) (4 8 11)
(setq XLists (append XLists (list cnt)))
)
(setq cnt (1+ cnt))
)
//x2-x1 사이값, t1
(setq t1 (- (nth 1 XLists) (nth 0 XLists)))
//x3-x2 사이값, t2
(setq t2 (- (nth 2 XLists) (nth 1 XLists)))
//전체문자열 개수-x3, t3
(setq t3 (- (1+ len) (nth 2 XLists)))
(setq x1 (substr HSizeList 1 (1- (nth 0 XLists))))
(setq x2 (substr HSizeList (+ (nth 0 XLists) 1) (1- t1)))
(setq x3 (substr HSizeList (+ (nth 1 XLists) 1) (1- t2)))
(setq x4 (substr HSizeList (+ (nth 2 XLists) 1) t3))
(setq SizeLists (list x1 x2 x3 x4))
(princ)
)
//Radian to Degree
(defun RadToDeg(a)(* PI (/ a 180.0)))
⑦ LISP 실행
완성된 H-Beam LISP의 대화상자는 다음과 같다.