// Change the order of items in 'names' so that all the things in 'order' that // are also in 'names' are at the beginning in the order that they appear in // 'order', followed by any remaining items in 'names' in their existing order. static void _ApplyOrdering(const TfTokenVector &order, TfTokenVector *names) { // If order is empty or names is empty, nothing to do. if (order.empty() || names->empty()) return; // Perf note: this walks 'order' and linear searches 'names' to find each // element, for O(M*N) operations, where M and N are the lengths of 'order' // and 'names'. We hope 1) that propertyOrder stmts are relatively rare and // 2) that property lists are relatively short. If those assumptions fail, // this may need revisiting. In some quick microbenchmarking, this linear // search seems to outperform binary search up to about 5000 names. We // suspect this is because linear search does TfToken pointer comparisons, // while binary search has to dereference and do string comparisons. typedef TfTokenVector::iterator Iter; Iter namesRest = names->begin(), namesEnd = names->end(); for (const TfToken &oName: order) { // Look for this name from 'order' in the rest of 'names'. Iter i = std::find(namesRest, namesEnd, oName); if (i != namesEnd) { // Found. Move to the front by rotating the sub-range. Using // std::rotate invokes swap(), which avoids TfToken refcounting. // Also advance 'namesRest' to the next element. std::rotate(namesRest++, i, i+1); } } }
GlfTextureHandleRefPtr GlfTextureRegistry::GetTextureHandle(const TfTokenVector &textures) { if (textures.empty()) { TF_WARN("Attempting to register arrayTexture with empty token vector."); return GlfTextureHandlePtr(); } const size_t numTextures = textures.size(); // We register an array texture with the // path of the first texture in the array TfToken texture = textures[0]; GlfTextureHandleRefPtr textureHandle; _TextureMetadata md(textures); // look into exisiting textures std::map<TfToken, _TextureMetadata>::iterator it = _textureRegistry.find(texture); if (it != _textureRegistry.end() && it->second.IsMetadataEqual(md)) { textureHandle = it->second.GetHandle(); } else { // if not exists, create it textureHandle = _CreateTexture(textures, numTextures); md.SetHandle(textureHandle); _textureRegistry[texture] = md; } return textureHandle; }
void UsdMayaAdaptor::UnapplySchemaByName( const TfToken& schemaName, MDGModifier& modifier) { if (!*this) { TF_CODING_ERROR("Adaptor is not valid"); return; } // Remove from schema list. TfTokenVector currentSchemas = GetAppliedSchemas(); currentSchemas.erase( std::remove( currentSchemas.begin(), currentSchemas.end(), schemaName), currentSchemas.end()); if (currentSchemas.empty()) { ClearMetadata(UsdTokens->apiSchemas, modifier); } else { SetMetadata( UsdTokens->apiSchemas, _GetListOpForTokenVector(currentSchemas), modifier); } }
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; }