직조(織造)알고리즘 (The Loom Algorithm)

본 번역은 원작자인 Zubin M Khabazi 와의 합의에 의해 이루어진 일입니다. 번역과 동시에 연재의 형식으로 포스팅 될 것입니다. 번역이 모두 끝나면 pdf 형식으로 합본을 배포하게 될 것입니다. 번역에 모자라는 부분이 있다면 댓글 형식으로 수정을 제안해주시기 바랍니다.

 

알고리즘을 시작하기에 앞서 전반적인 과정과 이에 필요한 data들을 살펴보도록 하자. 먼저 알고리즘의 input이 될 NURBS곡면이 있어야 한다. 이 위에 날실은 U 방향으로, 씨실은 V방향으로 생성될 것이다. 이 날실과 씨실들은 싸인 그래프의 곡선과 같은 형태를 가질 것이며 이러한 곡선을 그리기 위해서는 그것의 인풋이 되는 점들이 필요하다. 이 점은 번갈아가며 면의 위 아래로 이동하여 연결될 것이며 이때 점이 이동하는 방향으로는 각 점에서 input surface가 가지는 법선벡터와 그 반대 방향을 취할 것이다.

 

  1. 날실이 면 위의 점에서 시작한다면 그 옆의 날실은 면 아래의 점에서 시작해야만 한다. 이는 씨실도 마찬가지이다. 그래야만 파동형의 선이 번갈아가서 생기며 교차하며 면을 만들 수 있다.

 

  1. 면 위의 한 점을 이동시킬 때 법선의 방향으로 +A 만큼 이동시킨 점을 날실이 지난다면 –A 만큼 이동시킨 점은 씨실이 지나야 한다. 혹은 이 반대가 되어야만 면을 생성시킬 수 있다.

 

위와 같은 개념에 기초하여 Grasshopper에서의 알고리즘은 다음과 같이 생성될 수 있다.

Fig.2 4 위에서 언급한 것처럼 알고리즘을 시작하기 위해서는 먼저 결과물의 전체적인 형상을 결정할 ‘NURBS 곡면’이 필요하다. 이를 위해서 <surface>를 이용하여 Rhino상의 곡면을 Grasshopper에 연결시켜 준다. 이것의 이름을 <Target_surface>로 변경하였다.
 
 

Fig.2 5 <Subdivide>를 이용하여 <Target Surface>를 원하는 씨실과 날실의 수만큼 나누어 준다. 이 때 <input>이 되는 수를  <number slider>를 이용하여 입력하여 주자.[1] <Subdivide>을 이용하면 면이 UV수로 나눠져서 생긴 점(P: point)들과 그 점들에서 생긴 면들의 법선(N: normal) 그리고 각 점들의 UV 좌표값(UV: UV coordinates)을 얻을 수 있다.[2]
 
 

Fig.2 6 위에서 언급한 것처럼 파동형의 날실과 씨실을 만들기 위해서는 면에 생성된 점들을 면의 아래 위로 이동시켜야 한다. 이를 위해서는 같은 절대값을 가지는 음수와 양수가 하나씩 생기는 수의 data list가 필요하다.  <F1:-x>을 이용하여  <corrugation_height>에서 나오는 값을 음수로 만든 뒤 이 둘을 <weave>에 연결해주면 두 값을 하나의 data list로 묶어줄 수 있다.
 
 
 

2_3_1_날실의 생성(Warp Generation).

 

Fig.2 7 날실의 생성(Warp Generation). <Repeat>은 말 그대로 이것에 입력되는 data를 반복하여 생성해주는 것이다. <weave>에서 나오는 양수와 음수의 data list를 연결하여 이것을 씨실(weft)의 수만큼 반복 생성시켜주자. (날실을 생성하는데 사용되는 점의 수는 씨실의 수와 일치하기 때문이다.) 이 값을 <amplitude>를 이용하여 각 점이 가지는 법선(normal)값과 data matching을 시켜준다. <amplitude>는 ‘벡터(V: vector)’에 입력벡터를 ‘강도(A: amplitude)’에 입력된 값만큼의 크기로 변환해준다. 이것을 <move> 연결하면 면 위의 점들 원하는 만큼 이동시켜 줄 수 있다. <repeat>에서 나오는 값을 <F1: -x>를 이용하여 변환시킨 뒤 또 하나의 <amplitude>와 <move>에 입력시켜준다.
 
 

Fig.2 8 모든 점들이 면의 아래 위로 이동한 것을 확인할 수 있다. 이 때 두<move> 중에 하나를 선택하면 점이 어떻게 이동하였는지를 확인할 수 있다. 두 <move>가 각기 따로 아래 위로 점을 이동시켰다.
 
 

Fig.2 9 이렇게 <move>가 된 점들을 <interpolate curve>에 연결하면 같은 위치에서 mirror된 것처럼 보이는 곡선을 생성할 수 있다. 이제 이 두 선들을 <cull>을 이용하여 하나씩 번갈아서 선택하여 주자.
 
 

Fig.2 10 이 때 주의해야 할 것은 <interpolate curve>에서 생성된 data list는 트리구조를 가지고 있다는 것이다. 이를 <Param Viewer>를 통하여 확인할 수 있다. <cull>을 하기 위해서는 이 data list의 트리구조를 없애고 모든 data를 하나의 list 안에 정렬시켜주어야 한다.[3] 이러한 기능을 가진 것이 <flatten>이다. 이제 <cull>에 입력되는 Boolean data의 패턴(P: pattern)을 편집하여 주자.[4]
 
 

Fig.2 11 완성된 ‘날실의 생성(warp generation)’ 알고리즘

 
 
 

2_3_2_씨실의 생성(Weft Generation)

 

Fig.2 12 이 다음으로는 씨실을 생성해줘야 한다. <Subdivide>에서 생성되는 data가 U방향으로 생성되므로[5] 씨실을 생성하기 위해선 이것의 방향을 V방향으로 바꿔줘야 할 필요가 있다. 여기서는 이러한 문제를 해결할 수 있는 방법 중 가장 쉬운 것을 소개하겠다. 먼저 rhino상에서 그려진 <Target_Surface>를 같은 위치에 복사에 넣은 뒤 이것의 UV 방향을 바꿔주면 된다. 이를 하기 위한 과정은 다음과 같다.
 
1. <Target surface>를 선택한다.
 
2. 아래와 같은 순서로 명령어를 입력해준다.
 

      Copy (enter)

      I (enter)

      Dir (enter)

      S (enter)

      (enter)

 
이는 먼저 선택된 surface를 복사(copy)한 뒤 같은 위치에 (i) 만들어주고, 이것의 UV방향을 돌려준(s: swapping)해준 것이다. 이러면 같은 surface의 UV 방향만을 바꿔줄 수 있다.
 
3. 이제 이렇게 생성된 rhino상의 surface를 Grasshopper에서 <surface>와 연동시킨 뒤 <Swap: UV_Target_surface>로 명명해준다.[6]
 
 

Fig.2 13 여기서 또한 surface가 <subdivide> 된다. 이 때 <swap: UV_Target_surface>는 <Target_surface>의 UV 방향을 바꾼 것이므로 <subdivide>의 U(U: u direction)에 씨실(weft)의 수를, V(V: V direction)에 날실(warp)의 수를 연결시켜주어야 한다. 나머지 알고리즘은 ‘날실의 생성(Warp Generation)’ 알고리즘과 일치한다.
 
 

Fig.2 14 씨실과 날실의 생성에 사용된 알고리즘은 모두 같다.
 
 

Fig.2 15 이때 <cull>의 P에 입력되는 Boolean data를 위와 같이 바꿔주자. 모든 설정을 마치면 왼쪽 그림과 같은 결과를 얻을 수 있다.
 
 

Fig.2 16 이제 거의 마지막이다. <number slider>를 이용하여 이렇게 생성된 씨실과 날실의 곡선들에 적용할 두께 값을 설정해주자. 이것을 <Yarn_Thickness>로 명명하였다.
 
 

Fig.2 17 <cull>에 의해서 솎아낸 씨실과 날실의 곡선들을 모두 <pipe>에 연결해주자. 물론 씨실과 날실을 각각 다른 <pipe>에 연결하여 다른 두께 값을 주는 것이 가능하다.
 
 


