MStatus boingRbCmd::createRigidBody(collision_shape_t::pointer collision_shape, MObject node, MString name, MVector vel, MVector pos, MVector rot) { //MGlobal::getActiveSelectionList(m_undoSelectionList); if (!name.length()) { name = "dRigidBody"; } double mscale[3] = {1,1,1}; MQuaternion mrotation = MEulerRotation(rot).asQuaternion(); //collision_shape_t::pointer collision_shape; if(!collision_shape) { //not connected to a collision shape, put a default one collision_shape = solver_t::create_sphere_shape(); } else { if ( rot == MVector::zero || pos == MVector::zero ) { MFnDagNode fnDagNode(node); //cout<<"node : "<<fnDagNode.partialPathName()<<endl; MFnTransform fnTransform(fnDagNode.parent(0)); //cout<<"MFnTransform node : "<<fnTransform.partialPathName()<<endl; pos = fnTransform.getTranslation(MSpace::kTransform); fnTransform.getRotation(mrotation, MSpace::kTransform); fnTransform.getScale(mscale); } } //cout<<"removing m_rigid_body"<<endl; //solver_t::remove_rigid_body(m_rigid_body); cout<<"register name : "<<name<<endl; shared_ptr<solver_impl_t> solv = solver_t::get_solver(); rigid_body_t::pointer m_rigid_body = solver_t::create_rigid_body(collision_shape); solver_t::add_rigid_body(m_rigid_body, name.asChar()); //cout<<"transform : "<<pos<<endl; //cout<<"rotation : "<<rot<<endl; //cout<<"velocity : "<<vel<<endl; //m_rigid_body->collision_shape()->set_user_pointer(name); //const rigid_body_impl_t* rb = static_cast<const rigid_body_impl_t*>(m_rigid_body.get()); const rigid_body_impl_t* rb = m_rigid_body->impl(); //rigidBodyNode *rbNode = static_cast<rigidBodyNode*>(rb->get()); //rb->register_name(solv.get(),rbNode->name().asChar()); solv->register_name(rb, name.asChar()); m_rigid_body->set_transform(vec3f((float)pos.x, (float)pos.y, (float)pos.z), quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z)); m_rigid_body->collision_shape()->set_scale(vec3f((float)mscale[0], (float)mscale[1], (float)mscale[2])); float mass = 1.f; //MPlug(thisObject, rigidBodyNode::ia_mass).getValue(mass); /* float curMass = m_rigid_body->get_mass(); bool changedMassStatus= false; if ((curMass > 0.f) != (mass > 0.f)) { changedMassStatus = true; } if (changedMassStatus) solver_t::remove_rigid_body(m_rigid_body); */ m_rigid_body->set_mass(mass); m_rigid_body->set_inertia((float)mass * m_rigid_body->collision_shape()->local_inertia()); //if (changedMassStatus) // solver_t::add_rigid_body(m_rigid_body, name.asChar()); //initialize those default values too float restitution = 0.3f; //MPlug(thisObject, rigidBodyNode::ia_restitution).getValue(restitution); m_rigid_body->set_restitution(restitution); float friction = 0.5f; //MPlug(thisObject, rigidBodyNode::ia_friction).getValue(friction); m_rigid_body->set_friction(friction); float linDamp = 0.f; //MPlug(thisObject, rigidBodyNode::ia_linearDamping).getValue(linDamp); m_rigid_body->set_linear_damping(linDamp); float angDamp = 0.2f; //MPlug(thisObject, rigidBodyNode::ia_angularDamping).getValue(angDamp); m_rigid_body->set_angular_damping(angDamp); //shared_ptr<solver_impl_t> solv = solver_t::get_solver(); //const char *namePtr = solv->m_nameMap.find(m_rigid_body); //const char* rbname = MySerializer::findNameForPointer(m_rigid_body); //cout<<"rbname = "<<namePtr<<endl; //solv.get()->dynamicsWorld(); return MS::kSuccess; }
//----------------------------------------------------------------------------- // Purpose: Export the specified bits of the maya scene into the specified file // Input : i_mArgDatabase The command line arguments as passed // Output : MS::kSuccess if ok, MS::kFailure otherwise //----------------------------------------------------------------------------- MStatus CVstSmdIOCmd::DoExport( const MArgDatabase &mArgDatabase ) { MString optFilename; if ( mArgDatabase.getFlagArgument( kOptFilename, 0, optFilename ) != MS::kSuccess || optFilename.length() == 0 ) { MGlobal::displayError( "No filename specified for export" ); return MS::kFailure; } MSelectionList optSelectionList; if ( GetOptSelection( mArgDatabase, optSelectionList ) != MS::kSuccess ) return MS::kFailure; const uint exportType( GetExportType( mArgDatabase ) ); const uint exportFlags( GetExportFlags( mArgDatabase ) ); const uint version( mArgDatabase.isFlagSet( kOptRelativeMaterials ) && exportType & ( CSmdExport::kModel | CSmdExport::kPhysModel | CSmdExport::kVertexAnimation ) ? 2 : 1 ); CSmdExport smdExport( exportType, exportFlags, version ); smdExport.SetNodeAddPrefix( GetNodeAddPrefix( mArgDatabase ) ); smdExport.SetNodeDelPrefix( GetNodeDelPrefix( mArgDatabase ) ); if ( exportType & CSmdExport::kAnimation ) { double fs( 0.0 ); double fe( 0.0 ); double fi( 1.0 ); GetExportFrameRange( mArgDatabase, fs, fe, fi ); smdExport.SetFrameRange( fs, fe, fi ); } MStringArray result; if ( smdExport.DoIt( optFilename, optSelectionList, result ) != MS::kSuccess ) return MS::kFailure; if ( result.length() ) { result.append( "smd" ); result.append( optFilename ); } else { result.append( MString( "Exported to " ) + optFilename ); } if ( mArgDatabase.isFlagSet( kOptQci ) ) { MString optQci; mArgDatabase.getFlagArgument( kOptQci, 0, optQci ); MSelectionList qciSelectionList; if ( mArgDatabase.isFlagSet( kOptSelection ) ) { mArgDatabase.getObjects( qciSelectionList ); } MStringArray qciResult; CQciExport qciExport; if ( qciExport.DoIt( optQci, qciSelectionList, qciResult ) && qciResult.length() ) { for ( uint i( 0 ); i != qciResult.length(); ++i ) { result.append( qciResult[ i ] ); } } } setResult( result ); return MS::kSuccess; }
// Load the file textures for the cube maps. // MStatus hwRefractReflectShader_NV20::loadTextures(const MDrawRequest& request, M3dView& view) { // Get the cube map file names // MStringArray decalNames; MString decalName; // Find the cubemap textures by tracing through the connection from the color atttribute // ShadingConnection colorConnection(thisMObject(), request.multiPath().partialPathName(), "color"); // If the color attribute is ultimately connected to a environment, // find its filenames, otherwise use the default color texture. // bool gotAllEnvironmentMaps = TRUE; if (colorConnection.type() == ShadingConnection::TEXTURE && colorConnection.texture().hasFn(MFn::kEnvCube)) { // Get the filenames of the texture. MFnDependencyNode textureNode(colorConnection.texture()); MString attributeName; MString envNames[6] = { "top", "bottom", "left", "right", "front", "back" }; // Scan for connected file textures to the environment map node // for (int i=0; i<6; i++) { ShadingConnection conn(colorConnection.texture(), request.multiPath().partialPathName(), envNames[i]); if (conn.type() == ShadingConnection::TEXTURE && conn.texture().hasFn(MFn::kFileTexture)) { MFnDependencyNode envNode(conn.texture()); MPlug filenamePlug( conn.texture(), envNode.attribute(MString("fileTextureName")) ); filenamePlug.getValue(decalName); if (decalName.length() == 0) decalName = "internalDefaultTexture"; // Append next environment map name decalNames.append( decalName ); } // If any of the environment maps are not mapped put in a fake texture else { decalName = "internalDefaultTexture"; decalNames.append( decalName ); } } } else { // Put in a fake texture for each side decalName = "internalDefaultTexture"; for (int i=0; i<6; i++) { decalNames.append( decalName ); } } // Reload cube maps if the name of the textures // for any of the cube maps changes // bool reload = FALSE; for (int i=0; i<6; i++) { if (currentTextureNames[i] != decalNames[i]) { reload = TRUE; break; } } view.beginGL(); { if ( reload ) { MString ypTexName(decalNames[0]); // y+ == top MString ynTexName(decalNames[1]); // y- == bottom MString xpTexName(decalNames[2]); // x+ == left MString xnTexName(decalNames[3]); // x- == right MString zpTexName(decalNames[4]); // z+ == front MString znTexName(decalNames[5]); // z- == back MStatus stat; if (! (stat = theImage_XP.readFromFile(xpTexName)) ) return MS::kFailure; if (! (stat = theImage_XN.readFromFile(xnTexName)) ) return MS::kFailure; if (! (stat = theImage_YP.readFromFile(ypTexName)) ) return MS::kFailure; if (! (stat = theImage_YN.readFromFile(ynTexName)) ) return MS::kFailure; if (! (stat = theImage_ZP.readFromFile(zpTexName)) ) return MS::kFailure; if (! (stat = theImage_ZN.readFromFile(znTexName)) ) return MS::kFailure; // Only create texture names the first time if (fTextureName == -1) glGenTextures(1, &fTextureName); glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName ); glEnable( GL_TEXTURE_CUBE_MAP_ARB ); // The cubeMap textures have to have the same size // unsigned int width, height; stat = theImage_XP.getSize( width, height ); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_XP.pixels() ); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_XN.pixels() ); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_YP.pixels() ); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_YN.pixels() ); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_ZP.pixels() ); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, theImage_ZN.pixels() ); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); for (i=0; i<6; i++) currentTextureNames[i] = decalNames[i]; } // stage 0 -- cubeMap texture for the refraction // glActiveTextureARB( GL_TEXTURE0_ARB ); glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName ); glEnable( GL_TEXTURE_CUBE_MAP_ARB ); // stage 1 -- cubeMap texture for the reflection // glActiveTextureARB( GL_TEXTURE1_ARB ); glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName ); glEnable( GL_TEXTURE_CUBE_MAP_ARB ); } view.endGL(); return MS::kSuccess; }
MStatus CVsDmxIOTranslator::writer( const MFileObject &i_mFileObject, const MString &i_optionsString, const FileAccessMode i_fileAccessMode ) { MString cmd( "vsDmxIO -export" ); if ( i_optionsString.length() ) { bool useTimeline( true ); double fs( MAnimControl::minTime().as( MTime::uiUnit() ) ); double fe( MAnimControl::maxTime().as( MTime::uiUnit() ) ); double fi( 1.0 ); MStringArray options; if ( !i_optionsString.split( ';', options ) ) { merr << "Can't split " << s_name << " translator arguments" << std::endl; return MS::kFailure; } for ( unsigned int oi( 0 ); oi != options.length(); ++oi ) { MStringArray keyValue; if ( options[ oi ].split( '=', keyValue ) && keyValue.length() == 2 ) { const MString &key( keyValue[ 0 ] ); const MString &val( keyValue[ 1 ] ); if ( key == "useTimeline" ) { useTimeline = val.asInt() ? true : false; continue; } if ( !useTimeline ) { if ( key == "fs" ) { fs = val.asDouble(); continue; } if ( key == "fe" ) { fe = val.asDouble(); continue; } if ( key == "fi" ) { fi = val.asDouble(); continue; } } } } if ( !useTimeline ) { if ( fs > fe ) { merr << "Invalid frame start " << fs << " > frame end " << fe << ", ignoring and using timeline" << std::endl; } else { cmd += " -time \""; cmd += fs; cmd += "-"; cmd += fe; if ( fi <= 0 ) { mwarn << "Invalid frame increment " << fi << " specified, using 1" << std::endl; } else { cmd += "x"; cmd += fi; } cmd += "\""; } } } if ( i_fileAccessMode == MPxFileTranslator::kExportActiveAccessMode ) { cmd += " -selection"; } cmd += " -filename \""; cmd += i_mFileObject.fullName(); cmd += "\";"; return MGlobal::executeCommand( cmd, true, true ); }
MStatus metro_image::open( MString pathname, MImageFileInfo* info) { if( m_image != 0 ) delete m_image; MString ext = pathname.substring( pathname.length() - 3, pathname.length() ); if( ext == MString( "512" ) ) { m_width = m_height = 512; } else if( ext == MString( "1024" ) ) { m_width = m_height = 1024; } else if( ext == MString( "2048" ) ) { m_width = m_height = 2048; } else { return MS::kNotImplemented; } const char *path = pathname.asChar(); FILE *f = fopen( path, "rb" ); assert( f ); if( f == 0 ) { return MS::kNotFound; } fseek( f, 0, SEEK_END ); size_t size = ftell( f ); fseek( f, 0, SEEK_SET ); void *src = malloc( size ); fread( src, size, 1, f ); fclose( f ); int flags; switch( size ) { case 174776: flags = squish::kDxt1; break; case 349552: flags = squish::kDxt5; break; case 524288: flags = squish::kDxt1; break; case 1048576: flags = squish::kDxt5; break; case 2097152: flags = squish::kDxt1; break; case 4194304: flags = squish::kDxt5; break; default: return MS::kNotImplemented; } m_image = new squish::u8[m_width * m_height * 4]; squish::DecompressImage( m_image, m_width, m_height, src, flags ); free( src ); if( info) { info->width( m_width ); info->height( m_height ); info->numberOfImages( 1 ); info->channels( 4 ); info->hasAlpha( true ); info->hasMipMaps( false ); info->hardwareType( MImageFileInfo::kHwTexture2D ); info->imageType( MImageFileInfo::kImageTypeColor ); info->pixelType( MImage::kByte ); } return MS::kSuccess; }
MStatus animExport::writer( const MFileObject& file, const MString& options, FileAccessMode mode) { MStatus status = MS::kFailure; MString fileName = file.fullName(); #if defined (OSMac_) char fname[MAXPATHLEN]; strcpy (fname, fileName.asChar()); ofstream animFile(fname); #else ofstream animFile(fileName.asChar()); #endif // Defaults. // MString copyFlags("copyKey -cb api -fea 1 "); int precision = kDefaultPrecision; bool nodeNames = true; bool verboseUnits = false; // Parse the options. The options syntax is in the form of // "flag=val;flag1=val;flag2=val" // MString exportFlags; if (options.length() > 0) { const MString flagPrecision("precision"); const MString flagNodeNames("nodeNames"); const MString flagVerboseUnits("verboseUnits"); const MString flagCopyKeyCmd("copyKeyCmd"); // Start parsing. // MStringArray optionList; MStringArray theOption; options.split(';', optionList); unsigned nOptions = optionList.length(); for (unsigned i = 0; i < nOptions; i++) { theOption.clear(); optionList[i].split('=', theOption); if (theOption.length() < 1) { continue; } if (theOption[0] == flagPrecision && theOption.length() > 1) { if (theOption[1].isInt()) { precision = theOption[1].asInt(); } } else if ( theOption[0] == flagNodeNames && theOption.length() > 1) { if (theOption[1].isInt()) { nodeNames = (theOption[1].asInt()) ? true : false; } } else if ( theOption[0] == flagVerboseUnits && theOption.length() > 1) { if (theOption[1].isInt()) { verboseUnits = (theOption[1].asInt()) ? true : false; } } else if ( theOption[0] == flagCopyKeyCmd && theOption.length() > 1) { // Replace any '>' characters with '"'. This is needed // since the file translator option boxes do not handle // escaped quotation marks. // const char *optStr = theOption[1].asChar(); size_t nChars = strlen(optStr); char *copyStr = new char[nChars+1]; copyStr = strcpy(copyStr, optStr); for (size_t j = 0; j < nChars; j++) { if (copyStr[j] == '>') { copyStr[j] = '"'; } } copyFlags += copyStr; delete [] copyStr; } } } // Set the precision of the ofstream. // animFile.precision(precision); status = exportSelected(animFile, copyFlags, nodeNames, verboseUnits); animFile.flush(); animFile.close(); return status; }
void liqRibData::addAdditionalSurfaceParameters( MObject node ) { LIQDEBUGPRINTF("-> scanning for additional rman surface attributes \n"); MStatus status = MS::kSuccess; unsigned i; // work out how many elements there would be in a facevarying array if a mesh or subD // faceVaryingCount is a private data member if ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) { faceVaryingCount = 0; MFnMesh fnMesh( node ); for ( uint pOn = 0; pOn < fnMesh.numPolygons(); pOn++ ) { faceVaryingCount += fnMesh.polygonVertexCount( pOn ); } } // find how many additional MFnDependencyNode nodeFn( node ); // find the attributes MStringArray floatAttributesFound = findAttributesByPrefix( "rmanF", nodeFn ); MStringArray pointAttributesFound = findAttributesByPrefix( "rmanP", nodeFn ); MStringArray vectorAttributesFound = findAttributesByPrefix( "rmanV", nodeFn ); MStringArray normalAttributesFound = findAttributesByPrefix( "rmanN", nodeFn ); MStringArray colorAttributesFound = findAttributesByPrefix( "rmanC", nodeFn ); MStringArray stringAttributesFound = findAttributesByPrefix( "rmanS", nodeFn ); if ( floatAttributesFound.length() > 0 ) { for ( i = 0; i < floatAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = floatAttributesFound[i].substring(5, floatAttributesFound[i].length()); MPlug fPlug = nodeFn.findPlug( floatAttributesFound[i] ); MObject plugObj; status = fPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kDoubleArrayData ) { MFnDoubleArrayData fnDoubleArrayData( plugObj ); MDoubleArray doubleArrayData = fnDoubleArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, doubleArrayData.length() ); for( unsigned int kk = 0; kk < doubleArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, doubleArrayData[kk] ); } if ( ( type() == MRT_NuCurve ) && ( cutString == MString( "width" ) ) ) { tokenPointerPair.setDetailType( rVarying); } else if ( ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) && ( doubleArrayData.length() == faceVaryingCount ) ) { tokenPointerPair.setDetailType( rFaceVarying); } else { tokenPointerPair.setDetailType( rVertex ); } } else { if( fPlug.isArray() ) { int nbElts = fPlug.evaluateNumElements(); float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, true, // philippe :passed as uArray, otherwise it will think it is a single float nbElts ); MPlug elementPlug; for( unsigned int kk = 0; kk < nbElts; kk++ ) { elementPlug = fPlug.elementByPhysicalIndex(kk); elementPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( kk, floatValue ); } tokenPointerPair.setDetailType( rConstant ); } else { float floatValue; tokenPointerPair.set( cutString.asChar(), rFloat, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); fPlug.getValue( floatValue ); tokenPointerPair.setTokenFloat( 0, floatValue ); tokenPointerPair.setDetailType( rConstant ); } } tokenPointerArray.push_back( tokenPointerPair ); } } if ( pointAttributesFound.length() > 0 ) { for ( i = 0; i < pointAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = pointAttributesFound[i].substring(5, pointAttributesFound[i].length()); MPlug pPlug = nodeFn.findPlug( pointAttributesFound[i] ); MObject plugObj; status = pPlug.getValue( plugObj ); if ( plugObj.apiType() == MFn::kPointArrayData ) { MFnPointArrayData fnPointArrayData( plugObj ); MPointArray pointArrayData = fnPointArrayData.array( &status ); tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, true, false, pointArrayData.length() ); if ( type() == MRT_Nurbs || type() == MRT_NuCurve ) { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z, pointArrayData[kk].w ); } } else { for ( int kk = 0; kk < pointArrayData.length(); kk++ ) { tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z ); } } tokenPointerPair.setDetailType( rVertex ); } else { // Hmmmm float ? double ? float x, y, z; tokenPointerPair.set( cutString.asChar(), rPoint, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); // Hmmm should check as for arrays if we are in nurbs mode : 4 values pPlug.child(0).getValue( x ); pPlug.child(1).getValue( y ); pPlug.child(2).getValue( z ); tokenPointerPair.setTokenFloat( 0, x, y, z ); tokenPointerPair.setDetailType( rConstant ); } tokenPointerArray.push_back( tokenPointerPair ); } } parseVectorAttributes( nodeFn, vectorAttributesFound, rVector ); parseVectorAttributes( nodeFn, normalAttributesFound, rNormal ); parseVectorAttributes( nodeFn, colorAttributesFound, rColor ); if ( stringAttributesFound.length() > 0 ) { for ( i = 0; i < stringAttributesFound.length(); i++ ) { liqTokenPointer tokenPointerPair; MString cutString = stringAttributesFound[i].substring(5, stringAttributesFound[i].length()); MPlug sPlug = nodeFn.findPlug( stringAttributesFound[i] ); MObject plugObj; status = sPlug.getValue( plugObj ); tokenPointerPair.set( cutString.asChar(), rString, ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false, false, false, 0 ); MString stringVal; sPlug.getValue( stringVal ); tokenPointerPair.setTokenString( 0, stringVal.asChar(), stringVal.length() ); tokenPointerPair.setDetailType( rConstant ); tokenPointerArray.push_back( tokenPointerPair ); } } }
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs, GetMembersMap& gmMap) : mNoNormals(iArgs.noNormals), mWriteUVs(iArgs.writeUVs), mWriteColorSets(iArgs.writeColorSets), mWriteUVSets(iArgs.writeUVSets), mIsGeometryAnimated(false), mDagPath(iDag) { MStatus status = MS::kSuccess; MFnMesh lMesh( mDagPath, &status ); if ( !status ) { MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" ); } // intermediate objects aren't translated MObject surface = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(surface)) { mIsGeometryAnimated = true; } else { iTimeIndex = 0; } std::vector<float> uvs; std::vector<Alembic::Util::uint32_t> indices; std::string uvSetName; MString name = lMesh.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); // check to see if this poly has been tagged as a SubD MPlug plug = lMesh.findPlug("SubDivisionMesh"); if ( !plug.isNull() && plug.asBool() ) { Alembic::AbcGeom::OSubD obj(iParent, name.asChar(), iTimeIndex); mSubDSchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if (mWriteUVs || mWriteUVSets) { getUVs(uvs, indices, uvSetName); if (!uvs.empty()) { if (!uvSetName.empty()) { mSubDSchema.setUVSourceName(uvSetName); } uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope ); uvSamp.setVals(Alembic::AbcGeom::V2fArraySample( (const Imath::V2f *) &uvs.front(), uvs.size() / 2)); if (!indices.empty()) { uvSamp.setIndices(Alembic::Abc::UInt32ArraySample( &indices.front(), indices.size())); } } } Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(lMesh, iArgs)) { cp = mSubDSchema.getArbGeomParams(); up = mSubDSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh, iTimeIndex, iArgs)); writeSubD(uvSamp); } else { Alembic::AbcGeom::OPolyMesh obj(iParent, name.asChar(), iTimeIndex); mPolySchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if (mWriteUVs || mWriteUVSets) { getUVs(uvs, indices, uvSetName); if (!uvs.empty()) { if (!uvSetName.empty()) { mPolySchema.setUVSourceName(uvSetName); } uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope ); uvSamp.setVals(Alembic::AbcGeom::V2fArraySample( (const Imath::V2f *) &uvs.front(), uvs.size() / 2)); if (!indices.empty()) { uvSamp.setIndices(Alembic::Abc::UInt32ArraySample( &indices.front(), indices.size())); } } } Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(lMesh, iArgs)) { cp = mPolySchema.getArbGeomParams(); up = mPolySchema.getUserProperties(); } // set the rest of the props and write to the writer node mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh, iTimeIndex, iArgs)); writePoly(uvSamp); } if (mWriteColorSets) { MStringArray colorSetNames; lMesh.getColorSetNames(colorSetNames); if (colorSetNames.length() > 0) { // Create the color sets compound prop Alembic::Abc::OCompoundProperty arbParams; if (mPolySchema.valid()) { arbParams = mPolySchema.getArbGeomParams(); } else { arbParams = mSubDSchema.getArbGeomParams(); } std::string currentColorSet = lMesh.currentColorSetName().asChar(); for (unsigned int i=0; i < colorSetNames.length(); ++i) { // Create an array property for each color set std::string colorSetPropName = colorSetNames[i].asChar(); Alembic::AbcCoreAbstract::MetaData md; if (currentColorSet == colorSetPropName) { md.set("mayaColorSet", "1"); } else { md.set("mayaColorSet", "0"); } if (lMesh.getColorRepresentation(colorSetNames[i]) == MFnMesh::kRGB) { Alembic::AbcGeom::OC3fGeomParam colorProp(arbParams, colorSetPropName, true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md); mRGBParams.push_back(colorProp); } else { Alembic::AbcGeom::OC4fGeomParam colorProp(arbParams, colorSetPropName, true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md); mRGBAParams.push_back(colorProp); } } writeColor(); } } if (mWriteUVSets) { MStringArray uvSetNames; lMesh.getUVSetNames(uvSetNames); unsigned int uvSetNamesLen = uvSetNames.length(); if (uvSetNamesLen > 1) { // Create the uv sets compound prop Alembic::Abc::OCompoundProperty arbParams; if (mPolySchema.valid()) { arbParams = mPolySchema.getArbGeomParams(); } else { arbParams = mSubDSchema.getArbGeomParams(); } MString currentUV = lMesh.currentUVSetName(); for (unsigned int i = 0; i < uvSetNamesLen; ++i) { // Create an array property for each uv set MString uvSetPropName = uvSetNames[i]; // the current UV set gets mapped to the primary UVs if (currentUV == uvSetPropName) { continue; } if (uvSetPropName.length() > 0 && lMesh.numUVs(uvSetPropName) > 0) { mUVparams.push_back(Alembic::AbcGeom::OV2fGeomParam( arbParams, uvSetPropName.asChar(), true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex)); } } writeUVSets(); } } // write out facesets if(!iArgs.writeFaceSets) return; // get the connected shading engines MObjectArray connSGObjs (getOutConnectedSG(mDagPath)); const unsigned int sgCount = connSGObjs.length(); for (unsigned int i = 0; i < sgCount; ++i) { MObject connSGObj, compObj; connSGObj = connSGObjs[i]; MFnDependencyNode fnDepNode(connSGObj); MString connSgObjName = fnDepNode.name(); // retrive the component MObject status = getSetComponents(mDagPath, connSGObj, gmMap, compObj); if (status != MS::kSuccess) { // for some reason the shading group doesn't represent a face set continue; } // retrieve the face indices MIntArray indices; MFnSingleIndexedComponent compFn; compFn.setObject(compObj); compFn.getElements(indices); const unsigned int numData = indices.length(); // encountered the whole object mapping. skip it. if (numData == 0) continue; std::vector<Alembic::Util::int32_t> faceIndices(numData); for (unsigned int j = 0; j < numData; ++j) { faceIndices[j] = indices[j]; } connSgObjName = util::stripNamespaces(connSgObjName, iArgs.stripNamespace); Alembic::AbcGeom::OFaceSet faceSet; std::string faceSetName(connSgObjName.asChar()); MPlug abcFacesetNamePlug = fnDepNode.findPlug("AbcFacesetName", true); if (!abcFacesetNamePlug.isNull()) { faceSetName = abcFacesetNamePlug.asString().asChar(); } if (mPolySchema.valid()) { if (mPolySchema.hasFaceSet(faceSetName)) { faceSet = mPolySchema.getFaceSet(faceSetName); } else { faceSet = mPolySchema.createFaceSet(faceSetName); } } else { if (mSubDSchema.hasFaceSet(faceSetName)) { faceSet = mSubDSchema.getFaceSet(faceSetName); } else { faceSet = mSubDSchema.createFaceSet(faceSetName); } } Alembic::AbcGeom::OFaceSetSchema::Sample samp; samp.setFaces(Alembic::Abc::Int32ArraySample(faceIndices)); Alembic::AbcGeom::OFaceSetSchema faceSetSchema = faceSet.getSchema(); faceSetSchema.set(samp); faceSetSchema.setFaceExclusivity(Alembic::AbcGeom::kFaceSetExclusive); MFnDependencyNode iNode(connSGObj); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(iNode, iArgs)) { cp = faceSetSchema.getArbGeomParams(); up = faceSetSchema.getUserProperties(); } AttributesWriter attrWriter(cp, up, faceSet, iNode, iTimeIndex, iArgs); attrWriter.write(); } }
void cgfxVaryingParameter::setupAttributes( cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes, CGprogram program) { // Make sure our parameter name is acceptable is a Maya attribute name MString attrName = fName; int lastDot = attrName.rindex( '.'); if( lastDot >= 0) attrName = attrName.substring( lastDot + 1, attrName.length() - 1); MString semanticName = cgGetParameterSemantic( fParameter); MString semantic(semanticName); cgGetParameterSemantic( fParameter); semantic.toUpperCase(); // Is this varying parameter packed or atomic? CGtype type = cgGetNamedUserType( program, attrName.asChar()); if( type != CG_UNKNOWN_TYPE) { // It's packed: explode the inputs into the structure elements CGcontext context = cgGetProgramContext( program); CGparameter packing = cgCreateParameter( context, type); fVertexStructure = new cgfxVaryingParameterStructure(); fVertexStructure->fLength = 0; fVertexStructure->fSize = 0; CGparameter element = cgGetFirstStructParameter( packing); while( element) { MString elementName = cgGetParameterName( element); int lastDot = elementName.rindex( '.'); if( lastDot >= 0) elementName = elementName.substring( lastDot + 1, elementName.length() - 1); cgfxRCPtr<cgfxVertexAttribute> attr = setupAttribute( elementName, semantic, element, vertexAttributes); fVertexStructure->fElements[ fVertexStructure->fLength].fVertexAttribute = attr; int size = cgGetParameterRows( element) * cgGetParameterColumns( element); CGtype type = cgGetParameterBaseType( element); if( type == CG_FLOAT) size *= sizeof( GLfloat); else if( type == CG_INT) size *= sizeof( GLint); fVertexStructure->fElements[ fVertexStructure->fLength].fSize = size; fVertexStructure->fLength++; fVertexStructure->fSize += size; element = cgGetNextParameter( element); } cgDestroyParameter( packing); } else { // It's atomic - create a single, simple input fVertexAttribute = setupAttribute( attrName, semantic, fParameter, vertexAttributes); } // Now pull apart the semantic string to work out where to bind // this value in open GL (as the automagic binding through cgGL // didn't work so well when this was written) int radix = 1; fGLIndex = 0; unsigned int length = semantic.length(); const char* str = semantic.asChar(); // If sematic is NULL then stop here, bug 327649 if (length == 0) { fGLType = glRegister::kUnknown; return; } for(;;) { char c = str[ length - 1]; if( c < '0' || c > '9') break; fGLIndex += radix * (c - '0'); radix *= 10; --length; } if( semantic.length() != length) semantic = semantic.substring( 0, length - 1); // Determine the semantic and setup the gl binding type we should use // to set this parameter. If there's a sensible default value, set that // while we're here. // Note there is no need to set the source type, this gets determined // when the vertex attribute sources are analysed if( semantic == "POSITION") { fGLType = glRegister::kPosition; fVertexAttribute->fSourceName = "position"; } else if( semantic == "NORMAL") { fGLType = glRegister::kNormal; if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "normal"; } else if( semantic == "TEXCOORD") { fGLType = glRegister::kTexCoord; if( fVertexAttribute.isNull() == false ) { if( attrName.toLowerCase() == "tangent") fVertexAttribute->fSourceName = "tangent:map1"; else if( attrName.toLowerCase() == "binormal") fVertexAttribute->fSourceName = "binormal:map1"; else fVertexAttribute->fSourceName = "uv:map1"; } } else if( semantic == "TANGENT") { fGLType = glRegister::kTexCoord; fGLIndex += 6; // TANGENT is TEXCOORD6 if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "tangent:map1"; } else if( semantic == "BINORMAL") { fGLType = glRegister::kTexCoord; fGLIndex += 7; // BINORMAL is TEXCOORD7 if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "binormal:map1"; } else if( semantic == "COLOR") { fGLType = fGLIndex == 1 ? glRegister::kSecondaryColor : glRegister::kColor; } else if( semantic == "ATTR") { fGLType = glRegister::kVertexAttrib; if( fVertexAttribute.isNull() == false ) { fVertexAttribute->fSourceName = semanticName; } } else if( semantic == "PSIZE") { fGLType = glRegister::kVertexAttrib; fGLIndex = 6; } else { fGLType = glRegister::kUnknown; } }
/* virtual */ MStatus hwUnlitShader::bind(const MDrawRequest& request, M3dView& view) { MStatus status; // white, opaque. float bgColor[4] = {1,1,1,1}; // Get path of current object in draw request currentObjectPath = request.multiPath(); MString currentPathName( currentObjectPath.partialPathName() ); updateTransparencyFlags(currentPathName); // Get decal texture name MString decalName = ""; ShadingConnection colorConnection(thisMObject(), currentPathName, "color"); // If the color attribute is ultimately connected to a file texture, find its filename. // otherwise use the default color texture. if (colorConnection.type() == ShadingConnection::TEXTURE && colorConnection.texture().hasFn(MFn::kFileTexture)) { // Get the filename of the texture. MFnDependencyNode textureNode(colorConnection.texture()); MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(MString("fileTextureName")) ); filenamePlug.getValue(decalName); if (decalName == "") getFloat3(color, bgColor); } else { decalName = ""; getFloat3(color, bgColor); } assert(glGetError() == GL_NO_ERROR); view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); // Set the standard OpenGL blending mode. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Change the constant alpha value. float alpha = 1.0f - fConstantTransparency; // Set a color (with alpha). This color will be used directly if // the shader is not textured. Otherwise, the texture will get modulated // by the alpha. glColor4f(bgColor[0], bgColor[1], bgColor[2], alpha); // If the shader is textured... if (decalName.length() != 0) { // Enable 2D texturing. glEnable(GL_TEXTURE_2D); assert(glGetError() == GL_NO_ERROR); // Bind the 2D texture through the texture cache. The cache will keep // the texture around, so that it will only be loaded in video // memory once. In this example, the third parameter (mipmapping) is // false, so no mipmaps are generated. Note that mipmaps only work if // the texture has even dimensions. if(m_pTextureCache) m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false); // Set minification and magnification filtering to linear interpolation. // For better quality, you could enable mipmapping while binding and // use GL_MIPMAP_LINEAR_MIPMAP in for minification filtering. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } // Disable lighting. glDisable(GL_LIGHTING); view.endGL(); return MS::kSuccess; }
Helium::TUID Maya::GetNodeID( const MObject& node, bool create ) { if (node == MObject::kNullObj) { return Helium::TUID::Null; } MObject attr = MObject::kNullObj; MStatus status = MS::kFailure; MFnDependencyNode nodeFn (node); if ( create ) { // // GUID->TUID legacy handling // // look for the old GUID attribute attr = nodeFn.attribute(MString (s_GUIDAttributeName), &status); // if we found it if ( status == MS::kSuccess && !attr.isNull() ) { // get the GUID value MString str; MPlug plug (node, attr); status = plug.getValue(str); HELIUM_ASSERT( status != MS::kFailure ); // parse it Helium::GUID id; bool parsed = id.FromString(str.asTChar()); HELIUM_ASSERT( parsed ); // convert it to a TUID and set the new attribute Helium::TUID tuid; tuid.FromGUID( id ); status = SetNodeID( node, tuid ); HELIUM_ASSERT( status != MS::kFailure ); // check to see if we are a locked node bool nodeWasLocked = nodeFn.isLocked(); if ( nodeWasLocked ) { // turn off any node locking so an attribute can be added nodeFn.setLocked( false ); } // unlock the attribute status = plug.setLocked( false ); HELIUM_ASSERT( status != MS::kFailure ); // remove the attribute status = nodeFn.removeAttribute( attr ); HELIUM_ASSERT( status != MS::kFailure ); // reset to the prior state of wasLocked if ( nodeWasLocked ) { nodeFn.setLocked( nodeWasLocked ); } } } // look for the TUID attribute attr = nodeFn.attribute(MString (s_TUIDAttributeName)); // retrieve the attribute value (may be empty if we are not creating a new id) MString str; MPlug plug (node, attr); plug.getValue(str); // if we don't have an existing id and we should create one if ( str.length() == 0 && create ) { // generate a new ID Helium::TUID id( Helium::TUID::Generate() ); // set the new ID value on the node if( SetNodeID( node, id ) ) { return id; } else { return Helium::TUID::Null; } } // parse the value (this may be null if we did not create the attribute) Helium::TUID id; id.FromString(str.asTChar()); return id; }
MStatus PtexColorNode::compute(const MPlug& plug, MDataBlock& block) { if( ( plug != aOutColor ) && ( plug.parent() != aOutColor ) ) { return MS::kUnknownParameter; } if ( m_ptex_cache == NULL ) { m_ptex_cache = PtexCache::create( 0, 1024 * 1024 ); } if ( m_ptex_cache && m_ptex_texture == 0 ) { MDataHandle fileNameHnd = block.inputValue( aPtexFileName ); MDataHandle filterTypeHnd = block.inputValue( aPtexFilterType ); MString fileNameStr = fileNameHnd.asString(); int filterTypeValue = filterTypeHnd.asInt(); const float &filterSize = block.inputValue( aPtexFilterSize ).asFloat(); if ( fileNameStr.length() ) { Ptex::String error; m_ptex_texture = m_ptex_cache->get( fileNameStr.asChar(), error ); } if ( m_ptex_texture == 0 ) { MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor.x = 1.0f; outColor.y = 0.0f; outColor.z = 1.0f; return MS::kSuccess; } m_ptex_num_channels = m_ptex_texture->numChannels(); PtexFilter::FilterType ptexFilterType = PtexFilter::f_point; switch ( filterTypeValue ) { case 0: ptexFilterType = PtexFilter::f_point; break; case 1: ptexFilterType = PtexFilter::f_bilinear; break; case 2: ptexFilterType = PtexFilter::f_box; break; case 3: ptexFilterType = PtexFilter::f_gaussian; break; case 4: ptexFilterType = PtexFilter::f_bicubic; break; case 5: ptexFilterType = PtexFilter::f_bspline; break; case 6: ptexFilterType = PtexFilter::f_catmullrom; break; case 7: ptexFilterType = PtexFilter::f_mitchell; break; } PtexFilter::Options opts( ptexFilterType, 0, filterSize ); m_ptex_filter = PtexFilter::getFilter( m_ptex_texture, opts ); } const float2 &uv = block.inputValue( aUVPos ).asFloat2(); const float2 &duv = block.inputValue( aUVSize ).asFloat2(); int f = (int)uv[ 0 ]; float u = uv[ 0 ] - (float)f; float v = uv[ 1 ]; float result[4]; m_critical_section.lock(); m_ptex_filter->eval( result, 0, m_ptex_num_channels, f, u, v, duv[ 0 ], 0, 0, duv[ 1 ] ); m_critical_section.unlock(); // set ouput color attribute MFloatVector resultColor( result[ 0 ], result[ 1 ], result[ 2 ] ); MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); return MS::kSuccess; }
//----------------------------------------------------------------------------- // Figures out the material path name from the maya shading group //----------------------------------------------------------------------------- MString ValveMaya::GetMaterialPath( const MObject &shadingGroupObj, MObject *pFileObj, MObject *pPlace2dTextureObj, MObject *pVmtObj, bool *pbTransparent, MString *pDebugWhy ) { MString materialPath( "debug/debugEmpty" ); const MObject surfaceShaderObj( FindInputNode( shadingGroupObj, "surfaceShader" ) ); if ( surfaceShaderObj.isNull() ) { if ( pDebugWhy ) { *pDebugWhy = MString( "Can't find surfaceShader node from shadingGroup: No input to " ) + MFnDependencyNode( shadingGroupObj ).name() + ".surfaceShader"; } return materialPath; } if ( MFnDependencyNode( surfaceShaderObj ).typeName() == "vsVmt" ) { MPlug vmtP = MFnDependencyNode( surfaceShaderObj ).findPlug( "vmtPath" ); if ( !vmtP.isNull() ) { vmtP.getValue( materialPath ); return materialPath; } } const MObject fileObj( FindInputNodeOfType( surfaceShaderObj, "file", "color" ) ); if ( fileObj.isNull() ) { if ( pDebugWhy ) { *pDebugWhy = MString( "Can't find file texture node from surfaceShader: No input to " ) + MFnDependencyNode( surfaceShaderObj ).name() + ".color"; } return materialPath; } if ( pFileObj ) { *pFileObj = fileObj; } if ( pbTransparent ) { const MObject transObj( FindInputNodeOfType( surfaceShaderObj, "file", "transparency" ) ); if ( fileObj == transObj ) { *pbTransparent = true; } } if ( pPlace2dTextureObj ) { MObject place2dTextureObj( FindInputNodeOfType( fileObj, "place2dTexture", "uvCoord" ) ); if ( !place2dTextureObj.isNull() ) { const MPlug uvCoordP( MFnDependencyNode( place2dTextureObj ).findPlug( "uvCoord" ) ); if ( !( uvCoordP.isNull() || uvCoordP.isConnected() || uvCoordP.isLocked() ) ) { *pPlace2dTextureObj = place2dTextureObj; } } } // Check to see if a vsVmtToTex node is driving the filename const MObject vsVmtToTexObj = FindInputNodeOfType( fileObj, "vsVmtToTex" ); if ( !vsVmtToTexObj.isNull() ) { if ( pVmtObj ) { *pVmtObj = vsVmtToTexObj; } const MPlug materialPathP = MFnDependencyNode( vsVmtToTexObj ).findPlug( "materialPath" ); if ( !materialPathP.isNull() ) { materialPathP.getValue( materialPath ); if ( materialPath.length() ) { return materialPath; } } } // Otherwise do path munging to figure out MString fileTexture; int fLen( 0 ); const MFnDependencyNode fileFn( fileObj ); const MPlug fileP( fileFn.findPlug( "fileTextureName" ) ); fileP.getValue( fileTexture ); fLen = fileTexture.length(); if ( fLen == 0 ) { if ( pDebugWhy ) { *pDebugWhy = MString( "No texture filename specified on file texture node: " ) + MFnDependencyNode( fileObj ).name() + ".fileTextureName is empty"; } return materialPath; } MStringArray path; const uint pLen( SplitPath( StripExtension( fileTexture ), path ) ); if ( pLen == 0 ) return fileTexture.asChar(); materialPath = path[ pLen - 1 ]; // Make the path into a relative path for ( int i = pLen - 2; i >= 0; --i ) { if ( i > 1 && ( !stricmp( path[ i - 1 ].asChar(), "game" ) || !stricmp( path[ i - 1 ].asChar(), "content" ) ) ) break; if ( !stricmp( path[ i ].asChar(), "materials" ) || !stricmp( path[ i ].asChar(), "materialsrc" ) ) break; materialPath = path[ i ] + "/" + materialPath; } return materialPath; }
bool CUniformParameterBuilder::build() { //assert(mEffectVariable); // building the uniform based on the type // --------------------------------------- MUniformParameter::DataType type = convertType (); MUniformParameter::DataSemantic semantic = convertSemantic(); updateLightInfoFromSemantic(); // If we don't know what this parameter is, and we've been told to hide it, do so // NOTE that for now, we only hide simple constants as hiding everything we're // told to hide actually starts hiding textures and things the artist wants to see. // ---------------------------------------------------------------------------------- if (semantic == MUniformParameter::kSemanticUnknown && (type == MUniformParameter::kTypeFloat || type == MUniformParameter::kTypeString)) { if (mDesc.Semantic && _stricmp(mDesc.Semantic, dx11ShaderSemantic::kSTANDARDSGLOBAL)==0) { return false; } } /* The UIGroup annotation is used to groups multiple parameters in a single collapsible panel in the attribute editor. This helps organize related parameters. - All parameters sharing the same UIGroup annotation string will group together - The name of the group, as shown as the header of the collapsible panel, will be the value of the annotation - The order of the panels in the attribute editor will be sorted according to the parameter with the lowest UIOrder in that group - UIGroups win over UIOrder, this means all parameters will be grouped in a single panel even if there are non grouped parameters that have a UIOrder that falls within the range of UIOrders for parameters in that group - This commands lists all UIGroups: dx11Shader -listUIGroupInformation - This command lists all parameters for a group: dx11Shader -listUIGroupParameters <group> */ if (mUIGroupIndex == -1) { LPCSTR pszUIGroupName; if( getAnnotation( dx11ShaderAnnotation::kUIGroup, pszUIGroupName) && *pszUIGroupName) { MString uiGroupName(pszUIGroupName); mUIGroupIndex = mShader->getIndexForUIGroupName(uiGroupName, true); } } /* The name of the parameter in the attribute editor defaults to the name of the variable associated with the parameter. If there is a UIName attribute on the parameter, and the 'kVariableNameAsAttributeName' semantic is not set, this name will be used to define all three of the parameter short/long/nice name. If the UIName contains spaces or other script unfriendly characters, those will be replaced by underscores in the short and long names used in scripting. Using UIName as attribute name can lead to ambiguity since UIName annotations are not required to be unique by the compiler. The MPxHardwareShader class will add numbers at the end of the short/long names as required to make them unique. */ LPCSTR paramName = NULL; bool varAsAttr = false; if (mShader) varAsAttr = mShader->getVariableNameAsAttributeName(); LPCSTR uiName = NULL ; bool hasUIName = getAnnotation( dx11ShaderAnnotation::kUIName, uiName); if( varAsAttr || !hasUIName ) paramName = mDesc.Name; else paramName = uiName; /* If an integer parameter has a UIFieldNames annotation, then the annotation contents will be used to populate a dropdown menu when the parameter is shown in the attribute editor. The parameter type is changed from integer to enum. */ LPCSTR uiFieldNames = NULL ; MString fieldNames; if(type == MUniformParameter::kTypeInt && getAnnotation(dx11ShaderAnnotation::kUIFieldNames,uiFieldNames) && uiFieldNames) { fieldNames = uiFieldNames; type = MUniformParameter::kTypeEnum; } MUniformParameter uniform( paramName, type, semantic, mDescType.Rows, mDescType.Columns, (void*)mEffectVariable); mParam = uniform; // If shader author has specified to use var as attribute name and provided a UIName, then // tell Maya to use the UIName for the attribute's 'Nice Name': if (varAsAttr && hasUIName) mParam.setUINiceName( uiName ); updateRangeFromAnnotation(); updateUIVisibilityFromAnnotation(); if (fieldNames.length()) { mParam.setEnumFieldNames(fieldNames); } /* The UIOrder annotation can be used to make sure all parameters appear in a predictable sequence in the attribute editors even if the compiler decides to reorder them is the input block. - The content of the annotation is an integer - Parameters will be sorted according to increasing values of UIOrder annotation - The sort is stable, so parameters with identical UIOrder will appear in the order the compiler outputs them (which is not as stable as the sort) */ getAnnotation(dx11ShaderAnnotation::kUIOrder, mUIOrder); // set keyable for visible attributes other than textures mParam.setKeyable(!mParam.UIHidden() && !mParam.isATexture()); bool result = setParameterValueFromEffect(); if(result) { mValidUniformParameter = true; } return result; }
void SMOnlineRoom::AnalizeChat(unsigned int clientNum, PacketFunctions& Packet) { MString message = Packet.ReadNT(); ChatCommandPack ccp = ParseCommands(message, clientNum); switch(ccp.cmd) { case NONE: RelayChat(clientNum, message); return; case ANNOUNCE: { PacketFunctions reply; reply.ClearPacket(); reply.Write1(NSCSU+NSServerOffset); reply.WriteNT(ccp.data.front()); SERVER->SendToAll(reply); } return; case KICK: { const MString& name = ccp.data.front(); for (unsigned int x = 0; x < m_clients.size(); ++x) for (unsigned int y = 0; y < m_clients[x]->GetNumPlayers(); ++y) if (m_clients[x]->GetPlayer(y)->GetName() == name) { LOG->Write("Kicking " + name); m_kicked[ccp.data.front()] = KickClient(name); ChangeRoom(1, m_joinrooms[0]->GetTitle(), x, "", true); return; } } break; case BAN: { const MString& name = ccp.data.front(); for (unsigned int x = 0; x < m_clients.size(); ++x) for (unsigned int y = 0; y < m_clients[x]->GetNumPlayers(); ++y) if (m_clients[x]->GetPlayer(y)->GetName() == name) { LOG->Write("Banning " + name); m_banned[name] = name; ChangeRoom(1, m_joinrooms[0]->GetTitle(), x, "", true); return; } } break; case PM: { MString user = ccp.data.front(); ccp.data.pop(); MString message = ccp.data.front(); MString tmp; MString success = "PM Failed!"; if ((user.length() > 0) && (message.length() > 0)) { tmp = "PM from "; unsigned int numPlayers = m_clients[m_cNum]->GetNumPlayers(); for (unsigned int x = 0; x < numPlayers; ++x) { tmp += m_clients[m_cNum]->GetPlayerName(x); if ((numPlayers > 1) && (x < (numPlayers - 1))) tmp += "&"; } tmp += ": " + message; if (SERVER->MsgPlayer(user, tmp)) success = "PM Success!"; } PacketFunctions result; result.ClearPacket(); result.Write1(NSCCM + NSServerOffset); result.WriteNT(success); m_clients[m_cNum]->SendData(result); } break; case DROP: { SMOnlineClient* tmp = SERVER->GetPlayerClient(ccp.data.front()); if (tmp != NULL) tmp->connection.close(); } break; // case FORCESTART: // break; default: break; }; }
MStatus simulateBoids::doIt( const MArgList& args ) { // Description: implements the MEL boids command // Arguments: args - the argument list that was passes to the command from MEL MStatus status = MS::kSuccess; /**************************************** * building thread/dll data structure * ****************************************/ InfoCache infoCache; SimulationParameters simParams; RulesParameters *applyingRules; double progressBar=0; double aov=pi/3; int i,numberOfDesires=0; // params retrievement MSelectionList sel; MObject node; MFnDependencyNode nodeFn; MFnTransform locatorFn; MPlug plug; // simulation params int simulationLengthValue; // [int] in seconds int framesPerSecondValue; // [int] int startFrameValue; // [int] int boidsNumberValue; // [int] // export params MString logFilePathValue; // [char *] MString logFileNameValue; // [char *] int logFileTypeValue; // 0 = nCache; 1 = log file; 2 = XML; // locomotion params int locomotionModeValue; // [int] double maxSpeedValue; // [double] double maxForceValue; // [double] // double mass=1; // [double] MTime currentTime, maxTime; MPlug plugX, plugY, plugZ; double tx, ty, tz; int frameLength ; Vector * leader = NULL; MStatus leaderFound=MStatus::kFailure; MGlobal::getActiveSelectionList(sel); for ( MItSelectionList listIter(sel); !listIter.isDone(); listIter.next() ) { listIter.getDependNode(node); switch(node.apiType()) { case MFn::kTransform: // get locator transform to follow leaderFound=locatorFn.setObject(node); cout << locatorFn.name().asChar() << " is selected as locator" << endl; break; case MFn::kPluginDependNode: nodeFn.setObject(node); cout << nodeFn.name().asChar() << " is selected as brain" << endl; break; default: break; } cout<< node.apiTypeStr()<<endl; } // rules params setRuleVariables(alignment); setRuleVariables(cohesion); setRuleVariables(separation); setRuleVariables(follow); getPlugValue(simulationLength); getPlugValue(framesPerSecond); getPlugValue(startFrame); getPlugValue(boidsNumber); getPlugValue(logFileType); getRulePlugValue(alignment); getRulePlugValue(cohesion); getRulePlugValue(separation); getRulePlugValue(follow); getPlugValue(locomotionMode); getPlugValue(maxSpeed); getPlugValue(maxForce); getTypePlugValue(logFilePath); getTypePlugValue(logFileName); // counting active rules number if(alignmentActiveValue) numberOfDesires++; if(cohesionActiveValue) numberOfDesires++; if(separationActiveValue) numberOfDesires++; if(followActiveValue) numberOfDesires++; currentTime = MTime((double)startFrameValue); // MAnimControl::minTime(); maxTime = MTime((double)(startFrameValue + (simulationLengthValue * framesPerSecondValue))); // MAnimControl::maxTime(); cout << "time unit enum (6 is 24 fps): " << currentTime.unit() << endl; plugX = locatorFn.findPlug( MString( "translateX" ), &status ); plugY = locatorFn.findPlug( MString( "translateY" ), &status ); plugZ = locatorFn.findPlug( MString( "translateZ" ), &status ); frameLength = simulationLengthValue * framesPerSecondValue; if(leaderFound==MS::kSuccess) { leader = new Vector[frameLength]; while ( currentTime < maxTime ) { { int index = (int)currentTime.value() - startFrameValue; /* MGlobal::viewFrame(currentTime); pos = locatorFn.getTranslation(MSpace::kWorld); cout << "pos: " << pos.x << " " << pos.y << " " << pos.z << endl; */ status = plugX.getValue( tx, MDGContext(currentTime) ); status = plugY.getValue( ty, MDGContext(currentTime) ); status = plugZ.getValue( tz, MDGContext(currentTime) ); leader[index].x = tx; leader[index].y = ty; leader[index].z = tz; //cout << "pos at time " << currentTime.value() << " has x: " << tx << " y: " << ty << " z: " << tz << endl; currentTime++; } } } simParams.fps=framesPerSecondValue; simParams.lenght=simulationLengthValue; simParams.numberOfBoids=boidsNumberValue; simParams.maxAcceleration=maxForceValue; simParams.maxVelocity=maxSpeedValue; simParams.simplifiedLocomotion=TRUE; applyingRules=new RulesParameters[numberOfDesires]; // cache settings MString saveString; saveString = logFilePathValue+"/"+logFileNameValue; infoCache.fileName=new char[saveString.length()+1]; memcpy(infoCache.fileName,saveString.asChar(),sizeof(char)*(saveString.length()+1)); infoCache.cacheFormat=ONEFILE; infoCache.fps=framesPerSecondValue; infoCache.start=startFrameValue/framesPerSecondValue; infoCache.end=simulationLengthValue+infoCache.start; infoCache.loging=FALSE; infoCache.option=POSITIONVELOCITY; infoCache.particleSysName="BoidsNParticles"; infoCache.saveMethod=MAYANCACHE; for(i=0;i<numberOfDesires;i++) { applyingRules[i].enabled=TRUE; applyingRules[i].precedence=1; applyingRules[i].aov=aov; applyingRules[i].visibilityOption=FALSE; } if(cohesionActiveValue==0) applyingRules[COHESIONRULE].enabled=FALSE; else { applyingRules[COHESIONRULE].ruleName=COHESIONRULE; applyingRules[COHESIONRULE].ruleFactor=cohesionFactorValue; applyingRules[COHESIONRULE].ruleRadius=cohesionRadiusValue; applyingRules[COHESIONRULE].ruleWeight=cohesionWeightValue; } if(separationActiveValue==0) applyingRules[SEPARATIONRULE].enabled=FALSE; else { applyingRules[SEPARATIONRULE].ruleName=SEPARATIONRULE; applyingRules[SEPARATIONRULE].ruleFactor=separationFactorValue; applyingRules[SEPARATIONRULE].ruleRadius=separationRadiusValue; applyingRules[SEPARATIONRULE].ruleWeight=separationWeightValue; } if(alignmentActiveValue==0) applyingRules[ALIGNMENTRULE].enabled=FALSE; else { applyingRules[ALIGNMENTRULE].ruleName=ALIGNMENTRULE; applyingRules[ALIGNMENTRULE].ruleFactor=alignmentFactorValue; applyingRules[ALIGNMENTRULE].ruleRadius=alignmentRadiusValue; applyingRules[ALIGNMENTRULE].ruleWeight=alignmentWeightValue; } if(followActiveValue==0) applyingRules[FOLLOWRULE].enabled=FALSE; else { applyingRules[FOLLOWRULE].ruleName=FOLLOWRULE; applyingRules[FOLLOWRULE].ruleRadius=followRadiusValue; applyingRules[FOLLOWRULE].ruleFactor=followFactorValue; applyingRules[FOLLOWRULE].ruleWeight=followWeightValue; } // initializing simulation parameters boidInit(numberOfDesires, applyingRules, simParams , infoCache, leader); DLLData datadll; // preparing threads pool status = MThreadPool::init(); if (status==MStatus::kSuccess) { MThreadPool::newParallelRegion(ThreadsCreator, &datadll); setResult( "Command executed!\n" ); CHECK_MSTATUS(MProgressWindow::endProgress()); MThreadPool::release(); } switch(datadll.result) { case 0: status=MS::kSuccess; break; default: status=MS::kFailure; } MThreadPool::release(); return status; }
MStatus animImport::reader( const MFileObject& file, const MString& options, FileAccessMode mode) { MStatus status = MS::kFailure; MString fileName = file.fullName(); #if defined (OSMac_) char fname[MAXPATHLEN]; strcpy (fname, fileName.asChar()); ifstream animFile(fname); #else ifstream animFile(fileName.asChar()); #endif // Parse the options. The options syntax is in the form of // "flag=val;flag1=val;flag2=val" // MString pasteFlags; if (options.length() > 0) { // Set up the flags for the paste command. // const MString flagTargetTime("targetTime"); const MString flagTime("time"); const MString flagCopies("copies"); const MString flagOption("option"); const MString flagConnect("connect"); MString copyValue; MString flagValue; MString connectValue; MString timeValue; // Start parsing. // MStringArray optionList; MStringArray theOption; options.split(';', optionList); unsigned nOptions = optionList.length(); for (unsigned i = 0; i < nOptions; i++) { theOption.clear(); optionList[i].split('=', theOption); if (theOption.length() < 1) { continue; } if (theOption[0] == flagCopies && theOption.length() > 1) { copyValue = theOption[1];; } else if (theOption[0] == flagOption && theOption.length() > 1) { flagValue = theOption[1]; } else if (theOption[0] == flagConnect && theOption.length() > 1) { if (theOption[1].asInt() != 0) { connectValue += theOption[1]; } } else if (theOption[0] == flagTime && theOption.length() > 1) { timeValue += theOption[1]; } } if (copyValue.length() > 0) { pasteFlags += " -copies "; pasteFlags += copyValue; pasteFlags += " "; } if (flagValue.length() > 0) { pasteFlags += " -option \""; pasteFlags += flagValue; pasteFlags += "\" "; } if (connectValue.length() > 0) { pasteFlags += " -connect "; pasteFlags += connectValue; pasteFlags += " "; } if (timeValue.length() > 0) { bool useQuotes = !timeValue.isDouble(); pasteFlags += " -time "; if (useQuotes) pasteFlags += "\""; pasteFlags += timeValue; if (useQuotes) pasteFlags += "\""; pasteFlags += " "; } } if (mode == kImportAccessMode) { status = importAnim(animFile, pasteFlags); } animFile.close(); return status; }
bool DXMAnchor::AddAnchor(MObject& site, const MString& longAnchorName, const MString& shortAnchorName, DXMAnchor* anchor) { DXCC_ASSERT( DXMAnchor::GetAnchor(site, shortAnchorName) == NULL ); DXCC_ASSERT(anchor != NULL); DXCC_ASSERT(anchor->GetSite().isNull()); DXCC_ASSERT(anchor->GetPoint().length() == 0); DXCC_ASSERT(longAnchorName.length() > 0); DXCC_ASSERT(shortAnchorName.length() > 0); DXCC_ASSERT(!site.isNull()); MFnDependencyNode depNode(site); MString name= depNode.name(); #ifdef DEBUG anchor->Name= name.asChar(); #endif if( g_DebugBasic ) { DXCC_DPFA_REPORT("%s", name.asChar()); } //this attribute may exist if you had asked for this node to be duplicated or instanced :( if( depNode.attribute( shortAnchorName ).isNull() ) { MFnNumericAttribute numeric; MObject anchorAttrib= numeric.create(longAnchorName, shortAnchorName, MFnNumericData::kInt, 0); numeric.setReadable(false); numeric.setWritable(false); numeric.setConnectable(false); numeric.setStorable(false); numeric.setCached(true); numeric.setArray(false); numeric.setKeyable(false); numeric.setHidden(true); numeric.setUsedAsColor(false); numeric.setIndeterminant(true); numeric.setRenderSource(false); numeric.setInternal(false); DXCC_ASSERT(!anchorAttrib.isNull()); DXCHECK_MSTATUS( depNode.addAttribute(anchorAttrib) ); } MPlug anchorPlug= depNode.findPlug( shortAnchorName ); DXCC_ASSERT(!anchorPlug.isNull()); anchorPlug.setValue( *reinterpret_cast<int*>(&anchor) ); anchor->AnchorSite= site; anchor->AnchorPoint= shortAnchorName; // anchor->NodeDestroyedCID= MNodeMessage::addNodeDestroyedCallback(site, DXMAnchor::DispatchNodeDestroyed, anchor); // anchor->AboutToDeleteCID= MNodeMessage::addNodeAboutToDeleteCallback(site, DXMAnchor::DispatchAboutToDelete, anchor); anchor->OnPostAddAnchor(longAnchorName, shortAnchorName); return true; }
MStatus usdTranslatorExport::writer(const MFileObject &file, const MString &optionsString, MPxFileTranslator::FileAccessMode mode ) { std::string fileName(file.fullName().asChar()); JobExportArgs jobArgs; double startTime=1, endTime=1; bool append=false; // Get the options if ( optionsString.length() > 0 ) { MStringArray optionList; MStringArray theOption; optionsString.split(';', optionList); for(int i=0; i<(int)optionList.length(); ++i) { theOption.clear(); optionList[i].split('=', theOption); if (theOption[0] == MString("exportReferencesAsInstanceable")) { jobArgs.exportRefsAsInstanceable = theOption[1].asInt(); } if (theOption[0] == MString("shadingMode")) { // Set default (most common) options jobArgs.exportDisplayColor = true; jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->none; if (theOption[1]=="None") { jobArgs.exportDisplayColor = false; }else if (theOption[1]=="Look Colors") { jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->displayColor; } else if (theOption[1]=="RfM Shaders") { TfToken shadingMode("pxrRis"); if (PxrUsdMayaShadingModeRegistry::GetInstance().GetExporter(shadingMode)) { jobArgs.shadingMode = shadingMode; } } } if (theOption[0] == MString("exportUVs")) { jobArgs.exportMeshUVs = theOption[1].asInt(); jobArgs.exportNurbsExplicitUV = theOption[1].asInt(); } if (theOption[0] == MString("normalizeUVs")) { jobArgs.normalizeMeshUVs = theOption[1].asInt(); jobArgs.nurbsExplicitUVType = PxUsdExportJobArgsTokens->Uniform; } if (theOption[0] == MString("exportColorSets")) { jobArgs.exportColorSets = theOption[1].asInt(); } if (theOption[0] == MString("renderableOnly")) { jobArgs.excludeInvisible = theOption[1].asInt(); } if (theOption[0] == MString("allCameras")) { jobArgs.exportDefaultCameras = theOption[1].asInt(); } if (theOption[0] == MString("renderLayerMode")) { jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->defaultLayer; if (theOption[1]=="Use Current Layer") { jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->currentLayer; } else if (theOption[1]=="Modeling Variant Per Layer") { jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->modelingVariant; } } if (theOption[0] == MString("mergeXForm")) { jobArgs.mergeTransformAndShape = theOption[1].asInt(); } if (theOption[0] == MString("defaultMeshScheme")) { if (theOption[1]=="Polygonal Mesh") { jobArgs.defaultMeshScheme = UsdGeomTokens->none; } else if (theOption[1]=="Bilinear SubDiv") { jobArgs.defaultMeshScheme = UsdGeomTokens->bilinear; } else if (theOption[1]=="CatmullClark SDiv") { jobArgs.defaultMeshScheme = UsdGeomTokens->catmullClark; } else if (theOption[1]=="Loop SDiv") { jobArgs.defaultMeshScheme = UsdGeomTokens->loop; } } if (theOption[0] == MString("exportVisibility")) { jobArgs.exportVisibility = theOption[1].asInt(); } if (theOption[0] == MString("animation")) { jobArgs.exportAnimation = theOption[1].asInt(); } if (theOption[0] == MString("startTime")) { startTime = theOption[1].asDouble(); } if (theOption[0] == MString("endTime")) { endTime = theOption[1].asDouble(); } } // Now resync start and end frame based on animation mode if (jobArgs.exportAnimation) { if (endTime<startTime) endTime=startTime; } else { startTime=MAnimControl::currentTime().value(); endTime=startTime; } } MSelectionList objSelList; if(mode == MPxFileTranslator::kExportActiveAccessMode) { // Get selected objects MGlobal::getActiveSelectionList(objSelList); } else if(mode == MPxFileTranslator::kExportAccessMode) { // Get all objects at DAG root objSelList.add("|*", true); } // Convert selection list to jobArgs dagPaths for (unsigned int i=0; i < objSelList.length(); i++) { MDagPath dagPath; if (objSelList.getDagPath(i, dagPath) == MS::kSuccess) { jobArgs.dagPaths.insert(dagPath); } } if (jobArgs.dagPaths.size()) { MTime oldCurTime = MAnimControl::currentTime(); usdWriteJob writeJob(jobArgs); if (writeJob.beginJob(fileName, append, startTime, endTime)) { for (double i=startTime;i<(endTime+1);i++) { MGlobal::viewFrame(i); writeJob.evalJob(i); } writeJob.endJob(); MGlobal::viewFrame(oldCurTime); } } else { MGlobal::displayWarning("No DAG nodes to export. Skipping"); } return MS::kSuccess; }
// -------------------------------------- void ReferenceManager::processReference ( const MObject& referenceNode ) { MStatus status; MFnDependencyNode referenceNodeFn ( referenceNode, &status ); if (status != MStatus::kSuccess) return; #if MAYA_API_VERSION >= 600 MString referenceNodeName = MFnDependencyNode( referenceNode ).name(); Reference* reference = new Reference(); reference->referenceNode = referenceNode; mReferences.push_back ( reference ); // Get the paths of the root transforms included in this reference MObjectArray subReferences; getRootObjects ( referenceNode, reference->paths, subReferences ); uint pathCount = reference->paths.length(); // Process the sub-references first uint subReferenceCount = subReferences.length(); for (uint i = 0; i < subReferenceCount; ++i) { MObject& subReference = subReferences[i]; if ( subReference != MObject::kNullObj ) processReference ( subReference ); } // Retrieve the reference node's filename MString command = MString("reference -rfn \"") + referenceNodeFn.name() + MString("\" -q -filename;"); MString filename; status = MGlobal::executeCommand ( command, filename ); if (status != MStatus::kSuccess || filename.length() == 0) return; // Strip the filename of the multiple file token int stripIndex = filename.index('{'); if (stripIndex != -1) filename = filename.substring(0, stripIndex - 1); // Avoid transform look-ups on COLLADA references. int extLocation = filename.rindex('.'); if (extLocation > 0) { MString ext = filename.substring(extLocation + 1, filename.length() - 1).toLowerCase(); if (ext == "dae" || ext == "xml") return; } // Check for already existing file information // Otherwise create a new file information sheet with current node names for ( ReferenceFileList::iterator it = mFiles.begin(); it != mFiles.end(); ++it ) { if ((*it)->filename == filename) { reference->file = (*it); break; } } if ( reference->file == NULL ) reference->file = processReferenceFile(filename); // Get the list of the root transform's first child's unreferenced parents. // This is a list of the imported nodes! for (uint j = 0; j < pathCount; ++j) { MDagPath path = reference->paths[j]; if (path.childCount() > 0) { path.push ( path.child(0) ); MFnDagNode childNode ( path ); if (!childNode.object().hasFn(MFn::kTransform)) continue; uint parentCount = childNode.parentCount(); for (uint k = 0; k < parentCount; ++k) { MFnDagNode parentNode(childNode.parent(k)); if (parentNode.object() == MObject::kNullObj || parentNode.isFromReferencedFile()) continue; MDagPath parentPath = MDagPath::getAPathTo(parentNode.object()); if (parentPath.length() > 0) { ReferenceRootList::iterator it = reference->reroots.insert( reference->reroots.end(), ReferenceRoot() ); (*it).index = j; (*it).reroot = parentPath; } } } } #endif }
MStatus AbcExport::doIt(const MArgList & args) { try { MStatus status; MTime oldCurTime = MAnimControl::currentTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } bool verbose = argData.isFlagSet("verbose"); // If skipFrame is true, when going through the playback range of the // scene, as much frames are skipped when possible. This could cause // a problem for, time dependent solutions like // particle system / hair simulation bool skipFrame = true; if (argData.isFlagSet("dontSkipUnwrittenFrames")) skipFrame = false; double startEvaluationTime = DBL_MAX; if (argData.isFlagSet("preRollStartFrame")) { double startAt = 0.0; argData.getFlagArgument("preRollStartFrame", 0, startAt); startEvaluationTime = startAt; } unsigned int jobSize = argData.numberOfFlagUses("jobArg"); if (jobSize == 0) return status; // the frame range we will be iterating over for all jobs, // includes frames which are not skipped and the startAt offset std::set<double> allFrameRange; // this will eventually hold only the animated jobs. // its a list because we will be removing jobs from it std::list < AbcWriteJobPtr > jobList; for (unsigned int jobIndex = 0; jobIndex < jobSize; jobIndex++) { JobArgs jobArgs; MArgList jobArgList; argData.getFlagArgumentList("jobArg", jobIndex, jobArgList); MString jobArgsStr = jobArgList.asString(0); MStringArray jobArgsArray; { // parse the job arguments // e.g. -perFrameCallbackMel "print \"something\"" will be splitted to // [0] -perFrameCallbackMel // [1] print "something" enum State { kArgument, // parsing an argument (not quoted) kDoubleQuotedString, // parsing a double quoted string kSingleQuotedString, // parsing a single quoted string }; State state = kArgument; MString stringBuffer; for (unsigned int charIdx = 0; charIdx < jobArgsStr.numChars(); charIdx++) { MString ch = jobArgsStr.substringW(charIdx, charIdx); switch (state) { case kArgument: if (ch == " ") { // space terminates the current argument if (stringBuffer.length() > 0) { jobArgsArray.append(stringBuffer); stringBuffer.clear(); } // goto another argument state = kArgument; } else if (ch == "\"") { if (stringBuffer.length() > 0) { // double quote is part of the argument stringBuffer += ch; } else { // goto double quoted string state = kDoubleQuotedString; } } else if (ch == "'") { if (stringBuffer.length() > 0) { // single quote is part of the argument stringBuffer += ch; } else { // goto single quoted string state = kSingleQuotedString; } } else { stringBuffer += ch; } break; case kDoubleQuotedString: // double quote terminates the current string if (ch == "\"") { jobArgsArray.append(stringBuffer); stringBuffer.clear(); state = kArgument; } else if (ch == "\\") { // escaped character MString nextCh = (++charIdx < jobArgsStr.numChars()) ? jobArgsStr.substringW(charIdx, charIdx) : "\\"; if (nextCh == "n") stringBuffer += "\n"; else if (nextCh == "t") stringBuffer += "\t"; else if (nextCh == "r") stringBuffer += "\r"; else if (nextCh == "\\") stringBuffer += "\\"; else if (nextCh == "'") stringBuffer += "'"; else if (nextCh == "\"") stringBuffer += "\""; else stringBuffer += nextCh; } else { stringBuffer += ch; } break; case kSingleQuotedString: // single quote terminates the current string if (ch == "'") { jobArgsArray.append(stringBuffer); stringBuffer.clear(); state = kArgument; } else if (ch == "\\") { // escaped character MString nextCh = (++charIdx < jobArgsStr.numChars()) ? jobArgsStr.substringW(charIdx, charIdx) : "\\"; if (nextCh == "n") stringBuffer += "\n"; else if (nextCh == "t") stringBuffer += "\t"; else if (nextCh == "r") stringBuffer += "\r"; else if (nextCh == "\\") stringBuffer += "\\"; else if (nextCh == "'") stringBuffer += "'"; else if (nextCh == "\"") stringBuffer += "\""; else stringBuffer += nextCh; } else { stringBuffer += ch; } break; } } // the rest of the argument if (stringBuffer.length() > 0) { jobArgsArray.append(stringBuffer); } } // the frame range within this job std::vector< FrameRangeArgs > frameRanges(1); frameRanges.back().startTime = oldCurTime.value(); frameRanges.back().endTime = oldCurTime.value(); frameRanges.back().strideTime = 1.0; bool hasRange = false; bool hasRoot = false; bool sampleGeo = true; // whether or not to subsample geometry std::string fileName; bool asOgawa = true; unsigned int numJobArgs = jobArgsArray.length(); for (unsigned int i = 0; i < numJobArgs; ++i) { MString arg = jobArgsArray[i]; arg.toLowerCase(); if (arg == "-f" || arg == "-file") { if (i+1 >= numJobArgs) { MGlobal::displayError("File incorrectly specified."); return MS::kFailure; } fileName = jobArgsArray[++i].asChar(); } else if (arg == "-fr" || arg == "-framerange") { if (i+2 >= numJobArgs || !jobArgsArray[i+1].isDouble() || !jobArgsArray[i+2].isDouble()) { MGlobal::displayError("Frame Range incorrectly specified."); return MS::kFailure; } // this is not the first -frameRange argument, we are going // to add one more frame range to the frame range array. if (hasRange) { frameRanges.push_back(FrameRangeArgs()); } hasRange = true; frameRanges.back().startTime = jobArgsArray[++i].asDouble(); frameRanges.back().endTime = jobArgsArray[++i].asDouble(); // make sure start frame is smaller or equal to endTime if (frameRanges.back().startTime > frameRanges.back().endTime) { std::swap(frameRanges.back().startTime, frameRanges.back().endTime); } } else if (arg == "-frs" || arg == "-framerelativesample") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble()) { MGlobal::displayError( "Frame Relative Sample incorrectly specified."); return MS::kFailure; } frameRanges.back().shutterSamples.insert( jobArgsArray[++i].asDouble()); } else if (arg == "-nn" || arg == "-nonormals") { jobArgs.noNormals = true; } else if (arg == "-pr" || arg == "-preroll") { frameRanges.back().preRoll = true; } else if (arg == "-ro" || arg == "-renderableonly") { jobArgs.excludeInvisible = true; } else if (arg == "-s" || arg == "-step") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble()) { MGlobal::displayError("Step incorrectly specified."); return MS::kFailure; } frameRanges.back().strideTime = jobArgsArray[++i].asDouble(); } else if (arg == "-sl" || arg == "-selection") { jobArgs.useSelectionList = true; } else if (arg == "-sn" || arg == "-stripnamespaces") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isUnsigned()) { // the strip all namespaces case // so we pick a very LARGE number jobArgs.stripNamespace = 0xffffffff; } else { jobArgs.stripNamespace = jobArgsArray[++i].asUnsigned(); } } else if (arg == "-uv" || arg == "-uvwrite") { jobArgs.writeUVs = true; } else if (arg == "-wcs" || arg == "-writecolorsets") { jobArgs.writeColorSets = true; } else if (arg == "-wfs" || arg == "-writefacesets") { jobArgs.writeFaceSets = true; } else if (arg == "-wfg" || arg == "-wholeframegeo") { sampleGeo = false; } else if (arg == "-ws" || arg == "-worldspace") { jobArgs.worldSpace = true; } else if (arg == "-wuvs" || arg == "-writeuvsets") { jobArgs.writeUVSets = true; } else if (arg == "-wv" || arg == "-writevisibility") { jobArgs.writeVisibility = true; } else if (arg == "-as" || arg == "-autosubd") { jobArgs.autoSubd = true; } else if (arg == "-mfc" || arg == "-melperframecallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "melPerFrameCallback incorrectly specified."); return MS::kFailure; } jobArgs.melPerFrameCallback = jobArgsArray[++i].asChar(); } else if (arg == "-pfc" || arg == "-pythonperframecallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "pythonPerFrameCallback incorrectly specified."); return MS::kFailure; } jobArgs.pythonPerFrameCallback = jobArgsArray[++i].asChar(); } else if (arg == "-mpc" || arg == "-melpostjobcallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "melPostJobCallback incorrectly specified."); return MS::kFailure; } jobArgs.melPostCallback = jobArgsArray[++i].asChar(); } else if (arg == "-ppc" || arg == "-pythonpostjobcallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "pythonPostJobCallback incorrectly specified."); return MS::kFailure; } jobArgs.pythonPostCallback = jobArgsArray[++i].asChar(); } // geomArbParams - attribute filtering stuff else if (arg == "-atp" || arg == "-attrprefix") { if (i+1 >= numJobArgs) { MGlobal::displayError( "attrPrefix incorrectly specified."); return MS::kFailure; } jobArgs.prefixFilters.push_back(jobArgsArray[++i].asChar()); } else if (arg == "-a" || arg == "-attr") { if (i+1 >= numJobArgs) { MGlobal::displayError( "attr incorrectly specified."); return MS::kFailure; } jobArgs.attribs.insert(jobArgsArray[++i].asChar()); } // userProperties - attribute filtering stuff else if (arg == "-uatp" || arg == "-userattrprefix") { if (i+1 >= numJobArgs) { MGlobal::displayError( "userAttrPrefix incorrectly specified."); return MS::kFailure; } jobArgs.userPrefixFilters.push_back(jobArgsArray[++i].asChar()); } else if (arg == "-u" || arg == "-userattr") { if (i+1 >= numJobArgs) { MGlobal::displayError( "userAttr incorrectly specified."); return MS::kFailure; } jobArgs.userAttribs.insert(jobArgsArray[++i].asChar()); } else if (arg == "-rt" || arg == "-root") { if (i+1 >= numJobArgs) { MGlobal::displayError( "root incorrectly specified."); return MS::kFailure; } hasRoot = true; MString root = jobArgsArray[++i]; MSelectionList sel; if (sel.add(root) != MS::kSuccess) { MString warn = root; warn += " could not be select, skipping."; MGlobal::displayWarning(warn); continue; } unsigned int numRoots = sel.length(); for (unsigned int j = 0; j < numRoots; ++j) { MDagPath path; if (sel.getDagPath(j, path) != MS::kSuccess) { MString warn = path.fullPathName(); warn += " (part of "; warn += root; warn += " ) not a DAG Node, skipping."; MGlobal::displayWarning(warn); continue; } jobArgs.dagPaths.insert(path); } } else if (arg == "-ef" || arg == "-eulerfilter") { jobArgs.filterEulerRotations = true; } else if (arg == "-df" || arg == "-dataformat") { if (i+1 >= numJobArgs) { MGlobal::displayError( "dataFormat incorrectly specified."); return MS::kFailure; } MString dataFormat = jobArgsArray[++i]; dataFormat.toLowerCase(); if (dataFormat == "hdf") { asOgawa = false; } else if (dataFormat == "ogawa") { asOgawa = true; } } else { MString warn = "Ignoring unsupported flag: "; warn += jobArgsArray[i]; MGlobal::displayWarning(warn); } } // for i if (fileName == "") { MString error = "-file not specified."; MGlobal::displayError(error); return MS::kFailure; } { MString fileRule, expandName; MString alembicFileRule = "alembicCache"; MString alembicFilePath = "cache/alembic"; MString queryFileRuleCmd; queryFileRuleCmd.format("workspace -q -fre \"^1s\"", alembicFileRule); MString queryFolderCmd; queryFolderCmd.format("workspace -en `workspace -q -fre \"^1s\"`", alembicFileRule); // query the file rule for alembic cache MGlobal::executeCommand(queryFileRuleCmd, fileRule); if (fileRule.length() > 0) { // we have alembic file rule, query the folder MGlobal::executeCommand(queryFolderCmd, expandName); } else { // alembic file rule does not exist, create it MString addFileRuleCmd; addFileRuleCmd.format("workspace -fr \"^1s\" \"^2s\"", alembicFileRule, alembicFilePath); MGlobal::executeCommand(addFileRuleCmd); // save the workspace. maya may discard file rules on exit MGlobal::executeCommand("workspace -s"); // query the folder MGlobal::executeCommand(queryFolderCmd, expandName); } // resolve the expanded file rule if (expandName.length() == 0) { expandName = alembicFilePath; } // get the path to the alembic file rule MFileObject directory; directory.setRawFullName(expandName); MString directoryName = directory.resolvedFullName(); // make sure the cache folder exists if (!directory.exists()) { // create the cache folder MString createFolderCmd; createFolderCmd.format("sysFile -md \"^1s\"", directoryName); MGlobal::executeCommand(createFolderCmd); } // resolve the relative path MFileObject absoluteFile; absoluteFile.setRawFullName(fileName.c_str()); #if MAYA_API_VERSION < 201300 if (absoluteFile.resolvedFullName() != absoluteFile.expandedFullName()) { #else if (!MFileObject::isAbsolutePath(fileName.c_str())) { #endif // this is a relative path MString absoluteFileName = directoryName + "/" + fileName.c_str(); absoluteFile.setRawFullName(absoluteFileName); fileName = absoluteFile.resolvedFullName().asChar(); } else { fileName = absoluteFile.resolvedFullName().asChar(); } // check the path must exist before writing MFileObject absoluteFilePath; absoluteFilePath.setRawFullName(absoluteFile.path()); if (!absoluteFilePath.exists()) { MString error; error.format("Path ^1s does not exist!", absoluteFilePath.resolvedFullName()); MGlobal::displayError(error); return MS::kFailure; } // check the file is used by any AlembicNode in the scene MItDependencyNodes dgIter(MFn::kPluginDependNode); for (; !dgIter.isDone(); dgIter.next()) { MFnDependencyNode alembicNode(dgIter.thisNode()); if (alembicNode.typeName() != "AlembicNode") { continue; } MPlug abcFilePlug = alembicNode.findPlug("abc_File"); if (abcFilePlug.isNull()) { continue; } MFileObject alembicFile; alembicFile.setRawFullName(abcFilePlug.asString()); if (!alembicFile.exists()) { continue; } if (alembicFile.resolvedFullName() == absoluteFile.resolvedFullName()) { MString error = "Can't export to an Alembic file which is in use."; MGlobal::displayError(error); return MS::kFailure; } } std::ofstream ofs(fileName.c_str()); if (!ofs.is_open()) { MString error = MString("Can't write to file: ") + fileName.c_str(); MGlobal::displayError(error); return MS::kFailure; } ofs.close(); } // if -frameRelativeSample argument is not specified for a frame range, // we are assuming a -frameRelativeSample 0.0 for (std::vector<FrameRangeArgs>::iterator range = frameRanges.begin(); range != frameRanges.end(); ++range) { if (range->shutterSamples.empty()) range->shutterSamples.insert(0.0); } if (jobArgs.prefixFilters.empty()) { jobArgs.prefixFilters.push_back("ABC_"); } // the list of frame ranges for sampling std::vector<FrameRangeArgs> sampleRanges; std::vector<FrameRangeArgs> preRollRanges; for (std::vector<FrameRangeArgs>::const_iterator range = frameRanges.begin(); range != frameRanges.end(); ++range) { if (range->preRoll) preRollRanges.push_back(*range); else sampleRanges.push_back(*range); } // the list of frames written into the abc file std::set<double> geoSamples; std::set<double> transSamples; for (std::vector<FrameRangeArgs>::const_iterator range = sampleRanges.begin(); range != sampleRanges.end(); ++range) { for (double frame = range->startTime; frame <= range->endTime; frame += range->strideTime) { for (std::set<double>::const_iterator shutter = range->shutterSamples.begin(); shutter != range->shutterSamples.end(); ++shutter) { double curFrame = *shutter + frame; if (!sampleGeo) { double intFrame = (double)(int)( curFrame >= 0 ? curFrame + .5 : curFrame - .5); // only insert samples that are close to being an integer if (fabs(curFrame - intFrame) < 1e-4) { geoSamples.insert(curFrame); } } else { geoSamples.insert(curFrame); } transSamples.insert(curFrame); } } if (geoSamples.empty()) { geoSamples.insert(range->startTime); } if (transSamples.empty()) { transSamples.insert(range->startTime); } } bool isAcyclic = false; if (sampleRanges.empty()) { // no frame ranges or all frame ranges are pre-roll ranges hasRange = false; geoSamples.insert(frameRanges.back().startTime); transSamples.insert(frameRanges.back().startTime); } else { // check if the time range is even (cyclic) // otherwise, we will use acyclic // sub frames pattern std::vector<double> pattern( sampleRanges.begin()->shutterSamples.begin(), sampleRanges.begin()->shutterSamples.end()); std::transform(pattern.begin(), pattern.end(), pattern.begin(), std::bind2nd(std::plus<double>(), sampleRanges.begin()->startTime)); // check the frames against the pattern std::vector<double> timeSamples( transSamples.begin(), transSamples.end()); for (size_t i = 0; i < timeSamples.size(); i++) { // next pattern if (i % pattern.size() == 0 && i / pattern.size() > 0) { std::transform(pattern.begin(), pattern.end(), pattern.begin(), std::bind2nd(std::plus<double>(), sampleRanges.begin()->strideTime)); } // pattern mismatch, we use acyclic time sampling type if (timeSamples[i] != pattern[i % pattern.size()]) { isAcyclic = true; break; } } } // the list of frames to pre-roll std::set<double> preRollSamples; for (std::vector<FrameRangeArgs>::const_iterator range = preRollRanges.begin(); range != preRollRanges.end(); ++range) { for (double frame = range->startTime; frame <= range->endTime; frame += range->strideTime) { for (std::set<double>::const_iterator shutter = range->shutterSamples.begin(); shutter != range->shutterSamples.end(); ++shutter) { double curFrame = *shutter + frame; preRollSamples.insert(curFrame); } } if (preRollSamples.empty()) { preRollSamples.insert(range->startTime); } } if (jobArgs.dagPaths.size() > 1) { // check for validity of the DagPath relationships complexity : n^2 util::ShapeSet::const_iterator m, n; util::ShapeSet::const_iterator end = jobArgs.dagPaths.end(); for (m = jobArgs.dagPaths.begin(); m != end; ) { MDagPath path1 = *m; m++; for (n = m; n != end; n++) { MDagPath path2 = *n; if (util::isAncestorDescendentRelationship(path1,path2)) { MString errorMsg = path1.fullPathName(); errorMsg += " and "; errorMsg += path2.fullPathName(); errorMsg += " have an ancestor relationship."; MGlobal::displayError(errorMsg); return MS::kFailure; } } // for n } // for m } // no root is specified, and we aren't using a selection // so we'll try to translate the whole Maya scene by using all // children of the world as roots. else if (!hasRoot && !jobArgs.useSelectionList) { MSelectionList sel; #if MAYA_API_VERSION >= 201100 sel.add("|*", true); #else // older versions of Maya will not be able to find top level nodes // within namespaces sel.add("|*"); #endif unsigned int numRoots = sel.length(); for (unsigned int i = 0; i < numRoots; ++i) { MDagPath path; sel.getDagPath(i, path); jobArgs.dagPaths.insert(path); } } else if (hasRoot && jobArgs.dagPaths.empty()) { MString errorMsg = "No valid root nodes were specified."; MGlobal::displayError(errorMsg); return MS::kFailure; } else if (jobArgs.useSelectionList) { MSelectionList activeList; MGlobal::getActiveSelectionList(activeList); if (activeList.length() == 0) { MString errorMsg = "-selection specified but nothing is actively selected."; MGlobal::displayError(errorMsg); return MS::kFailure; } } AbcA::TimeSamplingPtr transTime, geoTime; if (hasRange) { if (isAcyclic) { // acyclic, uneven time sampling // e.g. [0.8, 1, 1.2], [2.8, 3, 3.2], .. not continuous // [0.8, 1, 1.2], [1.7, 2, 2.3], .. shutter different std::vector<double> samples( transSamples.begin(), transSamples.end()); std::transform(samples.begin(), samples.end(), samples.begin(), std::bind2nd(std::multiplies<double>(), util::spf())); transTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType( AbcA::TimeSamplingType::kAcyclic), samples)); } else { // cyclic, even time sampling between time periods // e.g. [0.8, 1, 1.2], [1.8, 2, 2.2], ... std::vector<double> samples; double startTime = sampleRanges[0].startTime; double strideTime = sampleRanges[0].strideTime; for (std::set<double>::const_iterator shutter = sampleRanges[0].shutterSamples.begin(); shutter != sampleRanges[0].shutterSamples.end(); ++shutter) { samples.push_back((startTime + *shutter) * util::spf()); } if (samples.size() > 1) { Alembic::Util::uint32_t numSamples = static_cast<Alembic::Util::uint32_t>(samples.size()); transTime.reset( new AbcA::TimeSampling(AbcA::TimeSamplingType( numSamples, strideTime * util::spf()), samples)); } // uniform sampling else { transTime.reset(new AbcA::TimeSampling( strideTime * util::spf(), samples[0])); } } } else { // time ranges are not specified transTime.reset(new AbcA::TimeSampling()); } if (sampleGeo || !hasRange) { geoTime = transTime; } else { // sampling geo on whole frames if (isAcyclic) { // acyclic, uneven time sampling std::vector<double> samples( geoSamples.begin(), geoSamples.end()); // one more sample for setup() if (*transSamples.begin() != *geoSamples.begin()) samples.insert(samples.begin(), *transSamples.begin()); std::transform(samples.begin(), samples.end(), samples.begin(), std::bind2nd(std::multiplies<double>(), util::spf())); geoTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType( AbcA::TimeSamplingType::kAcyclic), samples)); } else { double geoStride = sampleRanges[0].strideTime; if (geoStride < 1.0) geoStride = 1.0; double geoStart = *geoSamples.begin() * util::spf(); geoTime.reset(new AbcA::TimeSampling( geoStride * util::spf(), geoStart)); } } AbcWriteJobPtr job(new AbcWriteJob(fileName.c_str(), asOgawa, transSamples, transTime, geoSamples, geoTime, jobArgs)); jobList.push_front(job); // make sure we add additional whole frames, if we arent skipping // the inbetween ones if (!skipFrame && !allFrameRange.empty()) { double localMin = *(transSamples.begin()); std::set<double>::iterator last = transSamples.end(); last--; double localMax = *last; double globalMin = *(allFrameRange.begin()); last = allFrameRange.end(); last--; double globalMax = *last; // if the min of our current frame range is beyond // what we know about, pad a few more frames if (localMin > globalMax) { for (double f = globalMax; f < localMin; f++) { allFrameRange.insert(f); } } // if the max of our current frame range is beyond // what we know about, pad a few more frames if (localMax < globalMin) { for (double f = localMax; f < globalMin; f++) { allFrameRange.insert(f); } } } // right now we just copy over the translation samples since // they are guaranteed to contain all the geometry samples allFrameRange.insert(transSamples.begin(), transSamples.end()); // copy over the pre-roll samples allFrameRange.insert(preRollSamples.begin(), preRollSamples.end()); } // add extra evaluation run up, if necessary if (startEvaluationTime != DBL_MAX && !allFrameRange.empty()) { double firstFrame = *allFrameRange.begin(); for (double f = startEvaluationTime; f < firstFrame; ++f) { allFrameRange.insert(f); } } std::set<double>::iterator it = allFrameRange.begin(); std::set<double>::iterator itEnd = allFrameRange.end(); MComputation computation; computation.beginComputation(); // loop through every frame in the list, if a job has that frame in it's // list of transform or shape frames, then it will write out data and // call the perFrameCallback, if that frame is also the last one it has // to work on then it will also call the postCallback. // If it doesn't have this frame, then it does nothing for (; it != itEnd; it++) { if (verbose) { double frame = *it; MString info; info = frame; MGlobal::displayInfo(info); } MGlobal::viewFrame(*it); std::list< AbcWriteJobPtr >::iterator j = jobList.begin(); std::list< AbcWriteJobPtr >::iterator jend = jobList.end(); while (j != jend) { if (computation.isInterruptRequested()) return MS::kFailure; bool lastFrame = (*j)->eval(*it); if (lastFrame) { j = jobList.erase(j); } else j++; } } computation.endComputation(); // set the time back MGlobal::viewFrame(oldCurTime); return MS::kSuccess; } catch (Alembic::Util::Exception & e) { MString theError("Alembic Exception encountered: "); theError += e.what(); MGlobal::displayError(theError); return MS::kFailure; } catch (std::exception & e) { MString theError("std::exception encountered: "); theError += e.what(); MGlobal::displayError(theError); return MS::kFailure; } }
void IndigoRenderer::defineCamera() { std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; for (auto mobj : mayaScene->camList) { std::shared_ptr<mtin_MayaObject> icam(std::static_pointer_cast<mtin_MayaObject>(mobj)); MFnCamera camFn(icam->dagPath); float lensRadius = 0.01; getFloat(MString("mtin_lensRadius"), camFn, lensRadius); bool autoFocus = false; getBool(MString("mtin_autoFocus"), camFn, autoFocus); MVector camUp = camFn.upDirection(MSpace::kWorld); MVector camView = camFn.viewDirection(MSpace::kWorld); MPoint camPos = camFn.eyePoint(MSpace::kWorld); MMatrix m = icam->transformMatrices[0]; MPoint pos, rot, scale; getMatrixComponents(m, pos, rot, scale); camPos *= renderGlobals->globalConversionMatrix; camUp *= renderGlobals->globalConversionMatrix; camView *= renderGlobals->globalConversionMatrix; camUp.normalize(); camView.normalize(); double focusDistance = camFn.focusDistance(); double horizFilmAperture = camFn.horizontalFilmAperture(); double focalLen = camFn.focalLength(); logger.debug(MString("Using camera: ") + icam->fullName); Indigo::SceneNodeCameraRef cam(new Indigo::SceneNodeCamera()); if( renderGlobals->doDof ) cam->lens_radius = lensRadius; else cam->lens_radius = lensRadius / 10000.0; //apertureRadius = $iFocalLength / ($FStop * 2.0); float exposureDuration = 0.333f; getFloat("mtin_exposureDuration", camFn, exposureDuration); cam->exposure_duration = exposureDuration; cam->focus_distance = focusDistance * scale.x; // scale by global matrix scale cam->lens_sensor_dist = focalLen/1000.0; cam->autofocus = autoFocus; //cam->lens_shift_right_distance = 0; //cam->lens_shift_up_distance = 0; cam->sensor_width = (horizFilmAperture * 2.54 * 10.0) / 1000.0; cam->camera_type = Indigo::SceneNodeCamera::CameraType_ThinLensPerspective; cam->forwards = Indigo::Vec3d(camView.x, camView.y, camView.z); cam->up = Indigo::Vec3d(camUp.x, camUp.y, camUp.z); cam->setPos(Indigo::Vec3d(camPos.x, camPos.y, camPos.z)); int appShape = 0; getEnum(MString("mtin_apertureShape"), camFn, appShape); if( appShape == 0) // circle cam->aperture_shape = new Indigo::ApertureCircular(); if( appShape == 1) // generated { int numBlades = 5; float startAngle = 0.0f; float offset = 0.0f; float radius = 0.0f; getInt("mtin_numBlades", camFn, numBlades); getFloat("mtin_startAngle", camFn, startAngle); getFloat("mtin_bladeOffset", camFn, offset); getFloat("mtin_bladeCurvatureRadius", camFn, radius); cam->aperture_shape = new Indigo::ApertureGenerated(numBlades, offset, radius, startAngle); } if( appShape == 2) // image { MString fileName; getString(MString("mtin_appFile"), camFn, fileName); if( fileName.length() > 4) cam->aperture_shape = new Indigo::ApertureImage(fileName.asChar()); } sceneRootRef->addChildNode(cam); } }
// Write method of the GE2.0 translator / file exporter MStatus ge2Translator::writer ( const MFileObject & fileObject, const MString & options, MPxFileTranslator::FileAccessMode mode) { char LTmpStr[MAXPATHLEN]; unsigned int i, LN; // const MString fname = fileObject.fullName (); MString extension; MString baseFileName; // Lets strip off the known extension of .grp if it is there. extension.set (".grp"); int extLocation = fileObject.name ().rindex ('.'); if ( (extLocation != -1) && // no '.' in name (extLocation != 0) && // name was ".grp" -- that's ok?? (fileObject.name ().substring (extLocation, fileObject.name ().length () - 1) == extension) ) { baseFileName = fileObject.name ().substring (0, extLocation - 1); } else { baseFileName = fileObject.name (); extension.clear (); } geWrapper.setBaseFileName( baseFileName ); geWrapper.setPathName( fileObject.fullName() ); geWrapper.pluginVersion = version; // Set the directory at the Dt level strncpy( LTmpStr, geWrapper.getPathName().asChar(), MAXPATHLEN ); LN = (int)strlen( LTmpStr ); if ( LTmpStr[LN - 1] == '/' ) LTmpStr[LN - 1] = '\0'; DtSetDirectory( LTmpStr ); // in an ideal world, everything in setDefaults() should be overridden // with the option parsing. If the mel script doesn't get run for whatever // reason, or neglects to return some values, hopefully setDefaults will // enable the export to go through anyway geWrapper.setDefaults(); // Turn off this pesky warning on NT - performance warning // for int -> bool conversion. #ifdef WIN32 #pragma warning ( disable : 4800 ) #endif // Lets now do all of the option processing if ( options.length () > 0 ) { //Start parsing. MStringArray optionList; MStringArray theOption; options.split(';', optionList); //break out all the options. for ( i = 0; i < optionList.length (); ++i ) { theOption.clear (); optionList[i].split( '=', theOption ); if ( theOption.length () > 1 ) { if ( theOption[0] == MString( "enableAnim" ) ) { geWrapper.enableAnim = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animStart" ) ) { geWrapper.frameStart = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animEnd" ) ) { geWrapper.frameEnd = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animStep" ) ) { geWrapper.frameStep = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animVertices" ) ) { geWrapper.animVertices = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animDisplacement" ) ) { if ( theOption[1].asInt() == 1 ) geWrapper.vertexDisplacement = ge2Wrapper::kVDRelative; else geWrapper.vertexDisplacement = ge2Wrapper::kVDAbsolute; } else if ( theOption[0] == MString( "animTransforms" ) ) { geWrapper.animTransforms = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animShaders" ) ) { geWrapper.animShaders = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animLights" ) ) { geWrapper.animLights = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "animCamera" ) ) { geWrapper.animCamera = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "keyCurves" ) ) { geWrapper.keyCurves = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "keySample" ) ) { geWrapper.keySample = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "sampRate" ) ) { geWrapper.sampleRate = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "sampTol" ) ) { geWrapper.sampleTolerance = (float) ( theOption[1].asFloat() ); } else if ( theOption[0] == MString( "useGL" ) ) { geWrapper.useDomainGL = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "usePSX" ) ) { geWrapper.useDomainPSX = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "useN64" ) ) { geWrapper.useDomainN64 = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "useCustom" ) ) { geWrapper.useDomainCustom = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "hrcType" ) ) { geWrapper.hrcMode = static_cast <ge2Wrapper::GEHrcMode> ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportSel" ) ) { geWrapper.selType = static_cast <ge2Wrapper::GESelType> ( theOption[1].asInt() ); if ( (mode == MPxFileTranslator::kExportActiveAccessMode) && (geWrapper.selType == ge2Wrapper::kSelAll) ) { geWrapper.selType = ge2Wrapper::kSelActive; } } else if ( theOption[0] == MString( "exportLights" ) ) { geWrapper.outputLights = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportCamera" ) ) { geWrapper.outputCamera = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportJoints" ) ) { geWrapper.outputJoints = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportNormals" ) ) { geWrapper.outputNormals = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "opposite" ) ) { geWrapper.oppositeNormals = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportGeometry" ) ) { geWrapper.outputGeometry = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "reverse" ) ) { geWrapper.reverseWinding = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "exportTextures" ) ) { geWrapper.outputTextures = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "tesselation" ) ) { if ( theOption[1].asInt() == 2 ) DtExt_setTesselate( kTESSQUAD ); else DtExt_setTesselate( kTESSTRI ); } else if ( theOption[0] == MString( "texsample" ) ) { geWrapper.sampleTextures = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "texevaluate" ) ) { geWrapper.evalTextures = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "texOriginal" ) ) { geWrapper.useOriginalFileTextures = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "Xtexres" ) ) { geWrapper.xTexRes = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "Ytexres" ) ) { geWrapper.yTexRes = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "MaxXtexres" ) ) { geWrapper.xMaxTexRes = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "MaxYtexres" ) ) { geWrapper.yMaxTexRes = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "texType" ) ) { geWrapper.texType = theOption[1]; } else if ( theOption[0] == MString( "precision" ) ) { geWrapper.precision = (int) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "format" ) ) { geWrapper.useTabs = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "comments" ) ) { geWrapper.writeComments = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "verboseGeom" ) ) { geWrapper.verboseGeom = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "verboseLgt" ) ) { geWrapper.verboseLgt = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "verboseCam" ) ) { geWrapper.verboseCam = (bool) ( theOption[1].asInt() ); } else if ( theOption[0] == MString( "script" ) ) { geWrapper.userScript = theOption[1]; } else if ( theOption[0] == MString( "scriptAppend" ) ) { geWrapper.scriptAppendFileName = (int) ( theOption[1].asInt() ); } } } } #ifdef WIN32 #pragma warning ( default : 4800 ) #endif geWrapper.initScene(); // do some initialization geWrapper.writeScene(); // write it to the appropriate files geWrapper.killScene(); // clean-up return MS::kSuccess; }
MString defineTexture(MFnDependencyNode& shader, MString& attributeName) { boost::shared_ptr<AppleseedRenderer> appleRenderer = boost::static_pointer_cast<AppleseedRenderer>(getWorldPtr()->mRenderer); assert(appleRenderer != 0); renderer::Scene* scene = getSceneFromProject(appleRenderer->getProjectPtr()); foundation::SearchPaths &searchPaths = appleRenderer->getProjectPtr()->search_paths(); MStatus stat; MString textureDefinition(""); MPlug plug = shader.findPlug(attributeName, &stat); if (stat != MStatus::kSuccess) return textureDefinition; if (!plug.isConnected()) return textureDefinition; MObject connectedNode = getConnectedInNode(plug); if (!connectedNode.hasFn(MFn::kFileTexture)) return textureDefinition; MFnDependencyNode fileTextureNode(connectedNode, &stat); MString textureName = fileTextureNode.name() + "_texture"; MString fileTextureName = ""; getString(MString("fileTextureName"), fileTextureNode, fileTextureName); if (!pystring::endswith(fileTextureName.asChar(), ".exr") || (fileTextureName.length() == 0)) { if (fileTextureName.length() == 0) Logging::warning(MString("FileTextureName has no content.")); else Logging::warning(MString("FileTextureName does not have an .exr extension. Other filetypes are not yet supported, sorry.")); return textureDefinition; } removeTextureEntityIfItExists(textureName); MString colorProfile = "srgb"; renderer::ParamArray params; Logging::debug(MString("Now inserting file name: ") + fileTextureName); params.insert("filename", fileTextureName.asChar()); // OpenEXR only for now. The param is called filename but it can be a path params.insert("color_space", colorProfile.asChar()); foundation::auto_release_ptr<renderer::Texture> textureElement( renderer::DiskTexture2dFactory().create( textureName.asChar(), params, searchPaths)); // the project holds a set of search paths to find textures and other assets scene->textures().insert(textureElement); bool alphaIsLuminance = false; getBool(MString("alphaIsLuminance"), fileTextureNode, alphaIsLuminance); renderer::ParamArray tInstParams; tInstParams.insert("addressing_mode", "clamp"); tInstParams.insert("filtering_mode", "bilinear"); if (alphaIsLuminance) tInstParams.insert("alpha_mode", "luminance"); MString textureInstanceName = textureName + "_texInst"; foundation::auto_release_ptr<renderer::TextureInstance> tinst = renderer::TextureInstanceFactory().create( textureInstanceName.asChar(), tInstParams, textureName.asChar()); scene->texture_instances().insert(tinst); return textureInstanceName; }
MStatus AlembicExportCommand::doIt(const MArgList &args) { ESS_PROFILE_SCOPE("AlembicExportCommand::doIt"); MStatus status = MS::kFailure; MTime currentAnimStartTime = MAnimControl::animationStartTime(), currentAnimEndTime = MAnimControl::animationEndTime(), oldCurTime = MAnimControl::currentTime(), curMinTime = MAnimControl::minTime(), curMaxTime = MAnimControl::maxTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { // TODO: implement help for this command // MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } unsigned int jobCount = argData.numberOfFlagUses("jobArg"); MStringArray jobStrings; if (jobCount == 0) { // TODO: display dialog MGlobal::displayError("[ExocortexAlembic] No jobs specified."); MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no job specified"); return status; } else { // get all of the jobstrings for (unsigned int i = 0; i < jobCount; i++) { MArgList jobArgList; argData.getFlagArgumentList("jobArg", i, jobArgList); jobStrings.append(jobArgList.asString(0)); } } // create a vector to store the jobs std::vector<AlembicWriteJob *> jobPtrs; double minFrame = 1000000.0; double maxFrame = -1000000.0; double maxSteps = 1; double maxSubsteps = 1; // init the curve accumulators AlembicCurveAccumulator::Initialize(); try { // for each job, check the arguments bool failure = false; for (unsigned int i = 0; i < jobStrings.length(); ++i) { double frameIn = 1.0; double frameOut = 1.0; double frameSteps = 1.0; double frameSubSteps = 1.0; MString filename; bool purepointcache = false; bool normals = true; bool uvs = true; bool facesets = true; bool bindpose = true; bool dynamictopology = false; bool globalspace = false; bool withouthierarchy = false; bool transformcache = false; bool useInitShadGrp = false; bool useOgawa = false; // Later, will need to be changed! MStringArray objectStrings; std::vector<std::string> prefixFilters; std::set<std::string> attributes; std::vector<std::string> userPrefixFilters; std::set<std::string> userAttributes; MObjectArray objects; std::string search_str, replace_str; // process all tokens of the job MStringArray tokens; jobStrings[i].split(';', tokens); for (unsigned int j = 0; j < tokens.length(); j++) { MStringArray valuePair; tokens[j].split('=', valuePair); if (valuePair.length() != 2) { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } const MString &lowerValue = valuePair[0].toLowerCase(); if (lowerValue == "in") { frameIn = valuePair[1].asDouble(); } else if (lowerValue == "out") { frameOut = valuePair[1].asDouble(); } else if (lowerValue == "step") { frameSteps = valuePair[1].asDouble(); } else if (lowerValue == "substep") { frameSubSteps = valuePair[1].asDouble(); } else if (lowerValue == "normals") { normals = valuePair[1].asInt() != 0; } else if (lowerValue == "uvs") { uvs = valuePair[1].asInt() != 0; } else if (lowerValue == "facesets") { facesets = valuePair[1].asInt() != 0; } else if (lowerValue == "bindpose") { bindpose = valuePair[1].asInt() != 0; } else if (lowerValue == "purepointcache") { purepointcache = valuePair[1].asInt() != 0; } else if (lowerValue == "dynamictopology") { dynamictopology = valuePair[1].asInt() != 0; } else if (lowerValue == "globalspace") { globalspace = valuePair[1].asInt() != 0; } else if (lowerValue == "withouthierarchy") { withouthierarchy = valuePair[1].asInt() != 0; } else if (lowerValue == "transformcache") { transformcache = valuePair[1].asInt() != 0; } else if (lowerValue == "filename") { filename = valuePair[1]; } else if (lowerValue == "objects") { // try to find each object valuePair[1].split(',', objectStrings); } else if (lowerValue == "useinitshadgrp") { useInitShadGrp = valuePair[1].asInt() != 0; } // search/replace else if (lowerValue == "search") { search_str = valuePair[1].asChar(); } else if (lowerValue == "replace") { replace_str = valuePair[1].asChar(); } else if (lowerValue == "ogawa") { useOgawa = valuePair[1].asInt() != 0; } else if (lowerValue == "attrprefixes") { splitListArg(valuePair[1], prefixFilters); } else if (lowerValue == "attrs") { splitListArg(valuePair[1], attributes); } else if (lowerValue == "userattrprefixes") { splitListArg(valuePair[1], userPrefixFilters); } else if (lowerValue == "userattrs") { splitListArg(valuePair[1], userAttributes); } else { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } } // now check the object strings for (unsigned int k = 0; k < objectStrings.length(); k++) { MSelectionList sl; MString objectString = objectStrings[k]; sl.add(objectString); MDagPath dag; for (unsigned int l = 0; l < sl.length(); l++) { sl.getDagPath(l, dag); MObject objRef = dag.node(); if (objRef.isNull()) { MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" + objectStrings[k] + "', not found."); break; } // get all parents MObjectArray parents; // check if this is a camera bool isCamera = false; for (unsigned int m = 0; m < dag.childCount(); ++m) { MFnDagNode child(dag.child(m)); MFn::Type ctype = child.object().apiType(); if (ctype == MFn::kCamera) { isCamera = true; break; } } if (dag.node().apiType() == MFn::kTransform && !isCamera && !globalspace && !withouthierarchy) { MDagPath ppath = dag; while (!ppath.node().isNull() && ppath.length() > 0 && ppath.isValid()) { parents.append(ppath.node()); if (ppath.pop() != MStatus::kSuccess) { break; } } } else { parents.append(dag.node()); } // push all parents in while (parents.length() > 0) { bool found = false; for (unsigned int m = 0; m < objects.length(); m++) { if (objects[m] == parents[parents.length() - 1]) { found = true; break; } } if (!found) { objects.append(parents[parents.length() - 1]); } parents.remove(parents.length() - 1); } // check all of the shapes below if (!transformcache) { sl.getDagPath(l, dag); for (unsigned int m = 0; m < dag.childCount(); m++) { MFnDagNode child(dag.child(m)); if (child.isIntermediateObject()) { continue; } objects.append(child.object()); } } } } // check if we have incompatible subframes if (maxSubsteps > 1.0 && frameSubSteps > 1.0) { const double part = (frameSubSteps > maxSubsteps) ? (frameSubSteps / maxSubsteps) : (maxSubsteps / frameSubSteps); if (abs(part - floor(part)) > 0.001) { MString frameSubStepsStr, maxSubstepsStr; frameSubStepsStr.set(frameSubSteps); maxSubstepsStr.set(maxSubsteps); MGlobal::displayError( "[ExocortexAlembic] You cannot combine substeps " + frameSubStepsStr + " and " + maxSubstepsStr + " in one export. Aborting."); return MStatus::kInvalidParameter; } } // remember the min and max values for the frames if (frameIn < minFrame) { minFrame = frameIn; } if (frameOut > maxFrame) { maxFrame = frameOut; } if (frameSteps > maxSteps) { maxSteps = frameSteps; } if (frameSteps > 1.0) { frameSubSteps = 1.0; } if (frameSubSteps > maxSubsteps) { maxSubsteps = frameSubSteps; } // check if we have a filename if (filename.length() == 0) { MGlobal::displayError("[ExocortexAlembic] No filename specified."); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no filename " "specified"); return MStatus::kFailure; } // construct the frames MDoubleArray frames; { const double frameIncr = frameSteps / frameSubSteps; for (double frame = frameIn; frame <= frameOut; frame += frameIncr) { frames.append(frame); } } AlembicWriteJob *job = new AlembicWriteJob(filename, objects, frames, useOgawa, prefixFilters, attributes, userPrefixFilters, userAttributes); job->SetOption("exportNormals", normals ? "1" : "0"); job->SetOption("exportUVs", uvs ? "1" : "0"); job->SetOption("exportFaceSets", facesets ? "1" : "0"); job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0"); job->SetOption("exportBindPose", bindpose ? "1" : "0"); job->SetOption("exportPurePointCache", purepointcache ? "1" : "0"); job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0"); job->SetOption("indexedNormals", "1"); job->SetOption("indexedUVs", "1"); job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0"); job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0"); job->SetOption("transformCache", transformcache ? "1" : "0"); // check if the search/replace strings are valid! if (search_str.length() ? !replace_str.length() : replace_str.length()) // either search or // replace string is // missing or empty! { ESS_LOG_WARNING( "Missing search or replace parameter. No strings will be " "replaced."); job->replacer = SearchReplace::createReplacer(); } else { job->replacer = SearchReplace::createReplacer(search_str, replace_str); } // check if the job is satifsied if (job->PreProcess() != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied."); delete (job); failure = true; break; } // push the job to our registry MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" + jobStrings[i]); jobPtrs.push_back(job); } if (failure) { for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } return MS::kFailure; } // compute the job count unsigned int jobFrameCount = 0; for (size_t i = 0; i < jobPtrs.size(); i++) jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() * (unsigned int)jobPtrs[i]->GetFrames().size(); // now, let's run through all frames, and process the jobs const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit()); const double incrSteps = maxSteps / maxSubsteps; double nextFrame = minFrame + incrSteps; for (double frame = minFrame; frame <= maxFrame; frame += incrSteps, nextFrame += incrSteps) { MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds)); MAnimControl::setAnimationEndTime( MTime(nextFrame / frameRate, MTime::kSeconds)); MAnimControl::playForward(); // this way, it forces Maya to play exactly // one frame! and particles are updated! AlembicCurveAccumulator::StartRecordingFrame(); for (size_t i = 0; i < jobPtrs.size(); i++) { MStatus status = jobPtrs[i]->Process(frame); if (status != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job aborted :" + jobPtrs[i]->GetFileName()); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); return status; } } AlembicCurveAccumulator::StopRecordingFrame(); } } catch (...) { MGlobal::displayError( "[ExocortexAlembic] Jobs aborted, force closing all archives!"); for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin(); beg != jobPtrs.end(); ++beg) { (*beg)->forceCloseArchive(); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); MPxCommand::setResult("Error caught in AlembicExportCommand::doIt"); status = MS::kFailure; } MAnimControl::stop(); AlembicCurveAccumulator::Destroy(); // restore the animation start/end time and the current time! restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); // delete all jobs for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } // remove all known archives deleteAllArchives(); return status; }
MString PRTAttrs::longName(const MString& attrName) { return prtu::toCleanId(attrName.substring(attrName.index('$') + 1, attrName.length())); }
//----------------------------------------------------------------------------- // Purpose: Export the specified bits of the maya scene into the specified file // Input : mArgDatabase The command line arguments as passed // Output : MS::kSuccess if ok, MS::kFailure otherwise //----------------------------------------------------------------------------- MStatus CVstSmdIOCmd::DoImport( const MArgDatabase &mArgDatabase ) { MString optFilename; if ( mArgDatabase.getFlagArgument( kOptFilename, 0, optFilename ) != MS::kSuccess || optFilename.length() == 0 ) { MGlobal::displayError( "No filename specified for import" ); return MS::kFailure; } MString optGame; if ( mArgDatabase.isFlagSet( kOptGame ) ) { mArgDatabase.getFlagArgument( kOptGame, 0, optGame ); } MString optTextureArchive; if ( mArgDatabase.isFlagSet( kOptTextureArchive ) ) { mArgDatabase.getFlagArgument( kOptTextureArchive, 0, optTextureArchive ); } CQcData qcData; char fullPath[ MAX_PATH ]; if ( !_fullpath( fullPath, optFilename.asChar(), sizeof( fullPath ) ) ) { strncpy( fullPath, optFilename.asChar(), sizeof( fullPath ) ); } qcData.GetQcData( fullPath ); if ( mArgDatabase.isFlagSet( kOptUpAxis ) ) { MString upAxis; mArgDatabase.getFlagArgument( kOptUpAxis, 0, upAxis ); switch ( *upAxis.asChar() ) { case 'x': case 'X': qcData.m_upAxis = 0; break; case 'y': case 'Y': qcData.m_upAxis = 1; break; case 'z': case 'Z': default: qcData.m_upAxis = 2; break; } } CSmdImport smdImport( optGame.asChar(), optTextureArchive.asChar() ); if ( mArgDatabase.isFlagSet( kOptImportSkeleton ) && !mArgDatabase.isFlagSet( kOptVmf ) ) { mArgDatabase.getFlagArgument( kOptImportSkeleton, 0, smdImport.m_optImportSkeleton ); } smdImport.SetNodeAddPrefix( GetNodeAddPrefix( mArgDatabase ) ); smdImport.SetNodeDelPrefix( GetNodeDelPrefix( mArgDatabase ) ); if ( mArgDatabase.isFlagSet( kOptImportType ) ) { MString optImportType; if ( mArgDatabase.getFlagArgument( kOptImportType, 0, optImportType ) && ( *optImportType.asChar() == 'a' || *optImportType.asChar() == 'A' || *optImportType.asChar() == 's' || *optImportType.asChar() == 'S' ) ) { MSelectionList mSelectionList; mArgDatabase.getObjects( mSelectionList ); MDagPath rootDagPath; if ( mSelectionList.length() && mSelectionList.getDagPath( 0, rootDagPath ) ) { return smdImport.ImportAnimation( optFilename.asChar(), rootDagPath, qcData, m_undo ); } else { merr << "Cannot import animation without the root of the skeleton is selected or specified" << std::endl; return MS::kFailure; } } } MTransformationMatrix topLevel; if ( mArgDatabase.isFlagSet( kOptOrigin ) ) { MVector o; mArgDatabase.getFlagArgument( kOptOrigin, 0, o.x ); mArgDatabase.getFlagArgument( kOptOrigin, 1, o.y ); mArgDatabase.getFlagArgument( kOptOrigin, 2, o.z ); topLevel.setTranslation( o, MSpace::kObject ); } if ( mArgDatabase.isFlagSet( kOptAngles ) ) { MVector a; if ( mArgDatabase.isFlagSet( kOptVmf ) ) { // The angles are specified in Yaw Pitch Roll order ( YZX ) // but they're still an XYZ rotation mArgDatabase.getFlagArgument( kOptAngles, 0, a.y ); mArgDatabase.getFlagArgument( kOptAngles, 1, a.z ); mArgDatabase.getFlagArgument( kOptAngles, 2, a.x ); } else { mArgDatabase.getFlagArgument( kOptAngles, 0, a.x ); mArgDatabase.getFlagArgument( kOptAngles, 1, a.y ); mArgDatabase.getFlagArgument( kOptAngles, 2, a.z ); } const MEulerRotation e( a.x / 180.0 * M_PI, a.y / 180.0 * M_PI, a.z / 180.0 * M_PI, MEulerRotation::kXYZ ); topLevel.rotateBy( e.asQuaternion(), MSpace::kObject ); } if ( mArgDatabase.isFlagSet( kOptVmf ) ) { if ( qcData.m_upAxis == 1U ) { topLevel.rotateBy( MEulerRotation( 90.0 / 180.0 * M_PI, 0.0, 90.0 / 180.0 * M_PI ).asQuaternion(), MSpace::kObject ); } else { topLevel.rotateBy( MEulerRotation( 0.0, 0.0, 90.0 / 180.0 * M_PI ).asQuaternion(), MSpace::kObject ); } } else { switch ( qcData.m_upAxis ) { case 0U: // X Up if ( MGlobal::isYAxisUp() ) { topLevel.rotateBy( MEulerRotation( -M_PI / 2.0, M_PI / 2.0, 0.0 ).asQuaternion(), MSpace::kObject ); } else { topLevel.rotateBy( MEulerRotation( 0.0, M_PI / 2.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; case 1U: // Y Up if ( MGlobal::isZAxisUp() ) { topLevel.rotateBy( MEulerRotation( M_PI / 2.0, 0.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; default: case 2U: // Z Up if ( MGlobal::isYAxisUp() ) { topLevel.rotateBy( MEulerRotation( -M_PI / 2.0, 0.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; } } MDagPath mDagPath( smdImport.DoIt( optFilename.asChar(), qcData, topLevel, m_undo ) ); if ( mDagPath.isValid() && mDagPath.length() ) { if ( mArgDatabase.isFlagSet( kOptVmf ) ) { MFnNumericAttribute nFn; MObject aObj( nFn.create( "yUp", "yUp", MFnNumericData::kBoolean, false ) ); MDagPath sDagPath( mDagPath ); sDagPath.extendToShapeDirectlyBelow( 0 ); m_undo.DagModifier().addAttribute( sDagPath.node(), aObj ); m_undo.DagModifierDoIt(); MPlug aP( sDagPath.node(), aObj ); if ( qcData.m_upAxis == 1U ) { aP.setValue( true ); } else { aP.setValue( false ); } } m_undo.SaveCurrentSelection(); MGlobal::select( mDagPath, MObject::kNullObj, MGlobal::kReplaceList ); setResult( mDagPath.partialPathName() ); m_undo.SaveCurrentSelection(); return MS::kSuccess; } m_undo.Undo(); return MS::kFailure; }
MStatus cgfxShaderCmd::doCmd(const MArgList& args) // // Description: // implements the MEL cgfxShader command. // // Arguments: // -fx/fxFile The CgFX file to load. // -e/edit Edit an existing cgfxShader rather than creating // a new one. // -q/query Get specified info // // Return Value: // MS::kSuccess - command succeeded // MS::kFailure - command failed (returning this value will cause the // MEL script that is being run to terminate unless the // error is caught using a "catch" statement. // { // Get the current state of the flag // and store it in a temporary variable // static int tmpFlag = -1; #if defined(_WIN32) && defined(CGFX_DEBUG_MEMORY) if (tmpFlag == -1) { tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); // Turn On (OR) - call _CrtCheckMemory at every // allocation request tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF; // Turn on (OR) - check for memory leaks at end // of program. tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tmpFlag ); } #endif /* _WIN32 && CGFX_DEBUG_MEMORY */ MStatus status; MSelectionList selList; MObject oNode; MString sResult; MStringArray saResult; MString sFeedback; MString sTemp; MString sWho = "cgfxShader : "; status = parseArgs(args, selList); if (!status) { return status; } // -pp / -pluginPath // Returns the directory path where this plug-in's auxiliary // files, such as MEL scripts, are expected to be found. // The path name is in Maya format ('/' delimited) with no // trailing slash. Result type is string. (Query only) if ( fPluginPath ) { setResult( sPluginPath ); return MS::kSuccess; } // -lp / -listProfiles // // Return the names of the profiles supported on the current // platform. // // Each item in the result array has the form // "VertexProfileName<,GeometryProfileName,FragmentProfileName" // // Result type is string[]. (Query only; set internally) if ( fListProfiles ) { setResult( cgfxProfile::getProfileList() ); return status; } // -mtc / -maxTexCoords // Returns the maximum number of texcoord inputs that can be // passed to vertex shaders under the currently installed // OpenGL implementation. Returns 0 if the information is // not available. Result type is integer. (Query only) // // Don't use GL_MAX_TEXTURE_UNITS as this does not provide a proper // count when the # of image or texcoord inputs differs // from the conventional (older) notion of texture unit. // // Instead take the minimum of GL_MAX_TEXTURE_COORDS_ARB and // GL_MAX_TEXUTRE_IMAGE_UNITS_ARB according to the // ARB_FRAGMENT_PROGRAM specification. if ( fMaxTexCoords ) { GLint mtc = 0; M3dView vw = M3dView::active3dView( &status ); if ( status && vw.beginGL() ) { glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &mtc ); GLint mic = 0; glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &mic ); if (mic < mtc) mtc = mic; if ( mtc < 1 ) mtc = 1; else if ( mtc > CGFXSHADERNODE_GL_TEXTURE_MAX ) mtc = CGFXSHADERNODE_GL_TEXTURE_MAX; vw.endGL(); } setResult( (int)mtc ); return MS::kSuccess; } // If edit or query, find the specified cgfxShaderNode. MFnDependencyNode fnNode; cgfxShaderNode* pNode = NULL; if ( fIsEdit || fIsQuery ) { // We are editing an existing node which must have been // provided in the args (or the current selection list). // Get the correct node name into fNodeName; // if (selList.length() != 1) { status = MS::kNotFound; return status; } // Get the name of the node into fNodeName so that it can // be saved for undo/redo // MStringArray tmpList; selList.getSelectionStrings(tmpList); fNodeName = tmpList[0]; if ( fNodeName.length() ) { sWho += " \""; sWho += fNodeName; sWho += "\""; } status = selList.getDependNode(0, oNode); if (!status) { return status; } status = fnNode.setObject( oNode ); if (!status) { sFeedback = sWho; sFeedback += " is not a cgfxShader node."; MGlobal::displayError( sFeedback ); return status; } if (fnNode.typeId() != cgfxShaderNode::sId) { status = MS::kInvalidParameter; sFeedback = sWho; sFeedback += " is not a cgfxShader node."; MGlobal::displayError( sFeedback ); return status; } pNode = (cgfxShaderNode*)fnNode.userNode(); if (!pNode) { status = MS::kInvalidParameter; sFeedback = sWho; sFeedback += " is not cgfxShader node."; MGlobal::displayError( sFeedback ); return status; } } if ( fIsQuery ) { // -fx / -fxFile // Returns the shader file name. if ( fFxFile ) { MString path = pNode->shaderFxFile(); setResult( path ); return MS::kSuccess; } // -fxp / -fxPath // Returns the path of the fx file. The path name is in Maya // format ('/' delimited). Result type is string. // (Query only) if ( fFxPath ) { MString path = cgfxFindFile(pNode->shaderFxFile()); setResult( path ); return MS::kSuccess; } // -t / -technique // Returns the currently active technique if ( fTechnique ) { MString path = pNode->getTechnique(); setResult( path ); return MS::kSuccess; } // -p / -profile // Returns the current profile if ( fProfile ) { MString path = pNode->getProfile(); setResult( path ); return MS::kSuccess; } // -lt / -listTechniques // Return the technique names defined by the current effect. // // Each item in the result array has the form // "techniqueName<TAB>numPasses" // where // numPasses is the number of passes defined by the // technique, or 0 if the technique is not valid. // (Future versions of the cgfxShader plug-in may append // additional tab-separated fields.) // // Result type is string[]. (Query only; set internally) if ( fListTechniques ) { setResult( pNode->getTechniqueList() ); return status; } // -lp / -listParameters // Return the attribute names corresponding to the // shader's tweakable uniform parameters. // Result type is string[]. (Query only; set internally) // -des / -description // If specified, each item in the result array has the form // "attrName<TAB>type<TAB>semantic<TAB>description<TAB>extraAttrSuffix" // (Future versions of the cgfxShader plug-in may provide // additional tab-separated fields after the semantic.) // A missing field is indicated by a single space (" ") // so the string can be parsed more easily using the MEL // "tokenize" function, which treats a group of consecutive // delimiters the same as a single delimiter. if ( fListParameters ) { cgfxRCPtr<cgfxAttrDefList> list = cgfxAttrDef::attrsFromNode( oNode ); for ( cgfxAttrDefList::iterator it = list; it; ++it ) { cgfxAttrDef* aDef = *it; if ( fDescription ) { sResult = aDef->fName.length() ? aDef->fName : " "; sResult += "\t"; sTemp = aDef->typeName(); sResult += sTemp.length() ? sTemp : " "; sResult += "\t"; sResult += aDef->fSemantic.length() ? aDef->fSemantic : " "; sResult += "\t"; sResult += aDef->fDescription.length() ? aDef->fDescription : " "; sResult += "\t"; const char* suffix = aDef->getExtraAttrSuffix(); sResult += suffix ? suffix : " "; } else sResult = aDef->fName; saResult.append( sResult ); } setResult( saResult ); return status; } // -p / -parameter <name> // Return a string describing the data type and usage of // the attribute whose name is specified. // Result type is string (with no -description flag), or // string array (if you specify -description). // (Query only; set internally) // -ci / -caseInsensitive // If specified, returns information for the first // attribute that matches the specified name assuming // no distinction between upper and lower case letters. // -des / -description // If specified, the result is a string array containing: // [0] = attribute name // [1] = type // [2] = semantic // [3] = description from "desc" or "uiname" annotation // [4] = extra attribute suffix for Vector4 ("W") / Color4 ("Alpha") // (Future versions of the cgfxShader plug-in may provide // additional tab-separated fields after the semantic.) // If omitted, only the type is returned (a string). if ( fParameterName.length() > 0 ) { cgfxRCPtr<cgfxAttrDefList> list = cgfxAttrDef::attrsFromNode( oNode ); cgfxAttrDefList::iterator it; if ( fCaseInsensitive ) it = list->findInsensitive( fParameterName ); else it = list->find( fParameterName ); if ( fDescription ) { if ( it ) { cgfxAttrDef* aDef = *it; saResult.append( aDef->fName ); saResult.append( aDef->typeName() ); saResult.append( aDef->fSemantic ); saResult.append( aDef->fDescription ); const char* suffix = aDef->getExtraAttrSuffix(); saResult.append( suffix ? suffix : "" ); } setResult( saResult ); } else { if ( it ) sResult = (*it)->typeName(); setResult( sResult ); } return status; } // -euv / -emptyUV // Returns the names of blacklisted UV sets. These UV sets // are disabled from being passed to the shader because there // is at least one mesh where the UV set name is defined but // has no faces mapped. Due to a bug in Maya (in 5.0 and // possibly some other releases), Maya crashes if an empty // UV set is accessed by a hardware shader. Blacklisting is // intended to protect the user against accidentally hitting // the bug and crashing Maya. After the Maya fix has been // verified, this option can continue to be accepted for awhile // for compatibility, returning an empty result array. // Result type is string[]. (Query only; set internally) if ( fEmptyUV ) { setResult( pNode->getEmptyUVSets() ); return MS::kSuccess; } // -eus / -emptyUVShapes // Returns the names of shape nodes that have empty UV sets // which are causing the UV set names to be blacklisted. // After the Maya bug fix has been verified, this option // can remain for awhile for compatibility, returning an // empty result array. // Result type is string[]. (Query only; set internally) if ( fEmptyUVShapes ) { const MObjectArray& oaShapes = pNode->getEmptyUVSetShapes(); MFnDagNode fnDagNode; MDagPath dpShape; for ( unsigned iShape = 0; iShape < oaShapes.length(); ++iShape ) { fnDagNode.setObject( oaShapes[ iShape ] ); fnDagNode.getPath( dpShape ); saResult.append( dpShape.partialPathName() ); } setResult( saResult ); return MS::kSuccess; } // -tcs / -texCoordSource // Returns the value of the texCoordSource attribute, because // the MEL "getAttr" command doesn't work with string arrays. // Result type is string[]. (Query only; set via "setAttr") if ( fTexCoordSource ) { setResult( pNode->getTexCoordSource() ); return MS::kSuccess; } #if MAYA_API_VERSION >= 700 // -cs / -colorSource // Returns the value of the colorSource attribute, because // the MEL "getAttr" command doesn't work with string arrays. // Result type is string[]. (Query only; set via "setAttr") if ( fColorSource ) { setResult( pNode->getColorSource() ); return MS::kSuccess; } #endif // Error if -q with no other query flags. return MS::kInvalidParameter; } // If user didn't specify shader fx file, default to current // value of our cgfxShader node's "shader" attribute. if (!fFxFile && pNode) fNewFxFile = pNode->shaderFxFile(); // If user didn't specify technique name, default to current // value of our cgfxShader node's "technique" attribute. // // If a new fx file has been specified without a technique, we // leave the technique name empty so that the first technique of // the effect will be selected. if (!fTechnique && pNode) fNewTechnique = pNode->getTechnique(); // If user didn't specify profile name, default to current // value of our cgfxShader node's "profile" attribute. if (!fProfile && pNode) fNewProfile = pNode->getProfile(); // // Load the effect from the .fx file. // if (fFxFile) { // Attempt to read the new fEffect from the file // MString file = cgfxFindFile(fNewFxFile); MString projectFile = cgfxFindFile(fNewFxFile, true); // Compile and create the effect. fNewEffect = cgfxEffect::loadEffect(file, cgfxProfile::getProfile(fNewProfile)); //// Set the device. if (fNewEffect->isValid()) { // There is no current view in batch mode, just return // success then const MGlobal::MMayaState mayaState = MGlobal::mayaState(&status); if ( !status ) return status; if ( mayaState == MGlobal::kBatch ) return MS::kSuccess; fNewFxFile = projectFile; M3dView view = M3dView::active3dView(); // The M3dView class doesn't return the correct status if // there isn't an active 3D view, so we rely on the // success of beginGL() which will make the context // current. // if (!view.beginGL()) { MString es = "There is no active view to bind " + sWho + " to."; MGlobal::displayWarning( es ); return MS::kSuccess; } view.endGL(); } // Tell user if successful. if (fNewEffect->isValid()) { sFeedback = sWho; sFeedback += " loaded effect \""; sFeedback += file; sFeedback += "\""; MGlobal::displayInfo( sFeedback ); } else { sFeedback = sWho; sFeedback += " unable to load effect \""; sFeedback += file.length() ? file : fNewFxFile; sFeedback += "\""; MGlobal::displayError( sFeedback ); return MS::kFailure; } } // Create an MDGModifier to hold an agenda of operations to be // performed to update the DG. We build the agenda here; // then invoke it to do/redo/undo the updates. fDagMod = new MDGModifier; // Create new cgfxShader node if requested. if ( !fIsEdit ) { // Create node. oNode = fDagMod->createNode(cgfxShaderNode::sId, &status); M_CHECK( status ); if ( fNodeName.length() > 0 ) { status = fDagMod->renameNode(oNode, fNodeName); M_CHECK( status ); } status = fnNode.setObject( oNode ); M_CHECK( status && fnNode.typeId() == cgfxShaderNode::sId ); pNode = (cgfxShaderNode*)fnNode.userNode(); M_CHECK( pNode ); // On successful completion, redoCmd() will select the new node. // Save old selection for undo. status = MGlobal::getActiveSelectionList( fOldSelection ); M_CHECK( status ); } if (fFxFile) { // Save the current state of the node for undo purposes fOldFxFile = pNode->shaderFxFile(); fOldEffect = pNode->effect(); // save old CGeffect cgfxShaderNode::NodeList nodes; // getNodesToUpdate will return the list of nodes that will need to be updated : // if the new fx file is the same as the old fx file, the action is considered a reload, // we'll gather all the nodes that are using the old effect and reload them all. // else the effect file is different and only the current node will be updated. getNodesToUpdate(fOldEffect, pNode, nodes); cgfxShaderNode::NodeList::const_iterator it = nodes.begin(); cgfxShaderNode::NodeList::const_iterator itEnd = nodes.end(); for(; it != itEnd; ++it) { cgfxShaderNode* node = *it; MStringArray &oldAttributeList = fOldAttributeList[node]; cgfxRCPtr<cgfxAttrDefList> &oldAttrDefList = fOldAttrDefList[node]; MStringArray &newAttributeList = fNewAttributeList[node]; cgfxRCPtr<cgfxAttrDefList> &newAttrDefList = fNewAttrDefList[node]; node->getAttributeList( oldAttributeList ); oldAttrDefList = node->attrDefList(); // save old cgfxAttrDefList ptr // Now figure out what to do with the node. // // updateNode does a fair amount of work. First, it gets the // cgfxAttrDefList from the effect. Then it gets the equivalent // list from the node itself. It determines which attributes need // to be added and which need to be deleted and fills in all the // changes in the MDagModifier fDagMod. Then it builds a new value // for the attributeList attribute. Finally, it builds a new // value for the attrDefList internal value. All these values are // returned here where we can set them into the node. // cgfxAttrDef::updateNode( fNewEffect, // IN node, // IN fDagMod, // UPD newAttrDefList, // OUT newAttributeList ); // OUT } } // Save a reference to the node in a selection list for undo/redo. status = fNodeSelection.add( oNode ); M_CHECK( status ); // Save the current state of the node for undo purposes fOldTechnique = pNode->getTechnique(); fOldProfile = pNode->getProfile(); // I think we have all the information to redoIt(). // // Typically, the doIt() method only collects the infomation required // to do/undo the action and then stores it in class members. The // redo method is then called to do the actuall work. This prevents // code duplication. // return redoCmd( oNode, fnNode, pNode ); } // cgfxShaderCmd::doCmd
MStatus atomImport::reader( const MFileObject& file, const MString& options, FileAccessMode mode) { MStatus status = MS::kFailure; MString fileName = file.fullName(); #if defined (OSMac_) char fname[MAXPATHLEN]; strcpy (fname, fileName.asChar()); ifstream animFile(fname); #else ifstream animFile(fileName.asChar()); #endif // Parse the options. The options syntax is in the form of // "flag=val;flag1=val;flag2=val" // if(animFile.good()==false) return status; MString pasteFlags; MString prefix; MString suffix; MString search; MString replace; MString mapFile; bool replaceLayers = false; MString exportEditsFile; bool includeChildren = false; atomNodeNameReplacer::ReplaceType type = atomNodeNameReplacer::eHierarchy; MString templateName; MString viewName; bool useTemplate = false; if (options.length() > 0) { // Set up the flags for the paste command. // const MString flagSrcTime("srcTime"); const MString flagDstTime("dstTime"); const MString flagOldDstTime("time"); const MString flagCopies("copies"); const MString flagOption("option"); const MString flagConnect("connect"); const MString flagMatch("match"); const MString flagSearch("search"); const MString flagReplace("replace"); const MString flagPrefix("prefix"); const MString flagSuffix("suffix"); const MString flagMapFile("mapFile"); const MString flagHierarchy("hierarchy"); const MString flagString("string"); const MString flagSelected("selected"); const MString flagTemplate("template"); const MString flagView("view"); const MString optionChildrenToo("childrenToo"); const MString optionTemplate("template"); const MString flagExportEdits("exportEdits"); MString copyValue; MString flagValue; MString connectValue; MString match; MString srcTimeValue; MString dstTimeValue; // Start parsing. // MStringArray optionList; MStringArray theOption; options.split(';', optionList); unsigned nOptions = optionList.length(); for (unsigned i = 0; i < nOptions; i++) { theOption.clear(); optionList[i].split('=', theOption); if (theOption.length() < 1) { continue; } if (theOption[0] == flagCopies && theOption.length() > 1) { copyValue = theOption[1];; } else if (theOption[0] == flagOption && theOption.length() > 1) { flagValue = theOption[1]; } else if (theOption[0] == flagConnect && theOption.length() > 1) { if (theOption[1].asInt() != 0) { connectValue += theOption[1]; } } else if( theOption[0] == flagTemplate && theOption.length() > 1) { templateName = theOption[1]; } else if( theOption[0] == flagView && theOption.length() > 1) { viewName = theOption[1]; } else if (theOption[0] == flagSrcTime && theOption.length() > 1) { srcTimeValue += theOption[1]; } else if ((theOption[0] == flagDstTime || theOption[0] == flagOldDstTime )&& theOption.length() > 1) { dstTimeValue += theOption[1]; } else if (theOption[0] == flagMatch && theOption.length() > 1) { match = theOption[1]; } else if (theOption[0] == flagSearch && theOption.length() > 1) { search = theOption[1]; } else if (theOption[0] == flagReplace && theOption.length() > 1) { replace = theOption[1]; } else if (theOption[0] == flagPrefix && theOption.length() > 1) { prefix = theOption[1]; } else if (theOption[0] == flagSuffix && theOption.length() > 1) { suffix = theOption[1]; } else if (theOption[0] == flagMapFile && theOption.length() > 1) { mapFile = theOption[1]; } else if (theOption[0] == flagSelected && theOption.length() > 1) { includeChildren = (theOption[1] == optionChildrenToo) ? true : false; if(theOption[1] == optionTemplate) useTemplate = true; } else if (theOption[0] == flagExportEdits && theOption.length() > 1) { exportEditsFile = theOption[1]; } } if (copyValue.length() > 0) { pasteFlags += " -copies "; pasteFlags += copyValue; pasteFlags += " "; } if (flagValue.length() > 0) { pasteFlags += " -option \""; pasteFlags += flagValue; pasteFlags += "\" "; if(flagValue == MString("replace")) replaceLayers = true; } if (connectValue.length() > 0) { pasteFlags += " -connect "; pasteFlags += connectValue; pasteFlags += " "; } if (dstTimeValue.length() > 0) { bool useQuotes = !dstTimeValue.isDouble(); pasteFlags += " -time "; if (useQuotes) pasteFlags += "\""; pasteFlags += dstTimeValue; if (useQuotes) pasteFlags += "\""; pasteFlags += " "; } if (srcTimeValue.length() > 0) { MTime lClipStartTime; MTime lClipEndTime; MStringArray lTimes; if ( MStatus::kSuccess == srcTimeValue.split( L':', lTimes ) ) { if ( lTimes.length() > 0 ) { double lImportStartFrame = lTimes[0].asDouble(); double lImportEndFrame = lImportStartFrame; if ( lTimes.length() > 1 ) { lImportEndFrame = lTimes[1].asDouble(); } fReader.setImportFrameRange( lImportStartFrame, lImportEndFrame ); } else { fReader.clearImportFrameRange(); } } } else { fReader.clearImportFrameRange(); } if(match.length() >0) { if(match == flagHierarchy) type = atomNodeNameReplacer::eHierarchy; else if(match == flagString) type = atomNodeNameReplacer::eSearchReplace; else if(match == flagMapFile) type = atomNodeNameReplacer::eMapFile; } //not set, then we leave what we had } // If the selection list is empty, there is nothing to import. // MSelectionList sList; std::vector<unsigned int> depths; atomTemplateReader templateReader; if(useTemplate == true) { templateReader.setTemplate(templateName,viewName); includeChildren = false; templateReader.selectNodes(); //make the selection set be us. } SelectionGetter::getSelectedObjects(includeChildren,sList,depths); if (sList.isEmpty()) { MString msg = MStringResource::getString(kNothingSelected, status); MGlobal::displayError(msg); return (MS::kFailure); } atomNodeNameReplacer replacer(type,sList,depths,prefix,suffix,search,replace,mapFile); if (mode == kImportAccessMode) { status = importAnim(sList,animFile,pasteFlags,replacer,exportEditsFile,templateReader,replaceLayers); } animFile.close(); return status; }
void EntityNode::LoadArt() { MStatus stat; bool callbackRemoved = false; if( s_EditNodeAddedCBId != -1 ) { MDGMessage::removeCallback( s_EditNodeAddedCBId ); s_EditNodeAddedCBId = -1; callbackRemoved = true; } UnloadArt(); MString artFilePath; GetArtFilePath( artFilePath ); std::cout << "Importing from: " << artFilePath.asTChar() << "..." << std::endl; // add the callback to catch all the imported objects MObjectArray objectArrays[NodeArrays::Count]; s_ImportNodeAddedCBId = MDGMessage::addNodeAddedCallback( ImportNodeAddedCallback, kDefaultNodeType, &objectArrays ); // import stuff MFileIO::import( artFilePath, NULL, false ); // remove the callback MDGMessage::removeCallback( s_ImportNodeAddedCBId ); // add all imported stuff under this guy's transform MFnDagNode nodeFn( thisMObject() ); for( u32 i=0; i<objectArrays[NodeArrays::KeepNodes].length(); ++i ) { if( objectArrays[NodeArrays::KeepNodes][i].isNull() ) { continue; } MObjectHandle handle( objectArrays[NodeArrays::KeepNodes][i] ); if ( !handle.isValid() ) { continue; } // We should be getting only MFnDagNode in here, but just in case MFnDagNode dagFn( objectArrays[NodeArrays::KeepNodes][i], &stat ); if ( stat == MStatus::kSuccess ) { stat = dagFn.setDoNotWrite( true ); } else { MFnDependencyNode depNodeFn( objectArrays[NodeArrays::KeepNodes][i], &stat ); stat = depNodeFn.setDoNotWrite( true ); } #ifdef _DEBUG MString name = dagFn.name(); MString type = dagFn.typeName(); std::string nodeTypeStr( objectArrays[NodeArrays::KeepNodes][i].apiTypeStr() ); if ( name.length() ) { std::cout << " - Importing Child: " << name.asTChar() << " " << type.asTChar() << "(" << nodeTypeStr << ")" << std::endl; } #endif AddImportNode( objectArrays[NodeArrays::KeepNodes][i] ); nodeFn.addChild( objectArrays[NodeArrays::KeepNodes][i] ); } for( u32 i=0; i<objectArrays[NodeArrays::DeleteNodes].length(); ++i ) { MGlobal::deleteNode( objectArrays[NodeArrays::DeleteNodes][i] ); } MFnDagNode otherFn; for( u32 i=0 ; i<nodeFn.childCount(); ++i ) { MObject child = nodeFn.child( i ); if( !child.hasFn( MFn::kDagNode ) ) { continue; } otherFn.setObject( child ); if( otherFn.typeId() == EntityNode::s_TypeID ) { MDagModifier mod; u32 numChild = otherFn.childCount(); for( u32 j = 0; j < numChild; ++j ) { stat = mod.reparentNode( otherFn.child( j ), thisMObject() ); } mod.doIt(); MGlobal::deleteNode( child ); break; } } std::cout << "Done" << std::endl; }