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

//
// apiMeshShapeUI.cpp
//

#include <maya/MIOStream.h>

#include <apiMeshShapeUI.h>

#include <maya/MMaterial.h>
#include <maya/MColor.h>
#include <maya/MDrawData.h>
#include <maya/MMatrix.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MObjectArray.h>
#include <maya/MDagPath.h>
// for user interaction performance example code. (search on 
// "userChangingViewContext")
#include <maya/MGlobal.h>

#include <maya/MTextureEditorDrawInfo.h> 

// Object and component color defines
//
#define LEAD_COLOR                              18      // green
#define ACTIVE_COLOR                    15      // white
#define ACTIVE_AFFECTED_COLOR   8       // purple
#define DORMANT_COLOR                   4       // blue
#define HILITE_COLOR                    17      // pale blue
#define DORMANT_VERTEX_COLOR    8       // purple
#define ACTIVE_VERTEX_COLOR             16      // yellow

// Vertex point size
//
#define POINT_SIZE                              2.0     
#define UV_POINT_SIZE                   4.0

//
// UI implementation
//

apiMeshUI::apiMeshUI() {}
apiMeshUI::~apiMeshUI() {}

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

//
// Overrides
//

/* override */
void apiMeshUI::getDrawRequests( const MDrawInfo & info,
                                                         bool objectAndActiveOnly,
                                                         MDrawRequestQueue & queue )
