13#include <pxr/base/gf/rotation.h>
14#include <pxr/base/gf/vec3f.h>
15#include <pxr/usd/usdGeom/metrics.h>
16#include <pxr/usd/usdGeom/tokens.h>
17#include <pxr/usd/usdGeom/xformCache.h>
18#include <pxr/usd/usdGeom/xformCommonAPI.h>
19#include <pxr/usd/usdLux/domeLight.h>
20#include <pxr/usd/usdLux/tokens.h>
52static const pxr::TfToken
pole_axis_z(
"Z", pxr::TfToken::Immortal);
57struct WorldNtreeSearchPayload {
59 pxr::UsdStageRefPtr stage;
62 pxr::UsdStageRefPtr in_stage)
63 :
params(in_params), stage(in_stage)
82 std::string imported_file_source_path = tex_path;
84 if (import_textures) {
89 params.import_textures_dir;
94 params.tex_name_collision_mode;
96 tex_path =
import_asset(tex_path, textures_dir, name_collision_mode,
nullptr);
104 if (import_textures && imported_file_source_path != tex_path) {
123 int16_t new_node_type,
144 pxr::UsdStageRefPtr stage)
146 if (!(stage && scene && scene->
world)) {
158 std::string image_filepath;
162 if (image_filepath.empty()) {
165 if (
params.export_textures) {
172 pxr::UsdLuxDomeLight dome_light = pxr::UsdLuxDomeLight::Define(stage, env_light_path);
176 dome_light.CreateTextureFileAttr().Set(pxr::SdfAssetPath(image_filepath));
181 dome_light.CreateColorAttr().Set(color_val);
185 pxr::GfVec3d angles = res.
transform.DecomposeRotation(
186 pxr::GfVec3d::ZAxis(), pxr::GfVec3d::YAxis(), pxr::GfVec3d::XAxis());
187 pxr::GfVec3f rot_vec(angles[2], angles[1], angles[0]);
188 pxr::UsdGeomXformCommonAPI xform_api(dome_light);
189 xform_api.SetRotate(rot_vec, pxr::UsdGeomXformCommonAPI::RotationOrderXYZ);
194 dome_light.CreateIntensityAttr().Set(res.
intensity);
197 const std::string base_path = stage->GetRootLayer()->GetRealPath();
209 if (
BLI_copy(source_path.c_str(), dest_path) != 0) {
210 CLOG_WARN(&
LOG,
"USD Export: Couldn't write world color image to %s", dest_path);
215 dome_light.CreateTextureFileAttr().Set(pxr::SdfAssetPath(dest_path));
226 const pxr::UsdPrim &prim,
227 const pxr::UsdTimeCode time)
229 if (!(scene && scene->
world && prim)) {
235 nullptr, &scene->
world->
id,
"Shader Nodetree",
"ShaderNodeTree");
240 bNode *bgshader =
nullptr;
246 for (
bNode *node : ntree->all_nodes()) {
255 node->location[1] += 300;
262 output->location[0] = 300.0f;
263 output->location[1] = 300.0f;
277 if (shader_input && shader_input->
link) {
282 float intensity = dome_light_data.
intensity *
params.light_intensity_scale;
287 if (!dome_light_data.
has_tex) {
293 dome_light_data.
color.data());
313 vec_sock = vec_sock->
next;
318 dome_light_data.
color.data());
321 CLOG_WARN(&
LOG,
"Couldn't find vector multiply second vector socket");
325 bNode *tex =
nullptr;
341 const std::string &resolved_path = dome_light_data.
tex_path.GetResolvedPath();
342 if (resolved_path.empty()) {
344 "Couldn't get resolved path for asset %s",
345 dome_light_data.
tex_path.GetAssetPath().c_str());
351 CLOG_WARN(&
LOG,
"Couldn't load image file %s", resolved_path.c_str());
355 tex->
id = &image->
id;
358 pxr::UsdGeomXformCache xf_cache(time);
359 pxr::GfMatrix4d xf = xf_cache.GetLocalToWorldTransform(prim);
361 pxr::UsdStageRefPtr stage = prim.GetStage();
364 CLOG_WARN(&
LOG,
"Couldn't get stage for dome light %s", prim.GetPath().GetText());
371 const pxr::TfToken stage_up = pxr::UsdGeomGetStageUpAxis(stage);
372 const bool needs_stage_z_adjust = stage_up == pxr::UsdGeomTokens->z &&
374 pxr::UsdLuxTokens->Z,
375 pxr::UsdLuxTokens->scene);
376 const bool needs_stage_y_adjust = stage_up == pxr::UsdGeomTokens->y &&
378 if (needs_stage_z_adjust || needs_stage_y_adjust) {
379 xf *= pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 1.0, 0.0), 90.0));
381 else if (stage_up == pxr::UsdGeomTokens->
y) {
383 xf *= pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), 90.0));
387 xf = pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), -90.0)) *
388 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90.0)) * xf;
390 pxr::GfVec3d angles = xf.DecomposeRotation(
391 pxr::GfVec3d::XAxis(), pxr::GfVec3d::YAxis(), pxr::GfVec3d::ZAxis());
392 pxr::GfVec3f rot_vec(-angles[0], -angles[1], -angles[2]);
395 rot_vec *=
M_PI / 180.0f;
399 socket->default_value);
410 if (!(userdata && fromnode)) {
442 vec_sock = vec_sock->
next;
453 socket->default_value);
458 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), 90.0)) *
459 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0)) *
460 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), -
rot[2])) *
461 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 1.0, 0.0), -
rot[1])) *
462 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -
rot[0]));
473 "ShaderNodeOutputWorld");
475 for (
const bNode *node : bsdf_nodes) {
void BKE_image_packfiles(ReportList *reports, Image *ima, const char *basepath)
Image * BKE_image_load_exists(Main *bmain, const char *filepath, bool *r_exists=nullptr)
bool BKE_image_has_packedfile(const Image *image)
#define SH_NODE_OUTPUT_WORLD
#define SH_NODE_TEX_COORD
#define SH_NODE_VECTOR_MATH
#define SH_NODE_TEX_ENVIRONMENT
#define SH_NODE_BACKGROUND
void BKE_ntree_update_after_single_tree_change(Main &bmain, bNodeTree &modified_tree, const NodeTreeUpdateExtraParams ¶ms={})
File and directory operations.
int BLI_copy(const char *path_src, const char *path_dst) ATTR_NONNULL()
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
size_t BLI_path_append(char *__restrict dst, size_t dst_maxncpy, const char *__restrict file) ATTR_NONNULL(1
#define BLI_path_join(...)
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
void void BLI_path_split_dir_part(const char *filepath, char *dir, size_t dir_maxncpy) ATTR_NONNULL(1
size_t size_t BLI_path_append_dir(char *__restrict dst, size_t dst_maxncpy, const char *__restrict dir) ATTR_NONNULL(1
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
#define CLOG_WARN(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_BLEND_PATH(_bmain, _id)
@ NODE_VECTOR_MATH_MULTIPLY
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, StringRefNull name, StringRefNull idname)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
void node_chain_iterator(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *, const bool), void *userdata, bool reversed)
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
void node_set_active(bNodeTree &ntree, bNode &node)
void world_material_to_dome_light(const USDExportParams ¶ms, const Scene *scene, pxr::UsdStageRefPtr stage)
const char * temp_textures_dir()
bool should_import_asset(const std::string &path)
static Image * load_image(std::string tex_path, Main *bmain, const USDImportParams ¶ms)
pxr::SdfPath get_unique_path(pxr::UsdStageRefPtr stage, const std::string &path)
static void export_texture(const USDExporterContext &usd_export_context, bNode *node)
void dome_light_to_world_material(const USDImportParams ¶ms, Scene *scene, Main *bmain, const USDImportDomeLightData &dome_light_data, const pxr::UsdPrim &prim, const pxr::UsdTimeCode time)
std::string cache_image_color(const float color[4])
static bool node_search(bNode *fromnode, bNode *, void *userdata, bool)
@ USD_TEX_NAME_COLLISION_OVERWRITE
static std::string get_tex_image_asset_filepath(const USDExporterContext &usd_export_context, bNode *node)
void ensure_usd_source_path_prop(const std::string &path, ID *id)
static bNode * append_node(bNode *dst_node, int16_t new_node_type, const StringRef out_sock, const StringRef in_sock, bNodeTree *ntree, float offset)
std::string import_asset(const std::string &src, const char *import_dir, eUSDTexNameCollisionMode name_collision_mode, ReportList *reports)
static const pxr::TfToken pole_axis_z("Z", pxr::TfToken::Immortal)
struct bNodeTree * nodetree
struct bNodeSocket * next
pxr::SdfAssetPath tex_path
pxr::GfMatrix4d transform