From 655f5818a589539b286641450c00d27a5cac2bff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 04:46:10 +1000 Subject: Cleanup: use BKE_mesh_ prefix for the remesh API These functions deal with voxel remeshing of Mesh data, and aren't related to MOD_remesh.c for e.g. Name so other kinds of remeshing wont cause confusion. --- source/blender/blenkernel/BKE_mesh_remesh_voxel.h | 46 +++++ source/blender/blenkernel/BKE_remesh.h | 46 ----- source/blender/blenkernel/CMakeLists.txt | 4 +- .../blender/blenkernel/intern/mesh_remesh_voxel.c | 200 +++++++++++++++++++++ source/blender/blenkernel/intern/remesh.c | 200 --------------------- source/blender/editors/object/object_remesh.c | 4 +- 6 files changed, 250 insertions(+), 250 deletions(-) create mode 100644 source/blender/blenkernel/BKE_mesh_remesh_voxel.h delete mode 100644 source/blender/blenkernel/BKE_remesh.h create mode 100644 source/blender/blenkernel/intern/mesh_remesh_voxel.c delete mode 100644 source/blender/blenkernel/intern/remesh.c diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h new file mode 100644 index 00000000000..089e4de4709 --- /dev/null +++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h @@ -0,0 +1,46 @@ +/* + * 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) 2019 by Blender Foundation + * All rights reserved. + */ +#ifndef __BKE_REMESH_H__ +#define __BKE_REMESH_H__ + +/** \file + * \ingroup bke + */ + +#ifdef WITH_OPENVDB +# include "openvdb_capi.h" +#endif + +struct Mesh; + +/* OpenVDB Voxel Remesher */ +#ifdef WITH_OPENVDB +struct OpenVDBLevelSet *BKE_mesh_remesh_voxel_ovdb_mesh_to_level_set_create( + struct Mesh *mesh, struct OpenVDBTransform *transform); +struct Mesh *BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *level_set, + double isovalue, + double adaptivity, + bool relax_disoriented_triangles); +#endif +struct Mesh *BKE_mesh_remesh_voxel_to_mesh_nomain(struct Mesh *mesh, float voxel_size); + +/* Data reprojection functions */ +void BKE_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source); + +#endif /* __BKE_REMESH_H__ */ diff --git a/source/blender/blenkernel/BKE_remesh.h b/source/blender/blenkernel/BKE_remesh.h deleted file mode 100644 index 996e88e0ea0..00000000000 --- a/source/blender/blenkernel/BKE_remesh.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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) 2019 by Blender Foundation - * All rights reserved. - */ -#ifndef __BKE_REMESH_H__ -#define __BKE_REMESH_H__ - -/** \file - * \ingroup bke - */ - -#ifdef WITH_OPENVDB -# include "openvdb_capi.h" -#endif - -struct Mesh; - -/* OpenVDB Voxel Remesher */ -#ifdef WITH_OPENVDB -struct OpenVDBLevelSet *BKE_remesh_voxel_ovdb_mesh_to_level_set_create( - struct Mesh *mesh, struct OpenVDBTransform *transform); -struct Mesh *BKE_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *level_set, - double isovalue, - double adaptivity, - bool relax_disoriented_triangles); -#endif -struct Mesh *BKE_remesh_voxel_to_mesh_nomain(struct Mesh *mesh, float voxel_size); - -/* Data reprojection functions */ -void BKE_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source); - -#endif /* __BKE_REMESH_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 1f125b93b3f..669abff6599 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -151,6 +151,7 @@ set(SRC intern/mesh_mapping.c intern/mesh_merge.c intern/mesh_remap.c + intern/mesh_remesh_voxel.c intern/mesh_runtime.c intern/mesh_tangent.c intern/mesh_validate.c @@ -178,7 +179,6 @@ set(SRC intern/pbvh.c intern/pbvh_bmesh.c intern/pointcache.c - intern/remesh.c intern/report.c intern/rigidbody.c intern/scene.c @@ -301,6 +301,7 @@ set(SRC BKE_mesh_iterators.h BKE_mesh_mapping.h BKE_mesh_remap.h + BKE_mesh_remesh_voxel.h BKE_mesh_runtime.h BKE_mesh_tangent.h BKE_modifier.h @@ -318,7 +319,6 @@ set(SRC BKE_particle.h BKE_pbvh.h BKE_pointcache.h - BKE_remesh.h BKE_report.h BKE_rigidbody.h BKE_scene.h diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.c b/source/blender/blenkernel/intern/mesh_remesh_voxel.c new file mode 100644 index 00000000000..17347842216 --- /dev/null +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.c @@ -0,0 +1,200 @@ +/* + * 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) 2019 by Blender Foundation + * All rights reserved. + */ + +/** \file + * \ingroup bke + */ + +#include +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" +#include "BKE_library.h" +#include "BKE_customdata.h" +#include "BKE_bvhutils.h" +#include "BKE_mesh_remesh_voxel.h" /* own include */ + +#ifdef WITH_OPENVDB +# include "openvdb_capi.h" +#endif + +#ifdef WITH_OPENVDB +struct OpenVDBLevelSet *BKE_mesh_remesh_voxel_ovdb_mesh_to_level_set_create( + Mesh *mesh, struct OpenVDBTransform *transform) +{ + BKE_mesh_runtime_looptri_recalc(mesh); + const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); + MVertTri *verttri = MEM_callocN(sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh), + "remesh_looptri"); + BKE_mesh_runtime_verttri_from_looptri( + verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh)); + + unsigned int totfaces = BKE_mesh_runtime_looptri_len(mesh); + unsigned int totverts = mesh->totvert; + float *verts = (float *)MEM_malloc_arrayN(totverts * 3, sizeof(float), "remesh_input_verts"); + unsigned int *faces = (unsigned int *)MEM_malloc_arrayN( + totfaces * 3, sizeof(unsigned int), "remesh_intput_faces"); + + for (unsigned int i = 0; i < totverts; i++) { + MVert *mvert = &mesh->mvert[i]; + verts[i * 3] = mvert->co[0]; + verts[i * 3 + 1] = mvert->co[1]; + verts[i * 3 + 2] = mvert->co[2]; + } + + for (unsigned int i = 0; i < totfaces; i++) { + MVertTri *vt = &verttri[i]; + faces[i * 3] = vt->tri[0]; + faces[i * 3 + 1] = vt->tri[1]; + faces[i * 3 + 2] = vt->tri[2]; + } + + struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL); + OpenVDBLevelSet_mesh_to_level_set(level_set, verts, faces, totverts, totfaces, transform); + + MEM_freeN(verts); + MEM_freeN(faces); + MEM_freeN(verttri); + + return level_set; +} + +Mesh *BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *level_set, + double isovalue, + double adaptivity, + bool relax_disoriented_triangles) +{ +# ifdef WITH_OPENVDB + struct OpenVDBVolumeToMeshData output_mesh; + OpenVDBLevelSet_volume_to_mesh( + level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles); +# endif + + Mesh *mesh = BKE_mesh_new_nomain( + output_mesh.totvertices, 0, output_mesh.totquads + output_mesh.tottriangles, 0, 0); + int q = output_mesh.totquads; + + for (int i = 0; i < output_mesh.totvertices; i++) { + float vco[3] = {output_mesh.vertices[i * 3], + output_mesh.vertices[i * 3 + 1], + output_mesh.vertices[i * 3 + 2]}; + copy_v3_v3(mesh->mvert[i].co, vco); + } + + for (int i = 0; i < output_mesh.totquads; i++) { + mesh->mface[i].v4 = output_mesh.quads[i * 4]; + mesh->mface[i].v3 = output_mesh.quads[i * 4 + 1]; + mesh->mface[i].v2 = output_mesh.quads[i * 4 + 2]; + mesh->mface[i].v1 = output_mesh.quads[i * 4 + 3]; + } + + for (int i = 0; i < output_mesh.tottriangles; i++) { + mesh->mface[i + q].v4 = 0; + mesh->mface[i + q].v3 = output_mesh.triangles[i * 3]; + mesh->mface[i + q].v2 = output_mesh.triangles[i * 3 + 1]; + mesh->mface[i + q].v1 = output_mesh.triangles[i * 3 + 2]; + } + + BKE_mesh_calc_edges_tessface(mesh); + BKE_mesh_convert_mfaces_to_mpolys(mesh); + BKE_mesh_tessface_clear(mesh); + BKE_mesh_calc_normals(mesh); + + MEM_freeN(output_mesh.quads); + MEM_freeN(output_mesh.vertices); + + if (output_mesh.tottriangles > 0) { + MEM_freeN(output_mesh.triangles); + } + + return mesh; +} +#endif + +Mesh *BKE_mesh_remesh_voxel_to_mesh_nomain(Mesh *mesh, float voxel_size) +{ + Mesh *new_mesh = NULL; +#ifdef WITH_OPENVDB + struct OpenVDBLevelSet *level_set; + struct OpenVDBTransform *xform = OpenVDBTransform_create(); + OpenVDBTransform_create_linear_transform(xform, (double)voxel_size); + level_set = BKE_mesh_remesh_voxel_ovdb_mesh_to_level_set_create(mesh, xform); + new_mesh = BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(level_set, 0.0, 0.0, false); + OpenVDBLevelSet_free(level_set); + OpenVDBTransform_free(xform); +#else + UNUSED_VARS(mesh, voxel_size); +#endif + return new_mesh; +} + +void BKE_remesh_reproject_paint_mask(Mesh *target, Mesh *source) +{ + BVHTreeFromMesh bvhtree = { + .nearest_callback = NULL, + }; + BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); + MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT); + + float *target_mask; + if (CustomData_has_layer(&target->vdata, CD_PAINT_MASK)) { + target_mask = CustomData_get_layer(&target->vdata, CD_PAINT_MASK); + } + else { + target_mask = CustomData_add_layer( + &target->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, target->totvert); + } + + float *source_mask; + if (CustomData_has_layer(&source->vdata, CD_PAINT_MASK)) { + source_mask = CustomData_get_layer(&source->vdata, CD_PAINT_MASK); + } + else { + source_mask = CustomData_add_layer( + &source->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, source->totvert); + } + + for (int i = 0; i < target->totvert; i++) { + float from_co[3]; + BVHTreeNearest nearest; + nearest.index = -1; + nearest.dist_sq = FLT_MAX; + copy_v3_v3(from_co, target_verts[i].co); + BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree); + if (nearest.index != -1) { + target_mask[i] = source_mask[nearest.index]; + } + } + free_bvhtree_from_mesh(&bvhtree); +} diff --git a/source/blender/blenkernel/intern/remesh.c b/source/blender/blenkernel/intern/remesh.c deleted file mode 100644 index 36e92689f1a..00000000000 --- a/source/blender/blenkernel/intern/remesh.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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) 2019 by Blender Foundation - * All rights reserved. - */ - -/** \file - * \ingroup bke - */ - -#include -#include -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - -#include "BKE_mesh.h" -#include "BKE_mesh_runtime.h" -#include "BKE_library.h" -#include "BKE_customdata.h" -#include "BKE_bvhutils.h" -#include "BKE_remesh.h" - -#ifdef WITH_OPENVDB -# include "openvdb_capi.h" -#endif - -#ifdef WITH_OPENVDB -struct OpenVDBLevelSet *BKE_remesh_voxel_ovdb_mesh_to_level_set_create( - Mesh *mesh, struct OpenVDBTransform *transform) -{ - BKE_mesh_runtime_looptri_recalc(mesh); - const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); - MVertTri *verttri = MEM_callocN(sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh), - "remesh_looptri"); - BKE_mesh_runtime_verttri_from_looptri( - verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh)); - - unsigned int totfaces = BKE_mesh_runtime_looptri_len(mesh); - unsigned int totverts = mesh->totvert; - float *verts = (float *)MEM_malloc_arrayN(totverts * 3, sizeof(float), "remesh_input_verts"); - unsigned int *faces = (unsigned int *)MEM_malloc_arrayN( - totfaces * 3, sizeof(unsigned int), "remesh_intput_faces"); - - for (unsigned int i = 0; i < totverts; i++) { - MVert *mvert = &mesh->mvert[i]; - verts[i * 3] = mvert->co[0]; - verts[i * 3 + 1] = mvert->co[1]; - verts[i * 3 + 2] = mvert->co[2]; - } - - for (unsigned int i = 0; i < totfaces; i++) { - MVertTri *vt = &verttri[i]; - faces[i * 3] = vt->tri[0]; - faces[i * 3 + 1] = vt->tri[1]; - faces[i * 3 + 2] = vt->tri[2]; - } - - struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL); - OpenVDBLevelSet_mesh_to_level_set(level_set, verts, faces, totverts, totfaces, transform); - - MEM_freeN(verts); - MEM_freeN(faces); - MEM_freeN(verttri); - - return level_set; -} - -Mesh *BKE_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *level_set, - double isovalue, - double adaptivity, - bool relax_disoriented_triangles) -{ -# ifdef WITH_OPENVDB - struct OpenVDBVolumeToMeshData output_mesh; - OpenVDBLevelSet_volume_to_mesh( - level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles); -# endif - - Mesh *mesh = BKE_mesh_new_nomain( - output_mesh.totvertices, 0, output_mesh.totquads + output_mesh.tottriangles, 0, 0); - int q = output_mesh.totquads; - - for (int i = 0; i < output_mesh.totvertices; i++) { - float vco[3] = {output_mesh.vertices[i * 3], - output_mesh.vertices[i * 3 + 1], - output_mesh.vertices[i * 3 + 2]}; - copy_v3_v3(mesh->mvert[i].co, vco); - } - - for (int i = 0; i < output_mesh.totquads; i++) { - mesh->mface[i].v4 = output_mesh.quads[i * 4]; - mesh->mface[i].v3 = output_mesh.quads[i * 4 + 1]; - mesh->mface[i].v2 = output_mesh.quads[i * 4 + 2]; - mesh->mface[i].v1 = output_mesh.quads[i * 4 + 3]; - } - - for (int i = 0; i < output_mesh.tottriangles; i++) { - mesh->mface[i + q].v4 = 0; - mesh->mface[i + q].v3 = output_mesh.triangles[i * 3]; - mesh->mface[i + q].v2 = output_mesh.triangles[i * 3 + 1]; - mesh->mface[i + q].v1 = output_mesh.triangles[i * 3 + 2]; - } - - BKE_mesh_calc_edges_tessface(mesh); - BKE_mesh_convert_mfaces_to_mpolys(mesh); - BKE_mesh_tessface_clear(mesh); - BKE_mesh_calc_normals(mesh); - - MEM_freeN(output_mesh.quads); - MEM_freeN(output_mesh.vertices); - - if (output_mesh.tottriangles > 0) { - MEM_freeN(output_mesh.triangles); - } - - return mesh; -} -#endif - -Mesh *BKE_remesh_voxel_to_mesh_nomain(Mesh *mesh, float voxel_size) -{ - Mesh *new_mesh = NULL; -#ifdef WITH_OPENVDB - struct OpenVDBLevelSet *level_set; - struct OpenVDBTransform *xform = OpenVDBTransform_create(); - OpenVDBTransform_create_linear_transform(xform, (double)voxel_size); - level_set = BKE_remesh_voxel_ovdb_mesh_to_level_set_create(mesh, xform); - new_mesh = BKE_remesh_voxel_ovdb_volume_to_mesh_nomain(level_set, 0.0, 0.0, false); - OpenVDBLevelSet_free(level_set); - OpenVDBTransform_free(xform); -#else - UNUSED_VARS(mesh, voxel_size); -#endif - return new_mesh; -} - -void BKE_remesh_reproject_paint_mask(Mesh *target, Mesh *source) -{ - BVHTreeFromMesh bvhtree = { - .nearest_callback = NULL, - }; - BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); - MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT); - - float *target_mask; - if (CustomData_has_layer(&target->vdata, CD_PAINT_MASK)) { - target_mask = CustomData_get_layer(&target->vdata, CD_PAINT_MASK); - } - else { - target_mask = CustomData_add_layer( - &target->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, target->totvert); - } - - float *source_mask; - if (CustomData_has_layer(&source->vdata, CD_PAINT_MASK)) { - source_mask = CustomData_get_layer(&source->vdata, CD_PAINT_MASK); - } - else { - source_mask = CustomData_add_layer( - &source->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, source->totvert); - } - - for (int i = 0; i < target->totvert; i++) { - float from_co[3]; - BVHTreeNearest nearest; - nearest.index = -1; - nearest.dist_sq = FLT_MAX; - copy_v3_v3(from_co, target_verts[i].co); - BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree); - if (nearest.index != -1) { - target_mask[i] = source_mask[nearest.index]; - } - } - free_bvhtree_from_mesh(&bvhtree); -} diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 2234b3875b7..1bcac9b4739 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -47,7 +47,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_customdata.h" -#include "BKE_remesh.h" +#include "BKE_mesh_remesh_voxel.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -102,7 +102,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) ED_sculpt_undo_geometry_begin(ob); } - new_mesh = BKE_remesh_voxel_to_mesh_nomain(mesh, mesh->remesh_voxel_size); + new_mesh = BKE_mesh_remesh_voxel_to_mesh_nomain(mesh, mesh->remesh_voxel_size); if (!new_mesh) { return OPERATOR_CANCELLED; -- cgit v1.2.3 From 1845f0ee8b33698ddd48c22000004ad4084a77ab Mon Sep 17 00:00:00 2001 From: Lazydodo Date: Wed, 14 Aug 2019 12:52:17 -0600 Subject: Cleanup: Fix build error with MSVC C99 style initializers are C++20 feature and should not be used. Reported by @deadpin on chat. --- source/blender/gpu/GPU_vertex_format.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index dc60c52122c..fc468436499 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -164,9 +164,9 @@ BLI_INLINE int gpu_convert_i16_to_i10(short x) BLI_INLINE GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3]) { GPUPackedNormal n = { - .x = gpu_convert_normalized_f32_to_i10(data[0]), - .y = gpu_convert_normalized_f32_to_i10(data[1]), - .z = gpu_convert_normalized_f32_to_i10(data[2]), + gpu_convert_normalized_f32_to_i10(data[0]), + gpu_convert_normalized_f32_to_i10(data[1]), + gpu_convert_normalized_f32_to_i10(data[2]), }; return n; } @@ -174,9 +174,9 @@ BLI_INLINE GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3]) BLI_INLINE GPUPackedNormal GPU_normal_convert_i10_s3(const short data[3]) { GPUPackedNormal n = { - .x = gpu_convert_i16_to_i10(data[0]), - .y = gpu_convert_i16_to_i10(data[1]), - .z = gpu_convert_i16_to_i10(data[2]), + gpu_convert_i16_to_i10(data[0]), + gpu_convert_i16_to_i10(data[1]), + gpu_convert_i16_to_i10(data[2]), }; return n; } -- cgit v1.2.3 From 5489611e53176ad4c1d5ac626db6377b27624cce Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Aug 2019 15:30:26 +0200 Subject: Compositor: Added denoising node This node is built on Intel's OpenImageDenoise library. Other denoisers could be integrated, for example Lukas' Cycles denoiser. Compositor: Made OpenImageDenoise optional, added CMake and build_env files to find OIDN Compositor: Fixed some warnings in the denoising operator build_environment: Updated OpenImageDenoise to 0.8.1 build_environment: Updated OpenImageDenoise in `make deps` for macOS Reviewers: sergey, jbakker, brecht Reviewed By: brecht Subscribers: YAFU, LazyDodo, Zen_YS, slumber, samgreen, tjvoll, yeus, ponomarovmax, getrad, coder.kalyan, vitos1k, Yegor, DeepBlender, kumaran7, Darkfie9825, aliasguru, aafra, ace_dragon, juang3d, pandrodor, cdog, lordodin, jtheninja, mavek, marcog, 5k1n2, Atair, rawalanche, 0o00o0oo, filibis, poor, lukasstockner97 Tags: #compositing Differential Revision: https://developer.blender.org/D4304 --- CMakeLists.txt | 2 + build_files/build_environment/CMakeLists.txt | 1 + build_files/build_environment/cmake/harvest.cmake | 2 + .../build_environment/cmake/openimagedenoise.cmake | 61 ++++++++ build_files/build_environment/cmake/tbb.cmake | 2 +- build_files/build_environment/cmake/versions.cmake | 4 + .../patches/openimagedenoise.diff | 119 ++++++++++++++++ .../cmake/Modules/FindOpenImageDenoise.cmake | 101 ++++++++++++++ build_files/cmake/config/blender_full.cmake | 1 + build_files/cmake/config/blender_lite.cmake | 1 + build_files/cmake/config/blender_release.cmake | 1 + build_files/cmake/macros.cmake | 6 + build_files/cmake/platform/platform_apple.cmake | 13 ++ build_files/cmake/platform/platform_unix.cmake | 9 ++ build_files/cmake/platform/platform_win32.cmake | 13 ++ release/scripts/startup/nodeitems_builtins.py | 1 + source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + source/blender/compositor/CMakeLists.txt | 13 +- source/blender/compositor/intern/COM_Converter.cpp | 6 +- .../blender/compositor/nodes/COM_DenoiseNode.cpp | 47 +++++++ source/blender/compositor/nodes/COM_DenoiseNode.h | 37 +++++ .../compositor/operations/COM_DenoiseOperation.cpp | 154 +++++++++++++++++++++ .../compositor/operations/COM_DenoiseOperation.h | 71 ++++++++++ source/blender/editors/space_node/CMakeLists.txt | 4 + source/blender/editors/space_node/drawnode.c | 13 ++ source/blender/makesdna/DNA_node_types.h | 5 + source/blender/makesrna/intern/rna_nodetree.c | 12 ++ source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_composite.h | 1 + source/blender/nodes/NOD_static_types.h | 1 + .../nodes/composite/nodes/node_composite_denoise.c | 58 ++++++++ 32 files changed, 759 insertions(+), 3 deletions(-) create mode 100644 build_files/build_environment/cmake/openimagedenoise.cmake create mode 100644 build_files/build_environment/patches/openimagedenoise.diff create mode 100644 build_files/cmake/Modules/FindOpenImageDenoise.cmake create mode 100644 source/blender/compositor/nodes/COM_DenoiseNode.cpp create mode 100644 source/blender/compositor/nodes/COM_DenoiseNode.h create mode 100644 source/blender/compositor/operations/COM_DenoiseOperation.cpp create mode 100644 source/blender/compositor/operations/COM_DenoiseOperation.h create mode 100644 source/blender/nodes/composite/nodes/node_composite_denoise.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ced6e1d76d..2a7a020c428 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,6 +237,7 @@ option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLO # Compositor option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON) +option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" OFF) option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ${_init_OPENSUBDIV}) @@ -1760,6 +1761,7 @@ if(FIRST_RUN) info_cfg_option(WITH_CYCLES) info_cfg_option(WITH_FREESTYLE) info_cfg_option(WITH_OPENCOLORIO) + info_cfg_option(WITH_OPENIMAGEDENOISE) info_cfg_option(WITH_OPENVDB) info_cfg_option(WITH_ALEMBIC) diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 0dbd3b572cf..1b387cb86a2 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -97,6 +97,7 @@ if(UNIX AND NOT APPLE) else() include(cmake/pugixml.cmake) endif() +include(cmake/openimagedenoise.cmake) if(WITH_WEBP) include(cmake/webp.cmake) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 27bcd184c44..97e4a6b69d4 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -166,6 +166,8 @@ harvest(openimageio/bin openimageio/bin "maketx") harvest(openimageio/bin openimageio/bin "oiiotool") harvest(openimageio/include openimageio/include "*") harvest(openimageio/lib openimageio/lib "*.a") +harvest(openimagedenoise/include openimagedenoise/include "*") +harvest(openimagedenoise/lib openimagedenoise/lib "*.a") harvest(openjpeg/include/openjpeg-2.3 openjpeg/include "*.h") harvest(openjpeg/lib openjpeg/lib "*.a") harvest(opensubdiv/include opensubdiv/include "*.h") diff --git a/build_files/build_environment/cmake/openimagedenoise.cmake b/build_files/build_environment/cmake/openimagedenoise.cmake new file mode 100644 index 00000000000..b20bb838ede --- /dev/null +++ b/build_files/build_environment/cmake/openimagedenoise.cmake @@ -0,0 +1,61 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# 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. +# +# ***** END GPL LICENSE BLOCK ***** + + +set(OIDN_EXTRA_ARGS + -DWITH_EXAMPLE=OFF + -DWITH_TEST=OFF + -DTBB_ROOT=${LIBDIR}/tbb + -DTBB_STATIC_LIB=ON + -DOIDN_STATIC_LIB=ON +) + +ExternalProject_Add(external_openimagedenoise + URL ${OIDN_URI} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH MD5=${OIDN_HASH} + PREFIX ${BUILD_DIR}/openimagedenoise + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openimagedenoise ${DEFAULT_CMAKE_FLAGS} ${OIDN_EXTRA_ARGS} + PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/openimagedenoise/src/external_openimagedenoise < ${PATCH_DIR}/openimagedenoise.diff + INSTALL_DIR ${LIBDIR}/openimagedenoise +) + +add_dependencies( + external_openimagedenoise + external_tbb +) + +if(WIN32) + if(BUILD_MODE STREQUAL Release) + ExternalProject_Add_Step(external_openimagedenoise after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openimagedenoise/include ${HARVEST_TARGET}/openimagedenoise/include + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn.lib + DEPENDEES install + ) + endif() + if(BUILD_MODE STREQUAL Debug) + ExternalProject_Add_Step(external_openimagedenoise after_install + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn_d.lib + DEPENDEES install + ) + endif() +endif() diff --git a/build_files/build_environment/cmake/tbb.cmake b/build_files/build_environment/cmake/tbb.cmake index 77f061e30d0..26c52e00c76 100644 --- a/build_files/build_environment/cmake/tbb.cmake +++ b/build_files/build_environment/cmake/tbb.cmake @@ -18,7 +18,7 @@ set(TBB_EXTRA_ARGS -DTBB_BUILD_SHARED=Off - -DTBB_BUILD_TBBMALLOC=Off + -DTBB_BUILD_TBBMALLOC=On -DTBB_BUILD_TBBMALLOC_PROXY=Off -DTBB_BUILD_STATIC=On ) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 3ee6a4920ed..c3b713096d6 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -302,3 +302,7 @@ set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7) set(EMBREE_VERSION 3.2.4) set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip) set(EMBREE_HASH 3d4a1147002ff43939d45140aa9d6fb8) + +set(OIDN_VERSION 1.0.0) +set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.zip) +set(OIDN_HASH 19fe67b0164e8f020ac8a4f520defe60) diff --git a/build_files/build_environment/patches/openimagedenoise.diff b/build_files/build_environment/patches/openimagedenoise.diff new file mode 100644 index 00000000000..08d7a397a6d --- /dev/null +++ b/build_files/build_environment/patches/openimagedenoise.diff @@ -0,0 +1,119 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 70ec895..e616b63 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -178,7 +178,9 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION "0") + ## Open Image Denoise examples + ## ---------------------------------------------------------------------------- + +-add_subdirectory(examples) ++if(WITH_EXAMPLE) ++ add_subdirectory(examples) ++endif() + + ## ---------------------------------------------------------------------------- + ## Open Image Denoise install and packaging +Submodule mkl-dnn contains modified content +diff --git a/mkl-dnn/cmake/TBB.cmake b/mkl-dnn/cmake/TBB.cmake +index 0711e699..c14210b6 100644 +--- a/mkl-dnn/cmake/TBB.cmake ++++ b/mkl-dnn/cmake/TBB.cmake +@@ -90,8 +90,8 @@ if(WIN32) + NO_DEFAULT_PATH + ) + set(TBB_LIB_DIR ${TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER}) +- find_library(TBB_LIBRARY tbb PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH) +- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH) ++ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH) ++ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH) + endif() + + else() +@@ -138,13 +138,13 @@ else() + set(TBB_LIBRARY_MALLOC TBB_LIBRARY_MALLOC-NOTFOUND) + if(APPLE) + find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH) +- find_library(TBB_LIBRARY tbb PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH) +- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH) ++ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH) ++ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH) + else() + find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH) + set(TBB_HINTS HINTS ${TBB_ROOT}/lib/intel64/gcc4.4 ${TBB_ROOT}/lib ${TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/) +- find_library(TBB_LIBRARY tbb ${TBB_HINTS}) +- find_library(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS}) ++ find_library(TBB_LIBRARY tbb_static ${TBB_HINTS}) ++ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static ${TBB_HINTS}) + endif() + endif() + +diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r +--- a/cmake/install.cmake 2019-08-12 18:02:20.794402575 +0200 ++++ b/cmake/install.cmake 2019-08-12 18:06:07.470045703 +0200 +@@ -18,6 +18,13 @@ + ## Install library + ## ---------------------------------------------------------------------------- + ++if(UNIX) ++install(FILES ++ ${CMAKE_BINARY_DIR}/libOpenImageDenoise.a ++ ${CMAKE_BINARY_DIR}/libmkldnn.a ++ ${CMAKE_BINARY_DIR}/libcommon.a ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++else() + install(TARGETS ${PROJECT_NAME} + EXPORT + ${PROJECT_NAME}_Export +@@ -38,6 +45,7 @@ + DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel + ) + endif() ++endif() + + ## ---------------------------------------------------------------------------- + ## Install headers +@@ -78,6 +86,7 @@ + ## Install CMake configuration files + ## ---------------------------------------------------------------------------- + ++if(NOT UNIX) + install(EXPORT ${PROJECT_NAME}_Export + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + #NAMESPACE ${PROJECT_NAME}:: +@@ -92,3 +101,4 @@ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + COMPONENT devel + ) ++endif() +diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r +--- a/CMakeLists.txt 2019-08-12 14:22:00.974078598 +0200 ++++ b/CMakeLists.txt 2019-08-12 18:05:05.949057375 +0200 +@@ -14,7 +14,11 @@ + ## limitations under the License. ## + ## ======================================================================== ## + +-cmake_minimum_required(VERSION 3.1) ++if(UNIX) ++ cmake_minimum_required(VERSION 3.1) ++else() ++ cmake_minimum_required(VERSION 3.13) ++endif() + + set(OIDN_VERSION_MAJOR 1) + set(OIDN_VERSION_MINOR 0) +@@ -32,13 +36,8 @@ + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") + + # Build as shared or static library +-if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") +- option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.") +- mark_as_advanced(CLEAR OIDN_STATIC_LIB) +-else() +- set(OIDN_STATIC_LIB OFF CACHE BOOL "Build Open Image Denoise as a static library." FORCE) +- mark_as_advanced(OIDN_STATIC_LIB) +-endif() ++option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.") ++mark_as_advanced(CLEAR OIDN_STATIC_LIB) + if(OIDN_STATIC_LIB) + set(OIDN_LIB_TYPE STATIC) + else() diff --git a/build_files/cmake/Modules/FindOpenImageDenoise.cmake b/build_files/cmake/Modules/FindOpenImageDenoise.cmake new file mode 100644 index 00000000000..85ba10b14e4 --- /dev/null +++ b/build_files/cmake/Modules/FindOpenImageDenoise.cmake @@ -0,0 +1,101 @@ +# - Find OpenImageDenoise library +# Find the native OpenImageDenoise includes and library +# This module defines +# OPENIMAGEDENOISE_INCLUDE_DIRS, where to find oidn.h, Set when +# OPENIMAGEDENOISE is found. +# OPENIMAGEDENOISE_LIBRARIES, libraries to link against to use OpenImageDenoise. +# OPENIMAGEDENOISE_ROOT_DIR, The base directory to search for OpenImageDenoise. +# This can also be an environment variable. +# OPENIMAGEDENOISE_FOUND, If false, do not try to use OpenImageDenoise. +# +# also defined, but not for general use are +# OPENIMAGEDENOISE_LIBRARY, where to find the OpenImageDenoise library. + +#============================================================================= +# Copyright 2019 Blender Foundation. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# If OPENIMAGEDENOISE_ROOT_DIR was defined in the environment, use it. +IF(NOT OPENIMAGEDENOISE_ROOT_DIR AND NOT $ENV{OPENIMAGEDENOISE_ROOT_DIR} STREQUAL "") + SET(OPENIMAGEDENOISE_ROOT_DIR $ENV{OPENIMAGEDENOISE_ROOT_DIR}) +ENDIF() + +SET(_openimagedenoise_SEARCH_DIRS + ${OPENIMAGEDENOISE_ROOT_DIR} + /usr/local + /sw # Fink + /opt/local # DarwinPorts + /opt/lib/openimagedenoise +) + +FIND_PATH(OPENIMAGEDENOISE_INCLUDE_DIR + NAMES + OpenImageDenoise/oidn.h + HINTS + ${_openimagedenoise_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +SET(_openimagedenoise_FIND_COMPONENTS + OpenImageDenoise + common + mkldnn +) + +SET(_openimagedenoise_LIBRARIES) +FOREACH(COMPONENT ${_openimagedenoise_FIND_COMPONENTS}) + STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT) + + FIND_LIBRARY(OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY + NAMES + ${COMPONENT} + HINTS + ${_openimagedenoise_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib + ) + LIST(APPEND _openimagedenoise_LIBRARIES "${OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY}") +ENDFOREACH() + +FIND_LIBRARY(OPENIMAGEDENOISE_LIBRARY + NAMES + OpenImageDenoise + HINTS + ${_openimagedenoise_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib + ) + +# handle the QUIETLY and REQUIRED arguments and set OPENIMAGEDENOISE_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENIMAGEDENOISE DEFAULT_MSG + OPENIMAGEDENOISE_LIBRARY OPENIMAGEDENOISE_INCLUDE_DIR) + +IF(OPENIMAGEDENOISE_FOUND) + SET(OPENIMAGEDENOISE_LIBRARIES ${_openimagedenoise_LIBRARIES}) + SET(OPENIMAGEDENOISE_INCLUDE_DIRS ${OPENIMAGEDENOISE_INCLUDE_DIR}) +ELSE() + SET(OPENIMAGEDENOISE_FOUND FALSE) +ENDIF() + +MARK_AS_ADVANCED( + OPENIMAGEDENOISE_INCLUDE_DIR +) + +FOREACH(COMPONENT ${_openimagedenoise_FIND_COMPONENTS}) + STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT) + MARK_AS_ADVANCED(OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY) +ENDFOREACH() + +UNSET(_openimagedenoise_SEARCH_DIRS) +UNSET(_openimagedenoise_FIND_COMPONENTS) +UNSET(_openimagedenoise_LIBRARIES) diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index 6786cb5ce37..38371ccb60e 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -40,6 +40,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE) set(WITH_OPENAL ON CACHE BOOL "" FORCE) set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE) set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE) +set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE) set(WITH_OPENMP ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE) set(WITH_OPENVDB ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index b85176d37f3..6596d1db674 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -45,6 +45,7 @@ set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE) set(WITH_OPENAL OFF CACHE BOOL "" FORCE) set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE) set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE) +set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE) set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE) set(WITH_OPENMP OFF CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 24032b6aed6..682f456dd3d 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -41,6 +41,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE) set(WITH_OPENAL ON CACHE BOOL "" FORCE) set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE) set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE) +set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE) set(WITH_OPENMP ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE) set(WITH_OPENVDB ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index c2f608de921..f6756cb514c 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -352,6 +352,9 @@ function(SETUP_LIBDIRS) if(WITH_OPENIMAGEIO) link_directories(${OPENIMAGEIO_LIBPATH}) endif() + if(WITH_OPENIMAGEDENOISE) + link_directories(${OPENIMAGEDENOISE_LIBPATH}) + endif() if(WITH_OPENCOLORIO) link_directories(${OPENCOLORIO_LIBPATH}) endif() @@ -462,6 +465,9 @@ function(setup_liblinks if(WITH_OPENIMAGEIO) target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES}) endif() + if(WITH_OPENIMAGEDENOISE) + target_link_libraries(${target} ${OPENIMAGEDENOISE_LIBRARIES} ${TBB_LIBRARIES}) + endif() if(WITH_OPENCOLORIO) target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES}) endif() diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 882f41b3c0d..e79359e9f3b 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -382,6 +382,19 @@ if(WITH_CYCLES_EMBREE) set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Xlinker -stack_size -Xlinker 0x100000") endif() +if(WITH_OPENIMAGEDENOISE) + find_package(OpenImageDenoise) + find_package(TBB) + + if(NOT OPENIMAGEDENOISE_FOUND) + set(WITH_OPENIMAGEDENOISE OFF) + message(STATUS "OpenImageDenoise not found") + elseif(NOT TBB_FOUND) + set(WITH_OPENIMAGEDENOISE OFF) + message(STATUS "TBB not found") + endif() +endif() + # CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags. if(WITH_OPENMP) if(CMAKE_C_COMPILER_ID MATCHES "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 43d13a97a3e..1b3f9cf3fad 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -368,6 +368,15 @@ if(WITH_CYCLES_EMBREE) find_package(Embree 3.2.4 REQUIRED) endif() +if(WITH_OPENIMAGEDENOISE) + find_package_wrapper(OpenImageDenoise) + + if(NOT OPENIMAGEDENOISE_FOUND) + set(WITH_OPENIMAGEDENOISE OFF) + message(STATUS "OpenImageDenoise not found") + endif() +endif() + if(WITH_LLVM) if(EXISTS ${LIBDIR}) set(LLVM_STATIC ON) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index ad1249949c9..208521a9e65 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -484,6 +484,19 @@ if(WITH_OPENVDB) set(OPENVDB_DEFINITIONS -DNOMINMAX) endif() +if(WITH_OPENIMAGEDENOISE) + set(TBB_LIBRARIES optimized ${LIBDIR}/tbb/lib/tbb.lib debug ${LIBDIR}/tbb/lib/tbb_debug.lib) + set(TBB_INCLUDE_DIR ${LIBDIR}/tbb/include) + set(OPENIMAGEDENOISE ${LIBDIR}/OpenImageDenoise) + set(OPENIMAGEDENOISE_LIBPATH ${LIBDIR}/OpenImageDenoise/lib) + set(OPENIMAGEDENOISE_INCLUDE_DIRS ${OPENIMAGEDENOISE}/include ${TBB_INCLUDE_DIR}) + set(OPENIMAGEDENOISE_LIBRARIES + optimized ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise.lib ${OPENIMAGEDENOISE_LIBPATH}/common.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn.lib + debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn_d.lib + ${TBB_LIBRARIES}) + set(OPENIMAGEDENOISE_DEFINITIONS) +endif() + if(WITH_ALEMBIC) set(ALEMBIC ${LIBDIR}/alembic) set(ALEMBIC_INCLUDE_DIR ${ALEMBIC}/include) diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index a626984cfa7..c6e83a646e5 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -352,6 +352,7 @@ compositor_node_categories = [ NodeItem("CompositorNodeDBlur"), NodeItem("CompositorNodePixelate"), NodeItem("CompositorNodeSunBeams"), + NodeItem("CompositorNodeDenoise"), ]), CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[ NodeItem("CompositorNodeNormal"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d9acbb3a843..9b2db5acd3b 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1129,6 +1129,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree, #define CMP_NODE_CORNERPIN 321 #define CMP_NODE_SWITCH_VIEW 322 #define CMP_NODE_CRYPTOMATTE 323 +#define CMP_NODE_DENOISE 324 /* channel toggles */ #define CMP_CHAN_RGB 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 7d7e1c75391..986571e34bd 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3779,6 +3779,7 @@ static void registerCompositNodes(void) register_node_type_cmp_despeckle(); register_node_type_cmp_defocus(); register_node_type_cmp_sunbeams(); + register_node_type_cmp_denoise(); register_node_type_cmp_valtorgb(); register_node_type_cmp_rgbtobw(); diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 308a95c0e0c..50b5951f99f 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -276,11 +276,12 @@ set(SRC nodes/COM_VectorBlurNode.h operations/COM_VectorBlurOperation.cpp operations/COM_VectorBlurOperation.h - nodes/COM_BlurNode.cpp nodes/COM_BlurNode.h nodes/COM_BokehBlurNode.cpp nodes/COM_BokehBlurNode.h + nodes/COM_DenoiseNode.h + nodes/COM_DenoiseNode.cpp nodes/COM_DespeckleNode.cpp nodes/COM_DespeckleNode.h nodes/COM_DilateErodeNode.cpp @@ -490,6 +491,8 @@ set(SRC operations/COM_ConvolutionEdgeFilterOperation.h operations/COM_ConvolutionFilterOperation.cpp operations/COM_ConvolutionFilterOperation.h + operations/COM_DenoiseOperation.h + operations/COM_DenoiseOperation.cpp operations/COM_DespeckleOperation.cpp operations/COM_DespeckleOperation.h operations/COM_DilateErodeOperation.cpp @@ -558,4 +561,12 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_OPENIMAGEDENOISE) + add_definitions(-DWITH_OPENIMAGEDENOISE) + add_definitions(-DOIDN_STATIC_LIB) + list(APPEND INC_SYS + ${OPENIMAGEDENOISE_INCLUDE_DIRS} + ) +endif() + blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 9dc55527f0d..704833389f8 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -53,6 +53,7 @@ extern "C" { #include "COM_CropNode.h" #include "COM_CryptomatteNode.h" #include "COM_DefocusNode.h" +#include "COM_DenoiseNode.h" #include "COM_DespeckleNode.h" #include "COM_DifferenceMatteNode.h" #include "COM_DilateErodeNode.h" @@ -122,7 +123,7 @@ bool Converter::is_fast_node(bNode *b_node) b_node->type == CMP_NODE_BOKEHBLUR || b_node->type == CMP_NODE_GLARE || b_node->type == CMP_NODE_DBLUR || b_node->type == CMP_NODE_MOVIEDISTORTION || b_node->type == CMP_NODE_LENSDIST || b_node->type == CMP_NODE_DOUBLEEDGEMASK || - b_node->type == CMP_NODE_DILATEERODE); + b_node->type == CMP_NODE_DILATEERODE || b_node->type == CMP_NODE_DENOISE); } Node *Converter::convert(bNode *b_node) @@ -402,6 +403,9 @@ Node *Converter::convert(bNode *b_node) case CMP_NODE_CRYPTOMATTE: node = new CryptomatteNode(b_node); break; + case CMP_NODE_DENOISE: + node = new DenoiseNode(b_node); + break; } return node; } diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.cpp b/source/blender/compositor/nodes/COM_DenoiseNode.cpp new file mode 100644 index 00000000000..7de120d1204 --- /dev/null +++ b/source/blender/compositor/nodes/COM_DenoiseNode.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019, Blender Foundation. + * + * 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. + * + * Contributor: + * Stefan Werner + */ + +#include "COM_DenoiseNode.h" +#include "DNA_node_types.h" +#include "COM_SetValueOperation.h" +#include "COM_MixOperation.h" +#include "COM_DenoiseOperation.h" + +DenoiseNode::DenoiseNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} + +void DenoiseNode::convertToOperations(NodeConverter &converter, + const CompositorContext & /*context*/) const +{ + bNode *node = this->getbNode(); + NodeDenoise *denoise = (NodeDenoise *)node->storage; + + DenoiseOperation *operation = new DenoiseOperation(); + converter.addOperation(operation); + operation->setDenoiseSettings(denoise); + + converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0)); + converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1)); + converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2)); + converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0)); +} diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.h b/source/blender/compositor/nodes/COM_DenoiseNode.h new file mode 100644 index 00000000000..0924da8931c --- /dev/null +++ b/source/blender/compositor/nodes/COM_DenoiseNode.h @@ -0,0 +1,37 @@ +/* + * Copyright 2019, Blender Foundation. + * + * 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. + * + * Contributor: + * Stefan Werner + */ + +#ifndef __COM_DENOISENODE_H__ +#define __COM_DENOISENODE_H__ + +#include "COM_Node.h" + +/** + * \brief DenoiseNode + * \ingroup Node + */ +class DenoiseNode : public Node { + public: + DenoiseNode(bNode *editorNode); + void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; +}; + +#endif diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp new file mode 100644 index 00000000000..af568490c72 --- /dev/null +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp @@ -0,0 +1,154 @@ +/* + * Copyright 2019, Blender Foundation. + * + * 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. + * + * Contributor: + * Stefan Werner + */ + +#include "COM_DenoiseOperation.h" +#include "BLI_math.h" +#ifdef WITH_OPENIMAGEDENOISE +# include +#endif +#include + +DenoiseOperation::DenoiseOperation() : SingleThreadedOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_COLOR); + this->m_settings = NULL; +} +void DenoiseOperation::initExecution() +{ + SingleThreadedOperation::initExecution(); + this->m_inputProgramColor = getInputSocketReader(0); + this->m_inputProgramAlbedo = getInputSocketReader(1); + this->m_inputProgramNormal = getInputSocketReader(2); +} + +void DenoiseOperation::deinitExecution() +{ + this->m_inputProgramColor = NULL; + this->m_inputProgramAlbedo = NULL; + this->m_inputProgramNormal = NULL; + SingleThreadedOperation::deinitExecution(); +} + +MemoryBuffer *DenoiseOperation::createMemoryBuffer(rcti *rect2) +{ + MemoryBuffer *tileColor = (MemoryBuffer *)this->m_inputProgramColor->initializeTileData(rect2); + MemoryBuffer *tileAlbedo = (MemoryBuffer *)this->m_inputProgramAlbedo->initializeTileData(rect2); + MemoryBuffer *tileNormal = (MemoryBuffer *)this->m_inputProgramNormal->initializeTileData(rect2); + rcti rect; + rect.xmin = 0; + rect.ymin = 0; + rect.xmax = getWidth(); + rect.ymax = getHeight(); + MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect); + float *data = result->getBuffer(); + this->generateDenoise(data, tileColor, tileAlbedo, tileNormal, this->m_settings); + return result; +} + +bool DenoiseOperation::determineDependingAreaOfInterest(rcti * /*input*/, + ReadBufferOperation *readOperation, + rcti *output) +{ + if (isCached()) { + return false; + } + else { + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} + +void DenoiseOperation::generateDenoise(float *data, + MemoryBuffer *inputTileColor, + MemoryBuffer *inputTileAlbedo, + MemoryBuffer *inputTileNormal, + NodeDenoise *settings) +{ + float *inputBufferColor = inputTileColor->getBuffer(); + BLI_assert(inputBufferColor); + if (!inputBufferColor) { + return; + } +#ifdef WITH_OPENIMAGEDENOISE + oidn::DeviceRef device = oidn::newDevice(); + device.commit(); + + oidn::FilterRef filter = device.newFilter("RT"); + filter.setImage("color", + inputBufferColor, + oidn::Format::Float3, + inputTileColor->getWidth(), + inputTileColor->getHeight(), + 0, + 4 * sizeof(float)); + if (inputTileAlbedo && inputTileAlbedo->getBuffer()) { + filter.setImage("albedo", + inputTileAlbedo->getBuffer(), + oidn::Format::Float3, + inputTileAlbedo->getWidth(), + inputTileAlbedo->getHeight(), + 0, + 4 * sizeof(float)); + } + if (inputTileNormal && inputTileNormal->getBuffer()) { + filter.setImage("normal", + inputTileNormal->getBuffer(), + oidn::Format::Float3, + inputTileNormal->getWidth(), + inputTileNormal->getHeight(), + 0, + 3 * sizeof(float)); + } + filter.setImage("output", + data, + oidn::Format::Float3, + inputTileColor->getWidth(), + inputTileColor->getHeight(), + 0, + 4 * sizeof(float)); + + BLI_assert(settings); + if (settings) { + filter.set("hdr", settings->hdr); + filter.set("srgb", false); + } + + filter.commit(); + filter.execute(); + + /* copy the alpha channel, OpenImageDenoise currently only supports RGB */ + size_t numPixels = inputTileColor->getWidth() * inputTileColor->getHeight(); + for (size_t i = 0; i < numPixels; ++i) { + data[i * 4 + 3] = inputBufferColor[i * 4 + 3]; + } +#else + ::memcpy(data, + inputBufferColor, + inputTileColor->getWidth() * inputTileColor->getHeight() * sizeof(float) * 4); +#endif +} diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.h b/source/blender/compositor/operations/COM_DenoiseOperation.h new file mode 100644 index 00000000000..6e19bd6034a --- /dev/null +++ b/source/blender/compositor/operations/COM_DenoiseOperation.h @@ -0,0 +1,71 @@ +/* + * Copyright 2019, Blender Foundation. + * + * 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. + * + * Contributor: + * Stefan Werner + */ + +#ifndef __COM_DENOISEBASEOPERATION_H__ +#define __COM_DENOISEBASEOPERATION_H__ + +#include "COM_SingleThreadedOperation.h" +#include "DNA_node_types.h" + +class DenoiseOperation : public SingleThreadedOperation { + private: + /** + * \brief Cached reference to the input programs + */ + SocketReader *m_inputProgramColor; + SocketReader *m_inputProgramAlbedo; + SocketReader *m_inputProgramNormal; + + /** + * \brief settings of the denoise node. + */ + NodeDenoise *m_settings; + + public: + DenoiseOperation(); + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setDenoiseSettings(NodeDenoise *settings) + { + this->m_settings = settings; + } + bool determineDependingAreaOfInterest(rcti *input, + ReadBufferOperation *readOperation, + rcti *output); + + protected: + void generateDenoise(float *data, + MemoryBuffer *inputTileColor, + MemoryBuffer *inputTileAlbedo, + MemoryBuffer *inputTileNormal, + NodeDenoise *settings); + + MemoryBuffer *createMemoryBuffer(rcti *rect); +}; +#endif diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 03c83305618..f8c30f9a688 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -71,6 +71,10 @@ if(WITH_COMPOSITOR) add_definitions(-DWITH_COMPOSITOR) endif() +if(WITH_OPENIMAGEDENOISE) + add_definitions(-DWITH_OPENIMAGEDENOISE) +endif() + add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 704d878e620..748e485f614 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2691,6 +2691,15 @@ static void node_composit_buts_brightcontrast(uiLayout *layout, uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE); } +static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ +#ifndef WITH_OPENIMAGEDENOISE + uiItemL(layout, IFACE_("Disabled, built without OpenImageDenoise"), ICON_ERROR); +#endif + + uiItemR(layout, ptr, "use_hdr", 0, NULL, ICON_NONE); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2924,6 +2933,10 @@ static void node_composit_set_butfunc(bNodeType *ntype) break; case CMP_NODE_BRIGHTCONTRAST: ntype->draw_buttons = node_composit_buts_brightcontrast; + break; + case CMP_NODE_DENOISE: + ntype->draw_buttons = node_composit_buts_denoise; + break; } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 04a42cb146c..3ad857ac7b7 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1012,6 +1012,11 @@ typedef struct NodeCryptomatte { char _pad[4]; } NodeCryptomatte; +typedef struct NodeDenoise { + char hdr; + char _pad[7]; +} NodeDenoise; + /* script node mode */ #define NODE_SCRIPT_INTERNAL 0 #define NODE_SCRIPT_EXTERNAL 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 347be6b8a72..c9815a6cc37 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -7600,6 +7600,18 @@ static void def_cmp_cryptomatte(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_remove"); } +static void def_cmp_denoise(StructRNA *srna) +{ + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeDenoise", "storage"); + + prop = RNA_def_property(srna, "use_hdr", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "hdr", 0); + RNA_def_property_ui_text(prop, "HDR", "Process HDR images"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + /* -- Texture Nodes --------------------------------------------------------- */ static void def_tex_output(StructRNA *srna) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index e8d5b2c6a39..284eaa8b70b 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -62,6 +62,7 @@ set(SRC composite/nodes/node_composite_cryptomatte.c composite/nodes/node_composite_curves.c composite/nodes/node_composite_defocus.c + composite/nodes/node_composite_denoise.c composite/nodes/node_composite_despeckle.c composite/nodes/node_composite_diffMatte.c composite/nodes/node_composite_dilate.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index e6d9ed6f70e..534e9012693 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -74,6 +74,7 @@ void register_node_type_cmp_dilateerode(void); void register_node_type_cmp_inpaint(void); void register_node_type_cmp_despeckle(void); void register_node_type_cmp_defocus(void); +void register_node_type_cmp_denoise(void); void register_node_type_cmp_valtorgb(void); void register_node_type_cmp_rgbtobw(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 796ad9e5d5b..c72e97642a2 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -216,6 +216,7 @@ DefNode(CompositorNode, CMP_NODE_PLANETRACKDEFORM,def_cmp_planetrackdeform,"PLAN DefNode(CompositorNode, CMP_NODE_CORNERPIN, 0, "CORNERPIN", CornerPin, "Corner Pin", "" ) DefNode(CompositorNode, CMP_NODE_SUNBEAMS, def_cmp_sunbeams, "SUNBEAMS", SunBeams, "Sun Beams", "" ) DefNode(CompositorNode, CMP_NODE_CRYPTOMATTE, def_cmp_cryptomatte, "CRYPTOMATTE", Cryptomatte, "Cryptomatte", "" ) +DefNode(CompositorNode, CMP_NODE_DENOISE, def_cmp_denoise, "DENOISE", Denoise, "Denoise", "" ) DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/composite/nodes/node_composite_denoise.c b/source/blender/nodes/composite/nodes/node_composite_denoise.c new file mode 100644 index 00000000000..e2fdb08816a --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_denoise.c @@ -0,0 +1,58 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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) 2019 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Stefan Werner + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_denoise.c + * \ingroup cmpnodes + */ + +#include "node_composite_util.h" + +static bNodeSocketTemplate cmp_node_denoise_in[] = { + {SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA, 1, N_("Albedo"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + {SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f}, + {-1, 0, ""}}; +static bNodeSocketTemplate cmp_node_denoise_out[] = {{SOCK_RGBA, 0, N_("Image")}, {-1, 0, ""}}; + +static void node_composit_init_denonise(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeDenoise *ndg = MEM_callocN(sizeof(NodeDenoise), "node denoise data"); + ndg->hdr = true; + node->storage = ndg; +} + +void register_node_type_cmp_denoise(void) +{ + static bNodeType ntype; + + cmp_node_type_base(&ntype, CMP_NODE_DENOISE, "Denoise", NODE_CLASS_OP_FILTER, 0); + node_type_socket_templates(&ntype, cmp_node_denoise_in, cmp_node_denoise_out); + node_type_init(&ntype, node_composit_init_denonise); + node_type_storage(&ntype, "NodeDenoise", node_free_standard_storage, node_copy_standard_storage); + + nodeRegisterType(&ntype); +} -- cgit v1.2.3 From 037cf920b42d9b3404687235c524516e50a31561 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Wed, 14 Aug 2019 22:54:23 +0200 Subject: Sculpt: mesh abstraction API These functions make possible porting the tools from the sculpt branch, making them compatible with PBVH_FACES and PBVH_BMESH without duplicating the code. They can also help to simplify some existing code. These functions should not be used when working with PBVH_GRIDS data in SculptSession. PBVH_GRIDS needs to be removed from the sculpt code and converted to PBVH_FACES to be compatible with this API. Reviewed By: brecht Differential Revision: https://developer.blender.org/D5352 --- source/blender/blenkernel/BKE_paint.h | 2 + source/blender/blenkernel/BKE_pbvh.h | 3 + source/blender/editors/sculpt_paint/sculpt.c | 229 +++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index cbe250d0ac8..37667599488 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -259,6 +259,8 @@ typedef struct SculptSession { struct StrokeCache *cache; + int active_vertex_index; + union { struct { struct SculptVertexPaintGeomMap gmap; diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 3806868e060..62544efad2c 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -301,6 +301,7 @@ typedef struct PBVHVertexIter { int gx; int gy; int i; + int index; /* grid */ struct CCGElem **grids; @@ -369,6 +370,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo continue; \ vi.co = vi.mvert->co; \ vi.no = vi.mvert->no; \ + vi.index = vi.vert_indices[vi.i]; \ if (vi.vmask) \ vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \ } \ @@ -385,6 +387,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo continue; \ vi.co = vi.bm_vert->co; \ vi.fno = vi.bm_vert->no; \ + vi.index = BM_elem_index_get(vi.bm_vert); \ vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \ } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index efaac6e97cf..cdd82b8ced3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -92,6 +92,235 @@ #include #include +/* Sculpt PBVH abstraction API */ + +/* Do not use these functions while working with PBVH_GRIDS data in SculptSession */ + +static int sculpt_active_vertex_get(SculptSession *ss) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + return ss->active_vertex_index; + case PBVH_BMESH: + return ss->active_vertex_index; + default: + return 0; + } +} + +static int sculpt_vertex_count_get(SculptSession *ss) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + return ss->totvert; + case PBVH_BMESH: + return BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT); + default: + return 0; + } +} + +static void sculpt_vertex_normal_get(SculptSession *ss, int index, float no[3]) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + normal_short_to_float_v3(no, ss->mvert[index].no); + return; + case PBVH_BMESH: + copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no); + default: + return; + } +} + +static float *sculpt_vertex_co_get(SculptSession *ss, int index) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + return ss->mvert[index].co; + case PBVH_BMESH: + return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co; + default: + return NULL; + } +} + +static void sculpt_vertex_co_set(SculptSession *ss, int index, float co[3]) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + copy_v3_v3(ss->mvert[index].co, co); + return; + case PBVH_BMESH: + copy_v3_v3(BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co, co); + return; + default: + return; + } +} + +static void sculpt_vertex_mask_set(SculptSession *ss, int index, float mask) +{ + BMVert *v; + float *mask_p; + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + ss->vmask[index] = mask; + return; + case PBVH_BMESH: + v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index); + mask_p = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK)); + *(mask_p) = mask; + return; + default: + return; + } +} + +static float sculpt_vertex_mask_get(SculptSession *ss, int index) +{ + BMVert *v; + float *mask; + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + return ss->vmask[index]; + case PBVH_BMESH: + v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index); + mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK)); + return *mask; + default: + return 0; + } +} + +static void sculpt_vertex_tag_update(SculptSession *ss, int index) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE; + return; + case PBVH_BMESH: + return; + default: + return; + } +} + +#define SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY 256 + +typedef struct SculptVertexNeighbourIter { + int *neighbours; + int size; + int capacity; + + int neighbours_fixed[SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY]; + + int index; + int i; +} SculptVertexNeighbourIter; + +static void sculpt_vertex_neighbour_add(SculptVertexNeighbourIter *iter, int neighbour_index) +{ + for (int i = 0; i < iter->size; i++) { + if (iter->neighbours[i] == neighbour_index) { + return; + } + } + + if (iter->size >= iter->capacity) { + iter->capacity += SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + + if (iter->neighbours == iter->neighbours_fixed) { + iter->neighbours = MEM_mallocN(iter->capacity * sizeof(int), "neighbour array"); + memcpy(iter->neighbours, iter->neighbours_fixed, sizeof(int) * iter->size); + } + else { + iter->neighbours = MEM_reallocN_id( + iter->neighbours, iter->capacity * sizeof(int), "neighbour array"); + } + } + + iter->neighbours[iter->size] = neighbour_index; + iter->size++; +} + +static void sculpt_vertex_neighbours_get_bmesh(SculptSession *ss, + int index, + SculptVertexNeighbourIter *iter) +{ + BMVert *v = BM_vert_at_index(ss->bm, index); + BMIter liter; + BMLoop *l; + iter->size = 0; + iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + iter->neighbours = iter->neighbours_fixed; + + int i = 0; + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + const BMVert *adj_v[2] = {l->prev->v, l->next->v}; + for (i = 0; i < ARRAY_SIZE(adj_v); i++) { + const BMVert *v_other = adj_v[i]; + if (BM_elem_index_get(v_other) != (int)index) { + sculpt_vertex_neighbour_add(iter, BM_elem_index_get(v_other)); + } + } + } +} + +static void sculpt_vertex_neighbours_get_faces(SculptSession *ss, + int index, + SculptVertexNeighbourIter *iter) +{ + int i; + MeshElemMap *vert_map = &ss->pmap[(int)index]; + iter->size = 0; + iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + iter->neighbours = iter->neighbours_fixed; + + for (i = 0; i < ss->pmap[(int)index].count; i++) { + const MPoly *p = &ss->mpoly[vert_map->indices[i]]; + unsigned f_adj_v[2]; + if (poly_get_adj_loops_from_vert(p, ss->mloop, (int)index, f_adj_v) != -1) { + int j; + for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { + if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) { + if (f_adj_v[j] != (int)index) { + sculpt_vertex_neighbour_add(iter, f_adj_v[j]); + } + } + } + } + } +} + +static void sculpt_vertex_neighbours_get(SculptSession *ss, + int index, + SculptVertexNeighbourIter *iter) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + sculpt_vertex_neighbours_get_faces(ss, index, iter); + return; + case PBVH_BMESH: + sculpt_vertex_neighbours_get_bmesh(ss, index, iter); + return; + default: + break; + } +} + +#define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \ + sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \ + for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.size; \ + neighbour_iterator.i++) { \ + neighbour_iterator.index = ni.neighbours[ni.i]; + +#define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \ + } \ + if (neighbour_iterator.neighbours != neighbour_iterator.neighbours_fixed) { \ + MEM_freeN(neighbour_iterator.neighbours); \ + } + /** \name Tool Capabilities * * Avoid duplicate checks, internal logic only, -- cgit v1.2.3 From 67f49f9c03c95eb3a62ece38db0ae8feafd4992e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Aug 2019 23:26:26 +0200 Subject: Cleanup: fix compiler warnings --- source/blender/blenkernel/intern/mesh_convert.c | 4 ++-- source/blender/editors/space_text/text_undo.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index ee060a117dc..3a2ba078dce 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -978,7 +978,7 @@ static void curve_to_mesh_eval_ensure(Object *object) * * So we create temporary copy of the object which will use same data as the original bevel, but * will have no modifiers. */ - Object bevel_object = {NULL}; + Object bevel_object = {{NULL}}; if (remapped_curve.bevobj != NULL) { bevel_object = *remapped_curve.bevobj; BLI_listbase_clear(&bevel_object.modifiers); @@ -986,7 +986,7 @@ static void curve_to_mesh_eval_ensure(Object *object) } /* Same thing for taper. */ - Object taper_object = {NULL}; + Object taper_object = {{NULL}}; if (remapped_curve.taperobj != NULL) { taper_object = *remapped_curve.taperobj; BLI_listbase_clear(&taper_object.modifiers); diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.c index a6393291f9a..4a628cf70e4 100644 --- a/source/blender/editors/space_text/text_undo.c +++ b/source/blender/editors/space_text/text_undo.c @@ -187,6 +187,7 @@ static bool text_undosys_step_encode(struct bContext *C, Text *text = us->text_ref.ptr; BLI_assert(text == CTX_data_edit_text(C)); + UNUSED_VARS_NDEBUG(C); us->step.data_size += text_undosys_step_encode_to_state(&us->states[1], text); -- cgit v1.2.3 From deb5416a1a50e153cf2f9e3809755a5e82bd8f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 14 Aug 2019 22:18:47 +0200 Subject: GPU: Vertex Format: ADd function for safe GLSL attrib name This remove code duplication and use base63 encoding of the hash. Use mumur hash to have more randomness. --- .../blender/draw/intern/draw_cache_extract_mesh.c | 43 ++++++--------- source/blender/draw/intern/draw_cache_impl_mesh.c | 16 +++--- source/blender/gpu/GPU_shader.h | 4 +- source/blender/gpu/GPU_vertex_format.h | 12 +++-- source/blender/gpu/intern/gpu_codegen.c | 20 ++++--- source/blender/gpu/intern/gpu_vertex_format.c | 63 ++++++++++++++++++++-- 6 files changed, 108 insertions(+), 50 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index f9d6c9ed582..ea1813464c3 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -1570,23 +1570,17 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) bool orco_allocated = false; const bool use_orco_tan = mr->cache->cd_used.tan_orco != 0; - /* XXX FIXME XXX */ - /* We use a hash to identify each data layer based on its name. - * Gawain then search for this name in the current shader and bind if it exists. - * NOTE : This is prone to hash collision. - * One solution to hash collision would be to format the cd layer name - * to a safe glsl var name, but without name clash. - * NOTE 2 : Replicate changes to code_generate_vertex_new() in gpu_codegen.c */ for (int i = 0; i < MAX_MTFACE; i++) { if (uv_layers & (1 << i)) { - char attr_name[32]; + char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i); - uint hash = BLI_ghashutil_strhash_p(layer_name); + + GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME); /* UV layer name. */ - BLI_snprintf(attr_name, sizeof(attr_name), "u%u", hash); + BLI_snprintf(attr_name, sizeof(attr_name), "u%s", attr_safe_name); GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* Auto layer name. */ - BLI_snprintf(attr_name, sizeof(attr_name), "a%u", hash); + BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name); GPU_vertformat_alias_add(&format, attr_name); /* Active render layer name. */ if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) { @@ -1610,11 +1604,11 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) for (int i = 0; i < MAX_MTFACE; i++) { if (tan_layers & (1 << i)) { - char attr_name[32]; + char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i); - uint hash = BLI_ghashutil_strhash_p(layer_name); + GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME); /* Tangent layer name. */ - BLI_snprintf(attr_name, sizeof(attr_name), "t%u", hash); + BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name); GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT); /* Active render layer name. */ if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) { @@ -1687,10 +1681,10 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) } if (use_orco_tan) { - char attr_name[32]; + char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_TANGENT, 0); - uint hash = BLI_ghashutil_strhash_p(layer_name); - BLI_snprintf(attr_name, sizeof(*attr_name), "t%u", hash); + GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME); + BLI_snprintf(attr_name, sizeof(*attr_name), "t%s", attr_safe_name); GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPU_vertformat_alias_add(&format, "t"); GPU_vertformat_alias_add(&format, "at"); @@ -1779,20 +1773,13 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf) CustomData *cd_ldata = &mr->me->ldata; uint32_t vcol_layers = mr->cache->cd_used.vcol; - /* XXX FIXME XXX */ - /* We use a hash to identify each data layer based on its name. - * Gawain then search for this name in the current shader and bind if it exists. - * NOTE : This is prone to hash collision. - * One solution to hash collision would be to format the cd layer name - * to a safe glsl var name, but without name clash. - * NOTE 2 : Replicate changes to code_generate_vertex_new() in gpu_codegen.c */ for (int i = 0; i < 8; i++) { if (vcol_layers & (1 << i)) { - char attr_name[32]; + char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i); - uint hash = BLI_ghashutil_strhash_p(layer_name); + GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME); - BLI_snprintf(attr_name, sizeof(attr_name), "c%u", hash); + BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name); GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPCOL)) { @@ -1804,7 +1791,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf) /* Gather number of auto layers. */ /* We only do vcols that are not overridden by uvs */ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) { - BLI_snprintf(attr_name, sizeof(attr_name), "a%u", hash); + BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name); GPU_vertformat_alias_add(&format, attr_name); } } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index f498771b596..b23dac838e6 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -244,10 +244,12 @@ static void mesh_cd_extract_auto_layers_names_and_srgb(Mesh *me, for (int i = 0; i < uv_len; i++) { if ((cd_used.uv & (1 << i)) != 0) { const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i); - uint hash = BLI_ghashutil_strhash_p(name); + char safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; + GPU_vertformat_safe_attrib_name(name, safe_name, GPU_MAX_SAFE_ATTRIB_NAME); + auto_ofs += BLI_snprintf_rlen( + auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%s", safe_name); /* +1 to include '\0' terminator. */ - auto_ofs += 1 + BLI_snprintf_rlen( - auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash); + auto_ofs += 1; } } @@ -257,10 +259,12 @@ static void mesh_cd_extract_auto_layers_names_and_srgb(Mesh *me, const char *name = CustomData_get_layer_name(cd_ldata, CD_MLOOPCOL, i); /* We only do vcols that are not overridden by a uv layer with same name. */ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, name) == -1) { - uint hash = BLI_ghashutil_strhash_p(name); + char safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; + GPU_vertformat_safe_attrib_name(name, safe_name, GPU_MAX_SAFE_ATTRIB_NAME); + auto_ofs += BLI_snprintf_rlen( + auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%s", safe_name); /* +1 to include '\0' terminator. */ - auto_ofs += 1 + BLI_snprintf_rlen( - auto_names + auto_ofs, auto_names_len - auto_ofs, "ba%u", hash); + auto_ofs += 1; auto_is_srgb[auto_is_srgb_ofs] = true; auto_is_srgb_ofs++; } diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 124f1f1ff8a..f4a94c7759a 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -396,7 +396,9 @@ void GPU_shader_free_builtin_shaders(void); /* Vertex attributes for shaders */ -#define GPU_MAX_ATTR 32 +/* Hardware limit is 16. Position attribute is always needed so we reduce to 15. + * This makes sure the GPUVertexFormat name buffer does not overflow. */ +#define GPU_MAX_ATTR 15 typedef struct GPUVertAttrLayers { struct { diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index fc468436499..97c1828b593 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -32,8 +32,10 @@ #define GPU_VERT_ATTR_MAX_LEN 16 #define GPU_VERT_ATTR_MAX_NAMES 6 -#define GPU_VERT_ATTR_NAME_AVERAGE_LEN 11 -#define GPU_VERT_ATTR_NAMES_BUF_LEN ((GPU_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GPU_VERT_ATTR_MAX_LEN) +#define GPU_VERT_ATTR_NAMES_BUF_LEN 256 +#define GPU_VERT_FORMAT_MAX_NAMES 63 /* More than enough, actual max is ~30. */ +/* Computed as GPU_VERT_ATTR_NAMES_BUF_LEN / 30 (actual max format name). */ +#define GPU_MAX_SAFE_ATTRIB_NAME 8 typedef enum { GPU_COMP_I8, @@ -80,8 +82,8 @@ BLI_STATIC_ASSERT(GPU_VERT_ATTR_NAMES_BUF_LEN <= 256, typedef struct GPUVertFormat { /** 0 to 16 (GPU_VERT_ATTR_MAX_LEN). */ uint attr_len : 5; - /** Total count of active vertex attribute. */ - uint name_len : 5; + /** Total count of active vertex attribute names. (max GPU_VERT_FORMAT_MAX_NAMES) */ + uint name_len : 6; /** Stride in bytes, 1 to 1024. */ uint stride : 11; /** Has the format been packed. */ @@ -117,6 +119,8 @@ BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format, return format->names + attr->names[n_idx]; } +void GPU_vertformat_safe_attrib_name(const char *attrib_name, char *r_safe_name, uint max_len); + /* format conversion */ typedef struct GPUPackedNormal { diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 3e635b3198a..0e15fdd000b 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -46,6 +46,7 @@ #include "GPU_shader.h" #include "GPU_texture.h" #include "GPU_uniformbuffer.h" +#include "GPU_vertex_format.h" #include "BLI_sys_types.h" /* for intptr_t support */ @@ -1011,19 +1012,24 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u ds, "#define att%d %s\n", input->attr_id, attr_prefix_get(input->attr_type)); } else { - uint hash = BLI_ghashutil_strhash_p(input->attr_name); + char attr_safe_name[GPU_MAX_SAFE_ATTRIB_NAME]; + GPU_vertformat_safe_attrib_name( + input->attr_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME); BLI_dynstr_appendf(ds, - "DEFINE_ATTR(%s, %s%u);\n", + "DEFINE_ATTR(%s, %s%s);\n", GPU_DATATYPE_STR[input->type], attr_prefix_get(input->attr_type), - hash); - BLI_dynstr_appendf( - ds, "#define att%d %s%u\n", input->attr_id, attr_prefix_get(input->attr_type), hash); + attr_safe_name); + BLI_dynstr_appendf(ds, + "#define att%d %s%s\n", + input->attr_id, + attr_prefix_get(input->attr_type), + attr_safe_name); /* Auto attribute can be vertex color byte buffer. * We need to know and convert them to linear space in VS. */ if (input->attr_type == CD_AUTO_FROM_NAME) { - BLI_dynstr_appendf(ds, "uniform bool ba%u;\n", hash); - BLI_dynstr_appendf(ds, "#define att%d_is_srgb ba%u\n", input->attr_id, hash); + BLI_dynstr_appendf(ds, "uniform bool ba%s;\n", attr_safe_name); + BLI_dynstr_appendf(ds, "#define att%d_is_srgb ba%s\n", input->attr_id, attr_safe_name); } } BLI_dynstr_appendf(ds, diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index f672d350afa..2cfb17b1568 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -31,6 +31,8 @@ #include #include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BLI_ghash.h" #define PACK_DEBUG 0 @@ -149,9 +151,9 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format, GPUVertFetchMode fetch_mode) { #if TRUST_NO_ONE - assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(format->attr_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(!format->packed); /* packed means frozen/locked */ + assert(format->name_len < GPU_VERT_FORMAT_MAX_NAMES); /* there's room for more */ + assert(format->attr_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(!format->packed); /* packed means frozen/locked */ assert((comp_len >= 1 && comp_len <= 4) || comp_len == 8 || comp_len == 12 || comp_len == 16); switch (comp_type) { @@ -197,7 +199,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias) { GPUVertAttr *attr = &format->attrs[format->attr_len - 1]; #if TRUST_NO_ONE - assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(format->name_len < GPU_VERT_FORMAT_MAX_NAMES); /* there's room for more */ assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES); #endif format->name_len++; /* multiname support */ @@ -218,6 +220,59 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name) return -1; } +/* Encode 4 original bytes into 6 safe bytes. */ +static void safe_bytes(char out[6], const char data[4]) +{ + char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + + uint32_t in = *(uint32_t *)data; + for (int i = 0; i < 6; i++) { + /* Encoding in base63 */ + out[i] = safe_chars[in % 63u]; + in /= 63u; + } +} + +#if 0 /* For when we can use 11chars names. */ +/* Encode 8 original bytes into 11 safe bytes. */ +static void safe_bytes(char out[11], const char data[8]) +{ + char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + + uint64_t in = *(uint64_t *)data; + for (int i = 0; i < 11; i++) { + /* Encoding in base63 */ + out[i] = safe_chars[in % 63lu]; + in /= 63lu; + } +} +#endif + +/* Warning: Always add a prefix to the result of this function as + * the generated string can start with a number and not be a valid attribute name. */ +void GPU_vertformat_safe_attrib_name(const char *attrib_name, + char *r_safe_name, + uint UNUSED(max_len)) +{ + char data[4] = {0}; + /* We use a hash to identify each data layer based on its name. + * NOTE: This is still prone to hash collision but the risks are very low.*/ + *(uint *)data = BLI_ghashutil_strhash_p_murmur(attrib_name); + /* Convert to safe bytes characters. */ + safe_bytes(r_safe_name, data); + /* End the string */ + r_safe_name[6] = '\0'; + + /* TOOD(fclem) When UV and Tangent buffers will be separated, name buffer will have plenty more + * space. In this case, we can think of having ~13 chars for each name which would be enough to + * encode some of the input string along with the hash to reduce colision possibility. */ + + BLI_assert(GPU_MAX_SAFE_ATTRIB_NAME >= 7); +#if 0 /* For debugging */ + printf("%s > %x > %s\n", attrib_name, *(uint32_t *)data, r_safe_name); +#endif +} + /* Make attribute layout non-interleaved. * Warning! This does not change data layout! * Use direct buffer access to fill the data. -- cgit v1.2.3 From 80e9eb66d568311f4acddf5dfe5bbf8f8618f18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 14 Aug 2019 22:43:44 +0200 Subject: Mesh Batch Cache: Split UV an tangent into 2 distinct VBOs This is done because they don't have the same update frequency. UV can be persistent even on geometry update (ex: skinned object) but tangents can change if the normals change. Also the name buffer per vbo was too small to contain all names. --- source/blender/draw/intern/draw_cache_extract.h | 3 +- .../blender/draw/intern/draw_cache_extract_mesh.c | 125 +++++++++++++-------- source/blender/draw/intern/draw_cache_impl_mesh.c | 37 +++--- source/blender/gpu/GPU_batch.h | 2 +- 4 files changed, 102 insertions(+), 65 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 5a06210fe8e..9305dc6eef7 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -86,7 +86,8 @@ typedef struct MeshBufferCache { GPUVertBuf *lnor; /* extend */ GPUVertBuf *edge_fac; /* extend */ GPUVertBuf *weights; /* extend */ - GPUVertBuf *uv_tan; + GPUVertBuf *uv; + GPUVertBuf *tan; GPUVertBuf *vcol; GPUVertBuf *orco; /* Only for edit mode. */ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index ea1813464c3..95b984747bd 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -1554,21 +1554,16 @@ const MeshExtract extract_lnor = {extract_lnor_init, /** \} */ /* ---------------------------------------------------------------------- */ -/** \name Extract UV / Tangent layers +/** \name Extract UV layers * \{ */ -static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) +static void *extract_uv_init(const MeshRenderData *mr, void *buf) { GPUVertFormat format = {0}; GPU_vertformat_deinterleave(&format); CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; - CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata; uint32_t uv_layers = mr->cache->cd_used.uv; - uint32_t tan_layers = mr->cache->cd_used.tan; - float(*orco)[3] = CustomData_get_layer(cd_vdata, CD_ORCO); - bool orco_allocated = false; - const bool use_orco_tan = mr->cache->cd_used.tan_orco != 0; for (int i = 0; i < MAX_MTFACE; i++) { if (uv_layers & (1 << i)) { @@ -1599,6 +1594,65 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) } } + int v_len = mr->loop_len; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + /* VBO will not be used, only allocate minimum of memory. */ + v_len = 1; + } + + GPUVertBuf *vbo = buf; + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, v_len); + + float(*uv_data)[2] = (float(*)[2])vbo->data; + for (int i = 0; i < MAX_MTFACE; i++) { + if (uv_layers & (1 << i)) { + if (mr->extract_type == MR_EXTRACT_BMESH) { + int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_MLOOPUV, i); + BMIter f_iter, l_iter; + BMFace *efa; + BMLoop *loop; + BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (loop, &l_iter, efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, cd_ofs); + memcpy(uv_data, luv->uv, sizeof(*uv_data)); + uv_data++; + } + } + } + else { + MLoopUV *layer_data = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i); + for (int l = 0; l < mr->loop_len; l++, uv_data++, layer_data++) { + memcpy(uv_data, layer_data->uv, sizeof(*uv_data)); + } + } + } + } + + return NULL; +} + +const MeshExtract extract_uv = { + extract_uv_init, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, false}; +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Extract Tangent layers + * \{ */ + +static void *extract_tan_init(const MeshRenderData *mr, void *buf) +{ + GPUVertFormat format = {0}; + GPU_vertformat_deinterleave(&format); + + CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; + CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata; + uint32_t tan_layers = mr->cache->cd_used.tan; + float(*orco)[3] = CustomData_get_layer(cd_vdata, CD_ORCO); + bool orco_allocated = false; + const bool use_orco_tan = mr->cache->cd_used.tan_orco != 0; + int tan_len = 0; char tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME]; @@ -1705,32 +1759,7 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) GPU_vertbuf_init_with_format(vbo, &format); GPU_vertbuf_data_alloc(vbo, v_len); - float(*uv_data)[2] = (float(*)[2])vbo->data; - for (int i = 0; i < MAX_MTFACE; i++) { - if (uv_layers & (1 << i)) { - if (mr->extract_type == MR_EXTRACT_BMESH) { - int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_MLOOPUV, i); - BMIter f_iter, l_iter; - BMFace *efa; - BMLoop *loop; - BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (loop, &l_iter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, cd_ofs); - memcpy(uv_data, luv->uv, sizeof(*uv_data)); - uv_data++; - } - } - } - else { - MLoopUV *layer_data = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i); - for (int l = 0; l < mr->loop_len; l++, uv_data++, layer_data++) { - memcpy(uv_data, layer_data->uv, sizeof(*uv_data)); - } - } - } - } - /* Start tan_data after uv_data. */ - float(*tan_data)[4] = (float(*)[4])uv_data; + float(*tan_data)[4] = (float(*)[4])vbo->data; for (int i = 0; i < tan_len; i++) { void *layer_data = CustomData_get_layer_named(cd_ldata, CD_TANGENT, tangent_names[i]); memcpy(tan_data, layer_data, sizeof(*tan_data) * mr->loop_len); @@ -1746,18 +1775,18 @@ static void *extract_uv_tan_init(const MeshRenderData *mr, void *buf) return NULL; } -const MeshExtract extract_uv_tan = {extract_uv_tan_init, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI, - false}; +const MeshExtract extract_tan = {extract_tan_init, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI, + false}; /** \} */ @@ -4149,7 +4178,8 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, TEST_ASSIGN(VBO, vbo, pos_nor); TEST_ASSIGN(VBO, vbo, lnor); - TEST_ASSIGN(VBO, vbo, uv_tan); + TEST_ASSIGN(VBO, vbo, uv); + TEST_ASSIGN(VBO, vbo, tan); TEST_ASSIGN(VBO, vbo, vcol); TEST_ASSIGN(VBO, vbo, orco); TEST_ASSIGN(VBO, vbo, edge_fac); @@ -4214,7 +4244,8 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, EXTRACT(vbo, pos_nor); EXTRACT(vbo, lnor); - EXTRACT(vbo, uv_tan); + EXTRACT(vbo, uv); + EXTRACT(vbo, tan); EXTRACT(vbo, vcol); EXTRACT(vbo, orco); EXTRACT(vbo, edge_fac); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index b23dac838e6..8c89ac4703c 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -464,7 +464,8 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) FOREACH_MESH_BUFFER_CACHE(cache, mbufcache) { GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor); - GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv_tan); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.tan); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.vcol); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.orco); } @@ -492,7 +493,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache) { GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.stretch_angle); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.stretch_area); - GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv_tan); + GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.edituv_data); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_uv); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_edituv_data); @@ -1013,10 +1014,12 @@ void DRW_mesh_batch_cache_create_requested( if (cd_overlap == false) { FOREACH_MESH_BUFFER_CACHE(cache, mbuffercache) { - if ((cache->cd_used.uv & cache->cd_needed.uv) != cache->cd_needed.uv || - (cache->cd_used.tan & cache->cd_needed.tan) != cache->cd_needed.tan || + if ((cache->cd_used.uv & cache->cd_needed.uv) != cache->cd_needed.uv) { + GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.uv); + } + if ((cache->cd_used.tan & cache->cd_needed.tan) != cache->cd_needed.tan || cache->cd_used.tan_orco != cache->cd_needed.tan_orco) { - GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.uv_tan); + GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.tan); } if (cache->cd_used.orco != cache->cd_needed.orco) { GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.orco); @@ -1050,7 +1053,7 @@ void DRW_mesh_batch_cache_create_requested( GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.edituv_data); GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.stretch_angle); GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.stretch_area); - GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.uv_tan); + GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.uv); GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.fdots_uv); GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_tris); GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_lines); @@ -1094,7 +1097,7 @@ void DRW_mesh_batch_cache_create_requested( DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.lnor); DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.pos_nor); if (cache->cd_used.uv != 0) { - DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.uv); } if (cache->cd_used.vcol != 0) { DRW_vbo_request(cache->batch.surface, &mbufcache->vbo.vcol); @@ -1133,7 +1136,7 @@ void DRW_mesh_batch_cache_create_requested( DRW_ibo_request(cache->batch.wire_loops_uvs, &mbufcache->ibo.edituv_lines); /* For paint overlay. Active layer should have been queried. */ if (cache->cd_used.uv != 0) { - DRW_vbo_request(cache->batch.wire_loops_uvs, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.wire_loops_uvs, &mbufcache->vbo.uv); } } if (DRW_batch_requested(cache->batch.edit_mesh_analysis, GPU_PRIM_TRIS)) { @@ -1149,9 +1152,11 @@ void DRW_mesh_batch_cache_create_requested( /* Order matters. First ones override latest vbos' attribs. */ DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.lnor); DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.pos_nor); - if ((cache->cd_used.uv != 0) || (cache->cd_used.tan != 0) || - (cache->cd_used.tan_orco != 0)) { - DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.uv_tan); + if (cache->cd_used.uv != 0) { + DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.uv); + } + if ((cache->cd_used.tan != 0) || (cache->cd_used.tan_orco != 0)) { + DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.tan); } if (cache->cd_used.vcol != 0) { DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.vcol); @@ -1227,29 +1232,29 @@ void DRW_mesh_batch_cache_create_requested( /* Edit UV */ if (DRW_batch_requested(cache->batch.edituv_faces, GPU_PRIM_TRIS)) { DRW_ibo_request(cache->batch.edituv_faces, &mbufcache->ibo.edituv_tris); - DRW_vbo_request(cache->batch.edituv_faces, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.edituv_faces, &mbufcache->vbo.uv); DRW_vbo_request(cache->batch.edituv_faces, &mbufcache->vbo.edituv_data); } if (DRW_batch_requested(cache->batch.edituv_faces_strech_area, GPU_PRIM_TRIS)) { DRW_ibo_request(cache->batch.edituv_faces_strech_area, &mbufcache->ibo.edituv_tris); - DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.uv); DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.edituv_data); DRW_vbo_request(cache->batch.edituv_faces_strech_area, &mbufcache->vbo.stretch_area); } if (DRW_batch_requested(cache->batch.edituv_faces_strech_angle, GPU_PRIM_TRIS)) { DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->ibo.edituv_tris); - DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.uv); DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.edituv_data); DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &mbufcache->vbo.stretch_angle); } if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) { DRW_ibo_request(cache->batch.edituv_edges, &mbufcache->ibo.edituv_lines); - DRW_vbo_request(cache->batch.edituv_edges, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.edituv_edges, &mbufcache->vbo.uv); DRW_vbo_request(cache->batch.edituv_edges, &mbufcache->vbo.edituv_data); } if (DRW_batch_requested(cache->batch.edituv_verts, GPU_PRIM_POINTS)) { DRW_ibo_request(cache->batch.edituv_verts, &mbufcache->ibo.edituv_points); - DRW_vbo_request(cache->batch.edituv_verts, &mbufcache->vbo.uv_tan); + DRW_vbo_request(cache->batch.edituv_verts, &mbufcache->vbo.uv); DRW_vbo_request(cache->batch.edituv_verts, &mbufcache->vbo.edituv_data); } if (DRW_batch_requested(cache->batch.edituv_fdots, GPU_PRIM_POINTS)) { diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index c65ca5d905e..175033f70d9 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -40,7 +40,7 @@ typedef enum { GPU_BATCH_READY_TO_DRAW, } GPUBatchPhase; -#define GPU_BATCH_VBO_MAX_LEN 5 +#define GPU_BATCH_VBO_MAX_LEN 6 #define GPU_BATCH_VAO_STATIC_LEN 3 #define GPU_BATCH_VAO_DYN_ALLOC_COUNT 16 -- cgit v1.2.3 From 6fcd071c7bcb8c9a5e0a7d0e7a6ef6363e43627e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 14 Aug 2019 23:43:03 +0200 Subject: GPU: Vertex Format: Increase number of byte per attribute name This reduces the risks of hash collision while maintaining a small number of character per attrib. --- source/blender/gpu/GPU_vertex_format.h | 2 +- source/blender/gpu/intern/gpu_vertex_format.c | 49 +++++++++++++-------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index 97c1828b593..8c22e3e1104 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -35,7 +35,7 @@ #define GPU_VERT_ATTR_NAMES_BUF_LEN 256 #define GPU_VERT_FORMAT_MAX_NAMES 63 /* More than enough, actual max is ~30. */ /* Computed as GPU_VERT_ATTR_NAMES_BUF_LEN / 30 (actual max format name). */ -#define GPU_MAX_SAFE_ATTRIB_NAME 8 +#define GPU_MAX_SAFE_ATTRIB_NAME 12 typedef enum { GPU_COMP_I8, diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index 2cfb17b1568..11df86c0b3a 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -220,20 +220,6 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name) return -1; } -/* Encode 4 original bytes into 6 safe bytes. */ -static void safe_bytes(char out[6], const char data[4]) -{ - char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; - - uint32_t in = *(uint32_t *)data; - for (int i = 0; i < 6; i++) { - /* Encoding in base63 */ - out[i] = safe_chars[in % 63u]; - in /= 63u; - } -} - -#if 0 /* For when we can use 11chars names. */ /* Encode 8 original bytes into 11 safe bytes. */ static void safe_bytes(char out[11], const char data[8]) { @@ -246,7 +232,6 @@ static void safe_bytes(char out[11], const char data[8]) in /= 63lu; } } -#endif /* Warning: Always add a prefix to the result of this function as * the generated string can start with a number and not be a valid attribute name. */ @@ -254,22 +239,34 @@ void GPU_vertformat_safe_attrib_name(const char *attrib_name, char *r_safe_name, uint UNUSED(max_len)) { - char data[4] = {0}; - /* We use a hash to identify each data layer based on its name. - * NOTE: This is still prone to hash collision but the risks are very low.*/ - *(uint *)data = BLI_ghashutil_strhash_p_murmur(attrib_name); + char data[8] = {0}; + uint len = strlen(attrib_name); + + if (len > 8) { + /* Start with the first 4 chars of the name; */ + for (int i = 0; i < 4; i++) { + data[i] = attrib_name[i]; + } + /* We use a hash to identify each data layer based on its name. + * NOTE: This is still prone to hash collision but the risks are very low.*/ + /* Start hashing after the first 2 chars. */ + *(uint *)&data[4] = BLI_ghashutil_strhash_p_murmur(attrib_name + 4); + } + else { + /* Copy the whole name. Collision is barelly possible + * (hash would have to be equal to the last 4 bytes). */ + for (int i = 0; i < 8 && attrib_name[i] != '\0'; i++) { + data[i] = attrib_name[i]; + } + } /* Convert to safe bytes characters. */ safe_bytes(r_safe_name, data); /* End the string */ - r_safe_name[6] = '\0'; - - /* TOOD(fclem) When UV and Tangent buffers will be separated, name buffer will have plenty more - * space. In this case, we can think of having ~13 chars for each name which would be enough to - * encode some of the input string along with the hash to reduce colision possibility. */ + r_safe_name[11] = '\0'; - BLI_assert(GPU_MAX_SAFE_ATTRIB_NAME >= 7); + BLI_assert(GPU_MAX_SAFE_ATTRIB_NAME >= 12); #if 0 /* For debugging */ - printf("%s > %x > %s\n", attrib_name, *(uint32_t *)data, r_safe_name); + printf("%s > %lx > %s\n", attrib_name, *(uint64_t *)data, r_safe_name); #endif } -- cgit v1.2.3 From 5ff8fcfa7241e2b15c6ac110538f40e277db3f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 14 Aug 2019 23:43:33 +0200 Subject: Eevee: Fix tangent map node not using the right UVMap --- source/blender/nodes/shader/nodes/node_shader_tangent.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c index 6795f48edb3..478b9524737 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tangent.c +++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c @@ -42,7 +42,8 @@ static int node_shader_gpu_tangent(GPUMaterial *mat, NodeShaderTangent *attr = node->storage; if (attr->direction_type == SHD_TANGENT_UVMAP) { - return GPU_stack_link(mat, node, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, "")); + return GPU_stack_link( + mat, node, "node_tangentmap", in, out, GPU_attribute(CD_TANGENT, attr->uv_map)); } else { GPUNodeLink *orco = GPU_attribute(CD_ORCO, ""); -- cgit v1.2.3 From cb7ead2e3b62b9f1df85c985801db7918204dd2a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 14 Aug 2019 15:08:25 -0300 Subject: Fix T68658: Text offset makes scale to fit not to work Differential Revision: https://developer.blender.org/D5484 --- source/blender/blenkernel/intern/font.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 78117a4f615..b55635560be 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -955,7 +955,7 @@ static bool vfont_to_curve(Object *ob, } } - current_line_length += xof; + current_line_length += xof - MARGIN_X_MIN; if (ct->dobreak) { current_line_length += twidth; } @@ -1026,7 +1026,7 @@ static bool vfont_to_curve(Object *ob, } ct++; } - current_line_length += xof + twidth; + current_line_length += xof + twidth - MARGIN_X_MIN; longest_line_length = MAX2(current_line_length, longest_line_length); cu->lines = 1; -- cgit v1.2.3 From f4d548d384e20ef377b2573a6c54a2434c3f9134 Mon Sep 17 00:00:00 2001 From: Lazydodo Date: Wed, 14 Aug 2019 17:57:01 -0600 Subject: msvc: Enable /bigobj on all object files. bf_intern_openvdb makes a significant number of template instantiations causing it go over the maximum number of sections (int16) in a coff file when doing a debug build. This change switches the compiler to use the extended coff format which has this field extended (int32) all linkers post msvc2005 can process this format so there's no reason not to turn this on globally. Clang on windows does not need this change since clang switches implicitly to the extended format when required. [1] [1] https://reviews.llvm.org/rL217812 --- build_files/cmake/platform/platform_win32.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 208521a9e65..80097e6c84f 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -131,8 +131,8 @@ if(MSVC_CLANG) # Clangs version of cl doesn't support all flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /nologo /J /Gd /MP /EHsc") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /nologo /J /Gd /MP /EHsc /bigobj") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj") endif() set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") @@ -349,7 +349,7 @@ if(WITH_PYTHON) string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) set(PYTHON_LIBRARY ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.lib) set(PYTHON_LIBRARY_DEBUG ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}_d.lib) - + set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/include) set(PYTHON_NUMPY_INCLUDE_DIRS ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib/site-packages/numpy/core/include) set(NUMPY_FOUND On) @@ -490,7 +490,7 @@ if(WITH_OPENIMAGEDENOISE) set(OPENIMAGEDENOISE ${LIBDIR}/OpenImageDenoise) set(OPENIMAGEDENOISE_LIBPATH ${LIBDIR}/OpenImageDenoise/lib) set(OPENIMAGEDENOISE_INCLUDE_DIRS ${OPENIMAGEDENOISE}/include ${TBB_INCLUDE_DIR}) - set(OPENIMAGEDENOISE_LIBRARIES + set(OPENIMAGEDENOISE_LIBRARIES optimized ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise.lib ${OPENIMAGEDENOISE_LIBPATH}/common.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn.lib debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn_d.lib ${TBB_LIBRARIES}) -- cgit v1.2.3 From 7c258a8ad1b04a91d24b015fed6c5eae020bf8cc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 05:13:20 +1000 Subject: Mesh: bypass legacy tessface conversion step when remeshing --- .../blender/blenkernel/intern/mesh_remesh_voxel.c | 44 ++++++++++++---------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.c b/source/blender/blenkernel/intern/mesh_remesh_voxel.c index 17347842216..a5136311a22 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.c +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.c @@ -101,34 +101,38 @@ Mesh *BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *l level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles); # endif - Mesh *mesh = BKE_mesh_new_nomain( - output_mesh.totvertices, 0, output_mesh.totquads + output_mesh.tottriangles, 0, 0); - int q = output_mesh.totquads; + Mesh *mesh = BKE_mesh_new_nomain(output_mesh.totvertices, + 0, + 0, + (output_mesh.totquads * 4) + (output_mesh.tottriangles * 3), + output_mesh.totquads + output_mesh.tottriangles); for (int i = 0; i < output_mesh.totvertices; i++) { - float vco[3] = {output_mesh.vertices[i * 3], - output_mesh.vertices[i * 3 + 1], - output_mesh.vertices[i * 3 + 2]}; - copy_v3_v3(mesh->mvert[i].co, vco); + copy_v3_v3(mesh->mvert[i].co, &output_mesh.vertices[i * 3]); } - for (int i = 0; i < output_mesh.totquads; i++) { - mesh->mface[i].v4 = output_mesh.quads[i * 4]; - mesh->mface[i].v3 = output_mesh.quads[i * 4 + 1]; - mesh->mface[i].v2 = output_mesh.quads[i * 4 + 2]; - mesh->mface[i].v1 = output_mesh.quads[i * 4 + 3]; + MPoly *mp = mesh->mpoly; + MLoop *ml = mesh->mloop; + for (int i = 0; i < output_mesh.totquads; i++, mp++, ml += 4) { + mp->loopstart = (int)(ml - mesh->mloop); + mp->totloop = 4; + + ml[0].v = output_mesh.quads[i * 4 + 3]; + ml[1].v = output_mesh.quads[i * 4 + 2]; + ml[2].v = output_mesh.quads[i * 4 + 1]; + ml[3].v = output_mesh.quads[i * 4]; } - for (int i = 0; i < output_mesh.tottriangles; i++) { - mesh->mface[i + q].v4 = 0; - mesh->mface[i + q].v3 = output_mesh.triangles[i * 3]; - mesh->mface[i + q].v2 = output_mesh.triangles[i * 3 + 1]; - mesh->mface[i + q].v1 = output_mesh.triangles[i * 3 + 2]; + for (int i = 0; i < output_mesh.tottriangles; i++, mp++, ml += 3) { + mp->loopstart = (int)(ml - mesh->mloop); + mp->totloop = 3; + + ml[0].v = output_mesh.triangles[i * 3 + 2]; + ml[1].v = output_mesh.triangles[i * 3 + 1]; + ml[2].v = output_mesh.triangles[i * 3]; } - BKE_mesh_calc_edges_tessface(mesh); - BKE_mesh_convert_mfaces_to_mpolys(mesh); - BKE_mesh_tessface_clear(mesh); + BKE_mesh_calc_edges(mesh, false, false); BKE_mesh_calc_normals(mesh); MEM_freeN(output_mesh.quads); -- cgit v1.2.3 From bb2394a29889157a330bd1064d248c04055b117c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 15:53:11 +1000 Subject: Fix T68014: Add-on's override Python built-in modules Append addon paths to the sys.path to avoid name collisions with system modules. --- release/scripts/modules/addon_utils.py | 2 +- release/scripts/modules/bpy/utils/__init__.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 70768a102b3..376193f73a5 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -42,7 +42,7 @@ addons_fake_modules = {} def _initialize(): path_list = paths() for path in path_list: - _bpy.utils._sys_path_ensure(path) + _bpy.utils._sys_path_ensure_append(path) for addon in _preferences.addons: enable(addon.module) diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index b39099158c6..04aaa7bd69d 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -119,11 +119,17 @@ def _test_import(module_name, loaded_modules): return mod -def _sys_path_ensure(path): - if path not in _sys.path: # reloading would add twice +# Reloading would add twice. +def _sys_path_ensure_prepend(path): + if path not in _sys.path: _sys.path.insert(0, path) +def _sys_path_ensure_append(path): + if path not in _sys.path: + _sys.path.append(path) + + def modules_from_path(path, loaded_modules): """ Load all modules in a path and return them as a list. @@ -253,7 +259,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): for path_subdir in _script_module_dirs: path = _os.path.join(base_path, path_subdir) if _os.path.isdir(path): - _sys_path_ensure(path) + _sys_path_ensure_prepend(path) # Only add to 'sys.modules' unless this is 'startup'. if path_subdir == "startup": @@ -385,13 +391,13 @@ def refresh_script_paths(): for path_subdir in _script_module_dirs: path = _os.path.join(base_path, path_subdir) if _os.path.isdir(path): - _sys_path_ensure(path) + _sys_path_ensure_prepend(path) for path in _addon_utils.paths(): - _sys_path_ensure(path) + _sys_path_ensure_append(path) path = _os.path.join(path, "modules") if _os.path.isdir(path): - _sys_path_ensure(path) + _sys_path_ensure_append(path) def app_template_paths(subdir=None): -- cgit v1.2.3 From 1ddc12ceb922241d485ac9a1842c4c6f3d4ab300 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 16:39:57 +1000 Subject: Cleanup: unused warnings Reminder not to leave in unused code, or comment why it should be kept. --- source/blender/editors/sculpt_paint/sculpt.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index cdd82b8ced3..4b47c521ca9 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -96,6 +96,9 @@ /* Do not use these functions while working with PBVH_GRIDS data in SculptSession */ +/* TODO: why is this kept, should it be removed? */ +#if 0 /* UNUSED */ + static int sculpt_active_vertex_get(SculptSession *ss) { switch (BKE_pbvh_type(ss->pbvh)) { @@ -206,7 +209,7 @@ static void sculpt_vertex_tag_update(SculptSession *ss, int index) } } -#define SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY 256 +# define SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY 256 typedef struct SculptVertexNeighbourIter { int *neighbours; @@ -309,17 +312,19 @@ static void sculpt_vertex_neighbours_get(SculptSession *ss, } } -#define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \ - sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \ - for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.size; \ - neighbour_iterator.i++) { \ - neighbour_iterator.index = ni.neighbours[ni.i]; +# define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \ + sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \ + for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.size; \ + neighbour_iterator.i++) { \ + neighbour_iterator.index = ni.neighbours[ni.i]; -#define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \ - } \ - if (neighbour_iterator.neighbours != neighbour_iterator.neighbours_fixed) { \ - MEM_freeN(neighbour_iterator.neighbours); \ - } +# define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \ + } \ + if (neighbour_iterator.neighbours != neighbour_iterator.neighbours_fixed) { \ + MEM_freeN(neighbour_iterator.neighbours); \ + } + +#endif /* UNUSED */ /** \name Tool Capabilities * -- cgit v1.2.3 From 63b3cc17021d92ac59ac4edc6142e2d434f23f21 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 16:48:21 +1000 Subject: Cleanup: spelling --- source/blender/editors/sculpt_paint/sculpt.c | 70 ++++++++++++++-------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 4b47c521ca9..e0e25ad0fb8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -211,21 +211,21 @@ static void sculpt_vertex_tag_update(SculptSession *ss, int index) # define SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY 256 -typedef struct SculptVertexNeighbourIter { - int *neighbours; +typedef struct SculptVertexNeighborIter { + int *neighbors; int size; int capacity; - int neighbours_fixed[SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY]; + int neighbors_fixed[SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY]; int index; int i; -} SculptVertexNeighbourIter; +} SculptVertexNeighborIter; -static void sculpt_vertex_neighbour_add(SculptVertexNeighbourIter *iter, int neighbour_index) +static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, int neighbor_index) { for (int i = 0; i < iter->size; i++) { - if (iter->neighbours[i] == neighbour_index) { + if (iter->neighbors[i] == neighbor_index) { return; } } @@ -233,30 +233,30 @@ static void sculpt_vertex_neighbour_add(SculptVertexNeighbourIter *iter, int nei if (iter->size >= iter->capacity) { iter->capacity += SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; - if (iter->neighbours == iter->neighbours_fixed) { - iter->neighbours = MEM_mallocN(iter->capacity * sizeof(int), "neighbour array"); - memcpy(iter->neighbours, iter->neighbours_fixed, sizeof(int) * iter->size); + if (iter->neighbors == iter->neighbors_fixed) { + iter->neighbors = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); + memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(int) * iter->size); } else { - iter->neighbours = MEM_reallocN_id( - iter->neighbours, iter->capacity * sizeof(int), "neighbour array"); + iter->neighbors = MEM_reallocN_id( + iter->neighbors, iter->capacity * sizeof(int), "neighbor array"); } } - iter->neighbours[iter->size] = neighbour_index; + iter->neighbors[iter->size] = neighbor_index; iter->size++; } -static void sculpt_vertex_neighbours_get_bmesh(SculptSession *ss, - int index, - SculptVertexNeighbourIter *iter) +static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss, + int index, + SculptVertexNeighborIter *iter) { BMVert *v = BM_vert_at_index(ss->bm, index); BMIter liter; BMLoop *l; iter->size = 0; iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; - iter->neighbours = iter->neighbours_fixed; + iter->neighbors = iter->neighbors_fixed; int i = 0; BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { @@ -264,21 +264,21 @@ static void sculpt_vertex_neighbours_get_bmesh(SculptSession *ss, for (i = 0; i < ARRAY_SIZE(adj_v); i++) { const BMVert *v_other = adj_v[i]; if (BM_elem_index_get(v_other) != (int)index) { - sculpt_vertex_neighbour_add(iter, BM_elem_index_get(v_other)); + sculpt_vertex_neighbor_add(iter, BM_elem_index_get(v_other)); } } } } -static void sculpt_vertex_neighbours_get_faces(SculptSession *ss, - int index, - SculptVertexNeighbourIter *iter) +static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, + int index, + SculptVertexNeighborIter *iter) { int i; MeshElemMap *vert_map = &ss->pmap[(int)index]; iter->size = 0; iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; - iter->neighbours = iter->neighbours_fixed; + iter->neighbors = iter->neighbors_fixed; for (i = 0; i < ss->pmap[(int)index].count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; @@ -288,7 +288,7 @@ static void sculpt_vertex_neighbours_get_faces(SculptSession *ss, for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) { if (f_adj_v[j] != (int)index) { - sculpt_vertex_neighbour_add(iter, f_adj_v[j]); + sculpt_vertex_neighbor_add(iter, f_adj_v[j]); } } } @@ -296,32 +296,32 @@ static void sculpt_vertex_neighbours_get_faces(SculptSession *ss, } } -static void sculpt_vertex_neighbours_get(SculptSession *ss, - int index, - SculptVertexNeighbourIter *iter) +static void sculpt_vertex_neighbors_get(SculptSession *ss, + int index, + SculptVertexNeighborIter *iter) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: - sculpt_vertex_neighbours_get_faces(ss, index, iter); + sculpt_vertex_neighbors_get_faces(ss, index, iter); return; case PBVH_BMESH: - sculpt_vertex_neighbours_get_bmesh(ss, index, iter); + sculpt_vertex_neighbors_get_bmesh(ss, index, iter); return; default: break; } } -# define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \ - sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \ - for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.size; \ - neighbour_iterator.i++) { \ - neighbour_iterator.index = ni.neighbours[ni.i]; +# define sculpt_vertex_neighbors_iter_begin(ss, v_index, neighbor_iterator) \ + sculpt_vertex_neighbors_get(ss, v_index, &neighbor_iterator); \ + for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \ + neighbor_iterator.i++) { \ + neighbor_iterator.index = ni.neighbors[ni.i]; -# define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \ +# define sculpt_vertex_neighbors_iter_end(neighbor_iterator) \ } \ - if (neighbour_iterator.neighbours != neighbour_iterator.neighbours_fixed) { \ - MEM_freeN(neighbour_iterator.neighbours); \ + if (neighbor_iterator.neighbors != neighbor_iterator.neighbors_fixed) { \ + MEM_freeN(neighbor_iterator.neighbors); \ } #endif /* UNUSED */ -- cgit v1.2.3 From 32395dd4e2f6c18de1678b69bbba6ac38eec674e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 15 Aug 2019 11:07:44 +0200 Subject: UI: Finalize old TODO in UI float number handling. Just enable some commented-out code from rB636289b755f6ce (disabled at that time because we were too close of 2.79 release...). Issue raised in D5486, thanks. --- source/blender/editors/interface/interface.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index f9c65249918..7a123599be5 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2553,8 +2553,8 @@ void ui_but_string_get_ex(uiBut *but, } } else { + const int int_digits_num = integer_digits_f(value); if (use_exp_float) { - const int int_digits_num = integer_digits_f(value); if (int_digits_num < -6 || int_digits_num > 12) { BLI_snprintf(str, maxlen, "%.*g", prec, value); if (r_use_exp_float) { @@ -2568,10 +2568,8 @@ void ui_but_string_get_ex(uiBut *but, } } else { -#if 0 /* TODO, but will likely break some stuff, so better after 2.79 release. */ prec -= int_digits_num; CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX); -#endif BLI_snprintf(str, maxlen, "%.*f", prec, value); } } -- cgit v1.2.3 From 5b04829d43996267f2dec8ef5a1418e71647b3c5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Aug 2019 11:24:19 +0200 Subject: Cleanup: replace commented out code by comment --- source/blender/editors/space_view3d/view3d_edit.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ec7c1c0b3b9..9a9fe81a13e 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -517,9 +517,6 @@ static void viewops_data_create(bContext *C, static void viewops_data_free(bContext *C, wmOperator *op) { ARegion *ar; -#if 0 - Paint *p = BKE_paint_get_active_from_context(C); -#endif if (op->customdata) { ViewOpsData *vod = op->customdata; ar = vod->ar; @@ -536,12 +533,9 @@ static void viewops_data_free(bContext *C, wmOperator *op) ar = CTX_wm_region(C); } -#if 0 - if (p && (p->flags & PAINT_FAST_NAVIGATE)) -#endif - { - ED_region_tag_redraw(ar); - } + /* Need to redraw because drawing code uses RV3D_NAVIGATING to draw + * faster while navigation operator runs. */ + ED_region_tag_redraw(ar); } /** \} */ -- cgit v1.2.3 From c7598cd1a517fd6d0eb9c903d6727dcd1449d1a2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 19:50:52 +1000 Subject: Cleanup: spelling Missed in recent commit. --- source/blender/editors/sculpt_paint/sculpt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e0e25ad0fb8..440c4d42cae 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -209,14 +209,14 @@ static void sculpt_vertex_tag_update(SculptSession *ss, int index) } } -# define SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY 256 +# define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 typedef struct SculptVertexNeighborIter { int *neighbors; int size; int capacity; - int neighbors_fixed[SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY]; + int neighbors_fixed[SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY]; int index; int i; @@ -231,7 +231,7 @@ static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, int neigh } if (iter->size >= iter->capacity) { - iter->capacity += SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; if (iter->neighbors == iter->neighbors_fixed) { iter->neighbors = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); @@ -255,7 +255,7 @@ static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss, BMIter liter; BMLoop *l; iter->size = 0; - iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; iter->neighbors = iter->neighbors_fixed; int i = 0; @@ -277,7 +277,7 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, int i; MeshElemMap *vert_map = &ss->pmap[(int)index]; iter->size = 0; - iter->capacity = SCULPT_VERTEX_NEIGHBOUR_FIXED_CAPACITY; + iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; iter->neighbors = iter->neighbors_fixed; for (i = 0; i < ss->pmap[(int)index].count; i++) { -- cgit v1.2.3 From a2a9c95845559b0bfffaf4b6b5e32e31ed3da7a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 18:17:33 +1000 Subject: Fix T68678: Invisible fullscreen button Regression from 6148ed8cf9ca --- source/blender/editors/screen/area.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 5099c370a85..6f776d3115a 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -203,7 +203,7 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f alpha = min_ff(alpha, 0.75f); - UI_icon_draw_ex(x, y, ICON_FULLSCREEN_EXIT, 0.7f * U.inv_dpi_fac, 0.0f, alpha, NULL, false); + UI_icon_draw_ex(x, y, ICON_FULLSCREEN_EXIT, 0.7f * U.inv_dpi_fac, alpha, 0.0f, NULL, false); /* debug drawing : * The click_rect is the same as defined in fullscreen_click_rcti_init -- cgit v1.2.3 From e6fa174fd7744a88c1ea9a986fdb9b7e908c9047 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 18:18:22 +1000 Subject: UI: skip drawing the full-screen when alpha is zero --- source/blender/editors/screen/area.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 6f776d3115a..84ac3bfa29d 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -368,7 +368,9 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } } else if (az->type == AZONE_FULLSCREEN) { - area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + if (az->alpha > 0.0f) { + area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + } } } if (!IS_EQF(az->alpha, 0.0f) && ELEM(az->type, AZONE_FULLSCREEN, AZONE_REGION_SCROLL)) { -- cgit v1.2.3 From eac2a7ab0ecd7fe90cd58213ca96004a1e6a6d33 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 19:46:29 +1000 Subject: Fix full-screen button overlapping navigation gizmo --- source/blender/editors/screen/area.c | 58 +++++++----------------------- source/blender/editors/screen/screen_ops.c | 16 ++------- 2 files changed, 14 insertions(+), 60 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 84ac3bfa29d..3cf39b67054 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -188,51 +188,17 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) /** * \brief Corner widget use for quitting fullscreen. */ -static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) +static void area_draw_azone_fullscreen( + short UNUSED(x1), short UNUSED(y1), short x2, short y2, float alpha) { - int x = x2 - ((float)x2 - x1) * 0.5f / UI_DPI_FAC; - int y = y2 - ((float)y2 - y1) * 0.5f / UI_DPI_FAC; - - /* adjust the icon distance from the corner */ - x += 36.0f / UI_DPI_FAC; - y += 36.0f / UI_DPI_FAC; - - /* draws from the left bottom corner of the icon */ - x -= UI_DPI_ICON_SIZE; - y -= UI_DPI_ICON_SIZE; - - alpha = min_ff(alpha, 0.75f); - - UI_icon_draw_ex(x, y, ICON_FULLSCREEN_EXIT, 0.7f * U.inv_dpi_fac, alpha, 0.0f, NULL, false); - - /* debug drawing : - * The click_rect is the same as defined in fullscreen_click_rcti_init - * Keep them both in sync */ - - if (G.debug_value == 101) { - rcti click_rect; - float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; - - BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - immUniformColor4f(1.0f, 0.0f, 0.0f, alpha); - imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); - - immUniformColor4f(0.0f, 1.0f, 1.0f, alpha); - immBegin(GPU_PRIM_LINES, 4); - immVertex2f(pos, click_rect.xmin, click_rect.ymin); - immVertex2f(pos, click_rect.xmax, click_rect.ymax); - immVertex2f(pos, click_rect.xmin, click_rect.ymax); - immVertex2f(pos, click_rect.xmax, click_rect.ymin); - immEnd(); - - immUnbindProgram(); - } + UI_icon_draw_ex(x2 - U.widget_unit, + y2 - U.widget_unit, + ICON_FULLSCREEN_EXIT, + U.inv_dpi_fac, + min_ff(alpha, 0.75f), + 0.0f, + NULL, + false); } /** @@ -908,10 +874,10 @@ static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) az->ar = ar; az->alpha = 0.0f; - az->x1 = ar->winrct.xmax - (AZONEFADEOUT - 1); - az->y1 = ar->winrct.ymax - (AZONEFADEOUT - 1); az->x2 = ar->winrct.xmax; az->y2 = ar->winrct.ymax; + az->x1 = az->x2 - AZONEFADEOUT; + az->y1 = az->y2 - AZONEFADEOUT; BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 4fb5e0c1af3..8377fd0e128 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -696,21 +696,9 @@ static bool actionzone_area_poll(bContext *C) /* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */ static void fullscreen_click_rcti_init( - rcti *rect, const short x1, const short y1, const short x2, const short y2) + rcti *rect, const short UNUSED(x1), const short UNUSED(y1), const short x2, const short y2) { - int x = x2 - ((float)x2 - x1) * 0.5f / UI_DPI_FAC; - int y = y2 - ((float)y2 - y1) * 0.5f / UI_DPI_FAC; - float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; - - /* adjust the icon distance from the corner */ - x += 36.0f / UI_DPI_FAC; - y += 36.0f / UI_DPI_FAC; - - /* draws from the left bottom corner of the icon */ - x -= UI_DPI_ICON_SIZE; - y -= UI_DPI_ICON_SIZE; - - BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size); + BLI_rcti_init(rect, x2 - U.widget_unit, x2, y2 - U.widget_unit, y2); } static bool azone_clipped_rect_calc(const AZone *az, rcti *r_rect_clip) -- cgit v1.2.3 From ff1ea600c98ba542c3b950fcfaf350626e078899 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 15 Aug 2019 11:39:45 +0200 Subject: Fix T68675: particle edit mode makes blender crash In rB9c010c44f420, DRW_mesh_batch_cache_create_requested was changed to take a scene (instead of toolsettings directly), but DRW_draw_depth_object is calling this with with NULL, just checking for this seems to fix... Reviewers: fclem Maniphest Tasks: T68675 Differential Revision: https://developer.blender.org/D5488 --- source/blender/draw/intern/draw_cache_impl_mesh.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 8c89ac4703c..12c6a715685 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -969,7 +969,10 @@ void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime) void DRW_mesh_batch_cache_create_requested( Object *ob, Mesh *me, const Scene *scene, const bool is_paint_mode, const bool use_hide) { - const ToolSettings *ts = scene->toolsettings; + const ToolSettings *ts = NULL; + if (scene) { + ts = scene->toolsettings; + } MeshBatchCache *cache = mesh_batch_cache_get(me); /* Early out */ -- cgit v1.2.3 From 143a44caeb4dc00f27b66b55d35a868127b5e4a9 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 15 Aug 2019 13:14:43 +0200 Subject: GPencil: Fix unreported missing VFX in Video Editor As the video editor mode is not Render mode the VFX was omitted. Now, the mode is only checked for View3D. --- source/blender/draw/engines/gpencil/gpencil_engine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 16162645f3d..db216c5eb2d 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -564,6 +564,8 @@ static void gpencil_add_draw_data(void *vedata, Object *ob) GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; bGPdata *gpd = (bGPdata *)ob->data; const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; int i = stl->g_data->gp_cache_used - 1; tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i]; @@ -580,7 +582,9 @@ static void gpencil_add_draw_data(void *vedata, Object *ob) /* FX passses */ cache_ob->has_fx = false; - if ((!stl->storage->simplify_fx) && (!ELEM(cache_ob->shading_type[0], OB_WIRE, OB_SOLID)) && + if ((!stl->storage->simplify_fx) && + ((!ELEM(cache_ob->shading_type[0], OB_WIRE, OB_SOLID)) || + ((v3d->spacetype != SPACE_VIEW3D))) && (BKE_shaderfx_has_gpencil(ob))) { cache_ob->has_fx = true; if ((!stl->storage->simplify_fx) && (!is_multiedit)) { -- cgit v1.2.3 From 9e54e6bdc57911be2911a7537ab9f67d87e31df0 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 15 Aug 2019 13:17:28 +0200 Subject: Cleanup: Minor change to previous commit --- source/blender/draw/engines/gpencil/gpencil_engine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index db216c5eb2d..efe67e1ead0 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -565,7 +565,7 @@ static void gpencil_add_draw_data(void *vedata, Object *ob) bGPdata *gpd = (bGPdata *)ob->data; const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); const DRWContextState *draw_ctx = DRW_context_state_get(); - View3D *v3d = draw_ctx->v3d; + const View3D *v3d = draw_ctx->v3d; int i = stl->g_data->gp_cache_used - 1; tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i]; -- cgit v1.2.3 From 95a0144293b840bfbdcb6a41c1a3a26976961b9b Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 08:29:34 -0300 Subject: Fix T68684: Vertex snapping with median not working if the object is not at center of the world --- source/blender/editors/transform/transform_snap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index d45a0588003..dbcc6c1b04a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1150,12 +1150,19 @@ static void TargetSnapMedian(TransInfo *t) add_v3_v3(v, td->center); } + if (i == 0) { + /* Is this possible? */ + continue; + } + + mul_v3_fl(v, 1.0 / i); + if (tc->use_local_mat) { mul_m4_v3(tc->mat, v); } add_v3_v3(t->tsnap.snapTarget, v); - i_accum += i; + i_accum++; } mul_v3_fl(t->tsnap.snapTarget, 1.0 / i_accum); -- cgit v1.2.3 From 48a6997e2a0657d8b238101b84b688b37bc88875 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 20:55:24 +1000 Subject: Fix T64888: full-screen button overlaps side-bar --- source/blender/editors/screen/area.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 3cf39b67054..d0a3382ee50 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -874,10 +874,19 @@ static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) az->ar = ar; az->alpha = 0.0f; - az->x2 = ar->winrct.xmax; - az->y2 = ar->winrct.ymax; + if (U.uiflag2 & USER_REGION_OVERLAP) { + rcti rect_visible; + ED_region_visible_rect(ar, &rect_visible); + az->x2 = ar->winrct.xmin + rect_visible.xmax; + az->y2 = ar->winrct.ymin + rect_visible.ymax; + } + else { + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymax; + } az->x1 = az->x2 - AZONEFADEOUT; az->y1 = az->y2 - AZONEFADEOUT; + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -- cgit v1.2.3 From e4084f8b24197ede2546da90459cb1b5ad0fd9a8 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Thu, 15 Aug 2019 07:55:29 -0400 Subject: Fix CDT bug causing crash with some output modes. Forgot to properly maintain the edge for faces while dissolving edges. --- source/blender/blenlib/intern/delaunay_2d.c | 18 ++++++++-- tests/gtests/blenlib/BLI_delaunay_2d_test.cc | 52 +++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c index 8e2687a6b2f..632847046a7 100644 --- a/source/blender/blenlib/intern/delaunay_2d.c +++ b/source/blender/blenlib/intern/delaunay_2d.c @@ -1961,13 +1961,17 @@ static void add_face_ids( } } -/* Delete_edge but try not to mess up outer face. */ +/* Delete_edge but try not to mess up outer face. + * Also faces have symedges now, so make sure not + * to mess those up either. */ static void dissolve_symedge(CDT_state *cdt, SymEdge *se) { - if (sym(se)->face == cdt->outer_face) { + SymEdge *symse = sym(se); + if (symse->face == cdt->outer_face) { se = sym(se); + symse = sym(se); } - if (cdt->outer_face->symedge == se || cdt->outer_face->symedge == sym(se)) { + if (cdt->outer_face->symedge == se || cdt->outer_face->symedge == symse) { /* Advancing by 2 to get past possible 'sym(se)'. */ if (se->next->next == se) { cdt->outer_face->symedge = NULL; @@ -1976,6 +1980,14 @@ static void dissolve_symedge(CDT_state *cdt, SymEdge *se) cdt->outer_face->symedge = se->next->next; } } + else { + if (se->face->symedge == se) { + se->face->symedge = se->next; + } + if (symse->face->symedge == se) { + symse->face->symedge = symse->next; + } + } delete_edge(cdt, se); } diff --git a/tests/gtests/blenlib/BLI_delaunay_2d_test.cc b/tests/gtests/blenlib/BLI_delaunay_2d_test.cc index 220c0a4100d..5b44c6277a3 100644 --- a/tests/gtests/blenlib/BLI_delaunay_2d_test.cc +++ b/tests/gtests/blenlib/BLI_delaunay_2d_test.cc @@ -616,6 +616,33 @@ TEST(delaunay, OverlapFaces) BLI_delaunay_2d_cdt_free(out); } +TEST(delaunay, TwoSquaresOverlap) +{ + CDT_input in; + CDT_result *out; + float p[][2] = { + {1.0f, -1.0f}, + {-1.0f, -1.0f}, + {-1.0f, 1.0f}, + {1.0f, 1.0f}, + {-1.5f, 1.5f}, + {0.5f, 1.5f}, + {0.5f, -0.5f}, + {-1.5f, -0.5f}, + }; + int f[] = {/* 0 */ 7, 6, 5, 4, /* 1 */ 3, 2, 1, 0}; + int fstart[] = {0, 4}; + int flen[] = {4, 4}; + + fill_input_verts(&in, p, 8); + add_input_faces(&in, f, fstart, flen, 2); + out = BLI_delaunay_2d_cdt_calc(&in, CDT_CONSTRAINTS_VALID_BMESH); + EXPECT_EQ(out->verts_len, 10); + EXPECT_EQ(out->edges_len, 12); + EXPECT_EQ(out->faces_len, 3); + BLI_delaunay_2d_cdt_free(out); +} + enum { RANDOM_PTS, RANDOM_SEGS, @@ -623,7 +650,7 @@ enum { }; // #define DO_TIMING -static void rand_delaunay_test(int test_kind, int max_lg_size, int reps_per_size) +static void rand_delaunay_test(int test_kind, int max_lg_size, int reps_per_size, CDT_output_type otype) { CDT_input in; CDT_result *out; @@ -679,7 +706,7 @@ static void rand_delaunay_test(int test_kind, int max_lg_size, int reps_per_size add_input_edges(&in, e, size - 1 + (test_kind == RANDOM_POLY)); } tstart = PIL_check_seconds_timer(); - out = BLI_delaunay_2d_cdt_calc(&in, CDT_FULL); + out = BLI_delaunay_2d_cdt_calc(&in, otype); EXPECT_NE(out->verts_len, 0); BLI_delaunay_2d_cdt_free(out); times[lg_size] += PIL_check_seconds_timer() - tstart; @@ -700,17 +727,32 @@ static void rand_delaunay_test(int test_kind, int max_lg_size, int reps_per_size TEST(delaunay, randompts) { - rand_delaunay_test(RANDOM_PTS, 7, 1); + rand_delaunay_test(RANDOM_PTS, 7, 1, CDT_FULL); } TEST(delaunay, randomsegs) { - rand_delaunay_test(RANDOM_SEGS, 7, 1); + rand_delaunay_test(RANDOM_SEGS, 7, 1, CDT_FULL); } TEST(delaunay, randompoly) { - rand_delaunay_test(RANDOM_POLY, 7, 1); + rand_delaunay_test(RANDOM_POLY, 7, 1, CDT_FULL); +} + +TEST(delaunay, randompoly_inside) +{ + rand_delaunay_test(RANDOM_POLY, 7, 1, CDT_INSIDE); +} + +TEST(delaunay, randompoly_constraints) +{ + rand_delaunay_test(RANDOM_POLY, 7, 1, CDT_CONSTRAINTS); +} + +TEST(delaunay, randompoly_validbmesh) +{ + rand_delaunay_test(RANDOM_POLY, 7, 1, CDT_CONSTRAINTS_VALID_BMESH); } #if 0 -- cgit v1.2.3 From fdef1a6712bc3ccf7fa41b0d7b11c725b5503288 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 22:36:28 +1000 Subject: UI: make int/float button clicking logic consistent - When no change is performed on a float button, cancel the action. - Move left/right clicks into the same block. - Replace ambiguous names: temp, tempf. --- .../blender/editors/interface/interface_handlers.c | 64 +++++++--------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 6ae7793509d..9c2eb4204e8 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4800,64 +4800,40 @@ static int ui_do_but_NUM( if (click) { /* we can click on the side arrows to increment/decrement, * or click inside to edit the value directly */ - float tempf, softmin, softmax; - int temp; - - softmin = but->softmin; - softmax = but->softmax; + const float softmin = but->softmin; + const float softmax = but->softmax; if (!ui_but_is_float(but)) { - if (but->drawflag & UI_BUT_ACTIVE_LEFT) { + /* Integer Value. */ + if (but->drawflag & (UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - - temp = (int)data->value - 1; - if (temp >= softmin && temp <= softmax) { - data->value = (double)temp; - } - else { - data->cancel = true; - } - - button_activate_state(C, but, BUTTON_STATE_EXIT); - } - else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) { - button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - - temp = (int)data->value + 1; - if (temp >= softmin && temp <= softmax) { - data->value = (double)temp; + const int value_step = 1; + const double value_test = (but->drawflag & UI_BUT_ACTIVE_LEFT) ? + (double)max_ii((int)softmin, (int)data->value - value_step) : + (double)min_ii((int)softmax, (int)data->value + value_step); + if (value_test != data->value) { + data->value = (double)value_test; } else { data->cancel = true; } - button_activate_state(C, but, BUTTON_STATE_EXIT); } - else { - button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); - } } else { - if (but->drawflag & UI_BUT_ACTIVE_LEFT) { + /* Float Value. */ + if (but->drawflag & (UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - - tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1); - if (tempf < softmin) { - tempf = softmin; + const double value_step = (double)but->a1 * UI_PRECISION_FLOAT_SCALE; + const double value_test = (but->drawflag & UI_BUT_ACTIVE_LEFT) ? + (double)max_ff(softmin, (float)(data->value - value_step)) : + (double)min_ff(softmax, (float)(data->value + value_step)); + if (value_test != data->value) { + data->value = value_test; } - data->value = tempf; - - button_activate_state(C, but, BUTTON_STATE_EXIT); - } - else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) { - button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - - tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1); - if (tempf > softmax) { - tempf = softmax; + else { + data->cancel = true; } - data->value = tempf; - button_activate_state(C, but, BUTTON_STATE_EXIT); } else { -- cgit v1.2.3 From 78b56fa7d973dab8d11786115a87af57681a7dda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Aug 2019 22:50:30 +1000 Subject: Fix T65461: IntProperty does not respect its 'step' field Originally D5020 by @deadpin, refactored to make the change simpler. --- source/blender/editors/interface/interface_handlers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 9c2eb4204e8..8fd39b5d120 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4807,7 +4807,8 @@ static int ui_do_but_NUM( /* Integer Value. */ if (but->drawflag & (UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); - const int value_step = 1; + const int value_step = (int)but->a1; + BLI_assert(value_step > 0); const double value_test = (but->drawflag & UI_BUT_ACTIVE_LEFT) ? (double)max_ii((int)softmin, (int)data->value - value_step) : (double)min_ii((int)softmax, (int)data->value + value_step); @@ -4825,6 +4826,7 @@ static int ui_do_but_NUM( if (but->drawflag & (UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); const double value_step = (double)but->a1 * UI_PRECISION_FLOAT_SCALE; + BLI_assert(value_step > 0.0f); const double value_test = (but->drawflag & UI_BUT_ACTIVE_LEFT) ? (double)max_ff(softmin, (float)(data->value - value_step)) : (double)min_ff(softmax, (float)(data->value + value_step)); -- cgit v1.2.3 From 261a02fc596db0e91667d4e3af9204b165ec4006 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 10:17:41 -0300 Subject: DRW: New function DRW_culling_min_max_test For testing intersection with frustrum planes without having to transform all bound box vertices into global space. --- source/blender/draw/intern/DRW_render.h | 1 + source/blender/draw/intern/draw_manager_exec.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index a8f67e10a4d..3379aa28d0f 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -597,6 +597,7 @@ bool DRW_view_is_persp_get(const DRWView *view); bool DRW_culling_sphere_test(const DRWView *view, const BoundSphere *bsphere); bool DRW_culling_box_test(const DRWView *view, const BoundBox *bbox); bool DRW_culling_plane_test(const DRWView *view, const float plane[4]); +bool DRW_culling_min_max_test(const DRWView *view, float obmat[4][4], float min[3], float max[3]); void DRW_culling_frustum_corners_get(const DRWView *view, BoundBox *corners); void DRW_culling_frustum_planes_get(const DRWView *view, float planes[6][4]); diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 949d3e1d38b..3bf442b4f39 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -22,6 +22,7 @@ #include "draw_manager.h" +#include "BLI_math.h" #include "BLI_math_bits.h" #include "BLI_memblock.h" @@ -488,6 +489,26 @@ bool DRW_culling_plane_test(const DRWView *view, const float plane[4]) return draw_culling_plane_test(&view->frustum_corners, plane); } +/* Return True if the given box intersect the current view frustum. + * This function will have to be replaced when world space bb per objects is implemented. */ +bool DRW_culling_min_max_test(const DRWView *view, float obmat[4][4], float min[3], float max[3]) +{ + view = view ? view : DST.view_default; + float tobmat[4][4]; + transpose_m4_m4(tobmat, obmat); + for (int i = 6; i--;) { + float frustum_plane_local[4], bb_near[3], bb_far[3]; + mul_v4_m4v4(frustum_plane_local, tobmat, view->frustum_planes[i]); + aabb_get_near_far_from_plane(frustum_plane_local, min, max, bb_near, bb_far); + + if (plane_point_side_v3(frustum_plane_local, bb_far) < 0.0f) { + return false; + } + } + + return true; +} + void DRW_culling_frustum_corners_get(const DRWView *view, BoundBox *corners) { view = view ? view : DST.view_default; -- cgit v1.2.3 From 4d320f43133b02a43212b017eecdb390476189f2 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 10:31:54 -0300 Subject: Edit Mesh Selection: Refactor: Redraw idmap buffer at runtime with only objects inside the rect But in the future the selection code may also be used in object mode (eg for snapping). So to avoid using too much VRAM resources, it is good to avoid drawing all objects in the viewport. The solution was to create an array with only objects that are detected within the selection area. If the selection operator is modal, objects already detected are not removed from the array until view3d is moved or orbited. To detect the object, its BoundBox is tested. Since the Select Engine does not have a dedicated depth texture, whenever a new object is "found" the depth of the objects in the array already drawn is redrawn. Reviewers: campbellbarton, fclem Reviewed By: fclem Differential Revision: https://developer.blender.org/D5435 --- source/blender/draw/DRW_engine.h | 4 +- source/blender/draw/DRW_select_buffer.h | 83 ++++++-- .../draw/engines/select/select_draw_utils.c | 44 +++- source/blender/draw/engines/select/select_engine.c | 145 ++++++++++--- .../blender/draw/engines/select/select_private.h | 6 +- source/blender/draw/intern/draw_manager.c | 30 +-- source/blender/draw/intern/draw_select_buffer.c | 225 +++++++++++++-------- source/blender/editors/mesh/editmesh_select.c | 14 +- source/blender/editors/mesh/meshtools.c | 10 +- source/blender/editors/sculpt_paint/paint_utils.c | 2 +- .../editors/space_view3d/view3d_draw_legacy.c | 3 +- .../blender/editors/space_view3d/view3d_select.c | 139 +++++++------ 12 files changed, 467 insertions(+), 238 deletions(-) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 53cec599b82..6cae9ceb7d6 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -141,9 +141,7 @@ void DRW_draw_depth_object(struct ARegion *ar, void DRW_draw_select_id(struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d, - struct Base **bases, - const uint bases_len, - short select_mode); + const struct rcti *rect); /* grease pencil render */ bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph); diff --git a/source/blender/draw/DRW_select_buffer.h b/source/blender/draw/DRW_select_buffer.h index ff40508b1a1..4aa1c403710 100644 --- a/source/blender/draw/DRW_select_buffer.h +++ b/source/blender/draw/DRW_select_buffer.h @@ -33,6 +33,13 @@ struct View3D; struct ViewLayer; struct rcti; +typedef struct SELECTID_ObjectData { + DrawData dd; + + uint drawn_index; + bool is_drawn; +} SELECTID_ObjectData; + struct ObjectOffsets { /* For convenience only. */ union { @@ -54,43 +61,75 @@ struct SELECTID_Context { struct GPUFrameBuffer *framebuffer_select_id; struct GPUTexture *texture_u32; - struct ObjectOffsets *index_offsets; + /* All context objects */ + struct Object **objects; uint objects_len; - uint last_object_drawn; - /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ - uint last_index_drawn; + + /* Array with only drawn objects. When a new object is found within the rect, + * it is added to the end of the list. + * The list is reset to any viewport or context update. */ + struct ObjectOffsets *index_offsets; + struct Object **objects_drawn; + uint objects_drawn_len; + + /** Total number of element indices `index_offsets[object_drawn_len - 1].vert`. */ + uint index_drawn_len; short select_mode; + + /* To check for updates. */ + float persmat[4][4]; + bool is_dirty; + + /* rect is used to check which objects whose indexes need to be drawn. */ + rcti last_rect; }; -/* select_buffer.c */ -void DRW_select_buffer_context_create(struct Base **bases, - const uint bases_len, - short select_mode); +/* draw_select_buffer.c */ bool DRW_select_buffer_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type); -uint DRW_select_buffer_context_offset_for_object_elem(const uint base_index, char elem_type); -uint *DRW_select_buffer_read(const struct rcti *rect, uint *r_buf_len); -void DRW_draw_select_id_object(struct Depsgraph *depsgraph, - struct ViewLayer *view_layer, - struct ARegion *ar, - struct View3D *v3d, - struct Object *ob, - short select_mode); -uint *DRW_select_buffer_bitmap_from_rect(const struct rcti *rect, uint *r_bitmap_len); -uint *DRW_select_buffer_bitmap_from_circle(const int center[2], +uint DRW_select_buffer_context_offset_for_object_elem(struct Depsgraph *depsgraph, + struct Object *object, + char elem_type); +uint *DRW_select_buffer_read(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const rcti *rect, + uint *r_buf_len); +uint *DRW_select_buffer_bitmap_from_rect(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const struct rcti *rect, + uint *r_bitmap_len); +uint *DRW_select_buffer_bitmap_from_circle(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2], const int radius, uint *r_bitmap_len); -uint *DRW_select_buffer_bitmap_from_poly(const int poly[][2], +uint *DRW_select_buffer_bitmap_from_poly(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int poly[][2], const int poly_len, - const struct rcti *rect); -uint DRW_select_buffer_sample_point(const int center[2]); -uint DRW_select_buffer_find_nearest_to_point(const int center[2], + const struct rcti *rect, + uint *r_bitmap_len); +uint DRW_select_buffer_sample_point(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2]); +uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2], const uint id_min, const uint id_max, uint *dist); +void DRW_select_buffer_context_create(struct Base **bases, + const uint bases_len, + short select_mode); /* select_engine.c */ struct SELECTID_Context *DRW_select_engine_context_get(void); diff --git a/source/blender/draw/engines/select/select_draw_utils.c b/source/blender/draw/engines/select/select_draw_utils.c index b65a158cdcf..268cd60a8aa 100644 --- a/source/blender/draw/engines/select/select_draw_utils.c +++ b/source/blender/draw/engines/select/select_draw_utils.c @@ -23,6 +23,8 @@ */ #include "BKE_editmesh.h" +#include "BKE_mesh.h" +#include "BKE_object.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" @@ -42,7 +44,7 @@ /** \name Draw Utilities * \{ */ -void draw_select_framebuffer_select_id_setup(struct SELECTID_Context *select_ctx) +static void select_id_framebuffer_setup(struct SELECTID_Context *select_ctx) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); int size[2]; @@ -73,6 +75,32 @@ void draw_select_framebuffer_select_id_setup(struct SELECTID_Context *select_ctx } } +/* Remove all tags from drawn or culled objects. */ +void select_id_context_clear(struct SELECTID_Context *select_ctx) +{ + select_ctx->objects_drawn_len = 0; + select_ctx->index_drawn_len = 1; + select_id_framebuffer_setup(select_ctx); + GPU_framebuffer_bind(select_ctx->framebuffer_select_id); + GPU_framebuffer_clear_color_depth( + select_ctx->framebuffer_select_id, (const float[4]){0.0f}, 1.0f); +} + +void select_id_object_min_max(Object *obj, float r_min[3], float r_max[3]) +{ + BoundBox *bb; + BMEditMesh *em = BKE_editmesh_from_object(obj); + if (em) { + /* Use Object Texture Space. */ + bb = BKE_mesh_texspace_get(em->mesh_eval_cage, NULL, NULL, NULL); + } + else { + bb = BKE_object_boundbox_get(obj); + } + copy_v3_v3(r_min, bb->vec[0]); + copy_v3_v3(r_max, bb->vec[6]); +} + short select_id_get_object_select_mode(Scene *scene, Object *ob) { short r_select_mode = 0; @@ -132,7 +160,7 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, if (draw_facedot) { struct GPUBatch *geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me); - DRW_shgroup_call(face_shgrp, geom_facedots, ob); + DRW_shgroup_call_no_cull(face_shgrp, geom_facedots, ob); } *r_face_offset = initial_offset + em->bm->totface; } @@ -141,14 +169,14 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, face_shgrp = stl->g_data->shgrp_face_unif; *r_face_offset = initial_offset; } - DRW_shgroup_call(face_shgrp, geom_faces, ob); + DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob); /* Unlike faces, only draw edges if edge select mode. */ if (select_mode & SCE_SELECT_EDGE) { struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge); DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset); - DRW_shgroup_call(edge_shgrp, geom_edges, ob); + DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob); *r_edge_offset = *r_face_offset + em->bm->totedge; } else { @@ -162,7 +190,7 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset); - DRW_shgroup_call(vert_shgrp, geom_verts, ob); + DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob); *r_vert_offset = *r_edge_offset + em->bm->totvert; } else { @@ -192,13 +220,13 @@ static void draw_select_id_mesh(SELECTID_StorageList *stl, face_shgrp = stl->g_data->shgrp_face_unif; *r_face_offset = initial_offset; } - DRW_shgroup_call(face_shgrp, geom_faces, ob); + DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob); if (select_mode & SCE_SELECT_EDGE) { struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge); DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset); - DRW_shgroup_call(edge_shgrp, geom_edges, ob); + DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob); *r_edge_offset = *r_face_offset + me->totedge; } else { @@ -209,7 +237,7 @@ static void draw_select_id_mesh(SELECTID_StorageList *stl, struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *r_edge_offset); - DRW_shgroup_call(vert_shgrp, geom_verts, ob); + DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob); *r_vert_offset = *r_edge_offset + me->totvert; } else { diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c index 67e926452b9..f437efe0c41 100644 --- a/source/blender/draw/engines/select/select_engine.c +++ b/source/blender/draw/engines/select/select_engine.c @@ -31,6 +31,11 @@ #include "DRW_engine.h" #include "DRW_select_buffer.h" +#include "DRW_select_buffer.h" + +#include "draw_cache_impl.h" +#include "draw_manager.h" + #include "select_private.h" #include "select_engine.h" @@ -41,6 +46,7 @@ static struct { SELECTID_Shaders sh_data[GPU_SHADER_CFG_LEN]; struct SELECTID_Context context; + uint runtime_new_objects; } e_data = {{{NULL}}}; /* Engine data */ /* Shaders */ @@ -90,8 +96,23 @@ static void select_engine_init(void *vedata) } { + /* Create view from a subregion */ + const DRWView *view_default = DRW_view_default_get(); + float viewmat[4][4], winmat[4][4], winmat_subregion[4][4]; + DRW_view_viewmat_get(view_default, viewmat, false); + DRW_view_winmat_get(view_default, winmat, false); + projmat_from_subregion(winmat, + (int[2]){draw_ctx->ar->winx, draw_ctx->ar->winy}, + e_data.context.last_rect.xmin, + e_data.context.last_rect.xmax, + e_data.context.last_rect.ymin, + e_data.context.last_rect.ymax, + winmat_subregion); + + stl->g_data->view_subregion = DRW_view_create(viewmat, winmat_subregion, NULL, NULL, NULL); + /* Create view with depth offset */ - stl->g_data->view_faces = (DRWView *)DRW_view_default_get(); + stl->g_data->view_faces = (DRWView *)view_default; stl->g_data->view_edges = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.0f); stl->g_data->view_verts = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.1f); } @@ -107,11 +128,19 @@ static void select_cache_init(void *vedata) if (e_data.context.select_mode == -1) { e_data.context.select_mode = select_id_get_object_select_mode(draw_ctx->scene, - OBACT(draw_ctx->view_layer)); + draw_ctx->obact); BLI_assert(e_data.context.select_mode != 0); } { + psl->depth_only_pass = DRW_pass_create("Depth Only Pass", DRW_STATE_DEFAULT); + stl->g_data->shgrp_depth_only = DRW_shgroup_create(sh_data->select_id_uniform, + psl->depth_only_pass); + + if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) { + DRW_shgroup_state_enable(stl->g_data->shgrp_depth_only, DRW_STATE_CLIP_PLANES); + } + psl->select_id_face_pass = DRW_pass_create("Face Pass", DRW_STATE_DEFAULT); if (e_data.context.select_mode & SCE_SELECT_FACE) { @@ -157,29 +186,82 @@ static void select_cache_init(void *vedata) } } - e_data.context.last_object_drawn = 0; - e_data.context.last_index_drawn = 1; + /* Check if the viewport has changed. */ + float(*persmat)[4] = draw_ctx->rv3d->persmat; + e_data.context.is_dirty = !compare_m4m4(e_data.context.persmat, persmat, FLT_EPSILON); + if (e_data.context.is_dirty) { + copy_m4_m4(e_data.context.persmat, persmat); + select_id_context_clear(&e_data.context); + } + e_data.runtime_new_objects = 0; } static void select_cache_populate(void *vedata, Object *ob) { + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - struct ObjectOffsets *base_ofs = - &e_data.context.index_offsets[e_data.context.last_object_drawn++]; - - uint offset = e_data.context.last_index_drawn; - - select_id_draw_object(vedata, - draw_ctx->v3d, - ob, - e_data.context.select_mode, - offset, - &base_ofs->vert, - &base_ofs->edge, - &base_ofs->face); - - base_ofs->offset = offset; - e_data.context.last_index_drawn = base_ofs->vert; + + SELECTID_ObjectData *sel_data = (SELECTID_ObjectData *)DRW_drawdata_get( + &ob->id, &draw_engine_select_type); + + if (!e_data.context.is_dirty && sel_data && sel_data->is_drawn) { + /* The object indices have already been drawn. Fill depth pass. + * Opti: Most of the time this depth pass is not used. */ + struct Mesh *me = ob->data; + struct GPUBatch *geom_faces; + if (e_data.context.select_mode & SCE_SELECT_FACE) { + geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + } + else { + geom_faces = DRW_mesh_batch_cache_get_surface(me); + } + DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_faces, ob->obmat); + + if (e_data.context.select_mode & SCE_SELECT_EDGE) { + struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); + DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_edges, ob->obmat); + } + + if (e_data.context.select_mode & SCE_SELECT_VERTEX) { + struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + DRW_shgroup_call_obmat(stl->g_data->shgrp_depth_only, geom_verts, ob->obmat); + } + return; + } + + float min[3], max[3]; + select_id_object_min_max(ob, min, max); + + if (DRW_culling_min_max_test(stl->g_data->view_subregion, ob->obmat, min, max)) { + if (sel_data == NULL) { + sel_data = (SELECTID_ObjectData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_select_type, sizeof(SELECTID_ObjectData), NULL, NULL); + } + sel_data->drawn_index = e_data.context.objects_drawn_len; + sel_data->is_drawn = true; + + struct ObjectOffsets *ob_offsets = + &e_data.context.index_offsets[e_data.context.objects_drawn_len]; + + uint offset = e_data.context.index_drawn_len; + select_id_draw_object(vedata, + draw_ctx->v3d, + ob, + e_data.context.select_mode, + offset, + &ob_offsets->vert, + &ob_offsets->edge, + &ob_offsets->face); + + ob_offsets->offset = offset; + e_data.context.index_drawn_len = ob_offsets->vert; + e_data.context.objects_drawn[e_data.context.objects_drawn_len] = ob; + e_data.context.objects_drawn_len++; + e_data.runtime_new_objects++; + } + else if (sel_data) { + sel_data->is_drawn = false; + } } static void select_draw_scene(void *vedata) @@ -187,17 +269,26 @@ static void select_draw_scene(void *vedata) SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl; - /* Setup framebuffer */ - draw_select_framebuffer_select_id_setup(&e_data.context); - GPU_framebuffer_bind(e_data.context.framebuffer_select_id); + if (!e_data.runtime_new_objects) { + /* Nothing new needs to be drawn. */ + return; + } /* dithering and AA break color coding, so disable */ glDisable(GL_DITHER); - GPU_framebuffer_clear_color_depth( - e_data.context.framebuffer_select_id, (const float[4]){0.0f}, 1.0f); - DRW_view_set_active(stl->g_data->view_faces); + + if (!DRW_pass_is_empty(psl->depth_only_pass)) { + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + GPU_framebuffer_bind(dfbl->depth_only_fb); + GPU_framebuffer_clear_depth(dfbl->depth_only_fb, 1.0f); + DRW_draw_pass(psl->depth_only_pass); + } + + /* Setup framebuffer */ + GPU_framebuffer_bind(e_data.context.framebuffer_select_id); + DRW_draw_pass(psl->select_id_face_pass); if (e_data.context.select_mode & SCE_SELECT_EDGE) { @@ -221,7 +312,9 @@ static void select_engine_free(void) DRW_TEXTURE_FREE_SAFE(e_data.context.texture_u32); GPU_FRAMEBUFFER_FREE_SAFE(e_data.context.framebuffer_select_id); + MEM_SAFE_FREE(e_data.context.objects); MEM_SAFE_FREE(e_data.context.index_offsets); + MEM_SAFE_FREE(e_data.context.objects_drawn); } /** \} */ diff --git a/source/blender/draw/engines/select/select_private.h b/source/blender/draw/engines/select/select_private.h index d95b14ff2b6..e48ce4314ae 100644 --- a/source/blender/draw/engines/select/select_private.h +++ b/source/blender/draw/engines/select/select_private.h @@ -32,6 +32,7 @@ typedef struct SELECTID_StorageList { } SELECTID_StorageList; typedef struct SELECTID_PassList { + struct DRWPass *depth_only_pass; struct DRWPass *select_id_face_pass; struct DRWPass *select_id_edge_pass; struct DRWPass *select_id_vert_pass; @@ -52,18 +53,21 @@ typedef struct SELECTID_Shaders { } SELECTID_Shaders; typedef struct SELECTID_PrivateData { + DRWShadingGroup *shgrp_depth_only; DRWShadingGroup *shgrp_face_unif; DRWShadingGroup *shgrp_face_flat; DRWShadingGroup *shgrp_edge; DRWShadingGroup *shgrp_vert; + DRWView *view_subregion; DRWView *view_faces; DRWView *view_edges; DRWView *view_verts; } SELECTID_PrivateData; /* Transient data */ /* select_draw_utils.c */ -void draw_select_framebuffer_select_id_setup(struct SELECTID_Context *r_select_ctx); +void select_id_context_clear(struct SELECTID_Context *select_ctx); +void select_id_object_min_max(struct Object *obj, float r_min[3], float r_max[3]); short select_id_get_object_select_mode(Scene *scene, Object *ob); void select_id_draw_object(void *vedata, View3D *v3d, diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 070713ad404..1046e0422c1 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2555,20 +2555,11 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph, DRW_opengl_context_disable(); } -void DRW_draw_select_id(Depsgraph *depsgraph, - ARegion *ar, - View3D *v3d, - Base **bases, - const uint bases_len, - short select_mode) +void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, const rcti *rect) { Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - DRW_select_buffer_context_create(bases, bases_len, select_mode); - - DRW_opengl_context_enable(); - /* Reset before using it. */ drw_state_prepare_clean_for_draw(&DST); DST.buffer_finish_called = true; @@ -2584,7 +2575,6 @@ void DRW_draw_select_id(Depsgraph *depsgraph, .depsgraph = depsgraph, }; - use_drw_engine(&draw_engine_select_type); drw_context_state_init(); /* Setup viewport */ @@ -2594,16 +2584,18 @@ void DRW_draw_select_id(Depsgraph *depsgraph, /* Update ubos */ DRW_globals_update(); - /* Init engines */ - drw_engines_init(); + /* Init Select Engine */ + struct SELECTID_Context *sel_ctx = DRW_select_engine_context_get(); + sel_ctx->last_rect = *rect; + use_drw_engine(&draw_engine_select_type); + drw_engines_init(); { drw_engines_cache_init(); - /* Keep `base_index` in sync with `e_data.context.last_base_drawn`. - * So don't skip objects. */ - for (uint base_index = 0; base_index < bases_len; base_index++) { - Object *obj_eval = DEG_get_evaluated_object(depsgraph, bases[base_index]->object); + Object **obj = &sel_ctx->objects[0]; + for (uint remaining = sel_ctx->objects_len; remaining--; obj++) { + Object *obj_eval = DEG_get_evaluated_object(depsgraph, *obj); drw_engines_cache_populate(obj_eval); } @@ -2621,10 +2613,6 @@ void DRW_draw_select_id(Depsgraph *depsgraph, /* Avoid accidental reuse. */ drw_state_ensure_not_reused(&DST); #endif - - /* Changin context */ - GPU_framebuffer_restore(); - DRW_opengl_context_disable(); } /** See #DRW_shgroup_world_clip_planes_from_rv3d. */ diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c index cd876b7b068..06bfd7a0d52 100644 --- a/source/blender/draw/intern/draw_select_buffer.c +++ b/source/blender/draw/intern/draw_select_buffer.c @@ -32,58 +32,81 @@ #include "GPU_select.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "DRW_engine.h" #include "DRW_select_buffer.h" #include "draw_manager.h" +#include "../engines/select/select_engine.h" + /* -------------------------------------------------------------------- */ /** \name Buffer of select ID's * \{ */ -/* Read a block of pixels from the select frame buffer. */ -uint *DRW_select_buffer_read(const rcti *rect, uint *r_buf_len) +/* Main function to read a block of pixels from the select frame buffer. */ +uint *DRW_select_buffer_read(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const rcti *rect, + uint *r_buf_len) { - struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); + uint *r_buf = NULL; + uint buf_len = 0; - /* clamp rect by texture */ + /* Clamp rect. */ rcti r = { .xmin = 0, - .xmax = GPU_texture_width(select_ctx->texture_u32), + .xmax = ar->winx, .ymin = 0, - .ymax = GPU_texture_height(select_ctx->texture_u32), + .ymax = ar->winy, }; + /* Make sure that the rect is within the bounds of the viewport. + * Some GPUs have problems reading pixels off limits. */ rcti rect_clamp = *rect; if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) { - uint buf_len = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); - uint *r_buf = MEM_mallocN(buf_len * sizeof(*r_buf), __func__); + struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); DRW_opengl_context_enable(); - GPU_framebuffer_bind(select_ctx->framebuffer_select_id); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(rect_clamp.xmin, - rect_clamp.ymin, - BLI_rcti_size_x(&rect_clamp), - BLI_rcti_size_y(&rect_clamp), - GL_RED_INTEGER, - GL_UNSIGNED_INT, - r_buf); + /* Update the drawing. */ + DRW_draw_select_id(depsgraph, ar, v3d, rect); + + if (select_ctx->index_drawn_len > 1) { + BLI_assert(ar->winx == GPU_texture_width(select_ctx->texture_u32) && + ar->winy == GPU_texture_height(select_ctx->texture_u32)); + + /* Read the UI32 pixels. */ + buf_len = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); + r_buf = MEM_mallocN(buf_len * sizeof(*r_buf), __func__); + + GPU_framebuffer_bind(select_ctx->framebuffer_select_id); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glReadPixels(rect_clamp.xmin, + rect_clamp.ymin, + BLI_rcti_size_x(&rect_clamp), + BLI_rcti_size_y(&rect_clamp), + GL_RED_INTEGER, + GL_UNSIGNED_INT, + r_buf); + + if (!BLI_rcti_compare(rect, &rect_clamp)) { + /* The rect has been clamped so you need to realign the buffer and fill in the blanks */ + GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); + } + } GPU_framebuffer_restore(); DRW_opengl_context_disable(); + } - if (!BLI_rcti_compare(rect, &rect_clamp)) { - GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); - } - - if (r_buf_len) { - *r_buf_len = buf_len; - } - - return r_buf; + if (r_buf_len) { + *r_buf_len = buf_len; } - return NULL; + + return r_buf; } /** \} */ @@ -101,25 +124,27 @@ uint *DRW_select_buffer_read(const rcti *rect, uint *r_buf_len) * \param mask: Specifies the rect pixels (optional). * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure. */ -uint *DRW_select_buffer_bitmap_from_rect(const rcti *rect, uint *r_bitmap_len) +uint *DRW_select_buffer_bitmap_from_rect(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const rcti *rect, + uint *r_bitmap_len) { struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); - const uint bitmap_len = select_ctx->last_index_drawn; - if (bitmap_len == 0) { - return NULL; - } - rcti rect_px = *rect; rect_px.xmax += 1; rect_px.ymax += 1; uint buf_len; - uint *buf = DRW_select_buffer_read(&rect_px, &buf_len); + uint *buf = DRW_select_buffer_read(depsgraph, ar, v3d, &rect_px, &buf_len); if (buf == NULL) { return NULL; } + BLI_assert(select_ctx->index_drawn_len > 0); + const uint bitmap_len = select_ctx->index_drawn_len - 1; + BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); const uint *buf_iter = buf; while (buf_len--) { @@ -144,17 +169,15 @@ uint *DRW_select_buffer_bitmap_from_rect(const rcti *rect, uint *r_bitmap_len) * \param radius: Circle radius. * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure. */ -uint *DRW_select_buffer_bitmap_from_circle(const int center[2], +uint *DRW_select_buffer_bitmap_from_circle(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2], const int radius, uint *r_bitmap_len) { struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); - const uint bitmap_len = select_ctx->last_index_drawn; - if (bitmap_len == 0) { - return NULL; - } - const rcti rect = { .xmin = center[0] - radius, .xmax = center[0] + radius + 1, @@ -162,15 +185,17 @@ uint *DRW_select_buffer_bitmap_from_circle(const int center[2], .ymax = center[1] + radius + 1, }; - const uint *buf = DRW_select_buffer_read(&rect, NULL); + const uint *buf = DRW_select_buffer_read(depsgraph, ar, v3d, &rect, NULL); if (buf == NULL) { return NULL; } - const uint *buf_iter = buf; + BLI_assert(select_ctx->index_drawn_len > 0); + const uint bitmap_len = select_ctx->index_drawn_len - 1; BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); + const uint *buf_iter = buf; const int radius_sq = radius * radius; for (int yc = -radius; yc <= radius; yc++) { for (int xc = -radius; xc <= radius; xc++, buf_iter++) { @@ -214,21 +239,22 @@ static void drw_select_mask_px_cb(int x, int x_end, int y, void *user_data) * \param rect: Polygon boundaries. * \returns a #BLI_bitmap. */ -uint *DRW_select_buffer_bitmap_from_poly(const int poly[][2], const int poly_len, const rcti *rect) +uint *DRW_select_buffer_bitmap_from_poly(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int poly[][2], + const int poly_len, + const rcti *rect, + uint *r_bitmap_len) { struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); - const uint bitmap_len = select_ctx->last_index_drawn; - if (bitmap_len == 0) { - return NULL; - } - rcti rect_px = *rect; rect_px.xmax += 1; rect_px.ymax += 1; uint buf_len; - uint *buf = DRW_select_buffer_read(&rect_px, &buf_len); + uint *buf = DRW_select_buffer_read(depsgraph, ar, v3d, &rect_px, &buf_len); if (buf == NULL) { return NULL; } @@ -248,6 +274,9 @@ uint *DRW_select_buffer_bitmap_from_poly(const int poly[][2], const int poly_len drw_select_mask_px_cb, &poly_mask_data); + BLI_assert(select_ctx->index_drawn_len > 0); + const uint bitmap_len = select_ctx->index_drawn_len - 1; + BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); const uint *buf_iter = buf; int i = 0; @@ -262,6 +291,10 @@ uint *DRW_select_buffer_bitmap_from_poly(const int poly[][2], const int poly_len MEM_freeN((void *)buf); MEM_freeN(buf_mask); + if (r_bitmap_len) { + *r_bitmap_len = bitmap_len; + } + return bitmap_buf; } @@ -277,8 +310,13 @@ uint *DRW_select_buffer_bitmap_from_poly(const int poly[][2], const int poly_len /** * Samples a single pixel. */ -uint DRW_select_buffer_sample_point(const int center[2]) +uint DRW_select_buffer_sample_point(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2]) { + uint ret = 0; + const rcti rect = { .xmin = center[0], .xmax = center[0] + 1, @@ -287,10 +325,13 @@ uint DRW_select_buffer_sample_point(const int center[2]) }; uint buf_len; - uint *buf = DRW_select_buffer_read(&rect, &buf_len); - BLI_assert(0 != buf_len); - uint ret = buf[0]; - MEM_freeN(buf); + uint *buf = DRW_select_buffer_read(depsgraph, ar, v3d, &rect, &buf_len); + if (buf) { + BLI_assert(0 != buf_len); + ret = buf[0]; + MEM_freeN(buf); + } + return ret; } @@ -299,7 +340,10 @@ uint DRW_select_buffer_sample_point(const int center[2]) * \param dist[in,out]: Use to initialize the distance, * when found, this value is set to the distance of the selection that's returned. */ -uint DRW_select_buffer_find_nearest_to_point(const int center[2], +uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + const int center[2], const uint id_min, const uint id_max, uint *dist) @@ -324,7 +368,7 @@ uint DRW_select_buffer_find_nearest_to_point(const int center[2], /* Read from selection framebuffer. */ uint buf_len; - const uint *buf = DRW_select_buffer_read(&rect, &buf_len); + const uint *buf = DRW_select_buffer_read(depsgraph, ar, v3d, &rect, &buf_len); if (buf == NULL) { return index; @@ -401,10 +445,10 @@ bool DRW_select_buffer_elem_get(const uint sel_id, struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); char elem_type = 0; - uint elem_id; + uint elem_id = 0; uint base_index = 0; - for (; base_index < select_ctx->objects_len; base_index++) { + for (; base_index < select_ctx->objects_drawn_len; base_index++) { struct ObjectOffsets *base_ofs = &select_ctx->index_offsets[base_index]; if (base_ofs->face > sel_id) { @@ -431,7 +475,8 @@ bool DRW_select_buffer_elem_get(const uint sel_id, *r_elem = elem_id; if (r_base_index) { - *r_base_index = base_index; + Object *obj_orig = DEG_get_original_object(select_ctx->objects_drawn[base_index]); + *r_base_index = obj_orig->runtime.select_id; } if (r_elem_type) { @@ -441,19 +486,31 @@ bool DRW_select_buffer_elem_get(const uint sel_id, return true; } -uint DRW_select_buffer_context_offset_for_object_elem(const uint base_index, char elem_type) +uint DRW_select_buffer_context_offset_for_object_elem(Depsgraph *depsgraph, + Object *object, + char elem_type) { struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); - struct ObjectOffsets *base_ofs = &select_ctx->index_offsets[base_index]; + + Object *ob_eval = DEG_get_evaluated_object(depsgraph, object); + + SELECTID_ObjectData *sel_data = (SELECTID_ObjectData *)DRW_drawdata_get( + &ob_eval->id, &draw_engine_select_type); + + if (!sel_data || !sel_data->is_drawn) { + return 0; + } + + struct ObjectOffsets *base_ofs = &select_ctx->index_offsets[sel_data->drawn_index]; if (elem_type == SCE_SELECT_VERTEX) { - return base_ofs->vert_start - 1; + return base_ofs->vert_start; } if (elem_type == SCE_SELECT_EDGE) { - return base_ofs->edge_start - 1; + return base_ofs->edge_start; } if (elem_type == SCE_SELECT_FACE) { - return base_ofs->face_start - 1; + return base_ofs->face_start; } BLI_assert(0); return 0; @@ -465,35 +522,29 @@ uint DRW_select_buffer_context_offset_for_object_elem(const uint base_index, cha /** \name Context * \{ */ -void DRW_select_buffer_context_create(Base **UNUSED(bases), - const uint bases_len, - short select_mode) +void DRW_select_buffer_context_create(Base **bases, const uint bases_len, short select_mode) { struct SELECTID_Context *select_ctx = DRW_select_engine_context_get(); - select_ctx->select_mode = select_mode; - select_ctx->objects_len = bases_len; + select_ctx->objects = MEM_reallocN(select_ctx->objects, + sizeof(*select_ctx->objects) * bases_len); - MEM_SAFE_FREE(select_ctx->index_offsets); - select_ctx->index_offsets = MEM_mallocN(sizeof(*select_ctx->index_offsets) * bases_len, - __func__); -} + select_ctx->index_offsets = MEM_reallocN(select_ctx->index_offsets, + sizeof(*select_ctx->index_offsets) * bases_len); -/** \} */ + select_ctx->objects_drawn = MEM_reallocN(select_ctx->objects_drawn, + sizeof(*select_ctx->objects_drawn) * bases_len); -/* -------------------------------------------------------------------- */ -/** \name Legacy - * \{ */ + for (uint base_index = 0; base_index < bases_len; base_index++) { + Object *obj = bases[base_index]->object; + select_ctx->objects[base_index] = obj; -void DRW_draw_select_id_object(Depsgraph *depsgraph, - ViewLayer *view_layer, - ARegion *ar, - View3D *v3d, - Object *ob, - short select_mode) -{ - Base *base = BKE_view_layer_base_find(view_layer, ob); - DRW_draw_select_id(depsgraph, ar, v3d, &base, 1, select_mode); -} + /* Weak but necessary for `DRW_select_buffer_elem_get`. */ + obj->runtime.select_id = base_index; + } + select_ctx->objects_len = bases_len; + select_ctx->select_mode = select_mode; + memset(select_ctx->persmat, 0, sizeof(select_ctx->persmat)); +} /** \} */ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 2f4688e2de7..94ffd9a34d6 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -317,9 +317,10 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ { - DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_VERTEX); + DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_VERTEX); - index = DRW_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); + index = DRW_select_buffer_find_nearest_to_point( + vc->depsgraph, vc->ar, vc->v3d, vc->mval, 1, UINT_MAX, &dist_px); if (index) { eve = (BMVert *)edbm_select_id_bm_elem_get(bases, index, &base_index); @@ -539,9 +540,10 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ { - DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_EDGE); + DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_EDGE); - index = DRW_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); + index = DRW_select_buffer_find_nearest_to_point( + vc->depsgraph, vc->ar, vc->v3d, vc->mval, 1, UINT_MAX, &dist_px); if (index) { eed = (BMEdge *)edbm_select_id_bm_elem_get(bases, index, &base_index); @@ -745,9 +747,9 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, BMFace *efa; { - DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_FACE); + DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_FACE); - index = DRW_select_buffer_sample_point(vc->mval); + index = DRW_select_buffer_sample_point(vc->depsgraph, vc->ar, vc->v3d, vc->mval); if (index) { efa = (BMFace *)edbm_select_id_bm_elem_get(bases, index, &base_index); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 0bdc59c7185..8d9d0e40f44 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1116,11 +1116,12 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px, if (dist_px) { /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - *r_index = DRW_select_buffer_find_nearest_to_point(mval, 1, me->totpoly + 1, &dist_px); + *r_index = DRW_select_buffer_find_nearest_to_point( + vc.depsgraph, vc.ar, vc.v3d, mval, 1, me->totpoly + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = DRW_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(vc.depsgraph, vc.ar, vc.v3d, mval); } if ((*r_index) == 0 || (*r_index) > (unsigned int)me->totpoly) { @@ -1297,11 +1298,12 @@ bool ED_mesh_pick_vert( if (dist_px > 0) { /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - *r_index = DRW_select_buffer_find_nearest_to_point(mval, 1, me->totvert + 1, &dist_px); + *r_index = DRW_select_buffer_find_nearest_to_point( + vc.depsgraph, vc.ar, vc.v3d, mval, 1, me->totvert + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = DRW_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(vc.depsgraph, vc.ar, vc.v3d, mval); } if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) { diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 806b7c471c6..4b9d9a2cc01 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -392,7 +392,7 @@ static int imapaint_pick_face(ViewContext *vc, /* sample only on the exact position */ ED_view3d_select_id_validate(vc); - *r_index = DRW_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(vc->depsgraph, vc->ar, vc->v3d, mval); if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) { return 0; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 040b257bb90..02ad481e6ce 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -185,7 +185,8 @@ static void validate_object_select_id( } if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { - DRW_draw_select_id_object(depsgraph, view_layer, ar, v3d, obact, -1); + Base *base = BKE_view_layer_base_find(view_layer, obact); + DRW_select_buffer_context_create(&base, 1, -1); } /* TODO: Create a flag in `DRW_manager` because the drawing is no longer diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a6728aef705..9a37c10180d 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -197,8 +197,6 @@ static bool object_deselect_all_except(ViewLayer *view_layer, Base *b) * \{ */ struct EditSelectBuf_Cache { - Base **bases; - uint bases_len; BLI_bitmap *select_bitmap; }; @@ -207,33 +205,25 @@ static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, short select_mode) { if (vc->obedit) { - esel->bases = BKE_view_layer_array_from_bases_in_edit_mode( - vc->view_layer, vc->v3d, &esel->bases_len); + uint bases_len = 0; + Base **bases = BKE_view_layer_array_from_bases_in_edit_mode( + vc->view_layer, vc->v3d, &bases_len); + + DRW_select_buffer_context_create(bases, bases_len, select_mode); + MEM_freeN(bases); } else { /* Use for paint modes, currently only a single object at a time. */ if (vc->obact) { - esel->bases = MEM_mallocN(sizeof(esel->bases), __func__); - esel->bases[0] = BKE_view_layer_base_find(vc->view_layer, vc->obact); - esel->bases_len = 1; - } - else { - esel->bases = NULL; - esel->bases_len = 0; + Base *base = BKE_view_layer_base_find(vc->view_layer, vc->obact); + DRW_select_buffer_context_create(&base, 1, select_mode); } } - - DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, esel->bases, esel->bases_len, select_mode); - - for (int i = 0; i < esel->bases_len; i++) { - esel->bases[i]->object->runtime.select_id = i; - } } static void editselect_buf_cache_free(struct EditSelectBuf_Cache *esel) { MEM_SAFE_FREE(esel->select_bitmap); - MEM_SAFE_FREE(esel->bases); } static void editselect_buf_cache_free_voidp(void *esel_voidp) @@ -260,6 +250,7 @@ static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *w * \{ */ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel, + Depsgraph *depsgraph, Object *ob, BMEditMesh *em, const eSelectOp sel_op) @@ -269,9 +260,12 @@ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, - SCE_SELECT_VERTEX); + uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_VERTEX); + if (index == 0) { + return false; + } + index -= 1; BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT); @@ -288,6 +282,7 @@ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel } static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel, + Depsgraph *depsgraph, Object *ob, BMEditMesh *em, const eSelectOp sel_op) @@ -297,9 +292,12 @@ static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, - SCE_SELECT_EDGE); + uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_EDGE); + if (index == 0) { + return false; + } + index -= 1; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT); @@ -316,6 +314,7 @@ static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel } static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel, + Depsgraph *depsgraph, Object *ob, BMEditMesh *em, const eSelectOp sel_op) @@ -325,9 +324,12 @@ static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, - SCE_SELECT_FACE); + uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_FACE); + if (index == 0) { + return false; + } + index -= 1; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT); @@ -737,10 +739,12 @@ static void do_lasso_select_mesh__doSelectEdge_pass0(void *user_data, { struct LassoSelectUserData_ForMeshEdge *data_for_edge = user_data; LassoSelectUserData *data = data_for_edge->data; - const bool is_visible = (data_for_edge->esel ? - BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, - data_for_edge->backbuf_offset + index) : - true); + bool is_visible = true; + if (data_for_edge->backbuf_offset) { + uint bitmap_inedx = data_for_edge->backbuf_offset + index - 1; + is_visible = BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, bitmap_inedx); + } + const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT); const bool is_inside = (is_visible && edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) && @@ -761,10 +765,12 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data, { struct LassoSelectUserData_ForMeshEdge *data_for_edge = user_data; LassoSelectUserData *data = data_for_edge->data; - const bool is_visible = (data_for_edge->esel ? - BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, - data_for_edge->backbuf_offset + index) : - true); + bool is_visible = true; + if (data_for_edge->backbuf_offset) { + uint bitmap_inedx = data_for_edge->backbuf_offset + index - 1; + is_visible = BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, bitmap_inedx); + } + const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT); const bool is_inside = (is_visible && BLI_lasso_is_edge_inside(data->mcords, data->moves, @@ -831,13 +837,15 @@ static bool do_lasso_select_mesh(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, ts->selectmode); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly( + vc->depsgraph, vc->ar, vc->v3d, mcords, moves, &rect, NULL); } } if (ts->selectmode & SCE_SELECT_VERTEX) { if (use_zbuf) { - data.is_changed |= edbm_backbuf_check_and_select_verts(esel, vc->obedit, vc->em, sel_op); + data.is_changed |= edbm_backbuf_check_and_select_verts( + esel, vc->depsgraph, vc->obedit, vc->em, sel_op); } else { mesh_foreachScreenVert( @@ -850,7 +858,7 @@ static bool do_lasso_select_mesh(ViewContext *vc, .data = &data, .esel = use_zbuf ? esel : NULL, .backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( - vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : + vc->depsgraph, vc->obedit, SCE_SELECT_EDGE) : 0, }; @@ -866,7 +874,8 @@ static bool do_lasso_select_mesh(ViewContext *vc, if (ts->selectmode & SCE_SELECT_FACE) { if (use_zbuf) { - data.is_changed |= edbm_backbuf_check_and_select_faces(esel, vc->obedit, vc->em, sel_op); + data.is_changed |= edbm_backbuf_check_and_select_faces( + esel, vc->depsgraph, vc->obedit, vc->em, sel_op); } else { mesh_foreachScreenFace( @@ -1141,7 +1150,8 @@ static bool do_lasso_select_paintvert(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_VERTEX); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly( + vc->depsgraph, vc->ar, vc->v3d, mcords, moves, &rect, NULL); } } @@ -1199,7 +1209,8 @@ static bool do_lasso_select_paintface(ViewContext *vc, if (esel == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_FACE); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly( + vc->depsgraph, vc->ar, vc->v3d, mcords, moves, &rect, NULL); } if (esel->select_bitmap) { @@ -2554,7 +2565,8 @@ static bool do_paintvert_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_VERTEX); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect( + vc->depsgraph, vc->ar, vc->v3d, rect, NULL); } if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); @@ -2608,7 +2620,8 @@ static bool do_paintface_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_FACE); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect( + vc->depsgraph, vc->ar, vc->v3d, rect, NULL); } if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); @@ -2731,10 +2744,12 @@ static void do_mesh_box_select__doSelectEdge_pass0( { struct BoxSelectUserData_ForMeshEdge *data_for_edge = userData; BoxSelectUserData *data = data_for_edge->data; - const bool is_visible = (data_for_edge->esel ? - BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, - data_for_edge->backbuf_offset + index) : - true); + bool is_visible = true; + if (data_for_edge->backbuf_offset) { + uint bitmap_inedx = data_for_edge->backbuf_offset + index - 1; + is_visible = BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, bitmap_inedx); + } + const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT); const bool is_inside = (is_visible && edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b)); @@ -2750,10 +2765,12 @@ static void do_mesh_box_select__doSelectEdge_pass1( { struct BoxSelectUserData_ForMeshEdge *data_for_edge = userData; BoxSelectUserData *data = data_for_edge->data; - const bool is_visible = (data_for_edge->esel ? - BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, - data_for_edge->backbuf_offset + index) : - true); + bool is_visible = true; + if (data_for_edge->backbuf_offset) { + uint bitmap_inedx = data_for_edge->backbuf_offset + index - 1; + is_visible = BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap, bitmap_inedx); + } + const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT); const bool is_inside = (is_visible && edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b)); const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside); @@ -2805,13 +2822,15 @@ static bool do_mesh_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, ts->selectmode); esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect( + vc->depsgraph, vc->ar, vc->v3d, rect, NULL); } } if (ts->selectmode & SCE_SELECT_VERTEX) { if (use_zbuf) { - data.is_changed |= edbm_backbuf_check_and_select_verts(esel, vc->obedit, vc->em, sel_op); + data.is_changed |= edbm_backbuf_check_and_select_verts( + esel, vc->depsgraph, vc->obedit, vc->em, sel_op); } else { mesh_foreachScreenVert( @@ -2824,7 +2843,7 @@ static bool do_mesh_box_select(ViewContext *vc, .data = &data, .esel = use_zbuf ? esel : NULL, .backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( - vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : + vc->depsgraph, vc->obedit, SCE_SELECT_EDGE) : 0, }; @@ -2840,7 +2859,8 @@ static bool do_mesh_box_select(ViewContext *vc, if (ts->selectmode & SCE_SELECT_FACE) { if (use_zbuf) { - data.is_changed |= edbm_backbuf_check_and_select_faces(esel, vc->obedit, vc->em, sel_op); + data.is_changed |= edbm_backbuf_check_and_select_faces( + esel, vc->depsgraph, vc->obedit, vc->em, sel_op); } else { mesh_foreachScreenFace( @@ -3393,7 +3413,8 @@ static bool mesh_circle_select(ViewContext *vc, if (use_zbuf) { if (esel->select_bitmap == NULL) { - esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle( + vc->depsgraph, vc->ar, vc->v3d, mval, (int)(rad + 1.0f), NULL); } } @@ -3401,7 +3422,7 @@ static bool mesh_circle_select(ViewContext *vc, if (use_zbuf) { if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); } } else { @@ -3413,7 +3434,7 @@ static bool mesh_circle_select(ViewContext *vc, if (use_zbuf) { if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_edges( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); } } else { @@ -3426,7 +3447,7 @@ static bool mesh_circle_select(ViewContext *vc, if (use_zbuf) { if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); } } else { @@ -3464,7 +3485,8 @@ static bool paint_facesel_circle_select(ViewContext *vc, { struct EditSelectBuf_Cache *esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle( + vc->depsgraph, vc->ar, vc->v3d, mval, (int)(rad + 1.0f), NULL); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); MEM_freeN(esel->select_bitmap); @@ -3518,7 +3540,8 @@ static bool paint_vertsel_circle_select(ViewContext *vc, if (use_zbuf) { struct EditSelectBuf_Cache *esel = wm_userdata->data; - esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle( + vc->depsgraph, vc->ar, vc->v3d, mval, (int)(rad + 1.0f), NULL); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); MEM_freeN(esel->select_bitmap); -- cgit v1.2.3 From 9684971addf0dfa43fb7367d9102460e8093c523 Mon Sep 17 00:00:00 2001 From: Lazydodo Date: Thu, 15 Aug 2019 09:27:15 -0600 Subject: Fix T56843 : fix case sensitive filenames on win10 When building with case sensitive folders there were some linker errors. --- build_files/cmake/platform/platform_win32.cmake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 80097e6c84f..42ac285f88d 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -418,7 +418,7 @@ endif() if(WITH_OPENIMAGEIO) windows_find_package(OpenImageIO) - set(OPENIMAGEIO ${LIBDIR}/openimageio) + set(OPENIMAGEIO ${LIBDIR}/OpenImageIO) set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) set(OIIO_OPTIMIZED optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO.lib optimized ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util.lib) @@ -459,14 +459,14 @@ if(WITH_LLVM) endif() if(WITH_OPENCOLORIO) - set(OPENCOLORIO ${LIBDIR}/opencolorio) + set(OPENCOLORIO ${LIBDIR}/OpenColorIO) set(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO}/include) - set(OPENCOLORIO_LIBPATH ${LIBDIR}/opencolorio/lib) + set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib) set(OPENCOLORIO_LIBRARIES optimized ${OPENCOLORIO_LIBPATH}/OpenColorIO.lib optimized ${OPENCOLORIO_LIBPATH}/tinyxml.lib optimized ${OPENCOLORIO_LIBPATH}/libyaml-cpp.lib - debug ${OPENCOLORIO_LIBPATH}/OpenColorIO_d.lib + debug ${OPENCOLORIO_LIBPATH}/OpencolorIO_d.lib debug ${OPENCOLORIO_LIBPATH}/tinyxml_d.lib debug ${OPENCOLORIO_LIBPATH}/libyaml-cpp_d.lib ) @@ -477,8 +477,8 @@ if(WITH_OPENVDB) set(BLOSC_LIBRARIES optimized ${LIBDIR}/blosc/lib/libblosc.lib debug ${LIBDIR}/blosc/lib/libblosc_d.lib) set(TBB_LIBRARIES optimized ${LIBDIR}/tbb/lib/tbb.lib debug ${LIBDIR}/tbb/lib/tbb_debug.lib) set(TBB_INCLUDE_DIR ${LIBDIR}/tbb/include) - set(OPENVDB ${LIBDIR}/openvdb) - set(OPENVDB_LIBPATH ${LIBDIR}/openvdb/lib) + set(OPENVDB ${LIBDIR}/openVDB) + set(OPENVDB_LIBPATH ${OPENVDB}/lib) set(OPENVDB_INCLUDE_DIRS ${OPENVDB}/include ${TBB_INCLUDE_DIR}) set(OPENVDB_LIBRARIES optimized ${OPENVDB_LIBPATH}/openvdb.lib debug ${OPENVDB_LIBPATH}/openvdb_d.lib ${TBB_LIBRARIES} ${BLOSC_LIBRARIES}) set(OPENVDB_DEFINITIONS -DNOMINMAX) @@ -502,7 +502,7 @@ if(WITH_ALEMBIC) set(ALEMBIC_INCLUDE_DIR ${ALEMBIC}/include) set(ALEMBIC_INCLUDE_DIRS ${ALEMBIC_INCLUDE_DIR}) set(ALEMBIC_LIBPATH ${ALEMBIC}/lib) - set(ALEMBIC_LIBRARIES optimized ${ALEMBIC}/lib/alembic.lib debug ${ALEMBIC}/lib/alembic_d.lib) + set(ALEMBIC_LIBRARIES optimized ${ALEMBIC}/lib/Alembic.lib debug ${ALEMBIC}/lib/Alembic_d.lib) set(ALEMBIC_FOUND 1) endif() -- cgit v1.2.3 From f4faf6d8560d7565f77823247d2f7f7650bba975 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 12:16:43 -0300 Subject: Cleanup: Remove redundant headers --- source/blender/draw/engines/select/select_engine.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c index f437efe0c41..4c158312e0f 100644 --- a/source/blender/draw/engines/select/select_engine.c +++ b/source/blender/draw/engines/select/select_engine.c @@ -24,15 +24,11 @@ #include "DNA_screen_types.h" -#include "GPU_shader.h" - #include "UI_resources.h" #include "DRW_engine.h" #include "DRW_select_buffer.h" -#include "DRW_select_buffer.h" - #include "draw_cache_impl.h" #include "draw_manager.h" -- cgit v1.2.3 From 4aad773061555144e77e6094fc0247831d397041 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 12:34:31 -0300 Subject: Cleanup: Silence C4115 warning `'ParticleSystem': named type definition in parentheses` And prevent the need for struct `Object` to be defined. --- source/blender/draw/intern/draw_cache.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 129b180957a..5dadcdc1457 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -27,6 +27,7 @@ struct GPUBatch; struct GPUMaterial; struct ModifierData; struct Object; +struct ParticleSystem; struct PTCacheEdit; void DRW_shape_cache_free(void); @@ -58,7 +59,7 @@ struct GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); -struct GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob); +struct GPUBatch *DRW_cache_object_face_wireframe_get(struct Object *ob); /* Empties */ struct GPUBatch *DRW_cache_plain_axes_get(void); @@ -152,7 +153,7 @@ struct GPUBatch **DRW_cache_curve_surface_shaded_get(struct Object *ob, uint gpumat_array_len); struct GPUBatch *DRW_cache_curve_loose_edges_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); -struct GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob); +struct GPUBatch *DRW_cache_curve_face_wireframe_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_detection_get(struct Object *ob, bool *r_is_manifold); /* edit-mode */ struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob); @@ -161,13 +162,13 @@ struct GPUBatch *DRW_cache_curve_vert_overlay_get(struct Object *ob, bool handle /* Font */ struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob); -struct GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold); +struct GPUBatch *DRW_cache_text_edge_detection_get(struct Object *ob, bool *r_is_manifold); struct GPUBatch *DRW_cache_text_loose_edges_get(struct Object *ob); struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob); struct GPUBatch **DRW_cache_text_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); -struct GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob); +struct GPUBatch *DRW_cache_text_face_wireframe_get(struct Object *ob); /* Surface */ struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob); @@ -176,7 +177,7 @@ struct GPUBatch *DRW_cache_surf_loose_edges_get(struct Object *ob); struct GPUBatch **DRW_cache_surf_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); -struct GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob); +struct GPUBatch *DRW_cache_surf_face_wireframe_get(struct Object *ob); struct GPUBatch *DRW_cache_surf_edge_detection_get(struct Object *ob, bool *r_is_manifold); /* Lattice */ @@ -206,7 +207,7 @@ struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob); struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); -struct GPUBatch *DRW_cache_mball_face_wireframe_get(Object *ob); +struct GPUBatch *DRW_cache_mball_face_wireframe_get(struct Object *ob); struct GPUBatch *DRW_cache_mball_edge_detection_get(struct Object *ob, bool *r_is_manifold); #endif /* __DRAW_CACHE_H__ */ -- cgit v1.2.3 From 8856c26fc364b4590755dacf132abe5ae7dac543 Mon Sep 17 00:00:00 2001 From: Lazydodo Date: Thu, 15 Aug 2019 09:42:00 -0600 Subject: Windows: add cycles debug logging to helper batch file. --- release/windows/batch/blender_debug_log.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/windows/batch/blender_debug_log.cmd b/release/windows/batch/blender_debug_log.cmd index ecb5803a5c9..2d708ea9104 100644 --- a/release/windows/batch/blender_debug_log.cmd +++ b/release/windows/batch/blender_debug_log.cmd @@ -12,5 +12,5 @@ mkdir "%temp%\blender\debug_logs" > NUL 2>&1 echo. echo Starting blender and waiting for it to exit.... set PYTHONPATH= -blender --debug --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0 +blender --debug --debug-cycles --python-expr "import bpy; bpy.ops.wm.sysinfo(filepath=r'%temp%\blender\debug_logs\blender_system_info.txt')" > "%temp%\blender\debug_logs\blender_debug_output.txt" 2>&1 < %0 explorer "%temp%\blender\debug_logs" -- cgit v1.2.3 From c883fe25da9b325b4e32074d5492edff703ce257 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Aug 2019 01:59:13 +1000 Subject: Cleanup: clang-format, unused arg --- source/blender/blenlib/intern/delaunay_2d.c | 2 +- source/blender/editors/space_view3d/view3d_select.c | 6 ++---- tests/gtests/blenlib/BLI_delaunay_2d_test.cc | 5 ++++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c index 632847046a7..23f560c5463 100644 --- a/source/blender/blenlib/intern/delaunay_2d.c +++ b/source/blender/blenlib/intern/delaunay_2d.c @@ -1961,7 +1961,7 @@ static void add_face_ids( } } -/* Delete_edge but try not to mess up outer face. +/* Delete_edge but try not to mess up outer face. * Also faces have symedges now, so make sure not * to mess those up either. */ static void dissolve_symedge(CDT_state *cdt, SymEdge *se) diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 9a37c10180d..725f655c8ce 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -200,9 +200,7 @@ struct EditSelectBuf_Cache { BLI_bitmap *select_bitmap; }; -static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, - ViewContext *vc, - short select_mode) +static void editselect_buf_cache_init(ViewContext *vc, short select_mode) { if (vc->obedit) { uint bases_len = 0; @@ -240,7 +238,7 @@ static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *w wm_userdata->data = esel; wm_userdata->free_fn = editselect_buf_cache_free_voidp; wm_userdata->use_free = true; - editselect_buf_cache_init(esel, vc, select_mode); + editselect_buf_cache_init(vc, select_mode); } /** \} */ diff --git a/tests/gtests/blenlib/BLI_delaunay_2d_test.cc b/tests/gtests/blenlib/BLI_delaunay_2d_test.cc index 5b44c6277a3..ce84baf802a 100644 --- a/tests/gtests/blenlib/BLI_delaunay_2d_test.cc +++ b/tests/gtests/blenlib/BLI_delaunay_2d_test.cc @@ -650,7 +650,10 @@ enum { }; // #define DO_TIMING -static void rand_delaunay_test(int test_kind, int max_lg_size, int reps_per_size, CDT_output_type otype) +static void rand_delaunay_test(int test_kind, + int max_lg_size, + int reps_per_size, + CDT_output_type otype) { CDT_input in; CDT_result *out; -- cgit v1.2.3 From f61c6a2a1fcae9f9175fc4ec8e61e39037f0d102 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Aug 2019 18:09:58 +0200 Subject: Build: enable OpenImageDenoise, now that we have libraries for all platforms Note that we are still missing an update for install_deps.sh to easily build this on Linux. Only "make deps" has it for now. --- CMakeLists.txt | 8 +++++--- build_files/cmake/config/blender_full.cmake | 2 +- build_files/cmake/config/blender_release.cmake | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a7a020c428..16ac322ebdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,6 +182,8 @@ if(UNIX AND NOT APPLE) set(_init_SDL OFF) set(_init_FFTW3 OFF) set(_init_OPENSUBDIV OFF) + set(_init_OPENVDB OFF) + set(_init_OPENIMAGEDENOISE OFF) elseif(WIN32) set(_init_JACK OFF) elseif(APPLE) @@ -237,12 +239,12 @@ option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLO # Compositor option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON) -option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" OFF) +option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ${_init_OPENIMAGEDENOISE}) option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ${_init_OPENSUBDIV}) -option(WITH_OPENVDB "Enable features relying on OpenVDB" OFF) -option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" OFF) +option(WITH_OPENVDB "Enable features relying on OpenVDB" ${_init_OPENVDB}) +option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" ${_init_OPENVDB}) option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF) mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE) diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index 38371ccb60e..75c5e0f34c1 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -40,7 +40,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE) set(WITH_OPENAL ON CACHE BOOL "" FORCE) set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE) set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE) -set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE) +set(WITH_OPENIMAGEDENOISE ON CACHE BOOL "" FORCE) set(WITH_OPENMP ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE) set(WITH_OPENVDB ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 682f456dd3d..08218a5e57c 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -41,7 +41,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE) set(WITH_OPENAL ON CACHE BOOL "" FORCE) set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE) set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE) -set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE) +set(WITH_OPENIMAGEDENOISE ON CACHE BOOL "" FORCE) set(WITH_OPENMP ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE) set(WITH_OPENVDB ON CACHE BOOL "" FORCE) -- cgit v1.2.3 From 5d72ceb8d806cef9fc4ff12d0678c2e649b4b339 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Aug 2019 18:20:33 +0200 Subject: Fix broken text editing of integer number buttons, after recent changes --- source/blender/editors/interface/interface_handlers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 8fd39b5d120..0cb0dbdc85c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4820,6 +4820,9 @@ static int ui_do_but_NUM( } button_activate_state(C, but, BUTTON_STATE_EXIT); } + else { + button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + } } else { /* Float Value. */ -- cgit v1.2.3 From b5fe838d44089abef761cb4723aa2d795299c68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 15 Aug 2019 18:46:29 +0200 Subject: Fix T68689 Fix infinite recursion cause by versioning code Complex nodetrees could fire infinite recursion with previous algo. Now using another gset we make sure we can only evaluate a tree once. --- source/blender/blenloader/intern/versioning_280.c | 44 +++++++++++++++-------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 462d32d40bd..8cf98761919 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -737,7 +737,8 @@ static void do_versions_seq_alloc_transform_and_crop(ListBase *seqbase) /* Return true if there is something to convert. */ static bool do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, char blend_method, - GSet *nodegrp_tree_set) + GSet *nodegrp_tree_set, + GSet *nooutput_tree_set) { bool need_update = false; bool do_conversion = false; @@ -758,9 +759,10 @@ static bool do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, bNodeTree *group_ntree = (bNodeTree *)fromnode->id; if (BLI_gset_add(nodegrp_tree_set, group_ntree)) { /* Recursive but not convert (blend_method = -1). Conversion happens after. */ - if (!do_versions_material_convert_legacy_blend_mode(group_ntree, -1, nodegrp_tree_set)) { - /* There is no output to convert in the tree, remove it. */ - BLI_gset_remove(nodegrp_tree_set, group_ntree, NULL); + if (!do_versions_material_convert_legacy_blend_mode( + group_ntree, -1, nodegrp_tree_set, nooutput_tree_set)) { + /* There is no output to convert in the tree. */ + BLI_gset_add(nooutput_tree_set, group_ntree); } } } @@ -768,9 +770,10 @@ static bool do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, bNodeTree *group_ntree = (bNodeTree *)tonode->id; if (BLI_gset_add(nodegrp_tree_set, group_ntree)) { /* Recursive but not convert (blend_method = -1). Conversion happens after. */ - if (!do_versions_material_convert_legacy_blend_mode(group_ntree, -1, nodegrp_tree_set)) { - /* There is no output to convert in the tree, remove it. */ - BLI_gset_remove(nodegrp_tree_set, group_ntree, NULL); + if (!do_versions_material_convert_legacy_blend_mode( + group_ntree, -1, nodegrp_tree_set, nooutput_tree_set)) { + /* There is no output to convert in the tree. */ + BLI_gset_add(nooutput_tree_set, group_ntree); } } } @@ -1259,32 +1262,45 @@ void do_versions_after_linking_280(Main *bmain, ReportList *reports) GSet *ntrees_additive = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__); GSet *ntrees_multiply = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__); GSet *ntrees_nolegacy = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__); + GSet *ntrees_nooutput = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__); for (Material *ma = bmain->materials.first; ma; ma = ma->id.next) { bNodeTree *ntree = ma->nodetree; if (ma->blend_method == 1 /* MA_BM_ADD */) { if (ma->use_nodes) { - do_versions_material_convert_legacy_blend_mode(ntree, ma->blend_method, ntrees_additive); + do_versions_material_convert_legacy_blend_mode( + ntree, ma->blend_method, ntrees_additive, ntrees_nooutput); } ma->blend_method = MA_BM_BLEND; } else if (ma->blend_method == 2 /* MA_BM_MULTIPLY */) { if (ma->use_nodes) { - do_versions_material_convert_legacy_blend_mode(ntree, ma->blend_method, ntrees_multiply); + do_versions_material_convert_legacy_blend_mode( + ntree, ma->blend_method, ntrees_multiply, ntrees_nooutput); } ma->blend_method = MA_BM_BLEND; } else { /* Still tag the group nodes as not using legacy blend modes. */ if (ma->use_nodes) { - do_versions_material_convert_legacy_blend_mode(ntree, -1, ntrees_nolegacy); + do_versions_material_convert_legacy_blend_mode( + ntree, -1, ntrees_nolegacy, ntrees_nooutput); } } } - /* Remove group nodetree that are used by material using non-legacy blend mode. */ GHashIterState iter = {0}; bNodeTree *ntree; + /* Remove trees that have no output nodes. + * This is done separately to avoid infinite recursion. */ + while (BLI_gset_pop(ntrees_nooutput, (GSetIterState *)&iter, (void **)&ntree)) { + BLI_gset_remove(ntrees_additive, ntree, NULL); + BLI_gset_remove(ntrees_multiply, ntree, NULL); + BLI_gset_remove(ntrees_nolegacy, ntree, NULL); + } + BLI_gset_free(ntrees_nooutput, NULL); + /* Remove group nodetree that are used by material using non-legacy blend mode. */ + GHashIterState iter_rm = {0}; bool error = false; - while (BLI_gset_pop(ntrees_nolegacy, (GSetIterState *)&iter, (void **)&ntree)) { + while (BLI_gset_pop(ntrees_nolegacy, (GSetIterState *)&iter_rm, (void **)&ntree)) { if (BLI_gset_remove(ntrees_additive, ntree, NULL)) { error = true; } @@ -1297,10 +1313,10 @@ void do_versions_after_linking_280(Main *bmain, ReportList *reports) GHashIterState iter_add = {0}; GHashIterState iter_mul = {0}; while (BLI_gset_pop(ntrees_additive, (GSetIterState *)&iter_add, (void **)&ntree)) { - do_versions_material_convert_legacy_blend_mode(ntree, 1 /* MA_BM_ADD */, NULL); + do_versions_material_convert_legacy_blend_mode(ntree, 1 /* MA_BM_ADD */, NULL, NULL); } while (BLI_gset_pop(ntrees_multiply, (GSetIterState *)&iter_mul, (void **)&ntree)) { - do_versions_material_convert_legacy_blend_mode(ntree, 2 /* MA_BM_MULTIPLY */, NULL); + do_versions_material_convert_legacy_blend_mode(ntree, 2 /* MA_BM_MULTIPLY */, NULL, NULL); } BLI_gset_free(ntrees_additive, NULL); BLI_gset_free(ntrees_multiply, NULL); -- cgit v1.2.3 From cbd1739004f854f4970f95ea3ed512f2aecf2fe7 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 15 Aug 2019 16:38:31 -0300 Subject: Fix T68705: Changing any editor to the properties crashes Blender Issue introduced (more like exposed) in b7f86ff72273. --- source/blender/editors/space_buttons/buttons_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index fde8b8f85f8..bb381e0dd1e 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -785,11 +785,11 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r SpaceProperties *sbuts = CTX_wm_space_properties(C); ButsContextPath *path = sbuts ? sbuts->path : NULL; - if (sbuts->mainb == BCONTEXT_TOOL) { + if (!path) { return 0; } - if (!path) { + if (sbuts->mainb == BCONTEXT_TOOL) { return 0; } -- cgit v1.2.3 From 50ad4428ac76705dc28e4cd85272a47118b6a654 Mon Sep 17 00:00:00 2001 From: Lazydodo Date: Thu, 15 Aug 2019 13:43:27 -0600 Subject: Windows/MSI: Rework MSI installer. The installer always upgraded the last version installed and did not allow for two versions to be installed side by side. The reworked installer will allow side by side installs install order: ``` 2.81 -> 2.81a -> 2.82 : Allowed , will result in both 2.82 and 2.81a being installed 2.82 -> 2.81 -> 2.81a : Allowed , will result in both 2.82 and 2.81a being installed 2.82 -> 2.81a : Allowed , will result in both 2.82 and 2.81a being installed 2.82 -> 2.81a -> 2.81 : Not Allowed, 2.81 will only install if you manually remove 2.81a first. ``` Do note though that this will not apply to any previously issued installers and even for 2.80a this is not something we can fix. This patch is for landing in 2.81 *only* and should be excluded from any possible 2.80a release. Second change is a change to the compression level, building the MSI takes 30 minutes, which is crazy, perhaps worth it if the compression actually pays of. ``` MSI - none 1:35 247.0 MB (260,025,634 bytes) MSI - mszip 2:02 89.6 MB ( 94,022,946 bytes) MSI - low 2:35 81.6 MB ( 85,646,626 bytes) MSI - medium 4:11 77.3 MB ( 81,136,930 bytes) MSI - high 28:01 74.7 MB ( 78,384,418 bytes) zip 1:32 93.2 MB ( 97,732,293 bytes) 7Z 2:22 65.0 MB ( 68,171,614 bytes) ``` It didn't, so I lowered it to medium, seemed reasonable. Differential Revision: https://developer.blender.org/D5494 Reviewers: brecht, jesterking --- build_files/cmake/packaging.cmake | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake index 06a97fc9abb..5ace42646c5 100644 --- a/build_files/cmake/packaging.cmake +++ b/build_files/cmake/packaging.cmake @@ -80,22 +80,28 @@ if(APPLE) endif() if(WIN32) - set(CPACK_PACKAGE_INSTALL_DIRECTORY "Blender Foundation/Blender") - set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Blender Foundation/Blender") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "Blender Foundation/Blender ${MAJOR_VERSION}.${MINOR_VERSION}") + set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Blender Foundation/Blender ${MAJOR_VERSION}.${MINOR_VERSION}") set(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/release/windows/icons/winblender.ico) set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/release/text/GPL3-license.txt) set(CPACK_WIX_PRODUCT_ICON ${CMAKE_SOURCE_DIR}/release/windows/icons/winblender.ico) - set(CPACK_WIX_UPGRADE_GUID "B767E4FD-7DE7-4094-B051-3AE62E13A17A") + + set(BLENDER_NAMESPACE_GUID "507F933F-5898-404A-9A05-18282FD491A6") + + string(UUID CPACK_WIX_UPGRADE_GUID + NAMESPACE ${BLENDER_NAMESPACE_GUID} + NAME ${CPACK_PACKAGE_INSTALL_DIRECTORY} + TYPE SHA1 UPPER + ) set(CPACK_WIX_TEMPLATE ${LIBDIR}/package/installer_wix/WIX.template) set(CPACK_WIX_UI_BANNER ${LIBDIR}/package/installer_wix/WIX_UI_BANNER.bmp) set(CPACK_WIX_UI_DIALOG ${LIBDIR}/package/installer_wix/WIX_UI_DIALOG.bmp) - #force lzma instead of deflate - set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:high) + set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:medium) endif() set(CPACK_PACKAGE_EXECUTABLES "blender" "blender") -- cgit v1.2.3 From 0f79c346c63f21f246ab636d74eea9b7aa874a33 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 15 Aug 2019 17:08:38 -0300 Subject: Fix check that validates a selection index --- source/blender/draw/intern/draw_select_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c index 06bfd7a0d52..974ea22ccea 100644 --- a/source/blender/draw/intern/draw_select_buffer.c +++ b/source/blender/draw/intern/draw_select_buffer.c @@ -468,7 +468,7 @@ bool DRW_select_buffer_elem_get(const uint sel_id, } } - if (base_index == select_ctx->objects_len) { + if (base_index == select_ctx->objects_drawn_len) { return false; } -- cgit v1.2.3 From 266e7b67fd3e2c219d8646e37a2fb3e393df4bda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Aug 2019 04:54:10 +1000 Subject: Cleanup: use boolean --- source/blender/blenkernel/BKE_context.h | 4 ++-- source/blender/blenkernel/intern/context.c | 7 ++++--- source/blender/blenkernel/intern/image.c | 4 ++-- source/blender/editors/object/object_vgroup.c | 6 +++--- source/blender/editors/sculpt_paint/paint_image_undo.c | 12 ++++++------ .../blender/editors/sculpt_paint/paint_vertex_weight_ops.c | 4 ++-- source/creator/creator.c | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 53976b4c1ad..755a155653b 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -137,8 +137,8 @@ void CTX_store_free(bContextStore *store); void CTX_store_free_list(ListBase *contexts); /* need to store if python is initialized or not */ -int CTX_py_init_get(bContext *C); -void CTX_py_init_set(bContext *C, int value); +bool CTX_py_init_get(bContext *C); +void CTX_py_init_set(bContext *C, bool value); void *CTX_py_dict_get(const bContext *C); void CTX_py_dict_set(bContext *C, void *value); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 2cb98d8d90b..f536f21c3e5 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -89,7 +89,8 @@ struct bContext { struct Scene *scene; int recursion; - int py_init; /* true if python is initialized */ + /** True if python is initialized. */ + bool py_init; void *py_context; } data; }; @@ -212,11 +213,11 @@ void CTX_store_free_list(ListBase *contexts) /* is python initialized? */ -int CTX_py_init_get(bContext *C) +bool CTX_py_init_get(bContext *C) { return C->data.py_init; } -void CTX_py_init_set(bContext *C, int value) +void CTX_py_init_set(bContext *C, bool value) { C->data.py_init = value; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 8e04ef2d3ca..a99407b9bf9 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2766,8 +2766,8 @@ static void do_makepicstring(char *string, int frame, const char imtype, const ImageFormatData *im_format, - const short use_ext, - const short use_frames, + const bool use_ext, + const bool use_frames, const char *suffix) { if (string == NULL) { diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a43ac59c9b8..08fe5e818b2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1139,7 +1139,7 @@ static bool vgroup_normalize(Object *ob) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = vertex_group_use_vert_sel(ob); + const bool use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return false; @@ -1623,7 +1623,7 @@ static bool vgroup_normalize_all(Object *ob, int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = vertex_group_use_vert_sel(ob); + const bool use_vert_sel = vertex_group_use_vert_sel(ob); if (subset_count == 0) { BKE_report(reports, RPT_ERROR, "No vertex groups to operate on"); @@ -2047,7 +2047,7 @@ static int vgroup_limit_total_subset(Object *ob, { MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; - const int use_vert_sel = vertex_group_use_vert_sel(ob); + const bool use_vert_sel = vertex_group_use_vert_sel(ob); int remove_tot = 0; ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel); diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c index c7ec4f3f2b9..93dcd3ad0f6 100644 --- a/source/blender/editors/sculpt_paint/paint_image_undo.c +++ b/source/blender/editors/sculpt_paint/paint_image_undo.c @@ -75,7 +75,8 @@ typedef struct UndoImageTile { * adds unnecessary overhead restoring undo steps when most tiles share the same image. */ UndoRefID_Image image_ref; - short source, use_float; + short source; + bool use_float; char gen_type; bool valid; @@ -172,7 +173,7 @@ void *image_undo_find_tile(ListBase *undo_tiles, bool validate) { UndoImageTile *tile; - short use_float = ibuf->rect_float ? 1 : 0; + const bool use_float = (ibuf->rect_float != NULL); for (tile = undo_tiles->first; tile; tile = tile->next) { if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && @@ -214,7 +215,7 @@ void *image_undo_push_tile(ListBase *undo_tiles, { UndoImageTile *tile; int allocsize; - short use_float = ibuf->rect_float ? 1 : 0; + const bool use_float = (ibuf->rect_float != NULL); void *data; /* check if tile is already pushed */ @@ -315,7 +316,6 @@ static void image_undo_restore_list(ListBase *lb) IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); for (UndoImageTile *tile = lb->first; tile; tile = tile->next) { - short use_float; Image *ima = tile->image_ref.ptr; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); @@ -341,7 +341,7 @@ static void image_undo_restore_list(ListBase *lb) continue; } - use_float = ibuf->rect_float ? 1 : 0; + const bool use_float = (ibuf->rect_float != NULL); if (use_float != tile->use_float) { BKE_image_release_ibuf(ima, ibuf, NULL); @@ -450,7 +450,7 @@ static bool image_undosys_step_encode(struct bContext *C, tile = tmp_tile; } else { - us->step.data_size += allocsize * ((tile->use_float) ? sizeof(float) : sizeof(char)); + us->step.data_size += allocsize * (tile->use_float ? sizeof(float) : sizeof(char)); tile = tile->next; } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c index 72fc08cc38d..4aa9dc8a295 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -580,7 +580,7 @@ typedef struct WPGradient_userData { BLI_bitmap *vert_visit; /* options */ - short use_select; + bool use_select; short type; float weightpaint; } WPGradient_userData; @@ -786,7 +786,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.sco_end = sco_end; data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end); data.def_nr = ob->actdef - 1; - data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)); + data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; data.vert_cache = vert_cache; data.vert_visit = NULL; data.type = RNA_enum_get(op->ptr, "type"); diff --git a/source/creator/creator.c b/source/creator/creator.c index d6e1d7e7f5f..9eb1578001c 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -442,7 +442,7 @@ int main(int argc, "this is not intended for typical usage\n\n"); #endif - CTX_py_init_set(C, 1); + CTX_py_init_set(C, true); WM_keyconfig_init(C); #ifdef WITH_FREESTYLE -- cgit v1.2.3 From 8f565f5a6ffa4f6170caca2de50a733e8c72367a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Aug 2019 05:41:43 +1000 Subject: WM: reuse visible region calculation Avoids calculating the visible part of a region whenever on-screen overlays are drawn. --- source/blender/draw/engines/eevee/eevee_lookdev.c | 13 ++++++------ source/blender/draw/intern/draw_manager.c | 6 +++--- .../blender/draw/intern/draw_manager_profiling.c | 6 +++--- .../blender/draw/intern/draw_manager_profiling.h | 2 +- source/blender/editors/gpencil/annotate_draw.c | 7 +++---- source/blender/editors/gpencil/annotate_paint.c | 8 +++----- source/blender/editors/gpencil/drawgpencil.c | 9 ++++---- source/blender/editors/gpencil/gpencil_paint.c | 6 ++---- source/blender/editors/include/ED_screen.h | 3 ++- .../editors/interface/view2d_gizmo_navigate.c | 13 ++++++------ source/blender/editors/screen/area.c | 24 +++++++++++++++------- source/blender/editors/space_image/image_draw.c | 5 ++--- source/blender/editors/space_image/space_image.c | 7 +++---- .../editors/space_sequencer/space_sequencer.c | 7 +++---- source/blender/editors/space_view3d/view3d_draw.c | 9 ++++---- .../editors/space_view3d/view3d_gizmo_navigate.c | 17 ++++++++------- source/blender/editors/transform/transform.c | 7 +++---- source/blender/makesdna/DNA_screen_types.h | 7 +++++++ 18 files changed, 80 insertions(+), 76 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c index e6e699bef10..f52fcf31267 100644 --- a/source/blender/draw/engines/eevee/eevee_lookdev.c +++ b/source/blender/draw/engines/eevee/eevee_lookdev.c @@ -75,22 +75,21 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, if (LOOK_DEV_OVERLAY_ENABLED(v3d)) { /* Viewport / Spheres size. */ - rcti rect; - ED_region_visible_rect(draw_ctx->ar, &rect); + const rcti *rect = ED_region_visible_rect(draw_ctx->ar); /* Make the viewport width scale the lookdev spheres a bit. * Scale between 1000px and 2000px. */ const float viewport_scale = clamp_f( - BLI_rcti_size_x(&rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f); + BLI_rcti_size_x(rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f); const int sphere_size = U.lookdev_sphere_size * U.dpi_fac * viewport_scale; - if (sphere_size != effects->sphere_size || rect.xmax != effects->anchor[0] || - rect.ymin != effects->anchor[1]) { + if (sphere_size != effects->sphere_size || rect->xmax != effects->anchor[0] || + rect->ymin != effects->anchor[1]) { /* If sphere size or anchor point moves, reset TAA to avoid ghosting issue. * This needs to happen early because we are changing taa_current_sample. */ effects->sphere_size = sphere_size; - effects->anchor[0] = rect.xmax; - effects->anchor[1] = rect.ymin; + effects->anchor[0] = rect->xmax; + effects->anchor[1] = rect->ymin; EEVEE_temporal_sampling_reset(vedata); } } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1046e0422c1..a2bbb368caa 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1725,9 +1725,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, if (G.debug_value > 20 && G.debug_value < 30) { GPU_depth_test(false); - rcti rect; /* local coordinate visible rect inside region, to accommodate overlapping ui */ - ED_region_visible_rect(DST.draw_ctx.ar, &rect); - DRW_stats_draw(&rect); + /* local coordinate visible rect inside region, to accommodate overlapping ui */ + const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar); + DRW_stats_draw(rect); GPU_depth_test(true); } diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c index 5e21e5e576c..bab69cf7a57 100644 --- a/source/blender/draw/intern/draw_manager_profiling.c +++ b/source/blender/draw/intern/draw_manager_profiling.c @@ -200,7 +200,7 @@ void DRW_stats_reset(void) } } -static void draw_stat_5row(rcti *rect, int u, int v, const char *txt, const int size) +static void draw_stat_5row(const rcti *rect, int u, int v, const char *txt, const int size) { BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit, rect->ymax - (3 + v) * U.widget_unit, @@ -209,13 +209,13 @@ static void draw_stat_5row(rcti *rect, int u, int v, const char *txt, const int size); } -static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size) +static void draw_stat(const rcti *rect, int u, int v, const char *txt, const int size) { BLF_draw_default_ascii( rect->xmin + (1 + u) * U.widget_unit, rect->ymax - (3 + v) * U.widget_unit, 0.0f, txt, size); } -void DRW_stats_draw(rcti *rect) +void DRW_stats_draw(const rcti *rect) { char stat_string[64]; int lvl_index[MAX_NESTED_TIMER]; diff --git a/source/blender/draw/intern/draw_manager_profiling.h b/source/blender/draw/intern/draw_manager_profiling.h index 7fe2280f9b2..3da6a4c8b1c 100644 --- a/source/blender/draw/intern/draw_manager_profiling.h +++ b/source/blender/draw/intern/draw_manager_profiling.h @@ -35,6 +35,6 @@ void DRW_stats_group_end(void); void DRW_stats_query_start(const char *name); void DRW_stats_query_end(void); -void DRW_stats_draw(rcti *rect); +void DRW_stats_draw(const rcti *rect); #endif /* __DRAW_MANAGER_PROFILING_H__ */ diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c index dce6ed29c05..697d06aa098 100644 --- a/source/blender/editors/gpencil/annotate_draw.c +++ b/source/blender/editors/gpencil/annotate_draw.c @@ -936,7 +936,6 @@ static void annotation_draw_data_layers( /* draw a short status message in the top-right corner */ static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar) { - rcti rect; /* Cannot draw any status text when drawing OpenGL Renders */ if (G.f & G_FLAG_RENDER_VIEWPORT) { @@ -944,7 +943,7 @@ static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar) } /* Get bounds of region - Necessary to avoid problems with region overlap */ - ED_region_visible_rect(ar, &rect); + const rcti *rect = ED_region_visible_rect(ar); /* for now, this should only be used to indicate when we are in stroke editmode */ if (gpd->flag & GP_DATA_STROKE_EDITMODE) { @@ -956,8 +955,8 @@ static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar) BLF_width_and_height( font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); - int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; - int yco = (rect.ymax - U.widget_unit); + int xco = (rect->xmax - U.widget_unit) - (int)printable_size[0]; + int yco = (rect->ymax - U.widget_unit); /* text label */ UI_FontThemeColor(font_id, TH_TEXT_HI); diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index c9c4a67644e..07b61751b22 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -2242,11 +2242,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) } } else if (p->ar) { - rcti region_rect; - - /* Perform bounds check using */ - ED_region_visible_rect(p->ar, ®ion_rect); - in_bounds = BLI_rcti_isect_pt_v(®ion_rect, event->mval); + /* Perform bounds check. */ + const rcti *region_rect = ED_region_visible_rect(p->ar); + in_bounds = BLI_rcti_isect_pt_v(region_rect, event->mval); } else { /* No region */ diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 2b31af5ff1f..7c76f3aeab6 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -1173,15 +1173,14 @@ void ED_gp_draw_fill(tGPDdraw *tgpw) /* draw a short status message in the top-right corner */ static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar) { - rcti rect; /* Cannot draw any status text when drawing OpenGL Renders */ if (G.f & G_FLAG_RENDER_VIEWPORT) { return; } - /* Get bounds of region - Necessary to avoid problems with region overlap */ - ED_region_visible_rect(ar, &rect); + /* Get bounds of region - Necessary to avoid problems with region overlap. */ + const rcti *rect = ED_region_visible_rect(ar); /* for now, this should only be used to indicate when we are in stroke editmode */ if (gpd->flag & GP_DATA_STROKE_EDITMODE) { @@ -1193,8 +1192,8 @@ static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar BLF_width_and_height( font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); - int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; - int yco = (rect.ymax - U.widget_unit); + int xco = (rect->xmax - U.widget_unit) - (int)printable_size[0]; + int yco = (rect->ymax - U.widget_unit); /* text label */ UI_FontThemeColor(font_id, TH_TEXT_HI); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 894fb6eced4..a5425d64c2e 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -3629,11 +3629,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) } } else if (p->ar) { - rcti region_rect; - /* Perform bounds check using */ - ED_region_visible_rect(p->ar, ®ion_rect); - in_bounds = BLI_rcti_isect_pt_v(®ion_rect, event->mval); + const rcti *region_rect = ED_region_visible_rect(p->ar); + in_bounds = BLI_rcti_isect_pt_v(region_rect, event->mval); } else { /* No region */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index e67a3b003fc..c7ee7be49b5 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -124,7 +124,8 @@ void ED_region_image_metadata_draw( void ED_region_image_metadata_panel_draw(struct ImBuf *ibuf, struct uiLayout *layout); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); float ED_region_blend_alpha(struct ARegion *ar); -void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect); +void ED_region_visible_rect_calc(struct ARegion *ar, struct rcti *rect); +const rcti *ED_region_visible_rect(ARegion *ar); bool ED_region_is_overlap(int spacetype, int regiontype); int ED_region_snap_size_test(const struct ARegion *ar); diff --git a/source/blender/editors/interface/view2d_gizmo_navigate.c b/source/blender/editors/interface/view2d_gizmo_navigate.c index 883f16c63f2..9b15f2309a1 100644 --- a/source/blender/editors/interface/view2d_gizmo_navigate.c +++ b/source/blender/editors/interface/view2d_gizmo_navigate.c @@ -201,21 +201,20 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g struct NavigateWidgetGroup *navgroup = gzgroup->customdata; ARegion *ar = CTX_wm_region(C); - rcti rect_visible; - ED_region_visible_rect(ar, &rect_visible); + const rcti *rect_visible = ED_region_visible_rect(ar); - if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) && - (navgroup->state.rect_visible.ymax == rect_visible.ymax)) { + if ((navgroup->state.rect_visible.xmax == rect_visible->xmax) && + (navgroup->state.rect_visible.ymax == rect_visible->ymax)) { return; } - navgroup->state.rect_visible = rect_visible; + navgroup->state.rect_visible = *rect_visible; const float icon_size = GIZMO_SIZE; const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC; const float co[2] = { - rect_visible.xmax - (icon_offset_mini * 0.75f), - rect_visible.ymax - (icon_offset_mini * 0.75f), + rect_visible->xmax - (icon_offset_mini * 0.75f), + rect_visible->ymax - (icon_offset_mini * 0.75f), }; wmGizmo *gz; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index d0a3382ee50..1775a0c55a2 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -875,10 +875,9 @@ static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) az->alpha = 0.0f; if (U.uiflag2 & USER_REGION_OVERLAP) { - rcti rect_visible; - ED_region_visible_rect(ar, &rect_visible); - az->x2 = ar->winrct.xmin + rect_visible.xmax; - az->y2 = ar->winrct.ymin + rect_visible.ymax; + const rcti *rect_visible = ED_region_visible_rect(ar); + az->x2 = ar->winrct.xmin + rect_visible->xmax; + az->y2 = ar->winrct.ymin + rect_visible->ymax; } else { az->x2 = ar->winrct.xmax; @@ -1492,6 +1491,9 @@ static void region_rect_recursive( if (ar->winx != prev_winx || ar->winy != prev_winy) { ED_region_tag_redraw(ar); } + + /* Clear, initialize on demand. */ + memset(&ar->runtime.visible_rect, 0, sizeof(ar->runtime.visible_rect)); } static void area_calc_totrct(ScrArea *sa, const rcti *window_rect) @@ -2786,11 +2788,10 @@ void ED_region_info_draw_multiline(ARegion *ar, uiStyle *style = UI_style_get_dpi(); int fontid = style->widget.uifont_id; int scissor[4]; - rcti rect; int num_lines = 0; /* background box */ - ED_region_visible_rect(ar, &rect); + rcti rect = *ED_region_visible_rect(ar); /* Box fill entire width or just around text. */ if (!full_redraw) { @@ -3268,7 +3269,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) /* If the area has overlapping regions, it returns visible rect for Region *ar */ /* rect gets returned in local region coordinates */ -void ED_region_visible_rect(ARegion *ar, rcti *rect) +static void region_visible_rect_calc(ARegion *ar, rcti *rect) { ARegion *arn = ar; @@ -3315,6 +3316,15 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect) BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); } +const rcti *ED_region_visible_rect(ARegion *ar) +{ + rcti *rect = &ar->runtime.visible_rect; + if (rect->xmin == 0 && rect->ymin == 0 && rect->xmax == 0 && rect->ymax == 0) { + region_visible_rect_calc(ar, rect); + } + return rect; +} + /* Cache display helpers */ void ED_region_cache_draw_background(const ARegion *ar) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 97a3c7f2480..9a2b0d95c20 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -156,9 +156,8 @@ void ED_image_draw_info(Scene *scene, char str[256]; int dx = 6; /* local coordinate visible rect inside region, to accommodate overlapping ui */ - rcti rect; - ED_region_visible_rect(ar, &rect); - const int ymin = rect.ymin; + const rcti *rect = ED_region_visible_rect(ar); + const int ymin = rect->ymin; const int dy = ymin + 0.3f * UI_UNIT_Y; /* text colors */ diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 17f808f727d..33e77d3623e 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -501,11 +501,10 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar) int winy = BLI_rcti_size_y(&ar->winrct) + 1; /* For region overlap, move center so image doesn't overlap header. */ - rcti visible_rect; - ED_region_visible_rect(ar, &visible_rect); - const int visible_winy = BLI_rcti_size_y(&visible_rect) + 1; + const rcti *visible_rect = ED_region_visible_rect(ar); + const int visible_winy = BLI_rcti_size_y(visible_rect) + 1; int visible_centerx = 0; - int visible_centery = visible_rect.ymin + (visible_winy - winy) / 2; + int visible_centery = visible_rect->ymin + (visible_winy - winy) / 2; ar->v2d.tot.xmin = 0; ar->v2d.tot.ymin = 0; diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 12b446c3f4c..9aa9d14cbc8 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -675,10 +675,9 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *ar) WM_gizmomap_draw(ar->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D); if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) { - rcti rect; - ED_region_visible_rect(ar, &rect); - int xoffset = rect.xmin + U.widget_unit; - int yoffset = rect.ymax; + const rcti *rect = ED_region_visible_rect(ar); + int xoffset = rect->xmin + U.widget_unit; + int yoffset = rect->ymax; ED_scene_draw_fps(scene, xoffset, &yoffset); } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 8844428b1bf..6c534ee1b98 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1382,8 +1382,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar) ED_region_pixelspace(ar); /* local coordinate visible rect inside region, to accommodate overlapping ui */ - rcti rect; - ED_region_visible_rect(ar, &rect); + const rcti *rect = ED_region_visible_rect(ar); view3d_draw_border(C, ar); view3d_draw_grease_pencil(C); @@ -1399,14 +1398,14 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar) /* The gizmo handles it's own drawing. */ break; case USER_MINI_AXIS_TYPE_MINIMAL: - draw_view_axis(rv3d, &rect); + draw_view_axis(rv3d, rect); case USER_MINI_AXIS_TYPE_NONE: break; } } - int xoffset = rect.xmin + U.widget_unit; - int yoffset = rect.ymax; + int xoffset = rect->xmin + U.widget_unit; + int yoffset = rect->ymax; if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) { if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c index ad1a57eb71f..3c911e266a9 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c @@ -246,18 +246,17 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g copy_v3_v3(navgroup->gz_array[GZ_INDEX_ROTATE]->matrix_offset[i], rv3d->viewmat[i]); } - rcti rect_visible; - ED_region_visible_rect(ar, &rect_visible); + const rcti *rect_visible = ED_region_visible_rect(ar); - if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) && - (navgroup->state.rect_visible.ymax == rect_visible.ymax) && + if ((navgroup->state.rect_visible.xmax == rect_visible->xmax) && + (navgroup->state.rect_visible.ymax == rect_visible->ymax) && (navgroup->state.rv3d.is_persp == rv3d->is_persp) && (navgroup->state.rv3d.is_camera == (rv3d->persp == RV3D_CAMOB)) && (navgroup->state.rv3d.viewlock == rv3d->viewlock)) { return; } - navgroup->state.rect_visible = rect_visible; + navgroup->state.rect_visible = *rect_visible; navgroup->state.rv3d.is_persp = rv3d->is_persp; navgroup->state.rv3d.is_camera = (rv3d->persp == RV3D_CAMOB); navgroup->state.rv3d.viewlock = rv3d->viewlock; @@ -268,8 +267,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC; const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC; const float co_rotate[2] = { - rect_visible.xmax - icon_offset, - rect_visible.ymax - icon_offset, + rect_visible->xmax - icon_offset, + rect_visible->ymax - icon_offset, }; float icon_offset_from_axis = 0.0f; @@ -286,8 +285,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g } const float co[2] = { - rect_visible.xmax - icon_offset_from_axis, - rect_visible.ymax - icon_offset_mini * 0.75f, + rect_visible->xmax - icon_offset_from_axis, + rect_visible->ymax - icon_offset_mini * 0.75f, }; wmGizmo *gz; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 98203a7e316..14995144c5c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2009,19 +2009,18 @@ static void drawTransformView(const struct bContext *C, ARegion *ar, void *arg) * to warn that autokeying is enabled */ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) { - rcti rect; const char *printable = IFACE_("Auto Keying On"); float printable_size[2]; int xco, yco; - ED_region_visible_rect(ar, &rect); + const rcti *rect = ED_region_visible_rect(ar); const int font_id = BLF_default(); BLF_width_and_height( font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); - xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; - yco = (rect.ymax - U.widget_unit); + xco = (rect->xmax - U.widget_unit) - (int)printable_size[0]; + yco = (rect->ymax - U.widget_unit); /* warning text (to clarify meaning of overlays) * - original color was red to match the icon, but that clashes badly with a less nasty border diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 0319993631c..aab71c15e44 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -375,6 +375,13 @@ typedef struct ScrArea { typedef struct ARegion_Runtime { /* Panel category to use between 'layout' and 'draw'. */ const char *category; + + /** + * The visible part of the region, use with region overlap not to draw + * on top of the overlapping regions. + * + * Lazy initialize, zero'd when unset, relative to #ARegion.winrct x/y min. */ + rcti visible_rect; } ARegion_Runtime; typedef struct ARegion { -- cgit v1.2.3 From 9dab57a9f829881dad1e659b53413ded15ec085e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Aug 2019 07:02:22 +1000 Subject: Outliner: only activate outliner items when clicking on icon/text This is 2.7x behavior, while there are plans to improve on this, committing in case larger changes take longer. Without this it's not easy to select object data without changing modes. See D5493 --- source/blender/editors/space_outliner/outliner_select.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index c932766ab93..7f45c4d22fa 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -1305,8 +1305,15 @@ static int outliner_item_do_activate_from_cursor(bContext *C, TreeStoreElem *activate_tselem = TREESTORE(activate_te); outliner_item_select(soops, activate_te, extend, extend); - do_outliner_item_activate_tree_element( - C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive); + + /* Only change modes when clicking on the icon/text, + * otherwise we can't easily select without changing modes. */ + if ((te->flag & TE_ICONROW) == 0) { + if (view_mval[0] >= te->xs && view_mval[0] <= te->xend) { + do_outliner_item_activate_tree_element( + C, scene, view_layer, soops, activate_te, activate_tselem, extend, recursive); + } + } changed = true; } -- cgit v1.2.3