#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>
#include <maya/MGlobal.h>
#include <maya/MTextureEditorDrawInfo.h>
#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
#define POINT_SIZE 2.0
#define UV_POINT_SIZE 4.0
apiMeshUI::apiMeshUI() {}
apiMeshUI::~apiMeshUI() {}
void* apiMeshUI::creator()
{
return new apiMeshUI();
}
void apiMeshUI::getDrawRequests(
const MDrawInfo & info,
bool objectAndActiveOnly,
{
apiMesh* meshNode = (apiMesh*)surfaceShape();
apiMeshGeom * geom = meshNode->meshGeomToUse();
if ( (NULL == geom) || (0 == geom->faceCount) ) {
return;
}
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
getDrawData( geom, data );
_OPENMAYA_DEPRECATION_POP_WARNING
return;
switch ( appearance )
{
{
switch ( displayStatus )
{
request.
setColor( LEAD_COLOR, activeColorTable );
break;
request.
setColor( ACTIVE_COLOR, activeColorTable );
break;
request.
setColor( ACTIVE_AFFECTED_COLOR, activeColorTable );
break;
request.
setColor( DORMANT_COLOR, dormantColorTable );
break;
request.
setColor( HILITE_COLOR, activeColorTable );
break;
default:
break;
}
break;
}
{
}
cerr << "Couldnt evaluate\n";
}
bool drawTexture = true;
}
bool materialTransparent = false;
if ( materialTransparent ) {
}
{
wireRequest.
setToken( kDrawWireframeOnShaded );
switch ( displayStatus )
{
wireRequest.
setColor( LEAD_COLOR, activeColorTable );
break;
wireRequest.
setColor( ACTIVE_COLOR, activeColorTable );
break;
wireRequest.
setColor( HILITE_COLOR, activeColorTable );
break;
default:
break;
}
queue.
add( wireRequest );
}
break;
}
break;
break;
default:
break;
}
if ( !objectAndActiveOnly ) {
{
vertexRequest.
setToken( kDrawVertices );
vertexRequest.
setColor( DORMANT_VERTEX_COLOR,
queue.
add( vertexRequest );
}
if ( surfaceShape()->hasActiveComponents() ) {
activeVertexRequest.
setToken( kDrawVertices );
activeVertexRequest.
setColor( ACTIVE_VERTEX_COLOR,
MObject vertexComponent = clist[0];
queue.
add( activeVertexRequest );
}
}
}
{
int token = request.
token();
switch( token )
{
case kDrawWireframe :
case kDrawWireframeOnShaded :
drawWireframe( request, view );
break;
case kDrawSmoothShaded :
drawShaded( request, view );
break;
case kDrawFlatShaded :
break;
case kDrawVertices :
drawVertices( request, view );
break;
case kDrawBoundingBox:
drawBoundingBox( request, view );
break;
case kDrawRedPointAtCenter:
drawRedPointAtCenter( request, view );
break;
}
}
{
bool selected = false;
bool componentSelected = false;
bool hilited = false;
if ( hilited ) {
componentSelected = selectVertices( selectInfo, selectionList,
worldSpaceSelectPts );
selected = selected || componentSelected;
}
if ( !selected ) {
apiMesh* meshNode = (apiMesh*)surfaceShape();
selected = true;
item.
add( selectInfo.selectPath() );
if ( selectInfo.singleSelection() ) {
MPoint center = meshNode->boundingBox().center();
xformedPt = center;
xformedPt *= selectInfo.selectPath().inclusiveMatrix();
}
selectInfo.addSelection( item, xformedPt, selectionList,
worldSpaceSelectPts, priorityMask, false );
}
return selected;
}
void apiMeshUI::drawWireframe(
const MDrawRequest & request,
{
apiMeshGeom * geom = (apiMeshGeom*)data.
geometry();
int token = request.
token();
bool wireFrameOnShaded = false;
if ( kDrawWireframeOnShaded == token ) {
wireFrameOnShaded = true;
}
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
if ( lightingWasOn ) {
glDisable( GL_LIGHTING );
}
if ( wireFrameOnShaded ) {
glDepthMask( false );
}
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();
}
if ( lightingWasOn ) {
glEnable( GL_LIGHTING );
}
if ( wireFrameOnShaded ) {
glDepthMask( true );
}
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
{
apiMeshGeom * geom = (apiMeshGeom*)data.
geometry();
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
#if defined(SGI) || defined(MESA)
glEnable( GL_POLYGON_OFFSET_EXT );
#else
glEnable( GL_POLYGON_OFFSET_FILL );
#endif
bool drawTexture =
if ( drawTexture ) glEnable(GL_TEXTURE_2D);
if ( drawTexture ) {
}
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 (uv_len > 0)
{
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();
}
if ( drawTexture ) glDisable(GL_TEXTURE_2D);
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
{
apiMeshGeom * geom = (apiMeshGeom*)data.
geometry();
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
if ( lightingWasOn ) {
glDisable( GL_LIGHTING );
}
float lastPointSize;
glGetFloatv( GL_POINT_SIZE, &lastPointSize );
glPointSize( POINT_SIZE*2 );
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();
}
}
else {
glPointSize( POINT_SIZE );
int vid = 0;
for ( int i=0; i<geom->faceCount; i++ )
{
glBegin( GL_POINTS );
for ( int v=0; v<geom->face_counts[i]; v++ )
{
geom->vertices[ geom->face_connects[vid++] ];
glVertex3f( (float)vertex[0],
(float)vertex[1],
(float)vertex[2] );
}
glEnd();
}
}
if ( lightingWasOn ) {
glEnable( GL_LIGHTING );
}
glPointSize( lastPointSize );
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
void apiMeshUI::drawBoundingBox(
const MDrawRequest & request,
{
if ( !shape )
return;
float w = (float) box.
width();
float h = (float) box.
height();
float d = (float) box.
depth();
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
glBegin( GL_LINE_LOOP );
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();
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();
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();
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
void apiMeshUI::drawRedPointAtCenter(
const MDrawRequest & request,
{
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
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();
glPopAttrib();
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
bool apiMeshUI::selectVertices(
MSelectInfo &selectInfo,
{
bool selected = false;
double z,previousZ = 0.0;
int closestPointVertexIndex = -1;
const MDagPath & path = selectInfo.multiPath();
int vertexIndex;
bool singleSelection = selectInfo.singleSelection();
if( singleSelection ) {
alignmentMatrix = selectInfo.getAlignmentMatrix();
}
apiMesh* meshNode = (apiMesh*)surfaceShape();
apiMeshGeom * geom = meshNode->meshGeomToUse();
int numVertices = geom->vertices.length();
for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ )
{
MPoint currentPoint = geom->vertices[ vertexIndex ];
glBegin( GL_POINTS );
glVertex3f( (float)currentPoint[0],
(float)currentPoint[1],
(float)currentPoint[2] );
glEnd();
{
selected = true;
if ( singleSelection ) {
xformedPoint = currentPoint;
xformedPoint*= alignmentMatrix;
if ( closestPointVertexIndex < 0 || z > previousZ ) {
closestPointVertexIndex = vertexIndex;
singlePoint = currentPoint;
previousZ = z;
}
} else {
}
}
}
if ( selected && selectInfo.singleSelection() ) {
selectionPoint = singlePoint;
}
if ( selected ) {
selectionItem.
add( path, surfaceComponent );
selectInfo.addSelection(
selectionItem, selectionPoint,
selectionList, worldSpaceSelectPts,
mask, true );
}
return selected;
}
bool apiMeshUI::canDrawUV() const
{
apiMesh* meshNode = (apiMesh*)surfaceShape();
apiMeshGeom * geom = meshNode->meshGeomToUse();
return geom->uvcoords.uvcount() > 0;
}
void apiMeshUI::drawUVWireframe(
apiMeshGeom *geom,
) const
{
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
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();
}
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
void apiMeshUI::drawUVMapCoord(
int uv,
float u, float v,
bool drawNum
) const
{
if ( drawNum )
{
char s[32];
sprintf( s, "%d", uv );
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
glVertex3f( (GLfloat)u, (GLfloat)v, 0.0f );
}
void apiMeshUI::drawUVMapCoordNum(
apiMeshGeom *geom,
bool drawNumbers
) const
{
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
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 );
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
}
{
apiMesh* meshNode = (apiMesh*)surfaceShape();
apiMeshGeom * geom = meshNode->meshGeomToUse();
int uv_len = geom->uvcoords.uvcount();
if (uv_len > 0)
{
_OPENMAYA_DEPRECATION_PUSH_AND_DISABLE_WARNING
_OPENMAYA_POP_WARNING
switch( info.drawingFunction() ) {
drawUVWireframe( geom, view, info );
break;
drawUVWireframe( geom, view, info );
drawUVMapCoordNum( geom, view, info, false );
break;
default:
drawUVWireframe( geom, view, info );
};
}
}