//
// Description:
//
//     Add draw requests to the draw queue
//
// Arguments:
//
//     info                 - current drawing state
//     objectsAndActiveOnly - no components if true
//     queue                - queue of draw requests to add to
//
{
        // Get the data necessary to draw the shape
        //
        MDrawData data;
        apiMesh* meshNode = (apiMesh*)surfaceShape();
        apiMeshGeom * geom = meshNode->meshGeom();
        if ( (NULL == geom) || (0 == geom->faceCount) ) {
                cerr << "NO DrawRequest for apiMesh\n";
                return;
        }

        // This call creates a prototype draw request that we can fill
        // in and then add to the draw queue.
        //
        MDrawRequest request = info.getPrototype( *this );
        getDrawData( geom, data );
        request.setDrawData( data );

        // Decode the draw info and determine what needs to be drawn
        //

        M3dView::DisplayStyle  appearance    = info.displayStyle();
        M3dView::DisplayStatus displayStatus = info.displayStatus();
        
        // Are we displaying meshes?
        if ( ! info.objectDisplayStatus( M3dView::kDisplayMeshes ) )
                return;
        
        // Use this code to help speed up drawing. 
        // inUserInteraction() is true for any interaction with 
        // the viewport, including object or component TRS and camera changes. 
        // userChangingViewContext() is true only when the user is using view 
        // context tools (tumble, dolly, track, etc.)
        //
        if ( info.inUserInteraction() || info.userChangingViewContext() ) {
                // User is using view context tools so
                // request fast draw and get out
                //
                request.setToken( kDrawRedPointAtCenter );
                queue.add( request );
                return;
        }

        switch ( appearance )
        {
                case M3dView::kWireFrame :
                {
                        request.setToken( kDrawWireframe );

                        M3dView::ColorTable activeColorTable = M3dView::kActiveColors;
                        M3dView::ColorTable dormantColorTable = M3dView::kDormantColors;

                        switch ( displayStatus )
                        {
                                case M3dView::kLead :
                                        request.setColor( LEAD_COLOR, activeColorTable );
                                        break;
                                case M3dView::kActive :
                                        request.setColor( ACTIVE_COLOR, activeColorTable );
                                        break;
                                case M3dView::kActiveAffected :
                                        request.setColor( ACTIVE_AFFECTED_COLOR, activeColorTable );
                                        break;
                                case M3dView::kDormant :
                                        request.setColor( DORMANT_COLOR, dormantColorTable );
                                        break;
                                case M3dView::kHilite :
                                        request.setColor( HILITE_COLOR, activeColorTable );
                                        break;
                                default:        
                                        break;
                        }

                        queue.add( request );

                        break;
                }

                case M3dView::kGouraudShaded :
                {
                        // Create the smooth shaded draw request
                        //
                        request.setToken( kDrawSmoothShaded );

                        // Need to get the material info
                        //
                        MDagPath path = info.multiPath();       // path to your dag object 
                        M3dView view = info.view();;            // view to draw to
                        MMaterial material = MPxSurfaceShapeUI::material( path );

                        // If the user currently has the default material enabled on the 
                        // view then use the default material for shading. 
                        // 
                        if ( view.usingDefaultMaterial() ) { 
                                material = MMaterial::defaultMaterial(); 
                        }
                        
                        // Evaluate the material and if necessary, the texture.
                        //
                        if ( ! material.evaluateMaterial( view, path ) ) {
                                cerr << "Couldnt evaluate\n";
                        }
                        
                        bool drawTexture = true;
                        if ( drawTexture && material.materialIsTextured() ) {
                                material.evaluateTexture( data );
                        }
                        
                        request.setMaterial( material );
                        
                        // request.setDisplayStyle( appearance );
                        
                        bool materialTransparent = false;
                        material.getHasTransparency( materialTransparent );
                        if ( materialTransparent ) {
                                request.setIsTransparent( true );
                        }

                        queue.add( request );

                        // create a draw request for wireframe on shaded if
                        // necessary.
                        //
                        if ( (displayStatus == M3dView::kActive) ||
                                 (displayStatus == M3dView::kLead) ||
                                 (displayStatus == M3dView::kHilite) )
                        {
                                MDrawRequest wireRequest = info.getPrototype( *this );
                                wireRequest.setDrawData( data );
                                wireRequest.setToken( kDrawWireframeOnShaded );
                                wireRequest.setDisplayStyle( M3dView::kWireFrame );

                                M3dView::ColorTable activeColorTable = M3dView::kActiveColors;

                                switch ( displayStatus )
                                {
                                        case M3dView::kLead :
                                                wireRequest.setColor( LEAD_COLOR, activeColorTable );
                                                break;
                                        case M3dView::kActive :
                                                wireRequest.setColor( ACTIVE_COLOR, activeColorTable );
                                                break;
                                        case M3dView::kHilite :
                                                wireRequest.setColor( HILITE_COLOR, activeColorTable );
                                                break;
                                        default:        
                                                break;

                                }

                                queue.add( wireRequest );
                        }

                        break;
                }

                case M3dView::kFlatShaded :
                        request.setToken( kDrawFlatShaded );
                        queue.add( request );
                        break;
                case M3dView::kBoundingBox :
                        request.setToken( kDrawBoundingBox );
                        queue.add( request );
                        break;
                default:        
                        break;
        }

        // Add draw requests for components
        //
        if ( !objectAndActiveOnly ) {

                // Inactive components
                //
                if ( (appearance == M3dView::kPoints) ||
                         (displayStatus == M3dView::kHilite) )
                {
                        MDrawRequest vertexRequest = info.getPrototype( *this ); 
                        vertexRequest.setDrawData( data );
                        vertexRequest.setToken( kDrawVertices );
                        vertexRequest.setColor( DORMANT_VERTEX_COLOR,
                                                                        M3dView::kActiveColors );

                        queue.add( vertexRequest );
                }

                // Active components
                //
                if ( surfaceShape()->hasActiveComponents() ) {

                        MDrawRequest activeVertexRequest = info.getPrototype( *this ); 
                        activeVertexRequest.setDrawData( data );
                    activeVertexRequest.setToken( kDrawVertices );
                    activeVertexRequest.setColor( ACTIVE_VERTEX_COLOR,
                                                                                  M3dView::kActiveColors );

                    MObjectArray clist = surfaceShape()->activeComponents();
                    MObject vertexComponent = clist[0]; // Should filter list
                    activeVertexRequest.setComponent( vertexComponent );

                        queue.add( activeVertexRequest );
                }
        }
}

