| Àμâ |

1. 코드 간소화하기

string $objects[];
$objects = `ls`;
select $objects;



는 다음처럼 한 줄로 표현할 수 있다.


select `ls`;



위 문장에서 ‘ls’ 커맨드는 씬에 있는 오브젝트 이름들을 반환하고, 이 반환값들은 ‘select’ 커맨드로 넘어간다. ‘ls’ 의 반환값을 ‘select’로 넘겨주기 위해 ls를 역따옴표(`)로 묶어주는 것을 잊지 말자.


2. 선택한 오브젝트 이동시키기

다음 스크립트는 선택한 오브젝트를 y 방향으로 5만큼 이동시킨다.


string $objects[] = `ls -sl`;
string $currentObject;
for ( $currentObject in $objects )
{
    move -r 0 5 0 $currentObject;
}



튜토리얼의 마지막에서 작성한 스크립트를 약간 변형한 것으로, for-in 루프의 바디(body) 부분만 move 커맨드로 교체하였다.

테스트:
  • conMel2_hw2.ma를 열어 몇 개의 오브젝트를 선택한다.
  • 작성한 스크립트를 수행하면 선택한 오브젝트들이 y 방향으로 5만큼 이동해야 한다.


3. file 노드의 이름 바꾸기

이 문제는 연습 문제 중에서 가장 어려운 예제이다. 때문에 단계별로 답을 만들어 가도록 하겠다.
먼저, 전체 구조를 잡아보자. 튜토리얼에서 이미 다음처럼 단계별 요약을 해 놓았다.

  1. 씬에 있는 file 노드를 찾는다
  2. 노드 이름에서 “scene”을 “sc”로 바꾼다
  3. 노드 이름에서 유저 이름을 “”로 바꾼다.

일단, 1단계부터 스크립트로 구현해 보자.


ls -type file;



이 문장을 conMel2_hw3.ma에 수행해 보면 다음과 같이 파일 노드 리스트를 출력할 것이다.


// Result: chris_scene3_t jason scene1_cameron_t
scene2_christmas_t scene2_coolguy_t scene3_chris_t //

이제 파일 노드 리스트를 구했으니, for-in loop로 각각의 파일 노드의 이름을 출력하도록 스크립트를 바꾸어 보겠다.

string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    print $f;
}


테스트 씬에 적용시키면, 각각의 파일 노드 이름이 출력될 것이다.

그럼 제 2단계인 “scene”을 “sc”로 교체하는 작업을 해 보자. 튜토리얼에서 한 것과 마찬가지로 subsitute와 replace 커맨드를 쓴다.

string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    print $f;
    string $newname = `substitute "scene" $f "sc"`;
    rename $f $newname;
}


여기까지는 튜토리얼에서 연습한 것과 크게 다르지 않다.

제 3단계인 유저 이름을 삭제하는 작업을 해 보자. $newname 변수는 “scene”이 “sc”로 교체된 후의 새 이름을 저장하고 있으므로, 이 변수에서 유저 이름을 빈 문자열로 대체하면 되겠다. 그럼 $newname 에서 “chris”를 빈 문자열로 대체하여 보자.

string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    string $newname = `substitute "scene" $f "sc"`;
    string $newname2 = `substitute "chris" $newname ""`;
    rename $f $newname2;
}

ls -type file;


위의 예에서 다음 줄을 자세히 살펴보자.


string $newname2 = `substitute "chris" $newname ""`;

$newname 은 “scene”이 “sc”로 대체된 결과를 가지고 있다. 즉, “scene3_chris_t” 노드의 경우, $newname에 있는 값은 “sc3_chris_t”가 된다. 이제 그 중에서 “chris” 부분을 빈 문자열로 교체하여, “scehe3_chris_t”는 최종적으로 “sc3__t”로 바뀔 것이다.

스크립트 결과를 쉽게 알아보기 위하여 다음 문장을 마지막에 덧붙였다. 스크립트를 수행한 후의 파일 노드들의 이름을 출력할 것이다.

ls -type file;

마찬가지로 “coolguy”, “cameron”도 빈문자열로 대체하여 보자.

string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    string $newname = `substitute "scene" $f "sc"`;
    string $newname2 = `substitute "chris" $newname ""`;
    string $newname3 = `substitute "coolguy" $newname2 ""`;
    string $newname4 = `substitute "cameron" $newname3 ""`;
    rename $f $newname4;
}
ls -type file;

subsitutute 커맨드를 4번 연속 사용한 후에, 그 최종 결과를 rename 커맨드에 사용하였다.

conMel2_hw3.ma에 스크립트를 적용한 후, 파일 노드의 이름들을 살펴보자.

변경 전
변경 후
 chris_scene3_t
 _sc3_t
jason
jason
scene1_cameron_t
sc1__t
scene2_christmas_t
sc2_tmas_t
scene2_coolguy_t
sc2__t
scene3_chris_t
sc3__t

여기에서 몇 가지를 짚고 넘어가자.

  1. 테스트 씬에 있는 nurbsSurface들의 이름 역시 sceneX_<유저이름>_XX의 형식을 따르지만, 이들의 이름은 바뀌지 않았다.
  2. 문 제에서는, 파일 이름이 “sceneXX_<유저이름>_XX” 식으로 되어 있다고 하였지만, “chris_scene3_t”는 유저 이름이 씬 이름 앞에 오고 있다. 우리가 작성한 스크립트는 씬 이름이 먼저 나오는지 유저 이름이 먼저 나오는지는 구분하지 않고 있다.
  3. “scene2_christmas_t”에서 유저 이름은 실제로 “christmas”이지만, 우리의 스크립트는 “christmas”에서 “chris” 부분을 삭제하였다.
  4. 노드 이름에 “__”가 생겼다.

위에서 1번은 원하던 바이므로 스스로에게 박수를 쳐 주자. 2번은 상황에 따라서 원하는 것일 수도 있고 아닐 수도 있다. 3번은 원하지 않는 결과일 가능성이 더 크다. 4번역시 예뻐보이진 않는다.

2, 3,4 번을 고치는 것은 여러 가지 방법이 있지만, 우리가 지금까지 공부한 내용만을 바탕으로 해 보자:


string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    string $newname = `substitute "scene" $f "sc"`;
    string $newname2 = `substitute "_chris_" $newname "_"`;
    string $newname3 = `substitute "_coolguy_" $newname2 "_"`;
    string $newname4 = `substitute "_cameron_" $newname3 "_"`;
    rename $f $newname4;
}
ls -type file;

짠~

변경 전
변경 후
 chris_scene3_t
 chris_sc3_t
jason
jason
scene1_cameron_t
sc1_t
scene2_christmas_t
sc2_christmas_t
scene2_coolguy_t
sc2_t
scene3_chris_t
sc3_t

그럼 이 스크립트를 더욱 개선할 방법은 없을까?

있다.


string $files[] = `ls -type file`;
string $f;
for($f in $files)
{
    string $newname = `substitute "scene" $f "sc"`;
    $newname = `substitute "_chris_" $newname "_"`;
    $newname = `substitute "_coolguy_" $newname "_"`;
    $newname = `substitute "_cameron_" $newname "_"`;
    rename $f $newname;
}
ls -type file;



앞의 스크립트와 다른 점은, $newname변수를 반복해서 사용하고 있다는 점이다.


$newname = `substitute "_chris_" $newname "_"`;



위의 문장은, $newname에서 “_chris_”를 “_”로 대체한 결과를 다시 $newname 변수에 저장한다.

예를 들어 새 전화번호를 받았다고 치자. 예전 전화번호에 줄을 긋고 그 밑에 새 번호를 쓰는 경우가 앞의 스크립트가 되겠다. 예전 전화번호를 지우개로 지우고, 그 자리에 새 번호를 쓰는 것이 이 스크립트의 방법이다. 이 스크립트를 한 층 더 발전시키면 다음과 같이 된다.

string $files[] = `ls -type file`;
string $f;

string $users[];
$users[0] = "_chris_";
$users[1] = "_coolguy_";
$users[2] = "_cameron_";

string $u;
for($f in $files)
{
    string $newname = `substitute "scene" $f "sc"`;
    for($u in $users)
    {
        $newname = `substitute $u $newname "_"`;
    }
    rename $f $newname;
}
ls -type file;


위 스크립트는 for-in loop 안에 또다른 for-in loop가 있다. 이에 대해서는 좀 더 후에 살펴볼 예정이다.


4. 씬에 있는 phong 노드 삭제하기

훗.
3번 문제를 풀었다면, 4번은 훨씬 쉽게 끝낼 수 있을 것이다.


string $files[] = `ls -type phong`;
string $f;
for($f in $files)
{
    delete $f;
}

conMel2_hw4.ma를 열고 이 스크립트를 수행하면 phong 노드만 지워지고 다른 쉐이더 및 파일 노드 등은 그대로 남아있는다.