USD export: prototype invoking Python chasers #108823
|
@ -116,7 +116,8 @@ ExternalProject_Add(external_usd
|
|||
# usd_hydra.diff also included the blender changes and usd_pull_1965 and has been edited to remove those sections.
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/usd/src/external_usd < ${PATCH_DIR}/usd.diff &&
|
||||
${PATCH_CMD} -p 1 -d ${BUILD_DIR}/usd/src/external_usd < ${PATCH_DIR}/usd_pull_1965.diff &&
|
||||
${PATCH_CMD} -p 1 -d ${BUILD_DIR}/usd/src/external_usd < ${PATCH_DIR}/usd_hydra.diff
|
||||
${PATCH_CMD} -p 1 -d ${BUILD_DIR}/usd/src/external_usd < ${PATCH_DIR}/usd_hydra.diff &&
|
||||
${PATCH_CMD} -p 1 -d ${BUILD_DIR}/usd/src/external_usd < ${PATCH_DIR}/usd_core_profile.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/usd -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${USD_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/usd
|
||||
)
|
||||
|
|
|
@ -14,14 +14,14 @@ if [ `id -u` -ne 0 ]; then
|
|||
fi
|
||||
|
||||
# Required by: config manager command below to enable powertools.
|
||||
dnf install 'dnf-command(config-manager)'
|
||||
dnf -y install 'dnf-command(config-manager)'
|
||||
|
||||
# Packages `ninja-build` and `meson` are not available unless CBR or PowerTools repositories are enabled.
|
||||
# See: https://wiki.rockylinux.org/rocky/repo/#notes-on-unlisted-repositories
|
||||
dnf config-manager --set-enabled powertools
|
||||
|
||||
# Required by: epel-release has the patchelf and rubygem-asciidoctor packages
|
||||
dnf install epel-release
|
||||
dnf -y install epel-release
|
||||
|
||||
# `yum-config-manager` does not come in the default minimal install,
|
||||
# so make sure it is installed and available.
|
||||
|
|
|
@ -0,0 +1,415 @@
|
|||
diff --git a/pxr/imaging/hdSt/indirectDrawBatch.cpp b/pxr/imaging/hdSt/indirectDrawBatch.cpp
|
||||
index ec9b224..bf59cdf 100644
|
||||
--- a/pxr/imaging/hdSt/indirectDrawBatch.cpp
|
||||
+++ b/pxr/imaging/hdSt/indirectDrawBatch.cpp
|
||||
@@ -109,11 +109,17 @@ HdSt_IndirectDrawBatch::HdSt_IndirectDrawBatch(
|
||||
, _allowGpuFrustumCulling(allowGpuFrustumCulling)
|
||||
, _instanceCountOffset(0)
|
||||
, _cullInstanceCountOffset(0)
|
||||
+ , _vao(0)
|
||||
{
|
||||
_Init(drawItemInstance);
|
||||
}
|
||||
|
||||
-HdSt_IndirectDrawBatch::~HdSt_IndirectDrawBatch() = default;
|
||||
+HdSt_IndirectDrawBatch::~HdSt_IndirectDrawBatch()
|
||||
+{
|
||||
+ if (_vao) {
|
||||
+ glDeleteVertexArrays(1, &_vao);
|
||||
+ }
|
||||
+}
|
||||
|
||||
/*virtual*/
|
||||
void
|
||||
@@ -1146,6 +1152,14 @@ HdSt_IndirectDrawBatch::_ExecuteDraw(
|
||||
state.instancePrimvarBars);
|
||||
}
|
||||
|
||||
+ // OpenGL core profile requries a VAO for binding buffers.
|
||||
+ if (capabilities->GetCoreProfile()) {
|
||||
+ if (!_vao) {
|
||||
+ glCreateVertexArrays(1, &_vao);
|
||||
+ }
|
||||
+ glBindVertexArray(_vao);
|
||||
+ }
|
||||
+
|
||||
state.BindResourcesForDrawing(renderPassState, *capabilities);
|
||||
|
||||
HdSt_GeometricShaderSharedPtr geometricShader = state.geometricShader;
|
||||
@@ -1374,6 +1388,15 @@ HdSt_IndirectDrawBatch::_ExecuteFrustumCull(
|
||||
cullingProgram.GetGeometricShader());
|
||||
|
||||
Hgi * hgi = resourceRegistry->GetHgi();
|
||||
+ HgiCapabilities const *capabilities = hgi->GetCapabilities();
|
||||
+
|
||||
+ // OpenGL core profile requries a VAO for binding buffers.
|
||||
+ if (capabilities->GetCoreProfile()) {
|
||||
+ if (!_vao) {
|
||||
+ glCreateVertexArrays(1, &_vao);
|
||||
+ }
|
||||
+ glBindVertexArray(_vao);
|
||||
+ }
|
||||
|
||||
HgiGraphicsPipelineSharedPtr const & pso =
|
||||
_GetCullPipeline(resourceRegistry,
|
||||
diff --git a/pxr/imaging/hdSt/indirectDrawBatch.h b/pxr/imaging/hdSt/indirectDrawBatch.h
|
||||
index 44971f5..4292aa3 100644
|
||||
--- a/pxr/imaging/hdSt/indirectDrawBatch.h
|
||||
+++ b/pxr/imaging/hdSt/indirectDrawBatch.h
|
||||
@@ -195,6 +195,8 @@ private:
|
||||
|
||||
int _instanceCountOffset;
|
||||
int _cullInstanceCountOffset;
|
||||
+
|
||||
+ uint32_t _vao;
|
||||
};
|
||||
|
||||
|
||||
diff --git a/pxr/imaging/hdSt/renderPassState.cpp b/pxr/imaging/hdSt/renderPassState.cpp
|
||||
index da0e4f3..8f87fc1 100644
|
||||
--- a/pxr/imaging/hdSt/renderPassState.cpp
|
||||
+++ b/pxr/imaging/hdSt/renderPassState.cpp
|
||||
@@ -769,7 +769,9 @@ HdStRenderPassState::Bind(HgiCapabilities const &hgiCapabilities)
|
||||
// If not using GL_MULTISAMPLE, use GL_POINT_SMOOTH to render points as
|
||||
// circles instead of square.
|
||||
// XXX Switch points rendering to emit quad with FS that draws circle.
|
||||
- glEnable(GL_POINT_SMOOTH);
|
||||
+ if (!hgiCapabilities.GetCoreProfile()) {
|
||||
+ glEnable(GL_POINT_SMOOTH);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,7 +815,9 @@ HdStRenderPassState::Unbind(HgiCapabilities const &hgiCapabilities)
|
||||
}
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
- glDisable(GL_POINT_SMOOTH);
|
||||
+ if (!hgiCapabilities.GetCoreProfile()) {
|
||||
+ glDisable(GL_POINT_SMOOTH);
|
||||
+ }
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/pxr/imaging/hgi/capabilities.h b/pxr/imaging/hgi/capabilities.h
|
||||
index ae2ecb4..c86afcb 100644
|
||||
--- a/pxr/imaging/hgi/capabilities.h
|
||||
+++ b/pxr/imaging/hgi/capabilities.h
|
||||
@@ -52,6 +52,11 @@ public:
|
||||
HGI_API
|
||||
virtual int GetShaderVersion() const = 0;
|
||||
|
||||
+ HGI_API
|
||||
+ virtual bool GetCoreProfile() const {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
HGI_API
|
||||
size_t GetMaxUniformBlockSize() const {
|
||||
return _maxUniformBlockSize;
|
||||
diff --git a/pxr/imaging/hgiGL/blitCmds.cpp b/pxr/imaging/hgiGL/blitCmds.cpp
|
||||
index ce62f41..20888a1 100644
|
||||
--- a/pxr/imaging/hgiGL/blitCmds.cpp
|
||||
+++ b/pxr/imaging/hgiGL/blitCmds.cpp
|
||||
@@ -136,7 +136,7 @@ HgiGLBlitCmds::_Submit(Hgi* hgi, HgiSubmitWaitType wait)
|
||||
// Capture OpenGL state before executing the 'ops' and restore it when this
|
||||
// function ends. We do this defensively because parts of our pipeline may
|
||||
// not set and restore all relevant gl state.
|
||||
- HgiGL_ScopedStateHolder openglStateGuard;
|
||||
+ HgiGL_ScopedStateHolder openglStateGuard(*hgi->GetCapabilities());
|
||||
|
||||
HgiGL* hgiGL = static_cast<HgiGL*>(hgi);
|
||||
HgiGLDevice* device = hgiGL->GetPrimaryDevice();
|
||||
diff --git a/pxr/imaging/hgiGL/capabilities.cpp b/pxr/imaging/hgiGL/capabilities.cpp
|
||||
index 8711a62..e11324b 100644
|
||||
--- a/pxr/imaging/hgiGL/capabilities.cpp
|
||||
+++ b/pxr/imaging/hgiGL/capabilities.cpp
|
||||
@@ -57,6 +57,7 @@ static const int _DefaultMaxClipDistances = 8;
|
||||
HgiGLCapabilities::HgiGLCapabilities()
|
||||
: _glVersion(0)
|
||||
, _glslVersion(_DefaultGLSLVersion)
|
||||
+ , _coreProfile(false)
|
||||
{
|
||||
_LoadCapabilities();
|
||||
}
|
||||
@@ -131,6 +132,11 @@ HgiGLCapabilities::_LoadCapabilities()
|
||||
&uniformBufferOffsetAlignment);
|
||||
_uniformBufferOffsetAlignment = uniformBufferOffsetAlignment;
|
||||
}
|
||||
+ if (_glVersion >= 320) {
|
||||
+ GLint profileMask = 0;
|
||||
+ glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask);
|
||||
+ _coreProfile = (profileMask & GL_CONTEXT_CORE_PROFILE_BIT);
|
||||
+ }
|
||||
if (_glVersion >= 430) {
|
||||
GLint maxShaderStorageBlockSize = 0;
|
||||
glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE,
|
||||
@@ -259,4 +265,9 @@ HgiGLCapabilities::GetShaderVersion() const {
|
||||
return _glslVersion;
|
||||
}
|
||||
|
||||
+bool
|
||||
+HgiGLCapabilities::GetCoreProfile() const {
|
||||
+ return _coreProfile;
|
||||
+}
|
||||
+
|
||||
PXR_NAMESPACE_CLOSE_SCOPE
|
||||
diff --git a/pxr/imaging/hgiGL/capabilities.h b/pxr/imaging/hgiGL/capabilities.h
|
||||
index 3c8f026..2f25b44 100644
|
||||
--- a/pxr/imaging/hgiGL/capabilities.h
|
||||
+++ b/pxr/imaging/hgiGL/capabilities.h
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
HGIGL_API
|
||||
int GetShaderVersion() const override;
|
||||
|
||||
+ HGIGL_API
|
||||
+ bool GetCoreProfile() const override;
|
||||
+
|
||||
private:
|
||||
void _LoadCapabilities();
|
||||
|
||||
@@ -60,6 +63,9 @@ private:
|
||||
|
||||
// GLSL version
|
||||
int _glslVersion; // 400, 410, ...
|
||||
+
|
||||
+ // Core Profile
|
||||
+ bool _coreProfile;
|
||||
};
|
||||
|
||||
PXR_NAMESPACE_CLOSE_SCOPE
|
||||
diff --git a/pxr/imaging/hgiGL/graphicsCmds.cpp b/pxr/imaging/hgiGL/graphicsCmds.cpp
|
||||
index 5e17416..e59ae35 100644
|
||||
--- a/pxr/imaging/hgiGL/graphicsCmds.cpp
|
||||
+++ b/pxr/imaging/hgiGL/graphicsCmds.cpp
|
||||
@@ -249,7 +249,7 @@ HgiGLGraphicsCmds::_Submit(Hgi* hgi, HgiSubmitWaitType wait)
|
||||
// Capture OpenGL state before executing the 'ops' and restore it when this
|
||||
// function ends. We do this defensively because parts of our pipeline may
|
||||
// not set and restore all relevant gl state.
|
||||
- HgiGL_ScopedStateHolder openglStateGuard;
|
||||
+ HgiGL_ScopedStateHolder openglStateGuard(*hgi->GetCapabilities());
|
||||
|
||||
// Resolve multisample textures
|
||||
HgiGL* hgiGL = static_cast<HgiGL*>(hgi);
|
||||
diff --git a/pxr/imaging/hgiGL/graphicsPipeline.cpp b/pxr/imaging/hgiGL/graphicsPipeline.cpp
|
||||
index 6983dd1..a1c7af7 100644
|
||||
--- a/pxr/imaging/hgiGL/graphicsPipeline.cpp
|
||||
+++ b/pxr/imaging/hgiGL/graphicsPipeline.cpp
|
||||
@@ -42,7 +42,12 @@ HgiGLGraphicsPipeline::HgiGLGraphicsPipeline(
|
||||
{
|
||||
}
|
||||
|
||||
-HgiGLGraphicsPipeline::~HgiGLGraphicsPipeline() = default;
|
||||
+HgiGLGraphicsPipeline::~HgiGLGraphicsPipeline()
|
||||
+{
|
||||
+ if (_vao) {
|
||||
+ glDeleteVertexArrays(1, &_vao);
|
||||
+ }
|
||||
+}
|
||||
|
||||
void
|
||||
HgiGLGraphicsPipeline::BindPipeline()
|
||||
@@ -50,6 +55,7 @@ HgiGLGraphicsPipeline::BindPipeline()
|
||||
if (_vao) {
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
+ _vao = 0;
|
||||
}
|
||||
|
||||
if (!_descriptor.vertexBuffers.empty()) {
|
||||
@@ -108,6 +114,8 @@ HgiGLGraphicsPipeline::BindPipeline()
|
||||
glBindVertexArray(_vao);
|
||||
}
|
||||
|
||||
+ const bool coreProfile = _hgi->GetCapabilities()->GetCoreProfile();
|
||||
+
|
||||
//
|
||||
// Depth Stencil State
|
||||
//
|
||||
@@ -172,7 +180,9 @@ HgiGLGraphicsPipeline::BindPipeline()
|
||||
// If not using GL_MULTISAMPLE, use GL_POINT_SMOOTH to render points as
|
||||
// circles instead of square.
|
||||
// XXX Switch points rendering to emit quad with FS that draws circle.
|
||||
- glEnable(GL_POINT_SMOOTH);
|
||||
+ if (!coreProfile) {
|
||||
+ glEnable(GL_POINT_SMOOTH);
|
||||
+ }
|
||||
}
|
||||
if (_descriptor.multiSampleState.alphaToCoverageEnable) {
|
||||
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||
@@ -207,7 +217,7 @@ HgiGLGraphicsPipeline::BindPipeline()
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
- if (_descriptor.rasterizationState.lineWidth != 1.0f) {
|
||||
+ if (!coreProfile && _descriptor.rasterizationState.lineWidth != 1.0f) {
|
||||
glLineWidth(_descriptor.rasterizationState.lineWidth);
|
||||
}
|
||||
|
||||
diff --git a/pxr/imaging/hgiGL/scopedStateHolder.cpp b/pxr/imaging/hgiGL/scopedStateHolder.cpp
|
||||
index 89cd0ac..5c65753 100644
|
||||
--- a/pxr/imaging/hgiGL/scopedStateHolder.cpp
|
||||
+++ b/pxr/imaging/hgiGL/scopedStateHolder.cpp
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "pxr/imaging/hgiGL/scopedStateHolder.h"
|
||||
#include "pxr/imaging/hgiGL/conversions.h"
|
||||
#include "pxr/imaging/hgiGL/diagnostic.h"
|
||||
+#include "pxr/imaging/hgiGL/hgi.h"
|
||||
|
||||
#include "pxr/base/trace/trace.h"
|
||||
#include "pxr/base/tf/diagnostic.h"
|
||||
@@ -33,8 +34,10 @@
|
||||
|
||||
PXR_NAMESPACE_OPEN_SCOPE
|
||||
|
||||
-HgiGL_ScopedStateHolder::HgiGL_ScopedStateHolder()
|
||||
- : _restoreRenderBuffer(0)
|
||||
+HgiGL_ScopedStateHolder::HgiGL_ScopedStateHolder(
|
||||
+ HgiCapabilities const& capabilities)
|
||||
+ : _coreProfile(capabilities.GetCoreProfile())
|
||||
+ , _restoreRenderBuffer(0)
|
||||
, _restoreVao(0)
|
||||
, _restoreDepthTest(false)
|
||||
, _restoreDepthWriteMask(false)
|
||||
@@ -115,7 +118,9 @@ HgiGL_ScopedStateHolder::HgiGL_ScopedStateHolder()
|
||||
glGetBooleanv(
|
||||
GL_SAMPLE_ALPHA_TO_ONE,
|
||||
(GLboolean*)&_restoreSampleAlphaToOne);
|
||||
- glGetFloatv(GL_LINE_WIDTH, &_lineWidth);
|
||||
+ if (!_coreProfile) {
|
||||
+ glGetFloatv(GL_LINE_WIDTH, &_lineWidth);
|
||||
+ }
|
||||
glGetBooleanv(GL_CULL_FACE, (GLboolean*)&_cullFace);
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &_cullMode);
|
||||
glGetIntegerv(GL_FRONT_FACE, &_frontFace);
|
||||
@@ -139,7 +144,9 @@ HgiGL_ScopedStateHolder::HgiGL_ScopedStateHolder()
|
||||
}
|
||||
|
||||
glGetBooleanv(GL_MULTISAMPLE, (GLboolean*)&_restoreMultiSample);
|
||||
- glGetBooleanv(GL_POINT_SMOOTH, (GLboolean*)&_restorePointSmooth);
|
||||
+ if (!_coreProfile) {
|
||||
+ glGetBooleanv(GL_POINT_SMOOTH, (GLboolean*)&_restorePointSmooth);
|
||||
+ }
|
||||
|
||||
HGIGL_POST_PENDING_GL_ERRORS();
|
||||
#if defined(GL_KHR_debug)
|
||||
@@ -235,7 +242,9 @@ HgiGL_ScopedStateHolder::~HgiGL_ScopedStateHolder()
|
||||
_restoreViewport[2], _restoreViewport[3]);
|
||||
glBindVertexArray(_restoreVao);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, _restoreRenderBuffer);
|
||||
- glLineWidth(_lineWidth);
|
||||
+ if (!_coreProfile) {
|
||||
+ glLineWidth(_lineWidth);
|
||||
+ }
|
||||
if (_cullFace) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
} else {
|
||||
@@ -285,10 +294,12 @@ HgiGL_ScopedStateHolder::~HgiGL_ScopedStateHolder()
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
- if (_restorePointSmooth) {
|
||||
- glEnable(GL_POINT_SMOOTH);
|
||||
- } else {
|
||||
- glDisable(GL_POINT_SMOOTH);
|
||||
+ if (!_coreProfile) {
|
||||
+ if (_restorePointSmooth) {
|
||||
+ glEnable(GL_POINT_SMOOTH);
|
||||
+ } else {
|
||||
+ glDisable(GL_POINT_SMOOTH);
|
||||
+ }
|
||||
}
|
||||
|
||||
static const GLuint samplers[8] = {0};
|
||||
diff --git a/pxr/imaging/hgiGL/scopedStateHolder.h b/pxr/imaging/hgiGL/scopedStateHolder.h
|
||||
index d006480..be6698e 100644
|
||||
--- a/pxr/imaging/hgiGL/scopedStateHolder.h
|
||||
+++ b/pxr/imaging/hgiGL/scopedStateHolder.h
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
PXR_NAMESPACE_OPEN_SCOPE
|
||||
|
||||
+class HgiCapabilities;
|
||||
|
||||
/// \class HgiGLScopedStateHolder
|
||||
///
|
||||
@@ -50,7 +51,7 @@ class HgiGL_ScopedStateHolder final
|
||||
{
|
||||
public:
|
||||
HGIGL_API
|
||||
- HgiGL_ScopedStateHolder();
|
||||
+ HgiGL_ScopedStateHolder(HgiCapabilities const& capabilities);
|
||||
|
||||
HGIGL_API
|
||||
~HgiGL_ScopedStateHolder();
|
||||
@@ -59,6 +60,8 @@ private:
|
||||
HgiGL_ScopedStateHolder& operator=(const HgiGL_ScopedStateHolder&) = delete;
|
||||
HgiGL_ScopedStateHolder(const HgiGL_ScopedStateHolder&) = delete;
|
||||
|
||||
+ bool _coreProfile;
|
||||
+
|
||||
int32_t _restoreRenderBuffer;
|
||||
int32_t _restoreVao;
|
||||
|
||||
diff --git a/pxr/imaging/hgiInterop/opengl.cpp b/pxr/imaging/hgiInterop/opengl.cpp
|
||||
index 683c058..e921c2a 100644
|
||||
--- a/pxr/imaging/hgiInterop/opengl.cpp
|
||||
+++ b/pxr/imaging/hgiInterop/opengl.cpp
|
||||
@@ -110,6 +110,7 @@ HgiInteropOpenGL::HgiInteropOpenGL()
|
||||
, _fsDepth(0)
|
||||
, _prgNoDepth(0)
|
||||
, _prgDepth(0)
|
||||
+ , _vao(0)
|
||||
, _vertexBuffer(0)
|
||||
{
|
||||
_vs = _CompileShader(_vertexFullscreen, GL_VERTEX_SHADER);
|
||||
@@ -117,6 +118,7 @@ HgiInteropOpenGL::HgiInteropOpenGL()
|
||||
_fsDepth = _CompileShader(_fragmentDepthFullscreen, GL_FRAGMENT_SHADER);
|
||||
_prgNoDepth = _LinkProgram(_vs, _fsNoDepth);
|
||||
_prgDepth = _LinkProgram(_vs, _fsDepth);
|
||||
+ glCreateVertexArrays(1, &_vao);
|
||||
_vertexBuffer = _CreateVertexBuffer();
|
||||
TF_VERIFY(glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
@@ -129,6 +131,7 @@ HgiInteropOpenGL::~HgiInteropOpenGL()
|
||||
glDeleteProgram(_prgNoDepth);
|
||||
glDeleteProgram(_prgDepth);
|
||||
glDeleteBuffers(1, &_vertexBuffer);
|
||||
+ glDeleteVertexArrays(1, &_vao);
|
||||
TF_VERIFY(glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
@@ -202,10 +205,13 @@ HgiInteropOpenGL::CompositeToInterop(
|
||||
}
|
||||
|
||||
// Get the current array buffer binding state
|
||||
+ GLint restoreVao = 0;
|
||||
+ glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &restoreVao);
|
||||
GLint restoreArrayBuffer = 0;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &restoreArrayBuffer);
|
||||
|
||||
// Vertex attributes
|
||||
+ glBindVertexArray(_vao);
|
||||
const GLint locPosition = glGetAttribLocation(prg, "position");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
|
||||
glVertexAttribPointer(locPosition, 4, GL_FLOAT, GL_FALSE,
|
||||
@@ -271,6 +277,7 @@ HgiInteropOpenGL::CompositeToInterop(
|
||||
glDisableVertexAttribArray(locPosition);
|
||||
glDisableVertexAttribArray(locUv);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, restoreArrayBuffer);
|
||||
+ glBindVertexArray(restoreVao);
|
||||
|
||||
if (!blendEnabled) {
|
||||
glDisable(GL_BLEND);
|
||||
diff --git a/pxr/imaging/hgiInterop/opengl.h b/pxr/imaging/hgiInterop/opengl.h
|
||||
index 18840a9..27434ac 100644
|
||||
--- a/pxr/imaging/hgiInterop/opengl.h
|
||||
+++ b/pxr/imaging/hgiInterop/opengl.h
|
||||
@@ -62,6 +62,7 @@ private:
|
||||
uint32_t _fsDepth;
|
||||
uint32_t _prgNoDepth;
|
||||
uint32_t _prgDepth;
|
||||
+ uint32_t _vao;
|
||||
uint32_t _vertexBuffer;
|
||||
};
|
||||
|
|
@ -227,7 +227,7 @@ void ColorSpaceManager::is_builtin_colorspace(ustring colorspace,
|
|||
if (!compare_floats(v, out_v, 1e-6f, 64)) {
|
||||
is_scene_linear = false;
|
||||
}
|
||||
if (!compare_floats(color_srgb_to_linear(v), out_v, 1e-5f, 64)) {
|
||||
if (!compare_floats(color_srgb_to_linear(v), out_v, 1e-4f, 64)) {
|
||||
is_srgb = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,7 +503,7 @@ void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
|
|||
if (!compare_floats(v, out_v, 1e-6f, 64)) {
|
||||
is_scene_linear = false;
|
||||
}
|
||||
if (!compare_floats(srgb_to_linearrgb(v), out_v, 1e-5f, 64)) {
|
||||
if (!compare_floats(srgb_to_linearrgb(v), out_v, 1e-4f, 64)) {
|
||||
is_srgb = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,8 +114,7 @@ colorspaces:
|
|||
description: |
|
||||
sRGB display space
|
||||
isdata: false
|
||||
to_reference: !<FileTransform> {src: srgb.spi1d, interpolation: linear}
|
||||
from_reference: !<FileTransform> {src: srgb_inv.spi1d, interpolation: linear}
|
||||
from_reference: !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}
|
||||
|
||||
- !<ColorSpace>
|
||||
name: Non-Color
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -21,16 +21,22 @@
|
|||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
|
||||
std::string image_cache_file_path()
|
||||
{
|
||||
char dir_path[FILE_MAX];
|
||||
BLI_path_join(dir_path, sizeof(dir_path), BKE_tempdir_session(), "hydra", "image_cache");
|
||||
return dir_path;
|
||||
}
|
||||
|
||||
static std::string get_cache_file(const std::string &file_name, bool mkdir = true)
|
||||
{
|
||||
std::string dir_path = image_cache_file_path();
|
||||
if (mkdir) {
|
||||
BLI_dir_create_recursive(dir_path);
|
||||
BLI_dir_create_recursive(dir_path.c_str());
|
||||
}
|
||||
|
||||
char file_path[FILE_MAX];
|
||||
BLI_path_join(file_path, sizeof(file_path), dir_path, file_name.c_str());
|
||||
BLI_path_join(file_path, sizeof(file_path), dir_path.c_str(), file_name.c_str());
|
||||
return file_path;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ struct ImageUser;
|
|||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
std::string image_cache_file_path();
|
||||
|
||||
std::string cache_or_get_image_file(Main *bmain, Scene *Scene, Image *image, ImageUser *iuser);
|
||||
std::string cache_image_color(float color[4]);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <pxr/imaging/hd/material.h>
|
||||
#include <pxr/imaging/hd/renderDelegate.h>
|
||||
#include <pxr/imaging/hd/tokens.h>
|
||||
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
@ -20,16 +21,22 @@
|
|||
#include "RNA_prototypes.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "bpy_rna.h"
|
||||
|
||||
#include "hydra_scene_delegate.h"
|
||||
#include "image.h"
|
||||
|
||||
#include "intern/usd_exporter_context.h"
|
||||
#include "intern/usd_writer_material.h"
|
||||
|
||||
namespace blender::io::hydra {
|
||||
|
||||
MaterialData::MaterialData(HydraSceneDelegate *scene_delegate,
|
||||
const Material *material,
|
||||
pxr::SdfPath const &prim_id)
|
||||
: IdData(scene_delegate, (const ID *)material, prim_id)
|
||||
: IdData(scene_delegate, &material->id, prim_id)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -37,6 +44,51 @@ void MaterialData::init()
|
|||
{
|
||||
ID_LOGN(1, "");
|
||||
double_sided = (((Material *)id)->blend_flag & MA_BL_CULL_BACKFACE) == 0;
|
||||
material_network_map_ = pxr::VtValue();
|
||||
|
||||
/* Create temporary in memory stage. */
|
||||
pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory();
|
||||
pxr::UsdTimeCode time = pxr::UsdTimeCode::Default();
|
||||
pxr::SdfPath material_library_path("/_materials");
|
||||
pxr::SdfPath material_path = material_library_path.AppendChild(
|
||||
pxr::TfToken(prim_id.GetElementString()));
|
||||
|
||||
/* Create USD export content to reuse USD file export code. */
|
||||
USDExportParams export_params;
|
||||
export_params.relative_paths = false;
|
||||
export_params.export_textures = false; /* Don't copy all textures, is slow. */
|
||||
export_params.evaluation_mode = DEG_get_mode(scene_delegate_->depsgraph);
|
||||
|
||||
usd::USDExporterContext export_context{scene_delegate_->bmain,
|
||||
scene_delegate_->depsgraph,
|
||||
stage,
|
||||
material_library_path,
|
||||
time,
|
||||
export_params,
|
||||
image_cache_file_path()};
|
||||
|
||||
/* Create USD material. */
|
||||
pxr::UsdShadeMaterial usd_material = usd::create_usd_material(
|
||||
export_context, material_path, (Material *)id, "st");
|
||||
|
||||
/* Convert USD material to Hydra material network map, adapted for render delegate. */
|
||||
const pxr::HdRenderDelegate *render_delegate =
|
||||
scene_delegate_->GetRenderIndex().GetRenderDelegate();
|
||||
const pxr::TfTokenVector contextVector = render_delegate->GetMaterialRenderContexts();
|
||||
pxr::TfTokenVector shaderSourceTypes = render_delegate->GetShaderSourceTypes();
|
||||
|
||||
pxr::HdMaterialNetworkMap network_map;
|
||||
|
||||
if (pxr::UsdShadeShader surface = usd_material.ComputeSurfaceSource(contextVector)) {
|
||||
pxr::UsdImagingBuildHdMaterialNetworkFromTerminal(surface.GetPrim(),
|
||||
pxr::HdMaterialTerminalTokens->surface,
|
||||
shaderSourceTypes,
|
||||
contextVector,
|
||||
&network_map,
|
||||
time);
|
||||
}
|
||||
|
||||
material_network_map_ = pxr::VtValue(network_map);
|
||||
}
|
||||
|
||||
void MaterialData::insert()
|
||||
|
@ -77,7 +129,7 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const & /* key */) const
|
|||
|
||||
pxr::VtValue MaterialData::get_material_resource() const
|
||||
{
|
||||
return pxr::VtValue();
|
||||
return material_network_map_;
|
||||
}
|
||||
|
||||
pxr::HdCullStyle MaterialData::cull_style() const
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
namespace blender::io::hydra {
|
||||
|
||||
class MaterialData : public IdData {
|
||||
public:
|
||||
bool double_sided = true;
|
||||
|
||||
private:
|
||||
pxr::VtValue material_network_map_;
|
||||
|
||||
public:
|
||||
MaterialData(HydraSceneDelegate *scene_delegate,
|
||||
const Material *material,
|
||||
|
@ -30,8 +36,6 @@ class MaterialData : public IdData {
|
|||
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
||||
pxr::VtValue get_material_resource() const;
|
||||
pxr::HdCullStyle cull_style() const;
|
||||
|
||||
bool double_sided = true;
|
||||
};
|
||||
|
||||
using MaterialDataMap = Map<pxr::SdfPath, std::unique_ptr<MaterialData>>;
|
||||
|
|
|
@ -44,19 +44,11 @@ USDSceneDelegate::~USDSceneDelegate()
|
|||
|
||||
void USDSceneDelegate::populate(Depsgraph *depsgraph)
|
||||
{
|
||||
USDExportParams params = {};
|
||||
params.export_hair = true;
|
||||
params.export_uvmaps = true;
|
||||
params.export_normals = true;
|
||||
params.export_materials = true;
|
||||
params.selected_objects_only = false;
|
||||
params.visible_objects_only = true;
|
||||
USDExportParams params;
|
||||
params.use_instancing = true;
|
||||
params.relative_paths = false; /* Unnecessary. */
|
||||
params.export_textures = false; /* Don't copy all textures, is slow. */
|
||||
params.evaluation_mode = DEG_get_mode(depsgraph);
|
||||
params.generate_preview_surface = true;
|
||||
params.export_textures = true;
|
||||
params.overwrite_textures = true;
|
||||
params.relative_paths = true;
|
||||
|
||||
/* Create clean directory for export. */
|
||||
BLI_delete(temp_dir_.c_str(), true, true);
|
||||
|
|
|
@ -20,8 +20,9 @@ struct USDExporterContext {
|
|||
Depsgraph *depsgraph;
|
||||
const pxr::UsdStageRefPtr stage;
|
||||
const pxr::SdfPath usd_path;
|
||||
const USDHierarchyIterator *hierarchy_iterator;
|
||||
pxr::UsdTimeCode time_code;
|
||||
const USDExportParams &export_params;
|
||||
std::string export_file_path;
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -64,20 +64,6 @@ void USDHierarchyIterator::set_export_frame(float frame_nr)
|
|||
export_time_ = pxr::UsdTimeCode(frame_nr);
|
||||
}
|
||||
|
||||
std::string USDHierarchyIterator::get_export_file_path() const
|
||||
{
|
||||
/* Returns the same path that was passed to `stage_` object during it's creation (via
|
||||
* `pxr::UsdStage::CreateNew` function). */
|
||||
const pxr::SdfLayerHandle root_layer = stage_->GetRootLayer();
|
||||
const std::string usd_export_file_path = root_layer->GetRealPath();
|
||||
return usd_export_file_path;
|
||||
}
|
||||
|
||||
const pxr::UsdTimeCode &USDHierarchyIterator::get_export_time_code() const
|
||||
{
|
||||
return export_time_;
|
||||
}
|
||||
|
||||
USDExporterContext USDHierarchyIterator::create_usd_export_context(const HierarchyContext *context)
|
||||
{
|
||||
pxr::SdfPath path;
|
||||
|
@ -88,7 +74,13 @@ USDExporterContext USDHierarchyIterator::create_usd_export_context(const Hierarc
|
|||
path = pxr::SdfPath(context->export_path);
|
||||
}
|
||||
|
||||
return USDExporterContext{bmain_, depsgraph_, stage_, path, this, params_};
|
||||
/* Returns the same path that was passed to `stage_` object during it's creation (via
|
||||
* `pxr::UsdStage::CreateNew` function). */
|
||||
const pxr::SdfLayerHandle root_layer = stage_->GetRootLayer();
|
||||
const std::string export_file_path = root_layer->GetRealPath();
|
||||
|
||||
return USDExporterContext{
|
||||
bmain_, depsgraph_, stage_, path, export_time_, params_, export_file_path};
|
||||
}
|
||||
|
||||
AbstractHierarchyWriter *USDHierarchyIterator::create_transform_writer(
|
||||
|
|
|
@ -35,8 +35,6 @@ class USDHierarchyIterator : public AbstractHierarchyIterator {
|
|||
const USDExportParams ¶ms);
|
||||
|
||||
void set_export_frame(float frame_nr);
|
||||
std::string get_export_file_path() const;
|
||||
const pxr::UsdTimeCode &get_export_time_code() const;
|
||||
|
||||
virtual std::string make_valid_name(const std::string &name) const override;
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#include "usd_writer_abstract.h"
|
||||
#include "usd_hierarchy_iterator.h"
|
||||
#include "usd_hook.h"
|
||||
#include "usd_writer_material.h"
|
||||
|
||||
#include <pxr/base/tf/stringUtils.h>
|
||||
|
@ -54,13 +53,13 @@ bool USDAbstractWriter::is_supported(const HierarchyContext * /*context*/) const
|
|||
|
||||
std::string USDAbstractWriter::get_export_file_path() const
|
||||
{
|
||||
return usd_export_context_.hierarchy_iterator->get_export_file_path();
|
||||
return usd_export_context_.export_file_path;
|
||||
}
|
||||
|
||||
pxr::UsdTimeCode USDAbstractWriter::get_export_time_code() const
|
||||
{
|
||||
if (is_animated_) {
|
||||
return usd_export_context_.hierarchy_iterator->get_export_time_code();
|
||||
return usd_export_context_.time_code;
|
||||
}
|
||||
/* By using the default timecode USD won't even write a single `timeSample` for non-animated
|
||||
* data. Instead, it writes it as non-timesampled. */
|
||||
|
@ -108,26 +107,15 @@ pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(const HierarchyCont
|
|||
pxr::UsdStageRefPtr stage = usd_export_context_.stage;
|
||||
|
||||
/* Construct the material. */
|
||||
pxr::TfToken material_name(usd_export_context_.hierarchy_iterator->get_id_name(&material->id));
|
||||
pxr::TfToken material_name(pxr::TfMakeValidIdentifier(material->id.name + 2));
|
||||
pxr::SdfPath usd_path = get_material_library_path().AppendChild(material_name);
|
||||
pxr::UsdShadeMaterial usd_material = pxr::UsdShadeMaterial::Get(stage, usd_path);
|
||||
if (usd_material) {
|
||||
return usd_material;
|
||||
}
|
||||
usd_material = pxr::UsdShadeMaterial::Define(stage, usd_path);
|
||||
|
||||
if (material->use_nodes && this->usd_export_context_.export_params.generate_preview_surface) {
|
||||
std::string active_uv = get_mesh_active_uvlayer_name(context.object);
|
||||
create_usd_preview_surface_material(
|
||||
this->usd_export_context_, material, usd_material, active_uv);
|
||||
}
|
||||
else {
|
||||
create_usd_viewport_material(this->usd_export_context_, material, usd_material);
|
||||
}
|
||||
|
||||
call_material_export_hooks(stage, material, usd_material);
|
||||
|
||||
return usd_material;
|
||||
std::string active_uv = get_mesh_active_uvlayer_name(context.object);
|
||||
return create_usd_material(usd_export_context_, usd_path, material, active_uv);
|
||||
}
|
||||
|
||||
void USDAbstractWriter::write_visibility(const HierarchyContext &context,
|
||||
|
|
|
@ -108,14 +108,11 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context,
|
|||
pxr::UsdShadeMaterial &usd_material,
|
||||
pxr::UsdShadeShader &usd_tex_shader,
|
||||
const pxr::TfToken &default_uv);
|
||||
static void export_texture(bNode *node,
|
||||
const pxr::UsdStageRefPtr stage,
|
||||
const bool allow_overwrite = false);
|
||||
static void export_texture(const USDExporterContext &usd_export_context, bNode *node);
|
||||
static bNode *find_bsdf_node(Material *material);
|
||||
static void get_absolute_path(Image *ima, char *r_path);
|
||||
static std::string get_tex_image_asset_filepath(bNode *node,
|
||||
const pxr::UsdStageRefPtr stage,
|
||||
const USDExportParams &export_params);
|
||||
static std::string get_tex_image_asset_filepath(const USDExporterContext &usd_export_context,
|
||||
bNode *node);
|
||||
static InputSpecMap &preview_surface_input_map();
|
||||
static bNodeLink *traverse_channel(bNodeSocket *input, short target_type);
|
||||
|
||||
|
@ -123,10 +120,10 @@ template<typename T1, typename T2>
|
|||
void create_input(pxr::UsdShadeShader &shader, const InputSpec &spec, const void *value);
|
||||
|
||||
void set_normal_texture_range(pxr::UsdShadeShader &usd_shader, const InputSpec &input_spec);
|
||||
void create_usd_preview_surface_material(const USDExporterContext &usd_export_context,
|
||||
Material *material,
|
||||
pxr::UsdShadeMaterial &usd_material,
|
||||
const std::string &default_uv)
|
||||
static void create_usd_preview_surface_material(const USDExporterContext &usd_export_context,
|
||||
Material *material,
|
||||
pxr::UsdShadeMaterial &usd_material,
|
||||
const std::string &default_uv)
|
||||
{
|
||||
if (!material) {
|
||||
return;
|
||||
|
@ -189,9 +186,7 @@ void create_usd_preview_surface_material(const USDExporterContext &usd_export_co
|
|||
|
||||
/* Export the texture, if necessary. */
|
||||
if (usd_export_context.export_params.export_textures) {
|
||||
export_texture(input_node,
|
||||
usd_export_context.stage,
|
||||
usd_export_context.export_params.overwrite_textures);
|
||||
export_texture(usd_export_context, input_node);
|
||||
}
|
||||
|
||||
/* Look for a connected uv node. */
|
||||
|
@ -270,6 +265,7 @@ void set_normal_texture_range(pxr::UsdShadeShader &usd_shader, const InputSpec &
|
|||
bias_attr.Set(pxr::GfVec4f(-1.0f, -1.0f, -1.0f, -1.0f));
|
||||
}
|
||||
|
||||
/* Create USD Shade Material network from Blender viewport display settings. */
|
||||
void create_usd_viewport_material(const USDExporterContext &usd_export_context,
|
||||
Material *material,
|
||||
pxr::UsdShadeMaterial &usd_material)
|
||||
|
@ -568,7 +564,15 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u
|
|||
return shader;
|
||||
}
|
||||
|
||||
/* Creates a USD Preview Surface shader based on the given cycles shading node. */
|
||||
/* Creates a USD Preview Surface shader based on the given cycles shading node.
|
||||
* Due to the limited nodes in the USD Preview Surface specification, only the following nodes
|
||||
* are supported:
|
||||
* - UVMap
|
||||
* - Texture Coordinate
|
||||
* - Image Texture
|
||||
* - Principled BSDF
|
||||
* More may be added in the future.
|
||||
*/
|
||||
static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &usd_export_context,
|
||||
pxr::UsdShadeMaterial &material,
|
||||
bNode *node)
|
||||
|
@ -581,8 +585,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u
|
|||
}
|
||||
|
||||
/* For texture image nodes we set the image path and color space. */
|
||||
std::string imagePath = get_tex_image_asset_filepath(
|
||||
node, usd_export_context.stage, usd_export_context.export_params);
|
||||
std::string imagePath = get_tex_image_asset_filepath(usd_export_context, node);
|
||||
if (!imagePath.empty()) {
|
||||
shader.CreateInput(usdtokens::file, pxr::SdfValueTypeNames->Asset)
|
||||
.Set(pxr::SdfAssetPath(imagePath));
|
||||
|
@ -611,9 +614,8 @@ static std::string get_tex_image_asset_filepath(Image *ima)
|
|||
* generated based on the image name for in-memory textures when exporting textures.
|
||||
* This function may return an empty string if the image does not have a filepath
|
||||
* assigned and no asset path could be determined. */
|
||||
static std::string get_tex_image_asset_filepath(bNode *node,
|
||||
const pxr::UsdStageRefPtr stage,
|
||||
const USDExportParams &export_params)
|
||||
static std::string get_tex_image_asset_filepath(const USDExporterContext &usd_export_context,
|
||||
bNode *node)
|
||||
{
|
||||
Image *ima = reinterpret_cast<Image *>(node->id);
|
||||
if (!ima) {
|
||||
|
@ -626,7 +628,7 @@ static std::string get_tex_image_asset_filepath(bNode *node,
|
|||
/* Get absolute path. */
|
||||
path = get_tex_image_asset_filepath(ima);
|
||||
}
|
||||
else if (export_params.export_textures) {
|
||||
else if (usd_export_context.export_params.export_textures) {
|
||||
/* Image has no filepath, but since we are exporting textures,
|
||||
* check if this is an in-memory texture for which we can
|
||||
* generate a file name. */
|
||||
|
@ -637,7 +639,7 @@ static std::string get_tex_image_asset_filepath(bNode *node,
|
|||
return path;
|
||||
}
|
||||
|
||||
if (export_params.export_textures) {
|
||||
if (usd_export_context.export_params.export_textures) {
|
||||
/* The texture is exported to a 'textures' directory next to the
|
||||
* USD root layer. */
|
||||
|
||||
|
@ -645,37 +647,35 @@ static std::string get_tex_image_asset_filepath(bNode *node,
|
|||
char file_path[FILE_MAX];
|
||||
BLI_path_split_file_part(path.c_str(), file_path, FILE_MAX);
|
||||
|
||||
if (export_params.relative_paths) {
|
||||
if (usd_export_context.export_params.relative_paths) {
|
||||
BLI_path_join(exp_path, FILE_MAX, ".", "textures", file_path);
|
||||
}
|
||||
else {
|
||||
/* Create absolute path in the textures directory. */
|
||||
pxr::SdfLayerHandle layer = stage->GetRootLayer();
|
||||
std::string stage_path = layer->GetRealPath();
|
||||
if (stage_path.empty()) {
|
||||
std::string export_path = usd_export_context.export_file_path;
|
||||
if (export_path.empty()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
char dir_path[FILE_MAX];
|
||||
BLI_path_split_dir_part(stage_path.c_str(), dir_path, FILE_MAX);
|
||||
BLI_path_split_dir_part(export_path.c_str(), dir_path, FILE_MAX);
|
||||
BLI_path_join(exp_path, FILE_MAX, dir_path, "textures", file_path);
|
||||
}
|
||||
BLI_string_replace_char(exp_path, '\\', '/');
|
||||
return exp_path;
|
||||
}
|
||||
|
||||
if (export_params.relative_paths) {
|
||||
if (usd_export_context.export_params.relative_paths) {
|
||||
/* Get the path relative to the USD. */
|
||||
pxr::SdfLayerHandle layer = stage->GetRootLayer();
|
||||
std::string stage_path = layer->GetRealPath();
|
||||
if (stage_path.empty()) {
|
||||
std::string export_path = usd_export_context.export_file_path;
|
||||
if (export_path.empty()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
char rel_path[FILE_MAX];
|
||||
STRNCPY(rel_path, path.c_str());
|
||||
|
||||
BLI_path_rel(rel_path, stage_path.c_str());
|
||||
BLI_path_rel(rel_path, export_path.c_str());
|
||||
if (!BLI_path_is_rel(rel_path)) {
|
||||
return path;
|
||||
}
|
||||
|
@ -770,12 +770,9 @@ static void copy_single_file(Image *ima, const std::string &dest_dir, const bool
|
|||
}
|
||||
}
|
||||
|
||||
/* Export the given texture node's image to a 'textures' directory
|
||||
* next to given stage's root layer USD.
|
||||
/* Export the given texture node's image to a 'textures' directory in the export path.
|
||||
* Based on ImagesExporter::export_UV_Image() */
|
||||
static void export_texture(bNode *node,
|
||||
const pxr::UsdStageRefPtr stage,
|
||||
const bool allow_overwrite)
|
||||
static void export_texture(const USDExporterContext &usd_export_context, bNode *node)
|
||||
{
|
||||
if (!ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT)) {
|
||||
return;
|
||||
|
@ -786,14 +783,13 @@ static void export_texture(bNode *node,
|
|||
return;
|
||||
}
|
||||
|
||||
pxr::SdfLayerHandle layer = stage->GetRootLayer();
|
||||
std::string stage_path = layer->GetRealPath();
|
||||
if (stage_path.empty()) {
|
||||
std::string export_path = usd_export_context.export_file_path;
|
||||
if (export_path.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char usd_dir_path[FILE_MAX];
|
||||
BLI_path_split_dir_part(stage_path.c_str(), usd_dir_path, FILE_MAX);
|
||||
BLI_path_split_dir_part(export_path.c_str(), usd_dir_path, FILE_MAX);
|
||||
|
||||
char tex_dir_path[FILE_MAX];
|
||||
BLI_path_join(tex_dir_path, FILE_MAX, usd_dir_path, "textures", SEP_STR);
|
||||
|
@ -803,6 +799,7 @@ static void export_texture(bNode *node,
|
|||
const bool is_dirty = BKE_image_is_dirty(ima);
|
||||
const bool is_generated = ima->source == IMA_SRC_GENERATED;
|
||||
const bool is_packed = BKE_image_has_packedfile(ima);
|
||||
const bool allow_overwrite = usd_export_context.export_params.overwrite_textures;
|
||||
|
||||
std::string dest_dir(tex_dir_path);
|
||||
|
||||
|
@ -829,4 +826,22 @@ const pxr::TfToken token_for_input(const char *input_name)
|
|||
return it->second.input_name;
|
||||
}
|
||||
|
||||
pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context,
|
||||
pxr::SdfPath usd_path,
|
||||
Material *material,
|
||||
const std::string &active_uv)
|
||||
{
|
||||
pxr::UsdShadeMaterial usd_material = pxr::UsdShadeMaterial::Define(usd_export_context.stage,
|
||||
usd_path);
|
||||
|
||||
if (material->use_nodes && usd_export_context.export_params.generate_preview_surface) {
|
||||
create_usd_preview_surface_material(usd_export_context, material, usd_material, active_uv);
|
||||
}
|
||||
else {
|
||||
create_usd_viewport_material(usd_export_context, material, usd_material);
|
||||
}
|
||||
|
||||
return usd_material;
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -16,31 +16,18 @@ namespace blender::io::usd {
|
|||
|
||||
struct USDExporterContext;
|
||||
|
||||
/* Returns a USDPreviewSurface token name for a given Blender shader Socket name,
|
||||
* or an empty TfToken if the input name is not found in the map. */
|
||||
const pxr::TfToken token_for_input(const char *input_name);
|
||||
|
||||
/**
|
||||
* Entry point to create an approximate USD Preview Surface network from a Cycles node graph.
|
||||
* Due to the limited nodes in the USD Preview Surface specification, only the following nodes
|
||||
* are supported:
|
||||
* - UVMap
|
||||
* - Texture Coordinate
|
||||
* - Image Texture
|
||||
* - Principled BSDF
|
||||
* More may be added in the future.
|
||||
/* Create USDMaterial from Blender material.
|
||||
*
|
||||
* \param default_uv: used as the default UV set name sampled by the `primvar`
|
||||
* reader shaders generated for image texture nodes that don't have an attached UVMap node.
|
||||
*/
|
||||
void create_usd_preview_surface_material(const USDExporterContext &usd_export_context,
|
||||
Material *material,
|
||||
pxr::UsdShadeMaterial &usd_material,
|
||||
const std::string &default_uv = "");
|
||||
pxr::UsdShadeMaterial create_usd_material(const USDExporterContext &usd_export_context,
|
||||
pxr::SdfPath usd_path,
|
||||
Material *material,
|
||||
const std::string &active_uv);
|
||||
|
||||
/* Entry point to create USD Shade Material network from Blender viewport display settings. */
|
||||
void create_usd_viewport_material(const USDExporterContext &usd_export_context,
|
||||
Material *material,
|
||||
pxr::UsdShadeMaterial &usd_material);
|
||||
/* Returns a USDPreviewSurface token name for a given Blender shader Socket name,
|
||||
* or an empty TfToken if the input name is not found in the map. */
|
||||
const pxr::TfToken token_for_input(const char *input_name);
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -109,7 +109,7 @@ TEST_F(UsdCurvesTest, usd_export_curves)
|
|||
/* File sanity check. */
|
||||
EXPECT_EQ(BLI_listbase_count(&bfile->main->objects), 6);
|
||||
|
||||
USDExportParams params{};
|
||||
USDExportParams params;
|
||||
|
||||
const bool result = USD_export(context, output_filename.c_str(), ¶ms, false);
|
||||
EXPECT_TRUE(result) << "USD export should succed.";
|
||||
|
|
|
@ -209,10 +209,11 @@ TEST_F(UsdExportTest, usd_export_rain_mesh)
|
|||
/* File sanity check. */
|
||||
EXPECT_EQ(BLI_listbase_count(&bfile->main->objects), 3);
|
||||
|
||||
USDExportParams params{};
|
||||
USDExportParams params;
|
||||
params.export_materials = false;
|
||||
params.export_normals = true;
|
||||
params.export_uvmaps = false;
|
||||
params.visible_objects_only = true;
|
||||
params.evaluation_mode = eEvaluationMode::DAG_EVAL_VIEWPORT;
|
||||
|
||||
bool result = USD_export(context, output_filename.c_str(), ¶ms, false);
|
||||
ASSERT_TRUE(result) << "Writing to " << output_filename << " failed!";
|
||||
|
@ -272,12 +273,13 @@ TEST_F(UsdExportTest, usd_export_material)
|
|||
|
||||
EXPECT_TRUE(bool(material));
|
||||
|
||||
USDExportParams params{};
|
||||
params.export_normals = true;
|
||||
USDExportParams params;
|
||||
params.export_materials = true;
|
||||
params.generate_preview_surface = true;
|
||||
params.export_normals = true;
|
||||
params.export_textures = false;
|
||||
params.export_uvmaps = true;
|
||||
params.evaluation_mode = eEvaluationMode::DAG_EVAL_VIEWPORT;
|
||||
params.generate_preview_surface = true;
|
||||
params.relative_paths = false;
|
||||
|
||||
const bool result = USD_export(context, output_filename.c_str(), ¶ms, false);
|
||||
ASSERT_TRUE(result) << "Unable to export stage to " << output_filename;
|
||||
|
|
|
@ -94,7 +94,9 @@ TEST_F(UsdUsdzExportTest, usdz_export)
|
|||
<< "BLI_current_working_dir is not expected to return a different value than the given char "
|
||||
"buffer.";
|
||||
|
||||
USDExportParams params{};
|
||||
USDExportParams params;
|
||||
params.export_materials = false;
|
||||
params.visible_objects_only = false;
|
||||
|
||||
bool result = USD_export(context, output_filepath, ¶ms, false);
|
||||
ASSERT_TRUE(result) << "usd export to " << output_filepath << " failed.";
|
||||
|
|
|
@ -40,20 +40,20 @@ typedef enum eUSDTexNameCollisionMode {
|
|||
} eUSDTexNameCollisionMode;
|
||||
|
||||
struct USDExportParams {
|
||||
bool export_animation;
|
||||
bool export_hair;
|
||||
bool export_uvmaps;
|
||||
bool export_normals;
|
||||
bool export_materials;
|
||||
bool selected_objects_only;
|
||||
bool visible_objects_only;
|
||||
bool use_instancing;
|
||||
enum eEvaluationMode evaluation_mode;
|
||||
bool generate_preview_surface;
|
||||
bool export_textures;
|
||||
bool overwrite_textures;
|
||||
bool relative_paths;
|
||||
char root_prim_path[1024]; /* FILE_MAX */
|
||||
bool export_animation = false;
|
||||
bool export_hair = true;
|
||||
bool export_uvmaps = true;
|
||||
bool export_normals = true;
|
||||
bool export_materials = true;
|
||||
bool selected_objects_only = false;
|
||||
bool visible_objects_only = true;
|
||||
bool use_instancing = false;
|
||||
enum eEvaluationMode evaluation_mode = DAG_EVAL_VIEWPORT;
|
||||
bool generate_preview_surface = true;
|
||||
bool export_textures = true;
|
||||
bool overwrite_textures = true;
|
||||
bool relative_paths = true;
|
||||
char root_prim_path[1024] = ""; /* FILE_MAX */
|
||||
};
|
||||
|
||||
struct USDImportParams {
|
||||
|
|
|
@ -55,8 +55,14 @@ def main():
|
|||
report.set_pixelated(True)
|
||||
report.set_reference_dir("compositor_renders")
|
||||
|
||||
# Temporary change to pass OpenImageDenoise test with both 1.3 and 1.4.
|
||||
if os.path.basename(test_dir) == 'filter':
|
||||
# Temporary change to pass OpenImageDenoise test with both 1.3 and 1.4.
|
||||
report.set_fail_threshold(0.05)
|
||||
elif os.path.basename(test_dir) == 'matte':
|
||||
# The node_keying_matte.blend test is very sensitive to the exact values in the
|
||||
# input image. It makes it hard to precisely match results on different systems
|
||||
# (with and without SSE, i.e.), especially when OCIO has different precision for
|
||||
# the exponent transform on different platforms.
|
||||
report.set_fail_threshold(0.05)
|
||||
|
||||
ok = report.run(test_dir, blender, get_arguments, batch=True)
|
||||
|
|
Loading…
Reference in New Issue