/* override */
void apiMeshUI::draw( const MDrawRequest & request, M3dView & view ) const
//
// Description:
//
//     Main (OpenGL) draw routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{ 
        // Get the token from the draw request.
        // The token specifies what needs to be drawn.
        //
        int token = request.token();

        switch( token )
        {
                case kDrawWireframe :
                case kDrawWireframeOnShaded :
                        drawWireframe( request, view );
                        break;

                case kDrawSmoothShaded :
                        drawShaded( request, view );
                        break;

                case kDrawFlatShaded : // Not implemented
                        break;

                case kDrawVertices :
                        drawVertices( request, view );
                        break;
                        
                case kDrawBoundingBox:
                        drawBoundingBox( request, view );
                        break;
                // for userChangingViewContext example code 
                //
                case kDrawRedPointAtCenter:
                        drawRedPointAtCenter( request, view );
                        break;
        }
}

/* override */
bool apiMeshUI::select( MSelectInfo &selectInfo, MSelectionList &selectionList,
                                        MPointArray &worldSpaceSelectPts ) const
//
// Description:
//
//     Main selection routine
//
// Arguments:
//
//     selectInfo           - the selection state information
//     selectionList        - the list of selected items to add to
//     worldSpaceSelectPts  -
//
{
        bool selected = false;
        bool componentSelected = false;
        bool hilited = false;

        hilited = (selectInfo.displayStatus() == M3dView::kHilite);
        if ( hilited ) {
                componentSelected = selectVertices( selectInfo, selectionList,
                                                                                        worldSpaceSelectPts );
                selected = selected || componentSelected;
        }

        if ( !selected ) {

                apiMesh* meshNode = (apiMesh*)surfaceShape();

                // NOTE: If the geometry has an intersect routine it should
                // be called here with the selection ray to determine if the
                // the object was selected.

                selected = true;
                MSelectionMask priorityMask( MSelectionMask::kSelectNurbsSurfaces );
                MSelectionList item;
                item.add( selectInfo.selectPath() );
                MPoint xformedPt;
                if ( selectInfo.singleSelection() ) {
                        MPoint center = meshNode->boundingBox().center();
                        xformedPt = center;
                        xformedPt *= selectInfo.selectPath().inclusiveMatrix();
                }

                selectInfo.addSelection( item, xformedPt, selectionList,
                                                                 worldSpaceSelectPts, priorityMask, false );
        }

        return selected;
}

//
// Helper routines
//

void apiMeshUI::drawWireframe( const MDrawRequest & request,
                                                           M3dView & view ) const
//
// Description:
//
//     Wireframe drawing routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
        MDrawData data = request.drawData();
        apiMeshGeom * geom = (apiMeshGeom*)data.geometry();

        int token = request.token();

        bool wireFrameOnShaded = false;
        if ( kDrawWireframeOnShaded == token ) {
                wireFrameOnShaded = true;
        }

        view.beginGL(); 

        // Query current state so it can be restored
        //
        bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
        if ( lightingWasOn ) {
                glDisable( GL_LIGHTING );
        }

        if ( wireFrameOnShaded ) {
                glDepthMask( false );
        }

        // Draw the wireframe mesh
        //
        int vid = 0;                    
        for ( int i=0; i<geom->faceCount; i++ )
        {
                glBegin( GL_LINE_LOOP );
                for ( int v=0; v<geom->face_counts[i]; v++ )
                {
                        MPoint vertex = geom->vertices[ geom->face_connects[vid++] ];
                        glVertex3f( (float)vertex[0], (float)vertex[1], (float)vertex[2] );
                }
                glEnd();
        }

        // Restore the state
        //
        if ( lightingWasOn ) {
                glEnable( GL_LIGHTING );
        }
        if ( wireFrameOnShaded ) {
                glDepthMask( true );
        }

        view.endGL(); 
}

void apiMeshUI::drawShaded( const MDrawRequest & request,
                                                        M3dView & view ) const
