#include <maya/MIOStream.h>
#include <maya/MPxSurfaceShape.h>
#include <maya/MPxSurfaceShapeUI.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnEnumAttribute.h>
#include <maya/MPoint.h>
#include <maya/MPlug.h>
#include <maya/MDrawData.h>
#include <maya/MDrawRequest.h>
#include <maya/MSelectionMask.h>
#include <maya/MSelectionList.h>
#include <maya/MDagPath.h>
#include <maya/MMaterial.h>
#if defined(OSMac_MachO_)
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif
#define MCHECKERROR(STAT,MSG) \
if ( MS::kSuccess != STAT ) { \
cerr << MSG << endl; \
return MS::kFailure; \
}
#define MAKE_NUMERIC_ATTR( NAME, SHORTNAME, TYPE, DEFAULT, KEYABLE ) \
MStatus NAME##_stat; \
MFnNumericAttribute NAME##_fn; \
NAME = NAME##_fn.create( #NAME, SHORTNAME, TYPE, DEFAULT ); \
MCHECKERROR(NAME##_stat, "numeric attr create error"); \
NAME##_fn.setHidden( !KEYABLE ); \
NAME##_fn.setKeyable( KEYABLE ); \
NAME##_fn.setInternal( true ); \
NAME##_stat = addAttribute( NAME ); \
MCHECKERROR(NAME##_stat, "addAttribute error");
#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
class quadricGeom
{
public:
double radius1;
double radius2;
double height;
double startAngle;
double sweepAngle;
short slices;
short loops;
short stacks;
short shapeType;
};
{
public:
quadricShape();
~quadricShape() override;
static void * creator();
quadricGeom* geometry();
private:
quadricGeom* fGeometry;
public:
};
{
public:
quadricShapeUI();
~quadricShapeUI() override;
bool objectAndActiveOnly,
static void * creator();
private:
enum {
kDrawCylinder,
kDrawDisk,
kDrawPartialDisk,
kDrawSphere
};
enum {
kDrawWireframe,
kDrawWireframeOnShaded,
kDrawSmoothShaded,
kDrawFlatShaded,
kLastToken
};
};
MTypeId quadricShape::id( 0x80111 );
quadricShape::quadricShape()
{
fGeometry = new quadricGeom;
fGeometry->radius1 = 1.0;
fGeometry->radius2 = 1.0;
fGeometry->height = 2.0;
fGeometry->startAngle = 0.0;
fGeometry->sweepAngle = 90.0;
fGeometry->slices = 8;
fGeometry->loops = 6;
fGeometry->stacks = 4;
fGeometry->shapeType = 0;
}
quadricShape::~quadricShape()
{
delete fGeometry;
}
void quadricShape::postConstructor()
{
setRenderable( true );
}
{
return MS::kUnknownParameter;
}
bool quadricShape::getInternalValue(
const MPlug& plug,
MDataHandle& datahandle )
{
bool isOk = true;
if ( plug == radius1 ) {
datahandle.
set( fGeometry->radius1 );
isOk = true;
}
else if ( plug == radius2 ) {
datahandle.
set( fGeometry->radius2 );
isOk = true;
}
else if ( plug == height ) {
datahandle.
set( fGeometry->height );
isOk = true;
}
else if ( plug == startAngle ) {
datahandle.
set( fGeometry->startAngle );
isOk = true;
}
else if ( plug == sweepAngle ) {
datahandle.
set( fGeometry->sweepAngle );
isOk = true;
}
else if ( plug == slices ) {
datahandle.
set( fGeometry->slices );
isOk = true;
}
else if ( plug == loops ) {
datahandle.
set( fGeometry->loops );
isOk = true;
}
else if ( plug == stacks ) {
datahandle.
set( fGeometry->stacks );
isOk = true;
}
else {
}
return isOk;
}
bool quadricShape::setInternalValue(
const MPlug& plug,
const MDataHandle& datahandle )
{
bool isOk = true;
if ( plug == radius1 ) {
double innerRadius = datahandle.
asDouble();
double outerRadius = fGeometry->radius2;
if ( innerRadius > outerRadius ) {
outerRadius = innerRadius;
}
if ( innerRadius < 0 ) {
innerRadius = 0;
}
fGeometry->radius1 = innerRadius;
fGeometry->radius2 = outerRadius;
isOk = true;
}
else if ( plug == radius2 ) {
double outerRadius = datahandle.
asDouble();
double innerRadius = fGeometry->radius1;
if ( outerRadius <= 0 ) {
outerRadius = 0.1;
}
if ( innerRadius > outerRadius ) {
innerRadius = outerRadius;
}
if ( innerRadius < 0 ) {
innerRadius = 0;
}
fGeometry->radius1 = innerRadius;
fGeometry->radius2 = outerRadius;
isOk = true;
}
else if ( plug == height ) {
if ( val <= 0 ) {
val = 0.1;
}
fGeometry->height = val;
}
else if ( plug == startAngle ) {
fGeometry->startAngle = val;
}
else if ( plug == sweepAngle ) {
fGeometry->sweepAngle = val;
}
else if ( plug == slices ) {
if ( val < 3 ) {
val = 3;
}
fGeometry->slices = val;
}
else if ( plug == loops ) {
if ( val < 3 ) {
val = 3;
}
fGeometry->loops = val;
}
else if ( plug == stacks ) {
if ( val < 2 ) {
val = 2;
}
fGeometry->stacks = val;
}
else {
}
return isOk;
}
bool quadricShape::isBounded() const { return true; }
{
quadricShape* nonConstThis = const_cast <quadricShape*> (this);
quadricGeom* geom = nonConstThis->geometry();
double r = geom->radius1;
r = geom->radius2;
r = geom->height;
return result;
}
void* quadricShape::creator()
{
return new quadricShape();
}
{
shapeType = enumAttr.
create(
"shapeType",
"st", 0, &stat );
MCHECKERROR( stat, "create shapeType attribute" );
stat = addAttribute( shapeType );
MCHECKERROR( stat, "Error adding shapeType attribute." );
return stat;
}
quadricGeom* quadricShape::geometry()
{
MObject this_object = thisMObject();
MPlug plug( this_object, radius1 ); plug.
getValue( fGeometry->radius1 );
return fGeometry;
}
quadricShapeUI::quadricShapeUI() {}
quadricShapeUI::~quadricShapeUI() {}
void* quadricShapeUI::creator()
{
return new quadricShapeUI();
}
void quadricShapeUI::getDrawRequests(
const MDrawInfo & info,
bool ,
{
quadricShape* shapeNode = (quadricShape*)surfaceShape();
quadricGeom* geom = shapeNode->geometry();
getDrawData( geom, data );
return;
{
getDrawRequestsWireframe( request, info );
break;
getDrawRequestsShaded( request, info, queue, data );
break;
getDrawRequestsShaded( request, info, queue, data );
break;
default:
break;
}
}
{
quadricGeom * geom = (quadricGeom*)data.
geometry();
int token = request.
token();
bool drawTexture = false;
view.beginGL();
if ( (token == kDrawSmoothShaded) || (token == kDrawFlatShaded) )
{
#if defined(SGI) || defined(MESA)
glEnable( GL_POLYGON_OFFSET_EXT );
#else
glEnable( GL_POLYGON_OFFSET_FILL );
#endif
if ( drawTexture ) glEnable(GL_TEXTURE_2D);
if ( drawTexture ) {
}
}
GLUquadricObj* qobj = gluNewQuadric();
switch( token )
{
case kDrawWireframe :
case kDrawWireframeOnShaded :
gluQuadricDrawStyle( qobj, GLU_LINE );
break;
case kDrawSmoothShaded :
gluQuadricNormals( qobj, GLU_SMOOTH );
gluQuadricTexture( qobj, true );
gluQuadricDrawStyle( qobj, GLU_FILL );
break;
case kDrawFlatShaded :
gluQuadricNormals( qobj, GLU_FLAT );
gluQuadricTexture( qobj, true );
gluQuadricDrawStyle( qobj, GLU_FILL );
break;
}
switch ( geom->shapeType )
{
case kDrawCylinder :
gluCylinder( qobj, geom->radius1, geom->radius2, geom->height,
geom->slices, geom->stacks );
break;
case kDrawDisk :
gluDisk( qobj, geom->radius1, geom->radius2, geom->slices, geom->loops );
break;
case kDrawPartialDisk :
gluPartialDisk( qobj, geom->radius1, geom->radius2, geom->slices,
geom->loops, geom->startAngle, geom->sweepAngle );
break;
case kDrawSphere :
default :
gluSphere( qobj, geom->radius1, geom->slices, geom->stacks );
break;
}
if ( drawTexture ) glDisable(GL_TEXTURE_2D);
view.endGL();
}
{
item.
add( selectInfo.selectPath() );
selectInfo.addSelection( item, xformedPt, selectionList,
worldSpaceSelectPts, priorityMask, false );
return true;
}
void quadricShapeUI::getDrawRequestsWireframe(
MDrawRequest& request,
{
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;
}
}
void quadricShapeUI::getDrawRequestsShaded(
MDrawRequest& request,
{
cerr << "Couldnt evaluate\n";
}
bool drawTexture = true;
}
bool materialTransparent = false;
if ( materialTransparent ) {
}
{
getDrawRequestsWireframe( wireRequest, info );
wireRequest.
setToken( kDrawWireframeOnShaded );
queue.
add( wireRequest );
}
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
return plugin.registerShape( "quadricShape", quadricShape::id,
&quadricShape::creator,
&quadricShape::initialize,
&quadricShapeUI::creator );
}
{
return plugin.deregisterNode( quadricShape::id );
}