apiSimpleShapeUI.cpp
#include <maya/MIOStream.h>
#include <apiSimpleShapeUI.h>
#include <maya/MMaterial.h>
#include <maya/MSelectionList.h>
#include <maya/MSelectionMask.h>
#include <maya/MDrawData.h>
#include <maya/MMatrix.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MObjectArray.h>
#include <maya/MDagPath.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
apiSimpleShapeUI::apiSimpleShapeUI() {}
apiSimpleShapeUI::~apiSimpleShapeUI() {}
void* apiSimpleShapeUI::creator()
{
return new apiSimpleShapeUI();
}
void apiSimpleShapeUI::getDrawRequests( const MDrawInfo & info,
bool objectAndActiveOnly,
MDrawRequestQueue & queue )
{
MDrawData data;
apiSimpleShape* shape = (apiSimpleShape*) surfaceShape();
MVectorArray* geomPtr = shape->getControlPoints();
MDrawRequest request = info.getPrototype( *this );
getDrawData( geomPtr, data );
request.setDrawData( data );
M3dView::DisplayStyle appearance = info.displayStyle();
M3dView::DisplayStatus displayStatus = info.displayStatus();
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 :
{
request.setToken( kDrawSmoothShaded );
MDagPath path = info.multiPath();
M3dView view = info.view();;
MMaterial material = MPxSurfaceShapeUI::material( path );
if ( ! material.evaluateMaterial( view, path ) ) {
cerr << "Couldnt evaluate\n";
}
bool drawTexture = true;
if ( drawTexture && material.materialIsTextured() ) {
material.evaluateTexture( data );
}
request.setMaterial( material );
bool materialTransparent = false;
material.getHasTransparency( materialTransparent );
if ( materialTransparent ) {
request.setIsTransparent( true );
}
queue.add( request );
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 );
break;
default:
break;
}
if ( !objectAndActiveOnly ) {
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 );
}
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];
activeVertexRequest.setComponent( vertexComponent );
queue.add( activeVertexRequest );
}
}
}
void apiSimpleShapeUI::draw( const MDrawRequest & request, M3dView & view ) const
{
int token = request.token();
switch( token )
{
case kDrawWireframe :
case kDrawWireframeOnShaded :
case kDrawVertices :
drawVertices( request, view );
break;
case kDrawSmoothShaded :
break;
case kDrawFlatShaded :
break;
}
}
bool apiSimpleShapeUI::select( MSelectInfo &selectInfo, MSelectionList &selectionList,
MPointArray &worldSpaceSelectPts ) const
{
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 )
{
selected = true;
MSelectionMask priorityMask( MSelectionMask::kSelectNurbsSurfaces );
MSelectionList item;
item.add( selectInfo.selectPath() );
MPoint xformedPt;
if ( selectInfo.singleSelection() ) {
MPoint center = surfaceShape()->boundingBox().center();
xformedPt = center;
xformedPt *= selectInfo.selectPath().inclusiveMatrix();
}
selectInfo.addSelection( item, xformedPt, selectionList,
worldSpaceSelectPts, priorityMask, false );
}
return selected;
}
void apiSimpleShapeUI::drawVertices( const MDrawRequest & request,
M3dView & view ) const
{
MDrawData data = request.drawData();
MVectorArray * geom = (MVectorArray*)data.geometry();
view.beginGL();
bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
if ( lightingWasOn ) {
glDisable( GL_LIGHTING );
}
float lastPointSize;
glGetFloatv( GL_POINT_SIZE, &lastPointSize );
glPointSize( POINT_SIZE );
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 );
MVector& point = (*geom)[index];
glVertex3f( (float)point[0],
(float)point[1],
(float)point[2] );
glEnd();
char annotation[32];
sprintf( annotation, "%d", index );
view.drawText( annotation, point );
}
}
else {
for ( unsigned int i=0; i<geom->length(); i++ )
{
glBegin( GL_POINTS );
MVector point = (*geom)[ i ];
glVertex3f( (float)point[0], (float)point[1], (float)point[2] );
glEnd();
}
}
if ( lightingWasOn ) {
glEnable( GL_LIGHTING );
}
glPointSize( lastPointSize );
view.endGL();
}
bool apiSimpleShapeUI::selectVertices( MSelectInfo &selectInfo,
MSelectionList &selectionList,
MPointArray &worldSpaceSelectPts ) const
{
bool selected = false;
M3dView view = selectInfo.view();
MPoint xformedPoint;
MPoint currentPoint;
MPoint selectionPoint;
double z,previousZ = 0.0;
int closestPointVertexIndex = -1;
const MDagPath & path = selectInfo.multiPath();
MFnSingleIndexedComponent fnComponent;
MObject surfaceComponent = fnComponent.create( MFn::kMeshVertComponent );
int vertexIndex;
MMatrix alignmentMatrix;
MPoint singlePoint;
bool singleSelection = selectInfo.singleSelection();
if( singleSelection ) {
alignmentMatrix = selectInfo.getAlignmentMatrix();
}
apiSimpleShape* shape = (apiSimpleShape*) surfaceShape();
MVectorArray* geomPtr = shape->getControlPoints();
MVectorArray& geom = *geomPtr;
int numVertices = geom.length();
for ( vertexIndex=0; vertexIndex<numVertices; vertexIndex++ )
{
const MVector& point = geom[ vertexIndex ];
view.beginSelect();
glBegin( GL_POINTS );
glVertex3f( (float)point[0],
(float)point[1],
(float)point[2] );
glEnd();
if ( view.endSelect() > 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 {
fnComponent.addElement( vertexIndex );
}
}
}
if ( selected && selectInfo.singleSelection() ) {
fnComponent.addElement(closestPointVertexIndex);
selectionPoint = singlePoint;
selectionPoint *= path.inclusiveMatrix();
}
if ( selected ) {
MSelectionList selectionItem;
selectionItem.add( path, surfaceComponent );
MSelectionMask mask( MSelectionMask::kSelectComponentsMask );
selectInfo.addSelection(
selectionItem, selectionPoint,
selectionList, worldSpaceSelectPts,
mask, true );
}
return selected;
}