//
// Description:
//
//     Shaded drawing routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
        MDrawData data = request.drawData();
        apiMeshGeom * geom = (apiMeshGeom*)data.geometry();

        view.beginGL(); 

#if             defined(SGI) || defined(MESA)
        glEnable( GL_POLYGON_OFFSET_EXT );
#else
        glEnable( GL_POLYGON_OFFSET_FILL );
#endif

        // Set up the material
        //
        MMaterial material = request.material();
        material.setMaterial( request.multiPath(), request.isTransparent() );

        // Enable texturing ... 
        // 
        // Note, Maya does not enable texturing if useDefaultMaterial is enabled. 
        // However, you can choose to ignore this in your draw routine.  
        //
        bool drawTexture = 
                material.materialIsTextured() && 
                !view.usingDefaultMaterial(); 

        if ( drawTexture ) glEnable(GL_TEXTURE_2D);

        // Apply the texture to the current view
        //
        if ( drawTexture ) {
                material.applyTexture( view, data );
        }

        // Draw the polygons
        //
        int vid = 0;
        int uv_len = geom->uvcoords.uvcount();
        for ( int i=0; i<geom->faceCount; i++ )
        {
                glBegin( GL_POLYGON );
                for ( int v=0; v<geom->face_counts[i]; v++ )
                {
                        MPoint vertex = geom->vertices[ geom->face_connects[vid] ];
                        MVector normal = geom->normals[ geom->face_connects[vid] ];

                        // If we are drawing the texture, make sure the  coord 
                        // arrays are in bounds.
                        if ( drawTexture ) {
                                float u, v; 
                                int uvId1 = geom->uvcoords.uvId(vid); 
                                if ( uvId1 < uv_len ) { 
                                        geom->uvcoords.getUV( uvId1, u, v ); 
                                        glTexCoord2f( (GLfloat)u, (GLfloat)v ); 
                                }
                        }

                        glNormal3f( (float)normal[0], (float)normal[1], (float)normal[2] );
                        glVertex3f( (float)vertex[0], (float)vertex[1], (float)vertex[2] );
                        vid++;
                }
                glEnd();
        } 

        // Turn off texture mode
        //
        if ( drawTexture ) glDisable(GL_TEXTURE_2D);

        view.endGL(); 
}

void apiMeshUI::drawVertices( const MDrawRequest & request,
                                                          M3dView & view ) const
//
// Description:
//
//     Component (vertex) drawing routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
        MDrawData data = request.drawData();
        apiMeshGeom * geom = (apiMeshGeom*)data.geometry();

        view.beginGL(); 

        // Query current state so it can be restored
        //
        bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
        if ( lightingWasOn ) {
                glDisable( GL_LIGHTING );
        }
        float lastPointSize;
        glGetFloatv( GL_POINT_SIZE, &lastPointSize );

        // Set the point size of the vertices
        //
        glPointSize( POINT_SIZE );

        // If there is a component specified by the draw request
        // then loop over comp (using an MFnComponent class) and draw the
        // active vertices, otherwise draw all vertices.
        //
        MObject comp = request.component();
        if ( ! comp.isNull() ) {
                MFnSingleIndexedComponent fnComponent( comp );
                for ( int i=0; i<fnComponent.elementCount(); i++ )
                {
                        int index = fnComponent.element( i );
                        glBegin( GL_POINTS );
                        MPoint vertex = geom->vertices[ index  ];
                        glVertex3f( (float)vertex[0], 
                                                (float)vertex[1], 
                                                (float)vertex[2] );
                        glEnd();

                        char annotation[32];
                        sprintf( annotation, "%d", index );
                        view.drawText( annotation, vertex );
                }
        }
        else {
                int vid = 0;
                for ( int i=0; i<geom->faceCount; i++ )
                {
                        glBegin( GL_POINTS );
                        for ( int v=0; v<geom->face_counts[i]; v++ )
                        {
                                MPoint vertex =
                                        geom->vertices[ geom->face_connects[vid++] ];
                                glVertex3f( (float)vertex[0], 
                                                        (float)vertex[1], 
                                                        (float)vertex[2] );
                        }
                        glEnd();
                }
        }

        // Restore the state
        //
        if ( lightingWasOn ) {
                glEnable( GL_LIGHTING );
        }
        glPointSize( lastPointSize );

        view.endGL(); 
}

