// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include #include #include #include #include #include #include #include "shaveGlobals.h" #include "shaveHairShape.h" #include "shaveRender.h" #include "shaveRenderCmd.h" #include "shaveUtil.h" #if defined(OSMac_) #include "shaveMacCarbon.h" #endif const MString shaveRenderCmd::commandName("shaveRender"); static const char* kCreateDRAFileLong = "-createDRAFile"; static const char* kCreateDRAFileShort = "-cdf"; static const char* kExportEndLong = "-exportEnd"; static const char* kExportEndShort = "-ee"; static const char* kExportStartLong = "-exportStart"; static const char* kExportStartShort = "-es"; static const char* kOcclusionsLong = "-occlusionsInDRA"; static const char* kOcclusionsShort = "-occ"; static const char* kRenderStartLong = "-renderStart"; static const char* kRenderStartShort = "-rs"; static const char* kRenderEndLong = "-renderEnd"; static const char* kRenderEndShort = "-re"; static const char* kFrameStartLong = "-frameStart"; static const char* kFrameStartShort = "-fs"; static const char* kFrameEndLong = "-frameEnd"; static const char* kFrameEndShort = "-fe"; static const char* kSwatchLong = "-swatch"; static const char* kSwatchShort = "-sw"; static const char* kTargetRendererLong = "-targetRenderer"; static const char* kTargetRendererShort= "-tr"; //static const char* kShutterOpenLong = "-shutterOpen"; //static const char* kShutterOpenShort = "-so"; // //static const char* kShutterCloseLong = "-shutterClose"; //static const char* kShutterCloseShort = "-sc"; // //static const char* kShutterExportLong = "-shutterExport"; //static const char* kShutterExportShort = "-se"; static const char* kVrayKeyframeLong = "-vrayKeyframe"; static const char* kVrayKeyframeShort = "-vr"; shaveRenderCmd::shaveRenderCmd() {} shaveRenderCmd::~shaveRenderCmd() {} void* shaveRenderCmd::createCmd() { return new shaveRenderCmd(); } MSyntax shaveRenderCmd::createSyntax() { MSyntax syntax; syntax.enableEdit(false); syntax.enableQuery(true); syntax.addFlag(kCreateDRAFileShort, kCreateDRAFileLong, MSyntax::kString); syntax.addFlag(kExportEndShort, kExportEndLong); syntax.addFlag(kExportStartShort, kExportStartLong, MSyntax::kString); syntax.addFlag(kFrameEndShort, kFrameEndLong); syntax.addFlag(kFrameStartShort, kFrameStartLong); syntax.addFlag(kOcclusionsShort, kOcclusionsLong); syntax.addFlag(kRenderEndShort, kRenderEndLong); syntax.addFlag(kRenderStartShort, kRenderStartLong); syntax.addFlag(kTargetRendererShort, kTargetRendererLong, MSyntax::kUnsigned); syntax.addFlag( kSwatchShort, kSwatchLong, MSyntax::kString, MSyntax::kUnsigned, MSyntax::kString ); //syntax.addFlag(kShutterOpenShort, kShutterOpenLong); //syntax.addFlag(kShutterCloseShort,kShutterCloseLong); //syntax.addFlag(kShutterExportShort,kShutterExportLong, MSyntax::kString); syntax.addFlag(kVrayKeyframeShort, kVrayKeyframeLong); return syntax; } MStatus shaveRenderCmd::doIt(const MArgList& argList) { MStatus status; MArgDatabase args(syntax(), argList, &status); if (!status) return status; // // Make sure that one, and only one, flag has been specified. // MStringArray flags; if (args.isFlagSet(kCreateDRAFileShort)) flags.append(kCreateDRAFileLong); if (args.isFlagSet(kRenderStartShort)) flags.append(kRenderStartLong); if (args.isFlagSet(kRenderEndShort)) flags.append(kRenderEndLong); if (args.isFlagSet(kExportStartShort)) flags.append(kExportStartLong); if (args.isFlagSet(kExportEndShort)) flags.append(kExportEndLong); if (args.isFlagSet(kFrameStartShort)) flags.append(kFrameStartLong); if (args.isFlagSet(kFrameEndShort)) flags.append(kFrameEndLong); if (args.isFlagSet(kSwatchShort)) flags.append(kSwatchLong); //if (args.isFlagSet(kShutterOpenShort)) flags.append(kShutterOpenLong); //if (args.isFlagSet(kShutterCloseShort)) flags.append(kShutterCloseLong); //if (args.isFlagSet(kShutterExportShort)) flags.append(kShutterExportLong); if (args.isFlagSet(kVrayKeyframeShort)) flags.append(kVrayKeyframeLong); if (flags.length() == 0) { MGlobal::displayError( commandName + ": no flags specified. Nothing to do." ); return MS::kNotFound; } else if (flags.length() > 1) { MGlobal::displayError( commandName + ": the '" + flags[0] + "' and '" + flags[1] + "' flags cannot be used together on the same command." ); return MS::kInvalidParameter; } SHAVE_RENDER_HOST renderHost = kShaveHostPRMAN; if (args.isFlagSet(kTargetRendererShort)) { int val; args.getFlagArgument(kTargetRendererShort, 0, val); switch ((SHAVE_RENDER_HOST)val) { case kShaveHostPRMAN: case kShaveHostBuffer: renderHost = (SHAVE_RENDER_HOST)val; break; default: displayError( commandName + ": invalid value for '" + kTargetRendererLong + "' flag. Must be one of " + kShaveHostPRMAN + " (PRMAN), " + kShaveHostBuffer + " (buffer)." ); return MS::kInvalidParameter; break; } } shaveGlobals::getGlobals(); // // I used to enclose all the 'kRender*' flags in a test such that these // commands would only be honoured during a render or export. // However, some render cleanup code runs on an idle event // and by the time it gets around to running, the flags telling us // whether we're doing a render or export might no longer be set. // So it's better to always honour these commands and rely on the // callers to only call them when it's appropriate. // if (args.isFlagSet(kRenderStartShort)) shaveRender::renderStart(NULL); else if (args.isFlagSet(kRenderEndShort)) shaveRender::renderEnd(NULL); else if (args.isFlagSet(kExportStartShort)) { MString exportFile; args.getFlagArgument(kExportStartShort, 0, exportFile); shaveRender::exportStart(exportFile); } else if (args.isFlagSet(kExportEndShort)) shaveRender::exportEnd(); else if (args.isFlagSet(kFrameStartShort)) shaveRender::frameStart(NULL); else if (args.isFlagSet(kFrameEndShort)) shaveRender::frameEnd(NULL); else if (args.isFlagSet(kSwatchShort)) { MString shaveHairShapeName; args.getFlagArgument(kSwatchShort, 0, shaveHairShapeName); MSelectionList list; list.add(shaveHairShapeName); MObject shaveHairShape; list.getDependNode(0, shaveHairShape); if (shaveHairShape.isNull()) { MGlobal::displayError( MString("shaveRender: '") + shaveHairShapeName + "' is not a shave hair node." ); return MS::kInvalidParameter; } MFnDependencyNode nodeFn(shaveHairShape); if (nodeFn.typeId() != shaveHairShape::id) { MGlobal::displayError( MString("shaveRender: '") + shaveHairShapeName + "' is not a shave hair node." ); return MS::kInvalidParameter; } unsigned int resolution; args.getFlagArgument(kSwatchShort, 1, resolution); if (resolution == 0) { MGlobal::displayError( "shaveRender: resolution of swatch must greater than zero." ); return MS::kInvalidParameter; } MString fileName; args.getFlagArgument(kSwatchShort, 2, fileName); #if defined(OSMac_) && !defined(OSMac_MachO_) // // The filename will be coming to us in standard POSIX form // (e.g. "/path/to/file"), but since this is the CFM version of // Maya on OSX then we need to convert that to an HSF filename. // fileName = shaveMacCarbon::makeMacFilename(fileName); #endif status = shaveRender::renderSwatch(shaveHairShape, resolution, fileName); if (!status) { MGlobal::displayError( MString("shaveRender: error rendering swatch to '") + fileName + "'." ); } } else if (args.isFlagSet(kCreateDRAFileShort)) { MString fileName; args.getFlagArgument(kCreateDRAFileShort, 0, fileName); bool includeOcclusions = args.isFlagSet(kOcclusionsShort); #if defined(OSMac_) && !defined(OSMac_MachO_) // // The filename will be coming to us in standard POSIX form // (e.g. "/path/to/file"), but since this is the CFM version of // Maya on OSX then we need to convert that to an HSF filename. // fileName = shaveMacCarbon::makeMacFilename(fileName); #endif MGlobal::displayInfo(MString("exporting hair to '") + fileName + "'."); status = shaveRender::renderToDRAFile( renderHost, fileName, voxelResolutionGlob, includeOcclusions ); if (status == MS::kNotFound) { MGlobal::displayError( commandName + ": no renderable shaveHairShapes in scene," + " no hair file generated." ); } } //else if(args.isFlagSet(kShutterOpenShort)) //{ // shaveRender::shutterOpen(); //} //else if(args.isFlagSet(kShutterCloseShort)) //{ // shaveRender::shutterClose(); //} //else if(args.isFlagSet(kShutterExportShort)) //{ // MString fileName; // args.getFlagArgument(kShutterExportShort, 0, fileName); // shaveRender::shutterExport(fileName); //} else if(args.isFlagSet(kVrayKeyframeShort)) { shaveRender::vrayKeyFrame(); } return status; }