//////////////////////////////////////////////////////////////////////////////
//		ToonShader.cpp	Maya3.0用Shaderプラグイン
//		2000 11/20	Ver1.0	Shouji Fukuda
//
//		使用注意
//		Maya3.0でしか動きません。
//		lightはDirectional LightかPoint Lightを使うこと。
//		
//////////////////////////////////////////////////////////////////////////////

#include <iostream.h>
#include <math.h>

#include <maya/MPxNode.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h> 
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h> 
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
#include <maya/MGlobal.h>

class toon : MPxNode 
{
public :
							toon () ;
	virtual				~toon () ;

	virtual	MStatus		compute ( const MPlug&, MDataBlock& ) ;
	virtual void		postConstructor () ;

	static  void *		creator () ;
	static  MStatus		initialize () ;
	static  MTypeId		id ;

protected :

	static MObject	aTranslucenceCoeff ;
	static MObject	aDiffuse ;
	static MObject	aColorR, aColorG, aColorB ;
	static MObject	aColor ;
	static MObject	aColorR2, aColorG2, aColorB2 ;
	static MObject	aColor2 ;
	//	白熱
	static MObject	aIncandescenceR, aIncandescenceG, aIncandescenceB ;
	static MObject	aIncandescence ;
	//	透明度
	static MObject	aInTransR, aInTransG, aInTransB ;
	static MObject	aInTransparency ;
	//	出力色
	static MObject	aOutColorR, aOutColorG, aOutColorB ;
	static MObject	aOutColor ;
	//	出力透明度
	static MObject	aOutTransR, aOutTransG, aOutTransB ;
	static MObject	aOutTransparency;
	//	法線データと思われる
	static MObject	aNormalCameraX, aNormalCameraY, aNormalCameraZ ;
	static MObject	aNormalCamera ;
	//	視線ベクトル
	static MObject	aPointCameraX, aPointCameraY, aPointCameraZ ;
	static MObject	aPointCamera ;
	//	輪郭線を出すためのパラメータ
	static MObject	aRinkaku ;
	//	影の濃さを調節する
	static MObject	aShadow ;

	static MObject	aLightDirectionX, aLightDirectionY, aLightDirectionZ ;
	static MObject	aLightDirection ;
	//	光の強度
	static MObject	aLightIntensityR, aLightIntensityG, aLightIntensityB ;
	static MObject	aLightIntensity ;
	static MObject	aLightAmbient, aLightDiffuse, aLightSpecular ;
	static MObject	aLightShadowFraction ;
	static MObject	aPreShadowIntensity ;
	static MObject	aLightBlindData;
	static MObject	aLightData ;
} ;

//////////////////////////////////////////////////////////////////////////////
//							IDを決める
//						Shading Nodeであると宣言	
//////////////////////////////////////////////////////////////////////////////
MTypeId toon::id ( 0x31003 ) ;

void toon::postConstructor ()
{
	setMPSafe(true);
}

//////////////////////////////////////////////////////////////////////////////
//								変数宣言
//////////////////////////////////////////////////////////////////////////////
MObject	toon::aTranslucenceCoeff ;
MObject toon::aDiffuse ;
MObject toon::aInTransparency ;
MObject toon::aInTransR ;
MObject toon::aInTransG ;
MObject toon::aInTransB ;
MObject toon::aColor ;
MObject toon::aColorR ;
MObject toon::aColorG ;
MObject toon::aColorB ;
MObject	toon::aColorR2 ;
MObject toon::aColorG2 ;
MObject toon::aColorB2 ;
MObject toon::aColor2 ;

MObject toon::aIncandescence ;
MObject toon::aIncandescenceR ;
MObject toon::aIncandescenceG ;
MObject toon::aIncandescenceB ;
MObject toon::aOutColor ;
MObject toon::aOutColorR ;
MObject toon::aOutColorG ;
MObject toon::aOutColorB;
MObject toon::aOutTransparency ;
MObject toon::aOutTransR ;
MObject toon::aOutTransG ;
MObject toon::aOutTransB ;
MObject toon::aNormalCamera ;
MObject toon::aNormalCameraX ;
MObject toon::aNormalCameraY ;
MObject toon::aNormalCameraZ ;

MObject toon::aPointCameraX ;
MObject	toon::aPointCameraY ;
MObject toon::aPointCameraZ ;
MObject toon::aPointCamera ;

MObject	toon::aRinkaku ;
MObject	toon::aShadow ;