Fig.2 18 직조 알고리즘을 이용한 Digital Textile의 생성 ‘평직(平織: plain weave)’,
 
 


[1] 역자 주: 해당 tutorial에 사용된 <receiver>는 0.8.0010버전 이후의 grasshopper에서는 존재하지 않는다.
[2] 역자 주: 0.8.0010버전에서는 <Subdivide>의 S를 우클릭 한 뒤 이를 ‘reparameterize’를 해야 UV 좌표값을 얻을 수 있다.
[3] 역자 주: 트리구조를 가지는 data에 관한 자세한 내용은 generative algorithm 의 5_6_On Data Trees 를 참고하기 바란다.
[4] 역자 주: P를 우클릭 한 뒤 ‘manage boolean collection’을 선택하면 Boolean data를 편집하여 줄 수 있다. 이 때 true와 false는 영문으로 입력해줄 수도 있고 false를 의미하는 ‘0’이나 true를 의미하는 ‘1’을 입력해줄 수도 있다.
[5] 역자 주: Grasshopper에서 생성되는 data는 일반적으로 U 방향으로 그 순서를 유지하며 생성된다. 이것의 방향을 바꾸기 위해선 매우 복잡한 과정을 거쳐야 하는데 이 튜토리얼에서 저자는 rhino의 input을 조절하여 매우 쉽게 이 문제를 해결하고 있다. 이처럼 어떠한 결과물을 그릴 때 rhino에서 input되는 기하체와 grasshopper에서 만들어지는 algorithm 둘을 적절하게 섞어서 만드는 것이 무척 중요하다.
[6] 역자 주: 날실을 생성하는 알고리즘을 모두 복사한 뒤 그것에서 <Target_surface>의 이름만 변경해주면 된다. 이 때 처음에 같은 절대값의 음수와 양수를 반복 생성하는 <F1: -x>과 <weave>는 공유하여 씨실과 날실이 같은 진폭(amplitude)를 가질 수 있도록 하자.

Generative Algorithm 040

두께 주기(Generating Ribs)


이렇게 재배열 된 section curve들에 뭔하는 만큼의 두께를 주도록 하자. 먼저 <offset>을 이용하여 curve를 원하는 만큼 <offset> 시킨다. 원래 curve와 <offset> 된 curve의 각 양끝을 찾은 뒤 이것에 <line>을 더하여 이어준다. 이러면 원하는 두께를 가진 구조체가 완성된다. 위와 같은 과정을 다른 방향으로 생성한 section curve에도 적용시켜 준다.

Generating Joints (Bridle Joints)

다음 단계로는 이 구조체들이 서로 얽힐 수 있도록 교차되는 부분을 반씩 파주는 것이다. 

여기서 사용된 다른 방향의 plane은 위에서 그린 plane이 아닌 저자가 새롭게 따로 그린 plane 이다. 이 plane이 input surface와 만나며 curve를 생성하게 된다. [1] 는 의 원점이 되는데 이때의 x 좌표는 를 통해 input 해준다. 다른 는 의 결과값을 x 좌표로 가지게 되는데 이 에 input에 되는 x는 에서 나오는 값이고 y는 의 x방향 길이인 값이다. 이렇게 하면 두 이 에 따라 대칭(mirror)된 형태를 가지게 된다. 이 두 을 에 연결하여 section curve를 얻도록 하자.

이 section curve와 위에서 그린 curve가 교차하는 점을 찾기 위해서는 (Intersect > Physical > Curve | Curve)를 사용하면 된다. 이때 data matching의 방식은 ‘cross reference’로 해주면 된다. 이제 이 교차점을 이용하여 재배열한 curve들 위에 bridle joint를 그려보자

<CCX>를 보면 point 뿐만 아니라 tA와 tB가 있는 것을 알 수 있다. 이는 각 curve 위 교차 point의 parameter를 내보내는 것이다. 이것을 <evaluate curve>의 T에 연결하고 재배열 된 curve들을 C에 연결하면 해당하는 위치의 point를 재배열 된 curve 위에 찾아줄 수 있다. 즉 이 경우 point는 <orient>가 아닌 <evaluate curve>를 이용해서 찾아 준 것이다.

이제 이점으로부터 시작되는 line을 그려보자. 이 때 사용할 수 있는 것은 <line SDL>이다. 이는 S: Start point, D: Direction, L: Length를 input으로 가진다. <unit Y>를 방향에 연결하고 <offset>에 사용한 값을 <f2: x/2>를 이용하여 L에 연결하여주자.

이렇게 그려진 line에 <end point>를 이용하여 찾은 끝점을 찾아주자. 이것에 다시 <line SDL>을 연결하여 X 방향으로 line을 그려준다. 이 길이는 <sheet_thickness>가 된다.

이제 이 X방향으로 그려진 line의 끝점에서 처음 시작했던 curve로 돌아가보자. 먼저 <end point>를 이용하여 끝점을 찾아준다. 여기에 <line SDL>을 연결해주자. 이 때 line의 방향은 Y의 반대방향이므로 <unit Y>와 함께 음수를 L에 연결해주면 된다. 길이의 경우 정확한 길이를 알 수 없으므로 일단 충분히 긴 line을 그린 뒤 이것의 교차점을 찾아주자. 이번에는 line과 curve의 교차이므로 <CLX>(Intersect > Mathematical > Curve | Line)을 이용하면 된다. 이 point는 tree 구조를 가지고 있게 되는데 이를 <flatten>을 이용하여 data list로 바꿔주도록 하자.
위에서 X방향으로 그린 선의 end point와 방금 전에 찾은 교차point를 각 시작과 끝으로 하는 line을 그려주면 된다.

이제 <joint curves>(Curve > Util > Join curves)를 이용하여 각 line을 join 시켜주자.
위를 똑같이 다른 쪽의 점에도 적용시켜 준다.

Labeling

fabrication으로 넘어가기에 앞서 각 부재들에 labeling을 해보자. 잘라야 할 것이 수백 개에 이른다면 부재를 구분하기 위해서라도 꼭 labeling을 해주는 것이 좋다. 이때 label은 조립의 순서에 따르는 것이 좋다.
Label은 수와 text의 조합으로 이루어질 것이다. 즉 하나의 열에 여러 개의 부재들이 있다고 했을 때 left_wing_01 과 같은 방식으로 labeling을 할 수 있다.
이 예제에서는 일련의 수를 적용하여 각 부재의 위치를 표시해보도록 하자. <text tag>의 input으로는 label이 표시 될 frame과 표시할 text의 내용, 그리고 text의 크기가 있다.

각 방향의 부재의 수는 section curve를 <orient>하는데 사용했던 frame과 그 수가 일치한다. (위에서 선택된 component가 바로 우리가 <orient>에 연결하였던 frame의 list 이다.) 이 plane의 개수를 <list length>를 이용하여 찾은 뒤 그 수를 <series>의 C에 연결해준다.

여기서 나오는 수의 data list를 <text tag>의 T에 연결해주자. 이 때 <integer>는 수에 붙어있는 .0을 없애주는 역할을 한다. 즉 수가 12.0 인 경우 이것을 12로 바꿔주는 것이다.
부재의 list를 <text tag>의  L에 그대로 연결하면 label들이 각 부재의 꼭지점에 있는 frame의 중심에 표시되게 된다. 그러므로 이 전에 frame을 이동시키고 이것을 꼭지점에 있는 plane을 X 방향으로 1만큼, Y 방향으로 0.5 만큼 이동시켜보자. 이 경우 <sum> 을 이용하여 두 vector를 합한 뒤 <move>에 적용하였다. 이것을  <text tag>의 L에 연결시켜주면 된다.

이제 부재들이 그려지는 surface를 바꿔가며 부재들을 그려주면 된다. 이때 재료를 낭비하지 않도록 주의하자. 위 그림의 경우 sheet_3에서 부재의 일부가 sheet의 끝에 닿는다는 것을 알 수 있다. 이것을 조절해주기 위해 Grasshopper의 algorithm을 바꿀 수도 있다. 하지만 이것을 bake 한 뒤 Rhino에서 자르기 전에 이동시켜주는 것이 더 간단하다. 즉 어떻게 작업을 하는 것이 더 쉬울지를 잘 판단하는 것이 중요하다.