void apiMeshUI::drawBoundingBox( const MDrawRequest & request,
                                                          M3dView & view ) const
//
// Description:
//
//     Bounding box drawing routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
        // Get the surface shape
        MPxSurfaceShape *shape = surfaceShape();
        if ( !shape )
                return;
                
        // Get the bounding box 
        MBoundingBox box = shape->boundingBox();
        float w = (float) box.width();
        float h = (float) box.height();
        float d = (float) box.depth();
        view.beginGL(); 
        
        // Below we just two sides and then connect
        // the edges together

        MPoint minVertex = box.min();
        
        // Draw first side
        glBegin( GL_LINE_LOOP );
        MPoint vertex = minVertex;
        glVertex3f( (float)vertex[0],   (float)vertex[1],   (float)vertex[2] );
        glVertex3f( (float)vertex[0]+w, (float)vertex[1],   (float)vertex[2] );
        glVertex3f( (float)vertex[0]+w, (float)vertex[1]+h, (float)vertex[2] );
        glVertex3f( (float)vertex[0],   (float)vertex[1]+h, (float)vertex[2] ); 
        glVertex3f( (float)vertex[0],   (float)vertex[1],   (float)vertex[2] );
        glEnd();

        // Draw second side
        MPoint sideFactor(0,0,d);
        MPoint vertex2 = minVertex + sideFactor;
        glBegin( GL_LINE_LOOP );
        glVertex3f( (float)vertex2[0],   (float)vertex2[1],   (float)vertex2[2] );      
        glVertex3f( (float)vertex2[0]+w, (float)vertex2[1],   (float)vertex2[2] );
        glVertex3f( (float)vertex2[0]+w, (float)vertex2[1]+h, (float)vertex2[2] );
        glVertex3f( (float)vertex2[0],   (float)vertex2[1]+h, (float)vertex2[2] );      
        glVertex3f( (float)vertex2[0],   (float)vertex2[1],   (float)vertex2[2] );      
        glEnd();

        // Connect the edges together
        glBegin( GL_LINES );
        glVertex3f( (float)vertex2[0],   (float)vertex2[1],   (float)vertex2[2] );      
        glVertex3f( (float)vertex[0],   (float)vertex[1],   (float)vertex[2] );

        glVertex3f( (float)vertex2[0]+w,   (float)vertex2[1],   (float)vertex2[2] );    
        glVertex3f( (float)vertex[0]+w,   (float)vertex[1],   (float)vertex[2] );

        glVertex3f( (float)vertex2[0]+w,   (float)vertex2[1]+h,   (float)vertex2[2] );  
        glVertex3f( (float)vertex[0]+w,   (float)vertex[1]+h,   (float)vertex[2] );

        glVertex3f( (float)vertex2[0],   (float)vertex2[1]+h,   (float)vertex2[2] );    
        glVertex3f( (float)vertex[0],   (float)vertex[1]+h,   (float)vertex[2] );
        glEnd();
        
        view.endGL(); 
}

// for userChangingViewContext example code 
//
void apiMeshUI::drawRedPointAtCenter( const MDrawRequest & request,
                                                                                M3dView & view ) const
//
// Description:
//
//     Simple very fast draw routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
        // Draw point
        // 
        view.beginGL();
                
        // save state
        //
        glPushAttrib( GL_CURRENT_BIT | GL_POINT_BIT );
        glPointSize( 20.0f );
        glBegin( GL_POINTS );
        glColor3f( 1.0f, 0.0f, 0.0f );
        glVertex3f(0.0f, 0.0f, 0.0f );
        glEnd();
                                                        
        // restore state
        //
        glPopAttrib();
        view.endGL();

}


