USD: implement native Unicode support
Make use of USD's new UTF-8 support to allow our import/export code to accept and generate appropriate USD files. This has been a long standing shortcoming since USD's introduction, with incomplete and complicated DCC-specific workarounds often attempted. Summary of changes - Export gets a new "Allow Unicode" option defaulting to "false". The new Unicode USD files are not backward compatible. DCCs using older versions of USD (before 24.03) will not be able to load such files so we want to provide this as an opt-in option for now. - Every location which used to call either `USDHierarchyIterator::make_valid_name` or `pxr::TfMakeValidIdentifier` will now go through a new `make_safe_name` API instead - Export code is responsible for passing in the `allow_unicode` option - Import code will always pass in `true` meaning Blender will happily accept both existing and new Unicode USD files Strangely, USD does not provide a convenient way of making valid UTF-8 identifiers and they left their old API unchanged. We had to roll our own per their advice: https://forum.aousd.org/t/how-to-make-a-unicode-identifier-valid/1435 Pull Request: https://projects.blender.org/blender/blender/pulls/122471
This commit is contained in:
committed by
Jesse Yurkovich
parent
f5131cdee0
commit
9ad2c7df0b
@@ -105,6 +105,9 @@ if(WITH_ALEMBIC)
|
||||
endif()
|
||||
|
||||
if(WITH_USD)
|
||||
list(APPEND INC_SYS
|
||||
${USD_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
bf_io_usd
|
||||
)
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
# include "io_utils.hh"
|
||||
# include "usd.hh"
|
||||
|
||||
# include <pxr/pxr.h>
|
||||
|
||||
# include <string>
|
||||
# include <utility>
|
||||
|
||||
@@ -259,6 +261,12 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
|
||||
|
||||
const int usdz_downscale_custom_size = RNA_int_get(op->ptr, "usdz_downscale_custom_size");
|
||||
|
||||
# if PXR_VERSION >= 2403
|
||||
const bool allow_unicode = RNA_boolean_get(op->ptr, "allow_unicode");
|
||||
# else
|
||||
const bool allow_unicode = false;
|
||||
# endif
|
||||
|
||||
char root_prim_path[FILE_MAX];
|
||||
RNA_string_get(op->ptr, "root_prim_path", root_prim_path);
|
||||
process_prim_path(root_prim_path);
|
||||
@@ -299,6 +307,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
|
||||
export_volumes,
|
||||
usdz_downscale_size,
|
||||
usdz_downscale_custom_size,
|
||||
allow_unicode,
|
||||
};
|
||||
|
||||
STRNCPY(params.root_prim_path, root_prim_path);
|
||||
@@ -337,6 +346,9 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op)
|
||||
row = uiLayoutRow(col, true);
|
||||
uiItemR(row, ptr, "author_blender_name", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiLayoutSetActive(row, RNA_boolean_get(op->ptr, "export_custom_properties"));
|
||||
# if PXR_VERSION >= 2403
|
||||
uiItemR(col, ptr, "allow_unicode", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
# endif
|
||||
|
||||
uiItemR(col, ptr, "convert_world_material", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
|
||||
@@ -645,6 +657,16 @@ void WM_OT_usd_export(wmOperatorType *ot)
|
||||
"Currently works for simple materials, consisting of an environment texture "
|
||||
"connected to a background shader, with an optional vector multiply of the texture color");
|
||||
|
||||
# if PXR_VERSION >= 2403
|
||||
RNA_def_boolean(
|
||||
ot->srna,
|
||||
"allow_unicode",
|
||||
false,
|
||||
"Allow Unicode",
|
||||
"Preserve UTF-8 encoded characters when writing USD prim and property names "
|
||||
"(requires software utilizing USD 24.03 or greater when opening the resulting files)");
|
||||
# endif
|
||||
|
||||
RNA_def_boolean(ot->srna, "export_meshes", true, "Meshes", "Export all meshes");
|
||||
|
||||
RNA_def_boolean(ot->srna, "export_lights", true, "Lights", "Export all lights");
|
||||
|
||||
@@ -97,6 +97,7 @@ set(SRC
|
||||
intern/usd_hook.cc
|
||||
intern/usd_light_convert.cc
|
||||
intern/usd_mesh_utils.cc
|
||||
intern/usd_utils.cc
|
||||
|
||||
intern/usd_writer_abstract.cc
|
||||
intern/usd_writer_armature.cc
|
||||
@@ -143,6 +144,7 @@ set(SRC
|
||||
intern/usd_hook.hh
|
||||
intern/usd_light_convert.hh
|
||||
intern/usd_mesh_utils.hh
|
||||
intern/usd_utils.hh
|
||||
|
||||
intern/usd_writer_abstract.hh
|
||||
intern/usd_writer_armature.hh
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_armature_utils.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
@@ -95,22 +96,23 @@ void get_armature_bone_names(const Object *ob_arm,
|
||||
visit_bones(ob_arm, visitor);
|
||||
}
|
||||
|
||||
pxr::TfToken build_usd_joint_path(const Bone *bone)
|
||||
pxr::TfToken build_usd_joint_path(const Bone *bone, bool allow_unicode)
|
||||
{
|
||||
std::string path(pxr::TfMakeValidIdentifier(bone->name));
|
||||
std::string path(bone->name);
|
||||
|
||||
const Bone *parent = bone->parent;
|
||||
while (parent) {
|
||||
path = pxr::TfMakeValidIdentifier(parent->name) + std::string("/") + path;
|
||||
path = parent->name + std::string("/") + path;
|
||||
parent = parent->parent;
|
||||
}
|
||||
|
||||
return pxr::TfToken(path);
|
||||
return pxr::TfToken(make_safe_name(path, allow_unicode));
|
||||
}
|
||||
|
||||
void create_pose_joints(pxr::UsdSkelAnimation &skel_anim,
|
||||
const Object &obj,
|
||||
const Map<StringRef, const Bone *> *deform_map)
|
||||
const Map<StringRef, const Bone *> *deform_map,
|
||||
bool allow_unicode)
|
||||
{
|
||||
BLI_assert(obj.pose);
|
||||
|
||||
@@ -126,7 +128,7 @@ void create_pose_joints(pxr::UsdSkelAnimation &skel_anim,
|
||||
continue;
|
||||
}
|
||||
|
||||
joints.push_back(build_usd_joint_path(pchan->bone));
|
||||
joints.push_back(build_usd_joint_path(pchan->bone, allow_unicode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,10 @@ void get_armature_bone_names(const Object *ob_arm, bool use_deform, Vector<std::
|
||||
* in the hierarchy.
|
||||
*
|
||||
* \param bone: The bone whose path will be queried.
|
||||
* \param allow_unicode: Whether to allow unicode bone names to be used
|
||||
* \return The path to the joint.
|
||||
*/
|
||||
pxr::TfToken build_usd_joint_path(const Bone *bone);
|
||||
pxr::TfToken build_usd_joint_path(const Bone *bone, bool allow_unicode);
|
||||
|
||||
/**
|
||||
* Sets the USD joint paths as an attribute on the given USD animation,
|
||||
@@ -61,10 +62,12 @@ pxr::TfToken build_usd_joint_path(const Bone *bone);
|
||||
* is not null, assume only deform bones are to be
|
||||
* exported and bones not found in this map will be
|
||||
* skipped
|
||||
* \param allow_unicode: Whether to allow unicode bone names to be used
|
||||
*/
|
||||
void create_pose_joints(pxr::UsdSkelAnimation &skel_anim,
|
||||
const Object &obj,
|
||||
const Map<StringRef, const Bone *> *deform_map);
|
||||
const Map<StringRef, const Bone *> *deform_map,
|
||||
bool allow_unicode);
|
||||
|
||||
/**
|
||||
* Return the modifier of the given type enabled for the given dependency graph's
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_blend_shape_utils.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include <pxr/usd/usdGeom/primvarsAPI.h>
|
||||
#include <pxr/usd/usdSkel/animMapper.h>
|
||||
@@ -190,7 +191,8 @@ bool is_mesh_with_shape_keys(const Object *obj)
|
||||
|
||||
void create_blend_shapes(pxr::UsdStageRefPtr stage,
|
||||
const Object *obj,
|
||||
const pxr::UsdPrim &mesh_prim)
|
||||
const pxr::UsdPrim &mesh_prim,
|
||||
bool allow_unicode)
|
||||
{
|
||||
const Key *key = get_mesh_shape_key(obj);
|
||||
|
||||
@@ -229,7 +231,7 @@ void create_blend_shapes(pxr::UsdStageRefPtr stage,
|
||||
continue;
|
||||
}
|
||||
|
||||
pxr::TfToken name(pxr::TfMakeValidIdentifier(kb->name));
|
||||
pxr::TfToken name(make_safe_name(kb->name, allow_unicode));
|
||||
blendshape_names.push_back(name);
|
||||
|
||||
pxr::SdfPath path = mesh_prim.GetPath().AppendChild(name);
|
||||
|
||||
@@ -44,10 +44,12 @@ bool is_mesh_with_shape_keys(const Object *obj);
|
||||
* \param stage: The stage
|
||||
* \param obj: The mesh object whose shape keys will be converted to blend shapes
|
||||
* \param mesh_prim: The USD mesh that will be assigned the blend shape targets
|
||||
* \param allow_unicode: Whether to allow unicode encoded characters in the blend shape name
|
||||
*/
|
||||
void create_blend_shapes(pxr::UsdStageRefPtr stage,
|
||||
const Object *obj,
|
||||
const pxr::UsdPrim &mesh_prim);
|
||||
const pxr::UsdPrim &mesh_prim,
|
||||
bool allow_unicode);
|
||||
|
||||
/**
|
||||
* Return the current weight values of the given key.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "usd_hierarchy_iterator.hh"
|
||||
#include "usd_skel_convert.hh"
|
||||
#include "usd_skel_root_utils.hh"
|
||||
#include "usd_utils.hh"
|
||||
#include "usd_writer_abstract.hh"
|
||||
#include "usd_writer_armature.hh"
|
||||
#include "usd_writer_camera.hh"
|
||||
@@ -21,8 +22,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <pxr/base/tf/stringUtils.h>
|
||||
|
||||
#include "BKE_main.hh"
|
||||
|
||||
#include "BLI_assert.h"
|
||||
@@ -78,7 +77,7 @@ void USDHierarchyIterator::release_writer(AbstractHierarchyWriter *writer)
|
||||
|
||||
std::string USDHierarchyIterator::make_valid_name(const std::string &name) const
|
||||
{
|
||||
return pxr::TfMakeValidIdentifier(name);
|
||||
return make_safe_name(name, params_.allow_unicode);
|
||||
}
|
||||
|
||||
void USDHierarchyIterator::process_usd_skel() const
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_reader_material.hh"
|
||||
#include "usd_reader_utils.hh"
|
||||
|
||||
#include "usd_asset_utils.hh"
|
||||
#include "usd_reader_utils.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include "BKE_appdir.hh"
|
||||
#include "BKE_image.h"
|
||||
@@ -1359,7 +1359,7 @@ void build_material_map(const Main *bmain, blender::Map<std::string, Material *>
|
||||
BLI_assert_msg(r_mat_map, "...");
|
||||
|
||||
LISTBASE_FOREACH (Material *, material, &bmain->materials) {
|
||||
std::string usd_name = pxr::TfMakeValidIdentifier(material->id.name + 2);
|
||||
std::string usd_name = make_safe_name(material->id.name + 2, true);
|
||||
r_mat_map->lookup_or_add_default(usd_name) = material;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "usd_mesh_utils.hh"
|
||||
#include "usd_reader_material.hh"
|
||||
#include "usd_skel_convert.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
@@ -84,6 +85,7 @@ static void assign_materials(Main *bmain,
|
||||
blender::Map<std::string, Material *> &mat_name_to_mat,
|
||||
blender::Map<std::string, std::string> &usd_path_to_mat_name)
|
||||
{
|
||||
using namespace blender::io::usd;
|
||||
if (!(stage && bmain && ob)) {
|
||||
return;
|
||||
}
|
||||
@@ -92,7 +94,7 @@ static void assign_materials(Main *bmain,
|
||||
return;
|
||||
}
|
||||
|
||||
blender::io::usd::USDMaterialReader mat_reader(params, bmain);
|
||||
USDMaterialReader mat_reader(params, bmain);
|
||||
|
||||
for (const auto item : mat_index_map.items()) {
|
||||
Material *assigned_mat = blender::io::usd::find_existing_material(
|
||||
@@ -120,10 +122,10 @@ static void assign_materials(Main *bmain,
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string mat_name = pxr::TfMakeValidIdentifier(assigned_mat->id.name + 2);
|
||||
const std::string mat_name = make_safe_name(assigned_mat->id.name + 2, true);
|
||||
mat_name_to_mat.lookup_or_add_default(mat_name) = assigned_mat;
|
||||
|
||||
if (params.mtl_name_collision_mode == blender::io::usd::USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
|
||||
if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
|
||||
/* Record the name of the Blender material we created for the USD material
|
||||
* with the given path. */
|
||||
usd_path_to_mat_name.lookup_or_add_default(item.key.GetAsString()) = mat_name;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "usd_reader_skeleton.hh"
|
||||
#include "usd_reader_volume.hh"
|
||||
#include "usd_reader_xform.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include <pxr/pxr.h>
|
||||
#include <pxr/usd/usdGeom/camera.h>
|
||||
@@ -566,7 +567,7 @@ void USDStageReader::import_all_materials(Main *bmain)
|
||||
Material *new_mtl = mtl_reader.add_material(usd_mtl);
|
||||
BLI_assert_msg(new_mtl, "Failed to create material");
|
||||
|
||||
const std::string mtl_name = pxr::TfMakeValidIdentifier(new_mtl->id.name + 2);
|
||||
const std::string mtl_name = make_safe_name(new_mtl->id.name + 2, true);
|
||||
settings_.mat_name_to_mat.lookup_or_add_default(mtl_name) = new_mtl;
|
||||
|
||||
if (params_.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
|
||||
|
||||
52
source/blender/io/usd/intern/usd_utils.cc
Normal file
52
source/blender/io/usd/intern/usd_utils.cc
Normal file
@@ -0,0 +1,52 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include <pxr/base/tf/stringUtils.h>
|
||||
#if PXR_VERSION >= 2403
|
||||
# include <pxr/base/tf/unicodeUtils.h>
|
||||
#endif
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
std::string make_safe_name(const std::string &name, [[maybe_unused]] bool allow_unicode)
|
||||
{
|
||||
#if PXR_VERSION >= 2403
|
||||
if (!allow_unicode) {
|
||||
return pxr::TfMakeValidIdentifier(name);
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
return "_";
|
||||
}
|
||||
|
||||
std::string buf;
|
||||
buf.resize(name.size()); // We won't be exceeding the size of the incoming string
|
||||
|
||||
bool first = true;
|
||||
size_t offset = 0;
|
||||
for (auto cp : pxr::TfUtf8CodePointView{name}) {
|
||||
constexpr pxr::TfUtf8CodePoint cp_underscore = pxr::TfUtf8CodePointFromAscii('_');
|
||||
const bool cp_allowed = first ? (cp == cp_underscore || pxr::TfIsUtf8CodePointXidStart(cp)) :
|
||||
pxr::TfIsUtf8CodePointXidContinue(cp);
|
||||
if (!cp_allowed) {
|
||||
offset += BLI_str_utf8_from_unicode(uint32_t('_'), buf.data() + offset, buf.size() - offset);
|
||||
}
|
||||
else {
|
||||
offset += BLI_str_utf8_from_unicode(cp.AsUInt32(), buf.data() + offset, buf.size() - offset);
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
return buf;
|
||||
#else
|
||||
return pxr::TfMakeValidIdentifier(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
||||
19
source/blender/io/usd/intern/usd_utils.hh
Normal file
19
source/blender/io/usd/intern/usd_utils.hh
Normal file
@@ -0,0 +1,19 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
/**
|
||||
* Return a valid USD identifier based on the passed in string.
|
||||
*
|
||||
* \param name: Incoming name to sanitize
|
||||
* \param allow_unicode: Whether to allow unicode encoded characters in the USD identifier
|
||||
* \return A valid USD identifier
|
||||
*/
|
||||
std::string make_safe_name(const std::string &name, bool allow_unicode);
|
||||
|
||||
} // namespace blender::io::usd
|
||||
@@ -2,9 +2,9 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#include "usd_writer_abstract.hh"
|
||||
#include "usd_utils.hh"
|
||||
#include "usd_writer_material.hh"
|
||||
|
||||
#include <pxr/base/tf/stringUtils.h>
|
||||
#include <pxr/usd/usdGeom/bboxCache.h>
|
||||
#include <pxr/usd/usdGeom/scope.h>
|
||||
|
||||
@@ -213,7 +213,8 @@ pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(const HierarchyCont
|
||||
pxr::UsdStageRefPtr stage = usd_export_context_.stage;
|
||||
|
||||
/* Construct the material. */
|
||||
pxr::TfToken material_name(pxr::TfMakeValidIdentifier(material->id.name + 2));
|
||||
pxr::TfToken material_name(
|
||||
make_safe_name(material->id.name + 2, usd_export_context_.export_params.allow_unicode));
|
||||
pxr::SdfPath usd_path = pxr::UsdGeomScope::Define(stage, get_material_library_path())
|
||||
.GetPath()
|
||||
.AppendChild(material_name);
|
||||
@@ -325,7 +326,8 @@ void USDAbstractWriter::write_user_properties(const pxr::UsdPrim &prim,
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string prop_name = pxr::TfMakeValidIdentifier(prop->name);
|
||||
std::string prop_name = make_safe_name(prop->name,
|
||||
usd_export_context_.export_params.allow_unicode);
|
||||
std::string full_prop_name = "userProperties:" + prop_name;
|
||||
|
||||
pxr::TfToken prop_token = pxr::TfToken(full_prop_name);
|
||||
|
||||
@@ -48,7 +48,8 @@ static pxr::GfMatrix4d parent_relative_pose_mat(const bPoseChannel *pchan)
|
||||
static void initialize(const Object *obj,
|
||||
pxr::UsdSkelSkeleton &skel,
|
||||
pxr::UsdSkelAnimation &skel_anim,
|
||||
const blender::Map<blender::StringRef, const Bone *> *deform_bones)
|
||||
const blender::Map<blender::StringRef, const Bone *> *deform_bones,
|
||||
bool allow_unicode)
|
||||
{
|
||||
using namespace blender::io::usd;
|
||||
|
||||
@@ -68,7 +69,7 @@ static void initialize(const Object *obj,
|
||||
return;
|
||||
}
|
||||
|
||||
joints.push_back(build_usd_joint_path(bone));
|
||||
joints.push_back(build_usd_joint_path(bone, allow_unicode));
|
||||
const pxr::GfMatrix4f arm_mat(bone->arm_mat);
|
||||
bind_xforms.push_back(pxr::GfMatrix4d(arm_mat));
|
||||
|
||||
@@ -97,7 +98,7 @@ static void initialize(const Object *obj,
|
||||
if (skel_anim) {
|
||||
usd_skel_api.CreateAnimationSourceRel().SetTargets(
|
||||
pxr::SdfPathVector({pxr::SdfPath(usdtokens::Anim)}));
|
||||
create_pose_joints(skel_anim, *obj, deform_bones);
|
||||
create_pose_joints(skel_anim, *obj, deform_bones, allow_unicode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,13 +167,14 @@ void USDArmatureWriter::do_write(HierarchyContext &context)
|
||||
}
|
||||
}
|
||||
|
||||
const bool allow_unicode = usd_export_context_.export_params.allow_unicode;
|
||||
Map<StringRef, const Bone *> *deform_map = usd_export_context_.export_params.only_deform_bones ?
|
||||
&deform_map_ :
|
||||
nullptr;
|
||||
|
||||
if (!this->frame_has_been_written_) {
|
||||
init_deform_bones_map(context.object, deform_map);
|
||||
initialize(context.object, skel, skel_anim, deform_map);
|
||||
initialize(context.object, skel, skel_anim, deform_map, allow_unicode);
|
||||
}
|
||||
|
||||
if (usd_export_context_.export_params.export_animation) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "usd_attribute_utils.hh"
|
||||
#include "usd_hierarchy_iterator.hh"
|
||||
#include "usd_utils.hh"
|
||||
#include "usd_writer_curves.hh"
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
@@ -405,7 +406,8 @@ void USDCurvesWriter::write_generic_data(const bke::CurvesGeometry &curves,
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode timecode = get_export_time_code();
|
||||
const pxr::TfToken pv_name(pxr::TfMakeValidIdentifier(attribute_id.name()));
|
||||
const pxr::TfToken pv_name(
|
||||
make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode));
|
||||
const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_curves);
|
||||
|
||||
pxr::UsdGeomPrimvar pv_attr = pv_api.CreatePrimvar(pv_name, *pv_type, *pv_interp);
|
||||
@@ -425,7 +427,8 @@ void USDCurvesWriter::write_uv_data(const bke::CurvesGeometry &curves,
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode timecode = get_export_time_code();
|
||||
const pxr::TfToken pv_name(pxr::TfMakeValidIdentifier(attribute_id.name()));
|
||||
const pxr::TfToken pv_name(
|
||||
make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode));
|
||||
const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_curves);
|
||||
|
||||
pxr::UsdGeomPrimvar pv_uv = pv_api.CreatePrimvar(
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_writer_material.hh"
|
||||
|
||||
#include "usd_exporter_context.hh"
|
||||
#include "usd_hook.hh"
|
||||
#include "usd_utils.hh"
|
||||
#include "usd_writer_abstract.hh"
|
||||
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_image_format.h"
|
||||
@@ -472,7 +473,8 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context,
|
||||
if (uv_node && uv_node->storage) {
|
||||
NodeShaderUVMap *shader_uv_map = static_cast<NodeShaderUVMap *>(uv_node->storage);
|
||||
/* We need to make valid here because actual uv primvar has been. */
|
||||
uv_name = pxr::TfMakeValidIdentifier(shader_uv_map->uv_map);
|
||||
uv_name = make_safe_name(shader_uv_map->uv_map,
|
||||
usd_export_context.export_params.allow_unicode);
|
||||
}
|
||||
|
||||
uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->String).Set(uv_name);
|
||||
@@ -778,7 +780,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u
|
||||
const int type)
|
||||
{
|
||||
pxr::SdfPath shader_path = material.GetPath().AppendChild(
|
||||
pxr::TfToken(pxr::TfMakeValidIdentifier(name)));
|
||||
pxr::TfToken(make_safe_name(name, usd_export_context.export_params.allow_unicode)));
|
||||
pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(usd_export_context.stage, shader_path);
|
||||
|
||||
switch (type) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "usd_attribute_utils.hh"
|
||||
#include "usd_blend_shape_utils.hh"
|
||||
#include "usd_skel_convert.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include <pxr/usd/usdGeom/mesh.h>
|
||||
#include <pxr/usd/usdGeom/primvarsAPI.h>
|
||||
@@ -261,7 +262,8 @@ void USDGenericMeshWriter::write_generic_data(const Mesh *mesh,
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode timecode = get_export_time_code();
|
||||
const pxr::TfToken pv_name(pxr::TfMakeValidIdentifier(attribute_id.name()));
|
||||
const pxr::TfToken pv_name(
|
||||
make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode));
|
||||
const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_mesh);
|
||||
|
||||
pxr::UsdGeomPrimvar pv_attr = pv_api.CreatePrimvar(pv_name, *pv_type, *pv_interp);
|
||||
@@ -282,7 +284,8 @@ void USDGenericMeshWriter::write_uv_data(const Mesh *mesh,
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode timecode = get_export_time_code();
|
||||
const pxr::TfToken pv_name(pxr::TfMakeValidIdentifier(attribute_id.name()));
|
||||
const pxr::TfToken pv_name(
|
||||
make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode));
|
||||
const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_mesh);
|
||||
|
||||
pxr::UsdGeomPrimvar pv_uv = pv_api.CreatePrimvar(
|
||||
@@ -303,7 +306,8 @@ void USDGenericMeshWriter::write_color_data(const Mesh *mesh,
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode timecode = get_export_time_code();
|
||||
const pxr::TfToken pv_name(pxr::TfMakeValidIdentifier(attribute_id.name()));
|
||||
const pxr::TfToken pv_name(
|
||||
make_safe_name(attribute_id.name(), usd_export_context_.export_params.allow_unicode));
|
||||
const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_mesh);
|
||||
|
||||
/* Varying type depends on original domain. */
|
||||
@@ -876,7 +880,10 @@ void USDMeshWriter::init_blend_shapes(const HierarchyContext &context)
|
||||
return;
|
||||
}
|
||||
|
||||
create_blend_shapes(this->usd_export_context_.stage, context.object, mesh_prim);
|
||||
create_blend_shapes(this->usd_export_context_.stage,
|
||||
context.object,
|
||||
mesh_prim,
|
||||
usd_export_context_.export_params.allow_unicode);
|
||||
}
|
||||
|
||||
void USDMeshWriter::do_write(HierarchyContext &context)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "usd_writer_volume.hh"
|
||||
#include "usd_hierarchy_iterator.hh"
|
||||
#include "usd_utils.hh"
|
||||
|
||||
#include <pxr/base/tf/pathUtils.h>
|
||||
#include <pxr/usd/usdVol/openVDBAsset.h>
|
||||
@@ -73,7 +74,8 @@ void USDVolumeWriter::do_write(HierarchyContext &context)
|
||||
for (const int i : IndexRange(num_grids)) {
|
||||
const bke::VolumeGridData *grid = BKE_volume_grid_get(volume, i);
|
||||
const std::string grid_name = bke::volume_grid::get_name(*grid);
|
||||
const std::string grid_id = pxr::TfMakeValidIdentifier(grid_name);
|
||||
const std::string grid_id = make_safe_name(grid_name,
|
||||
usd_export_context_.export_params.allow_unicode);
|
||||
const pxr::SdfPath grid_path = volume_path.AppendPath(pxr::SdfPath(grid_id));
|
||||
pxr::UsdVolOpenVDBAsset usd_grid = pxr::UsdVolOpenVDBAsset::Define(stage, grid_path);
|
||||
usd_grid.GetFieldNameAttr().Set(pxr::TfToken(grid_name), timecode);
|
||||
|
||||
@@ -129,9 +129,11 @@ struct USDExportParams {
|
||||
bool export_cameras = true;
|
||||
bool export_curves = true;
|
||||
bool export_volumes = true;
|
||||
|
||||
eUSDZTextureDownscaleSize usdz_downscale_size = eUSDZTextureDownscaleSize::USD_TEXTURE_SIZE_KEEP;
|
||||
int usdz_downscale_custom_size = 128;
|
||||
|
||||
bool allow_unicode = false;
|
||||
|
||||
char root_prim_path[1024] = ""; /* FILE_MAX */
|
||||
char collection[MAX_IDPROP_NAME] = "";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user