VEX 함수 prim

지오메트리 요소중, primitive가 갖는 어트리뷰트의 데이터값을 리턴하는 prim 함수에 대해서 알아보자.

Posted: March 27, 2021

Version: Houdini 18.0


Prim VEX Function

prim() 함수는 primitive의 특정 어트리뷰트 의 데이터값을 돌려준다.

prim() 함수의 기본형태는 다음과 같다.

prim(a, b, c)

 

각각의 인자는 다음과 같은 역할을 한다.

a: 어트리뷰트를 얻으려는 대상 지오메트리

b: 얻으려는 어트리뷰트 이름

c: 어트리뷰트를 얻으려는 지오메트리의 primitive 번호

 

괄호안에 각 인자들의 타입 은 다음과 같다.

인자 a 는 Wrangle 노드의 인풋번호이므로 Integer 타입을 기대한다.

인자 b 는 어트리뷰트 이름이므로 String 타입을 기대한다.

인자 c 는 Primitive Number 이므로 Integer 타입을 기대한다.


Prim 함수 예제

prim() 함수를 이용해서 스피어를 그리드 각 면들의 중심점에 번갈아 위치시켜 보자.

후디니를 열고 /obj 에 스피어 지오메트리를 하나 만든다.

VEX_func_point_1.jpg

 

만들어진 'sphere1' 노드를 더블클릭하여 Geometry 레벨로 들어간다.

‘sphere1’ 노드의 uniform scale 값을 반정도 줄여서 스피어 크기를 줄여준다.

vex-prim-img1.png

Grid SOP, Attribute Wrangle SOP 을 하나씩 만들고 다음과 같이 연결해 준다.

연결한 뒤에는 'attribwrangle1' 노드의 Display Flag 를 선택한다.

연결한 뒤에는 'attribwrangle1' 노드의 Display Flag 를 선택한다.

 

Wrangle 노드와 같이 여러개의 인풋을 연결할 때는 그 순서에 주의한다.

스피어의 위치를 변화시키는게 목적이므로 'sphere1' 노드를 첫번째 인풋에 연결한다.

그리드는 어트리뷰트 참조만 하기때문에 'grid1' 노드는 두번째 인풋에 연결한다.

 

아직 VEX 를 입력하지 않았기 때문에 스피어는 어떤 변화도 없다.

'grid1' 노드의 Template Flag 를 선택해서 같이 보도록 한다.

'grid1' 노드의 Template Flag 를 선택해서 같이 보도록 한다.

 

'attribwrangle1' 노드의 VEXpression 란에 다음과 같이 VEX 를 입력한다.

VEXpression 칸에 입력하는 동안은 결과를 볼수 없다. 마우스 커서를 VEXpression 칸 밖으로 이동시켜 클릭해야 입력된 VEX 가 적용된다. 바로 결과를 볼 수 있는 단축키는 Ctrl + Enter 이다.

VEXpression 칸에 입력하는 동안은 결과를 볼수 없다. 마우스 커서를 VEXpression 칸 밖으로 이동시켜 클릭해야 입력된 VEX 가 적용된다. 바로 결과를 볼 수 있는 단축키는 Ctrl + Enter 이다.

 

그 결과, 스피어의 위치가 그리드 0번 primitive의 중심점으로 옮겨진다.

primitive 번호를 확인할때는 씬뷰 오른쪽 바에 있는 display primitive numbers 아이콘을 클릭한다.

primitive 번호를 확인할때는 씬뷰 오른쪽 바에 있는 display primitive numbers 아이콘을 클릭한다.

 

이제 VEX 코드를 한문장씩 차근차근 보도록 하자.

 

vector pos = prim(1, "P", 0);

prim() 함수 첫번째 인자로 쓰인 1은 'attribwrangle1' 노드의 인풋번호를 뜻한다.

인풋번호는 0부터 시작하므로 1은 두번째 인풋인 'grid1' 노드를 말한다.

즉, 어트리뷰트를 참조할 대상이 그리드인 것이다.

 

두번째 인자 "P" 는 그리드가 가진 어트리뷰트들 중, 위치값(P) 을 참조한다는 뜻이다.

이때 다음과 같은 차이점을 구분하도록 한다.

참조하는 대상이 point인 경우, 어트리뷰트 P는 해당점의 위치값을 나타낸다.

참조하는 대상이 primitive인 경우, 어트리뷰트 P는 해당면의 중심점을 나타낸다.

세번째 인자는 그리드 81개의 면들중 0번 primitive의 P 값을 돌려달라는 뜻이다.

그리고 이 리턴값을 'pos' 라는 vector 타입 변수 에 할당하였다.

참조하려는 어트리뷰트(P) 가 벡터이므로 변수 'pos' 의 타입도 vector 로 정해준 것이다.

 

@P = pos;

스피어의 위치 'P' 어트리뷰트 값에 위에서 만든 'pos' 변수를 대입했다.

이와 같이, 변수는 VEX 안에서 원할 때마다 불러져 쓰일 수 있다.

결과적으로 스피어는 그리드 0번 primitive 중심점에 위치하게 된다.

 

VEX 코드를 다음과 같이 고친다.

prim() 함수 세번째 인자에 0 대신 @Frame 을 넣었다.

vector pos = prim(1, "P", @Frame);
@P = pos;

 

@Frame 은 후디니에서 지정된(Reserved) 어트리뷰트들 중 하나이다.

@Frame 은 글로벌 변수 $F 와 똑같이 현재 프레임 번호를 리턴한다.

이처럼 함수 인자에 고정이 아닌 변하는 수(@Frame) 가 쓰이면 그 함수가 리턴하는 값도 변하게 된다.

 

플레이를 해 본다.

다음과 같이 스피어가 그리드 각 면의 중심점을 차례대로 옮겨 다닌다.

 

그 원리는 다음과 같다.

Frame 1 에서 스피어 위치 = 그리드 (@Frame)번 면의 P = 그리드 1번 면의 중심점
Frame 2 에서 스피어 위치 = 그리드 (@Frame)번 면의 P = 그리드 2번 면의 중심점
Frame 3 에서 스피어 위치 = 그리드 (@Frame)번 면의 P = 그리드 3번 면의 중심점
...
Frame 80 에서 스피어 위치 = 그리드 (@Frame)번 면의 P = 그리드 80번 면의 중심점
현재 그리드의 마지막 primitive 번호가 80이기 때문에 Frame 81부터는 참조할 수 있는 면이 없게된다. 이 경우 prim() 함수는 0 을 리턴하기 때문에 스피어는 원점에 위치하게 된다.