diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2020-01-31 15:03:15 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2020-01-31 15:03:15 +0300 |
commit | 53d805abcbf0a68155025a186d8a3c60de4af374 (patch) | |
tree | 1855ef1e13c34af39d2cbc5fe8e3f0c7ee75619d | |
parent | 6ab359e525204e476cfa9c772e80d37d3d2c5014 (diff) | |
parent | c82b8c5944d85a24fcb1b6552e970accb4628c9d (diff) |
Merge branch 'blender-v2.82-release'
-rw-r--r-- | build_files/cmake/Modules/GTestTesting.cmake | 9 | ||||
-rw-r--r-- | intern/mikktspace/mikktspace.c | 2 | ||||
-rw-r--r-- | release/scripts/modules/sys_info.py | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist_tangent.c | 161 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_displist.c | 231 | ||||
-rw-r--r-- | source/blender/python/intern/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app.c | 3 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app_usd.c | 107 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app_usd.h | 29 | ||||
-rw-r--r-- | source/blender/usd/intern/usd_capi.cc | 15 | ||||
-rw-r--r-- | source/blender/usd/usd.h | 2 | ||||
-rw-r--r-- | source/creator/CMakeLists.txt | 18 |
12 files changed, 445 insertions, 144 deletions
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake index 30b10ae5980..c9f62906ae0 100644 --- a/build_files/cmake/Modules/GTestTesting.cmake +++ b/build_files/cmake/Modules/GTestTesting.cmake @@ -40,9 +40,14 @@ macro(BLENDER_SRC_GTEST_EX) add_executable(${TARGET_NAME} ${ARG_SRC} ${MANIFEST}) target_include_directories(${TARGET_NAME} PUBLIC "${TEST_INC}") target_include_directories(${TARGET_NAME} SYSTEM PUBLIC "${TEST_INC_SYS}") + target_link_libraries(${TARGET_NAME} ${ARG_EXTRA_LIBS} ${PLATFORM_LINKLIBS}) + 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. + target_link_libraries(${TARGET_NAME} ${TBB_LIBRARIES}) + endif() target_link_libraries(${TARGET_NAME} - ${ARG_EXTRA_LIBS} - ${PLATFORM_LINKLIBS} bf_testing_main bf_intern_eigen bf_intern_guardedalloc diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c index 285529298eb..47bed53ed28 100644 --- a/intern/mikktspace/mikktspace.c +++ b/intern/mikktspace/mikktspace.c @@ -1392,7 +1392,7 @@ static void QuickSort(int *pSortBuffer, int iLeft, int iRight, unsigned int uSee // Random unsigned int t = uSeed & 31; - t = (uSeed << t) | (uSeed >> (32 - t)); + t = rotl(uSeed, t); uSeed = uSeed + t + 3; // Random end diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index 8b4e224efe4..656e2b3bd54 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -172,6 +172,13 @@ def write_sysinfo(filepath): else: output.write("Blender was built without Alembic support\n") + usd = bpy.app.usd + output.write("USD: ") + if usd.supported: + output.write("%s\n" % usd.version_string) + else: + output.write("Blender was built without USD support\n") + if not bpy.app.build_options.sdl: output.write("SDL: Blender was built without SDL support\n") 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() |