흔한생각 (recording)/Dynamo

다이나모 파이썬 노드에서 임의로 설치한 패키지 사용하기

hnanmal 2022. 5. 9. 15:03
300x250

다이나모를 쓰다 보면 캔버스 공간 효율화와, 코드 단순화를 목적으로 파이썬 노드를 쓰게 되는 경우가 왕왕 있습니다.

그런데 파이썬으로 모든 기능을 구현하려면 흔히 말하는 ‘바퀴를 새로 발명해야 하는’ 문제가 생기기 쉬운데, 그럴 때는 기존에 사용하던 패키지에 의존하고 싶어 집니다.

패키지를 소환해서 쓰는 것은 별 문제가 아니지만, 패키지를 참조하게 되는 경로는 사용자의 PC 환경에 따라 매번 달라지기 때문에 범용성을 확보하기가 어렵습니다.


그래서 오늘은 환경변수를 활용하여, 다이나모 파일을 실행하는 환경이 바뀌어도 자동으로 패키지가 설치된 경로를 인식하여 패키지 참조를 수행하는 코드를 보여드리려고 합니다.

(Dynamo Revit 기준으로 설명하겠습니다.)


테스트용 archi-lab.net 패키지 설치하기

Online Package Search 접속

먼저 다이나모에서 Online Package Search 창을 열어 줍시다. 테스트 용으로 archi-lab.net 패키지를 설치하고 시작하겠습니다.(설치되신 분은 다음으로 넘어가면 됩니다.)


latest로 설치해 줍시다.


설치하고 나면 좌측의 라이브러리 창에서 archilab 패키지가 설치된 걸 확인할 수 있습니다.


패키지 설치경로 확인

이건 일종의 편법인데, 설치를 완료하고 나서, 패키지 다운로드 버튼의 작은 화살표를 눌러서 나오는 2번째 메뉴를 누르면 어느 경로에 다이나모 패키지들이 설치되는지 확인할 수 있습니다.


요렇게 파란색으로 확인했네요.
다이나모 패키지의 설치경로는 보통은 아래와 같습니다.
C:\Users\사용자명\AppData\Roaming\Dynamo\Dynamo Revit\버전명\packages


패키지를 파이썬으로 불러오기

archi-lab 패키지에는 설치된 레빗의 버전을 확인할 수 있는 노드가 있습니다. 이 기능을 파이썬으로 소환해보겠습니다.


모듈 import 하기: os, sys, re, clr

먼저 파이썬의 os 모듈과, sys 모듈, re모듈과 clr 모듈을 로드해 줍니다.


그다음에는 dynamo_rootpath라는 변수를 만들어서(이름은 제 맘대로 지은 것이니 크게 의미두지 마세요.) 위와 같이 코드를 작성해 줍니다.

간단히 설명하자면 위의 코드는 파이썬에서 환경변수를 읽어오는 부분입니다.


환경변수?

그럼 환경변수는 뭘까요?

이 글 서두에서 밝혔듯이 사용자마다 모듈설치 경로가 달라질 수 있는 부분들을 특정 이름의 변수로 할당하는 것을 말합니다.

환경변수는 시스템의 실행 파일이 놓여 있는 디렉터리의 지정 등 OS 상세서 동작하는 응용소프트웨어가 참조하기 위한 설정이 기록된다



어려운 말은 이렇습니다만, 더 쉽게 이해하려면 이렇게 해보시면 됩니다.

윈도우 탐색기를 열고 %APPDATA%라고 주소창에 적고 엔터를 눌러보세요.( % 표시도 앞뒤로 붙여야 합니다.)











엔터를 누르면 어떤 경로의 폴더로 바로 진입이 되죠? 이 %APPDATA% 라는 변수 이름을 이용하면, 다른 사람의 컴퓨터에서도 위의 경로에 대응하는 폴더로 진입이 된다는 것입니다.

우리가 아까 설치한 archi-lab 패키지는 이 경로의 하위에 있습니다.


%APPDATA% > Dynamo > Dynamo Revit의 경로로 이동해보면 폴더가 2개 있습니다.

하나는 backup 폴더로써, 확장자가 dyn 인 백업 파일들을 저장하는 폴더이고,
2.12라고 쓰여있는 폴더가 우리의 목적지입니다. 저 2.12라는 숫자는 Dynamo Revit의 버전 명입니다.

여러버전의 다이나모를 사용하게 되면, 이 경로에 있는 숫자 이름의 폴더가 늘어나겠군요.


패키지 설치 경로 정리하기

위에서 보여드린 이 코드가 바로 컴퓨터에게 위의 경로를 알려준 것이라고 이해하시면 됩니다.
이 경로를 지금부터 ‘다이나모 루트 패스’라고 부를게요.


이제 루트패스 하위에 존재하는 폴더들의 이름을 한번 출력해 보려고 합니다.
코드를 한 줄 덧붙여서 os모듈에 있는 listdir이라는 메서드를 사용해봅시다.

