82 if (!stage || !mesh_prim) {
86 pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(mesh_prim);
90 "Couldn't apply UsdSkelBindingAPI to mesh prim %s",
91 mesh_prim.GetPath().GetAsString().c_str());
95 pxr::UsdSkelSkeleton skel;
96 if (!skel_api.GetSkeleton(&skel)) {
97 pxr::SdfPath skel_path = mesh_prim.GetParent().GetPath().AppendChild(
usdtokens::Skel);
98 skel = pxr::UsdSkelSkeleton::Define(stage, skel_path);
102 "Couldn't find or create skeleton bound to mesh prim %s",
103 mesh_prim.GetPath().GetAsString().c_str());
107 skel_api.CreateSkeletonRel().AddTarget(skel.GetPath());
110 pxr::VtMatrix4dArray bind_transforms(1, pxr::GfMatrix4d(1.0));
111 pxr::VtMatrix4dArray rest_transforms(1, pxr::GfMatrix4d(1.0));
112 skel.CreateBindTransformsAttr().Set(bind_transforms);
113 skel.GetRestTransformsAttr().Set(rest_transforms);
118 skel.CreateJointsAttr().Set(joints);
121 pxr::UsdAttribute temp_weights_attr = pxr::UsdGeomPrimvarsAPI(mesh_prim).GetPrimvar(
124 if (!temp_weights_attr) {
130 pxr::UsdSkelAnimation anim = pxr::UsdSkelAnimation::Define(stage, anim_path);
133 CLOG_WARN(&
LOG,
"Couldn't define animation at path %s", anim_path.GetAsString().c_str());
137 pxr::VtTokenArray blendshape_names;
138 skel_api.GetBlendShapesAttr().Get(&blendshape_names);
139 anim.CreateBlendShapesAttr().Set(blendshape_names);
141 std::vector<double> times;
142 temp_weights_attr.GetTimeSamples(×);
144 pxr::UsdAttribute anim_weights_attr = anim.CreateBlendShapeWeightsAttr();
146 pxr::VtFloatArray weights;
147 for (
const double time : times) {
148 if (temp_weights_attr.Get(&weights, time)) {
149 anim_weights_attr.Set(weights, time);
155 skel_api = pxr::UsdSkelBindingAPI::Apply(skel.GetPrim());
159 "Couldn't apply UsdSkelBindingAPI to skeleton prim %s",
160 skel.GetPath().GetAsString().c_str());
164 if (!skel_api.CreateAnimationSourceRel().AddTarget(pxr::SdfPath(
usdtokens::Anim))) {
166 "Couldn't set animation source on skeleton %s",
167 skel.GetPath().GetAsString().c_str());
194 const pxr::UsdPrim &mesh_prim,
199 if (!(key && mesh_prim)) {
203 pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(mesh_prim);
207 "Couldn't apply UsdSkelBindingAPI to mesh prim %s",
208 mesh_prim.GetPath().GetAsString().c_str());
212 pxr::VtTokenArray blendshape_names;
213 std::vector<pxr::SdfPath> blendshape_paths;
222 int basis_totelem = basis_key->
totelem;
229 if (kb == basis_key) {
235 blendshape_names.push_back(
name);
237 pxr::SdfPath path = mesh_prim.GetPath().AppendChild(
name);
238 blendshape_paths.push_back(path);
240 pxr::UsdSkelBlendShape blendshape = pxr::UsdSkelBlendShape::Define(stage, path);
242 pxr::UsdAttribute offsets_attr = blendshape.CreateOffsetsAttr();
247 pxr::UsdAttribute point_indices_attr = blendshape.CreatePointIndicesAttr();
249 pxr::VtVec3fArray offsets(kb->totelem);
250 pxr::VtIntArray
indices(kb->totelem);
253 const float (*fp)[3] =
static_cast<float (*)[3]
>(kb->data);
255 const float (*basis_fp)[3] =
static_cast<float (*)[3]
>(basis_key->
data);
257 for (
int i = 0;
i < kb->totelem; ++
i) {
263 offsets_attr.Set(offsets);
264 point_indices_attr.Set(
indices);
268 pxr::UsdAttribute blendshape_attr = skel_api.CreateBlendShapesAttr();
269 blendshape_attr.Set(blendshape_names);
270 skel_api.CreateBlendShapeTargetsRel().SetTargets(blendshape_paths);
275 if (!skel_api.GetJointIndicesAttr().HasAuthoredValue()) {
276 pxr::VtArray<int> joint_indices(basis_totelem, 0);
277 skel_api.CreateJointIndicesPrimvar(false, 1).GetAttr().Set(joint_indices);
280 if (!skel_api.GetJointWeightsAttr().HasAuthoredValue()) {
281 pxr::VtArray<float> joint_weights(basis_totelem, 1.0f);
282 skel_api.CreateJointWeightsPrimvar(false, 1).GetAttr().Set(joint_weights);
304 const pxr::SdfPath &skel_path,
305 const pxr::SdfPathSet &mesh_paths)
307 pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Get(stage, skel_path);
310 CLOG_WARN(&
LOG,
"Couldn't get skeleton from path %s", skel_path.GetAsString().c_str());
315 pxr::UsdPrim anim_prim;
316 pxr::UsdSkelAnimation anim;
317 if (skel_api.GetAnimationSource(&anim_prim)) {
318 anim = pxr::UsdSkelAnimation(anim_prim);
322 anim = pxr::UsdSkelAnimation::Define(stage, anim_path);
326 CLOG_WARN(&
LOG,
"Couldn't get animation under skeleton %s", skel_path.GetAsString().c_str());
341 for (
const pxr::SdfPath &mesh_path : mesh_paths) {
343 pxr::UsdPrim mesh_prim = stage->GetPrimAtPath(mesh_path);
344 pxr::UsdSkelBindingAPI mesh_skel_api = pxr::UsdSkelBindingAPI::Apply(mesh_prim);
345 if (!mesh_skel_api) {
347 "Couldn't apply UsdSkelBindingAPI to mesh prim %s",
348 mesh_path.GetAsString().c_str());
353 pxr::UsdAttribute blend_shapes_attr = mesh_skel_api.GetBlendShapesAttr();
355 if (!blend_shapes_attr) {
359 pxr::VtTokenArray names;
360 if (!mesh_skel_api.GetBlendShapesAttr().Get(&names)) {
365 pxr::VtTokenArray unique_names;
367 for (
const pxr::TfToken &
name : names.AsConst()) {
368 std::string unique = add_unique_name(merged_names,
name.GetString());
369 unique_names.push_back(pxr::TfToken(unique));
373 mesh_skel_api.GetBlendShapesAttr().
Set(unique_names);
376 const pxr::UsdAttribute temp_weights_attr = pxr::UsdGeomPrimvarsAPI(mesh_prim).GetPrimvar(
379 if (!temp_weights_attr) {
385 merge_info.
append(BlendShapeMergeInfo());
386 merge_info.
last().src_blend_shapes = unique_names;
387 merge_info.
last().src_weights_attr = temp_weights_attr;
396 pxr::VtTokenArray skel_blend_shape_names;
397 for (
const std::string &
name : merged_names) {
398 skel_blend_shape_names.push_back(pxr::TfToken(
name));
402 for (BlendShapeMergeInfo &info : merge_info) {
403 info.init_anim_map(skel_blend_shape_names);
407 anim.CreateBlendShapesAttr().
Set(skel_blend_shape_names);
409 pxr::UsdAttribute dst_weights_attr = anim.CreateBlendShapeWeightsAttr();
412 std::vector<double> times;
413 merge_info.
first().src_weights_attr.GetTimeSamples(×);
418 times.push_back(pxr::UsdTimeCode::Default().GetValue());
421 pxr::VtFloatArray dst_weights;
423 for (
const double time : times) {
424 for (
const BlendShapeMergeInfo &info : merge_info) {
425 pxr::VtFloatArray src_weights;
426 if (info.src_weights_attr.Get(&src_weights, time)) {
427 if (!info.anim_map.Remap(src_weights.AsConst(), &dst_weights)) {
428 CLOG_WARN(&
LOG,
"Failed remapping blend shape weights");
433 dst_weights_attr.Set(dst_weights, time);
static void unique_name(bNode *node)