MObject toon::aLightData ;
MObject toon::aLightDirection ;
MObject toon::aLightDirectionX ;
MObject toon::aLightDirectionY ;
MObject toon::aLightDirectionZ ;
MObject toon::aLightIntensity ; 
MObject toon::aLightIntensityR ;
MObject toon::aLightIntensityG ;
MObject toon::aLightIntensityB ;
MObject toon::aLightAmbient ;
MObject toon::aLightDiffuse ;
MObject toon::aLightSpecular ;
MObject toon::aLightShadowFraction ;
MObject toon::aPreShadowIntensity ;
MObject toon::aLightBlindData ;

toon::toon ()
{
}

toon::~toon ()
{
}

void* toon::creator()
{
    return new toon () ;
}

MStatus toon::initialize()
{
    MFnNumericAttribute nAttr; 
    MFnLightDataAttribute lAttr;

    aTranslucenceCoeff = nAttr.create( "translucenceCoeff", "tc", MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aDiffuse = nAttr.create( "diffuse", "drfl", MFnNumericData::kFloat);
    nAttr.setStorable(true);
	nAttr.setMin(0.0f);
    nAttr.setMax(1.0f);
    nAttr.setDefault(0.5f);

    aColorR = nAttr.create( "colorR", "cr",MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aColorG = nAttr.create( "colorG", "cg",MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(1.0f);

    aColorB = nAttr.create( "colorB", "cb",MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aColor = nAttr.create( "color", "c", aColorR, aColorG, aColorB);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f, 1.0f, 0.0f);
    nAttr.setUsedAsColor(true);

	aColorR2 = nAttr.create ( "colorR2", "cr2", MFnNumericData::kFloat ) ;
	nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

	aColorG2 = nAttr.create( "colorG2", "cg2",MFnNumericData::kFloat ) ;
    nAttr.setStorable(true);
    nAttr.setDefault(0.5f);

	aColorB2 = nAttr.create( "colorB2", "cb2",MFnNumericData::kFloat ) ;
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aColor2 = nAttr.create( "color2", "c2", aColorR2, aColorG2, aColorB2 );
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f, 0.5f, 0.0f);
    nAttr.setUsedAsColor(true);
	
    aIncandescenceR = nAttr.create( "incandescenceR", "ir", MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aIncandescenceG = nAttr.create( "incandescenceG", "ig", MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aIncandescenceB = nAttr.create( "incandescenceB", "ib", MFnNumericData::kFloat);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f);

    aIncandescence = nAttr.create( "incandescence","ic", 
                                   aIncandescenceR, aIncandescenceG, aIncandescenceB);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f, 0.0f, 0.0f);
    nAttr.setUsedAsColor(true);

    aInTransR = nAttr.create( "transparencyR", "itr",MFnNumericData::kFloat);
    nAttr.setStorable(true);

    aInTransG = nAttr.create( "transparencyG", "itg",MFnNumericData::kFloat);
    nAttr.setStorable(true);

    aInTransB = nAttr.create( "transparencyB", "itb",MFnNumericData::kFloat);
    nAttr.setStorable(true);

    aInTransparency = nAttr.create( "Transparency", "it", aInTransR,aInTransG,aInTransB);
    nAttr.setStorable(true);
    nAttr.setDefault(0.0f, 0.0f, 0.0f);
    nAttr.setUsedAsColor(true);

    aOutColorR = nAttr.create( "outColorR", "ocr", MFnNumericData::kFloat);
    aOutColorG = nAttr.create( "outColorG", "ocg", MFnNumericData::kFloat);
    aOutColorB = nAttr.create( "outColorB", "ocb", MFnNumericData::kFloat);
    aOutColor = nAttr.create( "outColor","oc", aOutColorR, aOutColorG, aOutColorB);
    nAttr.setHidden(false);
    nAttr.setReadable(true);
    nAttr.setWritable(false);

    aOutTransR = nAttr.create( "outTransparencyR","otr", MFnNumericData::kFloat);
    aOutTransG = nAttr.create( "outTransparencyG","otg", MFnNumericData::kFloat);
    aOutTransB = nAttr.create( "outTransparencyB","otb", MFnNumericData::kFloat);
    aOutTransparency = nAttr.create( "outTransparency","ot", aOutTransR,aOutTransG,aOutTransB);
    nAttr.setHidden(false);
    nAttr.setReadable(true);
    nAttr.setWritable(false);

    aNormalCameraX = nAttr.create( "normalCameraX", "nx", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f);

    aNormalCameraY = nAttr.create( "normalCameraY", "ny", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f);

    aNormalCameraZ = nAttr.create( "normalCameraZ", "nz", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f);

    aNormalCamera = nAttr.create( "normalCamera","n", 
                                  aNormalCameraX, aNormalCameraY, aNormalCameraZ);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f, 1.0f, 1.0f);
    nAttr.setHidden(true);

	aPointCameraX = nAttr.create( "pointCameraX", "px", MFnNumericData::kFloat);
	nAttr.setStorable(false);
	nAttr.setDefault(1.0f);

    aPointCameraY = nAttr.create( "pointCameraY", "py", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f);

    aPointCameraZ = nAttr.create( "pointCameraZ", "pz", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setDefault(1.0f);

    aPointCamera = nAttr.create( "pointCamera","p",
								 aPointCameraX, aPointCameraY, aPointCameraZ);
    nAttr.setStorable(false);
    nAttr.setHidden(true);

	//輪郭線
	aRinkaku = nAttr.create ( "rinkaku", "rin", MFnNumericData::kFloat ) ;
    nAttr.setStorable(true);
	nAttr.setMin(-0.2f);
    nAttr.setMax(1.0f);
    nAttr.setDefault(0.3f);

	aShadow = nAttr.create ( "shadow", "sha", MFnNumericData::kFloat ) ;
	nAttr.setStorable(true);
	nAttr.setMin(0.0f);
    nAttr.setMax(1.0f);
    nAttr.setDefault(0.5f);

    aLightDirectionX = nAttr.create( "lightDirectionX", "ldx", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightDirectionY = nAttr.create( "lightDirectionY", "ldy", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightDirectionZ = nAttr.create( "lightDirectionZ", "ldz", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightDirection = nAttr.create( "lightDirection", "ld", 
                                    aLightDirectionX, aLightDirectionY, aLightDirectionZ);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f, 1.0f, 1.0f);

    aLightIntensityR = nAttr.create( "lightIntensityR", "lir", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightIntensityG = nAttr.create( "lightIntensityG", "lig", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightIntensityB = nAttr.create( "lightIntensityB", "lib", MFnNumericData::kFloat);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightIntensity = nAttr.create( "lightIntensity", "li", 
                                   aLightIntensityR, aLightIntensityG, aLightIntensityB);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(1.0f, 1.0f, 1.0f);

    aLightAmbient = nAttr.create( "lightAmbient", "la", MFnNumericData::kBoolean);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(true);

    aLightDiffuse = nAttr.create( "lightDiffuse", "ldf", MFnNumericData::kBoolean);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(true);

    aLightSpecular = nAttr.create( "lightSpecular", "ls", MFnNumericData::kBoolean);
    nAttr.setStorable(false);
    nAttr.setHidden(true);
    nAttr.setReadable(false);
    nAttr.setDefault(false);

    aLightShadowFraction = nAttr.create( "lightShadowFraction", "lsf", MFnNumericData::kFloat);
    nAttr.setStorable(false);
	nAttr.setReadable(true);
	nAttr.setWritable(true);
    nAttr.setDefault(1.0f);

    aPreShadowIntensity = nAttr.create( "preShadowIntensity", "psi", MFnNumericData::kFloat);
    nAttr.setStorable(false);
	nAttr.setHidden(true);
	nAttr.setReadable(false);
    nAttr.setDefault(1.0f);

    aLightBlindData = nAttr.create( "lightBlindData", "lbld", MFnNumericData::kLong);
    nAttr.setStorable(false);
	nAttr.setHidden(true);
	nAttr.setReadable(false);
    nAttr.setDefault(0);

	aLightData = lAttr.create( "lightDataArray", "ltd", 
                               aLightDirection, aLightIntensity, 
                               aLightAmbient, aLightDiffuse, aLightSpecular, 
                               aLightShadowFraction, aPreShadowIntensity, aLightBlindData);
    lAttr.setArray(true);
    lAttr.setStorable(false);
    lAttr.setHidden(true);
    lAttr.setDefault(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, true, false, 1.0f, 1.0f, 0);

    addAttribute(aTranslucenceCoeff);
    addAttribute(aDiffuse);
    addAttribute(aColorR);
    addAttribute(aColorG);
    addAttribute(aColorB);
    addAttribute(aColor);
	addAttribute ( aColorR2 ) ;
    addAttribute ( aColorG2 ) ;
    addAttribute ( aColorB2 ) ;
    addAttribute ( aColor2 ) ;

    addAttribute(aIncandescenceR);
    addAttribute(aIncandescenceG);
    addAttribute(aIncandescenceB);
    addAttribute(aIncandescence);
    addAttribute(aInTransR);
    addAttribute(aInTransG);
    addAttribute(aInTransB);
    addAttribute(aInTransparency);
    addAttribute(aOutColorR);
    addAttribute(aOutColorG);
    addAttribute(aOutColorB);
    addAttribute(aOutColor);
    addAttribute(aOutTransR);
    addAttribute(aOutTransG);
    addAttribute(aOutTransB);
    addAttribute(aOutTransparency);
    addAttribute(aNormalCameraX);
    addAttribute(aNormalCameraY);
    addAttribute(aNormalCameraZ);
    addAttribute(aNormalCamera);
	addAttribute(aPointCameraX);
    addAttribute(aPointCameraY);
    addAttribute(aPointCameraZ);
	addAttribute(aPointCamera);

	addAttribute ( aRinkaku ) ;
	addAttribute ( aShadow ) ;

	addAttribute(aLightDirectionX);
    addAttribute(aLightDirectionY);
    addAttribute(aLightDirectionZ);
    addAttribute(aLightDirection);
    addAttribute(aLightIntensityR);
    addAttribute(aLightIntensityG);
    addAttribute(aLightIntensityB);
    addAttribute(aLightIntensity);
    addAttribute(aLightAmbient);
    addAttribute(aLightDiffuse);
    addAttribute(aLightSpecular);
    addAttribute(aLightShadowFraction);
    addAttribute(aPreShadowIntensity);
	addAttribute ( aLightBlindData ) ;
    addAttribute(aLightData);

    attributeAffects (aTranslucenceCoeff, aOutColor);
    attributeAffects (aDiffuse, aOutColor);
    attributeAffects (aColorR, aOutColor);
    attributeAffects (aColorG, aOutColor);
    attributeAffects (aColorB, aOutColor);
    attributeAffects (aColor, aOutColor);
	attributeAffects ( aColorR2, aOutColor ) ;
    attributeAffects ( aColorG2, aOutColor ) ;
    attributeAffects ( aColorB2, aOutColor ) ;
    attributeAffects ( aColor2, aOutColor ) ;
    attributeAffects (aInTransR, aOutTransparency);
    attributeAffects (aInTransG, aOutTransparency);
    attributeAffects (aInTransB, aOutTransparency);
    attributeAffects (aInTransparency, aOutTransparency);
    attributeAffects (aInTransparency, aOutColor);
    attributeAffects (aIncandescenceR, aOutColor);
    attributeAffects (aIncandescenceG, aOutColor);
    attributeAffects (aIncandescenceB, aOutColor);
    attributeAffects (aIncandescence, aOutColor);
    attributeAffects (aLightIntensityR, aOutColor);
    attributeAffects (aLightIntensityB, aOutColor);
    attributeAffects (aLightIntensityG, aOutColor);
    attributeAffects (aLightIntensity, aOutColor);
    attributeAffects (aNormalCameraX, aOutColor);
    attributeAffects (aNormalCameraY, aOutColor);
    attributeAffects (aNormalCameraZ, aOutColor);
    attributeAffects (aNormalCamera, aOutColor);
	attributeAffects (aPointCameraX, aOutColor);
    attributeAffects (aPointCameraY, aOutColor);
    attributeAffects (aPointCameraZ,  aOutColor);
    attributeAffects (aPointCamera, aOutColor);

	attributeAffects ( aRinkaku, aOutColor ) ;
	attributeAffects ( aShadow, aOutColor ) ;

    attributeAffects (aLightDirectionX, aOutColor);
    attributeAffects (aLightDirectionY, aOutColor);
    attributeAffects (aLightDirectionZ, aOutColor);
    attributeAffects (aLightDirection, aOutColor);
    attributeAffects (aLightAmbient, aOutColor);
    attributeAffects (aLightSpecular, aOutColor);
    attributeAffects (aLightDiffuse, aOutColor);
    attributeAffects (aLightShadowFraction, aOutColor);
    attributeAffects (aPreShadowIntensity, aOutColor);
	attributeAffects ( aLightBlindData, aOutColor ) ;
    attributeAffects (aLightData, aOutColor);
	
    return MS::kSuccess;
}

MStatus toon::compute(
const MPlug&      plug,
      MDataBlock& block ) 
{ 
  if( plug == aOutColor || 
      plug == aOutColorR ||
      plug == aOutColorG ||
      plug == aOutColorB ||
      plug == aOutTransparency || 
      plug == aOutTransR ||
      plug == aOutTransG ||
      plug == aOutTransB )
  {

    MFloatVector resultColor(0.0,0.0,0.0);

    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    MFloatVector& surfaceColor  = block.inputValue( aColor ).asFloatVector();
	MFloatVector& surfaceColor2 = block.inputValue ( aColor2 ).asFloatVector () ;
    MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector();
	MFloatVector&  viewVector = block.inputValue( aPointCamera ).asFloatVector();

	float& rin = block.inputValue ( aRinkaku ).asFloat () ;
	float& sha = block.inputValue ( aShadow ).asFloat () ;

    float diffuse = block.inputValue( aDiffuse ).asFloat();
    float translucenceCoeff   = block.inputValue( aTranslucenceCoeff ).asFloat();
	float nor = block.inputValue( aNormalCameraZ ).asFloat();

	// Normalize the view vector
    double d = sqrt((viewVector[0] * viewVector[0]) +
                    (viewVector[1] * viewVector[1]) +
                    (viewVector[2] * viewVector[2]));


    if (d != (double)0.0) {
        viewVector[0] /= d;
        viewVector[1] /= d;
        viewVector[2] /= d;
    }

	viewVector[0] *= -1 ;
	viewVector[1] *= -1 ;
	viewVector[2] *= -1 ;


    // get light list
    MArrayDataHandle lightData = block.inputArrayValue( aLightData );
    int numLights = lightData.elementCount();

    // iterate through light list and get ambient/diffuse values
    for( int count=1; count <= numLights; count++ ) {
        MDataHandle currentLight = lightData.inputValue();
        MFloatVector& lightIntensity = currentLight.child(aLightIntensity).asFloatVector();

        // find diffuse component
        if( currentLight.child(aLightDiffuse).asBool() ) {
            MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector();
            float cosln = lightDirection * surfaceNormal;
			float sign = surfaceNormal * viewVector ;
			
           if( cosln > diffuse ) {
			   resultColor[0] += surfaceColor[0] ;
			   resultColor[1] += surfaceColor[1] ;
			   resultColor[2] += surfaceColor[2] ;
           } else {
				resultColor[0] += surfaceColor2[0] ;
				resultColor[1] += surfaceColor2[1] ;
				resultColor[2] += surfaceColor2[2] ;
		   }

		   if ( lightIntensity [0] < 1.0 ) {
				resultColor[0] *= sha ;
				resultColor[1] *= sha ;
				resultColor[2] *= sha ;
		   }

		   //輪郭線を決める
		   if ( sign > 0.0 && sign < rin ) {
				resultColor[0] = 0.0 ;
				resultColor[1] = 0.0 ;
				resultColor[2] = 0.0 ;
		   }
		   
        }
        if( !lightData.next() ) break;
    }

	resultColor[0] += incandescence[0] ;
	resultColor[1] += incandescence[1] ;
	resultColor[2] += incandescence[2] ;
    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();


    MFloatVector& transparency = block.inputValue( aInTransparency ).asFloatVector();

    // set ouput transparency
    MDataHandle outTransHandle = block.outputValue( aOutTransparency );
    MFloatVector& outTrans = outTransHandle.asFloatVector();
    outTrans = transparency;
    outTransHandle.setClean();

  } else
		return MS::kUnknownParameter;

  return MS::kSuccess;
}

//////////////////////////////////////////////////////////////////////////////
//			プラグインのチェックを付けたときにそれを起動する
//////////////////////////////////////////////////////////////////////////////
MStatus initializePlugin( MObject obj )
{ 
   const MString UserClassify( "shader/surface" );
MString command( "if( `window -exists createRenderNodeWindow` )  {refreshCreateRenderNodeWindow(\"" );

   MFnPlugin plugin( obj, "Shouji Fukuda", "1.0", "3.0");
   plugin.registerNode( "toonShader", toon::id, 
                         toon::creator, toon::initialize,
                         MPxNode::kDependNode, &UserClassify );
   command += UserClassify;
   command += "\");}\n";

   MGlobal::executeCommand(command);

	
   return MS::kSuccess;
}

//////////////////////////////////////////////////////////////////////////////
//			プラグインのチェックを外したときにそれをclearする
//////////////////////////////////////////////////////////////////////////////
MStatus uninitializePlugin( MObject obj )
{
   const MString UserClassify( "shader/surface" );
MString command( "if( `window -exists createRenderNodeWindow` )  {refreshCreateRenderNodeWindow(\"" );

   MFnPlugin plugin( obj );
   plugin.deregisterNode( toon::id );

   command += UserClassify;
   command += "\");}\n";

   MGlobal::executeCommand(command);

   return MS::kSuccess;
}

//////////////////////////////////////////////////////////////////////////////
//							EOF	ToonShader.cpp
//////////////////////////////////////////////////////////////////////////////

