aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveNode.cpp
diff options
context:
space:
mode:
authorBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
committerBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
commitbd0027e737c6512397f841c22786274ed74b927f (patch)
treef7ffbdb8f3741bb7f24635616cc189cba5cb865c /mayaPlug/shaveNode.cpp
downloadarchived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz
archived-shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'mayaPlug/shaveNode.cpp')
-rw-r--r--mayaPlug/shaveNode.cpp1226
1 files changed, 1226 insertions, 0 deletions
diff --git a/mayaPlug/shaveNode.cpp b/mayaPlug/shaveNode.cpp
new file mode 100644
index 0000000..149fe45
--- /dev/null
+++ b/mayaPlug/shaveNode.cpp
@@ -0,0 +1,1226 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include "shaveBlindData.h"
+#include <maya/MFnStringData.h>
+#include <maya/MFnCompoundAttribute.h>
+#include <maya/MFnEnumAttribute.h>
+#include <maya/MFnGenericAttribute.h>
+#include <maya/MFnMessageAttribute.h>
+#include <maya/MFnNumericAttribute.h>
+#include <maya/MFnTypedAttribute.h>
+#include <maya/MFnUnitAttribute.h>
+
+#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;
+}