;;; ¸éÀû Æò¼ö - TORVA ¹«·á ¸®½À (torva.kr/lisp.html)
;;; PY : ´ÝÈù °´Ã¼ ÇÏ³ª¸¦ °í¸£¸é ¸éÀû(m2)°ú Æò¼ö(py)¸¦ ±ÛÀÚ·Î ¾´´Ù. »ç°¢Çü¡¤»ï°¢ÇüÀº °¡·Î¡¤¼¼·Î(¹Øº¯¡¤³ôÀÌ)µµ ÇÔ²²
;;; »ðÀÔÁ¡À» Âï±â Àü¿¡ S(±ÛÀÚ ³ôÀÌ) U(µµ¸é ´ÜÀ§ mm/m)·Î ¼³Á¤À» ¹Ù²Û´Ù. ¹Ù²Û °ªÀº µµ¸éÀ» ´ÝÀ» ¶§±îÁö À¯ÁöµÈ´Ù
;;; ±ÛÀÚ ³ôÀÌ ±âº»°ª = 3.5 x DIMSCALE (1:100 µµ¸éÀÌ¸é 350). µµ¸é ´ÜÀ§ ±âº»°ª mm. ±Û²ÃÀº ÇöÀç ±Û²Ã ½ºÅ¸ÀÏ

(vl-load-com)

(if (null *TV-AREA-MM*) (setq *TV-AREA-MM* T))   ; T = µµ¸é ´ÜÀ§ mm, nil = m

;; ±ÛÀÚ ³ôÀÌ - Á÷Á¢ Á¤ÇÑ °ªÀÌ ¾øÀ¸¸é µµ¸é ÃàÃ´¿¡ ¸ÂÃá´Ù
(defun tv-area-h ()
  (cond (*TV-AREA-H*)
        ((> (getvar "DIMSCALE") 0) (* 3.5 (getvar "DIMSCALE")))
        (3.5)))

;; ±æÀÌ¸¦ m ·Î
(defun tv-area-m (d) (if *TV-AREA-MM* (/ d 1000.0) d))

