//////////////////////////////////////////////////////////////////////// // Copyright (C) 2002/02/20 Yosiyuki Nisino // File: CreateFur.cpp // MEL File: CreateFur.mel // MEL Command: CreateFur // ///////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ERR( s, r ) { if( !s ) return r; } #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 DORMANT_COLOR 4 // blue #define ACTIVE_AFFECTED_COLOR 8 // purple #define ACTIVE_COLOR 15 // white #define HILITE_COLOR 17 // pale blue #define LEAD_COLOR 18 // green typedef struct _Vector { float x; float y; float z; }Vector; typedef struct _Point { float x; float y; float z; }Point; int flag; int cnt1=0; int cnt2=0; short U_samples = 32; short V_samples = 32; double baseWidth = 0.05; double tipWidth = 0.03; MVector viewDirection, upDirection; Vector *normal; Point *start1, *end1; Point *start2, *end2; Point *A, *B, *C, *D; class furFeedbackGeom { public: short Usamples; short Vsamples; }; class furFeedbackShape : public MPxSurfaceShape { public: furFeedbackShape(); virtual ~furFeedbackShape(); virtual void postConstructor(); virtual MStatus compute( const MPlug&, MDataBlock& ); virtual bool getInternalValue( const MPlug&, MDataHandle& ); virtual bool setInternalValue( const MPlug&, const MDataHandle& ); virtual bool isBounded() const; virtual MBoundingBox boundingBox() const; static void * creator(); static MStatus initialize(); furFeedbackGeom* geometry(); private: furFeedbackGeom* fGeometry; static MObject Usamples; static MObject Vsamples; public: static MTypeId id; static MObject inputSurface; static MObject outputFur; }; class furFeedbackShapeUI : public MPxSurfaceShapeUI { public: furFeedbackShapeUI(); virtual ~furFeedbackShapeUI(); virtual void getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & requests ); virtual void draw( const MDrawRequest & request, M3dView & view ) const; virtual bool select( MSelectInfo &selectInfo, MSelectionList &selectionList, MPointArray &worldSpaceSelectPts ) const; void getDrawRequestsWireframe( MDrawRequest&, const MDrawInfo& ); void getDrawRequestsShaded( MDrawRequest&, const MDrawInfo&, MDrawRequestQueue&, MDrawData& data ); static void * creator(); private: enum { kDrawfurFeedback, kLastToken }; }; MObject furFeedbackShape::Usamples; MObject furFeedbackShape::Vsamples; MTypeId furFeedbackShape::id( 0x77777 ); MObject furFeedbackShape::inputSurface; MObject furFeedbackShape::outputFur; furFeedbackShape::furFeedbackShape() { fGeometry = new furFeedbackGeom; fGeometry->Usamples = 32; fGeometry->Vsamples = 32; } furFeedbackShape::~furFeedbackShape() { delete fGeometry; } void furFeedbackShape::postConstructor() { setRenderable( false ); } MStatus furFeedbackShape::compute( const MPlug& plug, MDataBlock& data ) { cout << "In furFeedbackShape::compute" << endl; MStatus status; if( plug == outputFur ) { cnt1=0; MDataHandle inputData = data.inputValue( inputSurface, &status ); if( status != MS::kSuccess ) { cerr << "ERROR getting data" << endl; } else { MObject surfaceinfo = inputData.asNurbsSurfaceTransformed(); MFnNurbsSurface fnNurbs( surfaceinfo, &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating nurbs function set" << endl; } else { int U_span, V_span; double i, j; MPoint pnt; MPointArray cvArray1, cvArray2; MVector normal; ERR( status, status ); U_span = fnNurbs.numSpansInU(); V_span = fnNurbs.numSpansInV(); start1 = new Point [10000]; end1 = new Point [10000]; start2 = new Point [100000]; end2 = new Point [100000]; for( i=0.0; i <= U_span; i+=(double)U_span / U_samples ) { for( j=0.0; j <= V_span; j+=(double)V_span / V_samples ) { normal = fnNurbs.normal( i, j ); ERR( fnNurbs.getPointAtParam( i, j, pnt ), MS::kFailure ); cvArray1.append( pnt ); cvArray1.append( pnt + normal ); start1[cnt1].x = cvArray1[0][0]; start1[cnt1].y = cvArray1[0][1]; start1[cnt1].z = cvArray1[0][2]; end1[cnt1].x = cvArray1[1][0]; end1[cnt1].y = cvArray1[1][1]; end1[cnt1].z = cvArray1[1][2]; cvArray1.clear(); cnt1++; } } for( i=0.0; i <= U_span; i+=(double)U_span / 100 ) { for( j=0.0; j <= V_span; j+=(double)V_span / 100 ) { normal = fnNurbs.normal( i, j ); ERR( fnNurbs.getPointAtParam( i, j, pnt ), MS::kFailure ); cvArray2.append( pnt ); cvArray2.append( pnt + normal ); start2[cnt2].x = cvArray2[0][0]; start2[cnt2].y = cvArray2[0][1]; start2[cnt2].z = cvArray2[0][2]; end2[cnt2].x = cvArray2[1][0]; end2[cnt2].y = cvArray2[1][1]; end2[cnt2].z = cvArray2[1][2]; cvArray2.clear(); cnt2++; } } short result1 = U_samples; short result2 = V_samples; MDataHandle nurbsHandle = data.outputValue( furFeedbackShape::outputFur ); nurbsHandle.set( result1, result2 ); data.setClean(plug); } } } else { return MS::kUnknownParameter; } return MS::kSuccess; } bool furFeedbackShape::getInternalValue( const MPlug& plug, MDataHandle& datahandle ) { cout << "In furFeedbackShape::getInternalValue" << endl; bool isOk = true; MObject this_object = thisMObject(); if ( plug == Usamples ) { datahandle.set( fGeometry->Usamples ); isOk = true; } else if ( plug == Vsamples ) { datahandle.set( fGeometry->Vsamples ); isOk = true; } else { isOk = MPxSurfaceShape::getInternalValue( plug, datahandle ); } return isOk; } bool furFeedbackShape::setInternalValue( const MPlug& plug, const MDataHandle& datahandle ) { cout << "In furFeedbackShape::setInternalValue" << endl; bool isOk = true; if ( plug == Usamples ) { short usamples = datahandle.asShort(); U_samples = usamples; cout << "U_samples" << U_samples << endl; if ( usamples < 0 ) { usamples = 1; } else if( usamples > 100 ) { usamples = 100; } fGeometry->Usamples = usamples; isOk = true; } else if ( plug == Vsamples ) { short vsamples = datahandle.asShort(); V_samples = vsamples; cout << "V_samples" << V_samples << endl; if ( vsamples < 0 ) { vsamples = 1; } else if( vsamples > 100 ) { vsamples = 100; } fGeometry->Vsamples = vsamples; isOk = true; } else { isOk = MPxSurfaceShape::setInternalValue( plug, datahandle ); } return isOk; } bool furFeedbackShape::isBounded() const { return true; } MBoundingBox furFeedbackShape::boundingBox() const { MBoundingBox result; furFeedbackShape* nonConstThis = const_cast (this); furFeedbackGeom* geom = nonConstThis->geometry(); double r = 1.0; result.expand( MPoint(r,r,r) ); result.expand( MPoint(-r,-r,-r) ); return result; } void* furFeedbackShape::creator() { return new furFeedbackShape(); } MStatus furFeedbackShape::initialize() { cout << "In furFeedbackShape::initialize" << endl; MStatus status; MFnNumericAttribute numericAttr; MFnTypedAttribute typedAttr; inputSurface = typedAttr.create( "inputSurface", "input", MFnData::kNurbsSurface, &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating inputSurface attribute" << endl; return status; } outputFur = numericAttr.create( "outputFur", "output", MFnNumericData::k2Short, 0, &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating outputFur attribute" << endl; return status; } numericAttr.setWritable(false); status = addAttribute( inputSurface ); if( status != MS::kSuccess ) { cerr << "addAttribute(inputSurface)" << endl; return status; } status = addAttribute( outputFur ); if( status != MS::kSuccess ) { cerr << "addAttribute(outputFur)" << endl; return status; } status = attributeAffects( inputSurface, outputFur ); if( status != MS::kSuccess ) { cerr << "attributeAffects(inputSurface, outputFur)" << endl; return status; } MAKE_NUMERIC_ATTR( Usamples, "usamples", MFnNumericData::kShort, 32, true ); MAKE_NUMERIC_ATTR( Vsamples, "vsamples", MFnNumericData::kShort, 32, true ); return status; } furFeedbackGeom* furFeedbackShape::geometry() { MObject this_object = thisMObject(); MPlug plug( this_object, Usamples ); plug.getValue( fGeometry->Usamples ); plug.setAttribute( Vsamples ); plug.getValue( fGeometry->Vsamples ); return fGeometry; } furFeedbackShapeUI::furFeedbackShapeUI() {} furFeedbackShapeUI::~furFeedbackShapeUI() {} void* furFeedbackShapeUI::creator() { return new furFeedbackShapeUI(); } void furFeedbackShapeUI::getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & queue ) { cout << "In furFeedbackShapeUI::getDrawRequests" << endl; MDrawData data; MDrawRequest request = info.getPrototype( *this ); furFeedbackShape* shapeNode = (furFeedbackShape*)surfaceShape(); furFeedbackGeom* geom = shapeNode->geometry(); getDrawData( geom, data ); request.setDrawData( data ); switch ( info.displayStyle() ) { case M3dView::kWireFrame : getDrawRequestsWireframe( request, info ); queue.add( request ); break; case M3dView::kGouraudShaded : getDrawRequestsWireframe( request, info ); queue.add( request ); break; case M3dView::kFlatShaded : getDrawRequestsWireframe( request, info ); queue.add( request ); break; } } void furFeedbackShapeUI::draw( const MDrawRequest & request, M3dView & view ) const { cout << "In furFeedbackShapeUI::draw" << endl; int i; MDrawData data = request.drawData(); furFeedbackGeom * geom = (furFeedbackGeom*)data.geometry(); short token = request.token(); bool drawTexture = false; view.beginGL(); if( token == kDrawfurFeedback ) { glLineWidth(1.0); glBegin(GL_LINES); { for(i=0; i < cnt1; i++ ) { glVertex3d(start1[i].x, start1[i].y, start1[i].z); glVertex3d(end1[i].x, end1[i].y, end1[i].z); } } glEnd(); } view.endGL(); } bool furFeedbackShapeUI::select( MSelectInfo &selectInfo, MSelectionList &selectionList, MPointArray &worldSpaceSelectPts ) const { flag++; cout << "In furFeedbackShapeUI::select" << endl; MSelectionMask priorityMask( MSelectionMask::kSelectObjectsMask ); MSelectionList item; item.add( selectInfo.selectPath() ); MPoint xformedPt; selectInfo.addSelection( item, xformedPt, selectionList, worldSpaceSelectPts, priorityMask, false ); return true; } void furFeedbackShapeUI::getDrawRequestsWireframe( MDrawRequest& request, const MDrawInfo& info ) { cout << "In furFeedbackShapeUI::getDrawRequestsWireframe" << endl; request.setToken( kDrawfurFeedback ); M3dView::DisplayStatus displayStatus = info.displayStatus(); M3dView::ColorTable activeColorTable = M3dView::kActiveColors; M3dView::ColorTable dormantColorTable = M3dView::kDormantColors; if( flag==0 ) { displayStatus = M3dView::kDormant; } 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( ACTIVE_AFFECTED_COLOR, dormantColorTable ); break; case M3dView::kHilite : request.setColor( HILITE_COLOR, activeColorTable ); break; } } class furRender : public MPxNode { public: furRender(); virtual ~furRender(); virtual MStatus compute( const MPlug& plug, MDataBlock& data ); static void* creator(); static MStatus initialize(); static MObject basewidth; static MObject tipwidth; static MTypeId id; static MObject time; static MObject outputMesh; protected: MObject createMesh( const MTime& time, MObject &outData, MStatus &status ); }; MObject furRender::basewidth; MObject furRender::tipwidth; MTypeId furRender::id( 0x88888 ); MObject furRender::time; MObject furRender::outputMesh; furRender::furRender() {} furRender::~furRender() {} void* furRender::creator() { return new furRender(); } MStatus furRender::initialize() { cout << "In furRender::initialize" << endl; MStatus status; MFnNumericAttribute numericAttr; MFnUnitAttribute unitAttr; MFnTypedAttribute typedAttr; time = unitAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating input attribute" << endl; return status; } outputMesh = typedAttr.create( "outputMesh", "out", MFnData::kMesh, &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating output attribute" << endl; return status; } typedAttr.setStorable(false); status = addAttribute( time ); if( status != MS::kSuccess ) { cerr << "addAttribute(input)" << endl; return status; } status = addAttribute( outputMesh ); if( status != MS::kSuccess ) { cerr << "addAttribute(output)" << endl; return status; } status = attributeAffects( time, outputMesh ); if( status != MS::kSuccess ) { cerr << "attributeAffects(time, outputMesh)" << endl; } MAKE_NUMERIC_ATTR( basewidth, "base", MFnNumericData::kDouble, 0.05, true ); MAKE_NUMERIC_ATTR( tipwidth, "tip", MFnNumericData::kDouble, 0.03, true ); return status; } MObject furRender::createMesh( const MTime& time, MObject& outData, MStatus &status ) { cout << "In furRender::createMesh" << endl; int i; int *num; double k, scalar, dot; Point stock, *down, *top; Vector view, up, cross, fur; MFloatPointArray points; MFnMesh meshFS; num = new int [1000]; normal = new Vector [1000]; down = new Point [1000]; top = new Point [1000]; A = new Point [1000]; B = new Point [1000]; C = new Point [1000]; D = new Point [1000]; for( i=0; i < 1000; i++ ) { num[i] = rand() % cnt2; view.x = viewDirection.x; view.y = viewDirection.y; view.z = viewDirection.z; up.x = upDirection.x; up.y = upDirection.y; up.z = upDirection.z; down[i].x = start2[num[i]].x; down[i].y = start2[num[i]].y; down[i].z = start2[num[i]].z; top[i].x = end2[num[i]].x; top[i].y = end2[num[i]].y; top[i].z = end2[num[i]].z; fur.x = top[i].x - down[i].x; fur.y = top[i].y - down[i].y; fur.z = top[i].z - down[i].z; dot = fur.x*view.x+fur.y*view.y+fur.z*view.z; /*if( dot == 1.0 ) { normal[i].x = -up.x; normal[i].y = -up.y; normal[i].z = -up.z; } else if( dot == -1.0 ) { normal[i].x = up.x; normal[i].y = up.y; normal[i].z = up.z; } else if( dot == 0.0 ) { normal[i].x = -view.x; normal[i].y = -view.y; normal[i].z = -view.z; scalar = normal[i].x*normal[i].x+normal[i].y*normal[i].y+normal[i].z*normal[i].z; normal[i].x /= scalar; normal[i].y /= scalar; normal[i].z /= scalar; } else if( dot < 0.0 ) { k = -( (view.x*fur.x)+(view.y*fur.y)+(view.z*fur.z) ) / ( (fur.x*fur.x)+(fur.y*fur.y)+(fur.z*fur.z) ); normal[i].x = -k*fur.x - view.x; normal[i].y = -k*fur.y - view.y; normal[i].z = -k*fur.z - view.z; scalar = normal[i].x*normal[i].x+normal[i].y*normal[i].y+normal[i].z*normal[i].z; normal[i].x /= scalar; normal[i].y /= scalar; normal[i].z /= scalar; } else if( dot > 0.0 ) { k = ( (view.x*fur.x)+(view.y*fur.y)+(view.z*fur.z) ) / ( (fur.x*fur.x)+(fur.y*fur.y)+(fur.z*fur.z) ); normal[i].x = k*fur.x - view.x; normal[i].y = k*fur.y - view.y; normal[i].z = k*fur.z - view.z; scalar = normal[i].x*normal[i].x+normal[i].y*normal[i].y+normal[i].z*normal[i].z; normal[i].x /= scalar; normal[i].y /= scalar; normal[i].z /= scalar; }*/ cross.x = (fur.y*view.z)-(fur.z*view.y); cross.y = (fur.z*view.x)-(fur.x*view.z); cross.z = (fur.x*view.y)-(fur.y*view.x); //scalar = cross.x*cross.x+cross.y*cross.y+cross.z*cross.z; //cross.x /= scalar; //cross.y /= scalar; //cross.x /= scalar; k = sqrt( baseWidth*baseWidth / 4.0*(cross.x*cross.x+cross.y*cross.y+cross.z*cross.z) ); stock.x = down[i].x + k*cross.x; stock.y = down[i].y + k*cross.y; stock.z = down[i].z + k*cross.z; if( ( ( stock.x - down[i].x ) / cross.x ) >= 0.0 ) { C[i].x = stock.x; C[i].y = stock.y; C[i].z = stock.z; D[i].x = down[i].x - k*cross.x; D[i].y = down[i].y - k*cross.y; D[i].z = down[i].z - k*cross.z; } else if( ( ( stock.x - down[i].x ) / cross.x ) < 0.0 ) { C[i].x = down[i].x - k*cross.x; C[i].y = down[i].y - k*cross.y; C[i].z = down[i].z - k*cross.z; D[i].x = stock.x; D[i].y = stock.y; D[i].z = stock.z; } k = sqrt( tipWidth*tipWidth / 4.0*(cross.x*cross.x+cross.y*cross.y+cross.z*cross.z) ); stock.x = top[i].x + k*cross.x; stock.y = top[i].y + k*cross.y; stock.z = top[i].z + k*cross.z; if( ( ( stock.x - top[i].x ) / cross.x ) >= 0.0 ) { B[i].x = stock.x; B[i].y = stock.y; B[i].z = stock.z; A[i].x = top[i].x - k*cross.x; A[i].y = top[i].y - k*cross.y; A[i].z = top[i].z - k*cross.z; } else if( ( ( stock.x - top[i].x ) / cross.x ) < 0.0 ) { B[i].x = top[i].x - k*cross.x; B[i].y = top[i].y - k*cross.y; B[i].z = top[i].z - k*cross.z; A[i].x = stock.x; A[i].y = stock.y; A[i].z = stock.z; } } int numFaces = 1000; int numVertices = 4000; int numFaceConnects = 4000; int face_counts[1000]; int face_connects[4000]; for( i=0; i < 1000; i++ ) { face_counts[i] = 4; } for( i=0; i < 4000; i++ ) { face_connects[i] = i; } for( i=0; i < 1000; i++ ) { MFloatPoint vtx_1( A[i].x, A[i].y, A[i].z ); MFloatPoint vtx_2( B[i].x, B[i].y, B[i].z ); MFloatPoint vtx_3( C[i].x, C[i].y, C[i].z ); MFloatPoint vtx_4( D[i].x, D[i].y, D[i].z ); points.append( vtx_1 ); points.append( vtx_2 ); points.append( vtx_3 ); points.append( vtx_4 ); } MIntArray faceCounts( face_counts, numFaces ); MIntArray faceConnects( face_connects, numFaceConnects ); MObject newMesh = meshFS.create( numVertices, numFaces, points, faceCounts, faceConnects, outData, &status ); return newMesh; } MStatus furRender::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; if( plug == outputMesh ) { cout << "In furRender::compute" << endl; MDataHandle timeData = data.inputValue( time, &status ); if( status != MS::kSuccess ) { cerr << "ERROR getting time data handle" << endl; } MTime time = timeData.asTime(); MDataHandle outputHandle = data.outputValue( outputMesh, &status ); if( status != MS::kSuccess ) { cerr << "ERROR getting polygon dataHandle" << endl; return status; } MFnMeshData dataCreator; MObject newOutputData = dataCreator.create( &status ); if( status != MS::kSuccess ) { cerr << "ERROR creating outputData" << endl; return status; } MObject newMesh = createMesh( time, newOutputData, status ); if( status != MS::kSuccess ) { cerr << "ERROR creating new Mesh" << endl; } outputHandle.set(newOutputData); data.setClean( plug ); } else { return MS::kUnknownParameter; } return MS::kSuccess; } class scanDag: public MPxCommand { public: scanDag() {}; virtual ~scanDag(); static void* creator(); virtual MStatus doIt( const MArgList& ); private: MStatus parseArgs( const MArgList& args, MItDag::TraversalType& traversalType, MFn::Type& filter, bool & quiet); MStatus doScan( const MItDag::TraversalType traversalType, MFn::Type filter, bool quiet); void printTransformData(const MDagPath& dagPath, bool quiet); }; scanDag::~scanDag() {} void* scanDag::creator() { return new scanDag; } MStatus scanDag::doIt( const MArgList& args ) { MItDag::TraversalType traversalType = MItDag::kDepthFirst; MFn::Type filter = MFn::kInvalid; MStatus status; bool quiet = false; status = parseArgs ( args, traversalType, filter, quiet ); if (!status) return status; return doScan( traversalType, filter, quiet); }; MStatus scanDag::parseArgs( const MArgList& args, MItDag::TraversalType& traversalType, MFn::Type& filter, bool & quiet) { MStatus stat; MString arg; const MString breadthFlag ("-b"); const MString breadthFlagLong ("-breadthFirst"); const MString depthFlag ("-d"); const MString depthFlagLong ("-depthFirst"); const MString cameraFlag ("-c"); const MString cameraFlagLong ("-cameras"); const MString lightFlag ("-l"); const MString lightFlagLong ("-lights"); const MString nurbsSurfaceFlag ("-n"); const MString nurbsSurfaceFlagLong ("-nurbsSurfaces"); const MString quietFlag ("-q"); const MString quietFlagLong ("-quiet"); // Parse the arguments. for ( size_t i = 0; i < args.length(); i++ ) { arg = args.asString( i, &stat ); if (!stat) continue; if ( arg == breadthFlag || arg == breadthFlagLong ) traversalType = MItDag::kBreadthFirst; else if ( arg == depthFlag || arg == depthFlagLong ) traversalType = MItDag::kDepthFirst; else if ( arg == cameraFlag || arg == cameraFlagLong ) filter = MFn::kCamera; else if ( arg == lightFlag || arg == lightFlagLong ) filter = MFn::kLight; else if ( arg == nurbsSurfaceFlag || arg == nurbsSurfaceFlagLong ) filter = MFn::kNurbsSurface; else if ( arg == quietFlag || arg == quietFlagLong ) quiet = true; else { arg += ": unknown argument"; displayError(arg); return MS::kFailure; } } return stat; } MStatus scanDag::doScan( const MItDag::TraversalType traversalType, MFn::Type filter, bool quiet) { MStatus status; MItDag dagIterator( traversalType, filter, &status); if ( !status) { status.perror("MItDag constructor"); return status; } // Scan the entire DAG and output the name and depth of each node if (traversalType == MItDag::kBreadthFirst) if (!quiet) cout << endl << "Starting Breadth First scan of the Dag"; else if (!quiet) cout << endl << "Starting Depth First scan of the Dag"; switch (filter) { case MFn::kCamera: if (!quiet) cout << ": Filtering for Cameras\n"; break; case MFn::kLight: if (!quiet) cout << ": Filtering for Lights\n"; break; case MFn::kNurbsSurface: if (!quiet) cout << ": Filtering for Nurbs Surfaces\n"; break; default: cout << endl; } int objectCount = 0; for ( ; !dagIterator.isDone(); dagIterator.next() ) { MDagPath dagPath; status = dagIterator.getPath(dagPath); if ( !status ) { status.perror("MItDag::getPath"); continue; } MFnDagNode dagNode(dagPath, &status); if ( !status ) { status.perror("MFnDagNode constructor"); continue; } if (!quiet) cout << dagNode.name() << ": " << dagNode.typeName() << endl; if (!quiet) cout << " dagPath: " << dagPath.fullPathName() << endl; objectCount += 1; if (dagPath.hasFn(MFn::kCamera)) { MFnCamera camera (dagPath, &status); if ( !status ) { status.perror("MFnCamera constructor"); continue; } // Get the translation/rotation/scale data printTransformData(dagPath, quiet); // Extract some interesting Camera data if (!quiet) { cout << " eyePoint: " << camera.eyePoint(MSpace::kWorld) << endl; cout << " upDirection: " << camera.upDirection(MSpace::kWorld) << endl; upDirection = camera.upDirection(MSpace::kWorld); cout << " viewDirection: " << camera.viewDirection(MSpace::kWorld) << endl; viewDirection = camera.viewDirection(MSpace::kWorld); cout << " aspectRatio: " << camera.aspectRatio() << endl; cout << " horizontalFilmAperture: " << camera.horizontalFilmAperture() << endl; cout << " verticalFilmAperture: " << camera.verticalFilmAperture() << endl; } } else if (dagPath.hasFn(MFn::kLight)) { MFnLight light (dagPath, &status); if ( !status ) { status.perror("MFnLight constructor"); continue; } // Get the translation/rotation/scale data printTransformData(dagPath, quiet); // Extract some interesting Light data MColor color; color = light.color(); if (!quiet) { cout << " color: [" << color.r << ", " << color.g << ", " << color.b << "]\n"; } color = light.shadowColor(); if (!quiet) { cout << " shadowColor: [" << color.r << ", " << color.g << ", " << color.b << "]\n"; cout << " intensity: " << light.intensity() << endl; } } else if (dagPath.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface surface (dagPath, &status); if ( !status ) { status.perror("MFnNurbsSurface constructor"); continue; } // Get the translation/rotation/scale data printTransformData(dagPath, quiet); // Extract some interesting Surface data if (!quiet) { cout << " numCVs: " << surface.numCVsInU() << " * " << surface.numCVsInV() << endl; cout << " numKnots: " << surface.numKnotsInU() << " * " << surface.numKnotsInV() << endl; cout << " numSpans: " << surface.numSpansInU() << " * " << surface.numSpansInV() << endl; } } else { // Get the translation/rotation/scale data printTransformData(dagPath, quiet); } } if (!quiet) { cout.flush(); } setResult(objectCount); return MS::kSuccess; } void scanDag::printTransformData(const MDagPath& dagPath, bool quiet) { MStatus status; MObject transformNode = dagPath.transform(&status); // This node has no transform - i.e., it's the world node if (!status && status.statusCode () == MStatus::kInvalidParameter) return; MFnDagNode transform (transformNode, &status); if (!status) { status.perror("MFnDagNode constructor"); return; } MTransformationMatrix matrix (transform.transformationMatrix()); if (!quiet) { cout << " translation: " << matrix.translation(MSpace::kWorld) << endl; } double threeDoubles[3]; MTransformationMatrix::RotationOrder rOrder; matrix.getRotation (threeDoubles, rOrder, MSpace::kWorld); if (!quiet) { cout << " rotation: [" << threeDoubles[0] << ", " << threeDoubles[1] << ", " << threeDoubles[2] << "]\n"; } matrix.getScale (threeDoubles, MSpace::kWorld); if (!quiet) { cout << " scale: [" << threeDoubles[0] << ", " << threeDoubles[1] << ", " << threeDoubles[2] << "]\n"; } } MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, "Yosiyuki Nisino", "1.0", "Any" ); status = plugin.registerCommand( "scanDag", scanDag::creator ); status = plugin.registerNode( "furRender", furRender::id, furRender::creator, furRender::initialize ); status = plugin.registerShape( "furFeedbackShape", furFeedbackShape::id, &furFeedbackShape::creator, &furFeedbackShape::initialize, &furFeedbackShapeUI::creator ); return status; } MStatus uninitializePlugin( MObject obj) { MStatus status; MFnPlugin plugin( obj ); status = plugin.deregisterCommand( "scanDag" ); status = plugin.deregisterNode( furRender::id ); status = plugin.deregisterNode( furFeedbackShape::id ); return status; }