bool GusdUSD_StageProxy::MultiAccessor::_GetPrims( const UT_Array<SdfPath>& primPaths, UT_Array<UsdPrim>& prims, GusdUT_ErrorContext* err) { if(!_Load(primPaths)) return false; prims.setSize(primPaths.size()); std::atomic_bool workerInterrupt(false); UTparallelFor(UT_BlockedRange<size_t>(0, primPaths.size()), _GetPrimsFn(*this, primPaths, prims, err, workerInterrupt)); return !UTgetInterrupt()->opInterrupt() && !workerInterrupt; }
OP_ERROR GusdSOP_usdimport::_CreateNewPrims(OP_Context& ctx, const GusdUSD_Traverse* traverse, GusdUT_ErrorContext& err) { fpreal t = ctx.getTime(); UT_String file, primPath; evalString(file, "import_file", 0, t); evalString(primPath, "import_primpath", 0, t); if(!file.isstring() || !primPath.isstring()) { // Nothing to do. return UT_ERROR_NONE; } /* The prim path may be a list of prims. Additionally, those prim paths may include variants (eg., /some/model{variant=sel}/subscope ). Including multiple variants may mean that we need to access multiple stages. Resolve the actual set of prims and variants first.*/ UT_Array<SdfPath> primPaths, variants; if(!GusdUSD_Utils::GetPrimAndVariantPathsFromPathList( primPath, primPaths, variants, &err)) return err(); GusdDefaultArray<UT_StringHolder> filePaths; filePaths.SetConstant(file); // Get stage edits applying any of our variants. GusdDefaultArray<GusdStageEditPtr> edits; edits.GetArray().setSize(variants.size()); for(exint i = 0; i < variants.size(); ++i) { if(!variants(i).IsEmpty()) { GusdStageBasicEdit* edit = new GusdStageBasicEdit; edit->GetVariants().append(variants(i)); edits.GetArray()(i).reset(edit); } } // Load the root prims. UT_Array<UsdPrim> rootPrims; { rootPrims.setSize(primPaths.size()); GusdStageCacheReader cache; if(!cache.GetPrims(filePaths, primPaths, edits, rootPrims.data(), GusdStageOpts::LoadAll(), &err)) return err(); } GusdDefaultArray<UsdTimeCode> times; times.SetConstant(evalFloat("import_time", 0, t)); UT_String purpose; evalString(purpose, "purpose", 0, t); GusdDefaultArray<GusdPurposeSet> purposes; purposes.SetConstant(GusdPurposeSet( GusdPurposeSetFromMask(purpose)| GUSD_PURPOSE_DEFAULT)); UT_Array<UsdPrim> prims; if(traverse) { // Before traversal, make a copy of the variants list. const UT_Array<SdfPath> variantsPreTraverse(variants); UT_Array<GusdUSD_Traverse::PrimIndexPair> primIndexPairs; UT_UniquePtr<GusdUSD_Traverse::Opts> opts(traverse->CreateOpts()); if(opts) { if(!opts->Configure(*this, t)) return err(); } if(!traverse->FindPrims(rootPrims, times, purposes, primIndexPairs, /*skip root*/ false, opts.get())) { return err(); } // Resize the prims and variants lists to match the size of // primIndexPairs. exint size = primIndexPairs.size(); prims.setSize(size); variants.setSize(size); // Now iterate through primIndexPairs to populate the prims // and variants lists. for (exint i = 0; i < size; i++) { prims(i) = primIndexPairs(i).first; exint index = primIndexPairs(i).second; variants(i) = index < variantsPreTraverse.size() ? variantsPreTraverse(index) : SdfPath(); } } else { std::swap(prims, rootPrims); } /* Have the resolved set of USD prims. Now create prims or points on the detail.*/ bool packedPrims = !evalInt("import_class", 0, t); if(packedPrims) { UT_String vpLOD; evalString(vpLOD, "viewportlod", 0, t); GusdDefaultArray<UT_StringHolder> lods; lods.SetConstant(vpLOD); GusdGU_USD::AppendPackedPrims(*gdp, prims, variants, times, lods, purposes, &err); } else { GusdGU_USD::AppendRefPoints(*gdp, prims, GUSD_PATH_ATTR, GUSD_PRIMPATH_ATTR, &err); } return err(); }