bool UsdSkelSkeletonQuery::_ComputeSkinningTransforms(VtMatrix4dArray* xforms, UsdTimeCode time) const { if (ComputeJointSkelTransforms(xforms, time)) { // XXX: Since this is a fairly frequent computation request, // skel-space inverse rest transforms are cached on-demand // on the definition VtMatrix4dArray inverseBindXforms; if (!_definition->GetJointWorldInverseBindTransforms( &inverseBindXforms)) { TF_WARN("%s -- Failed fetching bind transforms. The " "'bindTransforms' attribute may be unauthored, " "or may not match the number of joints.", GetSkeleton().GetPrim().GetPath().GetText()); return false; } if(xforms->size() == inverseBindXforms.size()) { // xforms = inverseBindXforms * xforms _PreMultXforms(inverseBindXforms, xforms); return true; } else { TF_WARN("%s -- Size of computed joints transforms [%zu] does not " "match the number of elements in the 'bindTransforms' " "attr [%zu].", GetSkeleton().GetPrim().GetPath().GetText(), xforms->size(), inverseBindXforms.size()); } } return false; }
static bool _GetMayaDictValue(const UsdAttribute& attr, const TfToken& key, T* outVal) { VtValue data = attr.GetCustomDataByKey(_tokens->Maya); if (!data.IsEmpty()) { if (data.IsHolding<VtDictionary>()) { VtValue val; if (TfMapLookup(data.UncheckedGet<VtDictionary>(), key, &val)) { if (val.IsHolding<T>()) { *outVal = val.UncheckedGet<T>(); return true; } else { TF_WARN("Unexpected type for %s[%s] on <%s>.", _tokens->Maya.GetText(), key.GetText(), attr.GetPath().GetText()); } } } else { TF_WARN("Expected to get %s on <%s> to be a dictionary.", _tokens->Maya.GetText(), attr.GetPath().GetText()); } } return false; }
void UsdMayaJobExportArgs::AddFilteredTypeName(const MString& typeName) { MNodeClass cls(typeName); unsigned int id = cls.typeId().id(); if (id == 0) { TF_WARN("Given excluded node type '%s' does not exist; ignoring", typeName.asChar()); return; } _filteredTypeIds.insert(id); // We also insert all inherited types - only way to query this is through mel, // which is slower, but this should be ok, as these queries are only done // "up front" when the export starts, not per-node MString queryCommand("nodeType -isTypeName -derived "); queryCommand += typeName; MStringArray inheritedTypes; MStatus status = MGlobal::executeCommand(queryCommand, inheritedTypes, false, false); if (!status) { TF_WARN("Error querying derived types for '%s': %s", typeName.asChar(), status.errorString().asChar()); return; } for (unsigned int i=0; i < inheritedTypes.length(); ++i) { if (inheritedTypes[i].length() == 0) continue; id = MNodeClass(inheritedTypes[i]).typeId().id(); if (id == 0) { // Unfortunately, the returned list will often include weird garbage, like // "THconstraint" for "constraint", which cannot be converted to a MNodeClass, // so just ignore these... continue; } _filteredTypeIds.insert(id); } }
GlfQGLPlatformDebugContextPrivate::GlfQGLPlatformDebugContextPrivate( int majorVersion, int minorVersion, bool coreProfile, bool directRendering) : _dpy(NULL) , _ctx(NULL) { Display *shareDisplay = glXGetCurrentDisplay(); GLXContext shareContext = glXGetCurrentContext(); int fbConfigId = 0; glXQueryContext(shareDisplay, shareContext, GLX_FBCONFIG_ID, &fbConfigId); int screen = 0; glXQueryContext(shareDisplay, shareContext, GLX_SCREEN, &screen); int configSpec[] = { GLX_FBCONFIG_ID, fbConfigId, None, }; GLXFBConfig *configs = NULL; int configCount = 0; configs = glXChooseFBConfig(shareDisplay, screen, configSpec, &configCount); if (not TF_VERIFY(configCount > 0)) { return; } const int profile = coreProfile ? GLX_CONTEXT_CORE_PROFILE_BIT_ARB : GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; int attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, majorVersion, GLX_CONTEXT_MINOR_VERSION_ARB, minorVersion, GLX_CONTEXT_PROFILE_MASK_ARB, profile, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, 0, }; // Extension entry points must be resolved at run-time. PFNGLXCREATECONTEXTATTRIBSARBPROC createContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB"); // Create a GL context with the requested capabilities. if (createContextAttribs) { _ctx = (*createContextAttribs)(shareDisplay, configs[0], shareContext, directRendering, attribs); } else { TF_WARN("Unable to create GL debug context."); XVisualInfo *vis = glXGetVisualFromFBConfig(shareDisplay, configs[0]); _ctx = glXCreateContext(shareDisplay, vis, shareContext, directRendering); } if (not TF_VERIFY(_ctx)) { return; } _dpy = shareDisplay; }
GfMatrix4d UsdGeomConstraintTarget::ComputeInWorldSpace( UsdTimeCode time, UsdGeomXformCache *xfCache) const { if (not IsDefined()) { TF_CODING_ERROR("Invalid constraint target."); return GfMatrix4d(1); } const UsdPrim &modelPrim = GetAttr().GetPrim(); GfMatrix4d localToWorld(1); if (xfCache) { xfCache->SetTime(time); localToWorld = xfCache->GetLocalToWorldTransform(modelPrim); } else { UsdGeomXformCache cache; cache.SetTime(time); localToWorld = cache.GetLocalToWorldTransform(modelPrim); } GfMatrix4d localConstraintSpace(1.); if (not Get(&localConstraintSpace, time)) { TF_WARN("Failed to get value of constraint target '%s' at path <%s>.", GetIdentifier().GetText(), GetAttr().GetPath().GetText()); return localConstraintSpace; } return localConstraintSpace * localToWorld; }
/* * Make the matrix orthonormal in place using an iterative method. * It is potentially slower if the matrix is far from orthonormal (i.e. if * the row basis vectors are close to colinear) but in the common case * of near-orthonormality it should be just as fast. * * The translation part is left intact. If the translation is represented as * a homogenous coordinate (i.e. a non-unity lower right corner), it is divided * out. */ bool GfMatrix4f::Orthonormalize(bool issueWarning) { // orthogonalize and normalize row vectors GfVec3d r0(_mtx[0][0],_mtx[0][1],_mtx[0][2]); GfVec3d r1(_mtx[1][0],_mtx[1][1],_mtx[1][2]); GfVec3d r2(_mtx[2][0],_mtx[2][1],_mtx[2][2]); bool result = GfVec3d::OrthogonalizeBasis(&r0, &r1, &r2, true); _mtx[0][0] = r0[0]; _mtx[0][1] = r0[1]; _mtx[0][2] = r0[2]; _mtx[1][0] = r1[0]; _mtx[1][1] = r1[1]; _mtx[1][2] = r1[2]; _mtx[2][0] = r2[0]; _mtx[2][1] = r2[1]; _mtx[2][2] = r2[2]; // divide out any homogeneous coordinate - unless it's zero if (_mtx[3][3] != 1.0 && !GfIsClose(_mtx[3][3], 0.0, GF_MIN_VECTOR_LENGTH)) { _mtx[3][0] /= _mtx[3][3]; _mtx[3][1] /= _mtx[3][3]; _mtx[3][2] /= _mtx[3][3]; _mtx[3][3] = 1.0; } if (!result && issueWarning) TF_WARN("OrthogonalizeBasis did not converge, matrix may not be " "orthonormal."); return result; }
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; }
// For now, this is only used by the mesh op. If this logic needs to be // accessed elsewhere, it should move down into usdKatana. static void _CreateFaceSetsFromFaceSetAPI( const UsdPrim& prim, const PxrUsdKatanaUsdInPrivateData &data, FnKat::GeolibCookInterface& interface) { UsdGeomFaceSetAPI faceSet = UsdShadeMaterial::GetMaterialFaceSet(prim); bool isPartition = faceSet.GetIsPartition();; if (!isPartition) { TF_WARN("Found face set on prim <%s> that is not a partition.", prim.GetPath().GetText()); // continue here? } const double currentTime = data.GetCurrentTime(); VtIntArray faceCounts, faceIndices; faceSet.GetFaceCounts(&faceCounts, currentTime); faceSet.GetFaceIndices(&faceIndices, currentTime); SdfPathVector bindingTargets; faceSet.GetBindingTargets(&bindingTargets); size_t faceSetIdxStart = 0; for(size_t faceSetIdx = 0; faceSetIdx < faceCounts.size(); ++faceSetIdx) { size_t faceCount = faceCounts[faceSetIdx]; FnKat::GroupBuilder faceSetAttrs; faceSetAttrs.set("type", FnKat::StringAttribute("faceset")); faceSetAttrs.set("materialAssign", FnKat::StringAttribute( PxrUsdKatanaUtils::ConvertUsdMaterialPathToKatLocation( bindingTargets[faceSetIdx], data))); FnKat::IntBuilder facesBuilder; { std::vector<int> faceIndicesVec(faceCount); for (size_t faceIndicesIdx = 0; faceIndicesIdx < faceCount; ++faceIndicesIdx) { faceIndicesVec[faceIndicesIdx] = faceIndices[faceSetIdxStart + faceIndicesIdx]; } faceSetIdxStart += faceCount; facesBuilder.set(faceIndicesVec); } faceSetAttrs.set("geometry.faces", facesBuilder.build()); std::string faceSetName = TfStringPrintf("faceset_%zu", faceSetIdx); FnKat::GroupBuilder staticSceneCreateAttrs; staticSceneCreateAttrs.set("a", faceSetAttrs.build()); interface.createChild( faceSetName, "StaticSceneCreate", staticSceneCreateAttrs.build()); } }
static TfToken HdSt_BasisToShaderKey(const TfToken& basis){ if (basis == HdTokens->bezier) return _tokens->curvesBezier; else if (basis == HdTokens->catmullRom) return _tokens->curvesCatmullRom; else if (basis == HdTokens->bSpline) return _tokens->curvesBspline; TF_WARN("Unknown basis"); return _tokens->curvesFallback; }
static TfToken _GetProxyOverlayMode() { TfToken overlay(TfGetEnvSetting(USDVMP_PROXY_OVERLAY)); if (overlay != _tokens->ghosted and overlay != _tokens->none and overlay != _tokens->wireframe) { TF_WARN("Invalid proxy USDVMP_PROXY_OVERLAY mode: %s\n", overlay.GetText()); return _tokens->ghosted; } return overlay; }
bool UsdGeomPrimvar::ComputeFlattened(VtValue *value, UsdTimeCode time) const { VtValue attrVal; if (!Get(&attrVal, time)) { return false; } // If the primvar attr value is not an array or if the primvar isn't // indexed, simply return the attribute value. if (!attrVal.IsArrayValued() || !IsIndexed()) { *value = VtValue::Take(attrVal); return true; } VtIntArray indices; if (!GetIndices(&indices, time)) { TF_CODING_ERROR("No indices authored for indexed primvar <%s>.", _attr.GetPath().GetText()); return false; } // Handle all known supported array value types. bool foundSupportedType = _ComputeFlattenedArray<VtVec2fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec2hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec3hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4fArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4iArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtVec4hArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtMatrix3dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtMatrix4dArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtStringArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtDoubleArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtIntArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtFloatArray>(attrVal, indices, value) || _ComputeFlattenedArray<VtHalfArray>(attrVal, indices, value); if (!foundSupportedType) { TF_WARN("Unsupported indexed primvar value type %s.", attrVal.GetTypeName().c_str()); } return !value->IsEmpty(); }
PXR_NAMESPACE_OPEN_SCOPE // TODO: We should centralize this logic in a UsdImaging ShaderAdapter. /*static*/ UsdPrim UsdImaging_MaterialStrategy::GetTargetedShader(UsdPrim const& materialPrim, UsdRelationship const& materialRel) { SdfPathVector targets; if (!materialRel.GetForwardedTargets(&targets)) return UsdPrim(); if (targets.size() != 1) { // XXX: This should really be a validation error once USD gets that // feature. TF_WARN("We expect only one target on relationship %s of prim <%s>, " "but got %zu.", materialRel.GetName().GetText(), materialPrim.GetPath().GetText(), targets.size()); return UsdPrim(); } if (!targets[0].IsPrimPath()) { // XXX: This should really be a validation error once USD gets that // feature. TF_WARN("We expect the target of the relationship %s of prim <%s> " "to be a prim, instead it is <%s>.", materialRel.GetName().GetText(), materialPrim.GetPath().GetText(), targets[0].GetText()); return UsdPrim(); } return materialPrim.GetStage()->GetPrimAtPath(targets[0]); }
static void _MatrixToVectorsWithPivotInvariant( const GfMatrix4d &m, const GfVec3d pivotPosition, const GfVec3d pivotOrientation, GfVec3d *translation, GfVec3d *rotation, GfVec3d *scale, GfVec3d *scaleOrientation) { GfMatrix3d pivotOrientMat = _EulerXYZToMatrix3d(pivotOrientation); GfMatrix4d pp = GfMatrix4d(1.0).SetTranslate( pivotPosition); GfMatrix4d ppInv = GfMatrix4d(1.0).SetTranslate(-pivotPosition); GfMatrix4d po = GfMatrix4d(1.0).SetRotate(pivotOrientMat); GfMatrix4d poInv = GfMatrix4d(1.0).SetRotate(pivotOrientMat.GetInverse()); GfMatrix4d factorMe = po * pp * m * ppInv; GfMatrix4d scaleOrientMat, factoredRotMat, perspMat; factorMe.Factor(&scaleOrientMat, scale, &factoredRotMat, translation, &perspMat); GfMatrix4d rotMat = factoredRotMat * poInv; if(not rotMat.Orthonormalize(/* issueWarning */ false)) TF_WARN("Failed to orthonormalize rotMat."); _RotMatToRotTriplet(rotMat, rotation); if(not scaleOrientMat.Orthonormalize(/* issueWarning */ false)) TF_WARN("Failed to orthonormalize scaleOrientMat."); _RotMatToRotTriplet(scaleOrientMat, scaleOrientation); }
bool HdExtCompPrimvarBufferSource::Resolve() { bool sourceValid = _source->IsValid(); if (sourceValid) { if (!_source->IsResolved()) { return false; } } if (!_TryLock()) return false; if (!sourceValid || _source->HasResolveError()) { _SetResolveError(); return true; } HdVtBufferSource output(_primvarName, _source->GetOutputByIndex(_sourceOutputIdx)); // Validate output type and count matches what is expected. if (output.GetTupleType() != _tupleType) { TF_WARN("Output type mismatch on %s. ", _primvarName.GetText()); _SetResolveError(); return true; } if (output.GetNumElements() != _source->GetNumElements()) { TF_WARN("Output elements mismatch on %s. ", _primvarName.GetText()); _SetResolveError(); return true; } _rawDataPtr = output.GetData(); _SetResolved(); return true; }
bool UsdSkelSkeletonQuery::ComputeJointRestRelativeTransforms( VtMatrix4dArray* xforms, UsdTimeCode time) const { TRACE_FUNCTION(); if (!xforms) { TF_CODING_ERROR("'xforms' pointer is null."); return false; } if(TF_VERIFY(IsValid(), "invalid skeleton query.")) { if (_HasMappableAnim()) { // jointLocalXf = restRelativeXf * restXf // restRelativeXf = jointLocalXf * inv(restXf) // Pull inverse rest transforms first // They are cached on the definition. VtMatrix4dArray invRestXforms; if (_definition->GetJointLocalInverseRestTransforms( &invRestXforms)) { VtMatrix4dArray localXforms; if (_ComputeJointLocalTransforms( &localXforms, time, /*atRest*/ false)) { if (TF_VERIFY(localXforms.size() == invRestXforms.size())) { xforms->resize(localXforms.size()); _MultTransforms(localXforms.cdata(), invRestXforms.cdata(), xforms->data(), xforms->size()); return true; } } } else { TF_WARN("%s -- Failed computing rest-relative transforms: " "the 'restTransforms' of the Skeleton are either unset, " "or do not have a matching number of joints.", GetSkeleton().GetPrim().GetPath().GetText()); } } else { // No bound animation, so rest relative transforms are identity. xforms->assign(GetTopology().GetNumJoints(), GfMatrix4d(1)); return true; } } return false; }
HdBasisCurvesTopology::HdBasisCurvesTopology(const TfToken &curveType, const TfToken &curveBasis, const TfToken &curveWrap, const VtIntArray &curveVertexCounts, const VtIntArray &curveIndices) : HdTopology() , _curveType(curveType) , _curveBasis(curveBasis) , _curveWrap(curveWrap) , _curveVertexCounts(curveVertexCounts) , _curveIndices(curveIndices) { if (_curveType != HdTokens->linear && _curveType != HdTokens->cubic){ TF_WARN("Curve type must be 'linear' or 'cubic'. Got: '%s'", _curveType.GetText()); _curveType = HdTokens->linear; _curveBasis = TfToken(); } if (curveBasis == HdTokens->linear && curveType == HdTokens->cubic){ TF_WARN("Basis 'linear' passed in to 'cubic' curveType. Converting 'curveType' to 'linear'."); _curveType = HdTokens->linear; _curveBasis = TfToken(); } HD_PERF_COUNTER_INCR(HdPerfTokens->basisCurvesTopology); }
void PxOsdMeshTopology::SetHoleIndices(VtIntArray const &holeIndices) { if (TfDebug::IsEnabled(0)) { // make sure faceIndices is given in ascending order. int nFaceIndices = holeIndices.size(); for (int i = 1; i < nFaceIndices; ++i) { if (holeIndices[i] <= holeIndices[i-1]) { // XXX: would be better to print the prim name. TF_WARN("hole face indices are not in ascending order."); return; } } } _holeIndices = holeIndices; }
bool TfUnsetenv(const std::string & name) { #ifdef PXR_PYTHON_SUPPORT_ENABLED if (TfPyIsInitialized()) { return TfPyUnsetenv(name); } #endif // PXR_PYTHON_SUPPORT_ENABLED if (ArchRemoveEnv(name.c_str())) { return true; } TF_WARN("Error unsetting '%s': %s", name.c_str(), ArchStrerror().c_str()); return false; }
/* static */ void UsdMayaUndoHelperCommand::ExecuteWithUndo(const UndoableFunction& func) { int cmdExists = 0; MGlobal::executeCommand("exists usdUndoHelperCmd", cmdExists); if (!cmdExists) { TF_WARN("usdUndoHelperCmd is unavailable; " "function will run without undo support"); MDGModifier modifier; func(modifier); return; } // Run function through command if it is available to get undo support! _dgModifierFunc = &func; MGlobal::executeCommand("usdUndoHelperCmd", false, true); }
PXR_NAMESPACE_USING_DIRECTIVE // Here we emit some warnings on the same line, so they // will get coalesced, and others on different lines, so they wont // We expect to get 4 results when coalesced, 6 uncoalesced static void EmitWarnings() { TF_WARN("aaaaaaaaaaaaaa"); TF_WARN("bbbbbbbbbbbbbb"); TF_WARN("cccccccccccccc"); TF_WARN("dddddddddddddd"); TF_WARN("eeeeeeeeeeeeee"); TF_WARN("ffffffffffffff"); }
SdfPrimSpecHandle UsdPrim::GetPrimDefinition() const { const TfToken &typeName = GetTypeName(); SdfPrimSpecHandle definition; if (!typeName.IsEmpty()) { // Look up definition from prim type name. definition = UsdSchemaRegistry::GetPrimDefinition(typeName); if (!definition) { // Issue a diagnostic for unknown prim types. TF_WARN("No definition for prim type '%s', <%s>", typeName.GetText(), GetPath().GetText()); } } return definition; }
PXR_NAMESPACE_OPEN_SCOPE bool TfSetenv(const std::string & name, const std::string & value) { #ifdef PXR_PYTHON_SUPPORT_ENABLED if (TfPyIsInitialized()) { return TfPySetenv(name, value); } #endif // PXR_PYTHON_SUPPORT_ENABLED if (ArchSetEnv(name.c_str(), value.c_str(), /* overwrite */ true)) { return true; } TF_WARN("Error setting '%s': %s", name.c_str(), ArchStrerror().c_str()); return false; }
static void _SetMayaDictValue(const UsdAttribute& attr, const TfToken& flagName, const T& val) { VtValue data = attr.GetCustomDataByKey(_tokens->Maya); VtDictionary newDict; if (!data.IsEmpty()) { if (data.IsHolding<VtDictionary>()) { newDict = data.UncheckedGet<VtDictionary>(); } else { TF_WARN("Expected to get %s on <%s> to be a dictionary.", _tokens->Maya.GetText(), attr.GetPath().GetText()); return; } } newDict[flagName] = VtValue(val); attr.SetCustomDataByKey(_tokens->Maya, VtValue(newDict)); }
/* Make the matrix orthonormal in place using an iterative method. * It is potentially slower if the matrix is far from orthonormal (i.e. if * the row basis vectors are close to colinear) but in the common case * of near-orthonormality it should be just as fast. */ bool GfMatrix3d::Orthonormalize(bool issueWarning) { // orthogonalize and normalize row vectors GfVec3d r0(_mtx[0][0],_mtx[0][1],_mtx[0][2]); GfVec3d r1(_mtx[1][0],_mtx[1][1],_mtx[1][2]); GfVec3d r2(_mtx[2][0],_mtx[2][1],_mtx[2][2]); bool result = GfVec3d::OrthogonalizeBasis(&r0, &r1, &r2, true); _mtx[0][0] = r0[0]; _mtx[0][1] = r0[1]; _mtx[0][2] = r0[2]; _mtx[1][0] = r1[0]; _mtx[1][1] = r1[1]; _mtx[1][2] = r1[2]; _mtx[2][0] = r2[0]; _mtx[2][1] = r2[1]; _mtx[2][2] = r2[2]; if (!result && issueWarning) TF_WARN("OrthogonalizeBasis did not converge, matrix may not be " "orthonormal."); return result; }
/// Extracts a token at \p key from \p userArgs. /// If the token value is not either \p defaultToken or one of the /// \p otherTokens, then returns \p defaultToken instead. static TfToken _Token( const VtDictionary& userArgs, const TfToken& key, const TfToken& defaultToken, const std::vector<TfToken>& otherTokens) { const TfToken tok(_String(userArgs, key)); for (const TfToken& allowedTok : otherTokens) { if (tok == allowedTok) { return tok; } } // Empty token will silently be promoted to default value. // Warning for non-empty tokens that don't match. if (tok != defaultToken && !tok.IsEmpty()) { TF_WARN("Value '%s' is not allowed for flag '%s'; using fallback '%s' " "instead", tok.GetText(), key.GetText(), defaultToken.GetText()); } return defaultToken; }
bool UsdSkelSkeletonQuery::_ComputeJointLocalTransforms(VtMatrix4dArray* xforms, UsdTimeCode time, bool atRest) const { if(atRest) { return _definition->GetJointLocalRestTransforms(xforms); } if(_animToSkelMapper.IsSparse()) { // Animation does not override all values; // Need to first fill in bind transforms. if (!_definition->GetJointLocalRestTransforms(xforms)) { TF_WARN("%s -- Failed computing local space transforms: " "the the animation source (<%s>) is sparse, but the " "'restTransforms' of the Skeleton are either unset, " "or do not match the number of joints.", GetSkeleton().GetPrim().GetPath().GetText(), GetAnimQuery().GetPrim().GetPath().GetText()); return false; } } VtMatrix4dArray animXforms; if(_animQuery.ComputeJointLocalTransforms(&animXforms, time)) { return _animToSkelMapper.RemapTransforms(animXforms, xforms); } else { // Failed to compute anim xforms. // Fall back to our rest transforms. // These will have already been initialized above, // unless we have a non-sparse mapping. if (!_animToSkelMapper.IsSparse()) { return _definition->GetJointLocalRestTransforms(xforms); } } return true; }
/* static */ bool UsdMayaTranslatorMesh::_AssignColorSetPrimvarToMesh( const UsdGeomMesh& primSchema, const UsdGeomPrimvar& primvar, MFnMesh& meshFn) { const TfToken& primvarName = primvar.GetPrimvarName(); const SdfValueTypeName& typeName = primvar.GetTypeName(); MString colorSetName(primvarName.GetText()); // If the primvar is displayOpacity and it is a FloatArray, check if // displayColor is authored. If not, we'll import this 'displayOpacity' // primvar as a 'displayColor' color set. This supports cases where the // user created a single channel value for displayColor. // Note that if BOTH displayColor and displayOpacity are authored, they will // be imported as separate color sets. We do not attempt to combine them // into a single color set. if (primvarName == UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName && typeName == SdfValueTypeNames->FloatArray) { if (!UsdMayaRoundTripUtil::IsAttributeUserAuthored(primSchema.GetDisplayColorPrimvar())) { colorSetName = UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText(); } } // We'll need to convert colors from linear to display if this color set is // for display colors. const bool isDisplayColor = (colorSetName == UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText()); // Get the raw data before applying any indexing. We'll only populate one // of these arrays based on the primvar's typeName, and we'll also set the // color representation so we know which array to use later. VtFloatArray alphaArray; VtVec3fArray rgbArray; VtVec4fArray rgbaArray; MFnMesh::MColorRepresentation colorRep; size_t numValues = 0; MStatus status = MS::kSuccess; if (typeName == SdfValueTypeNames->FloatArray) { colorRep = MFnMesh::kAlpha; if (!primvar.Get(&alphaArray) || alphaArray.empty()) { status = MS::kFailure; } else { numValues = alphaArray.size(); } } else if (typeName == SdfValueTypeNames->Float3Array || typeName == SdfValueTypeNames->Color3fArray) { colorRep = MFnMesh::kRGB; if (!primvar.Get(&rgbArray) || rgbArray.empty()) { status = MS::kFailure; } else { numValues = rgbArray.size(); } } else if (typeName == SdfValueTypeNames->Float4Array || typeName == SdfValueTypeNames->Color4fArray) { colorRep = MFnMesh::kRGBA; if (!primvar.Get(&rgbaArray) || rgbaArray.empty()) { status = MS::kFailure; } else { numValues = rgbaArray.size(); } } else { TF_WARN("Unsupported color set primvar type '%s' for primvar '%s' on " "mesh: %s", typeName.GetAsToken().GetText(), primvarName.GetText(), primvar.GetAttr().GetPrimPath().GetText()); return false; } if (status != MS::kSuccess || numValues == 0) { TF_WARN("Could not read color set values from primvar '%s' on mesh: %s", primvarName.GetText(), primvar.GetAttr().GetPrimPath().GetText()); return false; } VtIntArray assignmentIndices; int unauthoredValuesIndex = -1; if (primvar.GetIndices(&assignmentIndices)) { // The primvar IS indexed, so the indices array is what determines the // number of color values. numValues = assignmentIndices.size(); unauthoredValuesIndex = primvar.GetUnauthoredValuesIndex(); } // Go through the color data and translate the values into MColors in the // colorArray, taking into consideration that indexed data may have been // authored sparsely. If the assignmentIndices array is empty then the data // is NOT indexed. // Note that with indexed data, the data is added to the arrays in ascending // component ID order according to the primvar's interpolation (ascending // face ID for uniform interpolation, ascending vertex ID for vertex // interpolation, etc.). This ordering may be different from the way the // values are ordered in the primvar. Because of this, we recycle the // assignmentIndices array as we go to store the new mapping from component // index to color index. MColorArray colorArray; for (size_t i = 0; i < numValues; ++i) { int valueIndex = i; if (i < assignmentIndices.size()) { // The data is indexed, so consult the indices array for the // correct index into the data. valueIndex = assignmentIndices[i]; if (valueIndex == unauthoredValuesIndex) { // This component is unauthored, so just update the // mapping in assignmentIndices and then skip the value. // We don't actually use the value at the unassigned index. assignmentIndices[i] = -1; continue; } // We'll be appending a new value, so the current length of the // array gives us the new value's index. assignmentIndices[i] = colorArray.length(); } GfVec4f colorValue(1.0); switch(colorRep) { case MFnMesh::kAlpha: colorValue[3] = alphaArray[valueIndex]; break; case MFnMesh::kRGB: colorValue[0] = rgbArray[valueIndex][0]; colorValue[1] = rgbArray[valueIndex][1]; colorValue[2] = rgbArray[valueIndex][2]; break; case MFnMesh::kRGBA: colorValue[0] = rgbaArray[valueIndex][0]; colorValue[1] = rgbaArray[valueIndex][1]; colorValue[2] = rgbaArray[valueIndex][2]; colorValue[3] = rgbaArray[valueIndex][3]; break; default: break; } if (isDisplayColor) { colorValue = UsdMayaColorSpace::ConvertLinearToMaya(colorValue); } MColor mColor(colorValue[0], colorValue[1], colorValue[2], colorValue[3]); colorArray.append(mColor); } // colorArray now stores all of the values and any unassigned components // have had their indices set to -1, so update the unauthored values index. unauthoredValuesIndex = -1; const bool clamped = UsdMayaRoundTripUtil::IsPrimvarClamped(primvar); status = meshFn.createColorSet(colorSetName, nullptr, clamped, colorRep); if (status != MS::kSuccess) { TF_WARN("Unable to create color set '%s' for mesh: %s", colorSetName.asChar(), meshFn.fullPathName().asChar()); return false; } // Create colors on the mesh from the values we collected out of the // primvar. We'll assign mesh components to these values below. status = meshFn.setColors(colorArray, &colorSetName, colorRep); if (status != MS::kSuccess) { TF_WARN("Unable to set color data on color set '%s' for mesh: %s", colorSetName.asChar(), meshFn.fullPathName().asChar()); return false; } const TfToken& interpolation = primvar.GetInterpolation(); // Build an array of value assignments for each face vertex in the mesh. // Any assignments left as -1 will not be assigned a value. MIntArray colorIds = _GetMayaFaceVertexAssignmentIds(meshFn, interpolation, assignmentIndices, unauthoredValuesIndex); status = meshFn.assignColors(colorIds, &colorSetName); if (status != MS::kSuccess) { TF_WARN("Could not assign color values to color set '%s' on mesh: %s", colorSetName.asChar(), meshFn.fullPathName().asChar()); return false; } return true; }
/* static */ bool UsdMayaTranslatorMesh::_AssignUVSetPrimvarToMesh( const UsdGeomPrimvar& primvar, MFnMesh& meshFn) { const TfToken& primvarName = primvar.GetPrimvarName(); // Get the raw data before applying any indexing. VtVec2fArray uvValues; if (!primvar.Get(&uvValues) || uvValues.empty()) { TF_WARN("Could not read UV values from primvar '%s' on mesh: %s", primvarName.GetText(), primvar.GetAttr().GetPrimPath().GetText()); return false; } // This is the number of UV values assuming the primvar is NOT indexed. VtIntArray assignmentIndices; if (primvar.GetIndices(&assignmentIndices)) { // The primvar IS indexed, so the indices array is what determines the // number of UV values. int unauthoredValuesIndex = primvar.GetUnauthoredValuesIndex(); // Replace any index equal to unauthoredValuesIndex with -1. if (unauthoredValuesIndex != -1) { for (int& index : assignmentIndices) { if (index == unauthoredValuesIndex) { index = -1; } } } // Furthermore, if unauthoredValuesIndex is valid for uvValues, then // remove it from uvValues and shift the indices (we don't want to // import the unauthored value into Maya, where it has no meaning). if (unauthoredValuesIndex >= 0 && static_cast<size_t>(unauthoredValuesIndex) < uvValues.size()) { // This moves [unauthoredValuesIndex + 1, end) to // [unauthoredValuesIndex, end - 1), erasing the // unauthoredValuesIndex. std::move( uvValues.begin() + unauthoredValuesIndex + 1, uvValues.end(), uvValues.begin() + unauthoredValuesIndex); uvValues.pop_back(); for (int& index : assignmentIndices) { if (index > unauthoredValuesIndex) { index = index - 1; } } } } // Go through the UV data and add the U and V values to separate // MFloatArrays. MFloatArray uCoords; MFloatArray vCoords; for (const GfVec2f& v : uvValues) { uCoords.append(v[0]); vCoords.append(v[1]); } MStatus status; MString uvSetName(primvarName.GetText()); if (primvarName == UsdUtilsGetPrimaryUVSetName()) { // We assume that the primary USD UV set maps to Maya's default 'map1' // set which always exists, so we shouldn't try to create it. uvSetName = "map1"; } else { status = meshFn.createUVSet(uvSetName); if (status != MS::kSuccess) { TF_WARN("Unable to create UV set '%s' for mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } } // The following two lines should have no effect on user-visible state but // prevent a Maya crash in MFnMesh.setUVs after creating a crease set. // XXX this workaround is needed pending a fix by Autodesk. MString currentSet = meshFn.currentUVSetName(); meshFn.setCurrentUVSetName(currentSet); // Create UVs on the mesh from the values we collected out of the primvar. // We'll assign mesh components to these values below. status = meshFn.setUVs(uCoords, vCoords, &uvSetName); if (status != MS::kSuccess) { TF_WARN("Unable to set UV data on UV set '%s' for mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } const TfToken& interpolation = primvar.GetInterpolation(); // Build an array of value assignments for each face vertex in the mesh. // Any assignments left as -1 will not be assigned a value. MIntArray uvIds = _GetMayaFaceVertexAssignmentIds(meshFn, interpolation, assignmentIndices, -1); MIntArray vertexCounts; MIntArray vertexList; status = meshFn.getVertices(vertexCounts, vertexList); if (status != MS::kSuccess) { TF_WARN("Could not get vertex counts for UV set '%s' on mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } status = meshFn.assignUVs(vertexCounts, uvIds, &uvSetName); if (status != MS::kSuccess) { TF_WARN("Could not assign UV values to UV set '%s' on mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } return true; }
static void _AddClipsFromNode(const PcpPrimIndex& primIndex, Usd_ClipCache::Clips* clips) { Usd_ResolvedClipInfo clipInfo; auto node = Usd_ResolveClipInfo(primIndex, &clipInfo); // If we haven't found all of the required clip metadata we can just // bail out. Note that clipTimes and clipManifestAssetPath are *not* // required. if (!clipInfo.clipAssetPaths || !clipInfo.clipPrimPath || !clipInfo.clipActive) { return; } // The clip manifest is currently optional but can greatly improve // performance if specified. For debugging performance problems, // issue a message indicating if one hasn't been specified. if (!clipInfo.clipManifestAssetPath) { TF_DEBUG(USD_CLIPS).Msg( "No clip manifest specified for prim <%s>. " "Performance may be improved if a manifest is specified.", primIndex.GetPath().GetString().c_str()); } // XXX: Possibly want a better way to inform consumers of the error // message.. std::string error; if (!_ValidateClipFields( *clipInfo.clipAssetPaths, *clipInfo.clipPrimPath, *clipInfo.clipActive, &error)) { TF_WARN( "Invalid clips specified for prim <%s> in LayerStack %s: %s", node.GetPath().GetString().c_str(), TfStringify(node.GetLayerStack()).c_str(), error.c_str()); return; } // If a clip manifest has been specified, create a clip for it. if (clipInfo.clipManifestAssetPath) { const Usd_ClipRefPtr clip(new Usd_Clip( /* clipSourceNode = */ node, /* clipSourceLayerIndex = */ clipInfo.indexOfLayerWhereAssetPathsFound, /* clipAssetPath = */ *clipInfo.clipManifestAssetPath, /* clipPrimPath = */ SdfPath(*clipInfo.clipPrimPath), /* clipStartTime = */ Usd_ClipTimesEarliest, /* clipEndTime = */ Usd_ClipTimesLatest, /* clipTimes = */ Usd_Clip::TimeMappings())); clips->manifestClip = clip; } // Generate a mapping of startTime -> clip entry. This allows us to // quickly determine the (startTime, endTime) for a given clip. typedef std::map<double, Usd_ClipEntry> _TimeToClipMap; _TimeToClipMap startTimeToClip; for (const auto& startFrameAndClipIndex : *clipInfo.clipActive) { const double startFrame = startFrameAndClipIndex[0]; const int clipIndex = (int)(startFrameAndClipIndex[1]); const SdfAssetPath& assetPath = (*clipInfo.clipAssetPaths)[clipIndex]; Usd_ClipEntry entry; entry.startTime = startFrame; entry.clipAssetPath = assetPath; entry.clipPrimPath = SdfPath(*clipInfo.clipPrimPath); // Validation should have caused us to bail out if there were any // conflicting clip activations set. TF_VERIFY(startTimeToClip.insert( std::make_pair(entry.startTime, entry)).second); } // Build up the final vector of clips. const _TimeToClipMap::const_iterator itBegin = startTimeToClip.begin(); const _TimeToClipMap::const_iterator itEnd = startTimeToClip.end(); _TimeToClipMap::const_iterator it = startTimeToClip.begin(); while (it != itEnd) { const Usd_ClipEntry clipEntry = it->second; const Usd_Clip::ExternalTime clipStartTime = (it == itBegin ? Usd_ClipTimesEarliest : it->first); ++it; const Usd_Clip::ExternalTime clipEndTime = (it == itEnd ? Usd_ClipTimesLatest : it->first); // Generate the clip time mapping that applies to this clip. Usd_Clip::TimeMappings timeMapping; if (clipInfo.clipTimes) { for (const auto& clipTime : *clipInfo.clipTimes) { const Usd_Clip::ExternalTime extTime = clipTime[0]; const Usd_Clip::InternalTime intTime = clipTime[1]; if (clipStartTime <= extTime && extTime < clipEndTime) { timeMapping.push_back( Usd_Clip::TimeMapping(extTime, intTime)); } } } const Usd_ClipRefPtr clip(new Usd_Clip( /* clipSourceNode = */ node, /* clipSourceLayerIndex = */ clipInfo.indexOfLayerWhereAssetPathsFound, /* clipAssetPath = */ clipEntry.clipAssetPath, /* clipPrimPath = */ clipEntry.clipPrimPath, /* clipStartTime = */ clipStartTime, /* clipEndTime = */ clipEndTime, /* clipTimes = */ timeMapping)); clips->valueClips.push_back(clip); } clips->sourceNode = node; clips->sourceLayerIndex = clipInfo.indexOfLayerWhereAssetPathsFound; }
bool Hd_TriangleIndexBuilderComputation::Resolve() { if (not _TryLock()) return false; HD_TRACE_FUNCTION(); // generate triangle index buffer int const * numVertsPtr = _topology->GetFaceVertexCounts().cdata(); int const * vertsPtr = _topology->GetFaceVertexIndices().cdata(); int const * holeFacesPtr = _topology->GetHoleIndices().cdata(); int numFaces = _topology->GetFaceVertexCounts().size(); int numVertIndices = _topology->GetFaceVertexIndices().size(); int numTris = 0; int numHoleFaces = _topology->GetHoleIndices().size(); bool invalidTopology = false; int holeIndex = 0; for (int i=0; i<numFaces; ++i) { int nv = numVertsPtr[i]-2; if (nv < 1) { // skip degenerated face invalidTopology = true; } else if (holeIndex < numHoleFaces and holeFacesPtr[holeIndex] == i) { // skip hole face ++holeIndex; } else { numTris += nv; } } if (invalidTopology) { TF_WARN("degenerated face found [%s]", _id.GetText()); invalidTopology = false; } VtVec3iArray trianglesFaceVertexIndices(numTris); VtIntArray primitiveParam(numTris); bool flip = (_topology->GetOrientation() != HdTokens->rightHanded); // reset holeIndex holeIndex = 0; for (int i=0,tv=0,v=0; i<numFaces; ++i) { int nv = numVertsPtr[i]; if (nv < 3) { // Skip degenerate faces. } else if (holeIndex < numHoleFaces and holeFacesPtr[holeIndex] == i) { // Skip hole faces. ++holeIndex; } else { // edgeFlag is used for inner-line removal of non-triangle // faces on wireframe shading. // // 0__ 0 0 0__ // _/|\ \_ _/. .. . \_ // _/ | \ \_ -> _/ . . . . \_ // / A |C \ B \_ / A . .C . . B \_ // 1-----2---3----4 1-----2 1---2 1----2 // // Type EdgeFlag Draw // - 0 show all edges // A 1 hide [2-0] // B 2 hide [0-1] // C 3 hide [0-1] and [2-0] // int edgeFlag = 0; for (int j=0; j < nv-2; ++j) { if (nv > 3) { if (j == 0) edgeFlag = flip ? 2 : 1; else if (j == nv-3) edgeFlag = flip ? 1 : 2; else edgeFlag = 3; } if (not _FanTriangulate( trianglesFaceVertexIndices[tv], vertsPtr, v, j, numVertIndices, flip)) { invalidTopology = true; } // note that ptex indexing isn't available along with // triangulation. int coarseFaceParam = HdMeshTopology::EncodeCoarseFaceParam(i, edgeFlag); primitiveParam[tv] = coarseFaceParam; ++tv; } } // When the face is degenerate and nv > 0, we need to increment the v // pointer to walk past the degenerate verts. v += nv; } if (invalidTopology) { TF_WARN("numVerts and verts are incosistent [%s]", _id.GetText()); } _SetResult(HdBufferSourceSharedPtr( new HdVtBufferSource( HdTokens->indices, VtValue(trianglesFaceVertexIndices)))); _primitiveParam.reset(new HdVtBufferSource( HdTokens->primitiveParam, VtValue(primitiveParam))); _SetResolved(); return true; }