diff options
author | Hans Goudey <h.goudey@me.com> | 2022-01-19 18:37:46 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-01-19 18:37:46 +0300 |
commit | cee7c8f56c869033d6db2149b352a3ccee98585f (patch) | |
tree | 1d3a30723b803b2406e8d5ab77c93f32e1ffb211 | |
parent | 0c0ba3a2ee97d6dccc6609d0b7a759082722bac3 (diff) | |
parent | f179637222d1432b09c3c23201e1b7b75215b11a (diff) |
Merge branch 'master' into temp-geometry-nodes-extrude-mesh
47 files changed, 810 insertions, 381 deletions
diff --git a/intern/cycles/blender/output_driver.cpp b/intern/cycles/blender/output_driver.cpp index 7b253e4cd3e..d5cc0c60bae 100644 --- a/intern/cycles/blender/output_driver.cpp +++ b/intern/cycles/blender/output_driver.cpp @@ -51,7 +51,7 @@ bool BlenderOutputDriver::read_render_tile(const Tile &tile) BL::RenderLayer b_rlay = *b_single_rlay; - vector<float> pixels(tile.size.x * tile.size.y * 4); + vector<float> pixels(static_cast<size_t>(tile.size.x) * tile.size.y * 4); /* Copy each pass. * TODO:copy only the required ones for better performance? */ @@ -109,7 +109,7 @@ void BlenderOutputDriver::write_render_tile(const Tile &tile) BL::RenderLayer b_rlay = *b_single_rlay; - vector<float> pixels(tile.size.x * tile.size.y * 4); + vector<float> pixels(static_cast<size_t>(tile.size.x) * tile.size.y * 4); /* Copy each pass. */ for (BL::RenderPass &b_pass : b_rlay.passes) { diff --git a/intern/cycles/util/array.h b/intern/cycles/util/array.h index 4c905b09138..1c5e3e8d4ec 100644 --- a/intern/cycles/util/array.h +++ b/intern/cycles/util/array.h @@ -64,7 +64,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra else { data_ = mem_allocate(from.datasize_); if (from.datasize_ > 0) { - memcpy(data_, from.data_, from.datasize_ * sizeof(T)); + mem_copy(data_, from.data_, from.datasize_); } datasize_ = from.datasize_; capacity_ = datasize_; @@ -76,7 +76,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra if (this != &from) { resize(from.size()); if (datasize_ > 0) { - memcpy((void *)data_, from.data_, datasize_ * sizeof(T)); + mem_copy(data_, from.data_, datasize_); } } @@ -88,7 +88,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra resize(from.size()); if (from.size() > 0 && datasize_ > 0) { - memcpy(data_, &from[0], datasize_ * sizeof(T)); + mem_copy(data_, from.data(), datasize_); } return *this; @@ -161,8 +161,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra return NULL; } else if (data_ != NULL) { - memcpy( - (void *)newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize) * sizeof(T)); + mem_copy(newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize)); mem_free(data_, capacity_); } data_ = newdata; @@ -246,7 +245,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra if (newcapacity > capacity_) { T *newdata = mem_allocate(newcapacity); if (data_ != NULL) { - memcpy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity) * sizeof(T)); + mem_copy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity)); mem_free(data_, capacity_); } data_ = newdata; @@ -280,7 +279,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra if (from.size()) { size_t old_size = size(); resize(old_size + from.size()); - memcpy(data_ + old_size, from.data(), sizeof(T) * from.size()); + mem_copy(data_ + old_size, from.data(), from.size()); } } @@ -308,6 +307,11 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra } } + inline void mem_copy(T *mem_to, const T *mem_from, const size_t N) + { + memcpy((void *)mem_to, mem_from, sizeof(T) * N); + } + T *data_; size_t datasize_; size_t capacity_; diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 17a44274712..00eae2e8e6e 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -747,6 +747,14 @@ void CustomData_blend_write(struct BlendWriter *writer, struct ID *id); void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count); +#ifndef NDEBUG +struct DynStr; +/** Use to inspect mesh data when debugging. */ +void CustomData_debug_info_from_layers(const struct CustomData *data, + const char *indent, + struct DynStr *dynstr); +#endif /* NDEBUG */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index b7f675e4e97..4c6eb31db4b 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -406,6 +406,13 @@ int set_listbasepointers(struct Main *main, struct ListBase *lb[]); ((main)->versionfile < (ver) || \ ((main)->versionfile == (ver) && (main)->subversionfile < (subver))) +/** + * The size of thumbnails (optionally) stored in the `.blend` files header. + * + * NOTE(@campbellbarton): This is kept small as it's stored uncompressed in the `.blend` file, + * where a larger size would increase the size of every `.blend` file unreasonably. + * If we wanted to increase the size, we'd want to use compression (JPEG or similar). + */ #define BLEN_THUMB_SIZE 128 #define BLEN_THUMB_MEMSIZE(_x, _y) \ diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index e7382ce448a..6554a9c72aa 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -23,6 +23,7 @@ */ #include "BKE_mesh_types.h" +#include "BLI_compiler_attrs.h" #include "BLI_utildefines.h" struct BLI_Stack; @@ -1038,6 +1039,13 @@ void BKE_mesh_batch_cache_free(struct Mesh *me); extern void (*BKE_mesh_batch_cache_dirty_tag_cb)(struct Mesh *me, eMeshBatchDirtyMode mode); extern void (*BKE_mesh_batch_cache_free_cb)(struct Mesh *me); +/* mesh_debug.c */ +#ifndef NDEBUG +char *BKE_mesh_debug_info(const struct Mesh *me) + ATTR_NONNULL(1) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +void BKE_mesh_debug_print(const struct Mesh *me) ATTR_NONNULL(1); +#endif + /* Inlines */ /* NOTE(@sybren): Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h, diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index 5069fad6bb7..ad86f6d8f25 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -116,10 +116,6 @@ void BKE_mesh_runtime_eval_to_meshkey(struct Mesh *me_deformed, struct KeyBlock *kb); #ifndef NDEBUG -char *BKE_mesh_runtime_debug_info(struct Mesh *me_eval); -void BKE_mesh_runtime_debug_print(struct Mesh *me_eval); -/* XXX Should go in customdata file? */ -void BKE_mesh_runtime_debug_print_cdlayers(struct CustomData *data); bool BKE_mesh_runtime_is_valid(struct Mesh *me_eval); #endif /* NDEBUG */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index b5b8f629970..cb32bc29463 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -197,6 +197,7 @@ set(SRC intern/mesh.cc intern/mesh_boolean_convert.cc intern/mesh_convert.cc + intern/mesh_debug.cc intern/mesh_evaluate.cc intern/mesh_fair.cc intern/mesh_iterators.c diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 711b571a640..10ee7108682 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -44,6 +44,10 @@ #include "BLI_string_utils.h" #include "BLI_utildefines.h" +#ifndef NDEBUG +# include "BLI_dynstr.h" +#endif + #include "BLT_translation.h" #include "BKE_anonymous_attribute.h" @@ -5188,3 +5192,33 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count) CustomData_update_typemap(data); } + +#ifndef NDEBUG + +void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr) +{ + for (int type = 0; type < CD_NUMTYPES; type++) { + if (CustomData_has_layer(data, type)) { + /* NOTE: doesn't account for multiple layers. */ + const char *name = CustomData_layertype_name(type); + const int size = CustomData_sizeof(type); + const void *pt = CustomData_get_layer(data, type); + const int pt_size = pt ? (int)(MEM_allocN_len(pt) / size) : 0; + const char *structname; + int structnum; + CustomData_file_write_info(type, &structname, &structnum); + BLI_dynstr_appendf( + dynstr, + "%sdict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", + indent, + name, + structname, + type, + (const void *)pt, + size, + pt_size); + } + } +} + +#endif /* NDEBUG */ diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 1aa3477437a..9b0cf17a424 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -150,6 +150,8 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int BKE_mesh_update_customdata_pointers(mesh_dst, do_tessface); + mesh_dst->cd_flag = mesh_src->cd_flag; + mesh_dst->edit_mesh = nullptr; mesh_dst->mselect = (MSelect *)MEM_dupallocN(mesh_dst->mselect); diff --git a/source/blender/blenkernel/intern/mesh_debug.cc b/source/blender/blenkernel/intern/mesh_debug.cc new file mode 100644 index 00000000000..017f96c2ece --- /dev/null +++ b/source/blender/blenkernel/intern/mesh_debug.cc @@ -0,0 +1,115 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + * + * Evaluated mesh info printing function, to help track down differences output. + * + * Output from these functions can be evaluated as Python literals. + * See `bmesh_debug.c` for the equivalent #BMesh functionality. + */ + +#ifndef NDEBUG + +# include <stdio.h> + +# include "MEM_guardedalloc.h" + +# include "DNA_mesh_types.h" +# include "DNA_meshdata_types.h" +# include "DNA_object_types.h" + +# include "BLI_utildefines.h" + +# include "BKE_customdata.h" + +# include "BKE_mesh.h" + +# include "BLI_dynstr.h" + +static void mesh_debug_info_from_cd_flag(const Mesh *me, DynStr *dynstr) +{ + BLI_dynstr_append(dynstr, "'cd_flag': {"); + if (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) { + BLI_dynstr_append(dynstr, "'VERT_BWEIGHT', "); + } + if (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + BLI_dynstr_append(dynstr, "'EDGE_BWEIGHT', "); + } + if (me->cd_flag & ME_CDFLAG_EDGE_CREASE) { + BLI_dynstr_append(dynstr, "'EDGE_CREASE', "); + } + BLI_dynstr_append(dynstr, "},\n"); +} + +char *BKE_mesh_debug_info(const Mesh *me) +{ + DynStr *dynstr = BLI_dynstr_new(); + char *ret; + + const char *indent4 = " "; + const char *indent8 = " "; + + BLI_dynstr_append(dynstr, "{\n"); + BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)me); + BLI_dynstr_appendf(dynstr, " 'totvert': %d,\n", me->totvert); + BLI_dynstr_appendf(dynstr, " 'totedge': %d,\n", me->totedge); + BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", me->totface); + BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly); + + BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only); + BLI_dynstr_appendf(dynstr, " 'runtime.is_original': %d,\n", me->runtime.is_original); + + BLI_dynstr_append(dynstr, " 'vert_layers': (\n"); + CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'edge_layers': (\n"); + CustomData_debug_info_from_layers(&me->edata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'loop_layers': (\n"); + CustomData_debug_info_from_layers(&me->ldata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'poly_layers': (\n"); + CustomData_debug_info_from_layers(&me->pdata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'tessface_layers': (\n"); + CustomData_debug_info_from_layers(&me->fdata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, indent4); + mesh_debug_info_from_cd_flag(me, dynstr); + + BLI_dynstr_append(dynstr, "}\n"); + + ret = BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); + return ret; +} + +void BKE_mesh_debug_print(const Mesh *me) +{ + char *str = BKE_mesh_debug_info(me); + puts(str); + fflush(stdout); + MEM_freeN(str); +} + +#endif /* NDEBUG */ diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c index 39dbd7d66a4..e7e5064df7c 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.c +++ b/source/blender/blenkernel/intern/mesh_runtime.c @@ -298,129 +298,10 @@ void BKE_mesh_batch_cache_free(Mesh *me) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Mesh Runtime Debug Helpers +/** \name Mesh Runtime Validation * \{ */ -/* Evaluated mesh info printing function, to help track down differences output. */ - #ifndef NDEBUG -# include "BLI_dynstr.h" - -static void mesh_runtime_debug_info_layers(DynStr *dynstr, CustomData *cd) -{ - int type; - - for (type = 0; type < CD_NUMTYPES; type++) { - if (CustomData_has_layer(cd, type)) { - /* NOTE: doesn't account for multiple layers. */ - const char *name = CustomData_layertype_name(type); - const int size = CustomData_sizeof(type); - const void *pt = CustomData_get_layer(cd, type); - const int pt_size = pt ? (int)(MEM_allocN_len(pt) / size) : 0; - const char *structname; - int structnum; - CustomData_file_write_info(type, &structname, &structnum); - BLI_dynstr_appendf( - dynstr, - " dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", - name, - structname, - type, - (const void *)pt, - size, - pt_size); - } - } -} - -char *BKE_mesh_runtime_debug_info(Mesh *me_eval) -{ - DynStr *dynstr = BLI_dynstr_new(); - char *ret; - - BLI_dynstr_append(dynstr, "{\n"); - BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)me_eval); -# if 0 - const char *tstr; - switch (me_eval->type) { - case DM_TYPE_CDDM: - tstr = "DM_TYPE_CDDM"; - break; - case DM_TYPE_CCGDM: - tstr = "DM_TYPE_CCGDM"; - break; - default: - tstr = "UNKNOWN"; - break; - } - BLI_dynstr_appendf(dynstr, " 'type': '%s',\n", tstr); -# endif - BLI_dynstr_appendf(dynstr, " 'totvert': %d,\n", me_eval->totvert); - BLI_dynstr_appendf(dynstr, " 'totedge': %d,\n", me_eval->totedge); - BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", me_eval->totface); - BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me_eval->totpoly); - BLI_dynstr_appendf(dynstr, " 'deformed_only': %d,\n", me_eval->runtime.deformed_only); - - BLI_dynstr_append(dynstr, " 'vertexLayers': (\n"); - mesh_runtime_debug_info_layers(dynstr, &me_eval->vdata); - BLI_dynstr_append(dynstr, " ),\n"); - - BLI_dynstr_append(dynstr, " 'edgeLayers': (\n"); - mesh_runtime_debug_info_layers(dynstr, &me_eval->edata); - BLI_dynstr_append(dynstr, " ),\n"); - - BLI_dynstr_append(dynstr, " 'loopLayers': (\n"); - mesh_runtime_debug_info_layers(dynstr, &me_eval->ldata); - BLI_dynstr_append(dynstr, " ),\n"); - - BLI_dynstr_append(dynstr, " 'polyLayers': (\n"); - mesh_runtime_debug_info_layers(dynstr, &me_eval->pdata); - BLI_dynstr_append(dynstr, " ),\n"); - - BLI_dynstr_append(dynstr, " 'tessFaceLayers': (\n"); - mesh_runtime_debug_info_layers(dynstr, &me_eval->fdata); - BLI_dynstr_append(dynstr, " ),\n"); - - BLI_dynstr_append(dynstr, "}\n"); - - ret = BLI_dynstr_get_cstring(dynstr); - BLI_dynstr_free(dynstr); - return ret; -} - -void BKE_mesh_runtime_debug_print(Mesh *me_eval) -{ - char *str = BKE_mesh_runtime_debug_info(me_eval); - puts(str); - fflush(stdout); - MEM_freeN(str); -} - -void BKE_mesh_runtime_debug_print_cdlayers(CustomData *data) -{ - int i; - const CustomDataLayer *layer; - - printf("{\n"); - - for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) { - - const char *name = CustomData_layertype_name(layer->type); - const int size = CustomData_sizeof(layer->type); - const char *structname; - int structnum; - CustomData_file_write_info(layer->type, &structname, &structnum); - printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", - name, - structname, - layer->type, - (const void *)layer->data, - size, - (int)(MEM_allocN_len(layer->data) / size)); - } - - printf("}\n"); -} bool BKE_mesh_runtime_is_valid(Mesh *me_eval) { diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 7bf80939980..f57d4da4d26 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -100,6 +100,8 @@ set(SRC intern/bmesh_mesh.h intern/bmesh_mesh_convert.c intern/bmesh_mesh_convert.h + intern/bmesh_mesh_debug.c + intern/bmesh_mesh_debug.h intern/bmesh_mesh_duplicate.c intern/bmesh_mesh_duplicate.h intern/bmesh_mesh_normals.c diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 40db423ba2f..fc97c55091a 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -214,6 +214,7 @@ extern "C" { #include "intern/bmesh_marking.h" #include "intern/bmesh_mesh.h" #include "intern/bmesh_mesh_convert.h" +#include "intern/bmesh_mesh_debug.h" #include "intern/bmesh_mesh_duplicate.h" #include "intern/bmesh_mesh_normals.h" #include "intern/bmesh_mesh_partial_update.h" diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 5a9d1ba7bc4..a127089ad2c 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -510,23 +510,51 @@ static BMFace *bm_mesh_copy_new_face( return f_new; } -void BM_mesh_copy_init_customdata_from_mesh(BMesh *bm_dst, - const Mesh *me_src, - const BMAllocTemplate *allocsize) +void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst, + const Mesh *me_src_array[], + const int me_src_array_len, + const BMAllocTemplate *allocsize) + { if (allocsize == NULL) { allocsize = &bm_mesh_allocsize_default; } - CustomData_copy(&me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); - CustomData_copy(&me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); - CustomData_copy(&me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); - CustomData_copy(&me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + char cd_flag = 0; + + for (int i = 0; i < me_src_array_len; i++) { + const Mesh *me_src = me_src_array[i]; + if (i == 0) { + CustomData_copy(&me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); + CustomData_copy(&me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); + CustomData_copy(&me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); + CustomData_copy(&me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + } + else { + CustomData_merge(&me_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0); + CustomData_merge(&me_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0); + CustomData_merge(&me_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0); + CustomData_merge(&me_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0); + } + + cd_flag |= me_src->cd_flag; + } + + cd_flag |= BM_mesh_cd_flag_from_bmesh(bm_dst); CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT); CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE); CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE); + + BM_mesh_cd_flag_apply(bm_dst, cd_flag); +} + +void BM_mesh_copy_init_customdata_from_mesh(BMesh *bm_dst, + const Mesh *me_src, + const BMAllocTemplate *allocsize) +{ + BM_mesh_copy_init_customdata_from_mesh_array(bm_dst, &me_src, 1, allocsize); } void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTemplate *allocsize) diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 7b25a5b5a2a..008219165a8 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -146,6 +146,19 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v); void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v); +/** + * Initialize the `bm_dst` layers in preparation for populating it's contents with multiple meshes. + * Typically done using multiple calls to #BM_mesh_bm_from_me with the same `bm` argument). + * + * \note While the custom-data layers of all meshes are created, the active layers are set + * by the first instance mesh containing that layer type. + * This means the first mesh should always be the main mesh (from the user perspective), + * as this is the mesh they have control over (active UV layer for rendering for example). + */ +void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst, + const struct Mesh *me_src_array[], + int me_src_array_len, + const struct BMAllocTemplate *allocsize); void BM_mesh_copy_init_customdata_from_mesh(BMesh *bm_dst, const struct Mesh *me_src, const struct BMAllocTemplate *allocsize); diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c b/source/blender/bmesh/intern/bmesh_mesh_convert.c index d99fefbcd02..6b44fe2c9ff 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.c +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c @@ -315,13 +315,20 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE); CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); - - BM_mesh_cd_flag_apply(bm, me->cd_flag); } - - const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); - const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); - const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + BM_mesh_cd_flag_apply(bm, me->cd_flag | (is_new ? 0 : BM_mesh_cd_flag_from_bmesh(bm))); + + /* Only copy these values over if the source mesh is flagged to be using them. + * Even if `bm` has these layers, they may have been added from another mesh, when `!is_new`. */ + const int cd_vert_bweight_offset = (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) ? + CustomData_get_offset(&bm->vdata, CD_BWEIGHT) : + -1; + const int cd_edge_bweight_offset = (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) ? + CustomData_get_offset(&bm->edata, CD_BWEIGHT) : + -1; + const int cd_edge_crease_offset = (me->cd_flag & ME_CDFLAG_EDGE_CREASE) ? + CustomData_get_offset(&bm->edata, CD_CREASE) : + -1; const int cd_shape_key_offset = tot_shape_keys ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) : -1; const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ? diff --git a/source/blender/bmesh/intern/bmesh_mesh_debug.c b/source/blender/bmesh/intern/bmesh_mesh_debug.c new file mode 100644 index 00000000000..81a11df13f2 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_mesh_debug.c @@ -0,0 +1,86 @@ +/* + * 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. + */ + +/** \file + * \ingroup bke + * + * Evaluated mesh info printing function, to help track down differences output. + * + * Output from these functions can be evaluated as Python literals. + * See `mesh_debug.cc` for the equivalent #Mesh functionality. + */ + +#ifndef NDEBUG + +# include <stdio.h> + +# include "MEM_guardedalloc.h" + +# include "BLI_utildefines.h" + +# include "BKE_customdata.h" + +# include "bmesh.h" + +# include "bmesh_mesh_debug.h" + +# include "BLI_dynstr.h" + +char *BM_mesh_debug_info(BMesh *bm) +{ + DynStr *dynstr = BLI_dynstr_new(); + char *ret; + + const char *indent8 = " "; + + BLI_dynstr_append(dynstr, "{\n"); + BLI_dynstr_appendf(dynstr, " 'ptr': '%p',\n", (void *)bm); + BLI_dynstr_appendf(dynstr, " 'totvert': %d,\n", bm->totvert); + BLI_dynstr_appendf(dynstr, " 'totedge': %d,\n", bm->totedge); + BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", bm->totface); + + BLI_dynstr_append(dynstr, " 'vert_layers': (\n"); + CustomData_debug_info_from_layers(&bm->vdata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'edge_layers': (\n"); + CustomData_debug_info_from_layers(&bm->edata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'loop_layers': (\n"); + CustomData_debug_info_from_layers(&bm->ldata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, " 'poly_layers': (\n"); + CustomData_debug_info_from_layers(&bm->pdata, indent8, dynstr); + BLI_dynstr_append(dynstr, " ),\n"); + + BLI_dynstr_append(dynstr, "}\n"); + + ret = BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); + return ret; +} + +void BM_mesh_debug_print(BMesh *bm) +{ + char *str = BM_mesh_debug_info(bm); + puts(str); + fflush(stdout); + MEM_freeN(str); +} + +#endif /* NDEBUG */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_debug.h b/source/blender/bmesh/intern/bmesh_mesh_debug.h new file mode 100644 index 00000000000..e903b627419 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_mesh_debug.h @@ -0,0 +1,30 @@ +/* + * 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. + */ + +#pragma once + +/** \file + * \ingroup bmesh + */ + +#include "BLI_compiler_attrs.h" + +#include "bmesh.h" + +#ifndef NDEBUG +char *BM_mesh_debug_info(BMesh *bm) ATTR_NONNULL(1) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +void BM_mesh_debug_print(BMesh *bm) ATTR_NONNULL(1); +#endif /* NDEBUG */ diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 9f0bc5cacef..8474192ca23 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -2073,7 +2073,7 @@ void node_draw_link_bezier(const bContext &C, copy_v2_v2(node_link_data.bezierPts[i], vec[i]); } for (int i = 0; i < 3; i++) { - copy_v2_v2(node_link_data.colors[i], colors[i]); + copy_v4_v4(node_link_data.colors[i], colors[i]); } node_link_data.doArrow = drawarrow; node_link_data.doMuted = drawmuted; @@ -2086,7 +2086,7 @@ void node_draw_link_bezier(const bContext &C, GPUBatch *batch = g_batch_link.batch_single; GPUUniformBuf *ubo = GPU_uniformbuf_create_ex( - sizeof(node_link_data), &node_link_data, __func__); + sizeof(NodeLinkData), &node_link_data, __func__); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK); GPU_batch_uniformbuf_bind(batch, "node_link_data", ubo); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index d43ff38edf9..3b5e16d84a9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -39,6 +39,7 @@ #include "DNA_sound_types.h" #include "BKE_context.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_lib_id.h" #include "BKE_main.h" @@ -46,6 +47,7 @@ #include "BKE_sound.h" #include "SEQ_add.h" +#include "SEQ_animation.h" #include "SEQ_clipboard.h" #include "SEQ_edit.h" #include "SEQ_effects.h" @@ -66,6 +68,7 @@ #include "RNA_enum_types.h" /* For menu, popup, icons, etc. */ +#include "ED_keyframing.h" #include "ED_numinput.h" #include "ED_outliner.h" #include "ED_screen.h" @@ -1655,6 +1658,35 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) /** \name Duplicate Strips Operator * \{ */ +static void sequencer_backup_original_animation(Scene *scene, ListBase *list) +{ + if (scene->adt == NULL || scene->adt->action == NULL || + BLI_listbase_is_empty(&scene->adt->action->curves)) { + return; + } + + BLI_movelisttolist(list, &scene->adt->action->curves); +} + +static void sequencer_restore_original_animation(Scene *scene, ListBase *list) +{ + if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) { + return; + } + + BLI_movelisttolist(&scene->adt->action->curves, list); +} + +static void sequencer_duplicate_animation(Scene *scene, Sequence *seq, ListBase *curves_backup) +{ + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, curves_backup); + GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { + FCurve *fcu_cpy = BKE_fcurve_copy(fcu); + BLI_addtail(&scene->adt->action->curves, fcu_cpy); + } + GSET_FOREACH_END(); +} + static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1665,32 +1697,44 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) } Sequence *active_seq = SEQ_select_active_get(scene); - ListBase duplicated = {NULL, NULL}; + ListBase duplicated_strips = {NULL, NULL}; - SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated, ed->seqbasep, 0, 0); + SEQ_sequence_base_dupli_recursive(scene, scene, &duplicated_strips, ed->seqbasep, 0, 0); ED_sequencer_deselect_all(scene); - if (duplicated.first) { - Sequence *seq = duplicated.first; - /* Rely on the nseqbase list being added at the end. - * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ - BLI_movelisttolist(ed->seqbasep, &duplicated); - - /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation - * data. */ - for (; seq; seq = seq->next) { - if (active_seq != NULL && STREQ(seq->name, active_seq->name)) { - SEQ_select_active_set(scene, seq); - } - seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); - SEQ_ensure_unique_name(seq, scene); - } + if (duplicated_strips.first == NULL) { + return OPERATOR_CANCELLED; + } - WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - return OPERATOR_FINISHED; + /* Duplicate animation. + * First backup original curves from scene and duplicate strip curves from backup into scene. + * This way, when pasted strips are renamed, curves are renamed with them. Finally, restore + * original curves from backup. + */ + ListBase fcurves_original_backup = {NULL, NULL}; + sequencer_backup_original_animation(scene, &fcurves_original_backup); + + Sequence *seq = duplicated_strips.first; + + /* Rely on the nseqbase list being added at the end. + * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ + BLI_movelisttolist(ed->seqbasep, &duplicated_strips); + + /* Handle duplicated strips: set active, select, ensure unique name and duplicate animation + * data. */ + for (; seq; seq = seq->next) { + if (active_seq != NULL && STREQ(seq->name, active_seq->name)) { + SEQ_select_active_set(scene, seq); + } + seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); + sequencer_duplicate_animation(scene, seq, &fcurves_original_backup); + SEQ_ensure_unique_name(seq, scene); } - return OPERATOR_CANCELLED; + sequencer_restore_original_animation(scene, &fcurves_original_backup); + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; } void SEQUENCER_OT_duplicate(wmOperatorType *ot) @@ -1905,7 +1949,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } seq_next = seq->next; - SEQ_sequence_free(scene, seq, true); + SEQ_edit_flag_for_removal(scene, seqbase, seq); seq = seq_next; } else { @@ -1913,6 +1957,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } } + SEQ_edit_remove_flagged_sequences(scene, seqbase); + SEQ_sort(seqbase); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2441,6 +2487,22 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq) } } +static void sequencer_copy_animation(Scene *scene, Sequence *seq) +{ + if (scene->adt == NULL || scene->adt->action == NULL || + BLI_listbase_is_empty(&scene->adt->action->curves)) { + return; + } + + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); + + GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { + BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu)); + } + GSET_FOREACH_END(); + BLI_gset_free(fcurves, NULL); +} + static int sequencer_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2467,8 +2529,10 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) seqbase_clipboard_frame = scene->r.cfra; SEQ_clipboard_active_seq_name_store(scene); - /* Remove anything that references the current scene. */ LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { + /* Copy curves. */ + sequencer_copy_animation(scene, seq); + /* Remove anything that references the current scene. */ seq_copy_del_sound(scene, seq); } @@ -2513,6 +2577,29 @@ void ED_sequencer_deselect_all(Scene *scene) } } +static void sequencer_paste_animation(bContext *C) +{ + if (BLI_listbase_is_empty(&fcurves_clipboard)) { + return; + } + + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + bAction *act; + + if (scene->adt != NULL && scene->adt->action != NULL) { + act = scene->adt->action; + } + else { + /* get action to add F-Curve+keyframe to */ + act = ED_id_action_ensure(bmain, &scene->id); + } + + LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) { + BLI_addtail(&act->curves, BKE_fcurve_copy(fcu)); + } +} + static int sequencer_paste_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2542,6 +2629,17 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) ofs = scene->r.cfra - min_seq_startdisp; } + /* Paste animation. + * Note: Only fcurves are copied. Drivers and NLA action strips are not copied. + * First backup original curves from scene and move curves from clipboard into scene. This way, + * when pasted strips are renamed, pasted fcurves are renamed with them. Finally restore original + * curves from backup. + */ + + ListBase fcurves_original_backup = {NULL, NULL}; + sequencer_backup_original_animation(scene, &fcurves_original_backup); + sequencer_paste_animation(C); + /* Copy strips, temporarily restoring pointers to actual data-blocks. This * must happen on the clipboard itself, so that copying does user counting * on the actual data-blocks. */ @@ -2571,6 +2669,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) } } + sequencer_restore_original_animation(scene, &fcurves_original_backup); + DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index c6fecdb1fc6..82ba17d4db1 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -66,7 +66,7 @@ typedef struct ThumbDataItem { static void thumbnail_hash_data_free(void *val) { ThumbDataItem *item = val; - SEQ_sequence_free(item->scene, item->seq_dupli, 0); + SEQ_sequence_free(item->scene, item->seq_dupli); MEM_freeN(val); } diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c index 7f0f30624cb..82a0de9b845 100644 --- a/source/blender/editors/space_topbar/space_topbar.c +++ b/source/blender/editors/space_topbar/space_topbar.c @@ -243,8 +243,11 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu) if (wm->undo_stack == NULL) { return; } + int undo_step_count = 0; - for (UndoStep *us = wm->undo_stack->steps.first; us; us = us->next) { + int undo_step_count_all = 0; + for (UndoStep *us = wm->undo_stack->steps.last; us; us = us->prev) { + undo_step_count_all += 1; if (us->skip) { continue; } @@ -255,10 +258,12 @@ static void undo_history_draw_menu(const bContext *C, Menu *menu) uiLayout *column = NULL; const int col_size = 20 + (undo_step_count / 12); - int i = 0; undo_step_count = 0; - for (UndoStep *us = wm->undo_stack->steps.first; us; us = us->next, i++) { + + /* Reverse the order so the most recent state is first in the menu. */ + int i = undo_step_count_all - 1; + for (UndoStep *us = wm->undo_stack->steps.last; us; us = us->prev, i--) { if (us->skip) { continue; } diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 2244f82509f..01eae36e846 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -34,6 +34,7 @@ #include "ED_markers.h" +#include "SEQ_animation.h" #include "SEQ_edit.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" diff --git a/source/blender/gpu/GPU_shader_shared.h b/source/blender/gpu/GPU_shader_shared.h index f400e151487..334b974acd8 100644 --- a/source/blender/gpu/GPU_shader_shared.h +++ b/source/blender/gpu/GPU_shader_shared.h @@ -34,7 +34,9 @@ using blender::float4x4; struct NodeLinkData { float4 colors[3]; - float2 bezierPts[4]; + /* bezierPts Is actually a float2, but due to std140 each element needs to be aligned to 16 + * bytes. */ + float4 bezierPts[4]; bool1 doArrow; bool1 doMuted; float dim_factor; diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 3d4f27d2278..439eb735c95 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -85,6 +85,7 @@ void ShaderCreateInfo::finalize() if (!info.geometry_source_.is_empty()) { BLI_assert(geometry_source_.is_empty()); geometry_source_ = info.geometry_source_; + geometry_layout_ = info.geometry_layout_; } if (!info.fragment_source_.is_empty()) { BLI_assert(fragment_source_.is_empty()); diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index b4bd58630d5..a1ebdb0ec51 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -149,7 +149,7 @@ enum class Interpolation { }; /** Input layout for geometry shader. */ -enum class InputLayout { +enum class PrimitiveIn { POINTS = 0, LINES, LINES_ADJACENCY, @@ -158,7 +158,7 @@ enum class InputLayout { }; /** Output layout for geometry shader. */ -enum class OutputLayout { +enum class PrimitiveOut { POINTS = 0, LINE_STRIP, TRIANGLE_STRIP, @@ -233,16 +233,14 @@ struct ShaderCreateInfo { }; Vector<VertIn> vertex_inputs_; - struct GeomIn { - InputLayout layout; + struct GeometryStageLayout { + PrimitiveIn primitive_in; + int invocations; + PrimitiveOut primitive_out; + /** Set to -1 by default to check if used. */ + int max_vertices = -1; }; - GeomIn geom_in_; - - struct GeomOut { - OutputLayout layout; - int max_vertices; - }; - GeomOut geom_out_; + GeometryStageLayout geometry_layout_; struct FragOut { int index; @@ -350,11 +348,21 @@ struct ShaderCreateInfo { return *(Self *)this; } - Self &geometry_layout(InputLayout layout_in, OutputLayout layout_out, int max_vertices) + /** + * IMPORTANT: invocations count is only used if GL_ARB_gpu_shader5 is supported. On + * implementations that do not supports it, the max_vertices will be be multiplied by + * invocations. Your shader needs to account for this fact. Use `#ifdef GPU_ARB_gpu_shader5` + * and make a code path that does not rely on gl_InvocationID. + */ + Self &geometry_layout(PrimitiveIn prim_in, + PrimitiveOut prim_out, + int max_vertices, + int invocations = -1) { - geom_in_.layout = layout_in; - geom_out_.layout = layout_out; - geom_out_.max_vertices = max_vertices; + geometry_layout_.primitive_in = prim_in; + geometry_layout_.primitive_out = prim_out; + geometry_layout_.max_vertices = max_vertices; + geometry_layout_.invocations = invocations; return *(Self *)this; } diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 33574da9f58..1a445ebd7eb 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -246,6 +246,7 @@ static void detect_workarounds() GLContext::debug_layer_support = false; GLContext::direct_state_access_support = false; GLContext::fixed_restart_index_support = false; + GLContext::geometry_shader_invocations = false; GLContext::multi_bind_support = false; GLContext::multi_draw_indirect_support = false; GLContext::shader_draw_parameters_support = false; @@ -435,6 +436,7 @@ bool GLContext::copy_image_support = false; bool GLContext::debug_layer_support = false; bool GLContext::direct_state_access_support = false; bool GLContext::explicit_location_support = false; +bool GLContext::geometry_shader_invocations = false; bool GLContext::fixed_restart_index_support = false; bool GLContext::multi_bind_support = false; bool GLContext::multi_draw_indirect_support = false; @@ -494,6 +496,7 @@ void GLBackend::capabilities_init() GLContext::debug_layer_support = GLEW_VERSION_4_3 || GLEW_KHR_debug || GLEW_ARB_debug_output; GLContext::direct_state_access_support = GLEW_ARB_direct_state_access; GLContext::explicit_location_support = GLEW_VERSION_4_3; + GLContext::geometry_shader_invocations = GLEW_ARB_gpu_shader5; GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility; GLContext::multi_bind_support = GLEW_ARB_multi_bind; GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect; diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index eb365382d53..dd22418972b 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -70,6 +70,7 @@ class GLContext : public Context { static bool debug_layer_support; static bool direct_state_access_support; static bool explicit_location_support; + static bool geometry_shader_invocations; static bool fixed_restart_index_support; static bool multi_bind_support; static bool multi_draw_indirect_support; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index fe5ffe5a2ad..cec85abae6f 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -127,32 +127,32 @@ static const char *to_string(const Type &type) } } -static const char *to_string(const InputLayout &layout) +static const char *to_string(const PrimitiveIn &layout) { switch (layout) { - case InputLayout::POINTS: + case PrimitiveIn::POINTS: return "points"; - case InputLayout::LINES: + case PrimitiveIn::LINES: return "lines"; - case InputLayout::LINES_ADJACENCY: + case PrimitiveIn::LINES_ADJACENCY: return "lines_adjacency"; - case InputLayout::TRIANGLES: + case PrimitiveIn::TRIANGLES: return "triangles"; - case InputLayout::TRIANGLES_ADJACENCY: + case PrimitiveIn::TRIANGLES_ADJACENCY: return "triangles_adjacency"; default: return "unknown"; } } -static const char *to_string(const OutputLayout &layout) +static const char *to_string(const PrimitiveOut &layout) { switch (layout) { - case OutputLayout::POINTS: + case PrimitiveOut::POINTS: return "points"; - case OutputLayout::LINE_STRIP: + case PrimitiveOut::LINE_STRIP: return "line_strip"; - case OutputLayout::TRIANGLE_STRIP: + case PrimitiveOut::TRIANGLE_STRIP: return "triangle_strip"; default: return "unknown"; @@ -285,8 +285,7 @@ static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifie static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res) { - if (res.bind_type != ShaderCreateInfo::Resource::BindType::SAMPLER || - GLContext::explicit_location_support) { + if (GLContext::explicit_location_support) { os << "layout(binding = " << res.slot; if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { os << ", " << res.image.format; @@ -299,6 +298,9 @@ static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &r } os << ") "; } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) { + os << "layout(std140) "; + } int64_t array_offset; StringRef name_no_array; @@ -468,11 +470,24 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c std::string GLShader::geometry_layout_declare(const ShaderCreateInfo &info) const { + int max_verts = info.geometry_layout_.max_vertices; + int invocations = info.geometry_layout_.invocations; + + if (GLContext::geometry_shader_invocations == false && invocations != -1) { + max_verts *= invocations; + invocations = -1; + } + std::stringstream ss; - ss << "\n/* Layout. */\n"; - ss << "layout(" << to_string(info.geom_in_.layout) << ") in;\n"; - ss << "layout(" << to_string(info.geom_out_.layout) - << ", max_vertices = " << info.geom_out_.max_vertices << ") out;\n"; + ss << "\n/* Geometry Layout. */\n"; + ss << "layout(" << to_string(info.geometry_layout_.primitive_in); + if (invocations != -1) { + ss << ", invocations = " << invocations; + } + ss << ") in;\n"; + + ss << "layout(" << to_string(info.geometry_layout_.primitive_out) + << ", max_vertices = " << max_verts << ") out;\n"; ss << "\n"; return ss.str(); } @@ -529,6 +544,10 @@ static char *glsl_patch_default_get() STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n"); STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n"); } + if (GLContext::geometry_shader_invocations) { + STR_CONCAT(patch, slen, "#extension GL_ARB_gpu_shader5 : enable\n"); + STR_CONCAT(patch, slen, "#define GPU_ARB_gpu_shader5\n"); + } if (GLContext::texture_cube_map_array_support) { STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n"); STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n"); diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl index 3d3a042de65..b83ea59a692 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl @@ -64,10 +64,10 @@ flat out int isMainLine; # define doMuted (domuted[0] != 0) #else -# define P0 node_link_data.bezierPts[0] -# define P1 node_link_data.bezierPts[1] -# define P2 node_link_data.bezierPts[2] -# define P3 node_link_data.bezierPts[3] +# define P0 node_link_data.bezierPts[0].xy +# define P1 node_link_data.bezierPts[1].xy +# define P2 node_link_data.bezierPts[2].xy +# define P3 node_link_data.bezierPts[3].xy # define cols node_link_data.colors # define doArrow node_link_data.doArrow # define doMuted node_link_data.doMuted diff --git a/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh index 5c8410baf04..c337c399f59 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_gpencil_stroke_info.hh @@ -35,7 +35,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_gpencil_stroke) .vertex_in(1, Type::VEC3, "pos") .vertex_in(2, Type::FLOAT, "thickness") .vertex_out(gpencil_stroke_vert_iface) - .geometry_layout(InputLayout::LINES_ADJACENCY, OutputLayout::TRIANGLE_STRIP, 13) + .geometry_layout(PrimitiveIn::LINES_ADJACENCY, PrimitiveOut::TRIANGLE_STRIP, 13) .geometry_out(gpencil_stroke_geom_iface) .fragment_out(0, Type::VEC4, "fragColor") diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 63c4774d0e5..ec20fa54a44 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -729,7 +729,7 @@ void rna_Object_me_eval_info( } if (me_eval) { - ret = BKE_mesh_runtime_debug_info(me_eval); + ret = BKE_mesh_debug_info(me_eval); if (ret) { strcpy(result, ret); MEM_freeN(ret); diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 2a303c7741c..bb05ae3e1b3 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -248,13 +248,14 @@ static BMesh *BMD_mesh_bm_create( BMeshCreateParams bmesh_create_params{}; BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params); - /* Needed so active layers are set based on `mesh` not `mesh_operand_ob`, - * otherwise the wrong active render layer is used, see T92384. */ - BM_mesh_copy_init_customdata_from_mesh(bm, mesh, &allocsize); - - /* NOTE(@campbellbarton): Handle in #BM_mesh_bm_from_me, this is a local fix for T94197. */ - BM_mesh_cd_flag_apply(bm, - mesh->cd_flag | mesh_operand_ob->cd_flag | BM_mesh_cd_flag_from_bmesh(bm)); + /* Keep `mesh` first, needed so active layers are set based on `mesh` not `mesh_operand_ob`, + * otherwise the wrong active render layer is used, see T92384. + * + * NOTE: while initializing customer data layers the is not essential, + * it avoids the overhead of having to re-allocate #BMHeader.data when the 2nd mesh is added + * (if it contains additional custom-data layers). */ + const Mesh *mesh_array[2] = {mesh, mesh_operand_ob}; + BM_mesh_copy_init_customdata_from_mesh_array(bm, mesh_array, ARRAY_SIZE(mesh_array), &allocsize); BMeshFromMeshParams bmesh_from_mesh_params{}; bmesh_from_mesh_params.calc_face_normal = true; diff --git a/source/blender/python/gpu/gpu_py_framebuffer.c b/source/blender/python/gpu/gpu_py_framebuffer.c index a9347b71723..412fcac02ca 100644 --- a/source/blender/python/gpu/gpu_py_framebuffer.c +++ b/source/blender/python/gpu/gpu_py_framebuffer.c @@ -530,6 +530,7 @@ static PyObject *pygpu_framebuffer_read_color(BPyGPUFrameBuffer *self, PyErr_SetString(PyExc_BufferError, "the buffer size is smaller than expected"); return NULL; } + Py_INCREF(py_buffer); } else { py_buffer = BPyGPU_Buffer_CreatePyObject( @@ -590,6 +591,7 @@ static PyObject *pygpu_framebuffer_read_depth(BPyGPUFrameBuffer *self, PyErr_SetString(PyExc_BufferError, "the buffer size is smaller than expected"); return NULL; } + Py_INCREF(py_buffer); } else { py_buffer = BPyGPU_Buffer_CreatePyObject(GPU_DATA_FLOAT, (Py_ssize_t[]){h, w}, 2, NULL); diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt index eccc336141a..54524e453d4 100644 --- a/source/blender/sequencer/CMakeLists.txt +++ b/source/blender/sequencer/CMakeLists.txt @@ -46,6 +46,7 @@ set(INC_SYS set(SRC SEQ_add.h + SEQ_animation.h SEQ_clipboard.h SEQ_edit.h SEQ_effects.h @@ -62,6 +63,7 @@ set(SRC SEQ_transform.h SEQ_utils.h + intern/animation.c intern/clipboard.c intern/disk_cache.c intern/disk_cache.h diff --git a/source/blender/sequencer/SEQ_animation.h b/source/blender/sequencer/SEQ_animation.h new file mode 100644 index 00000000000..028f932344f --- /dev/null +++ b/source/blender/sequencer/SEQ_animation.h @@ -0,0 +1,41 @@ +/* + * 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) 2022 Blender Foundation. + * All rights reserved. + */ + +#pragma once + +/** \file + * \ingroup sequencer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct GSet; +struct ListBase; +struct Scene; +struct Sequence; + +void SEQ_free_animdata(struct Scene *scene, struct Sequence *seq); +void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); +struct GSet *SEQ_fcurves_by_strip_get(const struct Sequence *seq, struct ListBase *fcurve_base); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/sequencer/SEQ_clipboard.h b/source/blender/sequencer/SEQ_clipboard.h index 72388c5db64..dc78f8cc1a2 100644 --- a/source/blender/sequencer/SEQ_clipboard.h +++ b/source/blender/sequencer/SEQ_clipboard.h @@ -33,6 +33,7 @@ struct Scene; struct Sequence; extern struct ListBase seqbase_clipboard; +extern struct ListBase fcurves_clipboard; extern int seqbase_clipboard_frame; void SEQ_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); void SEQ_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index 1229f6f7bea..2e340049dbd 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -84,7 +84,7 @@ struct ListBase *SEQ_active_seqbase_get(const struct Editing *ed); */ void SEQ_seqbase_active_set(struct Editing *ed, struct ListBase *seqbase); struct Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type); -void SEQ_sequence_free(struct Scene *scene, struct Sequence *seq, bool do_clean_animdata); +void SEQ_sequence_free(struct Scene *scene, struct Sequence *seq); /** * Create and initialize #MetaStack, append it to `ed->metastack` ListBase * @@ -107,8 +107,6 @@ struct MetaStack *SEQ_meta_stack_active_get(const struct Editing *ed); * \param ms: meta stack */ void SEQ_meta_stack_free(struct Editing *ed, struct MetaStack *ms); -void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); -void SEQ_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst); struct Sequence *SEQ_sequence_dupli_recursive(const struct Scene *scene_src, struct Scene *scene_dst, struct ListBase *new_seq_list, diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c new file mode 100644 index 00000000000..492b757a4b1 --- /dev/null +++ b/source/blender/sequencer/intern/animation.c @@ -0,0 +1,122 @@ +/* + * 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) 2022 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup sequencer + */ + +#include <string.h> + +#include "DNA_anim_types.h" +#include "DNA_scene_types.h" +#include "DNA_sequence_types.h" + +#include "BKE_animsys.h" +#include "BKE_fcurve.h" + +#include "BLI_ghash.h" +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "DEG_depsgraph.h" + +#include "SEQ_animation.h" + +static bool seq_animation_curves_exist(Scene *scene) +{ + if (scene->adt == NULL || scene->adt->action == NULL || + BLI_listbase_is_empty(&scene->adt->action->curves)) { + return false; + } + return true; +} + +/* r_prefix + [" + escaped_name + "] + \0 */ +#define SEQ_RNAPATH_MAXSTR ((30 + 2 + (SEQ_NAME_MAXSTR * 2) + 2) + 1) + +static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char *name) +{ + char name_esc[SEQ_NAME_MAXSTR * 2]; + + BLI_str_escape(name_esc, name, sizeof(name_esc)); + return BLI_snprintf_rlen( + str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc); +} + +GSet *SEQ_fcurves_by_strip_get(const Sequence *seq, ListBase *fcurve_base) +{ + char rna_path[SEQ_RNAPATH_MAXSTR]; + size_t rna_path_len = sequencer_rna_path_prefix(rna_path, seq->name + 2); + + GSet *fcurves = BLI_gset_ptr_new(__func__); + LISTBASE_FOREACH (FCurve *, fcurve, fcurve_base) { + if (STREQLEN(fcurve->rna_path, rna_path, rna_path_len)) { + BLI_gset_add(fcurves, fcurve); + } + } + + return fcurves; +} + +#undef SEQ_RNAPATH_MAXSTR + +void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) +{ + if (!seq_animation_curves_exist(scene) || ofs == 0) { + return; + } + + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); + GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { + unsigned int i; + if (fcu->bezt) { + for (i = 0; i < fcu->totvert; i++) { + BezTriple *bezt = &fcu->bezt[i]; + bezt->vec[0][0] += ofs; + bezt->vec[1][0] += ofs; + bezt->vec[2][0] += ofs; + } + } + if (fcu->fpt) { + for (i = 0; i < fcu->totvert; i++) { + FPoint *fpt = &fcu->fpt[i]; + fpt->vec[0] += ofs; + } + } + } + GSET_FOREACH_END(); + BLI_gset_free(fcurves, NULL); + + DEG_id_tag_update(&scene->adt->action->id, ID_RECALC_ANIMATION); +} + +void SEQ_free_animdata(Scene *scene, Sequence *seq) +{ + if (!seq_animation_curves_exist(scene)) { + return; + } + + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); + GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { + BLI_remlink(&scene->adt->action->curves, fcu); + BKE_fcurve_free(fcu); + } + GSET_FOREACH_END(); + BLI_gset_free(fcurves, NULL); +} diff --git a/source/blender/sequencer/intern/clipboard.c b/source/blender/sequencer/intern/clipboard.c index 73e0f616da4..886ee89595b 100644 --- a/source/blender/sequencer/intern/clipboard.c +++ b/source/blender/sequencer/intern/clipboard.c @@ -28,6 +28,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_sound_types.h" @@ -35,6 +36,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "BKE_fcurve.h" #include "BKE_main.h" #include "BKE_movieclip.h" #include "BKE_scene.h" @@ -58,6 +60,7 @@ */ ListBase seqbase_clipboard; +ListBase fcurves_clipboard; int seqbase_clipboard_frame; static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR]; @@ -65,15 +68,17 @@ void seq_clipboard_pointers_free(struct ListBase *seqbase); void SEQ_clipboard_free(void) { - Sequence *seq, *nseq; - seq_clipboard_pointers_free(&seqbase_clipboard); - for (seq = seqbase_clipboard.first; seq; seq = nseq) { - nseq = seq->next; - seq_free_sequence_recurse(NULL, seq, false, true); + LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &seqbase_clipboard) { + seq_free_sequence_recurse(NULL, seq, false); } BLI_listbase_clear(&seqbase_clipboard); + + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &fcurves_clipboard) { + BKE_fcurve_free(fcu); + } + BLI_listbase_clear(&fcurves_clipboard); } #define ID_PT (*id_pt) diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index 30afa3f9c59..2cb2ba13fb5 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -591,7 +591,7 @@ void SEQ_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop) IMB_anim_index_rebuild_finish(context->index_context, stop); } - seq_free_sequence_recurse(NULL, context->seq, true, true); + seq_free_sequence_recurse(NULL, context->seq, true); MEM_freeN(context); } diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index e4120a3cf95..f0a45355143 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -34,10 +34,7 @@ #include "DNA_sound_types.h" #include "BLI_listbase.h" -#include "BLI_string.h" -#include "BKE_animsys.h" -#include "BKE_fcurve.h" #include "BKE_idprop.h" #include "BKE_lib_id.h" #include "BKE_sound.h" @@ -65,8 +62,6 @@ #include "sequencer.h" #include "utils.h" -static void seq_free_animdata(Scene *scene, Sequence *seq); - /* -------------------------------------------------------------------- */ /** \name Allocate / Free Functions * \{ */ @@ -156,8 +151,7 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int static void seq_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cache, - const bool do_id_user, - const bool do_clean_animdata) + const bool do_id_user) { if (seq->strip) { seq_free_strip(seq->strip); @@ -191,11 +185,6 @@ static void seq_sequence_free_ex(Scene *scene, if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { BKE_sound_remove_scene_sound(scene, seq->scene_sound); } - - /* XXX This must not be done in BKE code. */ - if (do_clean_animdata) { - seq_free_animdata(scene, seq); - } } if (seq->prop) { @@ -223,24 +212,21 @@ static void seq_sequence_free_ex(Scene *scene, MEM_freeN(seq); } -void SEQ_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata) +void SEQ_sequence_free(Scene *scene, Sequence *seq) { - seq_sequence_free_ex(scene, seq, true, true, do_clean_animdata); + seq_sequence_free_ex(scene, seq, true, true); } -void seq_free_sequence_recurse(Scene *scene, - Sequence *seq, - const bool do_id_user, - const bool do_clean_animdata) +void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user) { Sequence *iseq, *iseq_next; for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) { iseq_next = iseq->next; - seq_free_sequence_recurse(scene, iseq, do_id_user, do_clean_animdata); + seq_free_sequence_recurse(scene, iseq, do_id_user); } - seq_sequence_free_ex(scene, seq, false, do_id_user, do_clean_animdata); + seq_sequence_free_ex(scene, seq, false, do_id_user); } Editing *SEQ_editing_get(const Scene *scene) @@ -276,7 +262,7 @@ void SEQ_editing_free(Scene *scene, const bool do_id_user) /* handle cache freeing above */ LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &ed->seqbase) { - seq_free_sequence_recurse(scene, seq, do_id_user, false); + seq_free_sequence_recurse(scene, seq, do_id_user); } BLI_freelistN(&ed->metastack); @@ -623,120 +609,6 @@ bool SEQ_valid_strip_channel(Sequence *seq) return true; } -/* r_prefix + [" + escaped_name + "] + \0 */ -#define SEQ_RNAPATH_MAXSTR ((30 + 2 + (SEQ_NAME_MAXSTR * 2) + 2) + 1) - -static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char *name) -{ - char name_esc[SEQ_NAME_MAXSTR * 2]; - - BLI_str_escape(name_esc, name, sizeof(name_esc)); - return BLI_snprintf_rlen( - str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc); -} - -void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) -{ - /* XXX: hackish function needed for transforming strips! - * TODO: have some better solution. */ - - char str[SEQ_RNAPATH_MAXSTR]; - size_t str_len; - FCurve *fcu; - - if (scene->adt == NULL || ofs == 0 || scene->adt->action == NULL) { - return; - } - - str_len = sequencer_rna_path_prefix(str, seq->name + 2); - - for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) { - if (STREQLEN(fcu->rna_path, str, str_len)) { - unsigned int i; - if (fcu->bezt) { - for (i = 0; i < fcu->totvert; i++) { - BezTriple *bezt = &fcu->bezt[i]; - bezt->vec[0][0] += ofs; - bezt->vec[1][0] += ofs; - bezt->vec[2][0] += ofs; - } - } - if (fcu->fpt) { - for (i = 0; i < fcu->totvert; i++) { - FPoint *fpt = &fcu->fpt[i]; - fpt->vec[0] += ofs; - } - } - } - } - - DEG_id_tag_update(&scene->adt->action->id, ID_RECALC_ANIMATION); -} - -void SEQ_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst) -{ - char str_from[SEQ_RNAPATH_MAXSTR]; - size_t str_from_len; - FCurve *fcu; - FCurve *fcu_last; - FCurve *fcu_cpy; - ListBase lb = {NULL, NULL}; - - if (scene->adt == NULL || scene->adt->action == NULL) { - return; - } - - str_from_len = sequencer_rna_path_prefix(str_from, name_src); - - fcu_last = scene->adt->action->curves.last; - - for (fcu = scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu = fcu->next) { - if (STREQLEN(fcu->rna_path, str_from, str_from_len)) { - fcu_cpy = BKE_fcurve_copy(fcu); - BLI_addtail(&lb, fcu_cpy); - } - } - - /* notice validate is 0, keep this because the seq may not be added to the scene yet */ - BKE_animdata_fix_paths_rename( - &scene->id, scene->adt, NULL, "sequence_editor.sequences_all", name_src, name_dst, 0, 0, 0); - - /* add the original fcurves back */ - BLI_movelisttolist(&scene->adt->action->curves, &lb); -} - -/* XXX: hackish function needed to remove all fcurves belonging to a sequencer strip. */ -static void seq_free_animdata(Scene *scene, Sequence *seq) -{ - char str[SEQ_RNAPATH_MAXSTR]; - size_t str_len; - FCurve *fcu; - - if (scene->adt == NULL || scene->adt->action == NULL) { - return; - } - - str_len = sequencer_rna_path_prefix(str, seq->name + 2); - - fcu = scene->adt->action->curves.first; - - while (fcu) { - if (STREQLEN(fcu->rna_path, str, str_len)) { - FCurve *next_fcu = fcu->next; - - BLI_remlink(&scene->adt->action->curves, fcu); - BKE_fcurve_free(fcu); - - fcu = next_fcu; - } - else { - fcu = fcu->next; - } - } -} - -#undef SEQ_RNAPATH_MAXSTR - SequencerToolSettings *SEQ_tool_settings_copy(SequencerToolSettings *tool_settings) { SequencerToolSettings *tool_settings_copy = MEM_dupallocN(tool_settings); diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h index aff81255d7d..7d7ecbc8178 100644 --- a/source/blender/sequencer/intern/sequencer.h +++ b/source/blender/sequencer/intern/sequencer.h @@ -34,10 +34,7 @@ struct Sequence; * Cache must be freed before calling this function * since it leaves the seqbase in an invalid state. */ -void seq_free_sequence_recurse(struct Scene *scene, - struct Sequence *seq, - bool do_id_user, - bool do_clean_animdata); +void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, bool do_id_user); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index cf303e5be4e..0479d3012fa 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -43,6 +43,7 @@ #include "utils.h" #include "SEQ_add.h" +#include "SEQ_animation.h" #include "SEQ_edit.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" @@ -199,8 +200,9 @@ void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase) if (seq->type == SEQ_TYPE_META) { SEQ_edit_remove_flagged_sequences(scene, &seq->seqbase); } + SEQ_free_animdata(scene, seq); BLI_remlink(seqbase, seq); - SEQ_sequence_free(scene, seq, true); + SEQ_sequence_free(scene, seq); SEQ_sequence_lookup_tag(scene, SEQ_LOOKUP_TAG_INVALID); } } diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index ce5917b999f..432fc1c166f 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -33,6 +33,7 @@ #include "BKE_scene.h" #include "BKE_sound.h" +#include "SEQ_animation.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" #include "SEQ_relations.h" diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c index 156c6ac4cb9..140aa2d67c5 100644 --- a/source/blender/sequencer/intern/utils.c +++ b/source/blender/sequencer/intern/utils.c @@ -35,10 +35,12 @@ #include "BLI_blenlib.h" +#include "BKE_animsys.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_scene.h" +#include "SEQ_animation.h" #include "SEQ_edit.h" #include "SEQ_iterator.h" #include "SEQ_relations.h" @@ -583,7 +585,8 @@ void SEQ_ensure_unique_name(Sequence *seq, Scene *scene) BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); SEQ_sequence_base_unique_name_recursive(scene, &scene->ed->seqbase, seq); - SEQ_dupe_animdata(scene, name, seq->name + 2); + BKE_animdata_fix_paths_rename( + &scene->id, scene->adt, NULL, "sequence_editor.sequences_all", name, seq->name + 2, 0, 0, 0); if (seq->type == SEQ_TYPE_META) { LISTBASE_FOREACH (Sequence *, seq_child, &seq->seqbase) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 344f4959a93..1478712c3cd 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1521,11 +1521,29 @@ static void wm_history_file_update(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Save Main Blend-File (internal) Screen-Shot +/** \name Thumbnail Generation: Screen-Shot / Camera View + * + * Thumbnail Sizes + * =============== + * + * - `PREVIEW_RENDER_LARGE_HEIGHT * 2` is used to render a large thumbnail, + * giving some over-sampling when scaled down: + * + * - There are two outputs for this thumbnail: + * + * - An image is saved to the thumbnail cache, sized at #PREVIEW_RENDER_LARGE_HEIGHT. + * + * - A smaller thumbnail is stored in the `.blend` file it's self, sized at #BLEN_THUMB_SIZE. + * The size is kept small to prevent thumbnails bloating the size of `.blend` files. + * + * The this thumbnail will be extracted if the file is shared or the local thumbnail cache + * is cleared. see: `blendthumb_extract.cc` for logic that extracts the thumbnail. * - * Screen-shot the active window. * \{ */ +/** + * Screen-shot the active window. + */ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_thumb) { *r_thumb = NULL; @@ -1571,15 +1589,11 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t return ibuf; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Save Main Blend-File (internal) Camera View - * +/** * Render the current scene with the active camera. - * \{ */ - -/* screen can be NULL */ + * + * \param screen: can be NULL. + */ static ImBuf *blend_file_thumb_from_camera(const bContext *C, Scene *scene, bScreen *screen, @@ -1617,7 +1631,6 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, return NULL; } - /* gets scaled to BLEN_THUMB_SIZE */ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); /* Note that with scaling, this ends up being 0.5, @@ -1689,6 +1702,12 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, return ibuf; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Write Main Blend-File (internal) + * \{ */ + bool write_crash_blend(void) { char path[FILE_MAX]; @@ -2017,7 +2036,7 @@ void wm_autosave_delete(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Initialize WM_OT_open_xxx properties +/** \name Initialize `WM_OT_open_*` Properties * * Check if load_ui was set by the caller. * Fall back to user preference when file flags not specified. |