5#include "testing/testing.h"
8#include <pxr/base/tf/stringUtils.h>
9#include <pxr/base/vt/types.h>
10#include <pxr/base/vt/value.h>
11#include <pxr/usd/sdf/types.h>
12#include <pxr/usd/usd/common.h>
13#include <pxr/usd/usd/prim.h>
14#include <pxr/usd/usd/stage.h>
15#include <pxr/usd/usdGeom/mesh.h>
72 BlendfileLoadingBaseTest::SetUp();
88 for (
auto child : prim.GetChildren()) {
89 if (child.IsA<pxr::UsdGeomMesh>()) {
93 return pxr::UsdPrim();
102 ASSERT_NE(bsdf_node,
nullptr);
103 ASSERT_TRUE(
bool(bsdf_prim));
105 for (
const auto *socket : bsdf_node->input_sockets()) {
107 if (attribute_token.IsEmpty()) {
112 const pxr::UsdAttribute bsdf_attribute = bsdf_prim.GetAttribute(attribute_token);
113 pxr::SdfPathVector paths;
114 bsdf_attribute.GetConnections(&paths);
115 if (!paths.empty() || !bsdf_attribute.IsValid()) {
120 const float socket_value_f = *socket->default_value_typed<
float>();
121 const float3 socket_value_3f = *socket->default_value_typed<
float3>();
122 float attribute_value_f;
123 pxr::GfVec3f attribute_value_3f;
125 switch (socket->type) {
127 bsdf_attribute.Get(&attribute_value_f, 0.0);
128 EXPECT_FLOAT_EQ(socket_value_f, attribute_value_f);
132 bsdf_attribute.Get(&attribute_value_3f, 0.0);
133 EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]);
134 EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]);
135 EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]);
139 bsdf_attribute.Get(&attribute_value_3f, 0.0);
140 EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]);
141 EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]);
142 EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]);
146 FAIL() <<
"Socket " << socket->name <<
" has unsupported type " << socket->type;
153 const pxr::UsdPrim &image_prim)
155 const Image *image =
reinterpret_cast<Image *
>(image_node->
id);
157 const pxr::UsdShadeShader image_shader(image_prim);
158 const pxr::UsdShadeInput file_input = image_shader.GetInput(pxr::TfToken(
"file"));
159 EXPECT_TRUE(
bool(file_input));
161 pxr::VtValue file_val;
162 EXPECT_TRUE(file_input.Get(&file_val));
163 EXPECT_TRUE(file_val.IsHolding<pxr::SdfAssetPath>());
165 pxr::SdfAssetPath image_prim_asset = file_val.Get<pxr::SdfAssetPath>();
180 pxr::VtIntArray face_indices;
181 pxr::VtIntArray face_counts;
182 pxr::VtVec3fArray positions;
187 mesh_prim.GetFaceVertexIndicesAttr().Get(&face_indices, 0.0);
188 mesh_prim.GetFaceVertexCountsAttr().Get(&face_counts, 0.0);
189 mesh_prim.GetPointsAttr().Get(&positions, 0.0);
190 mesh_prim.GetNormalsAttr().Get(&
normals, 0.0);
210 params.export_materials =
false;
211 params.export_normals =
true;
212 params.export_uvmaps =
false;
218 ASSERT_TRUE(
bool(stage)) <<
"Unable to load Stage from " <<
output_filename;
224 const Mesh *mesh =
static_cast<Mesh *
>(
object->data);
227 const pxr::SdfPath sdf_path(
"/" + pxr::TfMakeValidIdentifier(object_name.
c_str()));
228 pxr::UsdPrim prim = stage->GetPrimAtPath(sdf_path);
229 EXPECT_TRUE(
bool(prim));
231 const pxr::UsdGeomMesh mesh_prim(get_first_child_mesh(prim));
232 EXPECT_TRUE(
bool(mesh_prim));
234 compare_blender_mesh_to_usd_prim(mesh, mesh_prim);
241 auto found_nodes = nodetree->nodes_by_type(type_idname);
242 if (found_nodes.size() == 1) {
243 return found_nodes[0];
270 EXPECT_TRUE(
bool(material));
273 params.export_materials =
true;
274 params.export_normals =
true;
275 params.export_textures =
false;
276 params.export_uvmaps =
true;
277 params.generate_preview_surface =
true;
278 params.generate_materialx_network =
false;
279 params.convert_world_material =
false;
280 params.relative_paths =
false;
286 ASSERT_NE(stage,
nullptr) <<
"Unable to open exported stage: " <<
output_filename;
288 material->
nodetree->ensure_topology_cache();
290 "ShaderNodeBsdfPrincipled");
292 const std::string prim_name = pxr::TfMakeValidIdentifier(bsdf_node->
name);
293 const pxr::UsdPrim bsdf_prim = stage->GetPrimAtPath(
294 pxr::SdfPath(
"/_materials/Material/" + prim_name));
296 compare_blender_node_to_usd_prim(bsdf_node, bsdf_prim);
299 ASSERT_NE(image_node,
nullptr);
300 ASSERT_NE(image_node->
storage,
nullptr);
302 const std::string image_prim_name = pxr::TfMakeValidIdentifier(image_node->
name);
304 const pxr::UsdPrim image_prim = stage->GetPrimAtPath(
305 pxr::SdfPath(
"/_materials/Material/" + image_prim_name));
307 ASSERT_TRUE(
bool(image_prim)) <<
"Unable to find Material prim from exported stage "
310 compare_blender_image_to_usd_image_shader(image_node, image_prim);
322 ASSERT_EQ(
make_safe_name(
"Test|$bézier @ world",
false), std::string(
"Test__b__zier___world"));
324 std::string(
"Test______________________"));
326 std::string(
"Test___________________________"));
327 ASSERT_EQ(
make_safe_name(
"Test|∧hello ○ wórld",
false), std::string(
"Test____hello_____w__rld"));
336 ASSERT_EQ(
make_safe_name(
"Test|$bézier @ world",
true), std::string(
"Test__bézier___world"));
337 ASSERT_EQ(
make_safe_name(
"Test|ハローワールド",
true), std::string(
"Test_ハローワールド"));
338 ASSERT_EQ(
make_safe_name(
"Test|Γεια σου κόσμε",
true), std::string(
"Test_Γεια_σου_κόσμε"));
339 ASSERT_EQ(
make_safe_name(
"Test|∧hello ○ wórld",
true), std::string(
"Test__hello___wórld"));
void CTX_data_main_set(bContext *C, Main *bmain)
void CTX_free(bContext *C)
void CTX_data_scene_set(bContext *C, Scene *scene)
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_path_cmp_normalized(const char *p1, const char *p2) ATTR_NONNULL(1
external readfile function prototypes.
virtual void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode)
bool blendfile_load(const char *filepath)
struct BlendFileData * bfile
constexpr const char * c_str() const
pxr::UsdPrim get_first_child_mesh(const pxr::UsdPrim prim)
void compare_blender_image_to_usd_image_shader(const bNode *image_node, const pxr::UsdPrim &image_prim)
void compare_blender_node_to_usd_prim(const bNode *bsdf_node, const pxr::UsdPrim &bsdf_prim)
void compare_blender_mesh_to_usd_prim(const Mesh *mesh, const pxr::UsdGeomMesh &mesh_prim)
bool load_file_and_depsgraph(const StringRefNull &filepath, const eEvaluationMode eval_mode=DAG_EVAL_VIEWPORT)
static float normals[][3]
static const bNode * find_node_for_type_in_graph(const bNodeTree *nodetree, const blender::StringRefNull type_idname)
pxr::TfToken token_for_input(const StringRef input_name)
TEST_F(UsdExportTest, usd_export_rain_mesh)
TEST(utilities, make_safe_name)
std::string make_safe_name(const StringRef name, bool allow_unicode)
const StringRefNull simple_scene_filename
const StringRefNull materials_filename
bool USD_export(const bContext *C, const char *filepath, const USDExportParams *params, bool as_background_job, ReportList *reports)
const StringRefNull output_filename
VecBase< float, 3 > float3
struct bNodeTree * nodetree