자르기(Cutting)

모든 준비가 끝났으면 이제 curve를 bake 한 뒤 부재를 자를 준비를 해보자. 아래에서 보이는 것 처럼 모든 부재를 재료의 사이즈와 양에 맞춰 잘 배열해보자. 이제 laser cutter를 사용할 준비가 모두 끝났다.

<a

조립(Assembly)

이 예제의 경우 부재의 조립은 어렵지 않다. 3d model과 비교해가며 조립하면 조립 순서와 부재의 위치를 쉽게 찾을 수 있을 것이다. 조립이 끝나면 종이를 이용하여 만든 surface가 완성될 것이다.

완성된 model

완성된 model

잘려진 부재, 조립할 준비가 되었다


 Fabrication을 잘 하기 위해서는 여러 가지 측면을 고려해야 한다. 어떠한 형상이어야 하는가, 어 떠한 재료를 사용해야 하는가, 어떤 제작도구를 이용하는가, 어떻게 조립할 것인가 등의 여러 사항에 따라 그 결과물이 달라질 수 있기 때문이다. 또한 project에 따라 fabrication에 필요한 data를 잘 추출해내는 것이 중요하다. 특히 결과물이 복잡한 기하체라면 조립의 규칙을 먼저 생각해보는 것 또한 무척 중요하다.

조립 방식; 흔한 재료와 간단한 joint로 제작하였지만 재료가 어떻게 만나는가와 점의 위치 data가 없다면 모형을 원하는 대로 제작할 수 없을 것이다.


 
 

이로서 Generative Algorithm의 연재를 마칩니다.
곧 pdf 합본으로 업로드할 예정입니다.
감사합니다.

 


 
[1] 이 전에 저자가 언급한 바는 없지만 위의 그림에서 보시다시피 top view에서 본surface의 왼쪽 아래 코너의 x, y좌표는 0이다. 만약 surface를 다른 곳에 그렸을 경우 이를 위의 그림에 맞게 옮기면 된다.
 

Generative Algorithm 039

8_2_Laser Cutting and Cutting based Manufacturing

 
복잡한 형태를 가진 3d model을 Laser cutter 가공이 가능하도록 만들어보자. Laser cutter를 이용하면 특히 가전면(developable surface)을 가진 모형이나 여러 면을 가진 접어서 만들어야 하는 모형(folded ones)을 제작할 때 매우 편리하다. Digital model에서 연결된 면들을 하나의 면이 되도록 편 뒤(unfold) 그 형태에 맞춰 모형재료를 자르고 다시 접거나 말아서 붙이는 방식으로 모형을 제작할 수 있기 때문이다. 즉 digital model의 면을 평평한 면의 단위로 분리하여 자른 뒤 이것을 다시 붙여가며 조립해가는 것이다. 복곡면(Double curved surface)의 경우도 위와 같은 방법으로 제작이 가능하다. 방울과 같은(blobby) 형태를 만들 경우에는 먼저 면을 두 방향으로 연속하는 section을 나눈 뒤 이 모양에 따라 재료를 자르고 다시 Bridle joint[1]등을 이용하여 격자형으로 조립할 수 있다.
즉 laser cutter란 판형재료를 가공할 수 있는 도구라는 것이다.  어떠한 형상이라도 연속하는 section과 같이 평평한 면으로 해석해내면 그 모형을 제작할 수 있다. 이때 재료는 종이, 금속, cardboard, 나무 등 무엇이든 가능하다.
이제부터 grasshopper를 이용하여 주어진 곡면을 sectioning을 이용하여 평평한 면으로 해석해보도록 하자.

Rhino에서 원하는 형상을 가진 surface를 그리자. 그리고 이 surface를 <geometry>를 이용하여 Grasshopper와 연동시킨다.
 

단면으로 해석하기(Ribs as Sections)

 
이 free-form surface의 모형을 제작하기 위해서는 먼저 면의 단면을 추출한 뒤 이것을 모형재료의 크기와 맞는 평평한 surface 위에 다시 그리도록 하자. 이때 Rhino에서 그려진 surface에는 두께가 없으므로 원하는 두께는 따로 설정해줘야 한다.

Sectioning을 하는데 사용되는 원리는 바로 면과 연속하는 평면을 교차시켰을 때 생기는 ‘curve를 사용하는 것이다. 먼저 <bounding box>를 이용하여 우리가 가공하고자 하는 3d model을 감싸는 최소한의 box를 구한다. 여기에 <box corners>(Surface > Analysis > Box corners)를 이용하여 이box의 각 꼭지점들을 추출하고 이중 두 끝을 잡아 각각 XZ plane과 YZ plane을 생성한다. 이제 이것을 가로와 세로 방향으로 이동시켜야 한다. 이를 위해 사용 되는 것이 <distance>와 <range> 이다. <distance>는 위에서 생성된 두 plane이 각각 y방향과 x 방향으로 이동하는데 사용되는 거리의 범위가 된다. 이것을 <range>를 이용하여 N만큼 나누어서 생기는 data list의 각 위치에 plane이 이동하게 된다.[2]

즉 주어진 면을 감싸고 있는 bounding box의 x와 y방향의 모서리의 길이와 꼭지점 하나를 추출한다. 이 꼭지점에 XZ plane을 생성하여 Y방향으로 연속 이동 시키고 YZ plane을 생성하여 X 방향으로 연속해서 이동시킨다. 이제 이 plane 들이 처음 연동시킨 surface와 교차되는 부분을 추출하면 우리가 원하는 section을 얻을 수 있다. 이 때 section의 개수는 <number slider>이용하여 N 값을 조절해주면 우리가 원하는 만큼 조절해줄 수 있다.

Plane의 원점(Origin)과 각 XY 방향은 위와 같이 frame으로 표시되게 된다. 위 그림에서 볼 수 있는 것처럼 각 frame들은 모서리에 수직방향으로 생기게 된다.

이제 이 plane들과 surface가 교차(intersect)하는 부분을 찾아보도록 하자. 이 경우 surface(Brep)과 plane이 교차하는 것이므로 intersect component 중 <Brep | Plane intersect>(Intersect > Mathematical > BRep | Plane) 를 사용하면 된다. 즉 두 개의 <Brep | Plane Intersect>를 만든 뒤 이 둘의 Brep에 처음 surface를 연동시킨 <geometry>를 연결시켜 준다. 또한 이 전 단계에서 얻어진 X방향으로 연속된 plane과 Y방향으로 연속된 plane들을 P에 연결시켜주면 된다.

이것의 결과물은 위에서 보는 것과 같이 각각 X, Y 방향으로 연속되는 curve이다.

Section 배열하기 (Nesting)

다음 단계는 바로 위에서 얻어진 curve들을 평평한 평면 위에 배열하는 것이다. 이것은 이 후 laser cutter를 이용하여 재료를 자르는데 사용될 것이다. 아래 그림과 같이 재료와 같은 크기를 가지는 직사각형의 Surface 을 그린다. 그리고 이 surface를 아래와 같이 연속하여 배열시킨다.

이제 <Orient>(XForm > Euclidian > Orient)를 이용하여 위에서 얻은 curve를 위 surface 위에 그려보자. <Orient>는 먼저 방향을 바꿀 G: geometry와 이동의 기준으로 사용 될 A: reference plane, 그리고 이 geometry가 이동되어 그려질 대상이 되는 B: target plane으로 이루어진다. 먼저 <Orient>에 G는 위에서 <Brep | Plane Intersect>에서 나오는 Curve가 될 것이고 A: reference plane은 위에서 section curve를 얻기 위해서 사용했던 plane들을 사용할 수 있다. 이제 target plane을 만들어보자.

먼저 위에서 그린 직사각형의 surface를 <surface>를 이용하여 Grasshopper와 연결시킨다. 이것에 <Surface Frame>(Surface > Util > Surface Frames)을 연결하도록 하자. 이것은 면 위에 UV 방향으로 우리가 원하는 수 만큼의 frame (plane의 원점과 방향이 표시된)을 생성할 수 있다.

