To Do
✅ GHpython을 이용한 레이어(Layer) 접근
✅ GHpython을 이용한 바운딩 박스 만들기
지난 포스트에서 바운딩 박스를 그래스호퍼 컴포넌트를 이용해서 만들어 봤다.
https://totheretirement.tistory.com/entry/Rhino-Grasshopper-bounding-box
이번에는 그래스호퍼3D 내에 파이썬 컴포넌트인 GHpython를 이용해서 레이어(Layer)에 접근해보려고 한다. 이번 케이스는 점(point)과 서피스(surface)가 같은 레이어에 묶여 있어서 그것까지 분류하는 과정을 다뤄본다. 그리고 이전에 바운딩 박스를 만드는 과정을 굳이 파이썬을 통해서는 어떻게 구현이 가능한지 살펴본다.
GHpython을 이용한 레이어 접근
지금 내가 다루고 있는 라이노 .3dm 파일에는 다음과 같이 레이어 구성이 되어있다. 레이어들을 모두 키면, 좌측 그림과 같이 여러 레이어들이 겹쳐있는 모습을 볼 수 있다.
굉장히 지저분하다 ㅋㅋ. 그냥 라이노만 가지고는 파라미터들을 분석하고 이것저것 조작해보기가 불편하기 때문에 그래스호퍼를 이용하는 것이다. 디자인 하는 분들은 또 나름대로의 이유가 있겠지만, 나 같은 경우는 파라미터를 통한 디자인 보다는, 후처리(post-processing)을 위해서 사용한다. 또 그래스호퍼에서 기본적으로 제공해주는 컴포넌트 그리고 Food4Rhino에서 다른 사람들이 개발한 플러그인(Plugin)을 사용할 수도 있지만, 내 입맛에 맞는 기능을 내가 만들 수도 있어야한다. 그렇기 때문에 결국 python, C#, VB를 통한 나만의 컴포넌트를 만들기도 하고 또 그게 묘미이기도 하다.
그럼 이제 GHpython을 이용하여 라이노에서 정의한 레이어에 접근하는 방법을 알아본다. output으로 원하는 건 세가지:
- 해당하는 레이어에 들어있는 지오메트리(geometry) 전체
- Only 서피스
- Only 포인트
천천히 살펴보자. print해서 아래 output을 보니 내가 선언한 모든 레이어들을 불러오는 것을 볼 수 있다.
내가 원하는 건 Seed 10 부터 Seed 70까지니 다음과 같이 슬라이싱 해서 접근한다. 파이썬 리스트 index는 0부터 시작하며 -1은 마지막 전꺼에 해당된다. 기초적인 파이썬 리스트 관련해서는 생략한다 어렵지 않으니 잘 모른다면? "python list 슬라이싱"을 키워드로 찾아보면 엄청 자료가 많으니 참고하자.
print layers[3:-1]
"""
output:
['Seed10', 'Seed20', 'Seed30', 'Seed40', 'Seed50', 'Seed60', 'Seed70']
"""
레이어에 담긴 포인트랑 서피스를 각각 다른 output 변수에 넣기 위해서 다음의 코드를 작성했고, 그 결과물을 살펴보자. 조건문(conditionals)은 작성하기 나름이다. 나 같은 경우는 brep 인지 아닌지를 판단하고 분류했는데, 반대로 point인지 아닌지로 분류 가능하다. 결과는 똑같다.
# Get the Guids of the according layer
guid = rs.ObjectsByLayer(seed_name[0]) # Seed10
# Empty list for append items
point_objs = []
brep_objs = []
# Allocate according items to the list
for g in guid:
if rs.IsBrep(g):
if rs.IsSurface(g):
obj = rs.coercesurface(g)
else:
obj = rs.coercegeometry(g)
brep_objs.append(obj)
else:
obj = rs.coerce3dpoint(g)
point_objs.append(obj)
# Output
surfs = brep_objs
points = point_objs
다음과 같이 따로 담긴 것을 panel을 통해서도 확인 가능하고 해당하는 컴포넌트는 Front 뷰에서 확인하면 다음과 같다.
다음으로는 GHpython을 이용하여 바운딩 박스를 생성하는 과정을 간단하게 작성해봤다.
GHpython을 이용한 바운딩 박스 만들기
이미 지난 번에 그냥 bounding box 컴포넌트로 만들어 봤지만 GHpython을 이용해서도 구현이 가능하다라는 것을 보여주기 위해 내용을 적어본다. 인덱싱(Indexing)된 서피스와 평면을 아래와 같이 각각 surf, plane이라는 input 변수명으로 선언하고 서피스들을 담을 s, 바운딩 박스를 담을 bounding_box 를 output 변수명 으로 선언했다. 코드는 매우 간단하다.
아래에서 실제로 쓰는 건 rhinoscriptsyntax 라이브러리/패키지를 rs로 선언하여 쓰는게 전부이지만 나머지도 많이 쓰니까 참고하자.
import rhinoscriptsyntax as rs
import ghpythonlib as ghpy
import Grasshopper as gh
import Rhino.Geometry as rg
import scriptcontext
bbox = []
surfs = []
for s, p in zip(surf, plane):
surfs.append(s)
bbox.append(rs.AddBox(rs.BoundingBox(s, p)))
bounding_box = bbox
s = surfs
파이썬을 다뤄본 사람들은 알겠지만 위 코드의 flow는 다음과 같다:
- bbox, surfs 라는 리스트를 선언
- input으로 들어간 각각의 서피스(변수명 surf)와 평면(변수명 plane)에 대해서 surfs와 bbox 리스트에 각각 서피스와 바운딩 박스를 붙여넣음(append method)
간단하게 파이썬 리스트 append 메소드 그리고 rhinoscriptsyntax를 이용하면 지난 포스트에서 다뤘던 아래의 bounding box 컴포넌트를 대체할 수 있다.
그래스호퍼3d(Grasshopper3d)를 필요에 의해서 쓰기 시작했었고, 쓰다보면 짜증날 때도 있지만 마치 코딩처럼 될 때 그 희열이 있다. 또 3d를 다루는 거다보니 그 기쁨이 배가 된다고 해야하나? ㅋㅋㅋ 개인적인 의견은 그렇다.
예전에 만들었던 것들도 공유할 수 있으면 공유하도록 하겠다. 평면을 step별로 옮겨가면서 교차(intersection)되는 개체(object)가 몇 개인지 세는 걸 했었는데 그것도 나름 재미가 있었다. 라이노랑 그래스호퍼를 진짜 잘 다룰 수 있는 단계까지 올라가는 건 어렵지만 이렇게 분석하는 건 또 하나보면 금방 느는 것 같다.
또 다른 포스트에서 재밌는 걸 다뤄보겠다!
Tistory 첫번째 pip 블로거로서,
도움이 되셨다면? 아래 pip button을 통해 후원해 주시면 감사합니다.
'Researches > Rhino(라이노) | Grasshopper' 카테고리의 다른 글
[Rhino | Grasshopper] 파이썬을 이용한 불리언 토글(Boolean Toggle) 닉네임과 값 읽고 쓰기 (0) | 2023.04.25 |
---|---|
[Rhino | Grasshopper] 원호(arc) 아크 그리기 - 그래스호퍼 3d 파이썬 활용 (0) | 2023.04.07 |
[Rhino | Grasshopper] 원하는 객체의 바운딩 박스(bounding box) - 그래스호퍼 활용 (2) | 2023.03.27 |