8#include <pxr/base/tf/stringUtils.h>
9#include <pxr/usd/usdGeom/bboxCache.h>
10#include <pxr/usd/usdGeom/scope.h>
25static const pxr::TfToken
diffuse_color(
"diffuseColor", pxr::TfToken::Immortal);
26static const pxr::TfToken
metallic(
"metallic", pxr::TfToken::Immortal);
27static const pxr::TfToken
preview_shader(
"previewShader", pxr::TfToken::Immortal);
28static const pxr::TfToken
preview_surface(
"UsdPreviewSurface", pxr::TfToken::Immortal);
29static const pxr::TfToken
roughness(
"roughness", pxr::TfToken::Immortal);
30static const pxr::TfToken
surface(
"surface", pxr::TfToken::Immortal);
31static const pxr::TfToken
blender_ns(
"userProperties:blender", pxr::TfToken::Immortal);
44 return name ? name :
"";
47template<
typename USDT>
50 const pxr::TfToken &prop_token,
51 const pxr::SdfValueTypeName &type_name,
52 const pxr::UsdTimeCode &timecode)
54 if (!prim || !prop || !prop->
data.
pointer || prop_token.IsEmpty() || !type_name) {
58 pxr::UsdAttribute vec_attr = prim.CreateAttribute(prop_token, type_name,
true);
62 "Couldn't create USD attribute for array property %s",
63 prop_token.GetString().c_str());
67 USDT vec_value(
static_cast<typename USDT::ScalarType *
>(prop->
data.
pointer));
69 return vec_attr.Set(vec_value, timecode);
76 const pxr::TfToken &prop_token,
77 const pxr::UsdTimeCode &timecode)
79 if (!prim || !prop || prop_token.IsEmpty()) {
85 "Property %s is not an array type and can't be converted to a vector attribute",
90 pxr::SdfValueTypeName type_name;
95 type_name = pxr::SdfValueTypeNames->Float2;
98 else if (prop->
len == 3) {
99 type_name = pxr::SdfValueTypeNames->Float3;
102 else if (prop->
len == 4) {
103 type_name = pxr::SdfValueTypeNames->Float4;
108 if (prop->
len == 2) {
109 type_name = pxr::SdfValueTypeNames->Double2;
112 else if (prop->
len == 3) {
113 type_name = pxr::SdfValueTypeNames->Double3;
116 else if (prop->
len == 4) {
117 type_name = pxr::SdfValueTypeNames->Double4;
122 if (prop->
len == 2) {
123 type_name = pxr::SdfValueTypeNames->Int2;
126 else if (prop->
len == 3) {
127 type_name = pxr::SdfValueTypeNames->Int3;
130 else if (prop->
len == 4) {
131 type_name = pxr::SdfValueTypeNames->Int4;
138 "Couldn't determine USD type name for array property %s",
139 prop_token.GetString().c_str());
145 &
LOG,
"Couldn't set USD attribute from array property %s", prop_token.GetString().c_str());
151 : usd_export_context_(usd_export_context), frame_has_been_written_(
false), is_animated_(
false)
173 static pxr::UsdTimeCode default_timecode = pxr::UsdTimeCode::Default();
174 return default_timecode;
200 static std::string material_library_path(
"/_materials");
204 if (root_prim_path[0] !=
'\0') {
205 return pxr::SdfPath(root_prim_path + material_library_path);
208 return pxr::SdfPath(material_library_path);
217 pxr::TfToken material_name(
221 .AppendChild(material_name);
222 pxr::UsdShadeMaterial usd_material = pxr::UsdShadeMaterial::Get(
stage,
usd_path);
232 auto prim = usd_material.GetPrim();
239 const pxr::UsdTimeCode timecode,
240 const pxr::UsdGeomImageable &usd_geometry)
242 pxr::UsdAttribute attr_visibility = usd_geometry.CreateVisibilityAttr(pxr::VtValue(),
true);
244 const bool is_visible = context.is_object_visible(
246 const pxr::TfToken visibility = is_visible ? pxr::UsdGeomTokens->inherited :
247 pxr::UsdGeomTokens->invisible;
249 usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode);
256 if (context.export_path == context.original_export_path) {
258 "Reference error: export path matches reference path: %s",
259 context.export_path.c_str());
264 BLI_assert(!context.original_export_path.empty());
265 BLI_assert(context.original_export_path.front() ==
'/');
268 ref_path_str += context.original_export_path;
270 pxr::SdfPath ref_path(ref_path_str);
275 if (!prim.GetReferences().AddInternalReference(ref_path)) {
280 "Unable to add reference from %s to %s, not instancing object for export",
281 context.export_path.c_str(),
282 context.original_export_path.c_str());
291 pxr::UsdTimeCode timecode)
const
301 pxr::SdfValueTypeNames->String,
303 .Set<std::string>(std::string(
id.name + 2));
307 pxr::SdfValueTypeNames->String,
320 pxr::UsdTimeCode timecode)
const
322 if (properties ==
nullptr) {
330 const StringRef displayName_identifier =
"displayName";
332 const std::string default_namespace(
336 if (displayName_identifier == prop->name) {
337 if (prop->type ==
IDP_STRING && prop->data.pointer) {
338 prim.SetDisplayName(
static_cast<char *
>(prop->data.pointer));
343 std::vector<std::string> path_names = pxr::TfStringTokenize(prop->name,
":");
347 if (!default_namespace.empty() && path_names.size() < 2) {
348 path_names.insert(path_names.begin(), default_namespace);
351 std::vector<std::string> safe_names;
352 for (
const std::string &name : path_names) {
356 std::string full_prop_name = pxr::SdfPath::JoinIdentifier(safe_names);
357 pxr::TfToken prop_token = pxr::TfToken(full_prop_name);
359 if (prim.HasAttribute(prop_token)) {
365 switch (prop->type) {
367 if (pxr::UsdAttribute int_attr = prim.CreateAttribute(
368 prop_token, pxr::SdfValueTypeNames->Int,
true))
370 int_attr.Set<
int>(prop->data.val, timecode);
374 if (pxr::UsdAttribute float_attr = prim.CreateAttribute(
375 prop_token, pxr::SdfValueTypeNames->Float,
true))
377 float_attr.Set<
float>(*
reinterpret_cast<float *
>(&prop->data.val), timecode);
381 if (pxr::UsdAttribute double_attr = prim.CreateAttribute(
382 prop_token, pxr::SdfValueTypeNames->Double,
true))
384 double_attr.Set<
double>(*
reinterpret_cast<double *
>(&prop->data.val), timecode);
388 if (pxr::UsdAttribute str_attr = prim.CreateAttribute(
389 prop_token, pxr::SdfValueTypeNames->String,
true))
391 str_attr.Set<std::string>(
static_cast<const char *
>(prop->data.pointer), timecode);
395 if (pxr::UsdAttribute bool_attr = prim.CreateAttribute(
396 prop_token, pxr::SdfValueTypeNames->Bool,
true))
398 bool_attr.Set<
bool>(prop->data.val, timecode);
412 const bool useExtentsHint =
false;
413 const pxr::TfTokenVector includedPurposes{pxr::UsdGeomTokens->default_};
414 pxr::UsdGeomBBoxCache bboxCache(timecode, includedPurposes, useExtentsHint);
415 pxr::GfBBox3d bounds = bboxCache.ComputeLocalBound(prim.GetPrim());
416 if (pxr::GfBBox3d() == bounds) {
420 "USD Export: no bounds could be computed for %s",
421 prim.GetPrim().GetName().GetText());
425 pxr::VtArray<pxr::GfVec3f> extent{(pxr::GfVec3f)bounds.GetRange().GetMin(),
426 (pxr::GfVec3f)bounds.GetRange().GetMax()};
427 prim.CreateExtentAttr().Set(extent);
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_msg(a, msg)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue Hue Saturation Apply a color transformation in the HSV color model Specular Similar to the Principled BSDF node but uses the specular workflow instead of metallic
virtual bool check_is_animated(const HierarchyContext &context) const
pxr::UsdShadeMaterial ensure_usd_material(const HierarchyContext &context, Material *material) const
virtual void do_write(HierarchyContext &context)=0
bool frame_has_been_written_
const pxr::SdfPath & usd_path() const
void write_user_properties(const pxr::UsdPrim &prim, IDProperty *properties, pxr::UsdTimeCode=pxr::UsdTimeCode::Default()) const
void write_visibility(const HierarchyContext &context, const pxr::UsdTimeCode timecode, const pxr::UsdGeomImageable &usd_geometry)
pxr::SdfPath get_material_library_path() const
ReportList * reports() const
virtual void author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim)
virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim)
pxr::UsdTimeCode get_export_time_code() const
pxr::UsdUtilsSparseValueWriter usd_value_writer_
USDAbstractWriter(const USDExporterContext &usd_export_context)
void write_id_properties(const pxr::UsdPrim &prim, const ID &id, pxr::UsdTimeCode=pxr::UsdTimeCode::Default()) const
virtual void write(HierarchyContext &context) override
virtual bool is_supported(const HierarchyContext *context) const
std::string get_export_file_path() const
const USDExporterContext usd_export_context_
std::string make_safe_name(const std::string &name, bool allow_unicode)
static void create_vector_attrib(const pxr::UsdPrim &prim, const IDProperty *prop, const pxr::TfToken &prop_token, const pxr::UsdTimeCode &timecode)
pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context, pxr::SdfPath usd_path, Material *material, const std::string &active_uvmap_name, ReportList *reports)
static const pxr::TfToken preview_shader("previewShader", pxr::TfToken::Immortal)
static const pxr::TfToken surface("surface", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
static const pxr::TfToken blender_ns("userProperties:blender", pxr::TfToken::Immortal)
static const pxr::TfToken diffuse_color("diffuseColor", pxr::TfToken::Immortal)
static const pxr::TfToken preview_surface("UsdPreviewSurface", pxr::TfToken::Immortal)
char root_prim_path[1024]
char custom_properties_namespace[MAX_IDPROP_NAME]
enum eEvaluationMode evaluation_mode
bool export_custom_properties
std::function< pxr::UsdTimeCode()> get_time_code
const USDExportParams & export_params
const pxr::SdfPath usd_path
std::string export_file_path
const pxr::UsdStageRefPtr stage
bool set_vec_attrib(const pxr::UsdPrim &prim, const IDProperty *prop, const pxr::TfToken &prop_token, const pxr::SdfValueTypeName &type_name, const pxr::UsdTimeCode &timecode)
static std::string get_mesh_active_uvlayer_name(const Object *ob)