저번에 Dynamo에서 파이썬 노드를 이용해 명령을 내리는 법을 살폈습니다.
다이나모에서 파이썬 노드를 활용하는 이유는 여러가지가 있습니다.
먼저 다양한 라이브러리들을 이용하기 위한 목적도 있고,
기본 노드로 작성된 코드가 지나치게 복잡해지는 경우, 하나의 노드 혹은 기능단위로 축약해서
깔끔하게 코드를 작성하기 위한 목적도 있습니다.
다이나모로 필터링 코드 작성하기
샘플 rvt 파일과 다이나모 열기
오토데스크에서 제공하는 샘플파일을 가지고 시작해보겠습니다. 샘플파일이 없다면 하기 링크 참조.
다이나모를 열어서 위 그림처럼 모든 벽을 소환하는 코드를 짭니다.
모든 벽체 꺼낸 뒤, family type 이름 확인하기
샘플 파일에는 여러가지 타입의 벽체가 모델링 되어 있습니다. 이중에서 콘크리트 벽체만 걸러내는 코드를 한번 작성해보겠습니다.
위 그림처럼 모든 벽체들이 소환된 All Elements of Category의 결과값에 “Element.Name” 노드를 배치하면 각 벽체들의 family type 이름이 보기좋게 출력됩니다.
잘 살펴보니 콘크리트 벽체들은 family type 명칭에 “Concrete” 가 포함됨을 알 수 있습니다. (대소문자 구별 주의)
“Element.Name” 노드를 살짝 밑으로 내려두고, 여기에 “String.Contains” 노드를 연결해 줍니다.
“String.Contains” 노드는,
searchFor 포트로 받아들인 문자열이
string으로 받아들인 문자열에 포함되어 있는지를 판별해서,
true 혹은 false 를 반환해 주는 기능을 합니다.
상기 링크에서 설명했듯이, 다이나모 기본노드들은 인자가 단일 개체로 들어올 때와, 리스트로 들어올 때를 자동으로 판별해서 순회문을 내부에서 적용합니다.
결과물도 벽체별로, 이름에 “Concrete”가 들어가있는지 아닌지를
true / false 로 잘 반환하고 있습니다.
벽체별로 참거짓을 리스트 형태로 만들어 둔 이유는 다음을 보세요.
List.FilterByBoolMask 노드로 걸러내기
“List.FilterByBoolMask” 라는 노드가 있습니다.
이 노드는 기본적으로 2개의 리스트를 받아서 동작하는 함수 입니다.
그런데 2개의 리스트가 특별한 관계에 있어야 합니다.
- 먼저 원소의 개수가 같아야 하고,
- mask 포트로 들어갈 리스트는 오직 true 와 false로 구성된 리스트여야 합니다.
이제 위에서 왜 벽체별로 이름에 “Concrete”가 들어가있는지 여부를 true, false 로 반환하는 리스트를 챙겨놨는지 이해하시겠죠?
위의 그림을 보시면 더 이해하기 쉬울 겁니다.
original 리스트의 28번째 원소는,
rule list의 28번째 원소가 true 라고 저장되어 있으므로,
“List.FilterByBoolMask” 노드를 만나면 “in” 리스트로 편성이 됩니다.
그에 반해 original 리스트의 29번째 원소는,
rule list의 29번째 원소가 false 라고 저장되어 있으므로,
“List.FilterByBoolMask” 노드를 만나면 “out” 리스트로 편성이 됩니다.
“List.FilterByBoolMask” 노드의 “in”포트로 출력되는 리스트에 “Element.Name”을 확인해보니,
10개의 벽체 모두 family type의 이름이 Concrete를 포함하고 있음을 확인했습니다.
완성된 코드는 위 그림과 같군요.
파이썬 코드로 변환하기
파이썬 노드 꺼내고, input data 포트 연결하기
All Elements of Category 까지의 코드만 남기고, 이번에는 파이썬 노드를 하나 꺼내줍니다.
그 다음에는 파이썬 코드들이 처리할 데이터를 연결 시켜줘야 합니다.
위 그림의 1번 처럼 파이썬 노드의 IN[0] 포트에 벽체 리스트를 연결해주고,
2번 처럼 inputs라는 이름의 변수를 만든 뒤, IN[0]포트의 값을 할당해 준다는 코드를 작성해 둡니다.
for 문 으로 코드 작성하기
이제 필터링 해주는 코드를 파이썬으로 작성해 봅시다.
위쪽에 import 라고 작성된 부분은 지금은 무시하셔도 됩니다. (파이썬 노드를 생성하면 저절로 작성되어 있는 부분입니다.)
먼저 “참결과”, “거짓결과” 라는 2개의 빈 리스트를 먼저 만들어 두고,
for 문을 사용해, inputs 로 들어온 모든 벽체 리스트의 원소들을 하나씩 꺼내 옵니다.
그 다음에는 if 문을 통해, 각 원소의 family type 이름이 ( a.Name )
“Concrete”라는 문자열을 포함하고 있는지 검사합니다.
if "Concrete" in a.Name:
그래서 결과가 참이면 “참결과” 리스트에 원소를 추가하고,
결과가 거짓이면 “거짓결과” 리스트에 원소를 추가하라고 코드를 짜면
끝나게 됩니다.
참고. 파이썬 노드에서는 OUT이라는 변수를 통해 노드 자체가 반환할 결과값을 지정하게 되어 있습니다. OUT 다음의 코드는 저와 동일하게 작성해서 테스트 하시면 됩니다.
이렇게 하면, 사용한 도구는 다르지만, 정확하게 다이나모 기본노드로 짠 코드와 동일하게 작동하는 파이썬 코드가 완성 되었습니다.
리스트컴프리헨션 문법으로 작성하기
이번에는 for 문을 조금 간략화 해서, 리스트컴프리헨션 문법을 통해 좀 더 간결한 코드로 작성해보죠.
동일한 결과인데 코드는 훨씬 깔끔하죠? 꼭 똑같이 실습해보세요.
리스트 컴프리헨션 문법에 대한 포스트는 하기 링크입니다.
결론
실습한 코드 전체입니다.
기본 노드로는 5개 이상의 노드가 배치되어야 하는 필터링 작업이, 파이썬을 쓰면 노드하나로 축약되니 정말 간편하죠?
물론 기본 노드로 짜진 코드가 다른 사람이 알아보기는 좀 더 편할 수 있지만, 지나치게 복잡한 노드들을 파이썬으로 축약하고, 상세한 주석을 남기는 것이 더 도움이 될 수 있다는 것을 알아두시면 좋을 것 같습니다.
'흔한생각 (recording) > Dynamo' 카테고리의 다른 글
List_Generate #2 (다이나모 기본노드 활용 시리즈-3) (0) | 2022.02.27 |
---|---|
List_Generate #1 (다이나모 기본노드 활용 시리즈-2) (0) | 2022.02.27 |
Import (다이나모 기본노드 활용 시리즈-1) (2) | 2022.02.24 |
다이나모 코드의 추상화 수준을 높여가는 방법 (0) | 2022.02.17 |
다이나모로 공공데이터 API 활용하기 (0) | 2022.02.15 |