// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include "shaveBlindData.h" #include #include #include #include #include #include #include #include #include "shaveDebug.h" #include "shaveError.h" #include "shaveNode.h" #include "shaveRender.h" #include "shaveSDK.h" #include "shaveUtil.h" #if defined(OSMac_) && !defined(OSMac_MachO_) #include "shaveMacCarbon.h" #endif const MString shaveNode::nodeTypeName("shaveNode"); const int shaveNode::kNodeVersion = 13; MObject shaveNode::blockDynamics; MObject shaveNode::collisionObjectsAttr; MObject shaveNode::collisionObjectsGroupIDAttr; MObject shaveNode::displayHairMaxAttr; MObject shaveNode::displayHairRatioAttr; MObject shaveNode::displayNodeAttr; MObject shaveNode::dspyMode; MObject shaveNode::growthObjectsGroupIDAttr; MObject shaveNode::hairColorTexture, shaveNode::hairColorTextureR, shaveNode::hairColorTextureG, shaveNode::hairColorTextureB; MObject shaveNode::inputCurve; MObject shaveNode::inputMesh; MObject shaveNode::inputSurf; MObject shaveNode::instanceMesh; MObject shaveNode::instanceMeshChanged; MObject shaveNode::instancingStatusChanged; MObject shaveNode::isActive; MObject shaveNode::mutantHairColorTexture, shaveNode::mutantHairColorTextureR, shaveNode::mutantHairColorTextureG, shaveNode::mutantHairColorTextureB; MObject shaveNode::neverBeenInstanced; MObject shaveNode::nodeVersionAttr; MObject shaveNode::outputMesh; MObject shaveNode::renderStateAttr; MObject shaveNode::ribInsert; MObject shaveNode::rootHairColorTexture, shaveNode::rootHairColorTextureR, shaveNode::rootHairColorTextureG, shaveNode::rootHairColorTextureB; MObject shaveNode::runDynamics; MObject shaveNode::shaveBlindHair; MObject shaveNode::shaveBlindState; MObject shaveNode::shaveNodeCommand; MObject shaveNode::shaveParamAmbDiff; // slider 6 MObject shaveNode::shaveParamAnimSpeed; // slider 33 MObject shaveNode::shaveParamCollide; MObject shaveNode::shaveParamCollisionMethod; MObject shaveNode::shaveParamDampening; // slider 40 MObject shaveNode::shaveParamDisplacement; // slider 43 MObject shaveNode::shaveParamFrizzAnim; // slider 32 MObject shaveNode::shaveParamFrizzAnimDir, shaveNode::shaveParamFrizzAnimDirX, shaveNode::shaveParamFrizzAnimDirY, shaveNode::shaveParamFrizzAnimDirZ; MObject shaveNode::shaveParamFrizzFreqX; // slider 1 MObject shaveNode::shaveParamFrizzFreqY; // slider 30 MObject shaveNode::shaveParamFrizzFreqZ; // slider 31 MObject shaveNode::shaveParamFrizzRoot; // slider 0 MObject shaveNode::shaveParamFrizzTip; // slider 24 MObject shaveNode::shaveParamGeomShadow; MObject shaveNode::shaveParamGloss; // slider 5 MObject shaveNode::shaveParamGravity; MObject shaveNode::shaveParamHairColor, shaveNode::shaveParamHairRed, // slider 9 shaveNode::shaveParamHairGreen, // slider 10 shaveNode::shaveParamHairBlue; // slider 11 MObject shaveNode::shaveParamHaircount; MObject shaveNode::shaveParamHueVariation; // slider 12 MObject shaveNode::shaveParamInstancingStatus; MObject shaveNode::shaveParamKinkFreqX; // slider 3 MObject shaveNode::shaveParamKinkFreqY; // slider 34 MObject shaveNode::shaveParamKinkFreqZ; // slider 35 MObject shaveNode::shaveParamKinkRoot; // slider 38 MObject shaveNode::shaveParamKinkTip; // slider 2 MObject shaveNode::shaveParamMultStrand; // slider 25 MObject shaveNode::shaveParamMutantColor, shaveNode::shaveParamMutantRed, // slider 13 shaveNode::shaveParamMutantGreen, // slider 14 shaveNode::shaveParamMutantBlue; // slider 15 MObject shaveNode::shaveParamMutantPercent; // slider 16 MObject shaveNode::shaveParamNoInterp; MObject shaveNode::shaveParamPainted; MObject shaveNode::shaveParamPasses; MObject shaveNode::shaveParamRandomizeMulti; // slider 42 MObject shaveNode::shaveParamRandScale; // slider 36 MObject shaveNode::shaveParamRootColor, shaveNode::shaveParamRootRed, // slider 17 shaveNode::shaveParamRootGreen, // slider 18 shaveNode::shaveParamRootBlue; // slider 19 MObject shaveNode::shaveParamRootStiffness; // slider 21 MObject shaveNode::shaveParamScale; // slider 41 MObject shaveNode::shaveParamSegs; MObject shaveNode::shaveParamSelfShadow; // slider 7 MObject shaveNode::shaveParamSpecular; // slider 4 MObject shaveNode::shaveParamSplayRoot; // slider 26 MObject shaveNode::shaveParamSplayTip; // slider 27 MObject shaveNode::shaveParamMultAsp; // slider 44 -- vlad|05July2010 MObject shaveNode::shaveParamOffset; // slider 45 -- vlad|09July2010 MObject shaveNode::shaveParamAspect; // slider 46 -- vlad|09July2010 MObject shaveNode::shaveParamStiffness; // slider 8 MObject shaveNode::shaveParamThickRoot; // slider 20 MObject shaveNode::shaveParamThickTip; // slider 37 MObject shaveNode::shaveParamTotalGuides; MObject shaveNode::shaveParamValueVariation; // slider 39 MObject shaveNode::shaveTexMutantColor; MObject shaveNode::shaveTextureAttr; MObject shaveNode::surfTessU; MObject shaveNode::surfTessV; MObject shaveNode::textureCacheUpdatedAttr; MObject shaveNode::timeAttr; MObject shaveNode::triggerAttr; MObject shaveNode::overrideGeomShaderAttr; MObject shaveNode::uvSetAssignmentsAttr; MObject shaveNode::uvSetNameAttr; MObject shaveNode::uvSetTexturesAttr; MObject shaveNode::versionLockAttr; MObject shaveNode::flyawayPerc; MObject shaveNode::flyawayStren; MObject shaveNode::messStren; MObject shaveNode::clumps; MObject shaveNode::clumpsStren; MObject shaveNode::clumpsColStren; MObject shaveNode::clumpsRotStren; MObject shaveNode::clumpsRotOffset; // Deprecated Attributes MObject shaveNode::birthName; MObject shaveNode::closeRibFilename; MObject shaveNode::growthSet; MObject shaveNode::instanceGeoAttr; MObject shaveNode::nodeNameAttr; MObject shaveNode::openRibFilename; MObject shaveNode::ribDumper; MObject shaveNode::shaveBlindShaveParams; MObject shaveNode::shaveParamThickness; MObject shaveNode::shaveUvSets; MObject shaveNode::signatureAttr; MObject shaveNode::skullSet; MObject shaveNode::sourceType; MTypeId shaveNode::id( 0x00106500 ); void* shaveNode::creator() { return new shaveNode; } MStatus shaveNode::initialize() { MFnUnitAttribute unitAttr; MFnTypedAttribute tAttr; MFnNumericAttribute nAttr; MFnCompoundAttribute compAttr; MFnEnumAttribute eAttr; MFnGenericAttribute gAttr; MFnMessageAttribute mesgAttr; MStatus stat; //*************************************************************** // // REGULAR ATTRIBUTES // //*************************************************************** blockDynamics = nAttr.create( "disableDynamics", "disabled", MFnNumericData::kBoolean, false ); nAttr.setStorable(true); addAttribute(blockDynamics); collisionObjectsAttr = gAttr.create("collisionObjects", "co"); 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); addAttribute(collisionObjectsAttr); collisionObjectsGroupIDAttr = nAttr.create("collisionObjectsGroupID", "cmgi", MFnNumericData::kLong); nAttr.setArray(true); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setDisconnectBehavior(MFnAttribute::kDelete); addAttribute(collisionObjectsGroupIDAttr); displayNodeAttr = mesgAttr.create("displayNode", "dn"); mesgAttr.setStorable(false); mesgAttr.setHidden(true); addAttribute(displayNodeAttr); dspyMode = eAttr.create("displayAs", "dspyas", 1); eAttr.addField("guides", kHairDisplayGuides); eAttr.addField("hairs", kHairDisplayHair); eAttr.addField("geometry", kHairDisplayGeom); eAttr.setStorable(true); addAttribute(dspyMode); growthObjectsGroupIDAttr = nAttr.create("growthObjectsGroupID", "gmgi", MFnNumericData::kLong); nAttr.setArray(true); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setDisconnectBehavior(MFnAttribute::kDelete); addAttribute(growthObjectsGroupIDAttr); hairColorTextureR = nAttr.create("hairColorTextureR", "hctr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(hairColorTextureR); hairColorTextureG = nAttr.create("hairColorTextureG", "hctg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(hairColorTextureG); hairColorTextureB = nAttr.create("hairColorTextureB", "hctb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(hairColorTextureB); hairColorTexture = nAttr.create( "hairColorTexture", "htc", hairColorTextureR, hairColorTextureG, hairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); addAttribute(hairColorTexture); inputCurve = tAttr.create("inputCurve", "incrv", MFnData::kNurbsCurve); tAttr.setArray (true); tAttr.setHidden(true); tAttr.setStorable(false); tAttr.setDisconnectBehavior(MFnAttribute::kDelete); addAttribute(inputCurve); inputMesh = tAttr.create ("inputMesh", "input", MFnData::kMesh); tAttr.setArray (true); tAttr.setHidden(true); tAttr.setStorable(false); tAttr.setDisconnectBehavior(MFnAttribute::kDelete); addAttribute(inputMesh); 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); addAttribute(inputSurf); instanceMesh = tAttr.create("instanceMesh", "im", MFnData::kMesh); tAttr.setHidden(true); tAttr.setStorable(true); addAttribute(instanceMesh); isActive = nAttr.create( "active", "act", MFnNumericData::kBoolean, true); nAttr.setStorable(true); addAttribute(isActive); mutantHairColorTextureR = nAttr.create( "mutantHairColorTextureR", "mhctr", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(mutantHairColorTextureR); mutantHairColorTextureG = nAttr.create( "mutantHairColorTextureG", "mhctg", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(mutantHairColorTextureG); mutantHairColorTextureB = nAttr.create( "mutantHairColorTextureB", "mhctb", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(mutantHairColorTextureB); mutantHairColorTexture = nAttr.create( "mutantHairColorTexture", "mhtc", mutantHairColorTextureR, mutantHairColorTextureG, mutantHairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); addAttribute(mutantHairColorTexture); neverBeenInstanced = nAttr.create( "neverBeenInstanced", "nbi", MFnNumericData::kBoolean, true ); nAttr.setConnectable(false); nAttr.setHidden(true); nAttr.setStorable(true); addAttribute(neverBeenInstanced); nodeVersionAttr = nAttr.create("nodeVersion", "nv", MFnNumericData::kLong); nAttr.setDefault(0); nAttr.setHidden(true); nAttr.setWritable(true); nAttr.setStorable(true); addAttribute(nodeVersionAttr); outputMesh = tAttr.create("outputMesh", "out", MFnData::kMesh); tAttr.setStorable(false); tAttr.setHidden(true); tAttr.setWritable(false); addAttribute(outputMesh); overrideGeomShaderAttr = nAttr.create( "overrideGeomShader", "ogsh", MFnNumericData::kBoolean, true ); nAttr.setStorable(true); addAttribute(overrideGeomShaderAttr); 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); addAttribute(renderStateAttr); ribInsert = tAttr.create("ribStuff", "rbs", MFnStringData::kString); tAttr.setStorable(true); addAttribute(ribInsert); rootHairColorTextureR = nAttr.create( "rootHairColorTextureR", "rhctr", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(rootHairColorTextureR); rootHairColorTextureG = nAttr.create( "rootHairColorTextureG", "rhctg", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(rootHairColorTextureG); rootHairColorTextureB = nAttr.create( "rootHairColorTextureB", "rhctb", MFnNumericData::kFloat, 0 ); nAttr.setStorable(true); addAttribute(rootHairColorTextureB); rootHairColorTexture = nAttr.create( "rootHairColorTexture", "rhtc", rootHairColorTextureR, rootHairColorTextureG, rootHairColorTextureB ); nAttr.setStorable(true); nAttr.setUsedAsColor(false); nAttr.setKeyable(true); addAttribute(rootHairColorTexture); runDynamics = nAttr.create("runDynamics", "rd", MFnNumericData::kLong, 0); nAttr.setStorable(true); nAttr.setHidden(true); addAttribute(runDynamics); shaveBlindHair = tAttr.create( "blindShaveData", "BSD", blindShaveData::dataTypeId ); tAttr.setHidden(true); tAttr.setStorable(true); addAttribute(shaveBlindHair); shaveNodeCommand = tAttr.create("evalOption", "evo", MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(shaveNodeCommand); //*************************************************************** // // 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); addAttribute(shaveParamAmbDiff); shaveParamCollide = nAttr.create( "enableCollision", "spec", MFnNumericData::kBoolean, false ); nAttr.setStorable(true); addAttribute(shaveParamCollide); shaveParamCollisionMethod = nAttr.create("collisionMethod", "spcm", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setHidden(true); addAttribute(shaveParamCollisionMethod); shaveParamDampening = nAttr.create("dampening", "damp", MFnNumericData::kFloat, 0.0); nAttr.setMin(0.0); nAttr.setMax(1.0); addAttribute(shaveParamDampening); shaveParamFrizzAnim = nAttr.create("frizzAnim", "spfa", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzAnim); shaveParamFrizzAnimDirX = nAttr.create("animDirX", "spadx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamFrizzAnimDirX); shaveParamFrizzAnimDirY = nAttr.create("animDirY", "spady", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamFrizzAnimDirY); shaveParamFrizzAnimDirZ = nAttr.create("animDirZ", "spadz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamFrizzAnimDirZ); shaveParamFrizzAnimDir = nAttr.create( "frizzAnimDir", "spad", shaveParamFrizzAnimDirX, shaveParamFrizzAnimDirY, shaveParamFrizzAnimDirZ ); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamFrizzAnimDir); shaveParamAnimSpeed = nAttr.create("animSpeed", "spas", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamAnimSpeed); shaveParamDisplacement = nAttr.create("displacement", "disp", MFnNumericData::kFloat, 0.0f); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setSoftMin(-10.0); nAttr.setSoftMax(10.0); addAttribute(shaveParamDisplacement); shaveParamFrizzFreqX = nAttr.create("frizzXFrequency", "spffx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzFreqX); shaveParamFrizzFreqY = nAttr.create("frizzYFrequency", "spffy", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzFreqY); shaveParamFrizzFreqZ = nAttr.create("frizzZFrequency", "spffz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzFreqZ); shaveParamFrizzRoot = nAttr.create("rootFrizz", "sprf", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzRoot); shaveParamFrizzTip = nAttr.create("tipFrizz", "sptf", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamFrizzTip); shaveParamGeomShadow = nAttr.create("geomShadow", "spgs", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.0); nAttr.setMax(1.0); nAttr.setStorable(true); addAttribute(shaveParamGeomShadow); shaveParamGloss = nAttr.create("gloss", "spgloss", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(0.099999); nAttr.setKeyable(true); addAttribute(shaveParamGloss); shaveParamHairRed = nAttr.create("hairRed", "sphr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamHairRed); shaveParamHairGreen = nAttr.create("hairGreen", "sphg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamHairGreen); shaveParamHairBlue = nAttr.create("hairBlue", "sphb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamHairBlue); shaveParamHairColor = nAttr.create( "hairColor", "sphcol", shaveParamHairRed, shaveParamHairGreen, shaveParamHairBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); addAttribute(shaveParamHairColor); shaveParamHaircount = nAttr.create("hairCount", "sphc", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(30000); addAttribute(shaveParamHaircount); shaveParamHueVariation = nAttr.create("hueVariation", "sphv", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); addAttribute(shaveParamHueVariation); shaveParamInstancingStatus = nAttr.create( "instancingStatus", "spis", MFnNumericData::kBoolean, false ); nAttr.setStorable(true); addAttribute(shaveParamInstancingStatus); shaveParamKinkFreqX = nAttr.create("kinkXFrequency", "spkfx", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamKinkFreqX); shaveParamKinkFreqY = nAttr.create("kinkYFrequency", "spkfy", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamKinkFreqY); shaveParamKinkFreqZ = nAttr.create("kinkZFrequency", "spkfz", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.001); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamKinkFreqZ); shaveParamKinkRoot = nAttr.create("rootKink", "spkr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamKinkRoot); shaveParamKinkTip = nAttr.create("tipKink", "spkt", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamKinkTip); shaveParamMultStrand = nAttr.create("multiStrandCount", "spms", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(10); addAttribute(shaveParamMultStrand); shaveParamMutantRed = nAttr.create("mutantHairRed", "spmhr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(shaveParamMutantRed); shaveParamMutantGreen = nAttr.create("mutantHairGreen", "spmhg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(shaveParamMutantGreen); shaveParamMutantBlue = nAttr.create("mutantHairBlue", "spmhb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); addAttribute(shaveParamMutantBlue); shaveParamMutantColor = nAttr.create( "mutantHairColor", "spmhc", shaveParamMutantRed, shaveParamMutantGreen, shaveParamMutantBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); addAttribute(shaveParamMutantColor); shaveParamMutantPercent = nAttr.create("percentMutantHairs", "spmp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); addAttribute(shaveParamMutantPercent); shaveParamNoInterp = nAttr.create( "interpolateGuides", "dointerp", MFnNumericData::kBoolean, true ); nAttr.setStorable(true); addAttribute(shaveParamNoInterp); shaveParamPasses = nAttr.create("hairPasses", "sphp", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(20); addAttribute(shaveParamPasses); shaveParamRandomizeMulti = nAttr.create("randomizeMulti", "sprm", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0.0f); nAttr.setMax(1.0f); addAttribute(shaveParamRandomizeMulti); shaveParamRandScale = nAttr.create("randScale", "sprs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); nAttr.setKeyable(true); addAttribute(shaveParamRandScale); shaveParamRootRed = nAttr.create("rootRed", "sprr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamRootRed); shaveParamRootGreen = nAttr.create("rootGreen", "sprg", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamRootGreen); shaveParamRootBlue = nAttr.create("rootBlue", "sprb", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setKeyable(true); addAttribute(shaveParamRootBlue); shaveParamRootColor = nAttr.create( "rootColor", "sprtc", shaveParamRootRed, shaveParamRootGreen, shaveParamRootBlue ); nAttr.setStorable(true); nAttr.setUsedAsColor(true); nAttr.setKeyable(true); addAttribute(shaveParamRootColor); shaveParamRootStiffness = nAttr.create("rootStiffness", "rstf", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.0); nAttr.setMax(1.0); addAttribute(shaveParamRootStiffness); shaveParamScale = nAttr.create("scale", "sc", MFnNumericData::kFloat, 1.0); nAttr.setMin(0.01); nAttr.setSoftMax(1.0); addAttribute(shaveParamScale); shaveParamSegs = nAttr.create("hairSegments", "spsegs", MFnNumericData::kShort, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setSoftMax(50); addAttribute(shaveParamSegs); shaveParamSelfShadow = nAttr.create("selfShadow", "spss", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); addAttribute(shaveParamSelfShadow); shaveParamSpecular = nAttr.create("specular", "spspec", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(1); nAttr.setKeyable(true); addAttribute(shaveParamSpecular); shaveParamSplayRoot = nAttr.create("rootSplay", "sprsp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamSplayRoot); shaveParamSplayTip = nAttr.create("tipSplay", "sptsp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamSplayTip); shaveParamSplayTip = nAttr.create("multAsp", "mlasp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamSplayTip); shaveParamStiffness = nAttr.create("stiffness", "spstiff", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1); nAttr.setKeyable(true); addAttribute(shaveParamStiffness); shaveParamThickRoot = nAttr.create("rootThickness", "sptr", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(2); nAttr.setKeyable(true); addAttribute(shaveParamThickRoot); shaveParamThickTip = nAttr.create("tipThickness", "sptt", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(2); nAttr.setKeyable(true); addAttribute(shaveParamThickTip); shaveParamTotalGuides = nAttr.create("totalGuides", "sptg", MFnNumericData::kShort, 0); nAttr.setHidden(true); addAttribute(shaveParamTotalGuides); shaveParamValueVariation = nAttr.create("valueVariation", "spvv", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(100); nAttr.setKeyable(true); addAttribute(shaveParamValueVariation); //vlad|05July2010 shaveParamMultAsp = nAttr.create("multAsp", "mlasp", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamMultAsp); //vlad|09July2010 shaveParamOffset = nAttr.create("Offset", "offs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamOffset); //vlad|09July2010 shaveParamAspect = nAttr.create("Asepect", "aspc", MFnNumericData::kFloat, 1.0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setSoftMax(5); nAttr.setKeyable(true); addAttribute(shaveParamAspect); //*************************************************************** // // MORE REGULAR ATTRIBUTES // //*************************************************************** shaveTextureAttr = nAttr.create("shaveTex", "shtx", MFnNumericData::kFloat); nAttr.setArray(true); nAttr.setIndexMatters(true); nAttr.setStorable(true); addAttribute(shaveTextureAttr); surfTessU = nAttr.create("uSubdivisions", "tusd", MFnNumericData::kShort, 2); nAttr.setStorable(true); addAttribute(surfTessU); surfTessV = nAttr.create("vSubdivisions", "tvsd", MFnNumericData::kShort, 2); nAttr.setStorable(true); addAttribute(surfTessV); timeAttr = unitAttr.create("time", "tm", MFnUnitAttribute::kTime, 0.0); unitAttr.setHidden(true); addAttribute(timeAttr); triggerAttr = nAttr.create("trigger", "trg", MFnNumericData::kFloat, 0); nAttr.setHidden(true); nAttr.setWritable(false); nAttr.setStorable(false); addAttribute(triggerAttr); uvSetNameAttr = tAttr.create("uvSetName", "uvsn", MFnStringData::kString); tAttr.setHidden(true); tAttr.setDisconnectBehavior(MFnAttribute::kReset); uvSetTexturesAttr = mesgAttr.create("uvSetTextures", "uvst"); mesgAttr.setStorable(false); mesgAttr.setHidden(true); mesgAttr.setArray(true); mesgAttr.setIndexMatters(false); mesgAttr.setDisconnectBehavior(MFnAttribute::kDelete); uvSetAssignmentsAttr = compAttr.create("uvSetAssignments", "uvsa"); compAttr.setHidden(true); compAttr.setArray(true); compAttr.setIndexMatters(false); compAttr.setDisconnectBehavior(MFnAttribute::kDelete); compAttr.addChild(uvSetNameAttr); compAttr.addChild(uvSetTexturesAttr); addAttribute(uvSetAssignmentsAttr); versionLockAttr = nAttr.create("versionLock", "vl", MFnNumericData::kLong); nAttr.setHidden(true); nAttr.setStorable(true); addAttribute(versionLockAttr); displayHairMaxAttr = nAttr.create( "displayHairMax", "dhm", MFnNumericData::kLong, 10000.0 ); nAttr.setMin(0.0); nAttr.setSoftMax(25000.0); addAttribute(displayHairMaxAttr); displayHairRatioAttr = nAttr.create( "displayHairRatio", "dhr", MFnNumericData::kFloat, 1.0 ); nAttr.setMin(0.0); nAttr.setMax(1.0); addAttribute(displayHairRatioAttr); textureCacheUpdatedAttr = nAttr.create( "textureCacheUpdated", "tau", MFnNumericData::kBoolean, false ); nAttr.setStorable(false); addAttribute(textureCacheUpdatedAttr); flyawayPerc = nAttr.create("flyawayPerc", "fwpc", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(1); nAttr.setMax(100); stat = addAttribute(flyawayPerc); MChkErr(stat, "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); stat = addAttribute(flyawayStren); MChkErr(stat, "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); stat = addAttribute(messStren); MChkErr(stat, "can't add 'messStren' attribute."); clumps = nAttr.create("clumps", "clp", MFnNumericData::kInt, 0); nAttr.setStorable(true); nAttr.setMin(0); nAttr.setMax(1000); stat = addAttribute(clumps); MChkErr(stat, "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); stat = addAttribute(clumpsStren); MChkErr(stat, "can't add 'clumpsStrength' attribute."); clumpsColStren = nAttr.create("clumpsColStren", "clcs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); stat = addAttribute(clumpsColStren); MChkErr(stat, "can't add 'clumpsColStren' attribute."); clumpsRotStren = nAttr.create("clumpsRotStren", "clrs", MFnNumericData::kFloat, 0); nAttr.setStorable(true); nAttr.setSoftMin(0.0); nAttr.setSoftMax(1.0); nAttr.setKeyable(true); stat = addAttribute(clumpsRotStren); MChkErr(stat, "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); stat = addAttribute(clumpsRotOffset); MChkErr(stat, "can't add 'clumpsRotOffset' attribute."); //*************************************************************** // // 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 "isc1" and "instancingStatusChanged1" //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( "instancingStatusChanged1", "isc1", //vlad|10Mar2010 - let's try another name MFnNumericData::kBoolean, /*false*/0 ); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setWritable(false); stat = addAttribute(instancingStatusChanged); MChkErr(stat, "can't add 'instancingStatusChanged' attribute."); //vlad|10Mar2010 attributeAffects(shaveParamInstancingStatus, instancingStatusChanged); instanceMeshChanged = nAttr.create( "instanceMeshChanged", "imc", MFnNumericData::kBoolean ); nAttr.setHidden(true); nAttr.setStorable(false); nAttr.setWritable(false); addAttribute(instanceMeshChanged); attributeAffects(instanceMesh, instanceMeshChanged); //*************************************************************** // // DEPRECATED ATTRIBUTES // // These attributes are no longer used. They are only retained // so that old scenes can still be loaded. // //*************************************************************** birthName = tAttr.create( "birthName", "bnme", MFnStringData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(birthName); shaveBlindShaveParams = tAttr.create("blindShaveParams", "BSP", blindShaveData::dataTypeId); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(shaveBlindShaveParams); shaveBlindState = tAttr.create("blindShaveState", "BSS", blindShaveData::dataTypeId); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(shaveBlindState); growthSet = mesgAttr.create("growthSet", "sgrs"); mesgAttr.setHidden(true); mesgAttr.setStorable(false); addAttribute(growthSet); instanceGeoAttr = mesgAttr.create("instanceSource", "instsrc"); mesgAttr.setHidden(true); mesgAttr.setStorable(false); addAttribute(instanceGeoAttr); nodeNameAttr = tAttr.create( "nodeName", "nme", MFnStringData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(nodeNameAttr); ribDumper = nAttr.create("ribDumper", "ribd", MFnNumericData::kBoolean, false); nAttr.setHidden(true); nAttr.setStorable(false); addAttribute(ribDumper); openRibFilename = tAttr.create("ribFilenameClose", "rfno",MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(openRibFilename); closeRibFilename = tAttr.create("ribFilenameOpen", "rfnc",MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(closeRibFilename); signatureAttr = tAttr.create( "dynamicsSeeds", "dysd", blindShaveData::dataTypeId ); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(signatureAttr); shaveParamGravity = nAttr.create("shaveGravity", "spgrv", MFnNumericData::kFloat, 0); nAttr.setStorable(false); nAttr.setHidden(true); addAttribute(shaveParamGravity); shaveUvSets = tAttr.create("shaveUvSets", "uvsts", MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); tAttr.setArray(true); addAttribute(shaveUvSets); skullSet = mesgAttr.create("skullSet", "ssks"); mesgAttr.setHidden(true); mesgAttr.setStorable(false); addAttribute(skullSet); sourceType = tAttr.create("sourceType", "stp", MFnData::kString); tAttr.setHidden(true); tAttr.setStorable(false); addAttribute(sourceType); shaveParamThickness = nAttr.create("thickness", "spthk", MFnNumericData::kFloat, 0.0); nAttr.setHidden(true); nAttr.setStorable(false); addAttribute(shaveParamThickness); return MS::kSuccess; }