clusterWeightFunction.cpp

//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+


#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MSimple.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MSelectionList.h>
#include <maya/MObjectArray.h>
#include <maya/MFnWeightGeometryFilter.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MItGeometry.h>
#include <maya/MPoint.h>


#define kSineFlag                                                               "-s"
#define kSineFlagLong                                                   "-sine"
#define kSineDistanceFlag                                               "-sd"
#define kSineDistanceFlagLong                                   "-sineDistance"
#define kSineDistance2Flag                                              "-sd2"
#define kSineDistance2FlagLong                                  "-sineDistance2"
#define kDistanceSineDistanceFlag                               "-dsd"
#define kDistanceSineDistanceFlagLong                   "-distanceSineDistance"
#define kInverseDistanceSineDistanceFlag                "-ids"
#define kInverseDistanceSineDistanceFlagLong    "-inverseDistanceSineDistance"
#define kDistanceFlag                                                   "-d"
#define kDistanceFlagLong                                               "-distance"
#define kDistance2Flag                                                  "-d2"
#define kDistance2FlagLong                                              "-distance2"
#define kDistance3Flag                                                  "-d3"
#define kDistance3FlagLong                                              "-distance3"
#define kDistance4Flag                                                  "-d4"
#define kDistance4FlagLong                                              "-distance4"
#define kInverseDistanceFlag                                    "-id"
#define kInverseDistanceFlagLong                                "-inverseDistance"
#define kInverseDistance2Flag                                   "-id2"
#define kInverseDistance2FlagLong                               "-inverseDistance2"
#define kInverseDistance3Flag                                   "-id3"
#define kInverseDistance3FlagLong                               "-inverseDistance3"
#define kInverseDistance4Flag                                   "-id4"
#define kInverseDistance4FlagLong                               "-inverseDistance4"


class clusterWeightFunctionCmd : public MPxCommand
{
public:
        clusterWeightFunctionCmd();
        virtual ~clusterWeightFunctionCmd();
        virtual MStatus doIt(const MArgList &args);
        static void *creator();
        static MSyntax newSyntax();
        
        enum effectType {
                kSine,
                kSineDistance,
                kSineDistance2,
                kDistanceSineDistance,
                kInverseDistanceSineDistance,
                kDistance,
                kDistance2,
                kDistance3,
                kDistance4,
                kInverseDistance,
                kInverseDistance2,
                kInverseDistance3,
                kInverseDistance4
        };

private:
        MStatus parseArgs(const MArgList &);
        MStatus performWeighting(MFnWeightGeometryFilter &,
                                                         MDagPath &,
                                                         MObject &);

        effectType fEffectType;
};


clusterWeightFunctionCmd::clusterWeightFunctionCmd()
{
}


clusterWeightFunctionCmd::~clusterWeightFunctionCmd()
{
}


MStatus clusterWeightFunctionCmd::doIt(const MArgList &argList)
{
        MStatus status;

        MSelectionList list;
        MGlobal::getActiveSelectionList(list);
        
        // Get the cluster
        MFnWeightGeometryFilter cluster;
        MObject dgNode;
        list.getDependNode(0, dgNode);
        if (!cluster.setObject(dgNode))
                return MS::kFailure;

        // Get the object
        MDagPath dagPath;
        MObject component;
        list.getDagPath(1, dagPath, component);

        status = parseArgs(argList);
        if (MS::kSuccess == status)
                status = performWeighting(cluster, dagPath, component);
        return status;
}


void *clusterWeightFunctionCmd::creator()
{
        return new clusterWeightFunctionCmd;
}


MSyntax clusterWeightFunctionCmd::newSyntax()
{
        MSyntax syntax;

        syntax.addFlag(kSineFlag, kSineFlagLong);
        syntax.addFlag(kSineDistanceFlag, kSineDistanceFlagLong);
        syntax.addFlag(kSineDistance2Flag, kSineDistance2FlagLong);
        syntax.addFlag(kDistanceSineDistanceFlag, kDistanceSineDistanceFlagLong);
        syntax.addFlag(kInverseDistanceSineDistanceFlag, 
                                   kInverseDistanceSineDistanceFlagLong);
        syntax.addFlag(kDistanceFlag, kDistanceFlagLong);
        syntax.addFlag(kDistance2Flag, kDistance2FlagLong);
        syntax.addFlag(kDistance3Flag, kDistance3FlagLong);
        syntax.addFlag(kDistance4Flag, kDistance4FlagLong);
        syntax.addFlag(kInverseDistanceFlag, kInverseDistanceFlagLong);
        syntax.addFlag(kInverseDistance2Flag, kInverseDistance2FlagLong);
        syntax.addFlag(kInverseDistance3Flag, kInverseDistance3FlagLong);
        syntax.addFlag(kInverseDistance4Flag, kInverseDistance4FlagLong);

        return syntax;
}


