MStatus sphericalBlendShapeVisualizer::initialize()
		
{
	MStatus status;

	MFnMatrixAttribute mAttr;
	MFnEnumAttribute   eAttr;

	aSpaceMatrix = mAttr.create("spaceMatrix", "spaceMatrix", MFnMatrixAttribute::kDouble, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);

	aPoleAxis = eAttr.create("poleAxis", "poleAxis", 1, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	eAttr.addField("+X", 0);
	eAttr.addField("+Y", 1);
	eAttr.addField("+Z", 2);
	eAttr.addField("-X", 3);
	eAttr.addField("-Y", 4);
	eAttr.addField("-Z", 5);
	eAttr.setDefault(1);
	eAttr.setKeyable(true);
	eAttr.setStorable(true);
	eAttr.setWritable(true);

	aSeamAxis = eAttr.create("seamAxis", "seamAxis", 0, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	eAttr.addField("+X", 0);
	eAttr.addField("+Y", 1);
	eAttr.addField("+Z", 2);
	eAttr.addField("-X", 3);
	eAttr.addField("-Y", 4);
	eAttr.addField("-Z", 5);
	eAttr.setDefault(0);
	eAttr.setKeyable(true);
	eAttr.setStorable(true);
	eAttr.setWritable(true);

	addAttribute(aSpaceMatrix);
	addAttribute(aPoleAxis);
	addAttribute(aSeamAxis);

	return MS::kSuccess;
}
Example #2
0
MStatus ModifyArrayNode::initialize()
{
    MStatus status;

    MFnTypedAttribute T;
    MFnNumericAttribute N;
    MFnEnumAttribute E;

    aInput = T.create("input", "i", MFnData::kDoubleArray);
    T.setKeyable(false);
    T.setChannelBox(false);
    T.setStorable(true);
    T.setWritable(true);

    aOperation = E.create("operation", "operation");
    E.addField("No Operation", kNO_OP);
    E.addField("Sort", kSORT);
    E.addField("Absolute Value", kABS);
    E.addField("Reflect Left", kREFLECT_LEFT);
    E.addField("Reflect Right", kREFLECT_RIGHT);
    E.setDefault(kNO_OP);
    E.setKeyable(true);
    E.setStorable(true);
    E.setWritable(true);

    aReverse = N.create("reverse", "rev", MFnNumericData::kBoolean);
    N.setKeyable(true);
    N.setChannelBox(true);
    N.setStorable(true);
    N.setWritable(true);

    aOutput = T.create("output", "o", MFnData::kDoubleArray);
    T.setKeyable(false);
    T.setChannelBox(false);
    T.setWritable(false);
    T.setStorable(false);

    addAttribute(aOperation);
    addAttribute(aInput);
    addAttribute(aReverse);
    addAttribute(aOutput);

    attributeAffects(aOperation, aOutput);
    attributeAffects(aInput, aOutput);
    attributeAffects(aReverse, aOutput);

    return MS::kSuccess;
}
Example #3
0
MStatus TestDeformer::initialize()
{
	MFnNumericAttribute numericAttr;
	MFnTypedAttribute polyMeshAttr;
	MFnEnumAttribute enumAttr;

	MStatus status; // Status will be used to hold the MStatus value

	// vertSnapInput
	driver_mesh = polyMeshAttr.create( "vertSnapInput", "vsnpin", MFnData::kMesh, &status );
	CHECK_MSTATUS( status );
	CHECK_MSTATUS( polyMeshAttr.setStorable( false ) );
	CHECK_MSTATUS( polyMeshAttr.setArray(true) );
	CHECK_MSTATUS( polyMeshAttr.setConnectable( true ) );
	CHECK_MSTATUS( addAttribute(driver_mesh) );
	CHECK_MSTATUS( attributeAffects(driver_mesh, outputGeom) );

	// initialize is used to mark this node's state
	initialized_data = enumAttr.create( "initialize", "inl", 0/*default*/, &status );
	CHECK_MSTATUS( status );
	CHECK_MSTATUS( enumAttr.addField(	"Off", 0) );
	CHECK_MSTATUS( enumAttr.addField(	"Re-Set Bind", 1) );
	CHECK_MSTATUS( enumAttr.addField(	"Bound", 2) );
	CHECK_MSTATUS( enumAttr.setKeyable(true) );
	CHECK_MSTATUS( enumAttr.setStorable(true) );
	CHECK_MSTATUS( enumAttr.setReadable(true) );
	CHECK_MSTATUS( enumAttr.setWritable(true) );
	CHECK_MSTATUS( enumAttr.setDefault(0) );
	CHECK_MSTATUS( addAttribute( initialized_data ) );
	CHECK_MSTATUS( attributeAffects( initialized_data, outputGeom ) );

    // hold the vertex index mapping
	vert_map = numericAttr.create( "vtxIndexMap", "vtximp", MFnNumericData::kLong, 0/*default*/, &status );
	CHECK_MSTATUS( status );
    CHECK_MSTATUS( numericAttr.setKeyable(false) );
	CHECK_MSTATUS( numericAttr.setArray(true) );
	CHECK_MSTATUS( numericAttr.setStorable(true) );
	CHECK_MSTATUS( numericAttr.setReadable(true) );
	CHECK_MSTATUS( numericAttr.setWritable(true) );
	CHECK_MSTATUS( addAttribute( vert_map ) );
	CHECK_MSTATUS( attributeAffects( vert_map, outputGeom ) );

	CHECK_MSTATUS( MGlobal::executePythonCommand("import maya.cmds; maya.cmds.makePaintable('"+TestDeformer::cTypeName()+"', 'weights', attrType='multiFloat')") );

	return( MS::kSuccess );
}
Example #4
0
MStatus ReduceArrayNode::initialize()
{
    MStatus status;

    MFnTypedAttribute T;
    MFnNumericAttribute N;
    MFnEnumAttribute E;

    aInput = T.create("input", "i", MFnData::kDoubleArray);
    T.setKeyable(false);
    T.setChannelBox(false);
    T.setStorable(true);
    T.setWritable(true);

    aOutput = N.create("output", "o", MFnNumericData::kDouble, 0.0);
    T.setKeyable(false);
    T.setChannelBox(false);
    T.setWritable(true);
    T.setStorable(true);

    aOperation = E.create("operation", "operation");
    E.addField("No Operation", kNO_OP);
    E.addField("Sum", kSUM);
    E.addField("Difference", kDIFFERENCE);
    E.addField("Average", kAVERAGE);
    E.addField("Product", kPRODUCT);
    E.addField("Quotient", kQUOTIENT);
    E.addField("Exponent", kEXPONENT);
    E.addField("Minimum", kMIN);
    E.addField("Maximum", kMAX);
    E.addField("Length", kLENGTH);
    E.setKeyable(true);
    E.setStorable(true);
    E.setWritable(true);

    addAttribute(aOperation);
    addAttribute(aInput);
    addAttribute(aOutput);

    attributeAffects(aOperation, aOutput);
    attributeAffects(aInput, aOutput);

    return MS::kSuccess;
}
Example #5
0
MStatus AlembicNode::initialize()
{
    MStatus status;

    MFnUnitAttribute    uAttr;
    MFnTypedAttribute   tAttr;
    MFnNumericAttribute nAttr;
    MFnGenericAttribute gAttr;
    MFnEnumAttribute    eAttr;

    // add the input attributes: time, file, sequence time
    mTimeAttr = uAttr.create("time", "tm", MFnUnitAttribute::kTime, 0.0);
    status = uAttr.setStorable(true);
    status = addAttribute(mTimeAttr);

    // input file name
    MFnStringData fileFnStringData;
    MObject fileNameDefaultObject = fileFnStringData.create("");
    mAbcFileNameAttr = tAttr.create("abc_File", "fn",
        MFnData::kString, fileNameDefaultObject);
    status = tAttr.setStorable(true);
    status = tAttr.setUsedAsFilename(true);
    status = addAttribute(mAbcFileNameAttr);

    // playback speed
    mSpeedAttr = nAttr.create("speed", "sp",
        MFnNumericData::kDouble, 1.0, &status);
    status = nAttr.setWritable(true);
    status = nAttr.setStorable(true);
    status = nAttr.setKeyable(true);
    status = addAttribute(mSpeedAttr);

    // frame offset
    mOffsetAttr = nAttr.create("offset", "of",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(true);
    status = nAttr.setStorable(true);
    status = nAttr.setKeyable(true);
    status = addAttribute(mOffsetAttr);

    // cycle type
    mCycleTypeAttr = eAttr.create("cycleType", "ct", 0,  &status );
    status = eAttr.addField("Hold", PLAYTYPE_HOLD);
    status = eAttr.addField("Loop", PLAYTYPE_LOOP);
    status = eAttr.addField("Reverse", PLAYTYPE_REVERSE);
    status = eAttr.addField("Bounce", PLAYTYPE_BOUNCE);
    status = eAttr.setWritable(true);
    status = eAttr.setStorable(true);
    status = eAttr.setKeyable(true);
    status = addAttribute(mCycleTypeAttr);

    // Regex Filter
    // This is a hidden variable to preserve a regexIncludefilter string
    // into a .ma file.
    mIncludeFilterAttr = tAttr.create("regexIncludeFilter", "ift",
        MFnData::kString);
    status = tAttr.setStorable(true);
    status = tAttr.setHidden(true);
    status = addAttribute(mIncludeFilterAttr);

    // Regex Filter
    // This is a hidden variable to preserve a regexExcludefilter string
    // into a .ma file.
    mExcludeFilterAttr = tAttr.create("regexExcludeFilter", "eft",
        MFnData::kString);
    status = tAttr.setStorable(true);
    status = tAttr.setHidden(true);
    status = addAttribute(mExcludeFilterAttr);

    // sequence min and max in frames
    mStartFrameAttr = nAttr.create("startFrame", "sf",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(false);
    status = nAttr.setStorable(true);
    status = addAttribute(mStartFrameAttr);

    mEndFrameAttr = nAttr.create("endFrame", "ef",
        MFnNumericData::kDouble, 0, &status);
    status = nAttr.setWritable(false);
    status = nAttr.setStorable(true);
    status = addAttribute(mEndFrameAttr);

    // add the output attributes
    // sampled subD mesh
    MFnMeshData fnMeshData;
    MObject meshDefaultObject = fnMeshData.create(&status);
    mOutSubDArrayAttr = tAttr.create("outSubDMesh", "osubd",
        MFnData::kMesh, meshDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutSubDArrayAttr);

    // sampled poly mesh
    mOutPolyArrayAttr = tAttr.create("outPolyMesh", "opoly",
        MFnData::kMesh, meshDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutPolyArrayAttr);

    // sampled nurbs surface
    MFnNurbsSurfaceData fnNSData;
    MObject nsDefaultObject = fnNSData.create(&status);
    mOutNurbsSurfaceArrayAttr = tAttr.create("outNSurface", "ons",
        MFnData::kNurbsSurface, nsDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutNurbsSurfaceArrayAttr);

    // sampled nurbs curve group
    MFnNurbsCurveData fnNCData;
    MObject ncDefaultObject = fnNCData.create(&status);
    mOutNurbsCurveGrpArrayAttr = tAttr.create("outNCurveGrp", "onc",
        MFnData::kNurbsCurve, ncDefaultObject);
    status = tAttr.setStorable(false);
    status = tAttr.setWritable(false);
    status = tAttr.setKeyable(false);
    status = tAttr.setArray(true);
    status = tAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutNurbsCurveGrpArrayAttr);

    // sampled locator
    mOutLocatorPosScaleArrayAttr = nAttr.create("outLoc", "olo",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutLocatorPosScaleArrayAttr);

    // sampled transform operations
    mOutTransOpArrayAttr = nAttr.create("transOp", "to",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutTransOpArrayAttr);

    // sampled camera
    // assume the boolean variables cannot be keyed
    mOutCameraArrayAttr = nAttr.create("outCamera", "ocam",
        MFnNumericData::kDouble, 0.0, &status);
    status = nAttr.setStorable(false);
    status = nAttr.setWritable(false);
    status = nAttr.setArray(true);
    status = nAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutCameraArrayAttr);

    // sampled custom-attributes
    mOutPropArrayAttr = gAttr.create("prop", "pr", &status);
    status = gAttr.addNumericDataAccept(MFnNumericData::kBoolean);
    status = gAttr.addNumericDataAccept(MFnNumericData::kByte);
    status = gAttr.addNumericDataAccept(MFnNumericData::kShort);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Short);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Short);
    status = gAttr.addNumericDataAccept(MFnNumericData::kInt);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Int);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Int);
    status = gAttr.addNumericDataAccept(MFnNumericData::kFloat);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Float);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Float);
    status = gAttr.addNumericDataAccept(MFnNumericData::kDouble);
    status = gAttr.addNumericDataAccept(MFnNumericData::k2Double);
    status = gAttr.addNumericDataAccept(MFnNumericData::k3Double);
    status = gAttr.addNumericDataAccept(MFnNumericData::k4Double);
    status = gAttr.addDataAccept(MFnData::kString);
    status = gAttr.addDataAccept(MFnData::kIntArray);
    status = gAttr.addDataAccept(MFnData::kDoubleArray);
    status = gAttr.addDataAccept(MFnData::kVectorArray);
    status = gAttr.addDataAccept(MFnData::kPointArray);

    status = gAttr.setWritable(false);
    status = gAttr.setKeyable(false);
    status = gAttr.setArray(true);
    status = gAttr.setUsesArrayDataBuilder(true);
    status = addAttribute(mOutPropArrayAttr);

    // set up affection relationships
    status = attributeAffects(mTimeAttr, mOutSubDArrayAttr);
    status = attributeAffects(mTimeAttr, mOutPolyArrayAttr);
    status = attributeAffects(mTimeAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mTimeAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mTimeAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mTimeAttr, mOutCameraArrayAttr);
    status = attributeAffects(mTimeAttr, mOutPropArrayAttr);
    status = attributeAffects(mTimeAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mSpeedAttr, mOutSubDArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutPolyArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutCameraArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutPropArrayAttr);
    status = attributeAffects(mSpeedAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mOffsetAttr, mOutSubDArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutPolyArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutCameraArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutPropArrayAttr);
    status = attributeAffects(mOffsetAttr, mOutLocatorPosScaleArrayAttr);

    status = attributeAffects(mCycleTypeAttr, mOutSubDArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutPolyArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutNurbsSurfaceArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutNurbsCurveGrpArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutTransOpArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutCameraArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutPropArrayAttr);
    status = attributeAffects(mCycleTypeAttr, mOutLocatorPosScaleArrayAttr);

    MGlobal::executeCommand( UITemplateMELScriptStr );

    return status;
}
MStatus sphericalBlendShape::initialize()
{
	MStatus status;

	MFnMatrixAttribute mAttr;
	MFnEnumAttribute   eAttr;

	aSpaceMatrix = mAttr.create("spaceMatrix", "spaceMatrix", MFnMatrixAttribute::kDouble, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);

	aPoleAxis = eAttr.create("poleAxis", "poleAxis", 1, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	eAttr.addField("+X", 0);
	eAttr.addField("+Y", 1);
	eAttr.addField("+Z", 2);
	eAttr.addField("-X", 3);
	eAttr.addField("-Y", 4);
	eAttr.addField("-Z", 5);
	eAttr.setDefault(1);
	eAttr.setKeyable(true);
	eAttr.setStorable(true);
	eAttr.setWritable(true);

	aSeamAxis = eAttr.create("seamAxis", "seamAxis", 0, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	eAttr.addField("+X", 0);
	eAttr.addField("+Y", 1);
	eAttr.addField("+Z", 2);
	eAttr.addField("-X", 3);
	eAttr.addField("-Y", 4);
	eAttr.addField("-Z", 5);
	eAttr.setDefault(0);
	eAttr.setKeyable(true);
	eAttr.setStorable(true);
	eAttr.setWritable(true);

	aWarpMatrix = mAttr.create("warpMatrix", "warpMatrix", MFnMatrixAttribute::kDouble, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);

	aMethod = eAttr.create("conversionMethod", "conversionMethod", 0, &status);
	CHECK_MSTATUS_AND_RETURN_IT(status);
	eAttr.addField("xyzToSpherical", 0);
	eAttr.addField("sphericalToXyz", 1);
	eAttr.setDefault(0);
	eAttr.setKeyable(true);
	eAttr.setStorable(true);
	eAttr.setWritable(true);

	addAttribute(aSpaceMatrix);
	addAttribute(aPoleAxis);
	addAttribute(aSeamAxis);
	addAttribute(aWarpMatrix);
	addAttribute(aMethod);

	attributeAffects(aSpaceMatrix, outputGeom);
	attributeAffects(aPoleAxis, outputGeom);
	attributeAffects(aSeamAxis, outputGeom);
	attributeAffects(aWarpMatrix, outputGeom);
	attributeAffects(aMethod, outputGeom);

	return MS::kSuccess;
}
Example #7
0
// Create and Add Attributes
//
//  Description:
//      This method is called to create and initialize all of the attributes
//      and attribute dependencies for this node type.  This is only called
//      once when the node type is registered with Maya.
//
//  Return Values:
//      MS::kSuccess
//      MS::kFailure
//
MStatus
MayaPolySmooth::initialize() {

    MStatus stat;

    MFnCompoundAttribute  cAttr;
    MFnEnumAttribute      eAttr;
    MFnGenericAttribute   gAttr;
    MFnLightDataAttribute lAttr;
    MFnMatrixAttribute    mAttr;
    MFnMessageAttribute   msgAttr;
    MFnNumericAttribute   nAttr;
    MFnTypedAttribute     tAttr;
    MFnUnitAttribute      uAttr;

    // MAYA_NODE_BUILDER:BEG [ATTRIBUTE CREATION] ==========
    // a_inputPolymesh : This is a description for this attribute
    a_inputPolymesh = tAttr.create("inputPolymesh", "ip", MFnData::kMesh, MObject::kNullObj, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::inputPolymesh" );
    stat = tAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::inputPolymesh.setReadable()" );
    stat = tAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::inputPolymesh.setWritable()" );
    stat = tAttr.setHidden(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::inputPolymesh.setHidden()" );
    stat = addAttribute( a_inputPolymesh );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_inputPolymesh)" );

    // a_output : This is a description for this attribute
    a_output = tAttr.create("output", "out", MFnData::kMesh, MObject::kNullObj, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::output" );
    stat = tAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::output.setReadable()" );
    stat = tAttr.setWritable(false);
    MCHECKERR( stat, "cannot MayaPolySmooth::output.setWritable()" );
    stat = tAttr.setHidden(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::output.setHidden()" );
    stat = addAttribute( a_output );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_output)" );

    // a_subdivisionLevels : The number of recursive quad subdivisions to perform on each face.
    a_subdivisionLevels = nAttr.create("subdivisionLevels", "sl", MFnNumericData::kInt, 0.0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::subdivisionLevels" );
    stat = nAttr.setDefault(2);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setDefault(2)" );
    stat = nAttr.setMin(0);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setMin(0)" );
    stat = nAttr.setMax(10);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setMax(10)" );
    stat = nAttr.setSoftMax(4);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setSoftMax(4)" );
    stat = nAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setReadable()" );
    stat = nAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::subdivisionLevels.setWritable()" );
    stat = addAttribute( a_subdivisionLevels );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_subdivisionLevels)" );

    // a_recommendedIsolation : The number of recursive quad subdivisions to perform on each face.
    a_recommendedIsolation = nAttr.create("recommendedIsolation", "ri", MFnNumericData::kInt, 0.0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::recommendedIsolation" );
    stat = nAttr.setDefault(2);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setDefault(0)" );
    stat = nAttr.setMin(0);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setMin(0)" );
    stat = nAttr.setMax(10);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setSoftMax(10)" );
    stat = nAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setReadable()" );
    stat = nAttr.setWritable(false);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setWritable()" );
    stat = nAttr.setHidden(false);
    MCHECKERR( stat, "cannot MayaPolySmooth::recommendedIsolation.setHidden()" );
    stat = addAttribute( a_recommendedIsolation );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_recommendedIsolation)" );

    // a_vertBoundaryMethod : Controls how boundary edges and vertices are interpolated. <ul> <li>Smooth, Edges: Renderman: InterpolateBoundaryEdgeOnly</li> <li>Smooth, Edges and Corners: Renderman: InterpolateBoundaryEdgeAndCorner</li> </ul>
    a_vertBoundaryMethod = eAttr.create("vertBoundaryMethod", "vbm", 0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::vertBoundaryMethod" );
    stat = eAttr.addField("Interpolate Edges", k_BoundaryMethod_InterpolateBoundaryEdgeOnly);
    MCHECKERR( stat, "cannot MayaPolySmooth::vertBoundaryMethod.addField(Interpolate Edges, k_BoundaryMethod_InterpolateBoundaryEdgeOnly)" );
    stat = eAttr.addField("Interpolate Edges And Corners", k_BoundaryMethod_InterpolateBoundaryEdgeAndCorner);
    MCHECKERR( stat, "cannot MayaPolySmooth::vertBoundaryMethod.addField(Interpolate Edges And Corners, k_BoundaryMethod_InterpolateBoundaryEdgeAndCorner)" );
    stat = eAttr.setDefault(k_BoundaryMethod_InterpolateBoundaryEdgeOnly);
    MCHECKERR( stat, "cannot MayaPolySmooth::vertBoundaryMethod.setDefault(k_BoundaryMethod_InterpolateBoundaryEdgeOnly)" );
    stat = eAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::vertBoundaryMethod.setReadable()" );
    stat = eAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::vertBoundaryMethod.setWritable()" );
    stat = addAttribute( a_vertBoundaryMethod );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_vertBoundaryMethod)" );

    // a_fvarBoundaryMethod : Controls how boundaries are treated for face-varying data (UVs and Vertex Colors). <ul> <li>Bi-linear (None): Renderman: InterpolateBoundaryNone</li> <li>Smooth, (Edge Only): Renderman: InterpolateBoundaryEdgeOnly</li> <li>Smooth, (Edges and Corners: Renderman: InterpolateBoundaryEdgeAndCorner</li> <li>Smooth, (ZBrush and Maya "Smooth Internal Only"): Renderman: InterpolateBoundaryAlwaysSharp</li> </ul>
    a_fvarBoundaryMethod = eAttr.create("fvarBoundaryMethod", "fvbm", 0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::fvarBoundaryMethod" );
    stat = eAttr.addField("Bi-linear (None)", k_BoundaryMethod_InterpolateBoundaryNone);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.addField(Bi-linear (None), k_BoundaryMethod_InterpolateBoundaryNone)" );
    stat = eAttr.addField("Smooth (Edge Only)", k_BoundaryMethod_InterpolateBoundaryEdgeOnly);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.addField(Smooth (Edge Only), k_BoundaryMethod_InterpolateBoundaryEdgeOnly)" );
    stat = eAttr.addField("Smooth (Edge and Corner)", k_BoundaryMethod_InterpolateBoundaryEdgeAndCorner);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.addField(Smooth (Edge and Corner), k_BoundaryMethod_InterpolateBoundaryEdgeAndCorner)" );
    stat = eAttr.addField("Smooth (Always Sharp)", k_BoundaryMethod_InterpolateBoundaryAlwaysSharp);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.addField(Smooth (Always Sharp), k_BoundaryMethod_InterpolateBoundaryAlwaysSharp)" );
    stat = eAttr.setDefault(k_BoundaryMethod_InterpolateBoundaryNone);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.setDefault(k_BoundaryMethod_InterpolateBoundaryNone)" );
    stat = eAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.setReadable()" );
    stat = eAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarBoundaryMethod.setWritable()" );
    stat = addAttribute( a_fvarBoundaryMethod );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_fvarBoundaryMethod)" );

    // a_fvarPropagateCorners :
    a_fvarPropagateCorners = nAttr.create("fvarPropagateCorners", "fvpc", MFnNumericData::kBoolean, 0.0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::fvarPropagateCorners" );
    stat = nAttr.setDefault(false);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarPropagateCorners.setDefault(false)" );
    stat = nAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarPropagateCorners.setReadable()" );
    stat = nAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::fvarPropagateCorners.setWritable()" );
    stat = addAttribute( a_fvarPropagateCorners );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_fvarPropagateCorners)" );

    // a_smoothTriangles : Apply a special subdivision rule be applied to all triangular faces that was empirically determined to make triangles subdivide more smoothly.
    a_smoothTriangles = nAttr.create("smoothTriangles", "stri", MFnNumericData::kBoolean, 0.0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::smoothTriangles" );
    stat = nAttr.setDefault(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::smoothTriangles.setDefault(true)" );
    stat = nAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::smoothTriangles.setReadable()" );
    stat = nAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::smoothTriangles.setWritable()" );
    stat = addAttribute( a_smoothTriangles );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_smoothTriangles)" );

    // a_creaseMethod : Controls how boundary edges and vertices are interpolated. <ul> <li>Normal</li> <li>Chaikin: Improves the appearance of multiedge creases with varying weight</li> </ul>
    a_creaseMethod = eAttr.create("creaseMethod", "crm", 0, &stat);
    MCHECKERR( stat, "cannot create MayaPolySmooth::creaseMethod" );
    stat = eAttr.addField("Normal", k_creaseMethod_normal);
    MCHECKERR( stat, "cannot MayaPolySmooth::creaseMethod.addField(Normal, k_creaseMethod_normal)" );
    stat = eAttr.addField("Chaikin", k_creaseMethod_chaikin);
    MCHECKERR( stat, "cannot MayaPolySmooth::creaseMethod.addField(Chaikin, k_creaseMethod_chaikin)" );
    stat = eAttr.setDefault(0);
    MCHECKERR( stat, "cannot MayaPolySmooth::creaseMethod.setDefault(0)" );
    stat = eAttr.setReadable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::creaseMethod.setReadable()" );
    stat = eAttr.setWritable(true);
    MCHECKERR( stat, "cannot MayaPolySmooth::creaseMethod.setWritable()" );
    stat = addAttribute( a_creaseMethod );
    MCHECKERR( stat, "cannot MayaPolySmooth::addAttribute(a_creaseMethod)" );

    // MAYA_NODE_BUILDER:END [ATTRIBUTE CREATION] ==========


    // Set up a dependency between the input and the output.  This will cause
    // the output to be marked dirty when the input changes.  The output will
    // then be recomputed the next time the value of the output is requested.
    //
    // MAYA_NODE_BUILDER:BEG [ATTRIBUTE DEPENDS] ==========
    stat = attributeAffects( a_creaseMethod, a_output );
    MCHECKERR( stat, "cannot have attribute creaseMethod affect output" );
    stat = attributeAffects( a_inputPolymesh, a_output );
    MCHECKERR( stat, "cannot have attribute inputPolymesh affect output" );
    stat = attributeAffects( a_subdivisionLevels, a_output );
    MCHECKERR( stat, "cannot have attribute subdivisionLevels affect output" );
    stat = attributeAffects( a_smoothTriangles, a_output );
    MCHECKERR( stat, "cannot have attribute smoothTriangles affect output" );
    stat = attributeAffects( a_fvarPropagateCorners, a_output );
    MCHECKERR( stat, "cannot have attribute fvarPropagateCorners affect output" );
    stat = attributeAffects( a_vertBoundaryMethod, a_output );
    MCHECKERR( stat, "cannot have attribute vertBoundaryMethod affect output" );
    stat = attributeAffects( a_fvarBoundaryMethod, a_output );
    MCHECKERR( stat, "cannot have attribute fvarBoundaryMethod affect output" );

    stat = attributeAffects( a_creaseMethod, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute creaseMethod affect .si output" );
    stat = attributeAffects( a_inputPolymesh, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute inputPolymesh affect .si output" );
    stat = attributeAffects( a_subdivisionLevels, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute subdivisionLevels affect .si output" );
    stat = attributeAffects( a_smoothTriangles, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute smoothTriangles affect .si output" );
    stat = attributeAffects( a_fvarPropagateCorners, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute fvarPropagateCorners affect .si output" );
    stat = attributeAffects( a_vertBoundaryMethod, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute vertBoundaryMethod affect .si output" );
    stat = attributeAffects( a_fvarBoundaryMethod, a_recommendedIsolation );
    MCHECKERR( stat, "cannot have attribute fvarBoundaryMethod affect .si output" );
    // MAYA_NODE_BUILDER:END [ATTRIBUTE DEPENDS] ==========

    return MS::kSuccess;
}
Example #8
0
MStatus VmIslandNode::initialize()
{
    fprintf( stderr, "VmIslandNode::initialize()...\n" );
    
    MStatus status;
    
    //Seed attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_seed = numericAttrFn.create( "seed", "sD", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0 );
        numericAttrFn.setMax( 1000 );
        numericAttrFn.setDefault ( 0 );
        status = addAttribute( ia_seed );
        CHECK_MSTATUS( status );
    }
    
    //Roughness attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_roughness = numericAttrFn.create( "roughness", "rG", MFnNumericData::kFloat, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0 );
        numericAttrFn.setMax( 1 );
        numericAttrFn.setDefault ( 0.75 );
        status = addAttribute( ia_roughness );
        CHECK_MSTATUS( status );
    }
    
    //Plane Height attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_planeHeight = numericAttrFn.create( "planeHeight", "pH", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0 );
        numericAttrFn.setMax( 2000 );
        numericAttrFn.setDefault ( 5 );
        status = addAttribute( ia_planeHeight );
        CHECK_MSTATUS( status );
    }

     //Plane smoothing attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_smooth = numericAttrFn.create( "smoothingStrength", "sS", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0 );
        numericAttrFn.setMax( 6 );
        numericAttrFn.setDefault ( 1 );
        status = addAttribute( ia_smooth );
        CHECK_MSTATUS( status );
    }
    
     //Plane resolution attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_resolution = numericAttrFn.create( "mayaResolution", "mR", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 1 );
        numericAttrFn.setMax( 10 );
        numericAttrFn.setDefault ( 1 );
        status = addAttribute( ia_resolution );
        CHECK_MSTATUS( status );
    }

    //Renderman resolution attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_rmanResolution = numericAttrFn.create( "rendermanResolution", "rR", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 1 );
        numericAttrFn.setMax( 10 );
        numericAttrFn.setDefault ( 6 );
        status = addAttribute( ia_rmanResolution );
        CHECK_MSTATUS( status );
    }

    //Plane size attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_planeSize = numericAttrFn.create( "planeSizeScale", "pS", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 1 );
        numericAttrFn.setMax( 200 );
        numericAttrFn.setDefault ( 20 );
        status = addAttribute( ia_planeSize );
        CHECK_MSTATUS( status );
    }


     //Plane size attribute
    {
        MFnNumericAttribute numericAttrFn;
        ia_gridSize = numericAttrFn.create( "gridSize", "gS", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 1 );
        numericAttrFn.setMax( 10 );
        numericAttrFn.setDefault ( 1 );
        status = addAttribute( ia_gridSize );
        CHECK_MSTATUS( status );
    }

     //Grass multiplier - Affects how many instances are spawned
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassMultiplier = numericAttrFn.create( "grassInstanceMultiplier", "gM", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 1 );
        numericAttrFn.setMax( 100 );
        numericAttrFn.setDefault ( 1 );
        status = addAttribute( ia_grassMultiplier );
        CHECK_MSTATUS( status );
    }


        //Grass multiplier - Affects how many instances are spawned
    {
        MFnNumericAttribute numericAttrFn;
        ia_baseWidth = numericAttrFn.create( "grassBaseWidth", "bW", MFnNumericData::kFloat, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0.01f );
        numericAttrFn.setMax( 2.0f ); 
        numericAttrFn.setDefault ( 0.6f );
        status = addAttribute( ia_baseWidth );
        CHECK_MSTATUS( status );
    }



    //Grass segment length - Length of segment pieces
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassSegmentLength = numericAttrFn.create( "grassSegmentLength", "gSL", MFnNumericData::kFloat, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0.001f );
        numericAttrFn.setMax( 10.0f );
        numericAttrFn.setDefault ( 1.0f );
        status = addAttribute( ia_grassSegmentLength );
        CHECK_MSTATUS( status );
    }

     //Number of segments per piece of grass
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassNumSegments = numericAttrFn.create( "numberOfGrassSegments", "nGS", MFnNumericData::kLong, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 3 );
        numericAttrFn.setMax( 20 );
        numericAttrFn.setDefault ( 5 );
        status = addAttribute( ia_grassNumSegments );
        CHECK_MSTATUS( status );
    }

    //Initial grass bend direction
    {
        MFnNumericAttribute numericAttrFn;
        ia_windDirection = numericAttrFn.createPoint( "windDirection", "wDir");
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setDefault(1.0f, 0.0f, 1.0f);
        status = addAttribute( ia_windDirection );
        CHECK_MSTATUS( status );
    }

    //Grass bend factor
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassBendAmount = numericAttrFn.create( "grassBendFactor", "gBF", MFnNumericData::kFloat, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0.0f );
        numericAttrFn.setMax( 1.0f );
        numericAttrFn.setDefault ( 0.0f );
        status = addAttribute( ia_grassBendAmount );
        CHECK_MSTATUS( status );
    }

    //Wind strength
    {
        MFnNumericAttribute numericAttrFn;
        ia_windSpread = numericAttrFn.create( "windSpread", "wS", MFnNumericData::kFloat, 0, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0.01f );
        numericAttrFn.setMax( 10.0f );
        numericAttrFn.setDefault ( 5.0f );
        status = addAttribute( ia_windSpread );
        CHECK_MSTATUS( status );
    }



        //Initial grass bend direction
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassBaseColour1 = numericAttrFn.createColor( "grassBaseColour1", "bCol1");
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setDefault(0.0f,0.251f,0.167f);
        status = addAttribute( ia_grassBaseColour1 );
        CHECK_MSTATUS( status );
    }

            //Initial grass bend direction
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassTipColour1 = numericAttrFn.createColor( "grassTipColour1", "tCol1");
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setDefault(0.395f,0.551f,0.257f);
        status = addAttribute( ia_grassTipColour1 );
        CHECK_MSTATUS( status );
    }

            //Initial grass bend direction
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassBaseColour2 = numericAttrFn.createColor( "grassBaseColour2", "bCol2");
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setDefault(0.275f,0.243f,0.043f);
        status = addAttribute( ia_grassBaseColour2 );
        CHECK_MSTATUS( status );
    }

            //Initial grass bend direction
    {
        MFnNumericAttribute numericAttrFn;
        ia_grassTipColour2 = numericAttrFn.createColor( "grassTipColour2", "tCol2");
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( true );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setDefault(0.611f,0.587f,0.257f);
        status = addAttribute( ia_grassTipColour2 );
        CHECK_MSTATUS( status );
    }





     //Clock attribute. Passes maya frame counter into node
    {
        MFnNumericAttribute numericAttrFn;
        ia_clock = numericAttrFn.create( "clock", "clk", MFnNumericData::kLong, false, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( false );
        numericAttrFn.setKeyable( true );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( false );
        numericAttrFn.setMin( 0 );
        numericAttrFn.setDefault( 0 );
        status = addAttribute( ia_clock );
        CHECK_MSTATUS( status );
    }

    
    // "drawStyle"
    //
    // How we should draw in Maya.
    //
    // We will use this value in our Maya plug-in, but we
    // will NOT use it in Renderman. Note elsewhere that
    // this value will not be sent to Renderman, nor will
    // it have any effect on RIB generation.
    //
    // We think of this as an input attribute - hence the
    // prefix "ia_" for "input attribute". 
    {
        MFnEnumAttribute enumAttrFn;
        ia_drawStyle = enumAttrFn.create( "drawStyle", "ds", 1, & status );
        CHECK_MSTATUS( status );
        enumAttrFn.setReadable( true );
        enumAttrFn.setWritable( true );
        enumAttrFn.setStorable( true );
        enumAttrFn.setKeyable( true );
        enumAttrFn.setConnectable( true );
        enumAttrFn.setHidden( false );
        enumAttrFn.addField( "Bounds", 0 );
        enumAttrFn.addField( "Sub bounds", 1 );
        enumAttrFn.addField( "Geometry", 2 );
        enumAttrFn.addField( "Terrain slope normals", 3 );
        enumAttrFn.addField( "Point instances", 4 );
        enumAttrFn.addField( "Wind Velocity", 5 );
        enumAttrFn.addField( "All", 6 );
        enumAttrFn.setDefault(3);
        status = addAttribute( ia_drawStyle );
        CHECK_MSTATUS( status );
    }
    
    // "update"
    //
    // A 'dummy' attribute, and a powerful one. Although
    // the value of this attribute is actually meaningless,
    // when we ask for it we trigger an important computation
    // processs.
    //
    // We think of this as an input attribute - hence the
    // prefix "oa_" for "computation attribute". This signifies
    // that we don't really care about it's final value, but
    // that we know it's going to compute a lot of stuff. 
    {
        MFnNumericAttribute numericAttrFn;
        oa_update = numericAttrFn.create( "update", "upd", MFnNumericData::kBoolean, false, & status );
        CHECK_MSTATUS( status );
        numericAttrFn.setReadable( true );
        numericAttrFn.setWritable( true );
        numericAttrFn.setStorable( false );
        numericAttrFn.setKeyable( false );
        numericAttrFn.setConnectable( true );
        numericAttrFn.setHidden( true );
        status = addAttribute( oa_update );
        CHECK_MSTATUS( status );
    }


   
    
    
    // "rib"
    //
    // A string which contains all the attributes, and that
    //  we need to have (and indeed will see again) on the 
    // Renderman side of things.
    //
    // We think of this as an output attribute - hence the
    // prefix "oa_" for "output attribute". The value
    // computed for this attribute (the string) is important,
    // an is used by whatever is asking for it.
    {
        MFnTypedAttribute typedAttrFn;
        oa_rib = typedAttrFn.create( "rib", "rb", MFnData::kString, MObject::kNullObj, & status );
        CHECK_MSTATUS( status );
        typedAttrFn.setReadable( true );
        typedAttrFn.setWritable( true );
        typedAttrFn.setStorable( false );
        typedAttrFn.setKeyable( false );
        typedAttrFn.setConnectable( true );
        typedAttrFn.setHidden( true );
        status = addAttribute( oa_rib );
        CHECK_MSTATUS( status );
    }


    
    // This section tells Maya what attribute effects
    // which attribute. When input attributes change, 
    // make the attributes they effect "dirty". That 
    // means that, when Maya asks for a dirty attribute, 
    // it will need to be computed and "cleaned".
    //
    // Changing an effecting "input" attribute does not
    // trigger a computation of it's effected "output"
    // attribute. It just tells Maya that - if the effected
    // attribute is ever asked for, it will have to call
    // the compute method to calculate it.
    //
    // For complex relationships between attributes,
    // an attributeEffects() call must exist for each
    // relationship. If A effects B, and B effects C,
    // then we will need to make two attributeEffects()
    // calls - one for A effecting B and one for B 
    // effecting C. Maya will not figure out that, if A
    // effects B, and B effets C, then A must effect C.
    //
    // Below we see that most "input" attributes effect
    // both our internal update and the rib generation
    // the same way in each case. But it's not always 
    // exactly the same like this.
    //
    // Notice also that ia_drawStyle does not effect
    // any of the attributes. It's something that's just
    // used in the draw method.
    
    attributeAffects( ia_seed, oa_update );
    attributeAffects( ia_seed, oa_rib );
    
    attributeAffects( ia_roughness, oa_update );
    attributeAffects( ia_roughness, oa_rib );

    attributeAffects( ia_smooth, oa_update );
    attributeAffects( ia_smooth, oa_rib );

    attributeAffects( ia_planeHeight, oa_update );
    attributeAffects( ia_planeHeight, oa_rib );

    attributeAffects( ia_resolution, oa_update );
    attributeAffects( ia_rmanResolution, oa_rib );
    
    attributeAffects( ia_planeSize, oa_update );
    attributeAffects( ia_planeSize, oa_rib );

    attributeAffects( ia_gridSize, oa_update );
    attributeAffects( ia_gridSize, oa_rib );

    attributeAffects( ia_grassMultiplier, oa_update );
    attributeAffects( ia_grassMultiplier, oa_rib );

    attributeAffects( ia_baseWidth, oa_update );
    attributeAffects( ia_baseWidth, oa_rib );

    attributeAffects( ia_grassSegmentLength, oa_update );
    attributeAffects( ia_grassSegmentLength, oa_rib );

    attributeAffects( ia_grassNumSegments, oa_update );
    attributeAffects( ia_grassNumSegments, oa_rib );

    attributeAffects( ia_grassBendAmount, oa_update );
    attributeAffects( ia_grassBendAmount, oa_rib );

    attributeAffects( ia_windDirection, oa_update );
    attributeAffects( ia_windDirection, oa_rib );

    attributeAffects( ia_windSpread, oa_update );
    attributeAffects( ia_windSpread, oa_rib );

    attributeAffects( ia_clock, oa_update );
    attributeAffects( ia_clock, oa_rib );

    attributeAffects( ia_grassBaseColour1, oa_update);
    attributeAffects( ia_grassBaseColour1, oa_rib);

    attributeAffects( ia_grassTipColour1, oa_update);
    attributeAffects( ia_grassTipColour1, oa_rib);

    attributeAffects( ia_grassBaseColour2, oa_update);
    attributeAffects( ia_grassBaseColour2, oa_rib);

    attributeAffects( ia_grassTipColour2, oa_update);
    attributeAffects( ia_grassTipColour2, oa_rib);


    
    
    fprintf( stderr, "VmIslandNode::initialize() done\n" );

    return MStatus::kSuccess;
}