#include <maya/MIOStream.h>
#include <math.h>
#include <stdlib.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MGlobal.h>
#include <maya/M3dView.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>
#include <maya/MPxContextCommand.h>
#include <maya/MPxContext.h>
#include <maya/MEvent.h>
#if defined(OSMac_MachO_)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
const char helpString[] =
"Click with left button or drag with middle button to select";
class marqueeContext : public MPxContext
{
public:
marqueeContext();
virtual void toolOnSetup( MEvent & event );
virtual MStatus doPress( MEvent & event );
virtual MStatus doDrag( MEvent & event );
virtual MStatus doRelease( MEvent & event );
virtual MStatus doEnterRegion( MEvent & event );
private:
short start_x, start_y;
short last_x, last_y;
#ifdef USE_SOFTWARE_OVERLAYS
short p_last_x, p_last_y;
bool fsDrawn;
#endif
MGlobal::ListAdjustment listAdjustment;
M3dView view;
};
marqueeContext::marqueeContext()
{
setTitleString ( "Marquee Tool" );
setImage("marqueeTool.xpm", MPxContext::kImage1 );
}
void marqueeContext::toolOnSetup ( MEvent & )
{
setHelpString( helpString );
}
MStatus marqueeContext::doPress( MEvent & event )
{
if (event.isModifierShift() || event.isModifierControl() ) {
if ( event.isModifierShift() ) {
if ( event.isModifierControl() ) {
listAdjustment = MGlobal::kAddToList;
} else {
listAdjustment = MGlobal::kXORWithList;
}
} else if ( event.isModifierControl() ) {
listAdjustment = MGlobal::kRemoveFromList;
}
} else {
listAdjustment = MGlobal::kReplaceList;
}
event.getPosition( start_x, start_y );
view = M3dView::active3dView();
view.beginGL();
#ifdef USE_SOFTWARE_OVERLAYS
p_last_x = start_x;
p_last_y = start_y;
fsDrawn = false;
#else
view.beginOverlayDrawing();
#endif
return MS::kSuccess;
}
MStatus marqueeContext::doDrag( MEvent & event )
{
event.getPosition( last_x, last_y );
#ifdef USE_SOFTWARE_OVERLAYS
GLboolean depthTest[1];
GLboolean colorLogicOp[1];
GLboolean lineStipple[1];
glGetBooleanv (GL_DEPTH_TEST, depthTest);
glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp);
glGetBooleanv (GL_LINE_STIPPLE, lineStipple);
#endif
glLineStipple( 1, 0x5555 );
glLineWidth( 1.0 );
glEnable( GL_LINE_STIPPLE );
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(
0.0, (GLdouble) view.portWidth(),
0.0, (GLdouble) view.portHeight()
);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
glIndexi (2);
#ifdef USE_SOFTWARE_OVERLAYS
glDisable (GL_DEPTH_TEST);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp (GL_XOR);
if (fsDrawn)
{
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( p_last_x, start_y );
glVertex2i( p_last_x, p_last_y );
glVertex2i( start_x, p_last_y );
glEnd();
}
fsDrawn = true;
#else
view.clearOverlayPlane();
#endif
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( last_x, start_y );
glVertex2i( last_x, last_y );
glVertex2i( start_x, last_y );
glEnd();
#ifdef _WIN32
SwapBuffers( view.deviceContext() );
#elif defined (OSMac_)
::aglSwapBuffers(view.display());
#else
glXSwapBuffers( view.display(), view.window() );
#endif
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
#ifdef USE_SOFTWARE_OVERLAYS
p_last_x = last_x;
p_last_y = last_y;
if (colorLogicOp[0])
glEnable (GL_COLOR_LOGIC_OP);
else
glDisable (GL_COLOR_LOGIC_OP);
if (depthTest[0])
glEnable (GL_DEPTH_TEST);
else
glDisable (GL_DEPTH_TEST);
if (lineStipple[0])
glEnable( GL_LINE_STIPPLE );
else
glDisable( GL_LINE_STIPPLE );
#endif
return MS::kSuccess;
}
MStatus marqueeContext::doRelease( MEvent & event )
{
MSelectionList incomingList, marqueeList;
#ifdef USE_SOFTWARE_OVERLAYS
GLboolean depthTest[1];
GLboolean colorLogicOp[1];
GLboolean lineStipple[1];
event.getPosition( last_x, last_y );
glGetBooleanv (GL_DEPTH_TEST, depthTest);
glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp);
glGetBooleanv (GL_LINE_STIPPLE, lineStipple);
glLineStipple( 1, 0x5555 );
glLineWidth( 1.0 );
glEnable( GL_LINE_STIPPLE );
glDisable (GL_DEPTH_TEST);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp (GL_INVERT);
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(
0.0, (GLdouble) view.portWidth(),
0.0, (GLdouble) view.portHeight()
);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
glIndexi (2);
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( p_last_x, start_y );
glVertex2i( p_last_x, p_last_y );
glVertex2i( start_x, p_last_y );
glEnd();
#ifndef _WIN32
glXSwapBuffers( view.display(), view.window() );
#else
SwapBuffers( view.deviceContext() );
#endif
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
glDisable(GL_COLOR_LOGIC_OP);
if (colorLogicOp[0])
glEnable (GL_COLOR_LOGIC_OP);
else
glDisable (GL_COLOR_LOGIC_OP);
if (depthTest[0])
glEnable (GL_DEPTH_TEST);
else
glDisable (GL_DEPTH_TEST);
if (lineStipple[0])
glEnable( GL_LINE_STIPPLE );
else
glDisable( GL_LINE_STIPPLE );
#else
view.clearOverlayPlane();
view.endOverlayDrawing();
#endif
view.endGL();
event.getPosition( last_x, last_y );
MGlobal::getActiveSelectionList(incomingList);
if ( abs(start_x - last_x) < 2 && abs(start_y - last_y) < 2 ) {
MGlobal::SelectionMethod selectionMethod = MGlobal::selectionMethod();
MGlobal::selectFromScreen( start_x, start_y, MGlobal::kReplaceList, selectionMethod );
} else {
MGlobal::selectFromScreen( start_x, start_y, last_x, last_y,
MGlobal::kReplaceList,
MGlobal::kWireframeSelectMethod );
}
MGlobal::getActiveSelectionList(marqueeList);
MGlobal::setActiveSelectionList(incomingList, MGlobal::kReplaceList);
MGlobal::selectCommand(marqueeList, listAdjustment);
return MS::kSuccess;
}
MStatus marqueeContext::doEnterRegion( MEvent & )
{
return setHelpString( helpString );
}
class marqueeContextCmd : public MPxContextCommand
{
public:
marqueeContextCmd();
virtual MPxContext* makeObj();
static void* creator();
};
marqueeContextCmd::marqueeContextCmd() {}
MPxContext* marqueeContextCmd::makeObj()
{
return new marqueeContext();
}
void* marqueeContextCmd::creator()
{
return new marqueeContextCmd;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
status = plugin.registerContextCommand( "marqueeToolContext",
marqueeContextCmd::creator );
return status;
}
MStatus uninitializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterContextCommand( "marqueeToolContext" );
return status;
}