<surface frame>에 생기는 frame의 개수는 U,V에 입력되는 수를 통하여 조절할 수 있다. 이 때 주의해야 할 것은 U에 1을 입력하더라도 이 방향으로 생성되는 frame은 총 2열이라는 것을 알 수 있다. Surface를 U 방향으로 1로 나누는 것이기 때문에 시작인 0과 끝이 1에 각각 frame이 생성되기 때문이다.[3] 즉 우리가 필요한 것 보다 더 많은 수의 frame이 생기게 된다. 이를 위해서 우리가 필요한 수만큼의 plane을 골라내어야 한다. 이 때 사용 가능한 것이 <split>이다. 이것은 L을 통하여 data list가 들어올 때 i: integer에 입력되는 수 만큼의 data 를 A로, 그 나머지를 B로 내보내주는 역할을 한다. 먼저 <Brep | Plane Intersection>에서 나오는 C의 개수를 <list length>를 이용하여 찾아준다. 이것을 split의 i에 연결시키면 우리가 원하는 수 만큼의 plane을 취할 수 있다. 또한 section이 surface의 모서리와 닿는 것을 방지하기 위하여 X방향으로 1만큼 이동시켜 주었다.

위의 algorithm의 결과물로 위처럼 curve들이 cutting sheet에 그려졌다.
 
 
 


 
[1] http://en.wikipedia.org/wiki/Bridle_joint
[2] 예를 들어 X방향으로의 길이가 50이라고 했을 때 이 길이를 <range>의 D에 넣고 N에 4를 넣으면 (0.0, 12.5, 25.0, 37.5, 50.0) 이라는 data list가 생긴다. 이는 현재 0.0에 위치하는 YZ plane이 12.5, 25.0, 37.5, 50.0 에도 생기게 되는 것을 의미한다.
[3] 이 때 주의할 점은 0.8.0004build에서는 <surface frame>에서 나오는 frame이 tree data의 형태로 나온다는 것이다. 즉 <surface frame>과 <split>사이에 <flatten tree>를 사용하면 위와 같은 결과를 얻을 수 있다.
 

Generative Algorithm 038

Exporting Data


위에서 길이 값을 표시해주는 <panel>을 우클릭 한 뒤, ‘stream contents’를 선택해준다. 이것은 panel이 가지고 있는 정보를 다른 format의 수치data로 변환시켜준다. 여기서는 이것을 .txt 로 저장하였다. 이제 이 정보를 excel에서 불러와보자.

Excel sheet을 연 뒤 빈 cell을 클릭하고 ‘Data’ tab의 ‘Get External Data’,  ‘From text’ 에서 위에서 저장한 text file을 불러와준다.

이제 excel data sheet에 저장된 data를 볼 수 있다. 위와 같은 작업을 나머지 정보에도 똑같이 사용해준다.

각curve위의 점들의 길이값이 정리되었다.


만약 여러 점들의 3d 공간좌표가 있다고 했을 때 이것의 좌표값들 또한 excel로 불러내줄 수 있다. 만약 이것의 좌표값을 그대로 불러오면 Comma나 bracket등을 일일이 지워야 한다. 이 때 excel의 옵션을 이용하여 위와 같은 정보를 다른 colomn에 붙여넣은 뒤 이것을 지워도 되지맘ㄴ 이 경우 data의 정렬이 흐트러질 수 있다.
이 때 사용 가능한 방법은 애초에 각각의 x,y,z 좌표값을 따로 불러오는 것이다.

<decompose point>를 이용하면 X,Y,Z값을 따로 data sheet에 정리해줄 수 있다.
이처럼 Excel의 고급 기능을 잘 활용하면 우리가 가진 data를 manage 하기 훨씬 쉬워진다.
이제 위에서 얻어진 길이정보를 이용하면 아래와 같은 종이 모형을 만들 수 있다. 가끔은 AA의 EmTech 튜터 Achim Menges가 창안한 HAM(Hand Aided Manufacturing)을 활용하는 것이 좋다.[1] 저자의 경우 종이를 자르고 붙이는데 약 한 시간 정도를 사용하였다.


[1] 원 저자가 농담을 한 것인데 제가 번역을 더 잘하지 못하겠습니다.

Generative Algorithm 037

Chapter_8_Fabrication

최근 들어 computer를 이용한 제작(Computer Aided Manufacturing)과 digital fabrication이 큰 관심을 끌고 있다. 이러한 Design process의 변화와 새로운 trend는 design 영역에서 가지고 있는 기존의 생산 개념을 ‘digital fabrication’으로 바꿔놓았다. 즉 digital modeling을 통하여 design에  관한 사항들을 결정하고 다른 scale에서의 fabrication과 조합을 시험해볼 수 있게 되었다. 이러한 변화 현장에서 전통적으로 사용되었던 건설기술 뿐만 아니라 다양한 생산방식이 적용될 수 있게 하였다. 예를 들어 CNC machine은 요즘에도 사용하고 있는 새로운 생산방식 중 하나이다. 또한 이것을 가능하게 하는 다양한 기술과 생산기계들이 계속해서 발명되고 있다.
이것을 design process에 적용하기 위해서는 먼저 다양한 재료에 따른 fabrication의 과정을 간략하게나마 이해하는 것이 중요하다. 우리가 design 하려는 결과물과 재료에 따라 그것의 조립 방식(assembly logic)이나 이동(transportation), 크기(scale) 등이 달라지기 때문이다. 원하는 결과물을 얻기 위해서는 그것에 적합한 data를 생성하고 생산에 알맞은 기계를 선택하여야 한다. 이때까지의 생산이 평면, 단면, 그리고 디테일 도면에 의해서였다면 이제는 data 와 code를 통해 생산에 대한 정보를 기계에 바로 입력할 수 있기 때문이다.
중요한 점은 designer 도한 이러한 data를 다룰 줄 알아야 한다는 것이다. 이러한 것이 design의 과정과 결과에 끼치는 영향이 더더욱 커지고 있기 때문이다. Designer는 때때로 fabrication의 결과물을 참고하여 data를 재조정 하여야만 한다. 또한 design 결과물이 기계나 조립 과정에서 가질 수 있는 제약으로 인하여 변해야 할 수 있기 때문이다.
지금부터는 grasshopper를 이용하여 design과 fabrication을 통합적으로 다룰 수 있는 방법을 보도록 하겠다. 먼저 데이터 준비(data-preparation) 단계에서 해야 할 일을 살펴보고 design에서 필요한 data를 추출(extraction)하는 과정을 살펴보도록 하겠다. 이 뿐만 아니라 기술적인 내용과 이것에 사용되는 기계, 재료까지 살펴보도록 하자.

8_1_Datasheets

객체를 생성하기 위한 data로는 기본적으로 ‘치수’, ‘각도(angle)’, ‘좌표(coordinates)’ 등과 같은 수치 data가 필요하다. Grasshopper에는 이러한 객체의 치수, 객체간의 거리, 각도 등을 입력하고 추출하기 위한 여러 가지 component들이 있다. 중요한 것은 design 목적에 맞는 정보를 적재적소에 input으로 활용하는 것이다. 이를 위해서는 먼저 결과물이 되는 객체의 기하학적 생성원리를 이해하는 것이 중요하다. 그 다음으로는 제작(fabrication)을 위하여 필요한 data와 그렇지 않은 data를 구분하는 것이다. Algorithm의 과정에서 많은 data가 생성되지만 그 중에는 마지막 fabrication 단계에서 필요 없는 경우가 많다. 마지막으로 필요한 것은 3d software에서 data를 spreadsheet과 datasheet로 추출하여 우리가 원하는 방향으로 수정하는 것이다.

종이띠를 이용한 fabrication (Paper Strip Project)

이번 예시는 필자의 개인 project의 일부이다. 종이조각들이 조립되는 논리를 이해하기 위해서 먼저 실재 종이를 잘라 간단한 모델을 만들어보았다. 이러한 간단한 physical modeling은 3d model이 생성되는 논리를 쉽게 이해할 수 있고 또 향 수 발생할 수 있는 문제를 예측해볼 수 있는 과정이다. 첫 번째 종이모형의 경우 만드는 과정에서 지나치게 복잡해졌고 또 원하는 결과물이 나오지 않았다.

종이띠, 첫 번째 결과물


