splitUVFtyAction.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.
// ==========================================================================
//+

// 
// File: splitUVFtyAction.cpp
//
// Node Factory: splitUVFty
//
// Author: Lonnie Li
//
#include "splitUVFty.h"

// General Includes
//
#include <maya/MGlobal.h>
#include <maya/MIOStream.h>

// Function Sets
//
#include <maya/MFnMesh.h>
#include <maya/MFnSingleIndexedComponent.h>

// Iterators
//
#include <maya/MItMeshPolygon.h>

MStatus splitUVFty::doIt()
//
//  Description:
//      Performs the actual splitUV operation on the given object and UVs
//
{
    MStatus status = MS::kSuccess;

    // Declare our processing variables //

    MString     selUVSet;

    // Face Id and Face Offset map to the selected UVs
    //
    MIntArray   selUVFaceIdMap;
    MIntArray   selUVFaceOffsetMap;

    // Local Vertex Index map to the selected UVs
    //
    MIntArray   selUVLocalVertIdMap;


    // Collect necessary information for the splitUV //
    //                                               //
    // - uvSet                                       //
    // - faceIds / localVertIds per selected UV      //

    MFnMesh meshFn( fMesh );
    meshFn.getCurrentUVSetName( selUVSet );

    int i;
    int j;
    int offset = 0;
    int selUVsCount = fSelUVs.length();

    MItMeshPolygon polyIter( fMesh );

    for( i = 0; i < selUVsCount; i++ )
    {
        selUVFaceOffsetMap.append(offset);

        for( polyIter.reset(); !polyIter.isDone(); polyIter.next() )
        {
            if( polyIter.hasUVs() )
            {
                int polyVertCount = polyIter.polygonVertexCount();

                for( j = 0; j < polyVertCount; j++ )
                {
                    int UVIndex = 0;
                    polyIter.getUVIndex(j, UVIndex);

                    if( UVIndex == fSelUVs[i] )
                    {
                        selUVFaceIdMap.append( polyIter.index() );
                        selUVLocalVertIdMap.append(j);
                        offset++;
                        break;
                    }
                }
            }
        }
    }

    // Store total length of the faceId map in the last element of
    // the offset map so that there is a way to get the number of faces
    // sharing each of the selected UVs
    //
    selUVFaceOffsetMap.append(offset);


    // Begin the splitUV operation //

    int currentUVCount = meshFn.numUVs( selUVSet );

    for( i = 0; i < selUVsCount; i++ )
    {
        // Get the current FaceId map offset
        //
        offset = selUVFaceOffsetMap[i];

        // Get the U and V values of the current UV
        //
        float u;
        float v;
        int uvId = fSelUVs[i];

        meshFn.getUV( uvId, u, v, &selUVSet );

        // Get the number of faces sharing the current UV
        //
        int faceCount = selUVFaceOffsetMap[i + 1] - selUVFaceOffsetMap[i];

        // Arbitrarily choose that the last faceId in the list of faces
        // sharing this UV, will keep the original UV.
        //
        for( j = 0; j < faceCount - 1; j++ )
        {
            meshFn.setUV( currentUVCount, u, v, &selUVSet );

            int localVertId = selUVLocalVertIdMap[offset];
            int faceId = selUVFaceIdMap[offset];

            meshFn.assignUV( faceId, localVertId, currentUVCount, &selUVSet );

            currentUVCount++;
            offset++;
        }
    }

    return status;
}