|
2004년 01월 22일
/*
먼저, API 연재 #2에서 제가 실수한 것을 정정하도록 하겠습니다. 송준택님께서 지적해 주셨듯이, DeclareSimpleCommand는 function이 아니라 Macro입니다. 그 외 많은 분들의 관심과 참여에 감사드립니다. 아, 그리고, 제가 인용하는 Source 코드는 Maya Manual 중에서 Maya Developer's Tool Kit의 Maya API Developer's Manual 에서 가져 온 겁니다. 더 자세한 사항을 보고 싶으신 분들은 이 문서를 직접 참고하시기 바랍니다. */ 3. API MEL command with MEL UI _______________________________________________ API 연재 #2를 잘 따라하신 분들이라면, 이제 뭔가 좀 만들어 보고싶다는 생각을 하실 겁니다. 그래서, 이번엔 argument를 가지는 MEL command를 API를 사용해서 만들어보고, 이 MEL command를 이용하기 편하도록 UI를 MEL을 사용하여 만들어 보도록 하겠습니다. 1) Maya Plug-in Wizard _______________________________________________ API 연재 #2를 기억하시면서 이제 MS Visual C++을 실행시키고, File > New를 선택하시고, Projects 탭에서 Maya Plug-in Wizard를 선택하세요. 그리고, Location부분엔 Project를 만들 위치를, Project name 부분엔 doHelix라고 입력하세요. 그 다음, OK를 누르고, 여기서 해당 Maya 버전을 선택하시고, Plug-in 개발자 이름을 입력한 뒤, Next를 누릅니다. 어떤 종류의 Plug-in을 만들지를 고르는 화면에서는 이번에 만들 doHelix 역시 간단한 MEL Command이므로, MEL Command를 선택하고, Maya type name란에 doHelix라고 입력합니다. 그리고, Next를 누릅니다. Plug-in에 포함될 Library를 선택하는 화면에서 doHelix는 간단한 Command이므로 가장 기본이 되는, Foundation과 OpenMaya만 선택하면 됩니다. 이제 Finish를 누르세요. 대충 아래와 같은 코드 뼈대가 만들어졌을 겁니다. 이제 이 뼈대에 살을 붙일 차례죠. // // Copyright (C) 2001 Gyedo Jeon // // File: doHelixCmd.cpp // // MEL Command: doHelix // // Author: Maya SDK Wizard // // Includes everything needed to register a simple MEL command with Maya. // #include <maya/MSimple.h> // Use helper macro to register a command with Maya. It creates and // registers a command that does not support undo or redo. The // created class derives off of MPxCommand. // DeclareSimpleCommand( doHelix, "Gyedo Jeon", "4.0"); MStatus doHelix::doIt( const MArgList& args ) // // Description: // implements the MEL doHelix command. // // Arguments: // args - the argument list that was passes to the command from MEL // // Return Value: // MS::kSuccess - command succeeded // MS::kFailure - command failed (returning this value will cause the // MEL script that is being run to terminate unless the // error is caught using a "catch" statement. // { MStatus stat = MS::kSuccess; // Since this class is derived off of MPxCommand, you can use the // inherited methods to return values and set error messages // setResult( "doHelix command executed! " ); return stat; } 2) #include _______________________________________________ doHelix는 사용자로부터 helix의 radius와 pitch를 입력받아 NURBS Curve로 helix를 그리는 MEL command입니다. 따라서, NURBS Curve를 만들어야 하는데 MFnNurbsCurve를 이용하면 NURBS Curve를 만들 수가 있습니다. 그런데, NURBS Curve를 만드려면, Curve Point들의 좌표와 Knot들의 값이 있어야 합니다. Maya API에는 Maya안에서의 좌표를 저장할 수 있는 MPoint라는 Class가 있고, 이 MPoint들의 array인 MPointArray가 있습니다. 또한 Knot 값들은 MDoubleArray를 이용해서 저장할 수 있습니다. 이러한 Maya API class들을 사용하려면 해당 header file들을 include해야 합니다. 그리고, sin, cos등의 기본 수학 함수를 사용하기 위해 C++ 표준 library인 math.h를 include해야 합니다. 아래의 코드와 같이 #include문을 사용하셔서 include 하세요. (여기서 C/C++ 프로그래밍에 대하여 설명하지는 않을 테니, C/C++을 잘 모르시는 분들은 다른 소스를 참고하시기 바랍니다.) #include <math.h> #include <maya/MSimple.h> #include <maya/MPoint.h> #include <maya/MPointArray.h> #include <maya/MDoubleArray.h> #include <maya/MFnNurbsCurve.h> 3) doHelix::doIt _______________________________________________ doHelix 명령과 해당 class를 만들어주는 DeclareSimpleCommand 구문은 그냥 놔두시면 됩니다. 그리고 실제 helix를 만드는 doIt function을 만들어야죠. MStatus stat; const unsigned deg = 3; // Curve Degree const unsigned ncvs = 20; // Number of CVs const unsigned spans = ncvs - deg; // Number of spans const unsigned nknots = spans+2*deg-1; // Number of knots double radius = 4.0; // Helix radius double pitch = 0.5; // Helix pitch unsigned i; MPointArray controlVertices; MDoubleArray knotSequences; 위의 코드 들과 같이 사용하게 될 변수들을 선언합니다. NURBS curve를 만드는 데는 Curve의 degree, CV 개수, Spand의 개수, Knot value등이 필요하죠. 그리고, CV들의 좌표를 저장하기 위해, MPointArray 타입의 controlVertices와 Knot value들을 저장하기 위해 MDoubleArray 타입의 knotSequences를 선언했습니다. 이번엔, 사용자로부터 입력받은 argument들을 parsing하는 부분입니다. MArgList class의 length와 asDouble등의 function을 사용해서 아래의 코드와 같이 argument 값을 읽어들입니다. // Parse the arguments. for ( i = 0; i < args.length(); i++ ) if ( MString( "-p" ) == args.asString( i ) ) pitch = args.asDouble( ++i ); else if ( MString( "-r" ) == args.asString( i ) ) radius = args.asDouble( ++i ); 이제 필요한 정보가 다 모였으니 실제 helix의 position을 구해 봅시다. helix를 만드는 algorithm은 간단합니다. radius * cos을 X좌표로, radius * sin을 Z좌표로 사용하면 Top View에서의 원을 그릴 수가 있는데, 이렇게 하면서 Y 좌표를 조금씩 키워나가는 방법으로 helix를 만드는 겁니다. helix의 position array는 이렇게 만들었고, knot값들은 0부터 시작해서 순차적으로 증가하게 만들었습니다. (NURBS에서의 knot 값에 대하여도 여기서 설명하지 않겠습니다. ^^;) // Set up cvs and knots for the helix // for (i = 0; i < ncvs; i++) controlVertices.append( MPoint( radius * cos( (double)i ), pitch * (double)i, radius * sin( (double)i ) ) ); for (i = 0; i < nknots; i++) knotSequences.append( (double)i ); 이렇게 만들어진 정보로 curve를 만드는 부분입니다. 앞에서도 이야기했듯이, Curve를 만드는데는 MFnNurbsCurve class가 사용됩니다. 먼저 MFnNurbsCurve class의 인스턴스를 하나 만들고, create function을 이용해서 Curve를 만들면 됩니다. MFnNurbsCurve class에 대한 자세한 정보는 Maya Manual 중에서 Maya Developer's Tool Kit의 Class 도큐먼트를 참고하세요. C:AW에 Maya를 설치하셨다면 여기를 누르시면 도큐먼트가 나옵니다. // Now create the curve // MFnNurbsCurve curveFn; MObject curve = curveFn.create( controlVertices, knotSequences, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat ) printf("Error creating curve. "); 완성된 코드는 다음과 같습니다. 이제 F7을 눌러서 Compile하시면 debug section에 doHelix.mll 이 만들어질겁니다. 다음 연재에서 이 코드를 사용해서 Debug하는 법을 가르쳐드릴테니까 release로 Compile하지 마세요. // // Copyright (C) 2001 Gyedo Jeon // // File: doHelixCmd.cpp // // MEL Command: doHelix // // Author: Maya SDK Wizard // // Includes everything needed to register a simple MEL command with Maya. // #include <math.h> #include <maya/MSimple.h> #include <maya/MPoint.h> #include <maya/MPointArray.h> #include <maya/MDoubleArray.h> #include <maya/MFnNurbsCurve.h> // Use helper macro to register a command with Maya. It creates and // registers a command that does not support undo or redo. The // created class derives off of MPxCommand. // DeclareSimpleCommand( doHelix, "Gyedo Jeon", "4.0"); MStatus doHelix::doIt( const MArgList& args ) // // Description: // implements the MEL doHelix command. // // Arguments: // args - the argument list that was passes to the command from MEL // // Return Value: // MS::kSuccess - command succeeded // MS::kFailure - command failed (returning this value will cause the // MEL script that is being run to terminate unless the // error is caught using a "catch" statement. // { MStatus stat; const unsigned deg = 3; // Curve Degree const unsigned ncvs = 20; // Number of CVs const unsigned spans = ncvs - deg; // Number of spans const unsigned nknots = spans+2*deg-1; // Number of knots double radius = 4.0; // Helix radius double pitch = 0.5; // Helix pitch unsigned i; MPointArray controlVertices; MDoubleArray knotSequences; // Parse the arguments. for ( i = 0; i < args.length(); i++ ) if ( MString( "-p" ) == args.asString( i ) ) pitch = args.asDouble( ++i ); else if ( MString( "-r" ) == args.asString( i ) ) radius = args.asDouble( ++i ); // Set up cvs and knots for the helix // for (i = 0; i < ncvs; i++) controlVertices.append( MPoint( radius * cos( (double)i ), pitch * (double)i, radius * sin( (double)i ) ) ); for (i = 0; i < nknots; i++) knotSequences.append( (double)i ); // Now create the curve // MFnNurbsCurve curveFn; MObject curve = curveFn.create( controlVertices, knotSequences, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat ) printf("Error creating curve. "); return stat; } 4) helix.mel _______________________________________________ 이제 Maya를 실행해서 Plug-in Manager에서 doHelix.mll을 load하고, Script Editor에서 doHelix 라고 입력해 보세요. radius와 pitch를 주지 않아도 기본값인 4.0, 0.5를 사용해서 helix가 만들어 질 겁니다. 이번엔, doHelix -r 8.0 -p 1.0 이라고 입력해 보세요. radius가 8.0, pitch가 1.0인 helix가 만들어지죠? 이번엔 간단한 MEL을 만들어서 이 doHelix command의 UI를 만들어 보겠습니다. Maya Script를 이용해서 다음과 같이 입력하세요. global proc helix() { window -t "HelixUI" helixWin; columnLayout -adjustableColumn true; floatSliderGrp -l "Radius" -v 4.0 -f true helixRadius; floatSliderGrp -l "Pitch" -v 0.5 -f true helixPitch; button -l "Make Helix" -c "makeHelix"; showWindow helixWin; } global proc makeHelix() { float $radius = `floatSliderGrp -q -v helixRadius`; float $pitch = `floatSliderGrp -q -v helixPitch`; doHelix $radius $pitch; }; 이제, Script Editor에서 helix라고 입력하시면 간단한 UI가 생기고 Make Helix 버튼을 누를 때마다 helix가 만들어지게 됩니다. _______________________________________________ 오늘은 여기까지. 질문들 하세요. |
최근 등록된 덧글
Maya Plug-in Wizard 는 여기..
by 해커킬러 at 10/28 잘봤습니다. 친절하게 잘 설명해.. by 랄프 at 05/26 강좌 완전 친절해요 ㅠ_ㅠb 정말.. by 문 at 03/19 이글루 파인더
카테고리
MEL Tips
Maya API on Rendering CG | VFX Java | JSP | DB from Gyedo Scraps Belief Book Movie Game Gadgets for fun Japanese June 라이프로그
이전블로그
2008년 04월
2008년 03월 2008년 02월 2008년 01월 2007년 11월 2007년 10월 2007년 08월 2007년 06월 2007년 05월 2007년 04월 2007년 03월 2007년 02월 2007년 01월 2006년 12월 2006년 09월 2006년 06월 2006년 05월 2006년 03월 2006년 02월 2006년 01월 2005년 12월 2005년 11월 2005년 10월 2005년 09월 2005년 07월 2005년 06월 2005년 05월 2005년 04월 2005년 03월 2005년 02월 2005년 01월 2004년 12월 2004년 11월 2004년 10월 2004년 09월 2004년 08월 2004년 07월 2004년 06월 2004년 04월 2004년 03월 2004년 01월 |