다음 단계에서는 digital modeling에 참고하기 위하여 좀 더 간단한 모형을 만들어 보았다.  바로 digital modeling을 시작하기 보다는, 간단한 physical model을 만들어 보면서 그릴 대상의 지하학적인 주성 원리를 이해해보는 것이 중요하다.
여기서는 세 개의 종이끈이 사용되었고, 이것의 각 끝을 연결하여 아래와 같은 모양을 만들었다. 즉 가운데 종이가 양쪽보다 더 짧은 것을 볼 수 있다. 이러한 기본 module이 조합되며 더 큰 surface를 만들어낼 것이다.

연결과 논리를 이해하기 위한 간단한 종이띠 module

Digital modelling

물리적으로 module이 만들어지는 방식을을 이해한 뒤, module을 digital tool을 이용하여 이 module을 modeling 해보자. 먼저 매우 간단한 curve를 그린 뒤 이것을 중심에 두고서 이를 일정한 간격으로 나눈다. 그 위에 생기는 점들을 한 점은 취하고, 다른 한 점은 버리는 방식으로 점을 솎아내어 준다. 이 때 취하는 점들을 중심이 되는 curve의 양 옆으로 이동시킨다. 이렇게 생성된 point들을 두 interpolated curve를 생성하는 점으로 사용한다. 마지막으로 중앙에 있는 curve와 양쪽의 두 interpolated curve를 extrude하면 종이로 만든 model과 유사한 형상을 얻을 수 있다.

중심선과 양쪽의 interpolated curve를 이용한 modeling


완성된 모델은 간단하지만 같은 크기와 형태가 계속 반복되고 있는 것을 볼 수 있다. 여기에 각 모듈의 크기를 변화시킬 수 있는 가능성을 주도록 하자. 이제 Grasshopper를 이용하여 같은 것을 modeling 해보자. 여기서 기본적인 개념을 설명하여보도록 하겠다.

