PtexExtractor/PtexLayout.h

//**************************************************************************/
// Copyright (c) 2010 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.
//
//**************************************************************************/
// DESCRIPTION:
// CREATED: August 2010
//**************************************************************************/

#if defined(JAMBUILD)
#include <Mudbox/mudbox.h>
#include <MapExtractor/MapExtractorInterface.h>
#include <UVlessPainting/UVGeneratorInterface.h>
#else
#include "../../include/Mudbox/mudbox.h"
#include "../../include/MapExtractor/MapExtractorInterface.h"
#include "../../include/UVlessPainting/UVGeneratorInterface.h"
#endif

using namespace mudbox;
using namespace mapextractionmodules;

// This class is responsible to specify the location and order of the reference points on the target mesh which needs a value to be extracter. In case of a ptex extraction
// process this class will specify points on each base level face in a grid pattern.
class PtexLayout : public Layout
{
    DECLARE_CLASS;
    // These are the additional data which will be added to each reference point. Based on these data the PtexUtilizer class (which is responsible to process the result
    // of the extraction) will know where to put the data in the ptex file.
    enum
    {
        dataURes,   // coordinate of the reference point in the grid in horizontal direction
        dataVRes,   // coordinate of the reference point in the grid in horizontal direction
        dataFaceID  // ID of the ptex face
    };
    PtexLayout( void );
    // This function creates the user interface widgets which belong to this type of layout.
    virtual QWidget *UserInterface( void );
    // Main function of the class. This is only called once for a map extraction operation. This function collects the reference points on the target surface(s).
    virtual void ProcessSurface( SubdivisionLevel *pSurface );
    // Prepares the instance for the extraction, returns the expected number of reference points (for progress indicator)
    virtual unsigned int Prepare( void );
    // When the map extraction node is saved into a mud file, this function must serialize the data members of the object.
    virtual void Serialize( Stream &s );
    // This function initializes data structures which are used to calculate the resolution for ptex faces.
    void InitializeResolution( const Mesh *pMesh );
    // Calculate resolution for a quad face.
    void CalculateQuadResolution( unsigned int iQuadIndex, int &iHRes, int &iVRes );
    // Calculate resolution for any ptex face. The four corners should be the UV space position of the face corners if the 
    // current distribution mode is distUVArea, world space position otherwise.
    void CalculateFaceResolution( const Vector &v0, const Vector &v1, const Vector &v2, const Vector &v3, unsigned int iFaceIndex, int &iHRes, int &iVRes );
    // Caculate the ptex resolution for a given direction.
    int Calculate1DResolution( float fIdeal );
    // This virtual function is used to catch events related to attributes.
    void OnNodeEvent( const Attribute &, NodeEventType );
    
    // This is the only one parameter of the object, it controls the resolution of the grid for each base level face.
    aenum m_eDistribution;
    afloatr m_fDensity;
    astring m_sTexelCount;
    enum Distribution
    {
        distUniform,
        distWorldArea,
        distUVArea,
        distCustom
    };
    // This is the number of texels the user wants. The plugin will try to match this by changing face resolutions up or down depending on the needs.
    unsigned int m_iDesiredTexelCount;

    // The remaining functions and variables are needed to caculate the adjacency information for nsided meshes. For full quad meshes
    // there is a one-to-one relationship between mudbox quads and ptex faces, so in that case the adjacency calculation is easy.
    // For more information on how ptex expects the adjacency info, see http://http://ptex.us/adjdata.html

    // This function precalculates some adjacency related data for the mesh.
    void PrepareAdjacency( const Mesh *m_pMesh );
    // This function calculates the adjacency info for an edge of a triagle mudbox face.
    unsigned int AdjacentFaceForTriangle( unsigned int iFaceIndex, unsigned int iSide, unsigned int iSegment, unsigned int &iEdge ) const;
    // This function calculates the adjacency info for a ptex face edge.
    unsigned int AdjacentFace( unsigned int iFaceID, unsigned int iSide, unsigned int &iEdge ) const;

    // Pointer to the mesh which adjacency is currently being calculated.
    const Mesh *m_pMesh;
    // The following array tells the ptex face id for a given mudbox triangle. Contains valid values only for real triangles.
    QVector<unsigned int> m_aFaceID;
    // The following array tells the mudbox triangle index for a given ptex face ID. This array is the opposite of the m_aFaceID array.
    QVector<unsigned int> m_aTriangle;

    // This section is used for resolution calculation
    struct ResolutionCalc
    {
        // Address of the current mesh
        const Mesh *m_pMesh;
        // Total sum of the surface area for the current mesh
        float m_fTotalSurfaceArea;
        // Number of texels generated
        unsigned int m_iTexelCount;
        // Processed area
        float m_fProcessedArea;
        // This tolerance controls which faces resolution can be changed in order to match the desired texel count/
        float m_fTolerance;
        UVGeneratorNode *m_pUVGen;
    } m_sRes;
};