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); } }
UsdMayaAdaptor::SchemaAdaptor UsdMayaAdaptor::ApplySchemaByName( const TfToken& schemaName, MDGModifier& modifier) { if (!*this) { TF_CODING_ERROR("Adaptor is not valid"); return SchemaAdaptor(); } // Get the schema's TfType; its name should be registered as an alias. const TfType schemaType = TfType::Find<UsdSchemaBase>().FindDerivedByName(schemaName); // Make sure that this is an API schema. Only API schemas can be applied. if (!schemaType.IsA<UsdAPISchemaBase>()) { TF_CODING_ERROR("'%s' is not a registered API schema", schemaName.GetText()); return SchemaAdaptor(); } // Make sure that this is an "apply" schema. if (!UsdSchemaRegistry::GetInstance().IsAppliedAPISchema(schemaType)) { TF_CODING_ERROR("'%s' is not an applied API schema", schemaName.GetText()); return SchemaAdaptor(); } // Get the schema definition. If it's registered, there should be a def. SdfPrimSpecHandle primDef = UsdSchemaRegistry::GetInstance().GetPrimDefinition(schemaName); if (!primDef) { TF_CODING_ERROR("Can't find schema definition for name '%s'", schemaName.GetText()); return SchemaAdaptor(); } // Add to schema list (if not yet present). TfTokenVector currentSchemas = GetAppliedSchemas(); if (std::find(currentSchemas.begin(), currentSchemas.end(), schemaName) == currentSchemas.end()) { currentSchemas.push_back(schemaName); SetMetadata( UsdTokens->apiSchemas, _GetListOpForTokenVector(currentSchemas), modifier); } return SchemaAdaptor(_handle.object(), primDef); }
std::vector<UsdProperty> UsdPrim::_GetPropertiesInNamespace(const std::string &namespaces, bool onlyAuthored) const { // XXX Would be nice to someday plumb the prefix search down through pcp if (namespaces.empty()) return onlyAuthored ? GetAuthoredProperties() : GetProperties(); const char delim = UsdObject::GetNamespaceDelimiter(); TfTokenVector names = _GetPropertyNames(onlyAuthored, /*applyOrder=*/false); // Set terminator to the expected position of the delimiter after all the // supplied namespaces. We perform an explicit test for this char below // so that we don't need to allocate a new string if namespaces does not // already end with the delimiter const size_t terminator = namespaces.size() - (*namespaces.rbegin() == delim); // Prune out non-matches before we sort size_t insertionPt = 0; for (const auto& name : names) { const std::string &s = name.GetString(); if (s.size() > terminator && TfStringStartsWith(s, namespaces) && s[terminator] == delim) { names[insertionPt++] = name; } } names.resize(insertionPt); sort(names.begin(), names.end(), TfDictionaryLessThan()); _ApplyOrdering(GetPropertyOrder(), &names); return _MakeProperties(names); }
/* static */ UsdUISceneGraphPrimAPI UsdUISceneGraphPrimAPI::Apply(const UsdStagePtr &stage, const SdfPath &path) { // Ensure we have a valid stage, path and prim if (!stage) { TF_CODING_ERROR("Invalid stage"); return UsdUISceneGraphPrimAPI(); } if (path == SdfPath::AbsoluteRootPath()) { TF_CODING_ERROR("Cannot apply an api schema on the pseudoroot"); return UsdUISceneGraphPrimAPI(); } auto prim = stage->GetPrimAtPath(path); if (!prim) { TF_CODING_ERROR("Prim at <%s> does not exist.", path.GetText()); return UsdUISceneGraphPrimAPI(); } TfToken apiName("SceneGraphPrimAPI"); // Get the current listop at the edit target UsdEditTarget editTarget = stage->GetEditTarget(); SdfPrimSpecHandle primSpec = editTarget.GetPrimSpecForScenePath(path); SdfTokenListOp listOp = primSpec->GetInfo(UsdTokens->apiSchemas) .UncheckedGet<SdfTokenListOp>(); // Append our name to the prepend list, if it doesnt exist locally TfTokenVector prepends = listOp.GetPrependedItems(); if (std::find(prepends.begin(), prepends.end(), apiName) != prepends.end()) { return UsdUISceneGraphPrimAPI(); } SdfTokenListOp prependListOp; prepends.push_back(apiName); prependListOp.SetPrependedItems(prepends); auto result = listOp.ApplyOperations(prependListOp); if (!result) { TF_CODING_ERROR("Failed to prepend api name to current listop."); return UsdUISceneGraphPrimAPI(); } // Set the listop at the current edit target and return the API prim primSpec->SetInfo(UsdTokens->apiSchemas, VtValue(*result)); return UsdUISceneGraphPrimAPI(prim); }
void HdPoints::_PopulateVertexPrimVars(HdDrawItem *drawItem, HdChangeTracker::DirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HD_MALLOC_TAG_FUNCTION(); SdfPath const& id = GetId(); HdSceneDelegate* delegate = GetDelegate(); HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance(); // The "points" attribute is expected to be in this list. TfTokenVector primVarNames = delegate->GetPrimVarVertexNames(id); TfTokenVector const& vars = delegate->GetPrimVarVaryingNames(id); primVarNames.insert(primVarNames.end(), vars.begin(), vars.end()); HdBufferSourceVector sources; sources.reserve(primVarNames.size()); int pointsIndexInSourceArray = -1; TF_FOR_ALL(nameIt, primVarNames) { if (not HdChangeTracker::IsPrimVarDirty(*dirtyBits, id, *nameIt)) continue; // TODO: We don't need to pull primvar metadata every time a value // changes, but we need support from the delegate. //assert name not in range.bufferArray.GetResources() VtValue value = delegate->Get(id, *nameIt); if (!value.IsEmpty()) { // Store where the points will be stored in the source array // we need this later to figure out if the number of points is changing // and we need to force a garbage collection to resize the buffer if (*nameIt == HdTokens->points) { pointsIndexInSourceArray = sources.size(); } // XXX: do we need special treatment for width as basicCurves? HdBufferSourceSharedPtr source(new HdVtBufferSource(*nameIt, value)); sources.push_back(source); } } // return before allocation if it's empty. if (sources.empty()) return; if (not drawItem->GetVertexPrimVarRange() or not drawItem->GetVertexPrimVarRange()->IsValid()) { // initialize buffer array HdBufferSpecVector bufferSpecs; TF_FOR_ALL(it, sources) { (*it)->AddBufferSpecs(&bufferSpecs); }
TfTokenVector UsdPrim::_GetPropertyNames(bool onlyAuthored, bool applyOrder) const { TfTokenVector names; // If we're including unauthored properties, take names from definition, if // present. if (!onlyAuthored) { UsdSchemaRegistry::HasField(GetTypeName(), TfToken(), SdfChildrenKeys->PropertyChildren, &names); } // Add authored names, then sort and apply ordering. GetPrimIndex().ComputePrimPropertyNames(&names); if (applyOrder) { sort(names.begin(), names.end(), TfDictionaryLessThan()); _ApplyOrdering(GetPropertyOrder(), &names); } return names; }