중심이 되는 띠를 Rhino에서 그린 뒤 이것을 <curve>를 이용하여 grasshopper와 연결시킨다. 이 선의 길이를 나눌 때 그 간격을 일정한 것이 아닌 점점 감소하도록 해보자. 먼저 <range>를 이용하여 0과 1사이의 수를 일정한 간격으로 나눠준다. 이렇게 나온 수의 data list를 <graph mapper> (Params > Special > Graph Mapper)에 연결해주도록 하자. 여기서 graph의 종류는 pop-up menu의 ‘graph type’ 항목을 통하여 선택할 수 있다.[1] 이 값을 <evaluate curve>에 연결하면 앞서 그린 중심 curve상에 있는 점들 중에서 <graph mapper>에서 나오는 값에 해당하는 parameter를 가지는 점들을 표시해줄 수 있다. (위 경우 <receiver>가 <curve>를 <evaluate curve>에 연결해주고 있다.

이제 각 점들 사이의 중간 점을 찾아주도록 하자. 원리는 간단하다. <graph mapper>로 부터 얻어진 수들 사이의 평균값을 parameter로 하는 curve상의 점을 찾아주면 된다. 두 수의 평균은 각 수를 더한 뒤 이것을 2로 나누면 되는 것이다. 이것을 위해서는 먼저 <graph mapper>에서 나오는 data list를 더해지는 두 수중 첫 번째 값의 list 그리고 두 번째 값의 list로 나누어 주면 된다. 첫 번째 값의 list의 경우에는 마지막 수가 필요가 없으므로 이것을 버려줘야 한다. 먼저 <list length>를 이용하여 data의 개수를 찾아준다. 이 수는 마지막 번째 data의 수와 일치한다. 이것을 <cull Nth>에 연결하면 이 값에 해당하는 data를 버릴 수 있다. 더해지는 두 번째 값의 list는 원래 <graph mapper>에서 나오는 값 중 가장 앞에 있는 값을 필요로 하지 않으므로 이 수를 버려주어야 한다. 이제 이 두 data list를 <f2: (x+y)/2>로 연결하여 matching 시켜주면 각 중간점에 해당하는 parameter를 얻을 수 있다. 이 수를 다시 <evaluate curve>에 연결하여 curve상에서 중점을 찾아주도록 하자.

이제 이 중간점을 curve 의 바깥으로 움직여보자. 이때 움직이는 방향은 각 점들의 법선 방향을 취해주면 된다. 중간점들의 parameter에 연결된 <evaluate curve>의 output은 점뿐만 아니라 각 점에서의 접선 vector (tangent vector)를 얻을 수 있다.
이 때 이용할 수 있는 것이 바로 벡터의 외적(Vector Cross product)[2]이다. 이것은 두 vector가 있을 때 이 두 vector 모두에 수직으로 만나는 하나의 vector를 찾아주는 연산이다. 예를 들어서 unit Z vector는 모두 unit X vector와 unit Y vector에 수직으로 만난다. 이것의 개념은 아래 그림을 참조하도록 하자. 이 경우 각 점에서의 Z 방향 vector와 tangent vector의 cross vector product를 찾아주면 이것이 바로 각 점에 수직으로 만나는 vector가 된다. 또한 이것은 중심이 되는 curve가 속해있는 평면 위에 있게 된다. <XProd>가 바로 이러한 연산을 해주는 component이다. 이 때 <cull Nth>에서 나오는 값을 <multiplication>을 이용하여 곱해주면 <unit Z>에 입력하면 이것의 크기를 조절할 수 있다. 이 값이 클수록 <XProd>가 내보내는 vector의 크기도 늘어나게 된다. 이것을 <move>의 T에 연결하여 주자. [3]
이 때  <graph mapper>의 graph type을 바꿔주면 다양한 결과를 얻을 수 있다.

위 그림은 Vector Cross product을 설명해주고 있다.  즉 Vector A와 Vector B가 base plane을 정의하고 이 plane에 수직으로 만나는 Vector C를 찾아주는 것이다.
Vector Cross product의 개념은 위와 같다. 즉 Vector A와 Vector B가 base plane을 정의하고 이 plane에 수직으로 만나는 Vector C를 찾아주는 것이다.

이제 중심이 되는 curve 위에서 찾아줬던 point의 data list와 위에서 움직여준 중간 점을 <weaver>를 이용하여 연결하여 준다. (<weave>의 사용 개념은 위에서 살펴보았다.) 이것의 결과물을 이용하여 <interpolate curve>를 만들어 주면 위와 같은 결과를 얻을 수 있다.

다른 한 쪽은 <Mirror Curve> (XForm > Morph > Mirror Curve) 를 이용하여 그려줄 수 있다. 즉, <interpolate curve>를 중심이 되는 curve를 기준으로 mirror를 해주는 것이다. 위 그림의 <receiver>는 중심이 되는 <curve>와 연결되어 있다. G는 mirror가 되는 기하체(geometry)를 의미한다.

이제 중심이 되는 curve와 양 옆에 생긴 curve들을 Z 방향으로 <extrude> 해주면 처음에 의도했던 결과물을 얻을 수 있다.

Rhino상에서 처음 그렸던 curve를 변형시켜주면 최종 결과물의 형태를 바꿔줄 수 있다. 혹은 <number slider>를 이용하여 이것이 extrude 되는 정도를 조절해줄 수 있다.
3d modeling을 마친 뒤 여기서 찾아진 정보를 이용하여 종이띠 model을 만들어 보자. 그릴 위해선 먼저 만들어진 model의 치수정보를 추출해야 한다. 물론 laser cutter를 이용하면 아래와 같은 내용 없이도 physical model을 만들 수 있다. 하지만 위에서 일반화된 data를 추출하면 단지 한 종류의 기계나 하나의 방식에 의존하지 않아도 된다.
먼저 중심이 되는 종이띠와 왼쪽과 오른쪽 종이띠 모두 다른 길이를 가지고 있는 것을 볼 수 있다. 그리고 이것들이 각각 만나는 지점이 다르다. 각 길이를 계산하고 이 지점을 각 종이 띠에 표시하여주면 이것을 이용하여 정확한 physical 모델을 만들 수 있다. 이제 grasshopper를 이용하여 이러한 길이정보와 접점의 위치정보를 추출하도록 하자.
이 경우 우리는 curve를 가지고 작업을 하였으므로 그 치수를 찾는데<distance>는 도움이 되지 않는다. 각 접점들이 펼쳐진 curve 위에서 위치하는 지점을 찾아줘야 하기 때문이다.
위에서 작성한 algorithm으로 돌아가 필요한 정보를 찾아보도록 하자.

위 그림에서 볼 수 있는 것처럼 <evaluate curve>의 L은 각 점들이 선위에서 시작점으로부터 가지는 길이정보를 보여준다. 위 그림에서 가장 위쪽에 있는 <evaluate curve>의 경우 처음 입력된 중심이 되는 <curve>와 연결되어 있으며 각 점들이 시작점으로부터 떨어진 길이를 보여주고 있다. 오른쪽에 있는 <evaluate curve>의 경우 조금 다르다. 이는 <interpolate curve>의 input으로 사용된 점을 그것의 결과물인 curve와 <curve closest point>를 통해 data matching을 하여 각 점의 길이를 찾아준 것이다. 즉 curve 위에 점을 다시 올려놓은 뒤 이것의 parameter를 추출하고 이것을 다시 <evaluate curve>에 연결하여 각 점들이 가지는 길이 정보를 찾아준다. 이것을 다른 쪽 curve에도 똑같이 적용시켜준다.
이 때 중심이 되는 curve와 두 interpolate curve의 방향이 같도록 해줘야 한다. 즉 이 세 curve가 가지는 시작점의 위치(길이 계산의 기준점)이 같아야 하는 것이다.
 
 


 
[1] 이 경우 <range>에서 나오는 수는 (0.0, 0.1666, 0.3333, 0.5, 0.6666, 0.8333, 1.0)이다. 또한 graph의 x축, y축의 범위도 0 to 1로 설정되어 있다. 이 경우 위 <range>에서 나온 값들을 X좌표로 가지는 graph 상의 점들이 가지는 y 좌표 값이 바로 graph의 output이 되며 그 수 또한 0과 1사이에 있게 된다. 이 output은 실시간으로 graph의 형태에 따라 변하게 된다.
[2] vector cross product에 관한 내용은 다음 link를 참고하기 바란다. https://geometricmind.wordpress.com/2010/11/18/essential-mathematics-for-computational-design-09/
[3] 혹은 <XProd>에서 나오는 값을 <Amplitude>를 이용하여 크게 해줄 수 있다.
 

Generative Algorithm 036

삼각형 패턴 생성하기 (Triangulation)



Grasshopper의 Mesh tab에는 triangulation에 사용 가능한 다양한 componenent들이 있다. Delaunay 나 Voronoi 혹은 Convex Hull등이 그 예이다. 이 component들이 그려내는 결과물은 복잡한 객체를 design할  때 유용하게 사용될 수 있다. 또한 중요한 점은 이 component들은 점을 input으로 하여 다른 기하체를 output으로 내놓는 다는 것이다. 모두 쉽게 사용할 수 있고 또 이것을 이용한 예제들을 쉽게 찾아볼 수 있을 것이다.

 

Generative Algorithm 035

7_5_ Mesh 객체를 활용한 Design (Manipulating Mesh objects as a way of Design)

Modeling의 목적에 따라서 그 결과물이 간단해도 상관 없을 경우에는 더욱 쉬운 방법으로 mesh surface를 생성할 수 있다. 즉 위의 예제처럼 처음부터 원하는 형상에 맞춰 Point grid를 생성한 뒤 이것을 vertices로 하는 mesh를 그리는 것이 아니라 미리 정의되어있는 mesh를 조작하는 것이다. 즉 미리 정의된 mesh object를 생성하는 component를 가져온 뒤 이것의 parameter를 추출할 수 있은 다른 component에 연결하고 이를 조작해주는 것이다.


이번 예제에서는 <mesh plane>을 이용하여 mesh surface를 생성한 뒤 이것을 <mesh component>를 이용하여 이 mesh의 vertices와 face를 조작할 수 있게 한다. 먼저 이 vertices들을 Z 방향으로 무작위의 값만큼 이동시키게 된다. 이 때 생성되는 값은 <random>의 R에서 설정된 domain 값인 0 to 1 이므로 여기에 <multiplication>을 연결하여 일괄적으로 <number slider>의 수를 곱해준다. 한편으로 면의 경우 <cull pattern>을 이용하여 사용하고 싶은 face를 솎아내어 준다. 이렇게 골라내어진 face 의 data list와 위에서 얻어진 vertices의 data list를 <Mesh>를 이용하여 matching시켜준다.  이렇게 얻어진 mesh surface는 처음의 mesh plane과 기하학적(geometrical)이면서 위상학적(topological)인 차이를 가지게 된다.
이렇게 기하학적으로 vertices를 조작하고 위상학적으로 면을 변화시키는 방식은 design 목적에 따라 여러 가지 가능성을 가지고 있다. 특히 Mesh의 경우 NURBS와 다르게 surface 내에서 face를 선택적으로 고를 수가 있기 때문에 다공질의 면(porous surface)를 생성하는데 유리하다. 이러한 점을 이해하고 이것을 자신만의 design idea로 승화시켜 보자.

Ramdon하게 조작된 Mesh surface


Design에 적용시키기

Generative Algorithm 034

7_4_색을 이용하여 분석결과 시각화하기 (On Colour Analysis)

 
이렇게 생성된 mesh에 색을 이용하여 분석 결과를 시각적으로 표현해보도록 하자. 기본적인 개념은 위치변화가 없는 점과 위치변화가 최대인 점에 각각의 색을 부여하고 그 사이의 점에는 점차적인 색의 변화를 주는 것이다.
먼저 점의 위치 변화 정도를 알기 위해서는 먼저 각 점들의 원래 좌표와 이동 후 좌표를 측정한 뒤 그 둘 사이의 거리를 측정해주면 된다. 이것에 따라 mesh의 face에 색을 지정해주면 된다.

가장 처음이 생성한 XZ plane 상의 point grid로 돌아가자. 이것을 <distance>에 연결하고 나머지 하나에는 가장 마지막으로 적용된<move>를 연결해준다.

이제 서서히 변하는 색(Gradient colour)을 적용해보자. 이것에는 <Gradient> (Params > Special > Gradient)를 이용하면 된다. 이것의 t에 parameter를 적용시켜주면 된다. 그것이 바로 <distance> 값이다. L0과 L1에는 t로 들어오는 parameter 중에서 최대값과 최소값을 각각 연결해줘야 한다. 이를 위해서 <distance>가 생성하는 data 중 가장 큰 값과 가장 작은 값을 찾아보도록 하자.

<sort>[1]를 이용하여 <distance>가 생성하는 data list의 값을 오름차순으로 정리해준다. 이것 중 가장 큰 값과 가장 작은 값은 <list item>을 이용하여 추출할 수 있다. 가장 작은 값의 index number는 0이므로 i에 0을 적용시켜주면 된다. 마지막이 경우 <list length>에서 1을 뺀 값을 i에 적용시켜 주면 된다.[2] 이제 이 두 값을 <gradient>의 L0과 L1에 적용시켜주면 된다.

<gradient>의 왼쪽 위에 있는 icon을 클릭하면 원하는 색을 골라줄 수 있다.

<gradient>를 우클릭 하면 pop-up menu가 나타나게 되고 여기서 원하는 색의 적용 방식을 선택할 수 있다. 원하는 분석 목적에 맞는 방식을 선택해주면 된다.

Spectrum과 Traffic을 선택한 경우의 차이


[1] 위 화면에 나온 sort의 경우 pop-up menu의 input manager를 이용하여 input의 개수를 늘려 준 것이다. 이 예제에서는 아무런 의미가 없다.

[2] Index number는 0부터 시작하기 때문에 마지막 data의 index number는 data list의 길이에서 1을 뺀 것과 같다.

Generative Algorithm 033

7_2_기하학과 위상수학(Geometry and Topology)

이때까지는 NURBS에 적용되는 component들에 대하여 살펴보았다. Grasshopper에는 이 뿐만 아니라 다른 종류의 surface에도 적용 가능한 여러 component들이 있다. NURBS가 그려내는 부드러운 곡면이 꼭 원하는 결과물이 아닐 수 있다. 혹은 좀 더 미세한 제어와 간단한 함수에 의한 처리가 가능한 surface를 그리고 싶을 수도 있다. 예를 들면 B-spline이나 Besier surface 같은 경우가 있을 수 있다. 이번 장에서는 Mesh에 대해서 다루고자 한다.
Mesh란 free-from surface의 한 종류로 아주 작은 면(face)들이 모여 하나의 surface를 형성하는 것이다. 이러한 surface에는 그 내부에 고유한 규칙을 가지고 있다거나 수학적 함수에 의거하지 않는다. 대신 각 face가 모여 전반적 surface의 형상을 결정한다. 즉 하나의 Mesh surface 에는 각 face를 만들어내는 점(grid of point)이 분포되어 있고 이러한 각 face는 삼각형, 사각형, 혹은 육각형일 수도 있다. 이러한 점들이 mesh surface를 형성하는 기본 단위이며 이 점들은 모두 연결되어 있다.
Mesh가 가진 가장 중요한 두 가지 특징으로는 바로 mesh를 형성하는 점들의 위치와 각 점들간의 연결이다. 점들의 위치는 각 face가 가진 면의 형상을 결정하고 이것들의 연결성은 topology와 연관된다.

Geometry VS. Topology

기하학(geometry)가 공간에서 객체의 위치를 결정짓는다면 위상수학(topology)는 각 객체간의 관계를 결정하게 된다. 수학적으로 말하자면 topology란 객체가 가진 한 특징으로서 이것은 그 객체를 변환(transformation)하거나 변형(deformation)하여도 변하지 않는 것이다. 즉 원(circle)과 타원(ellipse)은 위상수학적(topologically)으로 같은 것으로 이 둘은 기하학적(geometrical) 차이만을 가지게 된다. 아래 그림을 살펴보면 각 네 개의 point들이 서로 연결되어 있는 것을 볼 수 있다. 왼쪽 두 개의 그림을 살펴보면 A와 B는 이 둘은 각기 같은 방식으로 연결되어있기 때문에 같은 topology를 가지고 있다고 말할 수 있다. 하지만 이 둘은 기하학적으로 같지 않은데 이는 한 점의 위치가 다르기 때문이다. 반면 오른쪽에 있는 두 A 와 B는 같은 위치에 점을 가지고 있지만 다른 방식으로 연결되어 있기 때문에 이 점들은 기하학적으로 같고, 위상수학적으로 다른 형상이라고 할 수 있다.
이러한 topology의 개념은 mesh를 이해하는데 매우 중요한 역할을 한다. 각 mesh의 face들은 그 모서리에 point를 가지며 각 face들의 corner point들은 각자 같은 순서와 방식으로 서로 연결된다. 이러한 mesh를 변환(transformation)하게 되었을 때 각 face의 모서리 점들(vertices)의 위치가 변하게 된다. 각 점들이 가지는 변환의 정도 또한 각기 다를 수 있다. 그러나 각 vertex들이 연결되는 방식은 유지되게 된다.

회색 surface나 빨간색 surface 모두 mesh로 같은 face와 모서리 점들(vertices)을 가진다. 단지 회색 surface의 vertices들이 다른 위치를 가지게 되면서 mesh의 기하학적 형상(geometrical configuration)을 바꾸고 있을 뿐이다. 하지만 각 mesh들이 같은 방식으로 연결 되고 있으므로 두 mesh surface는 위상수학적(topologically)으로 같다고 할 수 있다.
이러한 mesh 객체들의 위상수학적인 측면을 이해한다면 point들의 뭉치가 있을 때 그것을 연속하는 mesh surface로 표현할 수 있게 된다. 또한 여러 algorithm을 이용하여 point를 조절하여도 이 mesh surface는 유지되는데, 이는 바로 각 점들이 가지는 topology 때문이다.
예를 들어 Dynamic relaxation이나 particle system과 같이 유한한 요소를 분석하는 것에는 이것은 mesh를 이용하여 작업하는 것이 다른 종류의 surface를 이용하는 것보다 훨씬 쉬운데 이러한 함수들은 mesh vertices의 위치를 변화시키면서도 그 연속성은 유지되기 때문이다.
또한 mesh surface는 그 위에 구멍을 뚫거나 면을 불연속(discontinuity)하게 처리할 수 있기 때문이다. 또한 여러 가지 algorithm을 이용하여 mesh를 다듬고 이를 더욱 부드럽게 만들 수 있다. 또한 mesh는 각 face가 다른 색을 가질 수 있기 때문에 분석의 결과를 표현하는데 유용하게 사용할 수 있다.
Grasshopper의 Mesh 탭을 살펴보면 mesh를 조작할 수 있는 여러 개의 component를 찾을 수 있다. 이제 mesh를 처음부터 다뤄보고 이것에 대한 이해를 넓혀보도록 하자.

 

7_3_On Meshes

Point로 이루어진 격자가 있다. 이제 이 point들을 이용하여 면을 만들어보자. 이러한 point grid가 surface를 구성하고 있고 이 surface가 위로 갈수록 바람(혹은 vector를 가진 여러 종류의 힘)의 영향을 많이 받는다고 가정해보자. 그렇다면 이러한 영향은 각 point가 받는 것이라고 볼 수 있다. 이러한 point의 위치 변화는 surface를 변형시킬 것이다. 또한 풍량을 조절하여 그 형상을 바꿀 수 있을 것이다.

첫 번째 단계는 무척 간단하다. <series>와 <number slide>를 이용하면 점의 위치와 그 간격을 조절 할 수 있다. 이<number slide>는 각각 <N_pt>와 <distance_pt>로 그 이름이 변경되었다. 이 중 <N_pt>는 ‘even number’가 되도록 설정하자. 이 때 <point>의 data matching 방식을 ‘cross reference’로 바꾸는 것을 잊지 말자.

위는 바람의 힘과 그것의 영향을 받는 surface의 관계를 나타내는 diagram이다. 왼쪽은 수직 방향으로 생기는 힘과 그 영향이고 오른쪽은 위에서 보았을 때의 그것이다.
위 두 가지를 이용하면 바람의 영향을 modeling할 수 있다. 첫 번째 것은 간단한 수학 방정식(X^2)로 표현 될 수 있다. 이 때 변수 X는 바로 각 point의 Z 좌표값을 적용하게 된다. 이 <point>를 <point decompose>에 연결하여 각 점의 Z좌표값을 추출하자.
Y 축 방향으로 풍력이 작용한다고 가정해보자. Grid 위의 각 점들은 위에 있을수록 더 큰 z값을 가지기 때문에 위에 있는 점이 더 큰 영향을 받게 되는 것을 알 수 있다. 즉 Z좌표값에 비례하는 Y방향의 vector를 만들고 이것을 각 점에 적용시켜 Y방향으로 각 값만큼 이동시키는 것이다.

<decompose point>에 의하여 추출된 Z좌표 값은 <f2;(x^2)>에 의하여 제곱이 되고 다시 <number slider>에 의하여 그 영향의 정도를 조절되게 된다. 그 결과물은 <multiply>(Vector > Vector > Multiply)를 이용하여 <unit Y>에 곱해지게 된다.

이렇게 만들어진 vector를 이용하여 점을 이동시키면 위와 같이 우리가 원하는 결과물을 얻을 수 있다. 이제 두 번째 mechanism을 적용시켜 보자. 위에서 언급한대로 평면상에서 보았을 때 가운데 있는 부분이 바람의 영향을 더욱 많이 받게 된다. 아래 그림은 각 열(row)위에 있는 점들이 어떻게 이동하는 지를 보여주는 것이다.

열 위에서 점 위치의 이동


위에서 적용된 vector값에 다시 인수의 data list를 생성하고 이를 곱한 vector값을 이용하여 point들을 이동시켜주면 된다. 즉 오른쪽과 왼쪽 양 끝에 있는 점의 vector에는 0을 곱하면 vector값이 0이 되기 때문에 원래 자리에 남게 된다. 나머지 점들은 가운데 쪽으로 갈수록 더 큰 값을 곱해주면 위와 같은 결과물을 얻을 수 있다. 그러한 인수의 data list를 만드는 방식은 아래와 같다.

먼저 <range>를 이용하여 0을 처음 값, 1을 마지막 값으로 가지는 data list를 생성해준다. 즉 0은 양끝 쪽에, 1은 가운데 쪽에 있는 점의 vector에 적용되는 것이다. 이를 위해서는 <range>를 활용하면 된다. 먼저 D에 들어있는 정의역(domain)의 범위를 ‘0 to 1’ 로 정해준 뒤 이것을 <N_pt>를 <f1: (x/2)-1>에 연결하여 점의 개수를 2로 나누고 다시 1만큼 빼준다. <range>가 만들어내는 data list의 길이는 N에 들어오는 수보다 항상 1만큼 크기 때문이다. 이 경우 0과 1사이의 수를 3등분 하게 되면 (0, 0.333, 0.666, 1)이라는 수를 가지게 된다. 다시 이것을 <reverse>를 이용하여 data의 순서를 뒤집으면 (1, 0.666, 0.333, 0)이된다. 이 두 list를 <merge2>를 이용하여 합쳐주면 (0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0) 이라는 data list를 생성할 수 있다. 위의 그림에 panel을 살펴보면 쉽게 이해할 수 있을 것이다. 이제 이것을 <duplicate>를 이용하여 복사를 해주게 된다. 이때 이것에 들어오는 N값은 <N_pt>를 이용해주면 된다. 이 경우 점은 8개의 X좌표값과 8개의 Z좌표값이 조합된 64개가된다. 위에서 생성된 data list가 8개이고 여기에 다시 8을 곱하면 점의 개수만큼의 data list를 생성할 수 있다.[1]

이번 예시의 경우 약간의 분석적인 사고를 요구하는 것이 사실이다. 현실에서는 Particle Spring System이나 Finite Element Analysis 의 경우 복수개의 vector가 점 전체에 영향을 끼치며 점들 사이에도 각자의 힘이 서로에게 영향을 끼치게 된다. 즉 하나의 surface을 만드는 point grid가 있을 때 여기에 하나의 힘이 작용하면 이것은 모든 점에 영향을 끼치게 될 뿐만 아니라 그와 동시에 점들끼리도 서로 영향을 끼치게 되는 것이다. 이러한 과정은 반복적인 loop을 거쳐 계산되며 이것의 결과물이 전체(system)내에서 각 점의 위치를 결정하게 된다. 이 예제의 경우 각 점이 서로에게 끼치는 영향을 배제하고 매우 간단한 수학적인 계산을 통하여 각 점이 받는 힘만을 고려한 것이다. 현실에서의 영향은 이것보다 훨씬 더 복잡함을 알아두도록 하자. 여기서는 이러한 결과물을 ‘mesh’를 이용하여 표현해보는 것이 그 목적이다. 이제 이 점들을 이용하여 mesh를 생성해보자.

메쉬(Mesh)

먼저 <mesh>(Mesh > Primitive > Mesh)를 불러온 뒤 이것에 위에서 생성한 점들을 연결하여 준다. 하지만 이것으로 mesh가 생성되는 것은 아니다. Mesh surface를 생성하기 위해서는 이것을 구성하게 될 face정보를 제공해줘야 한다. 이 정보는 일련의 수로 이루어진 data list로 이것은 각 vertex[2]가 연결되는 방식을 결정해주고 이것을 통해 surface를 생성해주게 된다. 즉 이 vertices 는 mesh의 기하학적인 면을 결정해준다. 하지만 이 뿐만 아니라 위상학적인 정의(topological definition)을 해줘야 mesh를 생성할 수 있는 것이다.
Point grid위에 있는 각 점들을 4개씩 연결하여 사각형의 면(quadrant face)을 생성하여보자. Point grid를 살펴보면 각 point들이 고유의 index number를 가지는 것을 알 수 있다. 즉 각 점의 좌표값을 알고 그것을 이용하지 않아도 이 index number를 이용하면 점을 다룰 수 있게 된다.

각 점들이 가지고 있는 index number


Mesh를 정의 하기 위해서는 각 face들이 가지는 네 개의 vertex을 정의해주어야 한다.

위에서 보이는 것과 같은 순서로 점들을 연결해주면 quadrant face을 생성해줄 수 있다. 이 순서는 바로 하나의 점으로부터 출발하여 같은 행(row) 위에 있는 오른쪽 옆에 있는 점, 그 다음은 같은 열(column) 바로 위에 있는 점, 그 다음은 같은 행(row)바로 왼쪽 옆에 있는 점, 그리고 그 시작점으로 돌아오게 된다. 여기서 가장 처음에 생기는 face에 필요한 점은 바로 [0, 1, 6, 5]이다.  그 다음 face는 [1, 2, 7, 6]이다.
Mesh surface 전체를 정의하기 위해서는 위와 같은 순서로 점을 연결하는 algorithm을 짜야 한다. 위의 matrix를 살펴보면 n 번째 점이 있을 때 그 다음 점의 index number는 바로 n+1 이다.
그 다음 점에는 n에 열(column)의 개수 c를 더해주고 다시 1을 더해주면 된다. 즉 n+c+1로 위 경우 c=5이다. 그 다음 점은 n+c가 된다.
즉 어떠한 점의 index number n이 주어졌을 때 quadrant face가 가지는 vertex의 index number는 [n, n+1, n+c+1, n+c] 이다.

각 face를 정의해주면 mesh가 생성되게 된다.


위의 그림을 보면 위처럼 vertex의 index number를 정의해준다 하더라도 약간의 문제가 있음을 눈치챌 수 있을 것이다. 이 전에 다룬 삼각형 pattern을 만드는 예제를 떠올려보자. 마지막 열과 마지막 행위에 있는 점들은 면의 시작점이 될 수 없다는 것을 알 수 있다. 즉 여기서 필요한 것은 mesh의 face를 생성하기 위한 algorithm 뿐만 아니라 face의 ‘시작점’이 될 수 있는 점과 그렇지 않은 점을 구분해주는 data management가 필요하다.
간단하게 말해서 마지막 열과 마지막 행을 제외한 나머지 점들이 각 면의 시작점으로 정의해주면 된다. 즉 이에 해당하는 점들의 index number를 제외하는 수의 data list를 만들어야 한다.

위에서 언급한 data list를 생성해주기 위한 algorithm이다. 기본적으로 <series>를 이용해주면 된다. <N_pt>에서 나오는 수는 row와 column의 수와 같다. 이것을 <f1: x*(x-1)>를 이용하면 이것은 열(column)의 수 * 행(row)의수 -1 과 그 의미가 같다. 즉 이렇게 되면 마지막 row 만큼의 index number를 생성하지 않게 된다.[3] 즉 이것은 columns*(rows-1) 와 같다. 이제 이것을 <cull Nth>에 연결하여 n번째 수를 모두 버려주자. 그러면 오른쪽 열 위의 점의 index number에 해당하는 수를 버릴 수 있다.

이렇게 생성된 수의 data list는 위와 같다. 이제 이것을 index number로 가지는 vertex들을 골라보자.

<Mesh quad> (Mesh > Primitive > Mesh quad)는 Grasshopper에서 mesh의 face를 생성하는 역할을 해준다. 이것에 각 면의 첫 번째 vertex에 해당하는 index number를 A에 넣어준다.

두 번째 점은 n+1과 같으므로 <f1: x+1>을 적용시켜줄 수 있다. 그 다음 점은 ((n+1)+c)이므로 여기에 위 <f1: x+1>에서 나온 수를 x로 하고 <N_pt>를 y로 하는 <f2: x+y>를 생성해준다. 마지막 점은 다시 여기서 1을 빼주면 된다. 즉, <f1: x-1>을 적용시켜준다. 이것을 <quad>의 각 A, B, C, D에 연결시켜주고 <mesh>의 F에 연결해준다.


[1] 즉 (0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0, 0, 0.333, 0.666, 1, 1, 0.666, 0.333, 0) 이라는 data list가 생성된다. 이것이 ‘행(row)’의 방향으로 반복되는 점에 적용된다.

[2] Vertex는 꼭지점을 의미한다. 그 복수형이 vertices 이다. 참고는 http://ko.wikipedia.org/wiki/%EA%BC%AD%EC%A7%80%EC%A0%90
http://en.wikipedia.org/wiki/Vertex_(geometry)

[3]Data는 원칙적으로 U방향으로 생성됨을 잊지 말자. 이 경우 U 방향은 X축 방향, row 방향 으로 생각할 수 있다.