bool apiMeshUI::selectVertices( MSelectInfo &selectInfo,
                                                         MSelectionList &selectionList,
                                                         MPointArray &worldSpaceSelectPts ) const
//
// Description:
//
//     Vertex selection.
//
// Arguments:
//
//     selectInfo           - the selection state information
//     selectionList        - the list of selected items to add to
//     worldSpaceSelectPts  -
//
{
        bool selected = false;
        M3dView view = selectInfo.view();

        MPoint          xformedPoint;
        MPoint          selectionPoint;
        double          z,previousZ = 0.0;
        int                     closestPointVertexIndex = -1;

        const MDagPath & path = selectInfo.multiPath();

        // Create a component that will store the selected vertices
        //
        MFnSingleIndexedComponent fnComponent;
        MObject surfaceComponent = fnComponent.create( MFn::kMeshVertComponent );
        int vertexIndex;

        // if the user did a single mouse click and we find > 1 selection
        // we will use the alignmentMatrix to find out which is the closest
        //
        MMatrix alignmentMatrix;
        MPoint singlePoint; 
        bool singleSelection = selectInfo.singleSelection();
        if( singleSelection ) {
                alignmentMatrix = selectInfo.getAlignmentMatrix();
        }

        // Get the geometry information
        //
        apiMesh* meshNode = (apiMesh*)surfaceShape();
        apiMeshGeom * geom = meshNode->meshGeom();

        // Loop through all vertices of the mesh and
        // see if they lie withing the selection area
        //
        int numVertices = geom->vertices.length();
        for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ )
        {
                MPoint currentPoint = geom->vertices[ vertexIndex ];

                // Sets OpenGL's render mode to select and stores
                // selected items in a pick buffer
                //
                view.beginSelect();

                glBegin( GL_POINTS );
                glVertex3f( (float)currentPoint[0], 
                                        (float)currentPoint[1], 
                                        (float)currentPoint[2] );
                glEnd();

                if ( view.endSelect() > 0 )     // Hit count > 0
                {
                        selected = true;

                        if ( singleSelection ) {
                                xformedPoint = currentPoint;
                                xformedPoint.homogenize();
                                xformedPoint*= alignmentMatrix;
                                z = xformedPoint.z;
                                if ( closestPointVertexIndex < 0 || z > previousZ ) {
                                        closestPointVertexIndex = vertexIndex;
                                        singlePoint = currentPoint;
                                        previousZ = z;
                                }
                        } else {
                                // multiple selection, store all elements
                                //
                                fnComponent.addElement( vertexIndex );
                        }
                }
        }

        // If single selection, insert the closest point into the array
        //
        if ( selected && selectInfo.singleSelection() ) {
                fnComponent.addElement(closestPointVertexIndex);

                // need to get world space position for this vertex
                //
                selectionPoint = singlePoint;
                selectionPoint *= path.inclusiveMatrix();
        }

        // Add the selected component to the selection list
        //
        if ( selected ) {
                MSelectionList selectionItem;
                selectionItem.add( path, surfaceComponent );

                MSelectionMask mask( MSelectionMask::kSelectComponentsMask );
                selectInfo.addSelection(
                        selectionItem, selectionPoint,
                        selectionList, worldSpaceSelectPts,
                        mask, true );
        }

        return selected;
}

bool apiMeshUI::canDrawUV() const
//
// Description: 
//  Tells Maya that this surface shape supports uv drawing. 
//
{
        apiMesh* meshNode = (apiMesh*)surfaceShape();
        apiMeshGeom * geom = meshNode->meshGeom();
        return geom->uvcoords.uvcount() > 0; 
}

