Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2020-01-31 15:03:15 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2020-01-31 15:03:15 +0300
commit53d805abcbf0a68155025a186d8a3c60de4af374 (patch)
tree1855ef1e13c34af39d2cbc5fe8e3f0c7ee75619d /source
parent6ab359e525204e476cfa9c772e80d37d3d2c5014 (diff)
parentc82b8c5944d85a24fcb1b6552e970accb4628c9d (diff)
Merge branch 'blender-v2.82-release'
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/displist_tangent.c161
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c231
-rw-r--r--source/blender/python/intern/CMakeLists.txt5
-rw-r--r--source/blender/python/intern/bpy_app.c3
-rw-r--r--source/blender/python/intern/bpy_app_usd.c107
-rw-r--r--source/blender/python/intern/bpy_app_usd.h29
-rw-r--r--source/blender/usd/intern/usd_capi.cc15
-rw-r--r--source/blender/usd/usd.h2
-rw-r--r--source/creator/CMakeLists.txt18
9 files changed, 430 insertions, 141 deletions
diff --git a/source/blender/blenkernel/intern/displist_tangent.c b/source/blender/blenkernel/intern/displist_tangent.c
index 754aa78c0ac..4ac8d47feba 100644
--- a/source/blender/blenkernel/intern/displist_tangent.c
+++ b/source/blender/blenkernel/intern/displist_tangent.c
@@ -29,17 +29,21 @@
/* interface */
#include "mikktspace.h"
-/** \name Tangent Space Calculation
- * \{ */
-
-/* Necessary complexity to handle looptri's as quads for correct tangents */
-#define USE_LOOPTRI_DETECT_QUADS
-
typedef struct {
const DispList *dl;
float (*tangent)[4]; /* destination */
+ /** Face normal for flat shading. */
+ float (*fnormals)[3];
+ /** Use by surfaces. Size of the surface in faces. */
+ int u_len, v_len;
} SGLSLDisplistToTangent;
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name DL_INDEX3 tangents
+ * \{ */
+
static int dl3_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
{
SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
@@ -102,10 +106,122 @@ static void dl3_ts_SetTSpace(const SMikkTSpaceContext *pContext,
dlt->tangent[0][3] = fSign;
}
-void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (**r_tangent)[4])
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name DL_SURF tangents
+ * \{ */
+
+static int dlsurf_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+ SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+
+ return dlt->v_len * dlt->u_len;
+}
+
+static int dlsurf_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+ UNUSED_VARS(pContext, face_num);
+
+ return 4;
+}
+
+static int face_to_vert_index(SGLSLDisplistToTangent *dlt,
+ const int face_num,
+ const int vert_index)
+{
+ int u = face_num % dlt->u_len;
+ int v = face_num / dlt->u_len;
+
+ if (vert_index == 0) {
+ u += 1;
+ }
+ else if (vert_index == 1) {
+ u += 1;
+ v += 1;
+ }
+ else if (vert_index == 2) {
+ v += 1;
+ }
+
+ /* Cyclic correction. */
+ u = u % dlt->dl->nr;
+ v = v % dlt->dl->parts;
+
+ return v * dlt->dl->nr + u;
+}
+
+static void dlsurf_ts_GetPosition(const SMikkTSpaceContext *pContext,
+ float r_co[3],
+ const int face_num,
+ const int vert_index)
+{
+ SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+ const float(*verts)[3] = (float(*)[3])dlt->dl->verts;
+
+ copy_v3_v3(r_co, verts[face_to_vert_index(dlt, face_num, vert_index)]);
+}
+
+static void dlsurf_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext,
+ float r_uv[2],
+ const int face_num,
+ const int vert_index)
+{
+ SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+
+ int idx = face_to_vert_index(dlt, face_num, vert_index);
+
+ /* Note: For some reason the shading U and V are swapped compared to the
+ * one described in the surface format. */
+ r_uv[0] = (idx / dlt->dl->nr) / (float)(dlt->v_len);
+ r_uv[1] = (idx % dlt->dl->nr) / (float)(dlt->u_len);
+
+ if (r_uv[0] == 0.0f && ELEM(vert_index, 1, 2)) {
+ r_uv[0] = 1.0f;
+ }
+ if (r_uv[1] == 0.0f && ELEM(vert_index, 0, 1)) {
+ r_uv[1] = 1.0f;
+ }
+}
+
+static void dlsurf_ts_GetNormal(const SMikkTSpaceContext *pContext,
+ float r_no[3],
+ const int face_num,
+ const int vert_index)
{
- UNUSED_VARS(fnormals);
+ SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+ const float(*nors)[3] = (float(*)[3])dlt->dl->nors;
+
+ if (dlt->fnormals) {
+ copy_v3_v3(r_no, dlt->fnormals[face_num]);
+ }
+ else {
+ copy_v3_v3(r_no, nors[face_to_vert_index(dlt, face_num, vert_index)]);
+ }
+}
+
+static void dlsurf_ts_SetTSpace(const SMikkTSpaceContext *pContext,
+ const float fvTangent[3],
+ const float fSign,
+ const int face_num,
+ const int vert_index)
+{
+ SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+ UNUSED_VARS(face_num, vert_index);
+
+ float *r_tan = dlt->tangent[face_num * 4 + vert_index];
+ copy_v3_v3(r_tan, fvTangent);
+ r_tan[3] = fSign;
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Entry point
+ * \{ */
+void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (**r_tangent)[4])
+{
if (dl->type == DL_INDEX3) {
/* INDEX3 have only one tangent so we don't need actual allocation. */
BLI_assert(*r_tangent != NULL);
@@ -128,14 +244,31 @@ void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (
genTangSpaceDefault(&sContext);
}
else if (dl->type == DL_SURF) {
-#if 0
- int vert_len = dl->parts * dl->nr;
+ SGLSLDisplistToTangent mesh2tangent = {
+ .dl = dl,
+ .u_len = dl->nr - ((dl->flag & DL_CYCL_U) ? 0 : 1),
+ .v_len = dl->parts - ((dl->flag & DL_CYCL_V) ? 0 : 1),
+ .fnormals = fnormals,
+ };
+
+ int loop_len = mesh2tangent.u_len * mesh2tangent.v_len * 4;
+
if (*r_tangent == NULL) {
- *r_tangent = MEM_mallocN(sizeof(float[4]) * vert_len, "displist tangents");
+ *r_tangent = MEM_mallocN(sizeof(float[4]) * loop_len, "displist tangents");
}
-#endif
- /* TODO */
- BLI_assert(0);
+ mesh2tangent.tangent = *r_tangent;
+ SMikkTSpaceContext sContext = {NULL};
+ SMikkTSpaceInterface sInterface = {NULL};
+ sContext.m_pUserData = &mesh2tangent;
+ sContext.m_pInterface = &sInterface;
+ sInterface.m_getNumFaces = dlsurf_ts_GetNumFaces;
+ sInterface.m_getNumVerticesOfFace = dlsurf_ts_GetNumVertsOfFace;
+ sInterface.m_getPosition = dlsurf_ts_GetPosition;
+ sInterface.m_getTexCoord = dlsurf_ts_GetTextureCoordinate;
+ sInterface.m_getNormal = dlsurf_ts_GetNormal;
+ sInterface.m_setTSpaceBasic = dlsurf_ts_SetTSpace;
+ /* 0 if failed */
+ genTangSpaceDefault(&sContext);
}
else {
/* Unsupported. */
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index 10f4b7ddbb6..50979d72189 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -362,32 +362,6 @@ static void surf_uv_quad(const DispList *dl, const uint quad[4], float r_uv[4][2
}
}
-static GPUPackedNormal surf_tan_quad(const DispList *dl,
- const float (*verts)[3],
- const float nor[3],
- uint index)
-{
- float tan[3], tmp[3];
-
- int v = index / dl->nr;
- /* Note: For some reason the shading U and V are swapped compared to the
- * one described in the surface format. So tangent is along V. */
- if (v == 0) {
- sub_v3_v3v3(tan, verts[index + dl->nr], verts[index]);
- }
- else {
- sub_v3_v3v3(tan, verts[index], verts[index - dl->nr]);
- }
- /* Orthonormalize around the normal. */
- cross_v3_v3v3(tmp, nor, tan);
- cross_v3_v3v3(tan, tmp, nor);
- normalize_v3(tan);
-
- GPUPackedNormal ptan = GPU_normal_convert_i10_v3(tan);
- ptan.w = 1; /* Pretty sure surfaces cannot have inverted normals. */
- return ptan;
-}
-
static void displist_vertbuf_attr_set_tri_pos_nor_uv(GPUVertBufRaw *pos_step,
GPUVertBufRaw *nor_step,
GPUVertBufRaw *uv_step,
@@ -428,6 +402,54 @@ static void displist_vertbuf_attr_set_tri_pos_nor_uv(GPUVertBufRaw *pos_step,
}
}
+#define SURFACE_QUAD_ITER_START(dl) \
+ { \
+ uint quad[4]; \
+ int quad_index = 0; \
+ int max_v = (dl->flag & DL_CYCL_V) ? dl->parts : (dl->parts - 1); \
+ int max_u = (dl->flag & DL_CYCL_U) ? dl->nr : (dl->nr - 1); \
+ for (int v = 0; v < max_v; v++) { \
+ quad[3] = dl->nr * v; \
+ quad[0] = quad[3] + 1; \
+ quad[2] = quad[3] + dl->nr; \
+ quad[1] = quad[0] + dl->nr; \
+ /* Cyclic wrap */ \
+ if (v == dl->parts - 1) { \
+ quad[1] -= dl->parts * dl->nr; \
+ quad[2] -= dl->parts * dl->nr; \
+ } \
+ for (int u = 0; u < max_u; u++, quad_index++) { \
+ /* Cyclic wrap */ \
+ if (u == dl->nr - 1) { \
+ quad[0] -= dl->nr; \
+ quad[1] -= dl->nr; \
+ }
+
+#define SURFACE_QUAD_ITER_END \
+ quad[2] = quad[1]; \
+ quad[1]++; \
+ quad[3] = quad[0]; \
+ quad[0]++; \
+ } \
+ } \
+ }
+
+static void displist_surf_fnors_ensure(const DispList *dl, float (**fnors)[3])
+{
+ int u_len = dl->nr - ((dl->flag & DL_CYCL_U) ? 0 : 1);
+ int v_len = dl->parts - ((dl->flag & DL_CYCL_V) ? 0 : 1);
+ const float(*verts)[3] = (float(*)[3])dl->verts;
+ float(*nor_flat)[3] = MEM_mallocN(sizeof(float) * 3 * u_len * v_len, __func__);
+ *fnors = nor_flat;
+
+ SURFACE_QUAD_ITER_START(dl)
+ {
+ normal_quad_v3(*nor_flat, verts[quad[0]], verts[quad[1]], verts[quad[2]], verts[quad[3]]);
+ nor_flat++;
+ }
+ SURFACE_QUAD_ITER_END
+}
+
void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
GPUVertBuf *vbo_pos_nor,
GPUVertBuf *vbo_uv,
@@ -495,7 +517,7 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
const GPUPackedNormal pnor = GPU_normal_convert_i10_v3(dl->nors);
GPUPackedNormal ptan = {0, 0, 0, 1};
- if (tan_step.size != 0) {
+ if (vbo_tan) {
float tan[4];
float(*tan_ptr)[4] = &tan;
BKE_displist_tangent_calc(dl, NULL, &tan_ptr);
@@ -533,102 +555,81 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
}
}
else if (dl->type == DL_SURF) {
- uint quad[4];
- for (int a = 0; a < dl->parts; a++) {
- if ((dl->flag & DL_CYCL_V) == 0 && a == dl->parts - 1) {
- break;
+ float(*tangents)[4] = NULL;
+ float(*fnors)[3] = NULL;
+
+ if (!is_smooth) {
+ displist_surf_fnors_ensure(dl, &fnors);
+ }
+
+ if (vbo_tan) {
+ BKE_displist_tangent_calc(dl, fnors, &tangents);
+ }
+
+ SURFACE_QUAD_ITER_START(dl)
+ {
+ if (vbo_uv) {
+ surf_uv_quad(dl, quad, uv);
}
- int b;
- if (dl->flag & DL_CYCL_U) {
- quad[0] = dl->nr * a;
- quad[3] = quad[0] + dl->nr - 1;
- quad[1] = quad[0] + dl->nr;
- quad[2] = quad[3] + dl->nr;
- b = 0;
+ GPUPackedNormal pnors_quad[4];
+ if (is_smooth) {
+ for (int j = 0; j < 4; j++) {
+ pnors_quad[j] = GPU_normal_convert_i10_v3(nors[quad[j]]);
+ }
}
else {
- quad[3] = dl->nr * a;
- quad[0] = quad[3] + 1;
- quad[2] = quad[3] + dl->nr;
- quad[1] = quad[0] + dl->nr;
- b = 1;
- }
- if ((dl->flag & DL_CYCL_V) && a == dl->parts - 1) {
- quad[1] -= dl->parts * dl->nr;
- quad[2] -= dl->parts * dl->nr;
+ pnors_quad[0] = GPU_normal_convert_i10_v3(fnors[quad_index]);
+ pnors_quad[1] = pnors_quad[2] = pnors_quad[3] = pnors_quad[0];
}
- for (; b < dl->nr; b++) {
- if (vbo_uv) {
- surf_uv_quad(dl, quad, uv);
- }
-
- GPUPackedNormal pnors_quad[4];
- GPUPackedNormal ptans_quad[4];
- if (is_smooth) {
- for (int j = 0; j < 4; j++) {
- pnors_quad[j] = GPU_normal_convert_i10_v3(nors[quad[j]]);
- if (tan_step.size != 0) {
- /* TODO(fclem) This is a waste of computation power because the same vertex
- * is computed 4 times. */
- ptans_quad[j] = surf_tan_quad(dl, verts, nors[quad[j]], quad[j]);
- }
- }
+ GPUPackedNormal ptans_quad[4];
+ if (vbo_tan) {
+ for (int j = 0; j < 4; j++) {
+ float *tan = tangents[quad_index * 4 + j];
+ ptans_quad[j] = GPU_normal_convert_i10_v3(tan);
+ ptans_quad[j].w = (tan[3] > 0.0f) ? 1 : -2;
}
- else {
- float nor_flat[3];
- normal_quad_v3(
- nor_flat, verts[quad[0]], verts[quad[1]], verts[quad[2]], verts[quad[3]]);
- if (tan_step.size != 0) {
- for (int j = 0; j < 4; j++) {
- ptans_quad[j] = surf_tan_quad(dl, verts, nor_flat, quad[j]);
- }
- }
- pnors_quad[0] = GPU_normal_convert_i10_v3(nor_flat);
- pnors_quad[1] = pnors_quad[2] = pnors_quad[3] = pnors_quad[0];
- }
-
- displist_vertbuf_attr_set_tri_pos_nor_uv(&pos_step,
- &nor_step,
- &uv_step,
- &tan_step,
- verts[quad[2]],
- verts[quad[0]],
- verts[quad[1]],
- &pnors_quad[2],
- &pnors_quad[0],
- &pnors_quad[1],
- &ptans_quad[2],
- &ptans_quad[0],
- &ptans_quad[1],
- uv[2],
- uv[0],
- uv[1]);
+ }
- displist_vertbuf_attr_set_tri_pos_nor_uv(&pos_step,
- &nor_step,
- &uv_step,
- &tan_step,
- verts[quad[0]],
- verts[quad[2]],
- verts[quad[3]],
- &pnors_quad[0],
- &pnors_quad[2],
- &pnors_quad[3],
- &ptans_quad[0],
- &ptans_quad[2],
- &ptans_quad[3],
- uv[0],
- uv[2],
- uv[3]);
+ displist_vertbuf_attr_set_tri_pos_nor_uv(&pos_step,
+ &nor_step,
+ &uv_step,
+ &tan_step,
+ verts[quad[2]],
+ verts[quad[0]],
+ verts[quad[1]],
+ &pnors_quad[2],
+ &pnors_quad[0],
+ &pnors_quad[1],
+ &ptans_quad[2],
+ &ptans_quad[0],
+ &ptans_quad[1],
+ uv[2],
+ uv[0],
+ uv[1]);
- quad[2] = quad[1];
- quad[1]++;
- quad[3] = quad[0];
- quad[0]++;
- }
+ displist_vertbuf_attr_set_tri_pos_nor_uv(&pos_step,
+ &nor_step,
+ &uv_step,
+ &tan_step,
+ verts[quad[0]],
+ verts[quad[2]],
+ verts[quad[3]],
+ &pnors_quad[0],
+ &pnors_quad[2],
+ &pnors_quad[3],
+ &ptans_quad[0],
+ &ptans_quad[2],
+ &ptans_quad[3],
+ uv[0],
+ uv[2],
+ uv[3]);
}
+ SURFACE_QUAD_ITER_END
+
+ MEM_SAFE_FREE(tangents);
+ MEM_SAFE_FREE(fnors);
}
else {
BLI_assert(dl->type == DL_INDEX4);
@@ -656,9 +657,7 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
normal_quad_v3(nor_flat, verts[idx[0]], verts[idx[1]], verts[idx[2]], verts[idx[3]]);
}
pnors_idx[0] = GPU_normal_convert_i10_v3(nor_flat);
- pnors_idx[1] = pnors_idx[0];
- pnors_idx[2] = pnors_idx[0];
- pnors_idx[3] = pnors_idx[0];
+ pnors_idx[1] = pnors_idx[2] = pnors_idx[3] = pnors_idx[0];
}
displist_vertbuf_attr_set_tri_pos_nor_uv(&pos_step,
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index adcda710622..7106dace084 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -56,6 +56,7 @@ set(SRC
bpy_app_sdl.c
bpy_app_timers.c
bpy_app_translations.c
+ bpy_app_usd.c
bpy_capi_utils.c
bpy_driver.c
bpy_gizmo_wrap.c
@@ -95,6 +96,7 @@ set(SRC
bpy_app_sdl.h
bpy_app_timers.h
bpy_app_translations.h
+ bpy_app_usd.h
bpy_capi_utils.h
bpy_driver.h
bpy_gizmo_wrap.h
@@ -309,6 +311,9 @@ endif()
if(WITH_USD)
add_definitions(-DWITH_USD)
+ list(APPEND INC
+ ../../usd
+ )
endif()
if(WITH_OPENIMAGEIO)
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 043b31007f1..678df0d8993 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -33,6 +33,7 @@
#include "bpy_app_opensubdiv.h"
#include "bpy_app_openvdb.h"
#include "bpy_app_sdl.h"
+#include "bpy_app_usd.h"
#include "bpy_app_build_options.h"
#include "bpy_app_translations.h"
@@ -108,6 +109,7 @@ static PyStructSequence_Field app_info_fields[] = {
/* submodules */
{"alembic", "Alembic library information backend"},
+ {"usd", "USD library information backend"},
{"ffmpeg", "FFmpeg library information backend"},
{"ocio", "OpenColorIO library information backend"},
{"oiio", "OpenImageIO library information backend"},
@@ -201,6 +203,7 @@ static PyObject *make_app_info(void)
#endif
SetObjItem(BPY_app_alembic_struct());
+ SetObjItem(BPY_app_usd_struct());
SetObjItem(BPY_app_ffmpeg_struct());
SetObjItem(BPY_app_ocio_struct());
SetObjItem(BPY_app_oiio_struct());
diff --git a/source/blender/python/intern/bpy_app_usd.c b/source/blender/python/intern/bpy_app_usd.c
new file mode 100644
index 00000000000..d87d218a5e5
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_usd.c
@@ -0,0 +1,107 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include "BLI_utildefines.h"
+
+#include "bpy_app_usd.h"
+
+#include "../generic/py_capi_utils.h"
+
+#ifdef WITH_USD
+# include "usd.h"
+#endif
+
+static PyTypeObject BlenderAppUSDType;
+
+static PyStructSequence_Field app_usd_info_fields[] = {
+ {"supported", "Boolean, True when Blender is built with USD support"},
+ {"version", "The USD version as a tuple of 3 numbers"},
+ {"version_string", "The USD version formatted as a string"},
+ {NULL},
+};
+
+static PyStructSequence_Desc app_usd_info_desc = {
+ "bpy.app.usd", /* name */
+ "This module contains information about the Universal Scene Description library Bender is "
+ "linked against", /* doc */
+ app_usd_info_fields, /* fields */
+ ARRAY_SIZE(app_usd_info_fields) - 1,
+};
+
+static PyObject *make_usd_info(void)
+{
+ PyObject *usd_info = PyStructSequence_New(&BlenderAppUSDType);
+
+ if (usd_info == NULL) {
+ return NULL;
+ }
+
+ int pos = 0;
+
+#ifndef WITH_USD
+# define SetStrItem(str) PyStructSequence_SET_ITEM(usd_info, pos++, PyUnicode_FromString(str))
+#endif
+
+#define SetObjItem(obj) PyStructSequence_SET_ITEM(usd_info, pos++, obj)
+
+#ifdef WITH_USD
+ const int curversion = USD_get_version();
+ const int major = curversion / 10000;
+ const int minor = (curversion / 100) % 100;
+ const int patch = curversion % 100;
+
+ SetObjItem(PyBool_FromLong(1));
+ SetObjItem(PyC_Tuple_Pack_I32(major, minor, patch));
+ SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d", major, minor, patch));
+#else
+ SetObjItem(PyBool_FromLong(0));
+ SetObjItem(PyC_Tuple_Pack_I32(0, 0, 0));
+ SetStrItem("Unknown");
+#endif
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(usd_info);
+ return NULL;
+ }
+
+#undef SetStrItem
+#undef SetObjItem
+
+ return usd_info;
+}
+
+PyObject *BPY_app_usd_struct(void)
+{
+ PyStructSequence_InitType(&BlenderAppUSDType, &app_usd_info_desc);
+
+ PyObject *ret = make_usd_info();
+
+ /* prevent user from creating new instances */
+ BlenderAppUSDType.tp_init = NULL;
+ BlenderAppUSDType.tp_new = NULL;
+ BlenderAppUSDType.tp_hash = (hashfunc)
+ _Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
+
+ return ret;
+}
diff --git a/source/blender/python/intern/bpy_app_usd.h b/source/blender/python/intern/bpy_app_usd.h
new file mode 100644
index 00000000000..e3e1d72b366
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_usd.h
@@ -0,0 +1,29 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup pythonintern
+ */
+
+#ifndef __BPY_APP_USD_H__
+#define __BPY_APP_USD_H__
+
+PyObject *BPY_app_usd_struct(void);
+
+#endif /* __BPY_APP_USD_H__ */
diff --git a/source/blender/usd/intern/usd_capi.cc b/source/blender/usd/intern/usd_capi.cc
index f8391700324..83e11cd7bf3 100644
--- a/source/blender/usd/intern/usd_capi.cc
+++ b/source/blender/usd/intern/usd_capi.cc
@@ -20,6 +20,7 @@
#include "usd.h"
#include "usd_hierarchy_iterator.h"
+#include <pxr/pxr.h>
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usdGeom/tokens.h>
@@ -216,3 +217,17 @@ bool USD_export(bContext *C,
return export_ok;
}
+
+int USD_get_version(void)
+{
+ /* USD 19.11 defines:
+ *
+ * #define PXR_MAJOR_VERSION 0
+ * #define PXR_MINOR_VERSION 19
+ * #define PXR_PATCH_VERSION 11
+ * #define PXR_VERSION 1911
+ *
+ * So the major version is implicit/invisible in the public version number.
+ */
+ return PXR_VERSION;
+}
diff --git a/source/blender/usd/usd.h b/source/blender/usd/usd.h
index c8e559c59f5..8a5575d53cf 100644
--- a/source/blender/usd/usd.h
+++ b/source/blender/usd/usd.h
@@ -54,6 +54,8 @@ bool USD_export(struct bContext *C,
const struct USDExportParams *params,
bool as_background_job);
+int USD_get_version(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 82c45b4fe64..690c332c20e 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -38,20 +38,16 @@ blender_include_dirs(
)
set(LIB
- # This forces TBB libraries to be in front of MKL (which is a part of OpenImageDenoise).
- #
- # The need of this comes to need to ensure static libraries initialization order, making it
- # so TBB is initialized prior to MKL (or any other dpeendnecy).
- #
- # This isn't fully robust but seems to work.
- ${TBB_LIBRARIES}
-
bf_windowmanager
)
-# Note: this should not be needed, but causes issues in some situations:
-# See reply to daf290dcc80c.
-if(WITH_TBB AND WITH_OPENIMAGEDENOISE)
+if(WITH_TBB)
+ # Force TBB libraries to be in front of MKL (part of OpenImageDenoise), so
+ # that it is initialized before MKL and static library initialization order
+ # issues are avoided.
+ #
+ # This isn't fully robust but seems to work.
+ list(INSERT LIB 0 ${TBB_LIBRARIES})
list(INSERT LIB 0 bf_blenkernel)
endif()