//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ //////////////////////////////////////////////////////////////////////// // // fluidInfoCmd // // Demonstrates the use of the MFnFluid class for retrieving // fluid information. The resolution, size and data methods // are printed to the script editor, followed by grid data for // those fluid attributes with grids. If $maxVoxelsToPrint // is not specified, it will print all of them. This might take // a VERY long time. // // Syntax: // fluidInfo $fluidNodeName $maxVoxelsToPrint; // // Example: // fluidInfo fluidShape2 10; // fluidInfo fluidShape2; // //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define mCommandName "fluidInfo" // Command name class fluidInfoCmd : public MPxCommand { public: fluidInfoCmd(); virtual ~fluidInfoCmd(); virtual MStatus doIt ( const MArgList& args ); static void* creator(); private: static MStatus nodeFromName(MString name, MObject & obj); MStatus fluidMethodName(MFnFluid::FluidMethod method, char *methodStr); MStatus colorMethodName(MFnFluid::ColorMethod method, char *methodStr); MStatus coordMethodName(MFnFluid::CoordinateMethod method, char *methodStr); MStatus falloffMethodName(MFnFluid::FalloffMethod method, char *methodStr); MStatus fluidGradientName(MFnFluid::FluidGradient gradient, char *gradientStr); MStatus parseArgs ( const MArgList& args ); MString fluidName; MObject fluidNode; int requestedVoxels; }; fluidInfoCmd::fluidInfoCmd() { } fluidInfoCmd::~fluidInfoCmd() { } // // /////////////////////////////////////////////////////////////////////////////// MStatus fluidInfoCmd::nodeFromName(MString name, MObject & obj) { MSelectionList tempList; tempList.add( name ); if ( tempList.length() > 0 ) { tempList.getDependNode( 0, obj ); return MS::kSuccess; } return MS::kFailure; } MStatus fluidInfoCmd::fluidMethodName(MFnFluid::FluidMethod method, char *methodStr) { MStatus stat = MS::kSuccess; if(!methodStr) { stat = MS::kFailure; } else { switch( method ) { case MFnFluid::kZero: strcpy(methodStr, "Zero"); break; case MFnFluid::kStaticGrid: strcpy(methodStr, "Static Grid"); break; case MFnFluid::kDynamicGrid: strcpy(methodStr, "Dynamic Grid"); break; case MFnFluid::kGradient: strcpy(methodStr, "Gradient"); break; default: strcpy(methodStr, "Garbage"); break; } } return stat; } MStatus fluidInfoCmd::falloffMethodName(MFnFluid::FalloffMethod method, char *methodStr) { MStatus stat = MS::kSuccess; if(!methodStr) { stat = MS::kFailure; } else { switch( method ) { case MFnFluid::kNoFalloffGrid: strcpy(methodStr, "No Falloff Grid"); break; case MFnFluid::kStaticFalloffGrid: strcpy(methodStr, "Static Grid"); break; default: strcpy(methodStr, "Garbage"); break; } } return stat; } MStatus fluidInfoCmd::colorMethodName(MFnFluid::ColorMethod method, char *methodStr) { MStatus stat = MS::kSuccess; if(!methodStr) { stat = MS::kFailure; } else { switch( method ) { case MFnFluid::kUseShadingColor: strcpy(methodStr, "Shading Color"); break; case MFnFluid::kStaticColorGrid: strcpy(methodStr, "Static Grid"); break; case MFnFluid::kDynamicColorGrid: strcpy(methodStr, "Dynamic Grid"); break; default: strcpy(methodStr, "Garbage"); break; } } return stat; } MStatus fluidInfoCmd::coordMethodName(MFnFluid::CoordinateMethod method, char *methodStr) { MStatus stat = MS::kSuccess; if(!methodStr) { stat = MS::kFailure; } else { switch( method ) { case MFnFluid::kFixed: strcpy(methodStr, "Fixed"); break; case MFnFluid::kGrid: strcpy(methodStr, "Grid"); break; default: strcpy(methodStr, "Garbage"); break; } } return stat; } MStatus fluidInfoCmd::fluidGradientName(MFnFluid::FluidGradient gradient, char *gradientStr) { MStatus stat = MS::kSuccess; if(!gradientStr) { stat = MS::kFailure; } else { switch( gradient ) { case MFnFluid::kConstant: strcpy(gradientStr, " Constant"); break; case MFnFluid::kXGradient: strcpy(gradientStr, "X Gradient"); break; case MFnFluid::kYGradient: strcpy(gradientStr, "Y Gradient"); break; case MFnFluid::kZGradient: strcpy(gradientStr, "Z Gradient"); break; case MFnFluid::kNegXGradient: strcpy(gradientStr, "Negative X Gradient"); break; case MFnFluid::kNegYGradient: strcpy(gradientStr, "Negative Y Gradient"); break; case MFnFluid::kNegZGradient: strcpy(gradientStr, "Negative Z Gradient"); break; case MFnFluid::kCenterGradient: strcpy(gradientStr, "Center Gradient"); break; default: strcpy(gradientStr, "Garbage"); break; } } return stat; } MStatus fluidInfoCmd::parseArgs( const MArgList& args ) { // Parse the arguments. MStatus stat = MS::kSuccess; // some defaults for the number of voxels we might want to print requestedVoxels = -1; if( args.length() < 1 ) { MGlobal::displayError( "Missing fluid node name argument." ); return MS::kFailure; } else if( args.length() > 2 ) { MGlobal::displayError( "Too many arguments." ); return MS::kFailure; } fluidName = args.asString( 0, &stat ); if (stat != MS::kSuccess) { MGlobal::displayError( "Failed to parse fluid node name argument." ); return MS::kFailure; } if(args.length() == 1) { // assume that the user wants to print all the voxels // they probably won't do this more than once requestedVoxels = -1; } else { requestedVoxels = args.asInt( 1, &stat ); if (stat != MS::kSuccess) { MGlobal::displayError( "Failed to parse num voxels to pribt argument." ); return MS::kFailure; } } nodeFromName( fluidName, fluidNode ); if( fluidNode.isNull() ) { MGlobal::displayError( "There is no fluid node with the given name." ); return MS::kFailure; } if( ! fluidNode.hasFn( MFn::kFluid ) ) { MGlobal::displayError( "The named node is not a fluid." ); return MS::kFailure; } return MS::kSuccess; } // // Main routine /////////////////////////////////////////////////////////////////////////////// MStatus fluidInfoCmd::doIt( const MArgList& args ) { MStatus stat = parseArgs( args ); if( stat != MS::kSuccess ) { return stat; } MFnFluid fluffy( fluidNode ); unsigned Xres, Yres, Zres; fluffy.getResolution(Xres, Yres, Zres); double Xdim, Ydim, Zdim; fluffy.getDimensions(Xdim, Ydim, Zdim); char buffer[256]; // first, the basic facts about the fluid sprintf( buffer, "Fluid: %s", fluidName.asChar()); MGlobal::displayInfo( buffer ); sprintf( buffer, "resolution %u %u %u", Xres, Yres, Zres ); MGlobal::displayInfo( buffer ); sprintf( buffer, "dimensions %g %g %g\n", Xdim, Ydim, Zdim ); MGlobal::displayInfo( buffer ); // now lets see how many voxels we want to print // definitely not more than the number of voxels int numPrintVoxels = requestedVoxels; if(requestedVoxels < 0 || requestedVoxels > (int)fluffy.gridSize()) { numPrintVoxels = fluffy.gridSize(); } // get the object space position of the first voxel/ MPoint centerPt; fluffy.voxelCenterPosition(0, 0, 0, centerPt); sprintf( buffer, "first voxel pos %g %g %g", centerPt.x, centerPt.y, centerPt.z ); MGlobal::displayInfo( buffer ); // // Print Density information // char methodName[32]; char gradientName[32]; MFnFluid::FluidMethod method = MFnFluid::kZero; MFnFluid::FluidGradient gradient = MFnFluid::kConstant; fluffy.getDensityMode(method, gradient); fluidMethodName(method, methodName); fluidGradientName(gradient, gradientName); if(method == MFnFluid::kGradient) sprintf( buffer, "Density method: %s type: %s", methodName, gradientName); else sprintf( buffer, "Density method: %s ", methodName); MGlobal::displayInfo( buffer ); if(method == MFnFluid::kStaticGrid || method == MFnFluid::kDynamicGrid) { float *densityGrid = fluffy.density(); if(densityGrid != NULL) { sprintf( buffer, "Density grid contents:"); MGlobal::displayInfo( buffer ); int xi, yi, zi; for(int i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] density: %g", i, xi, yi, zi, densityGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Temperature information // fluffy.getTemperatureMode(method, gradient); fluidMethodName(method, methodName); fluidGradientName(gradient, gradientName); if(method == MFnFluid::kGradient) sprintf( buffer, "Temperature method: %s type: %s", methodName, gradientName); else sprintf( buffer, "Temperature method: %s ", methodName); MGlobal::displayInfo( buffer ); if(method == MFnFluid::kStaticGrid || method == MFnFluid::kDynamicGrid) { float *tempGrid = fluffy.temperature(); if(tempGrid != NULL) { sprintf( buffer, "Tempereature grid contents:"); MGlobal::displayInfo( buffer ); int xi, yi, zi; for(int i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] temperature: %g", i, xi, yi, zi, tempGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Fuel information // fluffy.getFuelMode(method, gradient); fluidMethodName(method, methodName); fluidGradientName(gradient, gradientName); if(method == MFnFluid::kGradient) sprintf( buffer, "Fuel method: %s type: %s", methodName, gradientName); else sprintf( buffer, "Fuel method: %s ", methodName); MGlobal::displayInfo( buffer ); if(method == MFnFluid::kStaticGrid || method == MFnFluid::kDynamicGrid) { float *fuelGrid = fluffy.fuel(); if(fuelGrid != NULL) { sprintf( buffer, "Fuel grid contents:"); MGlobal::displayInfo( buffer ); int xi, yi, zi; for(int i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] fuel: %g", i, xi, yi, zi, fuelGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Velocity information // Note the difference in the velocity grid sizes // fluffy.getVelocityMode(method, gradient); fluidMethodName(method, methodName); fluidGradientName(gradient, gradientName); if(method == MFnFluid::kGradient) sprintf( buffer, "Velocity method: %s type: %s", methodName, gradientName); else sprintf( buffer, "Velocity method: %s ", methodName); MGlobal::displayInfo( buffer ); if(method == MFnFluid::kStaticGrid || method == MFnFluid::kDynamicGrid) { float *xvelGrid; float *yvelGrid; float *zvelGrid; fluffy.getVelocity(xvelGrid, yvelGrid, zvelGrid); if(xvelGrid && yvelGrid && zvelGrid) { int i; int xi, yi, zi; float xvel, yvel, zvel; // print out the X velocity grid, with its own grid indices int xvSize, yvSize, zvSize; fluffy.velocityGridSizes(xvSize, yvSize, zvSize); int numXvelVoxels = requestedVoxels; if(requestedVoxels < 0 || requestedVoxels > xvSize) { numXvelVoxels = xvSize; } sprintf( buffer, "X velocity grid contents:"); MGlobal::displayInfo( buffer ); for(i = 0; i < numXvelVoxels; i++) { fluffy.index(i, Xres+1, Yres, Zres, xi, yi, zi); sprintf(buffer, "index: %d voxel face: [%d %d %d] x velocity: %g", i, xi, yi, zi, xvelGrid[i]); MGlobal::displayInfo( buffer ); } // print out the average velocity at the voxel centers sprintf( buffer, "Voxel Center Velocity:"); MGlobal::displayInfo( buffer ); int viLow, viHigh; for(i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); viLow = fluffy.index(xi, yi, zi, Xres+1, Yres, Zres); viHigh = fluffy.index(xi+1, yi, zi, Xres+1, Yres, Zres); xvel = (xvelGrid[viHigh] + xvelGrid[viLow])/2.0f; viLow = fluffy.index(xi, yi, zi, Xres, Yres+1, Zres); viHigh = fluffy.index(xi, yi+1, zi, Xres, Yres+1, Zres); yvel = (yvelGrid[viHigh] + yvelGrid[viLow])/2.0f; viLow = fluffy.index(xi, yi, zi, Xres, Yres, Zres+1); viHigh = fluffy.index(xi, yi, zi+1, Xres, Yres, Zres+1); zvel = (zvelGrid[viHigh] + zvelGrid[viLow])/2.0f; sprintf(buffer, "index: %d voxel: [%d %d %d] velocity: (%g, %g, %g)", i, xi, yi, zi, xvel, yvel, zvel); MGlobal::displayInfo( buffer ); } } float *pressureGrid = fluffy.pressure(); if(pressureGrid != NULL) { sprintf( buffer, "Pressure grid contents:"); MGlobal::displayInfo( buffer ); int xi, yi, zi; for(int i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] pressure: %g", i, xi, yi, zi, pressureGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Texture Coordinate information // MFnFluid::CoordinateMethod coordMethod = MFnFluid::kFixed ; fluffy.getCoordinateMode(coordMethod); coordMethodName(coordMethod, methodName); sprintf( buffer, "Coordinate method: %s ", methodName); MGlobal::displayInfo( buffer ); if(coordMethod == MFnFluid::kGrid) { float *uGrid; float *vGrid; float *wGrid; fluffy.getCoordinates(uGrid, vGrid, wGrid); if(uGrid && vGrid && wGrid) { int xi, yi, zi; // print out the 3D texture coordinates int i; sprintf( buffer, "Tex Coord grid contents:"); MGlobal::displayInfo( buffer ); for(i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] uvw: (%g, %g, %g)", i, xi, yi, zi, uGrid[i], vGrid[i], wGrid[i]); MGlobal::displayInfo( buffer ); } } else if(uGrid && vGrid && (Zres == 1)) { int xi, yi, zi; // this is a 2D fluid and there are only 2D texture coordinates int i; sprintf( buffer, "Tex Coord grid contents:"); MGlobal::displayInfo( buffer ); for(i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] uv: (%g, %g)", i, xi, yi, zi, uGrid[i], vGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Color information // MFnFluid::ColorMethod colorMethod = MFnFluid::kUseShadingColor; fluffy.getColorMode(colorMethod); colorMethodName(colorMethod, methodName); sprintf( buffer, "Color method: %s ", methodName); MGlobal::displayInfo( buffer ); if(colorMethod != MFnFluid::kUseShadingColor) { float *rGrid; float *gGrid; float *bGrid; fluffy.getColors(rGrid, gGrid, bGrid); if(rGrid && gGrid && bGrid) { int xi, yi, zi; int i; sprintf( buffer, "Color grid contents:"); MGlobal::displayInfo( buffer ); for(i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] color: (%g, %g, %g)", i, xi, yi, zi, rGrid[i], gGrid[i], bGrid[i]); MGlobal::displayInfo( buffer ); } } } // // Print Falloff information // MFnFluid::FalloffMethod falloffMethod; fluffy.getFalloffMode(falloffMethod); falloffMethodName(falloffMethod, methodName); sprintf( buffer, "Falloff method: %s ", methodName); MGlobal::displayInfo( buffer ); if(falloffMethod == MFnFluid::kNoFalloffGrid ) { float *falloffGrid = fluffy.falloff(); if(falloffGrid != NULL) { sprintf( buffer, "Falloff grid contents:"); MGlobal::displayInfo( buffer ); int xi, yi, zi; for(int i = 0; i < numPrintVoxels; i++) { fluffy.index(i, xi, yi, zi); sprintf(buffer, "index: %d voxel: [%d %d %d] falloff: %g", i, xi, yi, zi, falloffGrid[i]); MGlobal::displayInfo( buffer ); } } } return MS::kSuccess; } // // /////////////////////////////////////////////////////////////////////////////// void * fluidInfoCmd::creator() { return new fluidInfoCmd(); } MStatus initializePlugin( MObject obj ) { MFnPlugin plugin( obj, PLUGIN_COMPANY, "6.0", "Any"); MStatus status = plugin.registerCommand(mCommandName, fluidInfoCmd::creator ); if (!status) status.perror("registerCommand"); return status; } MStatus uninitializePlugin( MObject obj ) { MFnPlugin plugin( obj ); MStatus status = plugin.deregisterCommand(mCommandName); if (!status) status.perror("deregisterCommand"); return status; }