void apiMeshUI::drawUVWireframe( 
        apiMeshGeom *geom, 
        M3dView &view, 
        const MTextureEditorDrawInfo &info 
) const 
//
// Description: 
//  Draws the UV layout in wireframe mode. 
// 
{
        view.beginGL(); 
        
        // Draw the polygons
        //
        int vid = 0;
        int vid_start = vid; 
        for ( int i=0; i<geom->faceCount; i++ )
        {
                glBegin( GL_LINES );
                int v;

                vid_start = vid; 
                for ( v=0; v<geom->face_counts[i]-1; v++ )
                {
                        float du1, dv1, du2, dv2; 
                        int uvId1 = geom->uvcoords.uvId(vid); 
                        int uvId2 = geom->uvcoords.uvId(vid+1); 
                        geom->uvcoords.getUV( uvId1, du1, dv1 ); 
                        geom->uvcoords.getUV( uvId2, du2, dv2 );
                        glVertex3f( (GLfloat)du1, (GLfloat)dv1, 0.0f ); 
                        glVertex3f( (GLfloat)du2, (GLfloat)dv2, 0.0f ); 
                        vid++;
                }
                
                float du1, dv1, du2, dv2; 
                int uvId1 = geom->uvcoords.uvId(vid); 
                int uvId2 = geom->uvcoords.uvId(vid_start); 
                geom->uvcoords.getUV( uvId1, du1, dv1 ); 
                geom->uvcoords.getUV( uvId2, du2, dv2 );
                glVertex3f( (GLfloat)du1, (GLfloat)dv1, 0.0f );
                glVertex3f( (GLfloat)du2, (GLfloat)dv2, 0.0f ); 
                vid ++ ; 
                glEnd();
        } 
        
}

void apiMeshUI::drawUVMapCoord( 
        M3dView &view, 
        int uv, 
        float u, float v, 
        bool drawNum
) const 
//
// Description: 
//  Draw the specified uv value into the port view. If drawNum is true 
//  It will also draw the UV id for the the UV.  
//
{
        if ( drawNum ) { 
                char s[32];
                sprintf( s, "%d", uv );
                view.drawText( s, MPoint( u, v, 0 ), M3dView::kCenter );
        }  
        glVertex3f( (GLfloat)u, (GLfloat)v, 0.0f ); 
}

void apiMeshUI::drawUVMapCoordNum( 
        apiMeshGeom *geom, 
        M3dView &view, 
        const MTextureEditorDrawInfo &info, 
        bool drawNumbers 
) const 
//
// Description: 
//  Draw the UV points for all uvs on this surface shape. 
//
{
        view.beginGL(); 

        GLfloat ptSize; 
        glGetFloatv( GL_POINT_SIZE, &ptSize ); 
        glPointSize( UV_POINT_SIZE );

        int uv; 
        int uv_len = geom->uvcoords.uvcount(); 
        for ( uv = 0; uv < uv_len; uv ++ ) { 
                float du, dv; 
                geom->uvcoords.getUV( uv, du, dv ); 
                drawUVMapCoord( view, uv, du, dv, drawNumbers );
        }       

        glPointSize( ptSize ); 
        view.endGL(); 
}

void apiMeshUI::drawUV( M3dView &view, const MTextureEditorDrawInfo &info ) const
// 
// Description: 
//   Main entry point for UV drawing. This method is called by the UV 
//   texture editor when the shape is 'active'. 
// 
// Input: 
//   A 3dView. 
//
{
        apiMesh* meshNode = (apiMesh*)surfaceShape();
        apiMeshGeom * geom = meshNode->meshGeom();
        
        view.setDrawColor( MColor( 1.0f, 0.0f, 0.0f ) ); 
        
        switch( info.drawingFunction() ) { 
        case MTextureEditorDrawInfo::kDrawWireframe: 
                drawUVWireframe( geom, view, info ); 
                break; 
        case MTextureEditorDrawInfo::kDrawEverything: 
        case MTextureEditorDrawInfo::kDrawUVForSelect: 
                drawUVWireframe( geom, view, info ); 
                drawUVMapCoordNum( geom, view, info, false ); 
                break; 
        case MTextureEditorDrawInfo::kDrawVertexForSelect: 
        case MTextureEditorDrawInfo::kDrawEdgeForSelect: 
        case MTextureEditorDrawInfo::kDrawFacetForSelect: 
        default: 
                drawUVWireframe( geom, view, info ); 
        };
}

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