출력 결과로 우리가 아까 탐색기에서 살펴본 것과 동일한 폴더명이 나오네요.
그런데 backup폴더는 우리의 목적지가 아니기 때문에 숫자이름을 가진 폴더만 골라내는 코드를 추가해 봅시다.


숫자. 숫자~의 형태로 된 폴더명을 추려내기 위해 정규표현식을 사용했습니다. 정규표현식을 지금 길게 설명할 수는 없으니 하기의 링크로 설명을 대신할게요.

https://hnanmal.tistory.com/entry/정규표현식-잘-몰라도-코드-짤-수-있어요

정규표현식 잘 몰라도 코드 짤 수 있어요

어.........음... 다만 코드가 엄청나게 길고 복잡해 질 뿐이죠. 네.. 이 말은 정규표현식에 대해 알아야 한다는 말입니다. 그런데 오히려 알아야한다는 말만 많이 듣고, 한두번씩 배움을 미루다 보

hnanmal.tistory.com


위 코드를 실행하면 2개의 폴더명 중 backup은 제외된 목록이 남게 되는 걸 볼 수 있습니다.
이 목록을 version_list라는 이름으로 저장해둡시다.


레빗에 연결된 다이나모 버전이 사람마다 다를 수 있고, 각각의 버전 중에 가장 최신 버전에 패키지가 설치될 확률이 높기 때문에, 위의 코드에서는 version_list 중 가장 마지막으로 배치되는 폴더를 선택하는 것으로 코드를 작성했습니다.

(이 부분은 사실 예외처리가 완벽하지는 않지만, 일반적으로 다이나모를 사용하는 사용자의 패턴이라면 대부분 오류 없이 동작한다고 보고 코드를 작성했습니다. 추후 오류사례를 모아서 더 범용적으로 동작하는 코드로 수정할 수 있습니다.)

그래서 가장 최신의 다이나모 폴더 하위에 있는 “\packages\archi-lab.net\bin”경로까지 합쳐주면, 패키지 참조에 필요한 전체 경로가 완성이 되고,
이제 이 경로 주소를 sys.path.append 메서드를 사용해 참조 경로 리스트에 추가해주어야 합니다.


참조 추가를 마치고 패키지 이름으로 import 하기

환경변수에 경로 추가까지 마치면 clr.AddReference 메소드를 이용해 archilab 패키지의 닷넷 어셈블리에 액세스 하면 됩니다. 여기서는 archilab 네임스페이스가 되겠죠?

이제 import archilab 명령으로 archilab 패키지에 있는 기능들을 비로소 사용할 수 있게 되었습니다!!
그런데 막상 어떤 노드를 쓰려고 하니 코드를 뭐라고 적어야 할지 모르겠죠?


노드를 파이썬 노드에서 사용하기

원하는 노드를 꺼낸 뒤에, 우측 버튼 클릭 후 Help 메뉴를 클릭하면 오른쪽에 노드의 상세가 적힌 페이지가 나옵니다.
거기서 적색 상자로 표시해 둔 부분을 이용하면 됩니다.


짜잔! 아래쪽은 archi-lab.net패키지의 VersionNumber 노드이고, 위쪽은 동일한 메소드를 파이썬으로 호출하여 결과를 반환하는 파이썬 노드입니다. 동일하게 잘 작동하죠?


지금까지 과정을 아래에 코드로 적어놓을 테니 한번 해보시면 좋을 것 같습니다.

# Load the Python Standard and DesignScript Libraries
import os
import sys
import re
import clr

dynamo_rootpath = os.getenv('APPDATA')+'\Dynamo\Dynamo Revit'
dyn_dir_list = os.listdir(dynamo_rootpath)

p = re.compile('\d[.]\d{2,5}')
version_list = list(filter(lambda x: p.match(x), dyn_dir_list))

dynamo_version = version_list[-1]

sys.path.append(os.getenv('APPDATA').replace('\\','\\\\') + f'\Dynamo\Dynamo Revit\{dynamo_version}\packages\archi-lab.net\bin')

clr.AddReference('archilab')
import archilab

# Assign your output to the OUT variable.
OUT = archilab.Revit.Elements.Applications.VersionNumber()


다른 패키지들도 동일한 방식으로 사용할 수 있습니다~.


위의 내용을 조금 응용하면, 다이나모 패키지가 아닌, 파이썬 패키지들도 다이나모에서 사용할 수 있습니다. (물론 모든 파이썬의 모든 패키지들이 Python in Dynamo 환경에서 전부 실행 가능한 것은 아닙니다.)
이건 내용을 정리해서 또다시 글 올리도록 하겠습니다.



해보시고 오류가 나시면 피드백 주세요. 좀 더 범용적으로 동작할 수 있게끔 계속 코드 수정해서 반영하도록 하겠습니다~

반응형