Esempio n. 1
0
GlfImageSharedPtr
GlfImageRegistry::_ConstructImage(std::string const & filename)
{
    static GlfImageSharedPtr NULL_IMAGE;

    // Lookup the plug-in type name based on the prim type.
    TfToken fileExtension(TfStringGetSuffix(filename));

    TfType const & pluginType = _typeMap->Find(fileExtension);

    if (!pluginType) {
        // Unknown prim type.
        TF_DEBUG(GLF_DEBUG_TEXTURE_IMAGE_PLUGINS).Msg(
                "[PluginLoad] Unknown image type '%s'\n",
                fileExtension.GetText());
        return NULL_IMAGE;
    }

    PlugRegistry& plugReg = PlugRegistry::GetInstance();
    PlugPluginPtr plugin = plugReg.GetPluginForType(pluginType);
    if (!plugin || !plugin->Load()) {
        TF_CODING_ERROR("[PluginLoad] PlugPlugin could not be loaded for "
                "TfType '%s'\n",
                pluginType.GetTypeName().c_str());
        return NULL_IMAGE;
    }

    GlfImageFactoryBase* factory = pluginType.GetFactory<GlfImageFactoryBase>();
    if (!factory) {
        TF_CODING_ERROR("[PluginLoad] Cannot manufacture type '%s' "
                "for image type '%s'\n",
                pluginType.GetTypeName().c_str(),
                fileExtension.GetText());

        return NULL_IMAGE;
    }

    GlfImageSharedPtr instance = factory->New();
    if (!instance) {
        TF_CODING_ERROR("[PluginLoad] Cannot construct instance of type '%s' "
                "for image type '%s'\n",
                pluginType.GetTypeName().c_str(),
                fileExtension.GetText());
        return NULL_IMAGE;
    }

    TF_DEBUG(GLF_DEBUG_TEXTURE_IMAGE_PLUGINS).Msg(
    	        "[PluginLoad] Loaded plugin '%s' for image type '%s'\n",
                pluginType.GetTypeName().c_str(),
                fileExtension.GetText());

    return instance;
}
Esempio n. 2
0
GlfTextureHandleRefPtr
GlfTextureRegistry::_CreateTexture(const TfToken &texture)
{
    GlfTextureRefPtr result;
    if (GlfTextureFactoryBase* factory = _GetTextureFactory(texture)) {
        result = factory->New(texture);
        if (!result) {
            TF_CODING_ERROR("[PluginLoad] Cannot construct texture for "
                            "type '%s'\n",
                            TfStringGetSuffix(texture).c_str());
        }
    }
    return result ? GlfTextureHandle::New(result) : TfNullPtr;
}
Esempio n. 3
0
GlfTextureHandleRefPtr
GlfTextureRegistry::_CreateTexture(const TfTokenVector &textures,
                                   const size_t numTextures)
{
    GlfTextureRefPtr result;
    TfToken filename = textures.empty() ? TfToken() : textures.front();
    if (GlfTextureFactoryBase* factory = _GetTextureFactory(filename)) {
        result = factory->New(textures);
        if (!result) {
            TF_CODING_ERROR("[PluginLoad] Cannot construct texture for "
                            "type '%s'\n",
                            TfStringGetSuffix(filename).c_str());
        }
    }
    return result ? GlfTextureHandle::New(result) : TfNullPtr;
}
Esempio n. 4
0
GlfTextureFactoryBase*
GlfTextureRegistry::_GetTextureFactory(const TfToken &filename)
{
    // Lookup the plug-in type name based on the file extension.
    TfToken fileExtension(TfStringGetSuffix(filename));

    TfType pluginType = _typeMap->Find(fileExtension);
    if (!pluginType) {
        // Unknown type.  Try the wildcard.
        pluginType = _typeMap->Find(TfToken("*"));
        if (!pluginType) {
            TF_DEBUG(GLF_DEBUG_TEXTURE_PLUGINS).Msg(
                    "[PluginLoad] Unknown texture type '%s'\n",
                    fileExtension.GetText());
            return nullptr;
        }
    }

    PlugRegistry& plugReg = PlugRegistry::GetInstance();
    PlugPluginPtr plugin = plugReg.GetPluginForType(pluginType);
    if (!plugin || !plugin->Load()) {
        TF_CODING_ERROR("[PluginLoad] PlugPlugin could not be loaded for "
                        "TfType '%s'\n",
                        pluginType.GetTypeName().c_str());
        return nullptr;
    }

    TF_DEBUG(GLF_DEBUG_TEXTURE_IMAGE_PLUGINS).Msg(
    	        "[PluginLoad] Loaded plugin '%s' for texture type '%s'\n",
                pluginType.GetTypeName().c_str(),
                fileExtension.GetText());

    if (GlfTextureFactoryBase* factory =
            pluginType.GetFactory<GlfTextureFactoryBase>()) {
        return factory;
    }
    TF_CODING_ERROR("[PluginLoad] Cannot manufacture type '%s' "
                    "for texture type '%s'\n",
                    pluginType.GetTypeName().c_str(),
                    fileExtension.GetText());

    return nullptr;
}
Esempio n. 5
0
bool usdWriteJob::beginJob(const std::string &iFileName,
                         bool append,
                         double startTime,
                         double endTime)
{
    // Check for DAG nodes that are a child of an already specified DAG node to export
    // if that's the case, report the issue and skip the export
    PxrUsdMayaUtil::ShapeSet::const_iterator m, n;
    PxrUsdMayaUtil::ShapeSet::const_iterator endPath = mArgs.dagPaths.end();
    for (m = mArgs.dagPaths.begin(); m != endPath; ) {
        MDagPath path1 = *m; m++;
        for (n = m; n != endPath; n++) {
            MDagPath path2 = *n;
            if (PxrUsdMayaUtil::isAncestorDescendentRelationship(path1,path2)) {
                MString errorMsg = path1.fullPathName();
                errorMsg += " and ";
                errorMsg += path2.fullPathName();
                errorMsg += " have an ancestor relationship. Skipping USD Export.";
                MGlobal::displayError(errorMsg);
                return false;
            }
        }  // for n
    }  // for m

    // Make sure the file name is a valid one with a proper USD extension.
    const std::string iFileExtension = TfStringGetSuffix(iFileName, '.');
    if (iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault   || 
            iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionASCII || 
            iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionCrate) {
        mFileName = iFileName;
    } else {
        mFileName = TfStringPrintf("%s.%s",
                                   iFileName.c_str(),
                                   PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText());
    }

    MGlobal::displayInfo("usdWriteJob::beginJob: Create stage file "+MString(mFileName.c_str()));

    ArResolverContext resolverCtx = ArGetResolver().GetCurrentContext();
    if (append) {
        mStage = UsdStage::Open(SdfLayer::FindOrOpen(mFileName), resolverCtx);
        if (!mStage) {
            MGlobal::displayError("Failed to open stage file "+MString(mFileName.c_str()));
            return false;
            }
    } else {
        mStage = UsdStage::CreateNew(mFileName, resolverCtx);
        if (!mStage) {
            MGlobal::displayError("Failed to create stage file "+MString(mFileName.c_str()));
            return false;
        }
    }

    // Set time range for the USD file
    mStage->SetStartTimeCode(startTime);
    mStage->SetEndTimeCode(endTime);
    
    mModelKindWriter.Reset();

    // Setup the requested render layer mode:
    //     defaultLayer    - Switch to the default render layer before exporting,
    //                       then switch back afterwards (no layer switching if
    //                       the current layer IS the default layer).
    //     currentLayer    - No layer switching before or after exporting. Just
    //                       use whatever is the current render layer for export.
    //     modelingVariant - Switch to the default render layer before exporting,
    //                       and export each render layer in the scene as a
    //                       modeling variant, then switch back afterwards (no
    //                       layer switching if the current layer IS the default
    //                       layer). The default layer will be made the default
    //                       modeling variant.
    MFnRenderLayer currentLayer(MFnRenderLayer::currentLayer());
    mCurrentRenderLayerName = currentLayer.name();

    if (mArgs.renderLayerMode == PxUsdExportJobArgsTokens->modelingVariant) {
        // Handle usdModelRootOverridePath for USD Variants
        MFnRenderLayer::listAllRenderLayers(mRenderLayerObjs);
        if (mRenderLayerObjs.length() > 1) {
            mArgs.usdModelRootOverridePath = SdfPath("/_BaseModel_");
        }
    }

    // Switch to the default render layer unless the renderLayerMode is
    // 'currentLayer', or the default layer is already the current layer.
    if (mArgs.renderLayerMode != PxUsdExportJobArgsTokens->currentLayer &&
            MFnRenderLayer::currentLayer() != MFnRenderLayer::defaultRenderLayer()) {
        // Set the RenderLayer to the default render layer
        MFnRenderLayer defaultLayer(MFnRenderLayer::defaultRenderLayer());
        MGlobal::executeCommand(MString("editRenderLayerGlobals -currentRenderLayer ")+
                                        defaultLayer.name(), false, false);
    }

    // Pre-process the argument dagPath path names into two sets. One set
    // contains just the arg dagPaths, and the other contains all parents of
    // arg dagPaths all the way up to the world root. Partial path names are
    // enough because Maya guarantees them to still be unique, and they require
    // less work to hash and compare than full path names.
    TfHashSet<std::string, TfHash> argDagPaths;
    TfHashSet<std::string, TfHash> argDagPathParents;
    PxrUsdMayaUtil::ShapeSet::const_iterator end = mArgs.dagPaths.end();
    for (PxrUsdMayaUtil::ShapeSet::const_iterator it = mArgs.dagPaths.begin();
            it != end; ++it) {
        MDagPath curDagPath = *it;
        std::string curDagPathStr(curDagPath.partialPathName().asChar());
        argDagPaths.insert(curDagPathStr);

        while (curDagPath.pop() && curDagPath.length() >= 0) {
            curDagPathStr = curDagPath.partialPathName().asChar();
            if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) {
                // We've already traversed up from this path.
                break;
            }
            argDagPathParents.insert(curDagPathStr);
        }
    }

    // Now do a depth-first traversal of the Maya DAG from the world root.
    // We keep a reference to arg dagPaths as we encounter them.
    MDagPath curLeafDagPath;
    for (MItDag itDag(MItDag::kDepthFirst, MFn::kInvalid); !itDag.isDone(); itDag.next()) {
        MDagPath curDagPath;
        itDag.getPath(curDagPath);
        std::string curDagPathStr(curDagPath.partialPathName().asChar());

        if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) {
            // This dagPath is a parent of one of the arg dagPaths. It should
            // be included in the export, but not necessarily all of its
            // children should be, so we continue to traverse down.
        } else if (argDagPaths.find(curDagPathStr) != argDagPaths.end()) {
            // This dagPath IS one of the arg dagPaths. It AND all of its
            // children should be included in the export.
            curLeafDagPath = curDagPath;
        } else if (!MFnDagNode(curDagPath).hasParent(curLeafDagPath.node())) {
            // This dagPath is not a child of one of the arg dagPaths, so prune
            // it and everything below it from the traversal.
            itDag.prune();
            continue;
        }

        MayaPrimWriterPtr primWriter = nullptr;
        if (!createPrimWriter(curDagPath, &primWriter) &&
                curDagPath.length() > 0) {
            // This dagPath and all of its children should be pruned.
            itDag.prune();
            continue;
        }

        if (primWriter) {
            mMayaPrimWriterList.push_back(primWriter);

            // Write out data (non-animated/default values).
            if (UsdPrim usdPrim = primWriter->write(UsdTimeCode::Default())) {
                MDagPath dag = primWriter->getDagPath();
                mDagPathToUsdPathMap[dag] = usdPrim.GetPath();

                // If we are merging transforms and the object derives from
                // MayaTransformWriter but isn't actually a transform node, we
                // need to add its parent.
                if (mArgs.mergeTransformAndShape) {
                    MayaTransformWriterPtr xformWriter =
                            boost::dynamic_pointer_cast<MayaTransformWriter>(
                                    primWriter);
                    if (xformWriter) {
                        MDagPath xformDag = xformWriter->getTransformDagPath();
                        mDagPathToUsdPathMap[xformDag] = usdPrim.GetPath();
                    }
                }

                mModelKindWriter.OnWritePrim(usdPrim, primWriter);

                if (primWriter->shouldPruneChildren()) {
                    itDag.prune();
                }
            }
        }
    }

    // Writing Materials/Shading
    PxrUsdMayaTranslatorMaterial::ExportShadingEngines(
                mStage, 
                mArgs.dagPaths,
                mArgs.shadingMode,
                mArgs.mergeTransformAndShape,
                mArgs.usdModelRootOverridePath);

    if (!mModelKindWriter.MakeModelHierarchy(mStage)) {
        return false;
    }

    // now we populate the chasers and run export default
    mChasers.clear();
    PxrUsdMayaChaserRegistry::FactoryContext ctx(mStage, mDagPathToUsdPathMap, mArgs);
    for (const std::string& chaserName : mArgs.chaserNames) {
        if (PxrUsdMayaChaserRefPtr fn = 
                PxrUsdMayaChaserRegistry::GetInstance().Create(chaserName, ctx)) {
            mChasers.push_back(fn);
        }
        else {
            std::string error = TfStringPrintf("Failed to create chaser: %s",
                                               chaserName.c_str());
            MGlobal::displayError(MString(error.c_str()));
        }
    }

    for (const PxrUsdMayaChaserRefPtr& chaser : mChasers) {
        if (!chaser->ExportDefault()) {
            return false;
        }
    }

    return true;
}