함수 설명

명령어를 만들 때, 항상 처음과 끝에 들어가야 하는 보조 함수

 

 

XiCAD 에서 제공하는 기능은 기본적으로 아래와 같은 구조로 만들어져 있습니다.

(defun c:xxx ( / )
   (xi:StartS)
   (if .......
      (progn
         (xi:StartUndo xi_acDoc)
         .....................
         (xi:EndUndo xi_acDoc)
      )
   )
   (xi:EndS)
)

 

이 글은 이 구조에 대한 설명입니다.

 

 

(xi:StartS) 와 (xi:EndS) 는 이 내용을 구성하는 시작/끝 함수입니다.

이 속에는 기본적으로 모든 Lisp 함수가 갖추어야 할 아래와 같은 구문이 들어가 있습니다.

 

(setvar 'cmdecho 0) ;; command 명령어를 사용할 때, 반환을 화면에 표시하지 않게 하는 변수


.... 


(setvar 'cmdecho 1) ;; 다시 화면에서 표시하는 것으로 설정하고 끝냄
(princ) ;; Lisp 로딩시 자잘한 반환 표시를 억제

 

 

이 내용에는, 추가로 아래의 변수를 기억했다가 명령어가 끝나면 다시 원래의 값으로 돌리는 역할도 합니다.

 

(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)
)

 

즉, 이 변수와 관련된 내용이 들어갔서 변경이 된다고 하더라도, 명령 실행 전의 값으로 자동으로 돌립니다. 이는 중간에 에러가 나도 같습니다.

 

예를 들어서... 아래와 같이 오스냅 모드가 변경이 된다고 하더라도, 명령이 종료되면 원래의 상태값을 복구합니다.

 

(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)
)

 

 

또한 (xi:StartS) 안 에는  ActiveX object 를 위한 아래의 정의도 들어 있습니다.

(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_acMspc    (vla-get-modelspace xi_acDoc)
      xi_acPspc    (vla-get-PaperSpace xi_acDoc)
      xi_acBlks    (vla-get-blocks xi_acDoc)
      xi_acLays    (vla-get-Layers xi_acDoc)
)

 

그러므로 함수 내에서 vlax-for 를 이용한 구문을 직접 만들 수 있습니다.

(vlax-for x xi_acBlks
.........
)

 

 

이와 함께 항상 쌍둥이 처럼 가는 것이 Undo 의 정의입니다.

xicad 에서는

(xi:StartUndo xi_acDoc)
.....
(xi:EndUndo xi_acDoc)

으로 사용됩니다.

 

 

또한 사용자 에러처리 내용을 입력할 수 있습니다.

XiCAD 내에서 정해진 변수값에 이 에러처리를 넣으면, 자동으로 에러처리 함수에 포함이 됩니다.

(setq xi_CustomError
   (vl-prin1-to-string
     '(progn
         ...... ;; 에러처리
      )
   )
)

 

 

위의 모든 것이 포함된.. XiCAD 명령어의 기본적인 구조는 아래와 같습니다.

사용자가 새로운 함수를 만들 때, 아래 내용을 복사해서 만들면 제작이 쉬워질 수 있습니다.

 

예제)

(defun c:xxx ( / ang ent len nothororper-p obj pt1 pt2 xi_customerror
               ;;;
               xis:MidPt
            )
;;;-----------------------------------------------------------------------------;
   ;;; 두점의 중간 점 반환
   (defun xis:MidPt ( p1 p2 )
      (mapcar '(lambda (x) (* x 0.5)) (mapcar '+ p1 p2))
   )
;;;-----------------------------------------------------------------------------;
;; 사용자 에러 추가
   (setq xi_CustomError
      (vl-prin1-to-string
        '(progn
            (if
               (and
                  obj
                  (not (vlax-erased-p obj))
               )
               (vla-erase obj)
            )
            ;;; 계속 추가 가능
         )
      )
   )
;;;-----------------------------------------------------------------------------;
   (xi:StartS)
   (prompt "\n   수직/수평선을 그려 봅시다. 틀리면 선이 삭제되고, 맞으면 원이 그려짐...")
   (setq notHororPer-p 'T)
   (while notHororPer-p
      (if
         (and
            (setq pt1 (getpoint "\n>> 첫번째 점 지정: "))
            (setq pt2 (getpoint pt1 "\n>> 첫번째 점 지정: "))
         )
         (progn
            (xi:StartUndo xi_acDoc)
            (setq ent (xi:MakeLine pt1 pt2 nil)
                  obj (vlax-ename->vla-object ent)
                  ang (vlax-get obj 'Angle)
                  len (distance pt1 pt2)
            )
            (cond
               (  (or
                     (equal ang 0.0 1e-8)
                     (equal ang pi 1e-8)
                     (equal ang (* pi 2.) 1e-8)
                  )
                  (prompt (strcat "길이가 " (rtos len 2 1) " 인 수평선이 그려짐"))
                  (xi:MakeCircle (xis:MidPt pt1 pt2) (/ len 2.) nil)
                  (setq notHororPer-p nil)
               )
               (  (or
                     (equal ang (/ pi 2.) 1e-8)
                     (equal ang (* (/ pi 2.) 3.) 1e-8)
                  )
                  (prompt (strcat "길이가 " (rtos len 2 1) " 인 수직선이 그려짐"))
                  (xi:MakeCircle (xis:MidPt pt1 pt2) (/ len 2.) nil)
                  (setq notHororPer-p nil)
               )
               (  'T
                  (vla-erase obj)
                  (prompt "수평/수직선이 아님.. 재시도")
               )
            )
            (xi:EndUndo xi_acDoc)
         )
      )
   )
   (xi:EndS)
)