(defun c:PY (/ *error* doc space ss ent obj area pts n l1 l2 l3 base w h dx dy lines txt inspt mt v s)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (defun *error* (msg)
    (vla-EndUndoMark doc)
    (if (not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*BREAK*")) (princ (strcat "\n¿À·ù: " msg)))
    (princ))
  (vla-StartUndoMark doc)
  (setq space (if (= (vla-get-activespace doc) 1) (vla-get-modelspace doc) (vla-get-paperspace doc)))

  ;; ¸ÕÀú °ñ¶ó µÐ °´Ã¼°¡ ÀÖÀ¸¸é ±×°ÍÀ» ¾´´Ù
  (if (setq ss (ssget "_I"))
    (setq ent (ssname ss 0))
    (if (setq ent (entsel "\n°´Ã¼ ¼±ÅÃ: ")) (setq ent (car ent))))

  (cond
    ((null ent) (princ "\n¼±ÅÃÇÑ °´Ã¼°¡ ¾ø½À´Ï´Ù."))
    ((vl-catch-all-error-p (setq area (vl-catch-all-apply 'vla-get-area (list (setq obj (vlax-ename->vla-object ent))))))
     (princ "\n¸éÀûÀ» ±¸ÇÒ ¼ö ¾ø´Â °´Ã¼ÀÔ´Ï´Ù."))
    (T
     ;; ²ÀÁþÁ¡ (Æú¸®¼±) - Ã³À½°ú ³¡ÀÌ °°À¸¸é ÇÏ³ª·Î
     (foreach x (entget ent) (if (= (car x) 10) (setq pts (cons (cdr x) pts))))
     (setq pts (reverse pts))
     (if (and (> (length pts) 1) (equal (car pts) (last pts) 1e-4)) (setq pts (cdr pts)))
     (setq n (length pts))

     ;; »ðÀÔÁ¡ - S U ·Î ¼³Á¤À» ¹Ù²Ù°í, Á¡À» ÂïÀ¸¸é ¾´´Ù. ¿£ÅÍ = ¾²Áö ¾ÊÀ½
     (setq inspt "S")
     (while (= (type inspt) 'STR)
       (initget "S U")
       (setq inspt (getpoint (strcat "\n±ÛÀÚ »ðÀÔÁ¡ [±ÛÀÚ ³ôÀÌ(S)/µµ¸é ´ÜÀ§(U)] <³ôÀÌ " (rtos (tv-area-h) 2 0)
                                     ", ´ÜÀ§ " (if *TV-AREA-MM* "mm" "m") ">: ")))
       (cond
         ((= inspt "S") (if (setq v (getdist (strcat "\n±ÛÀÚ ³ôÀÌ <" (rtos (tv-area-h) 2 0) ">: "))) (setq *TV-AREA-H* v)))
         ((= inspt "U") (setq *TV-AREA-MM* (not *TV-AREA-MM*)))))

     (if inspt
       (progn
         (setq area (if *TV-AREA-MM* (/ area 1000000.0) area))
         (cond
           ((= n 3)
            (setq l1 (distance (nth 0 pts) (nth 1 pts)) l2 (distance (nth 1 pts) (nth 2 pts)) l3 (distance (nth 2 pts) (nth 0 pts))
                  base (tv-area-m (max l1 l2 l3)))
            (setq lines (list (strcat "W: " (rtos base 2 2) "m / H: " (rtos (/ (* 2.0 area) base) 2 2) "m"))))
           ((= n 4)
            (setq l1 (distance (nth 0 pts) (nth 1 pts)) l2 (distance (nth 1 pts) (nth 2 pts))
                  dx (abs (- (car (nth 1 pts)) (car (nth 0 pts)))) dy (abs (- (cadr (nth 1 pts)) (cadr (nth 0 pts)))))
            (if (> dx dy) (setq w l1 h l2) (setq w l2 h l1))
            (setq lines (list (strcat "W: " (rtos (tv-area-m w) 2 2) "m / H: " (rtos (tv-area-m h) 2 2) "m")))))
         (setq lines (append lines (list (strcat (rtos area 2 2) " m\\U+00B2") (strcat (rtos (* area 0.3025) 2 2) " py"))))
         (setq txt (car lines))
         (foreach s (cdr lines) (setq txt (strcat txt "\\P" s)))
         (setq mt (vla-AddMText space (vlax-3d-point (trans inspt 1 0)) 0.0 txt))
         (vla-put-Height mt (tv-area-h))
         (vla-put-AttachmentPoint mt acAttachmentPointTopLeft)
         (vla-put-InsertionPoint mt (vlax-3d-point (trans inspt 1 0)))
         (princ (strcat "\n" (rtos area 2 2) " m2 / " (rtos (* area 0.3025) 2 2) " Æò"))))))
  (vla-EndUndoMark doc)
  (princ)
)

(princ "\n¸éÀû Æò¼ö: PY / torva.kr")
(princ)

;;; ---- ´ÜÃàÅ° ¹Ù²Ù±â (TVKEY) - TORVA ¸®½À °øÅë, torva.kr/lisp-guide.html ----
;;; TVKEY -> ¸í·É -> »õ ´ÜÃàÅ°. ¿ø·¡ ¸í·É¾îµµ ±×´ë·Î ¾´´Ù
;;; Á¤ÇÑ ´ÜÃàÅ°´Â ÀÌ PC ¿¡ TORVA-KEYS ·Î ÀúÀåµÇ°í, ¸®½ÀÀ» ºÒ·¯¿Ã ¶§¸¶´Ù µÇ»ì¾Æ³­´Ù
;;; (TORVA ¸®½À ÆÄÀÏ¸¶´Ù °°Àº ÄÚµå°¡ µé¾î ÀÖ´Ù. ¿©·¯ °³¸¦ ºÒ·¯¿Íµµ °°Àº Á¤ÀÇ¸¦ µ¤¾î¾µ »ÓÀÌ´Ù)

;; "A1=PY;B2=CN;" -> (("A1" . "PY") ("B2" . "CN"))
(defun tv-key-list (/ s i out)
  (setq s (cond ((getenv "TORVA-KEYS")) ("")) out nil)
  (while (setq i (vl-string-search ";" s))
    (setq out (cons (substr s 1 i) out) s (substr s (+ i 2))))
  (if (/= s "") (setq out (cons s out)))
  (vl-remove nil
    (mapcar '(lambda (x / j) (if (setq j (vl-string-search "=" x)) (cons (substr x 1 j) (substr x (+ j 2)))))
            (reverse out))))

(defun tv-key-save (lst)
  (setenv "TORVA-KEYS" (apply 'strcat (mapcar '(lambda (p) (strcat (car p) "=" (cdr p) ";")) lst))))

;; ºÒ·¯¿Â ¸®½À ¸í·ÉÀÎ°¡
(defun tv-key-cmd-p (cmd)
  (member (type (eval (read (strcat "C:" cmd)))) '(SUBR USUBR EXRXSUBR)))

(defun tv-key-def (key cmd)
  (eval (list 'defun (read (strcat "C:" key)) '() (list (read (strcat "C:" cmd))) '(princ))))

;; acad.pgp ¿¡ °°Àº º°ÄªÀÌ ÀÖ³ª ("L,   *LINE")
(defun tv-key-pgp-p (key / f h l hit)
  (if (setq f (findfile "acad.pgp"))
    (progn
      (setq h (open f "r"))
      (while (and (not hit) (setq l (read-line h)))
        (if (and (not (wcmatch l ";*")) (wcmatch (strcase l) (strcat key ",*"))) (setq hit T)))
      (close h)))
  hit)

;; ¾µ ¼ö ¾ø´Â ´ÜÃàÅ°¸é ±î´ßÀ», ¾µ ¼ö ÀÖÀ¸¸é nil
(defun tv-key-bad (key lst)
  (cond
    ((not (vl-every '(lambda (c) (or (<= 48 c 57) (<= 65 c 90))) (vl-string->list key))) "¿µ¹®°ú ¼ýÀÚ¸¸ ¾¹´Ï´Ù")
    ((getcname key) "AutoCAD ¸í·É°ú °°Àº ÀÌ¸§ÀÔ´Ï´Ù")
    ((tv-key-pgp-p key) "AutoCAD ´ÜÃàÅ°(acad.pgp)¿Í °°Àº ÀÌ¸§ÀÔ´Ï´Ù")
    ((and (tv-key-cmd-p key) (not (assoc key lst))) "ÀÌ¹Ì ÀÖ´Â ¸®½À ¸í·ÉÀÔ´Ï´Ù")))

(defun c:TVKEY (/ cmd key lst why)
  (setq lst (tv-key-list)
        cmd (strcase (getstring "\n´ÜÃàÅ°¸¦ ºÙÀÏ ¸í·É [¸ñ·Ï(?)]: ")))
  (cond
    ((= cmd ""))
    ((= cmd "?")
     (if lst
       (foreach p lst (princ (strcat "\n  " (car p) " = " (cdr p))))
       (princ "\nÁ¤ÇÑ ´ÜÃàÅ°°¡ ¾ø½À´Ï´Ù")))
    ((not (tv-key-cmd-p cmd)) (princ (strcat "\n" cmd " ´Â ºÒ·¯¿Â ¸®½À ¸í·ÉÀÌ ¾Æ´Õ´Ï´Ù")))
    (T
     (setq key (strcase (getstring (strcat "\n" cmd " ÀÇ »õ ´ÜÃàÅ° [Áö¿ì±â(-)]: "))))
     (cond
       ((= key ""))
       ((= key "-")
        (foreach p lst
          (if (= (cdr p) cmd) (set (read (strcat "C:" (car p))) nil)))
        (tv-key-save (vl-remove-if '(lambda (p) (= (cdr p) cmd)) lst))
        (princ (strcat "\n" cmd " ÀÇ ´ÜÃàÅ°¸¦ Áö¿ü½À´Ï´Ù")))
       ((= key cmd))
       ((setq why (tv-key-bad key lst)) (princ (strcat "\n" key ": " why)))
       (T
        (tv-key-save (cons (cons key cmd) (vl-remove-if '(lambda (p) (= (car p) key)) lst)))
        (tv-key-def key cmd)
        (princ (strcat "\nÀÌÁ¦ " key " ·Îµµ " cmd " °¡ ½ÇÇàµË´Ï´Ù"))))))
  (princ))

;; ºÒ·¯¿Ã ¶§ - ÀúÀåµÈ ´ÜÃàÅ° Áß ¸í·ÉÀÌ ºÒ·¯¿ÍÁ® ÀÖ´Â °ÍÀ» µÇ»ì¸°´Ù
(foreach p (tv-key-list)
  (if (tv-key-cmd-p (cdr p)) (tv-key-def (car p) (cdr p))))
(princ "\n´ÜÃàÅ° ¹Ù²Ù±â: TVKEY")
(princ)
