// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 // // This is actually part of the shaveHairShape class implementation. // However, since attribute initialization involves a large amount of // fairly repetitious code, we've pulled it out into a separate source file // to help make shaveHairShape.cpp a bit more managable. // #include #include #include #include #include #include #include #include #include #include #include "shaveBlindData.h" #include "shaveError.h" #include "shaveHairShape.h" #include "shaveRender.h" // // Attributes // // NOTE: The following Shave texture channels do not have their // own separate attributes, just elements within the shaveTextureAttr // array: // // 22 - wiggle amplitude // 23 - wiggle speed // 28 - hair density // 29 - cut length // // The 'wiggle' parameters are not supported in Maya as frizz anim // is a better way of dealing with it. // // The 'hair density' and 'cut length' parameters are supported, // but only when mapped. Since there is no single-valued version // of the parameters, they don't need separate attributes. // // It makes no sense to have an unmapped version of 'hair density' // because an overall change in hair density is much more // effectively achieved by altering the total haircount. // // It could be argued that an unmapped version of 'cut length' // would be useful, and that may be introduced at some future // time. // // Texture channel 44 is currently unused. // //vlad|06Apr2010 -- attribute replacement of 'int mStackIndex' MObject shaveHairShape::stackIndex; MObject shaveHairShape::aCachedBBox, shaveHairShape::aCachedBBoxMin, shaveHairShape::aCachedBBoxMax; MObject shaveHairShape::aCollisionSet; MObject shaveHairShape::aDisplayGuides; //goes to globals MObject shaveHairShape::aDisplaySegmentLimit; MObject shaveHairShape::aDisplayGuideThick; MObject shaveHairShape::aDisplayGuideExt; MObject shaveHairShape::aEvalOption; MObject shaveHairShape::aGrowthSet; MObject shaveHairShape::aGuide; MObject shaveHairShape::aGuideX; MObject shaveHairShape::aGuideY; MObject shaveHairShape::aGuideZ; MObject shaveHairShape::aHairGroup; MObject shaveHairShape::aNodeVersion; MObject shaveHairShape::aShaveVersion; MObject shaveHairShape::aSpecularTint; MObject shaveHairShape::aSpecularTint2; MObject shaveHairShape::aSplineLock; MObject shaveHairShape::aSplineLockTrigger; MObject shaveHairShape::aTipFade; MObject shaveHairShape::aSquirrel; MObject shaveHairShape::blockDynamics; MObject shaveHairShape::collisionObjectsAttr; MObject shaveHairShape::collisionObjectsGroupIDAttr; MObject shaveHairShape::displayHiarDoXparency; MObject shaveHairShape::displayHiarDoSsao; MObject shaveHairShape::displayHiarXparency; MObject shaveHairShape::displayNodeAttr; MObject shaveHairShape::dspyMode; MObject shaveHairShape::growthObjectsGroupIDAttr; MObject shaveHairShape::hairColorTexture, shaveHairShape::hairColorTextureR, shaveHairShape::hairColorTextureG, shaveHairShape::hairColorTextureB; MObject shaveHairShape::inputCurve; MObject shaveHairShape::inputMesh; MObject shaveHairShape::inputSurf; MObject shaveHairShape::instanceMesh; MObject shaveHairShape::instanceMeshChanged; MObject shaveHairShape::instancingStatusChanged; MObject shaveHairShape::mutantHairColorTexture, shaveHairShape::mutantHairColorTextureR, shaveHairShape::mutantHairColorTextureG, shaveHairShape::mutantHairColorTextureB; MObject shaveHairShape::neverBeenInstanced; MObject shaveHairShape::outputMesh; MObject shaveHairShape::renderStateAttr; MObject shaveHairShape::ribInsert; MObject shaveHairShape::rootHairColorTexture, shaveHairShape::rootHairColorTextureR, shaveHairShape::rootHairColorTextureG, shaveHairShape::rootHairColorTextureB; MObject shaveHairShape::runDynamics; MObject shaveHairShape::shaveBlindHair; MObject shaveHairShape::shaveBlindState; MObject shaveHairShape::shaveParamAmbDiff; // param 6 MObject shaveHairShape::shaveParamAnimSpeed; // param 33 MObject shaveHairShape::shaveParamCollide; MObject shaveHairShape::shaveParamCollisionMethod; MObject shaveHairShape::shaveParamDampening; // param 40 MObject shaveHairShape::shaveParamDisplacement; // param 43 MObject shaveHairShape::shaveParamFrizzAnim; // param 32 MObject shaveHairShape::shaveParamFrizzAnimDir, shaveHairShape::shaveParamFrizzAnimDirX, shaveHairShape::shaveParamFrizzAnimDirY, shaveHairShape::shaveParamFrizzAnimDirZ; MObject shaveHairShape::shaveParamFrizzFreqX; // param 1 MObject shaveHairShape::shaveParamFrizzFreqY; // param 30 MObject shaveHairShape::shaveParamFrizzFreqZ; // param 31 MObject shaveHairShape::shaveParamFrizzRoot; // param 0 MObject shaveHairShape::shaveParamFrizzTip; // param 24 MObject shaveHairShape::shaveParamGeomShadow; MObject shaveHairShape::shaveParamGloss; // param 5 MObject shaveHairShape::shaveParamGravity; MObject shaveHairShape::shaveParamHairColor, shaveHairShape::shaveParamHairRed, // param 9 shaveHairShape::shaveParamHairGreen, // param 10 shaveHairShape::shaveParamHairBlue; // param 11 MObject shaveHairShape::shaveParamHaircount; MObject shaveHairShape::shaveParamHueVariation; // param 12 MObject shaveHairShape::shaveParamInstancingStatus; MObject shaveHairShape::shaveParamKinkFreqX; // param 3 MObject shaveHairShape::shaveParamKinkFreqY; // param 34 MObject shaveHairShape::shaveParamKinkFreqZ; // param 35 MObject shaveHairShape::shaveParamKinkRoot; // param 38 MObject shaveHairShape::shaveParamKinkTip; // param 2 MObject shaveHairShape::shaveParamMultStrand; // param 25 MObject shaveHairShape::shaveParamsDisplaceStren; MObject shaveHairShape::shaveParamMutantColor, shaveHairShape::shaveParamMutantRed, // param 13 shaveHairShape::shaveParamMutantGreen, // param 14 shaveHairShape::shaveParamMutantBlue; // param 15 MObject shaveHairShape::shaveParamMutantPercent; // param 16 MObject shaveHairShape::shaveParamNoInterp; MObject shaveHairShape::shaveParamPainted; MObject shaveHairShape::shaveParamPasses; MObject shaveHairShape::shaveParamRandomizeMulti; // param 42 MObject shaveHairShape::shaveParamRandScale; // param 36 MObject shaveHairShape::shaveParamRootColor, shaveHairShape::shaveParamRootRed, // param 17 shaveHairShape::shaveParamRootGreen, // param 18 shaveHairShape::shaveParamRootBlue; // param 19 MObject shaveHairShape::shaveParamRootStiffness; // param 21 MObject shaveHairShape::shaveParamScale; // param 41 MObject shaveHairShape::shaveParamSegs; MObject shaveHairShape::shaveParamSelfShadow; // param 7 MObject shaveHairShape::shaveParamSpecular; // param 4 MObject shaveHairShape::shaveParamSplayRoot; // param 26 MObject shaveHairShape::shaveParamSplayTip; // param 27 MObject shaveHairShape::shaveParamMultAsp; // param 44 - vlad|05July2010 MObject shaveHairShape::shaveParamOffset; // param 45 - vlad|09July2010 MObject shaveHairShape::shaveParamAspect; // param 46 - vlad|09July2010 MObject shaveHairShape::shaveParamStiffness; // param 8 MObject shaveHairShape::shaveParamThickRoot; // param 20 MObject shaveHairShape::shaveParamThickTip; // param 37 MObject shaveHairShape::shaveParamTotalGuides; MObject shaveHairShape::shaveParamValueVariation; // param 39 MObject shaveHairShape::shaveTexMutantColor; MObject shaveHairShape::shaveTextureAttr; MObject shaveHairShape::surfTessU; MObject shaveHairShape::surfTessV; MObject shaveHairShape::subdTessDept; MObject shaveHairShape::subdTessSamp; MObject shaveHairShape::textureCacheUpdatedAttr; MObject shaveHairShape::timeAttr; MObject shaveHairShape::triggerAttr; MObject shaveHairShape::overrideGeomShaderAttr; MObject shaveHairShape::uvSetAssignmentsAttr; MObject shaveHairShape::uvSetNameAttr; MObject shaveHairShape::uvSetTexturesAttr; MObject shaveHairShape::versionLockAttr; MObject shaveHairShape::flyawayPerc; MObject shaveHairShape::flyawayStren; MObject shaveHairShape::messStren; MObject shaveHairShape::clumps; MObject shaveHairShape::clumpsStren; MObject shaveHairShape::clumpsColStren; MObject shaveHairShape::clumpsRotStren; MObject shaveHairShape::clumpsRotOffset; MObject shaveHairShape::clumpsRandomize; MObject shaveHairShape::clumpsFlatness; MObject shaveHairShape::clumpsScruffle; MObject shaveHairShape::procedural; MObject shaveHairShape::randomSeedOffset; // Deprecated Attributes MObject shaveHairShape::displayHairMaxAttr; MObject shaveHairShape::displayHairRatioAttr; MObject shaveHairShape::isActive; MStatus shaveHairShape::initialize() { MStatus st; MFnCompoundAttribute cAttr; MFnEnumAttribute eAttr; MFnGenericAttribute gAttr; MFnMessageAttribute mAttr; MFnNumericAttribute nAttr; MFnTypedAttribute tAttr; MFnUnitAttribute uAttr; //*************************************************************** // // HELPER ATTRIBUTES // //*************************************************************** // vlad|06Apr2010 -- attribute replacement of 'int mStackIndex' // so stack index can be retrieved from another module by // attribute name stackIndex = nAttr.create( "stackIndex", "sti", MFnNumericData::kInt, 0, &st); MChkErr(st, "can't create 'stackIndex' attribute."); nAttr.setStorable(false); nAttr.setKeyable (false); nAttr.setHidden (true); st = addAttribute(stackIndex); MChkErr(st, "can't add 'stackIndex' attribute."); //MGlobal::displayInfo("new stackIndex attribute added."); //*************************************************************** // // REGULAR ATTRIBUTES // //*************************************************************** blockDynamics = nAttr.create( "disableDynamics", "disabled", MFnNumericData::kBoolean, false, &st ); MChkErr(st, "can't create 'disableDynamics' attribute."); nAttr.setStorable(true); st = addAttribute(blockDynamics); MChkErr(st, "can't add 'disableDynamics' attribute."); collisionObjectsAttr = gAttr.create("collisionObjects", "co", &st); MChkErr(st, "can't create 'collisionObjects' attribute."); gAttr.setArray (true); gAttr.setHidden(true); gAttr.setStorable(false); gAttr.setDisconnectBehavior(MFnAttribute::kDelete); gAttr.addAccept(MFnData::kMesh); gAttr.addAccept(MFnData::kNurbsCurve); gAttr.addAccept(MFnData::kNurbsSurface); gAttr.addAccept(MFnData::kSubdSurface); st = addAttribute(collisionObjectsAttr); MChkErr(st, "can't add 'collisionObjects' attribute."); collisionObjectsGroupIDAttr = nAttr.create( "collisionObjectsGroupID", "cmgi", MFnNumericData::kLong, 0, &st ); MChkErr(st, "can't create 'collisionObjectsGroupID' attribute."); nAttr.setArray(true); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setDisconnectBehavior(MFnAttribute::kDelete); st = addAttribute(collisionObjectsGroupIDAttr); MChkErr(st, "can't add 'collisionObjectsGroupID' attribute."); displayNodeAttr = mAttr.create("displayNode", "dn"); mAttr.setStorable(false); mAttr.setHidden(true); st = addAttribute(displayNodeAttr); MChkErr(st, "can't add 'displayNode' attribute."); dspyMode = eAttr.create("displayAs", "dspyas", 1); eAttr.addField("none", kHairDisplayNone); eAttr.addField("hairs", kHairDisplayHair); eAttr.addField("geometry", kHairDisplayGeom); eAttr.setStorable(true); eAttr.setHidden(true); st = addAttribute(dspyMode); MChkErr(st, "can't add 'displayAs' attribute."); aDisplayGuides = nAttr.create( "displayGuides", "dg", MFnNumericData::kBoolean, 0, &st ); MChkErr(st, "can't create 'displayGuides' attribute."); nAttr.setDefault(false); st = addAttribute(aDisplayGuides); MChkErr(st, "can't add 'displayGuides' attribute."); //goes to globals aDisplaySegmentLimit = nAttr.create( "displaySegmentLimit", "dsl", MFnNumericData::kLong, 6, &st ); MChkErr(st, "can't create 'displaySegmentLimit' attribute."); nAttr.setHidden(true); // So it doesn't get saved as a preset. nAttr.setMin(1); nAttr.setSoftMax(20); st = addAttribute(aDisplaySegmentLimit); MChkErr(st, "can't add 'displaySegmentLimit' attribute."); //goes to globals aDisplayGuideThick = nAttr.create( "displayGuideThick", "dgt", MFnNumericData::kFloat, 0, &st ); MChkErr(st, "can't create 'displayGuideThick' attribute."); nAttr.setHidden(true); // So it doesn't get saved as a preset. nAttr.setMin(0.0f); nAttr.setSoftMax(1.0f); nAttr.setDefault(/*0.7f*/ 0.0f); st = addAttribute(aDisplayGuideThick); MChkErr(st, "can't add 'displayGuideThick' attribute."); aDisplayGuideExt = nAttr.create( "displayGuideExt", "dge", MFnNumericData::kFloat, 0, &st ); MChkErr(st, "can't create 'displayGuideExt' attribute."); nAttr.setHidden(true); st = addAttribute(aDisplayGuideExt); MChkErr(st, "can't add 'displayGuideExt' attribute."); growthObjectsGroupIDAttr = nAttr.create("growthObjectsGroupID", "gmgi", MFnNumericData::kLong); nAttr.setArray(true); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setDisconnectBehavior(MFnAttribute::kDelete); st = addAttribute(growthObjectsGroupIDAttr); MChkErr(st, "can't add 'growthObjectsGroupID' attribute."); hairColorTextureR = nAttr.create("hairColorTextureR", "hctr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(hairColorTextureR); MChkErr(st, "can't add 'hairColorTextureR' attribute."); hairColorTextureG = nAttr.create("hairColorTextureG", "hctg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(hairColorTextureG); MChkErr(st, "can't add 'hairColorTextureG' attribute."); hairColorTextureB = nAttr.create("hairColorTextureB", "hctb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(hairColorTextureB); MChkErr(st, "can't add 'hairColorTextureB' attribute."); hairColorTexture = nAttr.create( "hairColorTexture", "htc", hairColorTextureR, hairColorTextureG, hairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); st = addAttribute(hairColorTexture); MChkErr(st, "can't add 'hairColorTexture' attribute."); inputCurve = tAttr.create("inputCurve", "incrv", MFnData::kNurbsCurve); tAttr.setArray (true); tAttr.setHidden(true); tAttr.setStorable(false); tAttr.setDisconnectBehavior(MFnAttribute::kDelete); st = addAttribute(inputCurve); MChkErr(st, "can't add 'inputCurve' attribute."); inputMesh = tAttr.create ("inputMesh", "input", MFnData::kMesh); tAttr.setArray (true); tAttr.setHidden(true); tAttr.setStorable(false); tAttr.setDisconnectBehavior(MFnAttribute::kDelete); st = addAttribute(inputMesh); MChkErr(st, "can't add 'inputMesh' attribute."); inputSurf = gAttr.create("inputSurface", "insrf"); gAttr.setArray (true); gAttr.setHidden(true); gAttr.setStorable(false); gAttr.addAccept(MFnData::kNurbsSurface); gAttr.addAccept(MFnData::kSubdSurface); gAttr.setDisconnectBehavior(MFnAttribute::kDelete); st = addAttribute(inputSurf); MChkErr(st, "can't add 'inputSurface' attribute."); instanceMesh = tAttr.create("instanceMesh", "imsh", MFnData::kMesh); tAttr.setHidden(true); tAttr.setStorable(true); st = addAttribute(instanceMesh); MChkErr(st, "can't add 'instanceMesh' attribute."); mutantHairColorTextureR = nAttr.create( "mutantHairColorTextureR", "mhctr", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(mutantHairColorTextureR); MChkErr(st, "can't add 'mutantHairColorTextureR' attribute."); mutantHairColorTextureG = nAttr.create( "mutantHairColorTextureG", "mhctg", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(mutantHairColorTextureG); MChkErr(st, "can't add 'mutantHairColorTextureG' attribute."); mutantHairColorTextureB = nAttr.create( "mutantHairColorTextureB", "mhctb", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(mutantHairColorTextureB); MChkErr(st, "can't add 'mutantHairColorTextureB' attribute."); mutantHairColorTexture = nAttr.create( "mutantHairColorTexture", "mhtc", mutantHairColorTextureR, mutantHairColorTextureG, mutantHairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); st = addAttribute(mutantHairColorTexture); MChkErr(st, "can't add 'mutantHairColorTexture' attribute."); neverBeenInstanced = nAttr.create( "neverBeenInstanced", "nbi", MFnNumericData::kBoolean, true ); nAttr.setConnectable(false); nAttr.setHidden(true); nAttr.setStorable(true); st = addAttribute(neverBeenInstanced); MChkErr(st, "can't add 'neverBeenInstanced' attribute."); aNodeVersion = nAttr.create("nodeVersion", "nv", MFnNumericData::kLong); nAttr.setDefault(0); nAttr.setHidden(true); nAttr.setInternal(true); nAttr.setWritable(true); nAttr.setStorable(true); st = addAttribute(aNodeVersion); MChkErr(st, "can't add 'nodeVersion' attribute."); aShaveVersion = tAttr.create( "shaveVersion", "sv", MFnStringData::kString, MObject::kNullObj, &st ); MChkErr(st, "can't create 'shaveVersion' attribute."); tAttr.setStorable(true); st = addAttribute(aShaveVersion); MChkErr(st, "can't add 'shaveVersion' attribute."); outputMesh = tAttr.create("outputMesh", "out", MFnData::kMesh); tAttr.setStorable(false); tAttr.setHidden(true); tAttr.setWritable(false); st = addAttribute(outputMesh); MChkErr(st, "can't add 'outputMesh' attribute."); overrideGeomShaderAttr = nAttr.create( "overrideGeomShader", "ogsh", MFnNumericData::kBoolean, true ); nAttr.setStorable(true); st = addAttribute(overrideGeomShaderAttr); MChkErr(st, "can't add 'overrideGeomShader' attribute."); renderStateAttr = eAttr.create("renderState", "rs", shaveRender::kRenderNone); eAttr.addField("None", shaveRender::kRenderNone); eAttr.addField("Rendering", shaveRender::kRendering); eAttr.addField("Rendering Frame", shaveRender::kRenderingFrame); eAttr.setStorable(false); eAttr.setHidden(true); st = addAttribute(renderStateAttr); MChkErr(st, "can't add 'renderState' attribute."); ribInsert = tAttr.create("ribStuff", "rbs", MFnStringData::kString); tAttr.setStorable(true); st = addAttribute(ribInsert); MChkErr(st, "can't add 'ribStuff' attribute."); rootHairColorTextureR = nAttr.create( "rootHairColorTextureR", "rhctr", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(rootHairColorTextureR); MChkErr(st, "can't add 'rootHairColorTextureR' attribute."); rootHairColorTextureG = nAttr.create( "rootHairColorTextureG", "rhctg", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(rootHairColorTextureG); MChkErr(st, "can't add 'rootHairColorTextureG' attribute."); rootHairColorTextureB = nAttr.create( "rootHairColorTextureB", "rhctb", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); st = addAttribute(rootHairColorTextureB); MChkErr(st, "can't add 'rootHairColorTextureB' attribute."); rootHairColorTexture = nAttr.create( "rootHairColorTexture", "rhtc", rootHairColorTextureR, rootHairColorTextureG, rootHairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); st = addAttribute(rootHairColorTexture); MChkErr(st, "can't add 'rootHairColorTexture' attribute."); runDynamics = nAttr.create("runDynamics", "rd", MFnNumericData::kLong, 0); nAttr.setStorable(true); nAttr.setHidden(true); st = addAttribute(runDynamics); MChkErr(st, "can't add 'runDynamics' attribute."); shaveBlindHair = tAttr.create( "blindShaveData", "BSD", blindShaveData::dataTypeId, MObject::kNullObj, &st ); MChkErr(st, "can't create 'blindShaveData' attribute."); tAttr.setHidden(true); tAttr.setStorable(true); st = addAttribute(shaveBlindHair); MChkErr(st, "can't add 'blindShaveData' attribute."); aEvalOption = tAttr.create("evalOption", "evo", MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); st = addAttribute(aEvalOption); MChkErr(st, "can't add 'evalOption' attribute."); //*************************************************************** // // ATTRIBUTES FOR SHAVE ENGINE PARAMETERS // // These parameters represent values which get mapped directly to the // SHAVEPARMS structure passed to the Shave engine. // //*************************************************************** shaveParamAmbDiff = nAttr.create("amb/diff", "spambdif", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); nAttr.setKeyable(true); st = addAttribute(shaveParamAmbDiff); MChkErr(st, "can't add 'amb/diff' attribute."); shaveParamCollide = nAttr.create( "enableCollision", "spec", MFnNumericData::kBoolean, false ); nAttr.setStorable(true); st = addAttribute(shaveParamCollide); MChkErr(st, "can't add 'enableCollision' attribute."); shaveParamCollisionMethod = nAttr.create("collisionMethod", "spcm", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setHidden(true); st = addAttribute(shaveParamCollisionMethod); MChkErr(st, "can't add 'collisionMethod' attribute."); shaveParamDampening = nAttr.create("dampening", "damp", MFnNumericData::kFloat, 0.0); nAttr.setMin(0.0); nAttr.setMax(1.0); st = addAttribute(shaveParamDampening); MChkErr(st, "can't add 'dampening' attribute."); shaveParamFrizzAnim = nAttr.create("frizzAnim", "spfa", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzAnim); MChkErr(st, "can't add 'frizzAnim' attribute."); shaveParamFrizzAnimDirX = nAttr.create("animDirX", "spadx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzAnimDirX); MChkErr(st, "can't add 'animDirX' attribute."); shaveParamFrizzAnimDirY = nAttr.create("animDirY", "spady", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzAnimDirY); MChkErr(st, "can't add 'animDirY' attribute."); shaveParamFrizzAnimDirZ = nAttr.create("animDirZ", "spadz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzAnimDirZ); MChkErr(st, "can't add 'animDirZ' attribute."); shaveParamFrizzAnimDir = nAttr.create( "frizzAnimDir", "spad", shaveParamFrizzAnimDirX, shaveParamFrizzAnimDirY, shaveParamFrizzAnimDirZ ); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzAnimDir); MChkErr(st, "can't add 'frizzAnimDir' attribute."); shaveParamAnimSpeed = nAttr.create("animSpeed", "spas", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamAnimSpeed); MChkErr(st, "can't add 'animSpeed' attribute."); shaveParamDisplacement = nAttr.create("displacement", "disp", MFnNumericData::kFloat, 0.0f); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setSoftMin(-10.0); nAttr.setSoftMax(10.0); st = addAttribute(shaveParamDisplacement); MChkErr(st, "can't add 'displacement' attribute."); shaveParamFrizzFreqX = nAttr.create("frizzXFrequency", "spffx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzFreqX); MChkErr(st, "can't add 'frizzXFrequency' attribute."); shaveParamFrizzFreqY = nAttr.create("frizzYFrequency", "spffy", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzFreqY); MChkErr(st, "can't add 'frizzYFrequency' attribute."); shaveParamFrizzFreqZ = nAttr.create("frizzZFrequency", "spffz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzFreqZ); MChkErr(st, "can't add 'frizzZFrequency' attribute."); shaveParamFrizzRoot = nAttr.create("rootFrizz", "sprf", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzRoot); MChkErr(st, "can't add 'rootFrizz' attribute."); shaveParamFrizzTip = nAttr.create("tipFrizz", "sptf", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamFrizzTip); MChkErr(st, "can't add 'tipFrizz' attribute."); shaveParamGeomShadow = nAttr.create("geomShadow", "spgs", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.0); nAttr.setMax(1.0); nAttr.setStorable(true); st = addAttribute(shaveParamGeomShadow); MChkErr(st, "can't add 'geomShadow' attribute."); shaveParamGloss = nAttr.create("gloss", "spgloss", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(0.099999); nAttr.setKeyable(true); st = addAttribute(shaveParamGloss); MChkErr(st, "can't add 'gloss' attribute."); shaveParamHairRed = nAttr.create("hairRed", "sphr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamHairRed); MChkErr(st, "can't add 'hairRed' attribute."); shaveParamHairGreen = nAttr.create("hairGreen", "sphg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamHairGreen); MChkErr(st, "can't add 'hairGreen' attribute."); shaveParamHairBlue = nAttr.create("hairBlue", "sphb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamHairBlue); MChkErr(st, "can't add 'hairBlue' attribute."); shaveParamHairColor = nAttr.create( "hairColor", "sphcol", shaveParamHairRed, shaveParamHairGreen, shaveParamHairBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); st = addAttribute(shaveParamHairColor); MChkErr(st, "can't add 'hairColor' attribute."); shaveParamHaircount = nAttr.create("hairCount", "sphc", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(30000); st = addAttribute(shaveParamHaircount); MChkErr(st, "can't add 'hairCount' attribute."); shaveParamHueVariation = nAttr.create("hueVariation", "sphv", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); st = addAttribute(shaveParamHueVariation); MChkErr(st, "can't add 'hueVariation' attribute."); shaveParamInstancingStatus = nAttr.create( "instancingStatus", "spis", MFnNumericData::kBoolean, false ); nAttr.setStorable(true); st = addAttribute(shaveParamInstancingStatus); MChkErr(st, "can't add 'instancingStatus' attribute."); shaveParamKinkFreqX = nAttr.create("kinkXFrequency", "spkfx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamKinkFreqX); MChkErr(st, "can't add 'kinkXFrequency' attribute."); shaveParamKinkFreqY = nAttr.create("kinkYFrequency", "spkfy", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamKinkFreqY); MChkErr(st, "can't add 'kinkYFrequency' attribute."); shaveParamKinkFreqZ = nAttr.create("kinkZFrequency", "spkfz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamKinkFreqZ); MChkErr(st, "can't add 'kinkZFrequency' attribute."); shaveParamKinkRoot = nAttr.create("rootKink", "spkr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamKinkRoot); MChkErr(st, "can't add 'rootKink' attribute."); shaveParamKinkTip = nAttr.create("tipKink", "spkt", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamKinkTip); MChkErr(st, "can't add 'tipKink' attribute."); shaveParamMultStrand = nAttr.create("multiStrandCount", "spms", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(10); st = addAttribute(shaveParamMultStrand); MChkErr(st, "can't add 'multiStrandCount' attribute."); shaveParamMutantRed = nAttr.create("mutantHairRed", "spmhr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(shaveParamMutantRed); MChkErr(st, "can't add 'mutantHairRed' attribute."); shaveParamMutantGreen = nAttr.create("mutantHairGreen", "spmhg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(shaveParamMutantGreen); MChkErr(st, "can't add 'mutantHairGreen' attribute."); shaveParamMutantBlue = nAttr.create("mutantHairBlue", "spmhb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); st = addAttribute(shaveParamMutantBlue); MChkErr(st, "can't add 'mutantHairBlue' attribute."); shaveParamMutantColor = nAttr.create( "mutantHairColor", "spmhc", shaveParamMutantRed, shaveParamMutantGreen, shaveParamMutantBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); st = addAttribute(shaveParamMutantColor); MChkErr(st, "can't add 'mutantHairColor' attribute."); shaveParamMutantPercent = nAttr.create("percentMutantHairs", "spmp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); st = addAttribute(shaveParamMutantPercent); MChkErr(st, "can't add 'percentMutantHairs' attribute."); shaveParamNoInterp = nAttr.create( "interpolateGuides", "dointerp", MFnNumericData::kBoolean, true ); nAttr.setStorable(true); st = addAttribute(shaveParamNoInterp); MChkErr(st, "can't add 'interpolateGuides' attribute."); shaveParamPasses = nAttr.create("hairPasses", "sphp", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(20); st = addAttribute(shaveParamPasses); MChkErr(st, "can't add 'hairPasses' attribute."); shaveParamRandomizeMulti = nAttr.create("randomizeMulti", "sprm", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.0f); nAttr.setMax(1.0f); st = addAttribute(shaveParamRandomizeMulti); MChkErr(st, "can't add 'randomizeMulti' attribute."); shaveParamRandScale = nAttr.create("randScale", "sprs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); nAttr.setKeyable(true); st = addAttribute(shaveParamRandScale); MChkErr(st, "can't add 'randScale' attribute."); shaveParamRootRed = nAttr.create("rootRed", "sprr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamRootRed); MChkErr(st, "can't add 'rootRed' attribute."); shaveParamRootGreen = nAttr.create("rootGreen", "sprg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamRootGreen); MChkErr(st, "can't add 'rootGreen' attribute."); shaveParamRootBlue = nAttr.create("rootBlue", "sprb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); st = addAttribute(shaveParamRootBlue); MChkErr(st, "can't add 'rootBlue' attribute."); shaveParamRootColor = nAttr.create( "rootColor", "sprtc", shaveParamRootRed, shaveParamRootGreen, shaveParamRootBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); st = addAttribute(shaveParamRootColor); MChkErr(st, "can't add 'rootColor' attribute."); shaveParamRootStiffness = nAttr.create("rootStiffness", "rstf", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.0); nAttr.setMax(1.0); st = addAttribute(shaveParamRootStiffness); MChkErr(st, "can't add 'rootStiffness' attribute."); shaveParamScale = nAttr.create("scale", "sc", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.01); nAttr.setSoftMax(1.0); st = addAttribute(shaveParamScale); MChkErr(st, "can't add 'scale' attribute."); shaveParamSegs = nAttr.create("hairSegments", "spsegs", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(50); st = addAttribute(shaveParamSegs); MChkErr(st, "can't add 'hairSegments' attribute."); shaveParamSelfShadow = nAttr.create("selfShadow", "spss", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); st = addAttribute(shaveParamSelfShadow); MChkErr(st, "can't add 'selfShadow' attribute."); shaveParamSpecular = nAttr.create("specular", "spspec", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(1); nAttr.setKeyable(true); st = addAttribute(shaveParamSpecular); MChkErr(st, "can't add 'specular' attribute."); shaveParamSplayRoot = nAttr.create("rootSplay", "sprsp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamSplayRoot); MChkErr(st, "can't add 'rootSplay' attribute."); shaveParamSplayTip = nAttr.create("tipSplay", "sptsp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamSplayTip); MChkErr(st, "can't add 'tipSplay' attribute."); //vlad|05July2010 shaveParamMultAsp = nAttr.create("multAsp", "mlasp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamMultAsp); MChkErr(st, "can't add 'multAsp' attribute."); //vlad|09July2010 shaveParamOffset = nAttr.create("Offset", "offs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamOffset); MChkErr(st, "can't add 'Offset' attribute."); //vlad|09July2010 shaveParamAspect = nAttr.create("Aspect", "aspc", MFnNumericData::kFloat, 1.0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); st = addAttribute(shaveParamAspect); MChkErr(st, "can't add 'Aspect' attribute."); shaveParamStiffness = nAttr.create("stiffness", "spstiff", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); nAttr.setKeyable(true); st = addAttribute(shaveParamStiffness); MChkErr(st, "can't add 'stiffness' attribute."); shaveParamThickRoot = nAttr.create("rootThickness", "sptr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(2); nAttr.setKeyable(true); st = addAttribute(shaveParamThickRoot); MChkErr(st, "can't add 'rootThickness' attribute."); shaveParamThickTip = nAttr.create("tipThickness", "sptt", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(2); nAttr.setKeyable(true); st = addAttribute(shaveParamThickTip); MChkErr(st, "can't add 'tipThickness' attribute."); shaveParamTotalGuides = nAttr.create("totalGuides", "sptg", MFnNumericData::kShort, 0); nAttr.setHidden(true); st = addAttribute(shaveParamTotalGuides); MChkErr(st, "can't add 'totalGuides' attribute."); shaveParamValueVariation = nAttr.create("valueVariation", "spvv", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); st = addAttribute(shaveParamValueVariation); MChkErr(st, "can't add 'valueVariation' attribute."); //*************************************************************** // // MORE REGULAR ATTRIBUTES // //*************************************************************** shaveTextureAttr = nAttr.create("shaveTex", "shtx", MFnNumericData::kFloat); nAttr.setArray(true); nAttr.setIndexMatters(true); nAttr.setStorable(true); st = addAttribute(shaveTextureAttr); MChkErr(st, "can't add 'shaveTex' attribute."); surfTessU = nAttr.create("uSubdivisions", "tusd", MFnNumericData::kShort, 2); nAttr.setStorable(true); st = addAttribute(surfTessU); MChkErr(st, "can't add 'uSubdivisions' attribute."); surfTessV = nAttr.create("vSubdivisions", "tvsd", MFnNumericData::kShort, 2); nAttr.setStorable(true); st = addAttribute(surfTessV); MChkErr(st, "can't add 'vSubdivisions' attribute."); subdTessDept = nAttr.create("Depth", "sde", MFnNumericData::kShort, 1); nAttr.setStorable(true); st = addAttribute(subdTessDept); MChkErr(st, "can't add 'subdTessDept' attribute."); subdTessSamp = nAttr.create("sampleCount", "ssc", MFnNumericData::kShort, 1); nAttr.setStorable(true); st = addAttribute(subdTessSamp); MChkErr(st, "can't add 'subdTessSamp' attribute."); timeAttr = uAttr.create("time", "tm", MFnUnitAttribute::kTime, 0.0); uAttr.setHidden(true); st = addAttribute(timeAttr); MChkErr(st, "can't add 'time' attribute."); triggerAttr = nAttr.create("trigger", "trg", MFnNumericData::kFloat, 0); nAttr.setHidden(true); nAttr.setWritable(false); nAttr.setStorable(false); st = addAttribute(triggerAttr); MChkErr(st, "can't add 'trigger' attribute."); uvSetNameAttr = tAttr.create("hairUVSetName", "husn", MFnStringData::kString); tAttr.setHidden(true); tAttr.setDisconnectBehavior(MFnAttribute::kReset); // // The short name for this attribute used to be "uvst". Although that // does not appear to conflict with anything, it was causing crashes in // Maya 6.0. So I added an 'x' to the end and the problems went away. // uvSetTexturesAttr = mAttr.create("hairUVSetTextures", "husx"); mAttr.setStorable(false); mAttr.setHidden(true); mAttr.setArray(true); mAttr.setIndexMatters(false); mAttr.setDisconnectBehavior(MFnAttribute::kDelete); uvSetAssignmentsAttr = cAttr.create("hairUVSetAssignments", "husa"); cAttr.setHidden(true); cAttr.setArray(true); cAttr.setIndexMatters(false); cAttr.setDisconnectBehavior(MFnAttribute::kDelete); cAttr.addChild(uvSetNameAttr); cAttr.addChild(uvSetTexturesAttr); st = addAttribute(uvSetAssignmentsAttr); MChkErr(st, "can't add 'hairUVSetAssignments' attribute."); versionLockAttr = nAttr.create("versionLock", "vl", MFnNumericData::kLong); nAttr.setHidden(true); nAttr.setStorable(true); st = addAttribute(versionLockAttr); MChkErr(st, "can't add 'versionLock' attribute."); //goes to globals displayHiarDoXparency = nAttr.create( "displayHairTransprency", "dht", MFnNumericData::kBoolean, true ); st = addAttribute(displayHiarDoXparency); displayHiarXparency = nAttr.create( "displayHairTransprencyVal", "dhv", MFnNumericData::kFloat, 1.0 ); nAttr.setHidden(true); // So it doesn't get saved as a preset. nAttr.setMin(0.0f); nAttr.setMax(1.0f); nAttr.setDefault(1.0f); st = addAttribute(displayHiarXparency); //goes to globals displayHiarDoSsao = nAttr.create( "displayHairSsao", "dho", MFnNumericData::kBoolean, false ); st = addAttribute(displayHiarDoSsao); textureCacheUpdatedAttr = nAttr.create( "textureCacheUpdated", "tau", MFnNumericData::kBoolean, false ); nAttr.setStorable(false); st = addAttribute(textureCacheUpdatedAttr); MChkErr(st, "can't add 'textureCacheUpdated' attribute."); // // We cannot use createPoint() here because that will create a float // point while Maya's manips will blindly assume double, leading to mem // overwrites and crashes. So we have to set up the three doubleLinear // children ourselves. // aGuideX = uAttr.create( "guideX", "gdx", MFnUnitAttribute::kDistance, 0.0, &st ); MChkErr(st, "can't create 'guideX' attribute."); uAttr.setHidden(true); uAttr.setInternal(true); aGuideY = uAttr.create( "guideY", "gdy", MFnUnitAttribute::kDistance, 0.0, &st ); MChkErr(st, "can't create 'guideY' attribute."); uAttr.setHidden(true); uAttr.setInternal(true); aGuideZ = uAttr.create( "guideZ", "gdz", MFnUnitAttribute::kDistance, 0.0, &st ); MChkErr(st, "can't create 'guideZ' attribute."); uAttr.setHidden(true); uAttr.setInternal(true); aGuide = nAttr.create("guide", "gd", aGuideX, aGuideY, aGuideZ, &st); MChkErr(st, "can't create 'guide' attribute."); nAttr.setHidden(true); nAttr.setArray(true); nAttr.setInternal(true); st = addAttribute(aGuide); MChkErr(st, "can't add 'guide' attribute."); aHairGroup = nAttr.create( "hairGroup", "hg", MFnNumericData::kShort, 0, &st ); MChkErr(st, "can't create 'hairGroup' attribute."); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setWritable(false); st = addAttribute(aHairGroup); MChkErr(st, "can't add 'hairGroup' attribute."); aSpecularTint = nAttr.createColor("specularTint", "sptn", &st); MChkErr(st, "can't create 'specularTint' attribute."); nAttr.setDefault(1.0f, 1.0f, 1.0f); st = addAttribute(aSpecularTint); MChkErr(st, "can't add 'specularTint' attribute."); aSpecularTint2 = nAttr.createColor("specularTint2", "spt2", &st); MChkErr(st, "can't create 'specularTint2' attribute."); nAttr.setDefault(0.0f, 0.0f, 0.0f); st = addAttribute(aSpecularTint2); MChkErr(st, "can't add 'specularTint2' attribute."); aTipFade = nAttr.create("tipFade", "tf", MFnNumericData::kBoolean, 0, &st); MChkErr(st, "can't create 'tipFade' attribute."); nAttr.setDefault(true); nAttr.setStorable(true); st = addAttribute(aTipFade); MChkErr(st, "can't add 'tipFade' attribute."); aSquirrel = nAttr.create("squirrel", "sq", MFnNumericData::kBoolean, 0, &st); MChkErr(st, "can't create 'Binary Fade' attribute."); nAttr.setDefault(true); nAttr.setStorable(true); st = addAttribute(aSquirrel); MChkErr(st, "can't add 'Binary Fade' attribute."); flyawayPerc = nAttr.create("flyawayPerc", "fwpc", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(100); st = addAttribute(flyawayPerc); MChkErr(st, "can't add 'flyawayPerc' attribute."); flyawayStren = nAttr.create("flyawayStren", "fwst", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1.0); nAttr.setKeyable(true); st = addAttribute(flyawayStren); MChkErr(st, "can't add 'flyawayStren' attribute."); messStren = nAttr.create("messStren", "mest", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(messStren); MChkErr(st, "can't add 'messStren' attribute."); clumps = nAttr.create("clumps", "clp", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(100); st = addAttribute(clumps); MChkErr(st, "can't add 'clumps' attribute."); clumpsStren = nAttr.create("clumpsStrength", "cpst", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsStren); MChkErr(st, "can't add 'clumpsStren' attribute."); clumpsScruffle = nAttr.create("clumpsScruffle", "clsf", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(400.0); nAttr.setKeyable(true); st = addAttribute(clumpsScruffle); MChkErr(st, "can't add 'clumpsScruffle' attribute."); clumpsColStren = nAttr.create("clumpsColStren", "clcs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsColStren); MChkErr(st, "can't add 'clumpsColStren' attribute."); clumpsRotStren = nAttr.create("clumpsRotStren", "clrs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setMax(40.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsRotStren); MChkErr(st, "can't add 'clumpsRotStren' attribute."); clumpsRotOffset = nAttr.create("clumpsRotOffset", "clro", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsRotOffset); MChkErr(st, "can't add 'clumpsRotOffset' attribute."); clumpsRandomize = nAttr.create("clumpsRandomize", "clrd", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsRandomize); MChkErr(st, "can't add 'clumpsRandomize' attribute."); clumpsFlatness = nAttr.create("clumpsFlatness", "clfl", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); st = addAttribute(clumpsFlatness); MChkErr(st, "can't add 'clumpsFlatness' attribute."); procedural = nAttr.create("procedural", "proc", MFnNumericData::kInt, 0); nAttr.setStorable(true); st = addAttribute(procedural); MChkErr(st, "can't add 'procedural' attribute."); randomSeedOffset = nAttr.create("randomSeedOffset", "rdso", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setKeyable(false); st = addAttribute(randomSeedOffset); MChkErr(st, "can't add 'randomSeedOffset' attribute."); // // Bounding box cache (separate from our inherited 'nodeBoundingBox' // attr). // aCachedBBoxMin = nAttr.create( "cachedBBoxMin", "cbn", MFnNumericData::k3Double, 0.0, &st ); MChkErr(st, "cannot create cachedBBoxMin attribute."); aCachedBBoxMax = nAttr.create( "cachedBBoxMax", "cbx", MFnNumericData::k3Double, 0.0, &st ); MChkErr(st, "cannot create cachedBBoxMax attribute."); aCachedBBox = cAttr.create("cachedBBox", "cbb", &st); MChkErr(st, "cannot create cachedBBox attribute."); st = cAttr.addChild(aCachedBBoxMin); MChkErr(st, "cannot add cachedBBoxMin to cachedBBox attribute."); st = cAttr.addChild(aCachedBBoxMax); MChkErr(st, "cannot add cachedBBoxMax to cachedBBox attribute."); st = addAttribute(aCachedBBox); MChkErr(st, "cannot add cachedBBox attribute."); aCollisionSet = mAttr.create("collisionSet", "cs", &st); MChkErr(st, "cannot create collisionSet attribute."); mAttr.setHidden(true); st = addAttribute(aCollisionSet); MChkErr(st, "cannot add collisionSet attribute."); aGrowthSet = mAttr.create("growthSet", "gs", &st); MChkErr(st, "cannot create growthSet attribute."); mAttr.setHidden(true); st = addAttribute(aGrowthSet); MChkErr(st, "cannot add growthSet attribute."); aSplineLock = nAttr.create( "splineLock", "slk", MFnNumericData::kBoolean, 0, &st ); MChkErr(st, "cannot create splineLock attribute."); nAttr.setHidden(true); st = addAttribute(aSplineLock); MChkErr(st, "cannot add splineLock attribute."); aSplineLockTrigger = nAttr.create( "splineLockTrigger", "slkt", MFnNumericData::kBoolean, 0, &st ); MChkErr(st, "cannot create splineLockTrigger attribute."); nAttr.setHidden(true); nAttr.setConnectable(false); nAttr.setStorable(false); nAttr.setWritable(false); st = addAttribute(aSplineLockTrigger); MChkErr(st, "cannot add splineLockTrigger attribute."); doAffects(aCachedBBox); doAffects(outputMesh); doAffects(triggerAttr); doAffects(MPxSurfaceShape::visibility); attributeAffects(triggerAttr, outputMesh); attributeAffects(inputCurve, aHairGroup); attributeAffects(inputMesh, aHairGroup); attributeAffects(inputSurf, aHairGroup); attributeAffects(inputCurve, aSplineLockTrigger); attributeAffects(aSplineLock, aSplineLockTrigger); //*************************************************************** // // INTERMEDIATE ATTRIBUTES FOR TESTING DIRTY INPUTS // // When compute() is called for an output plug, it is sometimes useful // to know which input plug(s) are dirty. As there's no direct way of // determining this, we use intermediate attrs which are affected by // the input attr we're interested in and nothing else. If, when we // query them, they are recomputed, then we know that the input attr // has changed. // //*************************************************************** // // Whenever the instancing attrs change, we need to update the blind // data, but we don't want to have to do that every time the outputMesh // is dirty, so let's create some intermediate attributes to tell us // when the instancing attrs change. // //vlad|10Mar2010 - I do not see anything about it in Docs, probably Autodesk did //not update it yet. But they added some attribute named "isc" to MPxNode //so we can not add attribute with name already used. // //Solution: rename shave's attribute to "isc0" and "instancingStatusChanged0" //it is safe because: //1) attribute is not saved ( not storable ) so will not affect older scenes //2) we do not access *this* attribute by name using MFnDependencyNode::findPlug instancingStatusChanged = nAttr.create( "instancingStatusChanged0", "isc0", //vlad|10Mar2010 - let's try another name MFnNumericData::kBoolean, /*false*/0 //there is 'int' param ); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setWritable(false); st = addAttribute(instancingStatusChanged); MChkErr(st, "can't add 'instancingStatusChanged' attribute."); attributeAffects(shaveParamInstancingStatus, instancingStatusChanged); instanceMeshChanged = nAttr.create( "instanceMeshChanged", "imc", MFnNumericData::kBoolean ); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setWritable(false); st = addAttribute(instanceMeshChanged); MChkErr(st, "can't add 'instanceMeshChanged' attribute."); attributeAffects(instanceMesh, instanceMeshChanged); //*************************************************************** // // DEPRECATED ATTRIBUTES // // These attributes are no longer used. They are only retained // so that old scenes can still be loaded. // //*************************************************************** isActive = nAttr.create( "active", "act", MFnNumericData::kBoolean, true); nAttr.setHidden(true); // We want to keep this as storable for now so that we can revert // scenes which might get screwed up. nAttr.setStorable(true); st = addAttribute(isActive); shaveParamsDisplaceStren = nAttr.create("displaceStrength", "dist", MFnNumericData::kFloat, 0); nAttr.setHidden(true); nAttr.setStorable(false); addAttribute(shaveParamsDisplaceStren); displayHairMaxAttr = nAttr.create( "displayHairMax", "dhm", MFnNumericData::kLong ); nAttr.setHidden(true); nAttr.setStorable(false); addAttribute(displayHairMaxAttr); displayHairRatioAttr = nAttr.create( "displayHairRatio", "dhr", MFnNumericData::kFloat ); nAttr.setHidden(true); nAttr.setStorable(false); addAttribute(displayHairRatioAttr); return MS::kSuccess; } // // Do the 'attributeAffects' call for an output attr which is affected by // all the major input attrs. // // We also use this for chained dependencies where some other attr is // affected by one which is affected by all the major input attrs. We have // to do it this way because Maya's DG does not directly support chaining // within a single node. // void shaveHairShape::doAffects(MObject targetAttr) { attributeAffects( aDisplayGuides, targetAttr ); attributeAffects( aSplineLock, targetAttr ); attributeAffects( collisionObjectsAttr, targetAttr ); attributeAffects( collisionObjectsGroupIDAttr, targetAttr ); attributeAffects( displayHiarDoXparency, targetAttr ); attributeAffects( displayHiarDoSsao, targetAttr ); attributeAffects( shaveParamsDisplaceStren, targetAttr ); attributeAffects( displayHiarXparency, targetAttr ); // attributeAffects( displayHairMaxAttr, targetAttr ); // attributeAffects( displayHairRatioAttr, targetAttr ); attributeAffects( dspyMode, targetAttr ); attributeAffects( growthObjectsGroupIDAttr, targetAttr ); attributeAffects( inputCurve, targetAttr ); attributeAffects( inputMesh, targetAttr ); attributeAffects( inputSurf, targetAttr ); attributeAffects( instanceMesh, targetAttr ); attributeAffects( renderStateAttr, targetAttr ); attributeAffects( runDynamics, targetAttr ); attributeAffects( shaveBlindHair, targetAttr ); attributeAffects( aEvalOption, targetAttr ); attributeAffects( shaveParamAmbDiff, targetAttr ); attributeAffects( shaveParamAnimSpeed, targetAttr ); attributeAffects( shaveParamDampening, targetAttr ); attributeAffects( shaveParamDisplacement, targetAttr ); attributeAffects( shaveParamFrizzAnim, targetAttr ); attributeAffects( shaveParamFrizzAnimDir, targetAttr ); attributeAffects( shaveParamFrizzAnimDirX, targetAttr ); attributeAffects( shaveParamFrizzAnimDirY, targetAttr ); attributeAffects( shaveParamFrizzAnimDirZ, targetAttr ); attributeAffects( shaveParamFrizzFreqX, targetAttr ); attributeAffects( shaveParamFrizzFreqY, targetAttr ); attributeAffects( shaveParamFrizzFreqZ, targetAttr ); attributeAffects( shaveParamFrizzRoot, targetAttr ); attributeAffects( shaveParamFrizzTip, targetAttr ); attributeAffects( shaveParamGeomShadow, targetAttr ); attributeAffects( shaveParamGloss, targetAttr ); attributeAffects( shaveParamHaircount, targetAttr ); attributeAffects( shaveParamHairColor, targetAttr ); attributeAffects( shaveParamHueVariation, targetAttr ); attributeAffects( shaveParamInstancingStatus, targetAttr ); attributeAffects( shaveParamKinkFreqX, targetAttr ); attributeAffects( shaveParamKinkFreqY, targetAttr ); attributeAffects( shaveParamKinkFreqZ, targetAttr ); attributeAffects( shaveParamKinkRoot, targetAttr ); attributeAffects( shaveParamKinkTip, targetAttr ); attributeAffects( shaveParamMultStrand, targetAttr ); attributeAffects( shaveParamMutantColor, targetAttr ); attributeAffects( shaveParamMutantPercent, targetAttr ); attributeAffects( shaveParamNoInterp, targetAttr ); attributeAffects( shaveParamPasses, targetAttr ); attributeAffects( shaveParamRandScale, targetAttr ); attributeAffects( shaveParamRandomizeMulti, targetAttr ); attributeAffects( shaveParamRootColor, targetAttr ); attributeAffects( shaveParamRootStiffness, targetAttr ); attributeAffects( shaveParamScale, targetAttr ); attributeAffects( shaveParamSegs, targetAttr ); attributeAffects( shaveParamSelfShadow, targetAttr ); attributeAffects( shaveParamSpecular, targetAttr ); attributeAffects( shaveParamSplayRoot, targetAttr ); attributeAffects( shaveParamSplayTip, targetAttr ); attributeAffects( shaveParamMultAsp, targetAttr ); //vlad|05July2010 attributeAffects( shaveParamOffset, targetAttr ); //vlad|09July2010 attributeAffects( shaveParamAspect, targetAttr ); //vlad|09July2010 attributeAffects( shaveParamStiffness, targetAttr ); attributeAffects( shaveParamThickRoot, targetAttr ); attributeAffects( shaveParamThickTip, targetAttr ); attributeAffects( shaveParamValueVariation, targetAttr ); attributeAffects( surfTessU, targetAttr ); attributeAffects( surfTessV, targetAttr ); attributeAffects( subdTessDept, targetAttr ); attributeAffects( subdTessSamp, targetAttr ); attributeAffects( textureCacheUpdatedAttr, targetAttr ); attributeAffects( timeAttr, targetAttr ); attributeAffects( aSquirrel, targetAttr ); //to update param -- vlad|02July2010 attributeAffects( flyawayPerc, targetAttr ); attributeAffects( flyawayStren, targetAttr ); attributeAffects( messStren, targetAttr ); attributeAffects( clumps, targetAttr ); attributeAffects( clumpsStren, targetAttr ); attributeAffects( clumpsColStren, targetAttr ); attributeAffects( clumpsRotStren, targetAttr ); attributeAffects( clumpsRotOffset, targetAttr ); attributeAffects( clumpsRandomize, targetAttr ); attributeAffects( clumpsFlatness, targetAttr ); attributeAffects( clumpsScruffle, targetAttr ); attributeAffects( randomSeedOffset, targetAttr ); } //vlad|06Apr2010 -- 'stackIndex' value access int shaveHairShape::getStackIndex() const { int index; MPlug stackIndexPlug(thisMObject(),stackIndex); stackIndexPlug.getValue(index); return index; } //vlad|06Apr2010 -- 'stackIndex' value access void shaveHairShape::setStackIndex(int index) { MPlug stackIndexPlug(thisMObject(),stackIndex); stackIndexPlug.setValue(index); }