오토캐드(AUTO CAD) 단일 객체 시작점 끝점 구하는 리습(Lisp)

1. 선, 호, 폴리선, 스플라인의 시작점과 끝점 추출하기

리습(lisp) 프로그래밍을 통해 AutoCAD에서 단일 객체 시작점 끝점 구하는 방법을 알아보겠습니다. 시작점과 끝점을 구할 객체는 선, 호, 폴리선 스플라인 객체입니다. 오늘 내용을 통해 선, 호, 폴리선, 스플라인의 Vla 속성을 통해 시작점과 끝점을 변수로 저장하는 방법을 확인할 수 있습니다. 또한 변수로 저장된 시작점과 끝점 좌표를 통해 여러 동작을 구현할 수 있는 Command 구문을 작성하겠습니다.

오늘 작성한 리습은 단일 선, 호, 폴리선, 스플라인에 사용할 수 있으며 결합(join)된 다중객체나 블록은 사용할 수 없습니다. 활용방법 및 리습 코드가 궁금하시다면 맨 아래 활용 1, 활용 2 코드를 확인하세요.

호-선-스플라인-폴리라인-객체-시작점-끝점-구하기

1) 객체 선택하기

(setq ss(ssget '((0 . "LINE,ARC,LWPOLYLINE,SPLINE"))))
ssget 함수의 필터 기능을 이용하여 선, 호, 폴리선, 스플라인 객체만 선택합니다. 선택된 선택 세트는 변수 ss로 지정합니다.


(setq ent(ssname ss 0))
선택 세트 첫 번째 객체를 ent 변수로 지정합니다.


(setq ent1(entget ent))
변수 ent의 속성을 ent1 변수로 지정합니다.


(setq entType(cdr(assoc 0 ent1)))
ent1의 dxf 코드 0번의 객체 속성을 추출하고 객체의 종류를 entType 변수로 지정합니다. entType에 저장된 변수는 객체 종류를 식별하기 위해 사용됩니다.


(setq ent2 (vlax-ename->vla-object ent))
“vlax-ename->vla-object” 함수를 사용하여 객체 이름을 VLA 객체로 변환합니다. 객체를 변환하는 이유는 VLA 객체 속성을 사용하여 객체 정보를 불러오기 위함입니다.



2) 호(Arc) 시작점 끝점 추출

(setq asp(vlax-get ent2 'Startpoint))
(setq aep(vlax-get ent2 'endpoint))

호에 대한 Vla 객체 속성의 Startpoint, endpoint 좌표를 asp, aep 변수로 지정합니다.



3) 폴리선(Polyline) 시작점 끝점 추출

(setq plp(vlax-get ent2 'Coordinates))
폴리선 Vla 객체 속성 중 Coordinates 좌표를 plp 변수로 지정합니다. Coordinates 속성을 확인하면 시작점과 끝점 좌표가 하나의 리스트로 작성되어 있습니다.


(setq stp(list (nth 0 plp) (nth 1 plp)))
폴리선의 시작점 좌표를 추출하기 위해 Coordinates 속성의 첫 번째와 두 번째 좌표를 추출하여 stp 변수로 저장합니다.(nth 0번이 첫 번째 리스트입니다.)


(setq edp(list (nth 2 plp) (nth 3 plp)))
폴리선의 끝점 좌표를 추출하기 위해 Coordinates 속성의 세 번째와 네 번째 좌표를 추출하여 stp 변수로 저장합니다.



4) 선(line) 시작점 끝점 추출

(setq lsp(vlax-get ent2 'Startpoint))
(setq lep(vlax-get ent2 'endpoint))

선에 대한 Vla 객체 속성의 Startpoint, endpoint 좌표를 lsp, lep 변수로 지정합니다.


5) 스플라인(Spline) 시작점 끝점 추출

(setq spl(vlax-get ent2 'fitpoints))
스플라인 Vla 객체 속성 중 fitpoints 좌표를 spl 변수로 지정합니다. fitpoints 속성을 살펴보면 가장 앞에 위치한 좌표가 시작점 x,y,z,좌표이며 가장 끝에 있는 좌표가 끝점 x,y,z 좌표입니다.


(setq spsp(list (nth 0 spl) (nth 1 spl)))
spl 변수의 리스트 항목 중 첫 번째와 두 번째를 선택하여 (X, Y) 리스트로 작성하고 spsp 변수로 저장합니다.


(setq spl1(reverse spl))
spl 리스트를 역으로 나열하여 spl1 변수로 저장합니다. 끝점 위치를 추출하기 위해 spl 리스트 항목을 역순으로 나열합니다.


(setq spep(list (nth 2 spl1) (nth 1 spl1)))
역순으로 나열된 spl1 리스트에서 (X, Y) 리스트를 추출합니다. 이때 역순으로 나열된 spl1 리스트는 z, y, x 순으로 나열되기 때문에 순서를 확인하고 리스트를 추출해야 합니다. 추출된 리스트는 spep 변수로 지정합니다.



6) 조건에 맞춰 반복하기

선, 호, 폴리선, 스플라인의 시작점과 끝점을 추출하는 과정을 마쳤습니다. 이제 다중으로 선택했을 때 객체의 개수만큼 반복하는 과정과 객체 유형에 맞게 동작할 수 있는 조건을 삽입하겠습니다. 아래 작성된 코드는 동작을 위한 Command 구문이 빠져있습니다. 조건에 맞춰 반복하는 과정을 확인해보시고 동작을 위한 코드는 아래 활용 1, 활용 2 코드를 확인하시기 바랍니다.

  (setq ss (ssget '((0 . "LINE,ARC,LWPOLYLINE,SPLINE"))))
  (if ss
      (progn
        (setq i 0)
        (setq num (sslength ss))

        (while (< i num)
          (setq ent (ssname ss i))
          (setq ent1 (entget ent))
          (setq entType (cdr (assoc 0 ent1)))
          (setq ent2 (vlax-ename->vla-object ent))

          (cond
           ((= entType "LWPOLYLINE")
            (setq plp (vlax-get ent2 'Coordinates))
            (setq stp (list (nth 0 plp) (nth 1 plp)))
            (setq edp (list (nth 2 plp) (nth 3 plp))))
            

           ((= entType "LINE")
            (setq lsp (vlax-get ent2 'Startpoint))
            (setq lep (vlax-get ent2 'endpoint)))
            

           ((= entType "ARC")
            (setq asp (vlax-get ent2 'Startpoint))
            (setq aep (vlax-get ent2 'endpoint)))

           ((= entType "SPLINE")
            (setq spl (vlax-get ent2 'fitpoints))
            (setq spsp (list (nth 0 spl) (nth 1 spl)))
            (setq spl1 (reverse spl))
            (setq spep (list (nth 2 spl1) (nth 1 spl1))))
          (setq i (1+ i)))
        )
    )
  )




활용 1) 시작점 끝점에 원 그리기

선, 호, 폴리선, 스플라인의 시작점과 끝점에 반지름 20인 원을 그리는 리습입니다. 위에서 작성한 구문에 command 구문을 추가하였습니다. 실행 명령은 p2pcircle이며, 용도에 맞게 수정하세요. 처음에도 언급했지만, 블록 및 결합된 객체에는 동작하지 않으니 사용에 주의하시기 바랍니다.

(defun c:p2pcircle (/ ss i num ent ent1 entType ent2 plp stp edp lsp lep asp aep spl spsp spl1 spep)
  (setq ss (ssget '((0 . "LINE,ARC,LWPOLYLINE,SPLINE"))))
  (if ss
      (progn
        (setq i 0)
        (setq num (sslength ss))

        (while (< i num)
          (setq ent (ssname ss i))
          (setq ent1 (entget ent))
          (setq entType (cdr (assoc 0 ent1)))
          (setq ent2 (vlax-ename->vla-object ent))

          (cond
           ((= entType "LWPOLYLINE")
            (setq plp (vlax-get ent2 'Coordinates))
            (setq stp (list (nth 0 plp) (nth 1 plp)))
            (setq edp (list (nth 2 plp) (nth 3 plp)))
            (command "_circle" stp 50)
            (command "_circle" edp 50))

           ((= entType "LINE")
            (setq lsp (vlax-get ent2 'Startpoint))
            (setq lep (vlax-get ent2 'endpoint))
            (command "_circle" lsp 50)
            (command "_circle" lep 50))

           ((= entType "ARC")
            (setq asp (vlax-get ent2 'Startpoint))
            (setq aep (vlax-get ent2 'endpoint))
            (command "_circle" asp 50)
            (command "_circle" aep 50))

           ((= entType "SPLINE")
            (setq spl (vlax-get ent2 'fitpoints))
            (setq spsp (list (nth 0 spl) (nth 1 spl)))
            (setq spl1 (reverse spl))
            (setq spep (list (nth 2 spl1) (nth 1 spl1)))
            (command "_circle" spsp 50)
            (command "_circle" spep 50)))
          (setq i (1+ i)))
        )
    )
  )

활용 2) 시작점 끝점에 블록 삽입하기

선, 호, 폴리선, 스플라인의 시작점과 끝점에 블록을 삽입하는 리습입니다. 실행 명령은 p2pblock이며, 용도에 맞게 변경하세요. 사용하는 블록 이름은 “1”로 지정하였으며 사용하는 블록에 맞게 이름을 수정하시기 바랍니다.

(defun c:p2pblock (/ ss i num ent ent1 entType ent2 plp stp edp lsp lep asp aep spl spsp spl1 spep)
  (setq ss (ssget '((0 . "LINE,ARC,LWPOLYLINE,SPLINE"))))
  (if ss
      (progn
        (setq i 0)
        (setq num (sslength ss))

        (while (< i num)
          (setq ent (ssname ss i))
          (setq ent1 (entget ent))
          (setq entType (cdr (assoc 0 ent1)))
          (setq ent2 (vlax-ename->vla-object ent))

          (cond
           ((= entType "LWPOLYLINE")
            (setq plp (vlax-get ent2 'Coordinates))
            (setq stp (list (nth 0 plp) (nth 1 plp)))
            (setq edp (list (nth 2 plp) (nth 3 plp)))
            (command "_insert" 1 stp "" "" "") ;블록이름수정하세요
            (command "_insert" 1 edp "" "" ""))

           ((= entType "LINE")
            (setq lsp (vlax-get ent2 'Startpoint))
            (setq lep (vlax-get ent2 'endpoint))
            (command "_insert" 1 lsp "" "" "")
            (command "_insert" 1 lep "" "" ""))

           ((= entType "ARC")
            (setq asp (vlax-get ent2 'Startpoint))
            (setq aep (vlax-get ent2 'endpoint))
            (command "_insert" 1 asp "" "" "")
	    (command "_insert" 1 aep "" "" ""))

           ((= entType "SPLINE")
            (setq spl (vlax-get ent2 'fitpoints))
            (setq spsp (list (nth 0 spl) (nth 1 spl)))
            (setq spl1 (reverse spl))
            (setq spep (list (nth 2 spl1) (nth 1 spl1)))
	(command "_insert" 1 spsp "" "" "")
	(command "_insert" 1 spep "" "" "")))
          (setq i (1+ i)))
        )
    )
  )

Leave a Comment