GT_PrimitiveHandle GusdPrimWrapper:: defineForRead( const GusdUSD_StageProxyHandle& stage, const UsdGeomImageable& sourcePrim, const UsdTimeCode& time, const GusdPurposeSet& purposes ) { GT_PrimitiveHandle gtUsdPrimHandle; GusdUSD_ImageableHolder::ScopedLock lock; GusdUSD_ImageableHolder holder( sourcePrim, stage->GetLock() ); lock.Acquire( holder, /*write*/false); UsdGeomImageable sourceImageable = *lock; // Find the function registered for the source prim's type // to define the prim from read and call that function. if(sourcePrim) { USDTypeToDefineFuncMap::const_iterator mapIt = s_usdTypeToFuncMap.find(sourceImageable.GetPrim().GetTypeName()); if(mapIt != s_usdTypeToFuncMap.end()) { gtUsdPrimHandle = mapIt->second(stage,sourcePrim,time,purposes); } } return gtUsdPrimHandle; }
bool MayaPrimWriter::writePrimAttrs(const MDagPath &dagT, const UsdTimeCode &usdTime, UsdGeomImageable &primSchema) { MStatus status; MFnDependencyNode depFn(getDagPath().node()); MFnDependencyNode depFn2(dagT.node()); // optionally also scan a shape's transform if merging transforms if (getArgs().exportVisibility) { bool isVisible = true; // if BOTH shape or xform is animated, then visible bool isAnimated = false; // if either shape or xform is animated, then animated PxrUsdMayaUtil::getPlugValue(depFn, "visibility", &isVisible, &isAnimated); if ( dagT.isValid() ) { bool isVis, isAnim; if (PxrUsdMayaUtil::getPlugValue(depFn2, "visibility", &isVis, &isAnim)){ isVisible = isVisible and isVis; isAnimated = isAnimated or isAnim; } } TfToken const &visibilityTok = (isVisible ? UsdGeomTokens->inherited : UsdGeomTokens->invisible); if (usdTime.IsDefault() != isAnimated ) { if (usdTime.IsDefault()) primSchema.CreateVisibilityAttr(VtValue(visibilityTok), true); else primSchema.CreateVisibilityAttr().Set(visibilityTok, usdTime); } } UsdPrim usdPrim = primSchema.GetPrim(); // There is no Gprim abstraction in this module, so process the few // gprim attrs here. UsdGeomGprim gprim = UsdGeomGprim(usdPrim); if (gprim and usdTime.IsDefault()){ PxrUsdMayaPrimWriterContext* unused = NULL; PxrUsdMayaTranslatorGprim::Write( getDagPath().node(), gprim, unused); } _writeUsdInfo(dagT, usdTime, usdPrim); // Write user-tagged export attributes. Write attributes on the transform // first, and then attributes on the shape node. This means that attribute // name collisions will always be handled by taking the shape node's value // if we're merging transforms and shapes. if (dagT.isValid() and !(dagT == getDagPath())) { PxrUsdMayaWriteUtil::WriteUserExportedAttributes(dagT, usdPrim, usdTime); } PxrUsdMayaWriteUtil::WriteUserExportedAttributes(getDagPath(), usdPrim, usdTime); return true; }
GT_PrimitiveHandle GusdPrimWrapper:: defineForRead( const UsdGeomImageable& sourcePrim, UsdTimeCode time, GusdPurposeSet purposes ) { GT_PrimitiveHandle gtUsdPrimHandle; // Find the function registered for the source prim's type // to define the prim from read and call that function. if(sourcePrim) { const TfToken& typeName = sourcePrim.GetPrim().GetTypeName(); USDTypeToDefineFuncMap::const_accessor caccessor; if(s_usdTypeToFuncMap.find(caccessor, typeName)) { gtUsdPrimHandle = caccessor->second(sourcePrim,time,purposes); } else { // If no function is registered for the prim's type, try to // find a supported base type. const TfType& baseType = TfType::Find<UsdSchemaBase>(); const TfType& derivedType = baseType.FindDerivedByName(typeName.GetText()); vector<TfType> ancestorTypes; derivedType.GetAllAncestorTypes(&ancestorTypes); for(size_t i=1; i<ancestorTypes.size(); ++i) { const TfType& ancestorType = ancestorTypes[i]; vector<string> typeAliases = baseType.GetAliases(ancestorType); typeAliases.push_back(ancestorType.GetTypeName()); for(auto const& typeAlias : typeAliases) { if(s_usdTypeToFuncMap.find(caccessor, TfToken(typeAlias))) { gtUsdPrimHandle = caccessor->second(sourcePrim,time,purposes); USDTypeToDefineFuncMap::accessor accessor; s_usdTypeToFuncMap.insert(accessor, typeName); accessor->second = caccessor->second; TF_WARN("Type \"%s\" not registered, using base type \"%s\".", typeName.GetText(), typeAlias.c_str()); break; } } if(gtUsdPrimHandle) break; } if(!gtUsdPrimHandle) { // If we couldn't find a function for the prim's type or any // of it's base types, register a function which returns an // empty prim handle. registerPrimDefinitionFuncForRead(typeName, _nullPrimReadFunc); TF_WARN("Couldn't read unsupported USD prim type \"%s\".", typeName.GetText()); } } } return gtUsdPrimHandle; }
GT_PrimitiveHandle GusdXformWrapper:: defineForRead( const UsdGeomImageable& sourcePrim, UsdTimeCode time, GusdPurposeSet purposes ) { return new GusdXformWrapper( UsdGeomXform( sourcePrim.GetPrim() ), time, purposes ); }
GT_PrimitiveHandle GusdScopeWrapper:: defineForRead( const GusdUSD_StageProxyHandle& stage, const UsdGeomImageable& sourcePrim, const UsdTimeCode& time, const GusdPurposeSet& purposes ) { return new GusdScopeWrapper( stage, UsdGeomScope( sourcePrim.GetPrim() ), time, purposes ); }
void GusdPrimWrapper::updateTransformFromGTPrim( const GfMatrix4d &xform, UsdTimeCode time, bool force ) { UsdGeomImageable usdGeom = getUsdPrimForWrite(); UsdGeomXformable prim( usdGeom ); // Determine if we need to clear previous transformations from a stronger // opinion on the stage before authoring ours. UsdStagePtr stage = usdGeom.GetPrim().GetStage(); UsdEditTarget currEditTarget = stage->GetEditTarget(); // If the edit target does no mapping, it is most likely the session // layer which means it is in the local layer stack and can overlay // any xformOps. if ( !currEditTarget.GetMapFunction().IsNull() && !currEditTarget.GetMapFunction().IsIdentity() ) { bool reset; std::vector<UsdGeomXformOp> xformVec = prim.GetOrderedXformOps(&reset); // The xformOps attribute is static so we only check if we haven't // changed anything yet. In addition nothing needs to be cleared if it // was previously empty. if (m_lastXformSet.IsDefault() && (int)xformVec.size() > 0) { // Load the root layer for temp, stronger opinion changes. stage->GetRootLayer()->SetPermissionToSave(false); stage->SetEditTarget(stage->GetRootLayer()); UsdGeomXformable stagePrim( getUsdPrimForWrite() ); // Clear the xformOps on the stronger layer, so our weaker edit // target (with mapping across a reference) can write out clean, // new transforms. stagePrim.ClearXformOpOrder(); stage->SetEditTarget(currEditTarget); } } if( !prim ) return; // Try to avoid setting the transform when we can. // If force it true, always write the transform (used when writting per frame) bool setKnot = true; if( !force ) { // Has the transform has been set at least once if( !m_lastXformSet.IsDefault() ) { // Is the transform at this frame the same as the last frame if( isClose(xform,m_xformCache) ) { setKnot = false; m_lastXformCompared = time; } else { // If the transform has been held for more than one frame, // set a knot on the last frame if( m_lastXformCompared != m_lastXformSet ) { prim.MakeMatrixXform().Set( m_xformCache, m_lastXformCompared ); } } } else { // If the transform is an identity, don't set it if( isClose(xform,GfMatrix4d( 1.0 ))) { setKnot = false; m_lastXformCompared = time; } else { // If the transform was identity and now isn't, set a knot on the last frame if( !m_lastXformCompared.IsDefault() ) { prim.MakeMatrixXform().Set( GfMatrix4d(1.0), m_lastXformCompared ); } } } } if( setKnot ) { prim.MakeMatrixXform().Set( xform, time ); m_xformCache = xform; m_lastXformSet = time; m_lastXformCompared = time; } }
bool GusdGU_PackedUSD::unpackPrim( GU_Detail& destgdp, UsdGeomImageable prim, const SdfPath& primPath, const UT_Matrix4D& xform, const GT_RefineParms& rparms, bool addPathAttributes ) const { GT_PrimitiveHandle gtPrim = GusdPrimWrapper::defineForRead( prim, m_frame, m_purposes ); if( !gtPrim ) { const TfToken &type = prim.GetPrim().GetTypeName(); if( type != "PxHairman" && type != "PxProcArgs" ) TF_WARN( "Can't convert prim for unpack. %s. Type = %s.", prim.GetPrim().GetPath().GetText(), type.GetText() ); return false; } GusdPrimWrapper* wrapper = UTverify_cast<GusdPrimWrapper*>(gtPrim.get()); if( !wrapper->unpack( destgdp, fileName(), primPath, xform, intrinsicFrame(), #if SYS_VERSION_FULL_INT < 0x10050000 intrinsicViewportLOD(), #else intrinsicViewportLOD( getPrim() ), #endif m_purposes )) { // If the wrapper prim does not do the unpack, do it here. UT_Array<GU_Detail *> details; if( prim.GetPrim().IsInMaster() ) { gtPrim->setPrimitiveTransform( new GT_Transform( &xform, 1 ) ); } GA_Size startIndex = destgdp.getNumPrimitives(); GT_Util::makeGEO(details, gtPrim, &rparms); for (exint i = 0; i < details.entries(); ++i) { copyPrimitiveGroups(*details(i), false); #if SYS_VERSION_FULL_INT < 0x11000000 unpackToDetail(destgdp, details(i), true); #else unpackToDetail(destgdp, details(i), &xform); #endif delete details(i); } if( addPathAttributes ) { // Add usdpath and usdprimpath attributes to unpacked geometry. GA_Size endIndex = destgdp.getNumPrimitives(); const char *path = prim.GetPrim().GetPath().GetString().c_str(); if( endIndex > startIndex ) { GA_RWHandleS primPathAttr( destgdp.addStringTuple( GA_ATTRIB_PRIMITIVE, GUSD_PRIMPATH_ATTR, 1 )); GA_RWHandleS pathAttr( destgdp.addStringTuple( GA_ATTRIB_PRIMITIVE, GUSD_PATH_ATTR, 1 )); for( GA_Size i = startIndex; i < endIndex; ++i ) { primPathAttr.set( destgdp.primitiveOffset( i ), 0, path ); pathAttr.set( destgdp.primitiveOffset( i ), 0, fileName().c_str() ); } } } } return true; }