diff options
| author | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
|---|---|---|
| committer | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
| commit | bd0027e737c6512397f841c22786274ed74b927f (patch) | |
| tree | f7ffbdb8f3741bb7f24635616cc189cba5cb865c /mayaPlug/shaveHairGeomIt.cpp | |
| download | shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip | |
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'mayaPlug/shaveHairGeomIt.cpp')
| -rw-r--r-- | mayaPlug/shaveHairGeomIt.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/mayaPlug/shaveHairGeomIt.cpp b/mayaPlug/shaveHairGeomIt.cpp new file mode 100644 index 0000000..8ce71a0 --- /dev/null +++ b/mayaPlug/shaveHairGeomIt.cpp @@ -0,0 +1,247 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +#include <maya/MDagPath.h> +#include <maya/MFnComponent.h> +#include <maya/MFnDoubleIndexedComponent.h> +#include <maya/MFnSingleIndexedComponent.h> +#include <maya/MMatrix.h> +#include <maya/MObjectArray.h> +#include <maya/MPoint.h> +#include <maya/MPxGeometryIterator.h> + +#include "shaveHairGeomIt.h" +#include "shaveHairShape.h" +#include "shaveSDKTYPES.h" + +static const int mid = SHAVE_VERTS_PER_GUIDE / 2; + + +shaveHairGeomIt::shaveHairGeomIt(void* geom, MObjectArray& components) +: MPxGeometryIterator(geom, components) +, mComponents(components) +, mHairShape((shaveHairShape*)geom) +{ + mWholeGeom = (components.length() == 0); + reset(); +} + +shaveHairGeomIt::shaveHairGeomIt(void* geom, MObject& components) +: MPxGeometryIterator(geom, components) +, mHairShape((shaveHairShape*)geom) +{ + mWholeGeom = components.isNull(); + + if (!mWholeGeom) mComponents.append(components); + + reset(); +} + + +void shaveHairGeomIt::component(MObject& comp) +{ + if (mIsDone) + comp = MObject::kNullObj; + else + { + MFnDoubleIndexedComponent compFn; + + comp = compFn.create(shaveHairShape::kShaveGuideVertComponent); + compFn.addElement(mCurGuide, mCurVert); + } +} + + +int shaveHairGeomIt::index() const +{ + return mIterationIndex; +} + + +int shaveHairGeomIt::indexUnsimplified() const +{ + return mCurGuide * SHAVE_VERTS_PER_GUIDE + mCurVert; +} + + +int shaveHairGeomIt::iteratorCount() const +{ + return mNumGuides * SHAVE_VERTS_PER_GUIDE; +} + + +void shaveHairGeomIt::next() +{ + if (!mIsDone) + { + if (mWholeGeom) + { + if (++mCurVert >= SHAVE_VERTS_PER_GUIDE) + { + mCurVert = 0; + mIsDone = (++mCurGuide >= mNumGuides); + } + } + else + { + MFnComponent compFn(mComponents[mObjIndex]); + + if (++mElementIndex >= compFn.elementCount()) + { + mElementIndex = 0; + + // + // I don't know if we need to worry about the + // possibility of empty component objects, but if so, + // this should take care of them. + // + while (++mObjIndex < mComponents.length()) + { + compFn.setObject(mComponents[mObjIndex]); + + if (compFn.elementCount() > 0) break; + } + + mIsDone = (mObjIndex >= mComponents.length()); + } + + if (!mIsDone) + { + if (mComponents[mObjIndex].hasFn(MFn::kSingleIndexedComponent)) + { + MFnSingleIndexedComponent guideComp(mComponents[mObjIndex]); + + mCurGuide = guideComp.element(mElementIndex); + mCurVert = mid; + } + else + { + MFnDoubleIndexedComponent vertComp(mComponents[mObjIndex]); + + vertComp.getElement(mElementIndex, mCurGuide, mCurVert); + } + } + } + + mIterationIndex++; + } +} + + +MPoint shaveHairGeomIt::point() const +{ + MPoint p; + + if (!mIsDone && mHairShape) + { + // + // Load the hairShape into the Shave engine. + // + mHairShape->makeCurrent(); + + SOFTGUIDE guide; + + if (SHAVEfetch_guide(mCurGuide, &guide) != -1) + { + VERT& vert = guide.guide[mCurVert]; + + p.x = (double)vert.x; + p.y = (double)vert.y; + p.z = (double)vert.z; + + // + // Transform the point into local space. + // + MDagPath shapePath; + + MDagPath::getAPathTo(mHairShape->thisMObject(), shapePath); + + p *= shapePath.inclusiveMatrixInverse(); + } + } + + return p; +} + + +void shaveHairGeomIt::reset() +{ + MPxGeometryIterator::reset(); + setCurrentPoint(0); + + mIterationIndex = 0; + + if (mHairShape) + { + mNumGuides = (int)mHairShape->getGuideCount(); + setMaxPoints(mNumGuides * SHAVE_VERTS_PER_GUIDE); + } + else + { + setMaxPoints(0); + mNumGuides = 0; + } + + mCurGuide = 0; + mCurVert = 0; + + if (mWholeGeom) + { + mIsDone = (mNumGuides == 0); + } + else + { + // + // I don't know if we have to worry about getting empty component + // objects, but let's check, just to be safe. + // + for (mObjIndex = 0; mObjIndex < mComponents.length(); mObjIndex++) + { + if (mComponents[mObjIndex].hasFn(MFn::kSingleIndexedComponent)) + { + MFnSingleIndexedComponent compFn(mComponents[mObjIndex]); + + if (compFn.elementCount() > 0) + { + mCurGuide = compFn.element(0); + mCurVert = mid; + break; + } + } + else if (mComponents[mObjIndex].hasFn(MFn::kDoubleIndexedComponent)) + { + MFnDoubleIndexedComponent compFn(mComponents[mObjIndex]); + + if (compFn.elementCount() > 0) + { + compFn.getElement(0, mCurGuide, mCurVert); + break; + } + } + } + + mIsDone = (mObjIndex >= mComponents.length()); + mElementIndex = 0; + } +} + + +void shaveHairGeomIt::setPoint(const MPoint& newPoint) const +{ +cout << "shaveHairGeomIt::setPoint" << endl; + // %%% not yet implemented +} + + +int shaveHairGeomIt::setPointGetNext(MPoint& pointInOut) +{ + // %%% 'set' portion not yet implemented + +cout << "shaveHairGeomIt::setPointGetNext" << endl; + next(); + pointInOut = point(); + + return index(); +} + |