MStatus clusterWeightFunctionCmd::parseArgs(const MArgList &argList)
{
        MArgDatabase argData(syntax(), argList);

        if (argData.isFlagSet(kSineFlag)) {
                fEffectType = kSine;
        }
        else if (argData.isFlagSet(kSineDistanceFlag)) {
                fEffectType = kSineDistance;
        }
        else if (argData.isFlagSet(kSineDistance2Flag)) {
                fEffectType = kSineDistance2;
        }
        else if (argData.isFlagSet(kDistanceSineDistanceFlag)) {
                fEffectType = kDistanceSineDistance;
        }
        else if (argData.isFlagSet(kInverseDistanceSineDistanceFlag)) {
                fEffectType = kInverseDistanceSineDistance;
        }
        else if (argData.isFlagSet(kDistanceFlag)) {
                fEffectType = kDistance;
        }
        else if (argData.isFlagSet(kDistance2Flag)) {
                fEffectType = kDistance2;
        }
        else if (argData.isFlagSet(kDistance3Flag)) {
                fEffectType = kDistance3;
        }
        else if (argData.isFlagSet(kDistance4Flag)) {
                fEffectType = kDistance4;
        }
        else if (argData.isFlagSet(kInverseDistanceFlag)) {
                fEffectType = kInverseDistance;
        }
        else if (argData.isFlagSet(kInverseDistance2Flag)) {
                fEffectType = kInverseDistance2;
        }
        else if (argData.isFlagSet(kInverseDistance3Flag)) {
                fEffectType = kInverseDistance3;
        }
        else if (argData.isFlagSet(kInverseDistance4Flag)) {
                fEffectType = kInverseDistance4;
        }

        return MS::kSuccess;
}


MStatus clusterWeightFunctionCmd::performWeighting(MFnWeightGeometryFilter &cluster,
                                                                                   MDagPath &dagPath,
                                                                                   MObject &component)
{
        MStatus status;
        MItGeometry geomIter(dagPath, component, &status);
        MObject comp;
        MObjectArray compArray;
        MDoubleArray weightArray;
        double weight = 0.0;

        if (MS::kSuccess == status) {
                for (; !geomIter.isDone(); geomIter.next()) {
                        comp = geomIter.component();

                        MPoint pnt = geomIter.position(MSpace::kWorld, &status);

                        if (MS::kSuccess != status) {
                                return MS::kFailure;
                        }

                        if (kSine == fEffectType) {
                                weight = sin(pnt.x)*sin(pnt.z);
                        }
                        else if (kSineDistance == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = sin(distance);
                        }
                        else if (kSineDistance2 == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = sin(distance*distance);
                        }
                        else if (kDistanceSineDistance == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = distance*sin(distance);
                        }
                        else if (kInverseDistanceSineDistance == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = sin(distance)/(distance+1);
                        }
                        else if (kDistance == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = distance;
                        }
                        else if (kDistance2 == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = distance*distance;
                        }
                        else if (kDistance3 == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = distance*distance*distance;
                        }
                        else if (kDistance4 == fEffectType) {
                                double distance = pnt.distanceTo(MPoint::origin);
                                weight = distance*distance*distance*distance;
                        }
                        else if (kInverseDistance == fEffectType) {
                                double dist = pnt.distanceTo(MPoint::origin) + 1;
                                weight = 1/(dist);
                        }
                        else if (kInverseDistance2 == fEffectType) {
                                double dist = pnt.distanceTo(MPoint::origin) + 1;
                                weight = 1/(dist*dist);
                        }
                        else if (kInverseDistance3 == fEffectType) {
                                double dist = pnt.distanceTo(MPoint::origin) + 1;
                                weight = 1/(dist*dist*dist);
                        }
                        else if (kInverseDistance4 == fEffectType) {
                                double dist = pnt.distanceTo(MPoint::origin) + 1;
                                weight = 1/(dist*dist*dist*dist);
                        }

                        compArray.append(comp);
                        weightArray.append(weight);
                }

                unsigned length = compArray.length();
                for (unsigned i = 0; i < length; i++) {
                        cluster.setWeight(dagPath, compArray[i], (float) weightArray[i]);
                }

                return MS::kSuccess;
        } else
                return MS::kFailure;
}


extern MStatus initializePlugin(MObject obj)
{
        MStatus status;
        MFnPlugin plugin(obj, PLUGIN_COMPANY, "3.0", "Any");
        
        status = plugin.registerCommand("clusterWeightFunction",
                                                                        clusterWeightFunctionCmd::creator,
                                                                        clusterWeightFunctionCmd::newSyntax);
        
        if (!status) {
                status.perror("registerCommand");
        }

        return status;
}


extern MStatus uninitializePlugin(MObject obj)
{
        MStatus status;
        MFnPlugin plugin(obj);
        
        status = plugin.deregisterCommand("clusterWeightFunction");

        if (!status) {
                status.perror("deregisterCommand");
        }       

        return status;
}


Autodesk® Maya® 2009 © 1997-2008 Autodesk, Inc. All rights reserved. Generated with doxygen 1.5.6