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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Trickey <howard.trickey@gmail.com>2020-08-28 17:27:21 +0300
committerHoward Trickey <howard.trickey@gmail.com>2020-08-28 17:27:21 +0300
commitb8cc4b93927929e5898f3270013aa8e03ba96724 (patch)
tree61c1e5b7d6bb6b49fdc914a5115dd7cd1b17ed5c
parent8556a10bd9f608ebdbf8d1faf573fc53aa59324a (diff)
parent7b2fe4c9ec683bb7da270a54c44d301016e1470d (diff)
Merge branch 'master' into newboolean
-rw-r--r--intern/cycles/device/opencl/device_opencl_impl.cpp8
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_bake.cl14
-rw-r--r--source/blender/blenkernel/BKE_customdata.h10
-rw-r--r--source/blender/blenkernel/BKE_deform.h7
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h4
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h1
-rw-r--r--source/blender/blenkernel/intern/customdata.c184
-rw-r--r--source/blender/blenkernel/intern/deform.c48
-rw-r--r--source/blender/blenkernel/intern/lattice.c70
-rw-r--r--source/blender/blenkernel/intern/lib_id.c29
-rw-r--r--source/blender/blenkernel/intern/lib_override.c14
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c12
-rw-r--r--source/blender/blenkernel/intern/mesh.c167
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c32
-rw-r--r--source/blender/blenloader/intern/readfile.c292
-rw-r--r--source/blender/blenloader/intern/writefile.c347
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc61
-rw-r--r--source/blender/draw/CMakeLists.txt22
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h8
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h10
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl1
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h7
-rw-r--r--source/blender/draw/intern/draw_manager.c16
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c3
-rw-r--r--source/blender/draw/intern/draw_manager_testing.h39
-rw-r--r--source/blender/draw/tests/shaders_test.cc270
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c9
-rw-r--r--source/blender/gpu/GPU_state.h1
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh2
-rw-r--r--source/blender/makesdna/intern/makesdna.c1
33 files changed, 1043 insertions, 663 deletions
diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp
index e851749949d..f0683d12f1f 100644
--- a/intern/cycles/device/opencl/device_opencl_impl.cpp
+++ b/intern/cycles/device/opencl/device_opencl_impl.cpp
@@ -864,6 +864,11 @@ void OpenCLDevice::load_preview_kernels()
bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures &requested_features)
{
+ if (requested_features.use_baking) {
+ /* For baking, kernels have already been loaded in load_required_kernels(). */
+ return true;
+ }
+
if (background) {
load_kernel_task_pool.wait_work();
use_preview_kernels = false;
@@ -1933,13 +1938,12 @@ void OpenCLDevice::bake(DeviceTask &task, RenderTile &rtile)
kernel_set_args(kernel, start_arg_index, sample);
enqueue_kernel(kernel, d_w, d_h);
+ clFinish(cqCommandQueue);
rtile.sample = sample + 1;
task.update_progress(&rtile, rtile.w * rtile.h);
}
-
- clFinish(cqCommandQueue);
}
static bool kernel_build_opencl_2(cl_device_id cdDevice)
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_bake.cl b/intern/cycles/kernel/kernels/opencl/kernel_bake.cl
index 041312b53cb..7b81e387467 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_bake.cl
+++ b/intern/cycles/kernel/kernels/opencl/kernel_bake.cl
@@ -12,12 +12,11 @@
__kernel void kernel_ocl_bake(
ccl_constant KernelData *data,
- ccl_global uint4 *input,
- ccl_global float4 *output,
+ ccl_global float *buffer,
KERNEL_BUFFER_PARAMS,
- int type, int filter, int sx, int sw, int offset, int sample)
+ int sx, int sy, int sw, int sh, int offset, int stride, int sample)
{
KernelGlobals kglobals, *kg = &kglobals;
@@ -27,12 +26,11 @@ __kernel void kernel_ocl_bake(
kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
+ int y = sy + ccl_global_id(1);
- if(x < sx + sw) {
-#ifdef __NO_BAKING__
- output[x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-#else
- kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, x, offset, sample);
+ if(x < sx + sw && y < sy + sh) {
+#ifndef __NO_BAKING__
+ kernel_bake_evaluate(kg, buffer, sample, x, y, offset, stride);
#endif
}
}
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 92bfa3a9490..25360d4b3fa 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -37,6 +37,8 @@ struct BMesh;
struct CustomData;
struct CustomData_MeshMasks;
struct ID;
+struct BlendWriter;
+struct BlendDataReader;
typedef uint64_t CustomDataMask;
/*a data type large enough to hold 1 element from any customdata layer type*/
@@ -571,6 +573,14 @@ typedef struct CustomDataTransferLayerMap {
void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
const CustomDataTransferLayerMap *laymap);
+/* .blend file I/O */
+void CustomData_blend_write(struct BlendWriter *writer,
+ struct CustomData *data,
+ int count,
+ CustomDataMask cddata_mask,
+ struct ID *id);
+void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 35111d5240e..a9f81676a7a 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -35,6 +35,8 @@ struct MLoop;
struct MPoly;
struct Object;
struct bDeformGroup;
+struct BlendWriter;
+struct BlendDataReader;
struct bDeformGroup *BKE_object_defgroup_new(struct Object *ob, const char *name);
void BKE_defgroup_copy_list(struct ListBase *lb1, const struct ListBase *lb2);
@@ -162,6 +164,11 @@ void BKE_defvert_extract_vgroup_to_polyweights(struct MDeformVert *dvert,
void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight);
+void BKE_defvert_blend_write(struct BlendWriter *writer, int count, struct MDeformVert *dvlist);
+void BKE_defvert_blend_read(struct BlendDataReader *reader,
+ int count,
+ struct MDeformVert *mdverts);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index a2cbe537349..7768e903ac3 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -59,6 +59,8 @@ struct Main;
struct PointerRNA;
struct PropertyRNA;
struct bContext;
+struct BlendWriter;
+struct BlendDataReader;
size_t BKE_libblock_get_alloc_info(short type, const char **name);
void *BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT;
@@ -285,6 +287,8 @@ bool BKE_id_is_in_global_main(struct ID *id);
void BKE_id_ordered_list(struct ListBase *ordered_lb, const struct ListBase *lb);
void BKE_id_reorder(const struct ListBase *lb, struct ID *id, struct ID *relative, bool after);
+void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id);
+
#define IS_TAGGED(_id) ((_id) && (((ID *)_id)->tag & LIB_TAG_DOIT))
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index c2059144388..ae1e437cd60 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -143,6 +143,7 @@ void BKE_rigidbody_aftertrans_update(struct Object *ob,
float rotAngle);
void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime);
+bool BKE_rigidbody_is_affected_by_simulation(struct Object *ob);
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, struct Scene *scene, float ctime);
void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, struct Scene *scene, float ctime);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index f728436a759..b75efb6cdf1 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -35,6 +35,8 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
+#include "BLI_bitmap.h"
+#include "BLI_endian_switch.h"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
#include "BLI_mempool.h"
@@ -47,10 +49,14 @@
#include "BKE_customdata.h"
#include "BKE_customdata_file.h"
+#include "BKE_deform.h"
#include "BKE_main.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_multires.h"
+#include "BKE_subsurf.h"
+
+#include "BLO_read_write.h"
#include "bmesh.h"
@@ -5155,3 +5161,181 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
MEM_SAFE_FREE(tmp_data_src);
}
+
+static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external)
+{
+ if (mdlist) {
+ BLO_write_struct_array(writer, MDisps, count, mdlist);
+ for (int i = 0; i < count; i++) {
+ MDisps *md = &mdlist[i];
+ if (md->disps) {
+ if (!external) {
+ BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]);
+ }
+ }
+
+ if (md->hidden) {
+ BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden);
+ }
+ }
+ }
+}
+
+static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask)
+{
+ if (grid_paint_mask) {
+ BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask);
+ for (int i = 0; i < count; i++) {
+ GridPaintMask *gpm = &grid_paint_mask[i];
+ if (gpm->data) {
+ const int gridsize = BKE_ccg_gridsize(gpm->level);
+ BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data);
+ }
+ }
+ }
+}
+
+void CustomData_blend_write(
+ BlendWriter *writer, CustomData *data, int count, CustomDataMask cddata_mask, ID *id)
+{
+ CustomDataLayer *layers = NULL;
+ CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_file_write_prepare(data, &layers, layers_buff, ARRAY_SIZE(layers_buff));
+
+ /* write external customdata (not for undo) */
+ if (data->external && !BLO_write_is_undo(writer)) {
+ CustomData_external_write(data, id, cddata_mask, count, 0);
+ }
+
+ BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers);
+
+ for (int i = 0; i < data->totlayer; i++) {
+ CustomDataLayer *layer = &layers[i];
+
+ if (layer->type == CD_MDEFORMVERT) {
+ /* layer types that allocate own memory need special handling */
+ BKE_defvert_blend_write(writer, count, layer->data);
+ }
+ else if (layer->type == CD_MDISPS) {
+ write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
+ }
+ else if (layer->type == CD_PAINT_MASK) {
+ const float *layer_data = layer->data;
+ BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
+ }
+ else if (layer->type == CD_SCULPT_FACE_SETS) {
+ const float *layer_data = layer->data;
+ BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
+ }
+ else if (layer->type == CD_GRID_PAINT_MASK) {
+ write_grid_paint_mask(writer, count, layer->data);
+ }
+ else if (layer->type == CD_FACEMAP) {
+ const int *layer_data = layer->data;
+ BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
+ }
+ else {
+ const char *structname;
+ int structnum;
+ CustomData_file_write_info(layer->type, &structname, &structnum);
+ if (structnum) {
+ int datasize = structnum * count;
+ BLO_write_struct_array_by_name(writer, structname, datasize, layer->data);
+ }
+ else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */
+ printf("%s error: layer '%s':%d - can't be written to file\n",
+ __func__,
+ structname,
+ layer->type);
+ }
+ }
+ }
+
+ if (data->external) {
+ BLO_write_struct(writer, CustomDataExternal, data->external);
+ }
+
+ if (!ELEM(layers, NULL, layers_buff)) {
+ MEM_freeN(layers);
+ }
+}
+
+static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external)
+{
+ if (mdisps) {
+ for (int i = 0; i < count; i++) {
+ BLO_read_data_address(reader, &mdisps[i].disps);
+ BLO_read_data_address(reader, &mdisps[i].hidden);
+
+ if (mdisps[i].totdisp && !mdisps[i].level) {
+ /* this calculation is only correct for loop mdisps;
+ * if loading pre-BMesh face mdisps this will be
+ * overwritten with the correct value in
+ * bm_corners_to_loops() */
+ float gridsize = sqrtf(mdisps[i].totdisp);
+ mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1;
+ }
+
+ if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) {
+ /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
+ /* this does swap for data written at write_mdisps() - readfile.c */
+ BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
+ }
+ if (!external && !mdisps[i].disps) {
+ mdisps[i].totdisp = 0;
+ }
+ }
+ }
+}
+
+static void blend_read_paint_mask(BlendDataReader *reader,
+ int count,
+ GridPaintMask *grid_paint_mask)
+{
+ if (grid_paint_mask) {
+ for (int i = 0; i < count; i++) {
+ GridPaintMask *gpm = &grid_paint_mask[i];
+ if (gpm->data) {
+ BLO_read_data_address(reader, &gpm->data);
+ }
+ }
+ }
+}
+
+void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
+{
+ BLO_read_data_address(reader, &data->layers);
+
+ /* annoying workaround for bug [#31079] loading legacy files with
+ * no polygons _but_ have stale customdata */
+ if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
+ CustomData_reset(data);
+ return;
+ }
+
+ BLO_read_data_address(reader, &data->external);
+
+ int i = 0;
+ while (i < data->totlayer) {
+ CustomDataLayer *layer = &data->layers[i];
+
+ if (layer->flag & CD_FLAG_EXTERNAL) {
+ layer->flag &= ~CD_FLAG_IN_MEMORY;
+ }
+
+ layer->flag &= ~CD_FLAG_NOFREE;
+
+ if (CustomData_verify_versions(data, i)) {
+ BLO_read_data_address(reader, &layer->data);
+ if (layer->type == CD_MDISPS) {
+ blend_read_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
+ }
+ else if (layer->type == CD_GRID_PAINT_MASK) {
+ blend_read_paint_mask(reader, count, layer->data);
+ }
+ i++;
+ }
+ }
+
+ CustomData_update_typemap(data);
+}
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 1a32deac776..4f5a2740ca6 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -50,6 +50,8 @@
#include "BKE_object.h"
#include "BKE_object_deform.h"
+#include "BLO_read_write.h"
+
#include "data_transfer_intern.h"
bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name)
@@ -1523,3 +1525,49 @@ void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name .blend file I/O
+ * \{ */
+
+void BKE_defvert_blend_write(BlendWriter *writer, int count, MDeformVert *dvlist)
+{
+ if (dvlist == NULL) {
+ return;
+ }
+
+ /* Write the dvert list */
+ BLO_write_struct_array(writer, MDeformVert, count, dvlist);
+
+ /* Write deformation data for each dvert */
+ for (int i = 0; i < count; i++) {
+ if (dvlist[i].dw) {
+ BLO_write_struct_array(writer, MDeformWeight, dvlist[i].totweight, dvlist[i].dw);
+ }
+ }
+}
+
+void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdverts)
+{
+ if (mdverts == NULL) {
+ return;
+ }
+
+ for (int i = count; i > 0; i--, mdverts++) {
+ /*convert to vgroup allocation system*/
+ MDeformWeight *dw;
+ if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) {
+ const ssize_t dw_len = mdverts->totweight * sizeof(MDeformWeight);
+ void *dw_tmp = MEM_mallocN(dw_len, __func__);
+ memcpy(dw_tmp, dw, dw_len);
+ mdverts->dw = dw_tmp;
+ MEM_freeN(dw);
+ }
+ else {
+ mdverts->dw = NULL;
+ mdverts->totweight = 0;
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 5782fab905f..7304dd91eea 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -35,6 +35,9 @@
#include "BLT_translation.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_curve_types.h"
#include "DNA_defaults.h"
#include "DNA_key_types.h"
@@ -43,7 +46,9 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_anim_data.h"
#include "BKE_curve.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_idtype.h"
#include "BKE_lattice.h"
@@ -53,10 +58,10 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
-#include "BKE_deform.h"
-
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
static void lattice_init_data(ID *id)
{
Lattice *lattice = (Lattice *)id;
@@ -124,6 +129,59 @@ static void lattice_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS(data, lattice->key, IDWALK_CB_USER);
}
+static void lattice_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Lattice *lt = (Lattice *)id;
+ if (lt->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ lt->editlatt = NULL;
+ lt->batch_cache = NULL;
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Lattice, id_address, &lt->id);
+ BKE_id_blend_write(writer, &lt->id);
+
+ /* write animdata */
+ if (lt->adt) {
+ BKE_animdata_blend_write(writer, lt->adt);
+ }
+
+ /* direct data */
+ BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def);
+
+ BKE_defvert_blend_write(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
+ }
+}
+
+static void lattice_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Lattice *lt = (Lattice *)id;
+ BLO_read_data_address(reader, &lt->def);
+
+ BLO_read_data_address(reader, &lt->dvert);
+ BKE_defvert_blend_read(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
+
+ lt->editlatt = NULL;
+ lt->batch_cache = NULL;
+
+ BLO_read_data_address(reader, &lt->adt);
+ BKE_animdata_blend_read_data(reader, lt->adt);
+}
+
+static void lattice_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Lattice *lt = (Lattice *)id;
+ BLO_read_id_address(reader, lt->id.lib, &lt->ipo); // XXX deprecated - old animation system
+ BLO_read_id_address(reader, lt->id.lib, &lt->key);
+}
+
+static void lattice_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Lattice *lt = (Lattice *)id;
+ BLO_expand(expander, lt->ipo); // XXX deprecated - old animation system
+ BLO_expand(expander, lt->key);
+}
+
IDTypeInfo IDType_ID_LT = {
.id_code = ID_LT,
.id_filter = FILTER_ID_LT,
@@ -141,10 +199,10 @@ IDTypeInfo IDType_ID_LT = {
.foreach_id = lattice_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = lattice_blend_write,
+ .blend_read_data = lattice_blend_read_data,
+ .blend_read_lib = lattice_blend_read_lib,
+ .blend_read_expand = lattice_blend_read_expand,
};
int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w)
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 7fb19458eec..678f717efe4 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -75,6 +75,8 @@
#include "RNA_access.h"
+#include "BLO_read_write.h"
+
#include "atomic_ops.h"
//#define DEBUG_TIME
@@ -2326,3 +2328,30 @@ void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
*id_order = relative_order - 1;
}
}
+
+void BKE_id_blend_write(BlendWriter *writer, ID *id)
+{
+ /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
+ if (id->properties && !ELEM(GS(id->name), ID_WM)) {
+ IDP_BlendWrite(writer, id->properties);
+ }
+
+ if (id->override_library) {
+ BLO_write_struct(writer, IDOverrideLibrary, id->override_library);
+
+ BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties);
+ LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) {
+ BLO_write_string(writer, op->rna_path);
+
+ BLO_write_struct_list(writer, IDOverrideLibraryPropertyOperation, &op->operations);
+ LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
+ if (opop->subitem_reference_name) {
+ BLO_write_string(writer, opop->subitem_reference_name);
+ }
+ if (opop->subitem_local_name) {
+ BLO_write_string(writer, opop->subitem_local_name);
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index cca312270bc..e9244c5af73 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1685,6 +1685,20 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
/* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */
BKE_id_free_ex(bmain, tmp_id, LIB_ID_FREE_NO_UI_USER, true);
+ if (GS(local->name) == ID_AR) {
+ /* Funtime again, thanks to bone pointers in pose data of objects. We keep same ID addresses,
+ * but internal data has changed for sure, so we need to invalidate posebones caches. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->pose != NULL && ob->data == local) {
+ BLI_assert(ob->type == OB_ARMATURE);
+ ob->pose->flag |= POSE_RECALC;
+ /* We need to clear pose bone pointers immediately, some code may access those before pose
+ * is actually recomputed, which can lead to segfault. */
+ BKE_pose_clear_pointers(ob->pose);
+ }
+ }
+ }
+
if (local->override_library->storage) {
/* We know this datablock is not used anywhere besides local->override->storage. */
/* XXX For until we get fully shadow copies, we still need to ensure storage releases
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index d4246056efe..c88513ec2af 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -244,17 +244,17 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
ID *old_id = r_id_remap_data->old_id;
if (!old_id || GS(old_id->name) == ID_AR) {
Object *ob = (Object *)r_id_remap_data->id_owner;
- /* Object's pose holds reference to armature bones... sic */
- /* Note that in theory, we should have to bother about
- * linked/non-linked/never-null/etc. flags/states.
+ /* Object's pose holds reference to armature bones. sic */
+ /* Note that in theory, we should have to bother about linked/non-linked/never-null/etc.
+ * flags/states.
* Fortunately, this is just a tag, so we can accept to 'over-tag' a bit for pose recalc,
* and avoid another complex and risky condition nightmare like the one we have in
- * foreach_libblock_remap_callback()... */
+ * foreach_libblock_remap_callback(). */
if (ob->pose && (!old_id || ob->data == old_id)) {
BLI_assert(ob->type == OB_ARMATURE);
ob->pose->flag |= POSE_RECALC;
- /* We need to clear pose bone pointers immediately, things like undo writefile may be
- * called before pose is actually recomputed, can lead to segfault... */
+ /* We need to clear pose bone pointers immediately, some code may access those before
+ * pose is actually recomputed, which can lead to segfault. */
BKE_pose_clear_pointers(ob->pose);
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index b6e77c100f0..a7568bcd6ea 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -23,6 +23,9 @@
#include "MEM_guardedalloc.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_defaults.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
@@ -32,6 +35,7 @@
#include "BLI_bitmap.h"
#include "BLI_edgehash.h"
+#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
#include "BLI_hash.h"
#include "BLI_linklist.h"
@@ -43,6 +47,7 @@
#include "BLT_translation.h"
#include "BKE_anim_data.h"
+#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_idtype.h"
@@ -63,6 +68,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
static void mesh_clear_geometry(Mesh *mesh);
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata);
@@ -163,6 +170,158 @@ static void mesh_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Mesh *mesh = (Mesh *)id;
+ if (mesh->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* cache only - don't write */
+ mesh->mface = NULL;
+ mesh->totface = 0;
+ memset(&mesh->fdata, 0, sizeof(mesh->fdata));
+ memset(&mesh->runtime, 0, sizeof(mesh->runtime));
+
+ BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
+ BKE_id_blend_write(writer, &mesh->id);
+
+ /* direct data */
+ if (mesh->adt) {
+ BKE_animdata_blend_write(writer, mesh->adt);
+ }
+
+ BLO_write_pointer_array(writer, mesh->totcol, mesh->mat);
+ BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
+
+ CustomData_blend_write(writer, &mesh->vdata, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id);
+ CustomData_blend_write(writer, &mesh->edata, mesh->totedge, CD_MASK_MESH.emask, &mesh->id);
+ /* fdata is really a dummy - written so slots align */
+ CustomData_blend_write(writer, &mesh->fdata, mesh->totface, CD_MASK_MESH.fmask, &mesh->id);
+ CustomData_blend_write(writer, &mesh->ldata, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id);
+ CustomData_blend_write(writer, &mesh->pdata, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id);
+ }
+}
+
+static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Mesh *mesh = (Mesh *)id;
+ BLO_read_pointer_array(reader, (void **)&mesh->mat);
+
+ BLO_read_data_address(reader, &mesh->mvert);
+ BLO_read_data_address(reader, &mesh->medge);
+ BLO_read_data_address(reader, &mesh->mface);
+ BLO_read_data_address(reader, &mesh->mloop);
+ BLO_read_data_address(reader, &mesh->mpoly);
+ BLO_read_data_address(reader, &mesh->tface);
+ BLO_read_data_address(reader, &mesh->mtface);
+ BLO_read_data_address(reader, &mesh->mcol);
+ BLO_read_data_address(reader, &mesh->dvert);
+ BLO_read_data_address(reader, &mesh->mloopcol);
+ BLO_read_data_address(reader, &mesh->mloopuv);
+ BLO_read_data_address(reader, &mesh->mselect);
+
+ /* animdata */
+ BLO_read_data_address(reader, &mesh->adt);
+ BKE_animdata_blend_read_data(reader, mesh->adt);
+
+ /* Normally BKE_defvert_blend_read should be called in CustomData_blend_read,
+ * but for backwards compatibility in do_versions to work we do it here. */
+ BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert);
+
+ CustomData_blend_read(reader, &mesh->vdata, mesh->totvert);
+ CustomData_blend_read(reader, &mesh->edata, mesh->totedge);
+ CustomData_blend_read(reader, &mesh->fdata, mesh->totface);
+ CustomData_blend_read(reader, &mesh->ldata, mesh->totloop);
+ CustomData_blend_read(reader, &mesh->pdata, mesh->totpoly);
+
+ mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
+ mesh->edit_mesh = NULL;
+ BKE_mesh_runtime_reset(mesh);
+
+ /* happens with old files */
+ if (mesh->mselect == NULL) {
+ mesh->totselect = 0;
+ }
+
+ /* Multires data */
+ BLO_read_data_address(reader, &mesh->mr);
+ if (mesh->mr) {
+ BLO_read_list(reader, &mesh->mr->levels);
+ MultiresLevel *lvl = mesh->mr->levels.first;
+
+ CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert);
+ BKE_defvert_blend_read(
+ reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
+ CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface);
+
+ BLO_read_data_address(reader, &mesh->mr->edge_flags);
+ BLO_read_data_address(reader, &mesh->mr->edge_creases);
+
+ BLO_read_data_address(reader, &mesh->mr->verts);
+
+ /* If mesh has the same number of vertices as the
+ * highest multires level, load the current mesh verts
+ * into multires and discard the old data. Needed
+ * because some saved files either do not have a verts
+ * array, or the verts array contains out-of-date
+ * data. */
+ if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) {
+ if (mesh->mr->verts) {
+ MEM_freeN(mesh->mr->verts);
+ }
+ mesh->mr->verts = MEM_dupallocN(mesh->mvert);
+ }
+
+ for (; lvl; lvl = lvl->next) {
+ BLO_read_data_address(reader, &lvl->verts);
+ BLO_read_data_address(reader, &lvl->faces);
+ BLO_read_data_address(reader, &lvl->edges);
+ BLO_read_data_address(reader, &lvl->colfaces);
+ }
+ }
+
+ /* if multires is present but has no valid vertex data,
+ * there's no way to recover it; silently remove multires */
+ if (mesh->mr && !mesh->mr->verts) {
+ multires_free(mesh->mr);
+ mesh->mr = NULL;
+ }
+
+ if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
+ TFace *tf = mesh->tface;
+ for (int i = 0; i < mesh->totface; i++, tf++) {
+ BLI_endian_switch_uint32_array(tf->col, 4);
+ }
+ }
+}
+
+static void mesh_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Mesh *me = (Mesh *)id;
+ /* this check added for python created meshes */
+ if (me->mat) {
+ for (int i = 0; i < me->totcol; i++) {
+ BLO_read_id_address(reader, me->id.lib, &me->mat[i]);
+ }
+ }
+ else {
+ me->totcol = 0;
+ }
+
+ BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys
+ BLO_read_id_address(reader, me->id.lib, &me->key);
+ BLO_read_id_address(reader, me->id.lib, &me->texcomesh);
+}
+
+static void mesh_read_expand(BlendExpander *expander, ID *id)
+{
+ Mesh *me = (Mesh *)id;
+ for (int a = 0; a < me->totcol; a++) {
+ BLO_expand(expander, me->mat[a]);
+ }
+
+ BLO_expand(expander, me->key);
+ BLO_expand(expander, me->texcomesh);
+}
+
IDTypeInfo IDType_ID_ME = {
.id_code = ID_ME,
.id_filter = FILTER_ID_ME,
@@ -180,10 +339,10 @@ IDTypeInfo IDType_ID_ME = {
.foreach_id = mesh_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = mesh_blend_write,
+ .blend_read_data = mesh_blend_read_data,
+ .blend_read_lib = mesh_blend_read_lib,
+ .blend_read_expand = mesh_read_expand,
};
enum {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index ece7d0f9136..95a8b3b3c15 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -229,6 +229,23 @@ void BKE_rigidbody_free_constraint(Object *ob)
ob->rigidbody_constraint = NULL;
}
+bool BKE_rigidbody_is_affected_by_simulation(Object *ob)
+{
+ /* Check if the object will have its transform changed by the rigidbody simulation. */
+
+ /* True if the shape of this object's parent is of type compound */
+ bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND);
+
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ if (rbo == NULL || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
+ obCompoundParent) {
+ return false;
+ }
+
+ return true;
+}
+
#ifdef WITH_BULLET
/* Copying Methods --------------------- */
@@ -1904,18 +1921,13 @@ bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
/* Sync rigid body and object transformations */
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{
- RigidBodyOb *rbo = ob->rigidbody_object;
-
- /* True if the shape of this object's parent is of type compound */
- bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
- ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND);
-
- /* keep original transform for kinematic and passive objects */
- if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
- obCompoundParent) {
+ if (!BKE_rigidbody_is_affected_by_simulation(ob)) {
+ /* Don't sync transforms for objects that are not affected/changed by the simulation. */
return;
}
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
/* use rigid body transform after cache start frame if objects is not being transformed */
if (BKE_rigidbody_check_sim_running(rbw, ctime) &&
!(ob->base_flag & BASE_SELECTED && G.moving & G_TRANSFORM_OBJ)) {
@@ -1941,8 +1953,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
void BKE_rigidbody_aftertrans_update(
Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
{
+ bool correct_delta = BKE_rigidbody_is_affected_by_simulation(ob);
RigidBodyOb *rbo = ob->rigidbody_object;
- bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE);
/* return rigid body and object to their initial states */
copy_v3_v3(rbo->pos, ob->loc);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c24db724222..aec5a254750 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -120,6 +120,7 @@
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_curveprofile.h"
+#include "BKE_deform.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
@@ -4108,245 +4109,6 @@ static void direct_link_particlesystems(BlendDataReader *reader, ListBase *parti
/** \name Read ID: Mesh
* \{ */
-static void lib_link_mesh(BlendLibReader *reader, Mesh *me)
-{
- /* this check added for python created meshes */
- if (me->mat) {
- for (int i = 0; i < me->totcol; i++) {
- BLO_read_id_address(reader, me->id.lib, &me->mat[i]);
- }
- }
- else {
- me->totcol = 0;
- }
-
- BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys
- BLO_read_id_address(reader, me->id.lib, &me->key);
- BLO_read_id_address(reader, me->id.lib, &me->texcomesh);
-}
-
-static void direct_link_dverts(BlendDataReader *reader, int count, MDeformVert *mdverts)
-{
- if (mdverts == NULL) {
- return;
- }
-
- for (int i = count; i > 0; i--, mdverts++) {
- /*convert to vgroup allocation system*/
- MDeformWeight *dw;
- if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) {
- const ssize_t dw_len = mdverts->totweight * sizeof(MDeformWeight);
- void *dw_tmp = MEM_mallocN(dw_len, "direct_link_dverts");
- memcpy(dw_tmp, dw, dw_len);
- mdverts->dw = dw_tmp;
- MEM_freeN(dw);
- }
- else {
- mdverts->dw = NULL;
- mdverts->totweight = 0;
- }
- }
-}
-
-static void direct_link_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external)
-{
- if (mdisps) {
- for (int i = 0; i < count; i++) {
- BLO_read_data_address(reader, &mdisps[i].disps);
- BLO_read_data_address(reader, &mdisps[i].hidden);
-
- if (mdisps[i].totdisp && !mdisps[i].level) {
- /* this calculation is only correct for loop mdisps;
- * if loading pre-BMesh face mdisps this will be
- * overwritten with the correct value in
- * bm_corners_to_loops() */
- float gridsize = sqrtf(mdisps[i].totdisp);
- mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1;
- }
-
- if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) {
- /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
- /* this does swap for data written at write_mdisps() - readfile.c */
- BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
- }
- if (!external && !mdisps[i].disps) {
- mdisps[i].totdisp = 0;
- }
- }
- }
-}
-
-static void direct_link_grid_paint_mask(BlendDataReader *reader,
- int count,
- GridPaintMask *grid_paint_mask)
-{
- if (grid_paint_mask) {
- for (int i = 0; i < count; i++) {
- GridPaintMask *gpm = &grid_paint_mask[i];
- if (gpm->data) {
- BLO_read_data_address(reader, &gpm->data);
- }
- }
- }
-}
-
-/*this isn't really a public api function, so prototyped here*/
-static void direct_link_customdata(BlendDataReader *reader, CustomData *data, int count)
-{
-
- BLO_read_data_address(reader, &data->layers);
-
- /* annoying workaround for bug [#31079] loading legacy files with
- * no polygons _but_ have stale customdata */
- if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) {
- CustomData_reset(data);
- return;
- }
-
- BLO_read_data_address(reader, &data->external);
-
- int i = 0;
- while (i < data->totlayer) {
- CustomDataLayer *layer = &data->layers[i];
-
- if (layer->flag & CD_FLAG_EXTERNAL) {
- layer->flag &= ~CD_FLAG_IN_MEMORY;
- }
-
- layer->flag &= ~CD_FLAG_NOFREE;
-
- if (CustomData_verify_versions(data, i)) {
- BLO_read_data_address(reader, &layer->data);
- if (layer->type == CD_MDISPS) {
- direct_link_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
- }
- else if (layer->type == CD_GRID_PAINT_MASK) {
- direct_link_grid_paint_mask(reader, count, layer->data);
- }
- i++;
- }
- }
-
- CustomData_update_typemap(data);
-}
-
-static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh)
-{
- BLO_read_pointer_array(reader, (void **)&mesh->mat);
-
- BLO_read_data_address(reader, &mesh->mvert);
- BLO_read_data_address(reader, &mesh->medge);
- BLO_read_data_address(reader, &mesh->mface);
- BLO_read_data_address(reader, &mesh->mloop);
- BLO_read_data_address(reader, &mesh->mpoly);
- BLO_read_data_address(reader, &mesh->tface);
- BLO_read_data_address(reader, &mesh->mtface);
- BLO_read_data_address(reader, &mesh->mcol);
- BLO_read_data_address(reader, &mesh->dvert);
- BLO_read_data_address(reader, &mesh->mloopcol);
- BLO_read_data_address(reader, &mesh->mloopuv);
- BLO_read_data_address(reader, &mesh->mselect);
-
- /* animdata */
- BLO_read_data_address(reader, &mesh->adt);
- BKE_animdata_blend_read_data(reader, mesh->adt);
-
- /* Normally direct_link_dverts should be called in direct_link_customdata,
- * but for backwards compatibility in do_versions to work we do it here. */
- direct_link_dverts(reader, mesh->totvert, mesh->dvert);
-
- direct_link_customdata(reader, &mesh->vdata, mesh->totvert);
- direct_link_customdata(reader, &mesh->edata, mesh->totedge);
- direct_link_customdata(reader, &mesh->fdata, mesh->totface);
- direct_link_customdata(reader, &mesh->ldata, mesh->totloop);
- direct_link_customdata(reader, &mesh->pdata, mesh->totpoly);
-
- mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
- mesh->edit_mesh = NULL;
- BKE_mesh_runtime_reset(mesh);
-
- /* happens with old files */
- if (mesh->mselect == NULL) {
- mesh->totselect = 0;
- }
-
- /* Multires data */
- BLO_read_data_address(reader, &mesh->mr);
- if (mesh->mr) {
- BLO_read_list(reader, &mesh->mr->levels);
- MultiresLevel *lvl = mesh->mr->levels.first;
-
- direct_link_customdata(reader, &mesh->mr->vdata, lvl->totvert);
- direct_link_dverts(reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
- direct_link_customdata(reader, &mesh->mr->fdata, lvl->totface);
-
- BLO_read_data_address(reader, &mesh->mr->edge_flags);
- BLO_read_data_address(reader, &mesh->mr->edge_creases);
-
- BLO_read_data_address(reader, &mesh->mr->verts);
-
- /* If mesh has the same number of vertices as the
- * highest multires level, load the current mesh verts
- * into multires and discard the old data. Needed
- * because some saved files either do not have a verts
- * array, or the verts array contains out-of-date
- * data. */
- if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) {
- if (mesh->mr->verts) {
- MEM_freeN(mesh->mr->verts);
- }
- mesh->mr->verts = MEM_dupallocN(mesh->mvert);
- }
-
- for (; lvl; lvl = lvl->next) {
- BLO_read_data_address(reader, &lvl->verts);
- BLO_read_data_address(reader, &lvl->faces);
- BLO_read_data_address(reader, &lvl->edges);
- BLO_read_data_address(reader, &lvl->colfaces);
- }
- }
-
- /* if multires is present but has no valid vertex data,
- * there's no way to recover it; silently remove multires */
- if (mesh->mr && !mesh->mr->verts) {
- multires_free(mesh->mr);
- mesh->mr = NULL;
- }
-
- if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) {
- TFace *tf = mesh->tface;
- for (int i = 0; i < mesh->totface; i++, tf++) {
- BLI_endian_switch_uint32_array(tf->col, 4);
- }
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Lattice
- * \{ */
-
-static void lib_link_latt(BlendLibReader *reader, Lattice *lt)
-{
- BLO_read_id_address(reader, lt->id.lib, &lt->ipo); // XXX deprecated - old animation system
- BLO_read_id_address(reader, lt->id.lib, &lt->key);
-}
-
-static void direct_link_latt(BlendDataReader *reader, Lattice *lt)
-{
- BLO_read_data_address(reader, &lt->def);
-
- BLO_read_data_address(reader, &lt->dvert);
- direct_link_dverts(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
-
- lt->editlatt = NULL;
- lt->batch_cache = NULL;
-
- BLO_read_data_address(reader, &lt->adt);
- BKE_animdata_blend_read_data(reader, lt->adt);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -6202,7 +5964,7 @@ static void direct_link_gpencil(BlendDataReader *reader, bGPdata *gpd)
/* relink weight data */
if (gps->dvert) {
BLO_read_data_address(reader, &gps->dvert);
- direct_link_dverts(reader, gps->totpoints, gps->dvert);
+ BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
}
}
}
@@ -8005,8 +7767,8 @@ static void direct_link_hair(BlendDataReader *reader, Hair *hair)
BKE_animdata_blend_read_data(reader, hair->adt);
/* Geometry */
- direct_link_customdata(reader, &hair->pdata, hair->totpoint);
- direct_link_customdata(reader, &hair->cdata, hair->totcurve);
+ CustomData_blend_read(reader, &hair->pdata, hair->totpoint);
+ CustomData_blend_read(reader, &hair->cdata, hair->totcurve);
BKE_hair_update_customdata_pointers(hair);
/* Materials */
@@ -8032,7 +7794,7 @@ static void direct_link_pointcloud(BlendDataReader *reader, PointCloud *pointclo
BKE_animdata_blend_read_data(reader, pointcloud->adt);
/* Geometry */
- direct_link_customdata(reader, &pointcloud->pdata, pointcloud->totpoint);
+ CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint);
BKE_pointcloud_update_customdata_pointers(pointcloud);
/* Materials */
@@ -8093,7 +7855,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
BLO_read_data_address(reader, &state->type);
if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles);
+ CustomData_blend_read(reader, &particle_state->attributes, particle_state->tot_particles);
}
}
@@ -8261,9 +8023,6 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_OB:
direct_link_object(&reader, (Object *)id);
break;
- case ID_ME:
- direct_link_mesh(&reader, (Mesh *)id);
- break;
case ID_CU:
direct_link_curve(&reader, (Curve *)id);
break;
@@ -8294,9 +8053,6 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_KE:
direct_link_key(&reader, (Key *)id);
break;
- case ID_LT:
- direct_link_latt(&reader, (Lattice *)id);
- break;
case ID_WO:
direct_link_world(&reader, (World *)id);
break;
@@ -8369,6 +8125,10 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_SIM:
direct_link_simulation(&reader, (Simulation *)id);
break;
+ case ID_ME:
+ case ID_LT:
+ /* Do nothing. Handled by IDTypeInfo callback. */
+ break;
}
/* try to restore (when undoing) or clear ID's cache pointers. */
@@ -9032,18 +8792,12 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_LA:
lib_link_light(&reader, (Light *)id);
break;
- case ID_LT:
- lib_link_latt(&reader, (Lattice *)id);
- break;
case ID_MB:
lib_link_mball(&reader, (MetaBall *)id);
break;
case ID_CU:
lib_link_curve(&reader, (Curve *)id);
break;
- case ID_ME:
- lib_link_mesh(&reader, (Mesh *)id);
- break;
case ID_CF:
lib_link_cachefiles(&reader, (CacheFile *)id);
break;
@@ -9097,6 +8851,10 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_LI:
lib_link_library(&reader, (Library *)id); /* Only init users. */
break;
+ case ID_ME:
+ case ID_LT:
+ /* Do nothing. Handled by IDTypeInfo callback. */
+ break;
}
id->tag &= ~LIB_TAG_NEED_LINK;
@@ -9911,12 +9669,6 @@ static void expand_light(BlendExpander *expander, Light *la)
BLO_expand(expander, la->ipo); // XXX deprecated - old animation system
}
-static void expand_lattice(BlendExpander *expander, Lattice *lt)
-{
- BLO_expand(expander, lt->ipo); // XXX deprecated - old animation system
- BLO_expand(expander, lt->key);
-}
-
static void expand_world(BlendExpander *expander, World *wrld)
{
BLO_expand(expander, wrld->ipo); // XXX deprecated - old animation system
@@ -9946,16 +9698,6 @@ static void expand_curve(BlendExpander *expander, Curve *cu)
BLO_expand(expander, cu->textoncurve);
}
-static void expand_mesh(BlendExpander *expander, Mesh *me)
-{
- for (int a = 0; a < me->totcol; a++) {
- BLO_expand(expander, me->mat[a]);
- }
-
- BLO_expand(expander, me->key);
- BLO_expand(expander, me->texcomesh);
-}
-
/* callback function used to expand constraint ID-links */
static void expand_constraint_cb(bConstraint *UNUSED(con),
ID **idpoin,
@@ -10389,9 +10131,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_OB:
expand_object(&expander, (Object *)id);
break;
- case ID_ME:
- expand_mesh(&expander, (Mesh *)id);
- break;
case ID_CU:
expand_curve(&expander, (Curve *)id);
break;
@@ -10410,9 +10149,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_WO:
expand_world(&expander, (World *)id);
break;
- case ID_LT:
- expand_lattice(&expander, (Lattice *)id);
- break;
case ID_LA:
expand_light(&expander, (Light *)id);
break;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 6ce822a09c1..a9c92719a33 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -161,6 +161,7 @@
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_curveprofile.h"
+#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
#include "BKE_global.h" // for G
@@ -658,33 +659,6 @@ static void writelist_id(WriteData *wd, int filecode, const char *structname, co
* These functions are used by blender's .blend system for file saving/loading.
* \{ */
-static void write_iddata(BlendWriter *writer, ID *id)
-{
- /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
- if (id->properties && !ELEM(GS(id->name), ID_WM)) {
- IDP_BlendWrite(writer, id->properties);
- }
-
- if (id->override_library) {
- BLO_write_struct(writer, IDOverrideLibrary, id->override_library);
-
- BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties);
- LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) {
- BLO_write_string(writer, op->rna_path);
-
- BLO_write_struct_list(writer, IDOverrideLibraryPropertyOperation, &op->operations);
- LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
- if (opop->subitem_reference_name) {
- BLO_write_string(writer, opop->subitem_reference_name);
- }
- if (opop->subitem_local_name) {
- BLO_write_string(writer, opop->subitem_local_name);
- }
- }
- }
- }
-}
-
static void write_previews(BlendWriter *writer, const PreviewImage *prv_orig)
{
/* Note we write previews also for undo steps. It takes up some memory,
@@ -713,7 +687,7 @@ static void write_action(BlendWriter *writer, bAction *act, const void *id_addre
{
if (act->id.us > 0 || BLO_write_is_undo(writer)) {
BLO_write_id_struct(writer, bAction, id_address, &act->id);
- write_iddata(writer, &act->id);
+ BKE_id_blend_write(writer, &act->id);
BKE_fcurve_blend_write(writer, &act->curves);
@@ -1171,7 +1145,7 @@ static void write_particlesettings(BlendWriter *writer,
if (part->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id);
- write_iddata(writer, &part->id);
+ BKE_id_blend_write(writer, &part->id);
if (part->adt) {
BKE_animdata_blend_write(writer, part->adt);
@@ -1593,7 +1567,7 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address
/* write LibData */
BLO_write_id_struct(writer, Object, id_address, &ob->id);
- write_iddata(writer, &ob->id);
+ BKE_id_blend_write(writer, &ob->id);
if (ob->adt) {
BKE_animdata_blend_write(writer, ob->adt);
@@ -1661,7 +1635,7 @@ static void write_vfont(BlendWriter *writer, VFont *vf, const void *id_address)
/* write LibData */
BLO_write_id_struct(writer, VFont, id_address, &vf->id);
- write_iddata(writer, &vf->id);
+ BKE_id_blend_write(writer, &vf->id);
/* direct data */
if (vf->packedfile) {
@@ -1677,7 +1651,7 @@ static void write_key(BlendWriter *writer, Key *key, const void *id_address)
if (key->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, Key, id_address, &key->id);
- write_iddata(writer, &key->id);
+ BKE_id_blend_write(writer, &key->id);
if (key->adt) {
BKE_animdata_blend_write(writer, key->adt);
@@ -1698,7 +1672,7 @@ static void write_camera(BlendWriter *writer, Camera *cam, const void *id_addres
if (cam->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, Camera, id_address, &cam->id);
- write_iddata(writer, &cam->id);
+ BKE_id_blend_write(writer, &cam->id);
if (cam->adt) {
BKE_animdata_blend_write(writer, cam->adt);
@@ -1723,7 +1697,7 @@ static void write_mball(BlendWriter *writer, MetaBall *mb, const void *id_addres
/* write LibData */
BLO_write_id_struct(writer, MetaBall, id_address, &mb->id);
- write_iddata(writer, &mb->id);
+ BKE_id_blend_write(writer, &mb->id);
/* direct data */
BLO_write_pointer_array(writer, mb->totcol, mb->mat);
@@ -1747,7 +1721,7 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address)
/* write LibData */
BLO_write_id_struct(writer, Curve, id_address, &cu->id);
- write_iddata(writer, &cu->id);
+ BKE_id_blend_write(writer, &cu->id);
/* direct data */
BLO_write_pointer_array(writer, cu->totcol, cu->mat);
@@ -1784,200 +1758,6 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address)
}
}
-static void write_dverts(BlendWriter *writer, int count, MDeformVert *dvlist)
-{
- if (dvlist) {
-
- /* Write the dvert list */
- BLO_write_struct_array(writer, MDeformVert, count, dvlist);
-
- /* Write deformation data for each dvert */
- for (int i = 0; i < count; i++) {
- if (dvlist[i].dw) {
- BLO_write_struct_array(writer, MDeformWeight, dvlist[i].totweight, dvlist[i].dw);
- }
- }
- }
-}
-
-static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external)
-{
- if (mdlist) {
- BLO_write_struct_array(writer, MDisps, count, mdlist);
- for (int i = 0; i < count; i++) {
- MDisps *md = &mdlist[i];
- if (md->disps) {
- if (!external) {
- BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]);
- }
- }
-
- if (md->hidden) {
- BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden);
- }
- }
- }
-}
-
-static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask)
-{
- if (grid_paint_mask) {
- BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask);
- for (int i = 0; i < count; i++) {
- GridPaintMask *gpm = &grid_paint_mask[i];
- if (gpm->data) {
- const int gridsize = BKE_ccg_gridsize(gpm->level);
- BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data);
- }
- }
- }
-}
-
-static void write_customdata(BlendWriter *writer,
- ID *id,
- int count,
- CustomData *data,
- CustomDataLayer *layers,
- CustomDataMask cddata_mask)
-{
- /* write external customdata (not for undo) */
- if (data->external && !BLO_write_is_undo(writer)) {
- CustomData_external_write(data, id, cddata_mask, count, 0);
- }
-
- BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers);
-
- for (int i = 0; i < data->totlayer; i++) {
- CustomDataLayer *layer = &layers[i];
- const char *structname;
- int structnum, datasize;
-
- if (layer->type == CD_MDEFORMVERT) {
- /* layer types that allocate own memory need special handling */
- write_dverts(writer, count, layer->data);
- }
- else if (layer->type == CD_MDISPS) {
- write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL);
- }
- else if (layer->type == CD_PAINT_MASK) {
- const float *layer_data = layer->data;
- BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
- }
- else if (layer->type == CD_SCULPT_FACE_SETS) {
- const float *layer_data = layer->data;
- BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
- }
- else if (layer->type == CD_GRID_PAINT_MASK) {
- write_grid_paint_mask(writer, count, layer->data);
- }
- else if (layer->type == CD_FACEMAP) {
- const int *layer_data = layer->data;
- BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data);
- }
- else {
- CustomData_file_write_info(layer->type, &structname, &structnum);
- if (structnum) {
- datasize = structnum * count;
- BLO_write_struct_array_by_name(writer, structname, datasize, layer->data);
- }
- else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */
- printf("%s error: layer '%s':%d - can't be written to file\n",
- __func__,
- structname,
- layer->type);
- }
- }
- }
-
- if (data->external) {
- BLO_write_struct(writer, CustomDataExternal, data->external);
- }
-}
-
-static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address)
-{
- if (mesh->id.us > 0 || BLO_write_is_undo(writer)) {
- /* cache only - don't write */
- mesh->mface = NULL;
- mesh->totface = 0;
- memset(&mesh->fdata, 0, sizeof(mesh->fdata));
- memset(&mesh->runtime, 0, sizeof(mesh->runtime));
-
- /* Reduce xdata layers, fill xlayers with layers to be written.
- * This makes xdata invalid for Blender, which is why we made a
- * temporary local copy. */
- CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
-
- CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff));
- CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff));
- flayers = flayers_buff;
- CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff));
- CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
-
- BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
- write_iddata(writer, &mesh->id);
-
- /* direct data */
- if (mesh->adt) {
- BKE_animdata_blend_write(writer, mesh->adt);
- }
-
- BLO_write_pointer_array(writer, mesh->totcol, mesh->mat);
- BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
-
- write_customdata(writer, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, CD_MASK_MESH.vmask);
- write_customdata(writer, &mesh->id, mesh->totedge, &mesh->edata, elayers, CD_MASK_MESH.emask);
- /* fdata is really a dummy - written so slots align */
- write_customdata(writer, &mesh->id, mesh->totface, &mesh->fdata, flayers, CD_MASK_MESH.fmask);
- write_customdata(writer, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask);
- write_customdata(writer, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask);
-
- /* free temporary data */
- if (vlayers && vlayers != vlayers_buff) {
- MEM_freeN(vlayers);
- }
- if (elayers && elayers != elayers_buff) {
- MEM_freeN(elayers);
- }
- if (flayers && flayers != flayers_buff) {
- MEM_freeN(flayers);
- }
- if (llayers && llayers != llayers_buff) {
- MEM_freeN(llayers);
- }
- if (players && players != players_buff) {
- MEM_freeN(players);
- }
- }
-}
-
-static void write_lattice(BlendWriter *writer, Lattice *lt, const void *id_address)
-{
- if (lt->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- lt->editlatt = NULL;
- lt->batch_cache = NULL;
-
- /* write LibData */
- BLO_write_id_struct(writer, Lattice, id_address, &lt->id);
- write_iddata(writer, &lt->id);
-
- /* write animdata */
- if (lt->adt) {
- BKE_animdata_blend_write(writer, lt->adt);
- }
-
- /* direct data */
- BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def);
-
- write_dverts(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
- }
-}
-
static void write_image(BlendWriter *writer, Image *ima, const void *id_address)
{
if (ima->id.us > 0 || BLO_write_is_undo(writer)) {
@@ -1992,7 +1772,7 @@ static void write_image(BlendWriter *writer, Image *ima, const void *id_address)
/* write LibData */
BLO_write_id_struct(writer, Image, id_address, &ima->id);
- write_iddata(writer, &ima->id);
+ BKE_id_blend_write(writer, &ima->id);
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
BLO_write_struct(writer, ImagePackedFile, imapf);
@@ -2023,7 +1803,7 @@ static void write_texture(BlendWriter *writer, Tex *tex, const void *id_address)
if (tex->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, Tex, id_address, &tex->id);
- write_iddata(writer, &tex->id);
+ BKE_id_blend_write(writer, &tex->id);
if (tex->adt) {
BKE_animdata_blend_write(writer, tex->adt);
@@ -2053,7 +1833,7 @@ static void write_material(BlendWriter *writer, Material *ma, const void *id_add
/* write LibData */
BLO_write_id_struct(writer, Material, id_address, &ma->id);
- write_iddata(writer, &ma->id);
+ BKE_id_blend_write(writer, &ma->id);
if (ma->adt) {
BKE_animdata_blend_write(writer, ma->adt);
@@ -2082,7 +1862,7 @@ static void write_world(BlendWriter *writer, World *wrld, const void *id_address
/* write LibData */
BLO_write_id_struct(writer, World, id_address, &wrld->id);
- write_iddata(writer, &wrld->id);
+ BKE_id_blend_write(writer, &wrld->id);
if (wrld->adt) {
BKE_animdata_blend_write(writer, wrld->adt);
@@ -2103,7 +1883,7 @@ static void write_light(BlendWriter *writer, Light *la, const void *id_address)
if (la->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, Light, id_address, &la->id);
- write_iddata(writer, &la->id);
+ BKE_id_blend_write(writer, &la->id);
if (la->adt) {
BKE_animdata_blend_write(writer, la->adt);
@@ -2148,7 +1928,7 @@ static void write_collection(BlendWriter *writer, Collection *collection, const
/* write LibData */
BLO_write_id_struct(writer, Collection, id_address, &collection->id);
- write_iddata(writer, &collection->id);
+ BKE_id_blend_write(writer, &collection->id);
write_collection_nolib(writer, collection);
}
@@ -2274,7 +2054,7 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address)
/* write LibData */
BLO_write_id_struct(writer, Scene, id_address, &sce->id);
- write_iddata(writer, &sce->id);
+ BKE_id_blend_write(writer, &sce->id);
if (sce->adt) {
BKE_animdata_blend_write(writer, sce->adt);
@@ -2508,7 +2288,7 @@ static void write_gpencil(BlendWriter *writer, bGPdata *gpd, const void *id_addr
/* write gpd data block to file */
BLO_write_id_struct(writer, bGPdata, id_address, &gpd->id);
- write_iddata(writer, &gpd->id);
+ BKE_id_blend_write(writer, &gpd->id);
if (gpd->adt) {
BKE_animdata_blend_write(writer, gpd->adt);
@@ -2529,7 +2309,7 @@ static void write_gpencil(BlendWriter *writer, bGPdata *gpd, const void *id_addr
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
BLO_write_struct_array(writer, bGPDspoint, gps->totpoints, gps->points);
BLO_write_struct_array(writer, bGPDtriangle, gps->tot_triangles, gps->triangles);
- write_dverts(writer, gps->totpoints, gps->dvert);
+ BKE_defvert_blend_write(writer, gps->totpoints, gps->dvert);
}
}
}
@@ -2782,7 +2562,7 @@ static void write_area_map(BlendWriter *writer, ScrAreaMap *area_map)
static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const void *id_address)
{
BLO_write_id_struct(writer, wmWindowManager, id_address, &wm->id);
- write_iddata(writer, &wm->id);
+ BKE_id_blend_write(writer, &wm->id);
write_wm_xr_data(writer, &wm->xr);
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
@@ -2817,7 +2597,7 @@ static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_ad
/* write LibData */
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
writestruct_at_address(writer->wd, ID_SCRN, bScreen, 1, id_address, screen);
- write_iddata(writer, &screen->id);
+ BKE_id_blend_write(writer, &screen->id);
write_previews(writer, screen->preview);
@@ -2857,7 +2637,7 @@ static void write_armature(BlendWriter *writer, bArmature *arm, const void *id_a
arm->act_edbone = NULL;
BLO_write_id_struct(writer, bArmature, id_address, &arm->id);
- write_iddata(writer, &arm->id);
+ BKE_id_blend_write(writer, &arm->id);
if (arm->adt) {
BKE_animdata_blend_write(writer, arm->adt);
@@ -2882,7 +2662,7 @@ static void write_text(BlendWriter *writer, Text *text, const void *id_address)
/* write LibData */
BLO_write_id_struct(writer, Text, id_address, &text->id);
- write_iddata(writer, &text->id);
+ BKE_id_blend_write(writer, &text->id);
if (text->filepath) {
BLO_write_string(writer, text->filepath);
@@ -2905,7 +2685,7 @@ static void write_speaker(BlendWriter *writer, Speaker *spk, const void *id_addr
if (spk->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, Speaker, id_address, &spk->id);
- write_iddata(writer, &spk->id);
+ BKE_id_blend_write(writer, &spk->id);
if (spk->adt) {
BKE_animdata_blend_write(writer, spk->adt);
@@ -2924,7 +2704,7 @@ static void write_sound(BlendWriter *writer, bSound *sound, const void *id_addre
/* write LibData */
BLO_write_id_struct(writer, bSound, id_address, &sound->id);
- write_iddata(writer, &sound->id);
+ BKE_id_blend_write(writer, &sound->id);
if (sound->packedfile) {
PackedFile *pf = sound->packedfile;
@@ -2939,7 +2719,7 @@ static void write_probe(BlendWriter *writer, LightProbe *prb, const void *id_add
if (prb->id.us > 0 || BLO_write_is_undo(writer)) {
/* write LibData */
BLO_write_id_struct(writer, LightProbe, id_address, &prb->id);
- write_iddata(writer, &prb->id);
+ BKE_id_blend_write(writer, &prb->id);
if (prb->adt) {
BKE_animdata_blend_write(writer, prb->adt);
@@ -2961,7 +2741,7 @@ static void write_nodetree(BlendWriter *writer, bNodeTree *ntree, const void *id
BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id);
/* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot
* be linked, etc., so we write actual id data here only, for 'real' ID trees. */
- write_iddata(writer, &ntree->id);
+ BKE_id_blend_write(writer, &ntree->id);
write_nodetree_nolib(writer, ntree);
}
@@ -2971,7 +2751,7 @@ static void write_brush(BlendWriter *writer, Brush *brush, const void *id_addres
{
if (brush->id.us > 0 || BLO_write_is_undo(writer)) {
BLO_write_id_struct(writer, Brush, id_address, &brush->id);
- write_iddata(writer, &brush->id);
+ BKE_id_blend_write(writer, &brush->id);
if (brush->curve) {
BKE_curvemapping_blend_write(writer, brush->curve);
@@ -3019,7 +2799,7 @@ static void write_palette(BlendWriter *writer, Palette *palette, const void *id_
if (palette->id.us > 0 || BLO_write_is_undo(writer)) {
PaletteColor *color;
BLO_write_id_struct(writer, Palette, id_address, &palette->id);
- write_iddata(writer, &palette->id);
+ BKE_id_blend_write(writer, &palette->id);
for (color = palette->colors.first; color; color = color->next) {
BLO_write_struct(writer, PaletteColor, color);
@@ -3031,7 +2811,7 @@ static void write_paintcurve(BlendWriter *writer, PaintCurve *pc, const void *id
{
if (pc->id.us > 0 || BLO_write_is_undo(writer)) {
BLO_write_id_struct(writer, PaintCurve, id_address, &pc->id);
- write_iddata(writer, &pc->id);
+ BKE_id_blend_write(writer, &pc->id);
BLO_write_struct_array(writer, PaintCurvePoint, pc->tot_points, pc->points);
}
@@ -3087,7 +2867,7 @@ static void write_movieclip(BlendWriter *writer, MovieClip *clip, const void *id
MovieTrackingObject *object;
BLO_write_id_struct(writer, MovieClip, id_address, &clip->id);
- write_iddata(writer, &clip->id);
+ BKE_id_blend_write(writer, &clip->id);
if (clip->adt) {
BKE_animdata_blend_write(writer, clip->adt);
@@ -3116,7 +2896,7 @@ static void write_mask(BlendWriter *writer, Mask *mask, const void *id_address)
MaskLayer *masklay;
BLO_write_id_struct(writer, Mask, id_address, &mask->id);
- write_iddata(writer, &mask->id);
+ BKE_id_blend_write(writer, &mask->id);
if (mask->adt) {
BKE_animdata_blend_write(writer, mask->adt);
@@ -3426,7 +3206,7 @@ static void write_linestyle(BlendWriter *writer,
{
if (linestyle->id.us > 0 || BLO_write_is_undo(writer)) {
BLO_write_id_struct(writer, FreestyleLineStyle, id_address, &linestyle->id);
- write_iddata(writer, &linestyle->id);
+ BKE_id_blend_write(writer, &linestyle->id);
if (linestyle->adt) {
BKE_animdata_blend_write(writer, linestyle->adt);
@@ -3468,7 +3248,7 @@ static void write_cachefile(BlendWriter *writer, CacheFile *cache_file, const vo
static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address)
{
BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id);
- write_iddata(writer, &workspace->id);
+ BKE_id_blend_write(writer, &workspace->id);
BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts);
BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations);
BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids);
@@ -3483,30 +3263,17 @@ static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const voi
static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address)
{
if (hair->id.us > 0 || BLO_write_is_undo(writer)) {
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_file_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
- CustomData_file_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
-
/* Write LibData */
BLO_write_id_struct(writer, Hair, id_address, &hair->id);
- write_iddata(writer, &hair->id);
+ BKE_id_blend_write(writer, &hair->id);
/* Direct data */
- write_customdata(writer, &hair->id, hair->totpoint, &hair->pdata, players, CD_MASK_ALL);
- write_customdata(writer, &hair->id, hair->totcurve, &hair->cdata, clayers, CD_MASK_ALL);
+ CustomData_blend_write(writer, &hair->pdata, hair->totpoint, CD_MASK_ALL, &hair->id);
+ CustomData_blend_write(writer, &hair->cdata, hair->totcurve, CD_MASK_ALL, &hair->id);
BLO_write_pointer_array(writer, hair->totcol, hair->mat);
if (hair->adt) {
BKE_animdata_blend_write(writer, hair->adt);
}
-
- /* Remove temporary data. */
- if (players && players != players_buff) {
- MEM_freeN(players);
- }
- if (clayers && clayers != clayers_buff) {
- MEM_freeN(clayers);
- }
}
}
@@ -3519,11 +3286,11 @@ static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const
/* Write LibData */
BLO_write_id_struct(writer, PointCloud, id_address, &pointcloud->id);
- write_iddata(writer, &pointcloud->id);
+ BKE_id_blend_write(writer, &pointcloud->id);
/* Direct data */
- write_customdata(
- writer, &pointcloud->id, pointcloud->totpoint, &pointcloud->pdata, players, CD_MASK_ALL);
+ CustomData_blend_write(
+ writer, &pointcloud->pdata, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id);
BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat);
if (pointcloud->adt) {
BKE_animdata_blend_write(writer, pointcloud->adt);
@@ -3544,7 +3311,7 @@ static void write_volume(BlendWriter *writer, Volume *volume, const void *id_add
/* write LibData */
BLO_write_id_struct(writer, Volume, id_address, &volume->id);
- write_iddata(writer, &volume->id);
+ BKE_id_blend_write(writer, &volume->id);
/* direct data */
BLO_write_pointer_array(writer, volume->totcol, volume->mat);
@@ -3564,7 +3331,7 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
{
if (simulation->id.us > 0 || BLO_write_is_undo(writer)) {
BLO_write_id_struct(writer, Simulation, id_address, &simulation->id);
- write_iddata(writer, &simulation->id);
+ BKE_id_blend_write(writer, &simulation->id);
if (simulation->adt) {
BKE_animdata_blend_write(writer, simulation->adt);
@@ -3584,21 +3351,11 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
BLO_write_struct(writer, ParticleSimulationState, particle_state);
- CustomDataLayer *layers = NULL;
- CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_file_write_prepare(
- &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff));
-
- write_customdata(writer,
- &simulation->id,
- particle_state->tot_particles,
- &particle_state->attributes,
- layers,
- CD_MASK_ALL);
-
- if (layers != NULL && layers != layers_buff) {
- MEM_freeN(layers);
- }
+ CustomData_blend_write(writer,
+ &particle_state->attributes,
+ particle_state->tot_particles,
+ CD_MASK_ALL,
+ &simulation->id);
}
else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
@@ -3654,7 +3411,7 @@ static void write_libraries(WriteData *wd, Main *main)
BlendWriter writer = {wd};
writestruct(wd, ID_LI, Library, 1, main->curlib);
- write_iddata(&writer, &main->curlib->id);
+ BKE_id_blend_write(&writer, &main->curlib->id);
if (main->curlib->packedfile) {
PackedFile *pf = main->curlib->packedfile;
@@ -3904,9 +3661,6 @@ static bool write_file_handle(Main *mainvar,
case ID_LA:
write_light(&writer, (Light *)id_buffer, id);
break;
- case ID_LT:
- write_lattice(&writer, (Lattice *)id_buffer, id);
- break;
case ID_VF:
write_vfont(&writer, (VFont *)id_buffer, id);
break;
@@ -3946,9 +3700,6 @@ static bool write_file_handle(Main *mainvar,
case ID_TE:
write_texture(&writer, (Tex *)id_buffer, id);
break;
- case ID_ME:
- write_mesh(&writer, (Mesh *)id_buffer, id);
- break;
case ID_PA:
write_particlesettings(&writer, (ParticleSettings *)id_buffer, id);
break;
@@ -3985,6 +3736,10 @@ static bool write_file_handle(Main *mainvar,
case ID_SIM:
write_simulation(&writer, (Simulation *)id_buffer, id);
break;
+ case ID_ME:
+ case ID_LT:
+ /* Do nothing, handled in IDTypeInfo callback. */
+ break;
case ID_LI:
/* Do nothing, handled below - and should never be reached. */
BLI_assert(0);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 2669de87bc4..670827dc4d8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1129,9 +1129,11 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
if (object->rigidbody_object == nullptr) {
continue;
}
- if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+
+ if (!BKE_rigidbody_is_affected_by_simulation(object)) {
continue;
}
+
/* Create operation for flushing results. */
/* Object's transform component - where the rigidbody operation
* lives. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 6feebe6f542..5f637a92069 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1703,9 +1703,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
if (object->rigidbody_object == nullptr) {
continue;
}
- if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
- continue;
- }
if (object->parent != nullptr && object->parent->rigidbody_object != nullptr &&
object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
@@ -1716,10 +1713,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
continue;
}
- OperationKey rb_transform_copy_key(
- &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- /* Rigid body synchronization depends on the actual simulation. */
- add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync");
/* Simulation uses object transformation after parenting and solving constraints. */
OperationKey object_transform_simulation_init_key(
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT);
@@ -1737,47 +1730,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
add_relation(object_geometry_key,
rb_simulate_key,
- "Object Geom Eval -> Rigidbody Rebuild",
+ "Object Geom Eval -> Rigidbody Sim Eval",
RELATION_FLAG_GODMODE);
}
+
/* Final transform is whetever solver gave to us. */
- OperationKey object_transform_final_key(
- &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
- add_relation(
- rb_transform_copy_key, object_transform_final_key, "Rigidbody Sync -> Transform Final");
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- }
- /* Constraints. */
- if (rbw->constraints != nullptr) {
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) {
- RigidBodyCon *rbc = object->rigidbody_constraint;
- if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
- /* When either ob1 or ob2 is nullptr, the constraint doesn't
- * work. */
- continue;
- }
- /* Make sure indirectly linked objects are fully built. */
- build_object(object);
- build_object(rbc->ob1);
- build_object(rbc->ob2);
- /* final result of the constraint object's transform controls how
- * the constraint affects the physics sim for these objects. */
- ComponentKey trans_key(&object->id, NodeType::TRANSFORM);
- if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) {
- OperationKey ob1_key(
- &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- /* Constrained-objects sync depends on the constraint-holder. */
- add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
- }
- if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) {
- OperationKey ob2_key(
- &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- /* Constrained-objects sync depends on the constraint-holder. */
- add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
+ if (BKE_rigidbody_is_affected_by_simulation(object)) {
+ /* We do not have to update the objects final transform after the simulation if it is
+ * passive or controlled by the animation system in blender.
+ * (Bullet doesn't move the object at all in these cases)
+ */
+ OperationKey rb_transform_copy_key(
+ &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
+ /* Rigid body synchronization depends on the actual simulation. */
+ add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync");
+
+ OperationKey object_transform_final_key(
+ &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
+ add_relation(rb_transform_copy_key,
+ object_transform_final_key,
+ "Rigidbody Sync -> Transform Final");
}
- /* Ensure that sim depends on this constraint's transform. */
- add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation");
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f85b03dc517..83d39b606fe 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -419,6 +419,28 @@ if(WITH_XR_OPENXR)
add_definitions(-DWITH_XR_OPENXR)
endif()
+if(WITH_GTESTS)
+ if(WITH_OPENGL_DRAW_TESTS)
+ add_definitions(-DWITH_OPENGL_DRAW_TESTS)
+ endif()
+endif()
+
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ if(WITH_OPENGL_DRAW_TESTS)
+ set(TEST_SRC
+ tests/shaders_test.cc
+ )
+ set(TEST_INC
+ "../../../intern/ghost/"
+ )
+ set(TEST_LIB
+ bf_draw
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_draw_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+ endif()
+endif() \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 9cde9e871e5..b25f21ce929 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -32,6 +32,10 @@
#include "BKE_camera.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct EEVEE_ShadowCasterBuffer;
struct GPUFrameBuffer;
struct Object;
@@ -1363,3 +1367,7 @@ static const float cubefacemat[6][4][4] = {
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index f8c7a6e16db..9e7e545167a 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -372,6 +372,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* If no world or volume material is present just clear the buffer with this drawcall */
grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@@ -656,6 +658,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 34d4488d066..852945b25c3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -24,10 +24,16 @@
#include "DNA_gpencil_types.h"
+#include "DRW_render.h"
+
#include "BLI_bitmap.h"
#include "GPU_batch.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern DrawEngineType draw_engine_gpencil_type;
struct GPENCIL_Data;
@@ -397,7 +403,6 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
/* Shaders */
struct GPUShader *GPENCIL_shader_antialiasing(int stage);
struct GPUShader *GPENCIL_shader_geometry_get(void);
-struct GPUShader *GPENCIL_shader_composite_get(void);
struct GPUShader *GPENCIL_shader_layer_blend_get(void);
struct GPUShader *GPENCIL_shader_mask_invert_get(void);
struct GPUShader *GPENCIL_shader_depth_merge_get(void);
@@ -438,3 +443,6 @@ void GPENCIL_render_to_image(void *vedata,
void gpencil_light_pool_free(void *storage);
void gpencil_material_pool_free(void *storage);
GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void);
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 7e93382796f..c9d29af91e6 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -22,6 +22,12 @@
#pragma once
+#include "DRW_render.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef __APPLE__
# define USE_GEOM_SHADER_WORKAROUND 1
#else
@@ -627,3 +633,7 @@ GPUShader *OVERLAY_shader_xray_fade(void);
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
void OVERLAY_shader_free(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index eb61edca6c7..122c99ca536 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -1,6 +1,5 @@
#define EPSILON 0.00001
-#define M_PI 3.14159265358979323846
#define CAVITY_BUFFER_RANGE 4.0
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 12e573a02d0..8983826f16f 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -33,6 +33,10 @@
#include "workbench_engine.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct DrawEngineType draw_engine_workbench;
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
@@ -519,3 +523,6 @@ void workbench_render(void *ved,
void workbench_render_update_passes(struct RenderEngine *engine,
struct Scene *scene,
struct ViewLayer *view_layer);
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index f6e65338fc7..da11dacefbd 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -84,6 +84,7 @@
#include "draw_color_management.h"
#include "draw_manager_profiling.h"
+#include "draw_manager_testing.h"
#include "draw_manager_text.h"
/* only for callbacks */
@@ -2887,6 +2888,8 @@ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
GPU_context_active_set(NULL);
}
+/** \} */
+
#ifdef WITH_XR_OPENXR
/* XXX
@@ -2922,4 +2925,17 @@ void DRW_xr_drawing_end(void)
}
#endif
+
+/** \name Internal testing API for gtests
+ * \{ */
+
+#ifdef WITH_OPENGL_DRAW_TESTS
+
+void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg)
+{
+ DST.draw_ctx.sh_cfg = sh_cfg;
+}
+
+#endif
+
/** \} */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index b3e1258ff7f..8a81b3db7d8 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -99,6 +99,9 @@ void drw_state_set(DRWState state)
if (state & DRW_STATE_WRITE_COLOR) {
write_mask |= GPU_WRITE_COLOR;
}
+ if (state & DRW_STATE_WRITE_STENCIL_ENABLED) {
+ write_mask |= GPU_WRITE_STENCIL;
+ }
switch (state & (DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT)) {
case DRW_STATE_CULL_BACK:
diff --git a/source/blender/draw/intern/draw_manager_testing.h b/source/blender/draw/intern/draw_manager_testing.h
new file mode 100644
index 00000000000..f8b5dd5af46
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_testing.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ * Copyright 2016, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw
+ */
+
+/* Internal API only for test cases. */
+
+#pragma once
+
+#include "GPU_shader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WITH_OPENGL_DRAW_TESTS
+void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
new file mode 100644
index 00000000000..b2f1020ed98
--- /dev/null
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -0,0 +1,270 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "intern/draw_manager_testing.h"
+
+#include "GPU_context.h"
+#include "GPU_init_exit.h"
+#include "GPU_shader.h"
+
+#include "GHOST_C-api.h"
+
+#include "engines/eevee/eevee_private.h"
+#include "engines/gpencil/gpencil_engine.h"
+#include "engines/overlay/overlay_private.h"
+#include "engines/workbench/workbench_private.h"
+
+/* Base class for draw test cases. It will setup and tear down the GPU part around each test. */
+class DrawTest : public ::testing::Test {
+ private:
+ GHOST_SystemHandle ghost_system;
+ GHOST_ContextHandle ghost_context;
+ GPUContext *context;
+
+ void SetUp() override
+ {
+ ghost_system = GHOST_CreateSystem();
+ ghost_context = GHOST_CreateOpenGLContext(ghost_system);
+ context = GPU_context_create(0);
+ GPU_init();
+ DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT);
+ }
+
+ void TearDown() override
+ {
+ GPU_exit();
+ GPU_context_discard(context);
+ GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
+ GHOST_DisposeSystem(ghost_system);
+ }
+};
+
+TEST_F(DrawTest, workbench_glsl_shaders)
+{
+ workbench_shader_library_ensure();
+ DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT);
+
+ const int MAX_WPD = 6;
+ WORKBENCH_PrivateData wpds[MAX_WPD];
+
+ wpds[0].sh_cfg = GPU_SHADER_CFG_DEFAULT;
+ wpds[0].shading.light = V3D_LIGHTING_FLAT;
+ wpds[1].sh_cfg = GPU_SHADER_CFG_DEFAULT;
+ wpds[1].shading.light = V3D_LIGHTING_MATCAP;
+ wpds[2].sh_cfg = GPU_SHADER_CFG_DEFAULT;
+ wpds[2].shading.light = V3D_LIGHTING_STUDIO;
+ wpds[3].sh_cfg = GPU_SHADER_CFG_CLIPPED;
+ wpds[3].shading.light = V3D_LIGHTING_FLAT;
+ wpds[4].sh_cfg = GPU_SHADER_CFG_CLIPPED;
+ wpds[4].shading.light = V3D_LIGHTING_MATCAP;
+ wpds[5].sh_cfg = GPU_SHADER_CFG_CLIPPED;
+ wpds[5].shading.light = V3D_LIGHTING_STUDIO;
+
+ for (int wpd_index = 0; wpd_index < MAX_WPD; wpd_index++) {
+ WORKBENCH_PrivateData *wpd = &wpds[wpd_index];
+ EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_MESH), nullptr);
+ EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_HAIR), nullptr);
+ EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD), nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_MESH, false), nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_MESH, true), nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_HAIR, false), nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_HAIR, true), nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, false),
+ nullptr);
+ EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, true),
+ nullptr);
+ EXPECT_NE(workbench_shader_composite_get(wpd), nullptr);
+ EXPECT_NE(workbench_shader_merge_infront_get(wpd), nullptr);
+
+ EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_MESH), nullptr);
+ EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_HAIR), nullptr);
+ EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD), nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_MESH, false),
+ nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_MESH, true), nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_HAIR, false),
+ nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_HAIR, true), nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, false),
+ nullptr);
+ EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, true),
+ nullptr);
+ EXPECT_NE(workbench_shader_transparent_resolve_get(wpd), nullptr);
+ }
+
+ EXPECT_NE(workbench_shader_shadow_pass_get(false), nullptr);
+ EXPECT_NE(workbench_shader_shadow_pass_get(true), nullptr);
+ EXPECT_NE(workbench_shader_shadow_fail_get(false, false), nullptr);
+ EXPECT_NE(workbench_shader_shadow_fail_get(false, true), nullptr);
+ EXPECT_NE(workbench_shader_shadow_fail_get(true, false), nullptr);
+ EXPECT_NE(workbench_shader_shadow_fail_get(true, true), nullptr);
+
+ /* NOTE: workbench_shader_cavity_get(false, false) isn't a valid option. */
+ EXPECT_NE(workbench_shader_cavity_get(false, true), nullptr);
+ EXPECT_NE(workbench_shader_cavity_get(true, false), nullptr);
+ EXPECT_NE(workbench_shader_cavity_get(true, true), nullptr);
+ EXPECT_NE(workbench_shader_outline_get(), nullptr);
+
+ EXPECT_NE(workbench_shader_antialiasing_accumulation_get(), nullptr);
+ EXPECT_NE(workbench_shader_antialiasing_get(0), nullptr);
+ EXPECT_NE(workbench_shader_antialiasing_get(1), nullptr);
+ EXPECT_NE(workbench_shader_antialiasing_get(2), nullptr);
+
+ EXPECT_NE(workbench_shader_volume_get(false, false, false, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, false, false, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, false, true, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, false, true, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, true, false, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, true, false, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, true, true, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(false, true, true, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, false, false, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, false, false, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, false, true, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, false, true, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, true, false, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, true, false, true), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, true, true, false), nullptr);
+ EXPECT_NE(workbench_shader_volume_get(true, true, true, true), nullptr);
+
+ GPUShader *dof_prepare_sh;
+ GPUShader *dof_downsample_sh;
+ GPUShader *dof_blur1_sh;
+ GPUShader *dof_blur2_sh;
+ GPUShader *dof_resolve_sh;
+ workbench_shader_depth_of_field_get(
+ &dof_prepare_sh, &dof_downsample_sh, &dof_blur1_sh, &dof_blur2_sh, &dof_resolve_sh);
+ EXPECT_NE(dof_prepare_sh, nullptr);
+ EXPECT_NE(dof_downsample_sh, nullptr);
+ EXPECT_NE(dof_blur1_sh, nullptr);
+ EXPECT_NE(dof_blur2_sh, nullptr);
+ EXPECT_NE(dof_resolve_sh, nullptr);
+
+ workbench_shader_free();
+}
+
+TEST_F(DrawTest, gpencil_glsl_shaders)
+{
+ EXPECT_NE(GPENCIL_shader_antialiasing(0), nullptr);
+ EXPECT_NE(GPENCIL_shader_antialiasing(1), nullptr);
+ EXPECT_NE(GPENCIL_shader_antialiasing(2), nullptr);
+
+ EXPECT_NE(GPENCIL_shader_geometry_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_layer_blend_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_mask_invert_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_depth_merge_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_blur_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_colorize_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_composite_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_transform_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_glow_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_pixelize_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_rim_get(), nullptr);
+ EXPECT_NE(GPENCIL_shader_fx_shadow_get(), nullptr);
+
+ GPENCIL_shader_free();
+}
+
+TEST_F(DrawTest, overlay_glsl_shaders)
+{
+ for (int i = 0; i < 2; i++) {
+ eGPUShaderConfig sh_cfg = i == 0 ? GPU_SHADER_CFG_DEFAULT : GPU_SHADER_CFG_CLIPPED;
+ DRW_draw_state_init_gtests(sh_cfg);
+ EXPECT_NE(OVERLAY_shader_antialiasing(), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_degrees_of_freedom_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_degrees_of_freedom_solid(), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_envelope(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_envelope(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_shape(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_shape(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_shape_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_sphere(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_sphere(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_stick(), nullptr);
+ EXPECT_NE(OVERLAY_shader_armature_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_background(), nullptr);
+ EXPECT_NE(OVERLAY_shader_clipbound(), nullptr);
+ EXPECT_NE(OVERLAY_shader_depth_only(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_curve_handle(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_curve_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_curve_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_gpencil_guide_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_gpencil_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_gpencil_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_lattice_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_lattice_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_analysis(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_edge(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_edge(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_face(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_facedot(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_normal(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_skin_root(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_mesh_vert(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_particle_strand(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_particle_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_groundline(), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_wire(false, false), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_wire(false, true), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_wire(true, false), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_wire(true, true), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_loose_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_facing(), nullptr);
+ EXPECT_NE(OVERLAY_shader_gpencil_canvas(), nullptr);
+ EXPECT_NE(OVERLAY_shader_grid(), nullptr);
+ EXPECT_NE(OVERLAY_shader_image(), nullptr);
+ EXPECT_NE(OVERLAY_shader_motion_path_line(), nullptr);
+ EXPECT_NE(OVERLAY_shader_motion_path_vert(), nullptr);
+ EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr);
+ EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_outline_prepass_gpencil(), nullptr);
+ EXPECT_NE(OVERLAY_shader_outline_prepass_pointcloud(), nullptr);
+ EXPECT_NE(OVERLAY_shader_extra_grid(), nullptr);
+ EXPECT_NE(OVERLAY_shader_outline_detect(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_face(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_texture(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_vertcol(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_weight(), nullptr);
+ EXPECT_NE(OVERLAY_shader_paint_wire(), nullptr);
+ EXPECT_NE(OVERLAY_shader_particle_dot(), nullptr);
+ EXPECT_NE(OVERLAY_shader_particle_shape(), nullptr);
+ EXPECT_NE(OVERLAY_shader_sculpt_mask(), nullptr);
+ EXPECT_NE(OVERLAY_shader_volume_velocity(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_volume_velocity(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_wireframe(false), nullptr);
+ EXPECT_NE(OVERLAY_shader_wireframe(true), nullptr);
+ EXPECT_NE(OVERLAY_shader_wireframe_select(), nullptr);
+ EXPECT_NE(OVERLAY_shader_xray_fade(), nullptr);
+ }
+
+ OVERLAY_shader_free();
+}
+
+TEST_F(DrawTest, eevee_glsl_shaders_static)
+{
+ EEVEE_shaders_lightprobe_shaders_init();
+ EEVEE_shaders_material_shaders_init();
+
+ EXPECT_NE(EEVEE_shaders_probe_filter_glossy_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_filter_diffuse_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_filter_visibility_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_grid_fill_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_planar_downsample_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_studiolight_probe_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_studiolight_background_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_cube_display_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_grid_display_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_probe_planar_display_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_update_noise_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_velocity_resolve_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA), nullptr);
+ EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA_REPROJECT), nullptr);
+
+ EEVEE_shaders_free();
+} \ No newline at end of file
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 9490c807989..f99301371d4 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -970,7 +970,7 @@ static bool do_lasso_select_curve(ViewContext *vc,
/* Deselect items that were not added to selection (indicated by temp flag). */
if (deselect_all) {
- BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
+ data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
}
if (data.is_changed) {
@@ -2772,7 +2772,7 @@ static bool do_nurbs_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel
/* Deselect items that were not added to selection (indicated by temp flag). */
if (deselect_all) {
- BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
+ data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
}
BKE_curve_nurb_vert_active_validate(vc->obedit->data);
@@ -3693,7 +3693,6 @@ static bool nurbscurve_circle_select(ViewContext *vc,
const bool select = (sel_op != SEL_OP_SUB);
const bool deselect_all = (sel_op == SEL_OP_SET);
CircleSelectUserData data;
- bool changed = false;
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
@@ -3711,12 +3710,12 @@ static bool nurbscurve_circle_select(ViewContext *vc,
/* Deselect items that were not added to selection (indicated by temp flag). */
if (deselect_all) {
- BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
+ data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT);
}
BKE_curve_nurb_vert_active_validate(vc->obedit->data);
- return changed || data.is_changed;
+ return data.is_changed;
}
static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2])
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index e56df6d77a7..253877bcca0 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -29,6 +29,7 @@ typedef enum eGPUWriteMask {
GPU_WRITE_BLUE = (1 << 2),
GPU_WRITE_ALPHA = (1 << 3),
GPU_WRITE_DEPTH = (1 << 4),
+ GPU_WRITE_STENCIL = (1 << 5),
GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA),
} eGPUWriteMask;
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 22de1a0f59e..d56a7b2500b 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -36,7 +36,7 @@ namespace gpu {
class Shader {
public:
/** Uniform & attribute locations for shader. */
- ShaderInterface *interface;
+ ShaderInterface *interface = nullptr;
protected:
/** For debugging purpose. */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 7aaedbff1ce..29e29961028 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -1373,6 +1373,7 @@ static int make_structDNA(const char *base_directory,
/* write a simple enum with all structs offsets,
* should only be accessed via SDNA_TYPE_FROM_STRUCT macro */
{
+ fprintf(file_offsets, "#pragma once\n");
fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n");
fprintf(file_offsets, "enum {\n");
for (i = 0; i < structs_len; i++) {