bool UsdGeomCollectionAPI::AppendTarget( const SdfPath &target, const VtIntArray &faceIndices /* =VtIntArray() */, const UsdTimeCode &time /* =UsdTimeCode::Default() */) const { if (target.IsEmpty()) { TF_CODING_ERROR("Cannot add empty target to collection '%s' on " "prim <%s>.", _name.GetText(), GetPath().GetText()); return false; } bool hasFaceCountsAtTime = true; if (time != UsdTimeCode::Default()) { UsdAttribute targetFaceCountsAttr = GetTargetFaceCountsAttr(); double lower=0., upper=0.; bool hasTimeSamples=false; if (targetFaceCountsAttr.GetBracketingTimeSamples(time.GetValue(), &lower, &upper, &hasTimeSamples)) { hasFaceCountsAtTime = (lower==upper && lower==time.GetValue()); } } VtIntArray targetFaceCounts, targetFaceIndices; if (hasFaceCountsAtTime) { GetTargetFaceCounts(&targetFaceCounts, time); GetTargetFaceIndices(&targetFaceIndices, time); } SdfPathVector targets; GetTargets(&targets); // If there are no existing face restrictions and no face-restriction is // specified on the current target, simly add the target and return. if (targetFaceCounts.empty() && targetFaceIndices.empty() && faceIndices.empty()) { // We can simply add the target here to the relationship here since // there are no companion non-list-edited integer arrays. return CreateTargetsRel().AppendTarget(target); } if (targetFaceCounts.empty() && !targetFaceIndices.empty()) { TF_CODING_ERROR("targetFaceCounts is empty, but targetFaceIndices " "is not, for the collection '%s' belonging to prim <%s>.", _name.GetText(), GetPath().GetText()); return false; } if (targetFaceCounts.empty() && !faceIndices.empty()) { for (size_t i = 0 ; i < targets.size(); i++) targetFaceCounts.push_back(0); } targetFaceCounts.push_back(faceIndices.size()); targetFaceIndices.reserve(targetFaceIndices.size() + faceIndices.size()); TF_FOR_ALL(it, faceIndices) { targetFaceIndices.push_back(*it); }
bool UsdGeomPointInstancer::ComputeInstanceTransformsAtTime( VtArray<GfMatrix4d>* xforms, const UsdTimeCode time, const UsdTimeCode baseTime, const ProtoXformInclusion doProtoXforms, const MaskApplication applyMask) const { // XXX: Need to add handling of velocities/angularVelocities and baseTime. (void)baseTime; if (!xforms) { TF_WARN("%s -- null container passed to ComputeInstanceTransformsAtTime()", GetPrim().GetPath().GetText()); return false; } VtIntArray protoIndices; if (!GetProtoIndicesAttr().Get(&protoIndices, time)) { TF_WARN("%s -- no prototype indices", GetPrim().GetPath().GetText()); return false; } if (protoIndices.empty()) { xforms->clear(); return true; } VtVec3fArray positions; if (!GetPositionsAttr().Get(&positions, time)) { TF_WARN("%s -- no positions", GetPrim().GetPath().GetText()); return false; } if (positions.size() != protoIndices.size()) { TF_WARN("%s -- positions.size() [%zu] != protoIndices.size() [%zu]", GetPrim().GetPath().GetText(), positions.size(), protoIndices.size()); return false; } VtVec3fArray scales; GetScalesAttr().Get(&scales, time); if (!scales.empty() && scales.size() != protoIndices.size()) { TF_WARN("%s -- scales.size() [%zu] != protoIndices.size() [%zu]", GetPrim().GetPath().GetText(), scales.size(), protoIndices.size()); return false; } VtQuathArray orientations; GetOrientationsAttr().Get(&orientations, time); if (!orientations.empty() && orientations.size() != protoIndices.size()) { TF_WARN("%s -- orientations.size() [%zu] != protoIndices.size() [%zu]", GetPrim().GetPath().GetText(), orientations.size(), protoIndices.size()); return false; } // If we're going to include the prototype transforms, verify that we have // prototypes and that all of the protoIndices are in bounds. SdfPathVector protoPaths; if (doProtoXforms == IncludeProtoXform) { const UsdRelationship prototypes = GetPrototypesRel(); if (!prototypes.GetTargets(&protoPaths) || protoPaths.empty()) { TF_WARN("%s -- no prototypes", GetPrim().GetPath().GetText()); return false; } TF_FOR_ALL(iter, protoIndices) { const int protoIndex = *iter; if (protoIndex < 0 || static_cast<size_t>(protoIndex) >= protoPaths.size()) { TF_WARN("%s -- invalid prototype index: %d. Should be in [0, %zu)", GetPrim().GetPath().GetText(), protoIndex, protoPaths.size()); return false; } } } // Compute the mask only if applyMask says we should, otherwise we leave // mask empty so that its application below is a no-op. std::vector<bool> mask; if (applyMask == ApplyMask) { mask = ComputeMaskAtTime(time); if (!mask.empty() && mask.size() != protoIndices.size()) { TF_WARN("%s -- mask.size() [%zu] != protoIndices.size() [%zu]", GetPrim().GetPath().GetText(), mask.size(), protoIndices.size()); return false; } } UsdStageWeakPtr stage = GetPrim().GetStage(); UsdGeomXformCache xformCache(time); xforms->assign(protoIndices.size(), GfMatrix4d(1.0)); for (size_t instanceId = 0; instanceId < protoIndices.size(); ++instanceId) { if (!mask.empty() && !mask[instanceId]) { continue; } GfTransform instanceTransform; if (!scales.empty()) { instanceTransform.SetScale(scales[instanceId]); } if (!orientations.empty()) { instanceTransform.SetRotation(GfRotation(orientations[instanceId])); } instanceTransform.SetTranslation(positions[instanceId]); GfMatrix4d protoXform(1.0); if (doProtoXforms == IncludeProtoXform) { const int protoIndex = protoIndices[instanceId]; const SdfPath& protoPath = protoPaths[protoIndex]; const UsdPrim& protoPrim = stage->GetPrimAtPath(protoPath); if (protoPrim) { // Get the prototype's local transformation. bool resetsXformStack; protoXform = xformCache.GetLocalTransformation(protoPrim, &resetsXformStack); } } (*xforms)[instanceId] = protoXform * instanceTransform.GetMatrix(); } return ApplyMaskToArray(mask, xforms); }