Posted: December 15, 2017
Version: Houdini 16
For-Each Loop 이란?
Loop 은 컴퓨터 프로그래밍에서는 어떤 일을 반복적으로 수행한다는 용어이다.
Geometry 레벨에서는 두 가지 Loop 방식을 지원한다.
1. For-Each Subnetwork
이 한개의 Subnet 안에 있는 노드들은 모두 반복된다.
이 방식은 Houdini 16.5 부터 없어지기 때문에 이번 강좌는 두번째 방식으로 진행한다.
2. For-Each Loop
For-Each Loop 방식은 두 개의 기본적인 SOP 노드를 만든다.
Block Begin SOP - Loop 블럭이 시작되는 곳이다.
Block End SOP - Loop 블럭이 종료되는 곳이다.
이 둘 사이에 연결되는 노드는 무조건 그 기능을 반복 수행한다.
For-Each Loop 특징
For-Each Loop 방식은 반복하려는 대상(For-Each) 에 따라 세 가지로 나눌 수 있다.
1. 지오메트리 요소 에 근거한 Loop
인풋 지오메트리의 각 Point 또는 Primitive 별로 반복한다.
총 반복횟수는 Points 또는 Primitives 총 개수가 된다.
2. 어트리뷰트 값에 근거한 Loop
인풋 지오메트리의 Point/Primitive 어트리뷰트에 따라 반복된다.
총 반복횟수는 서로다른 어트리뷰트 값들의 개수가 된다.
3. 단순한 횟수에 근거한 Loop
특별히 반복하려는 대상없이 원하는 횟수만큼 반복한다.
밑의 예제에서는 위 3가지 중 1번, 2번만 다루기로 한다.
For-Each Loop 예제 A
지오메트리 요소인 Point/Primitive 별로 반복 작업을 할 수 있다.
여기서는 Primitive 에 따라서 Looping 해보자.
후디니를 열고 /obj 에 그리드 지오메트리를 하나 만든다.
만들어진 'grid1' 노드를 더블클릭하여 Geometry 레벨로 들어간다.
안쪽에 있는 'grid1' 노드의 파라미터는 기본값을 유지한다.
현재 이 그리드는 81개의 Primitives 를 가지고 있다.
이제 For-Each Loop 으로 각 면의 사이즈를 변화시켜 보자.
TAB 메뉴로 For-Each Loop 을 선택한뒤, 만들어진 두개의 노드를 다음과 같이 연결한다.
연결하자마자 에러가 발생한다.
'foreach_end1' 노드의 Piece Attribute 옵션이 기본적으로 켜져있다.
이 옵션은 어트리뷰트 값에 따라서 Looping 하는 기능이다.
이 옵션은 두번째 예제에서 다루기 때문에 여기서는 끄도록 한다.
에러가 사라지고 씬뷰에는 그리드가 다시 나타난다.
그리드에는 별다른 변화가 없는듯 하다.
사실 이 그리드는 이미 Looping 이 일어난 후의 결과물이다.
즉, Looping 블럭안에서 각 면마다 차례대로 처리되어 합쳐진 것이다.
변화를 주기위해 TAB 메뉴로 Transform SOP 을 한개 만든다.
만들어진 'transform1' 노드를 다음과 같이 연결해 준다.
'transform1' 노드의 파라미터를 다음과 같이 수정한다.
Pivot 속성은 Transform 을 적용할 중심점을 가리킨다.
$CEX/$CEY/$CEZ 는 로컬변수 로서 인풋 지오메트리의 센터 위치를 X/Y/Z 축별로 돌려준다.
즉, Loop 안에서 각 면마다 반복될때 이 변수는 각 면의 센터점을 그 데이터로 갖는다.
Uniform Scale 속성은 Pivot 을 기준으로 X/Y/Z 동일한 비율로 사이즈를 조절한다.
결과적으로 그리드의 각 Primitive 가 그 중심점을 기준으로 사이즈가 20% 줄게 된다.
그리고 총 반복횟수는 Primitives 개수 81이 된다.
이제 'foreach_end1' 노드의 파라미터를 자세히 들여다 보자.
Iteration Method 속성은 반복(Iteration) 방식을 결정한다.
지금과 같이, 지오메트리 요소별로 반복할 때는 By Pieces or Points 를 선택한다.
그리고 Piece Elements 속성에서 반복할 요소를 결정한다.
현재 각 면마다 반복하므로 Primitives 를 선택한다.
마지막으로 Gather Method 속성에서 반복한 조각들을 어떻게 처리할지를 결정한다.
Merge Each Iteration 옵션은 각 조각(Each Iteration) 들을 최종적으로 합쳐(Merge) 준다.
For-Each Loop 예제 B
이번에는 Point/Primitive 어트리뷰트에 따라 Looping 해 보자.
예제 A 에서는 한번에 한개의 Point/Primitive 가 반복된다.
예제 B 에서는 한번에 같은 어트리뷰트값을 가진 Points/Primitives 들이 모두 함께 반복된다.
우선 looping 할 때 이용할 어트리뷰트를 만들어 주자.
TAB 메뉴로 Attribute Create 노드를 만들어 다음과 같이 연결한다.
만들어진 'attribcreate1' 노드의 파라미터를 다음과 같이 수정한다.
'xpos' 이라는 이름의 Primitive 어트리뷰트를 만드는 것이다.
Value 속성에서 어트리뷰트 값으로 로컬변수 $TX 를 입력했다.
Class 가 Point 일 때, $TX 변수는 각 점의 위치값(XYZ) 중 X 값을 돌려준다.
Class 가 Primitive 일 때, $TX 변수는 각 면의 센터의 위치값(XYZ) 중 X 값을 돌려준다.
다음은 그리드를 Top View 에서 본 그림이다.
맨 왼쪽 열에 있는 9개의 면들은 동일한 xpos 값(약 -4.5) 이 된다.
맨 오른쪽 열에 있는 9개의 면들도 동일한 xpos 값(약 +4.5) 이 된다.
이번에는 'foreach_end1' 노드의 Piece Attribute 옵션을 켜주자.
어트리뷰트 기본값으로 있는 'name' 대신 'xpos' 을 입력한다.
이제 xpos 값이 같은 면들은 각 반복횟수마다 다같이 처리된다.
'transform1' 노드의 $CEX/$CEY/$CEZ 변수도 각 열(9개의 면) 마다 데이터를 달리한다.
즉, Loop 안에서 각 열마다 반복될때 이 변수는 각 열의 센터점을 그 데이터로 갖는다.
결과적으로 9개의 면으로 이루어진 각 열이 그 중심점을 기준으로 사이즈가 20% 줄게 된다.
그리고 총 반복횟수는 열의 개수인 9가 된다.
이와 같이 For-Each Loop 은 중간과정은 숨기고 looping 이 끝난 최종 결과물만 보여준다.
'foreach_end1' 노드의 Single Pass 옵션을 켜 준다.
이 옵션은 반복횟수마다 처리되는 Points/Primitives 를 개별적으로 디스플레이 한다.
Single Pass 속성값을 1만큼씩 차례대로 올려보자.
반복횟수마다 처리되는 조각들이 올바른지 확인할 수 있다.