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:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c80
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h53
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_intern.h65
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c970
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c777
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/action.c11
-rw-r--r--source/blender/blenkernel/intern/armature.c18
-rw-r--r--source/blender/blenkernel/intern/brush.c229
-rw-r--r--source/blender/blenkernel/intern/cachefile.c1
-rw-r--r--source/blender/blenkernel/intern/collection.c24
-rw-r--r--source/blender/blenkernel/intern/curve.c11
-rw-r--r--source/blender/blenkernel/intern/customdata.c20
-rw-r--r--source/blender/blenkernel/intern/displist.c9
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c57
-rw-r--r--source/blender/blenkernel/intern/font.c1
-rw-r--r--source/blender/blenkernel/intern/gpencil.c26
-rw-r--r--source/blender/blenkernel/intern/hair.c139
-rw-r--r--source/blender/blenkernel/intern/image.c1
-rw-r--r--source/blender/blenkernel/intern/ipo.c1
-rw-r--r--source/blender/blenkernel/intern/lib_query.c910
-rw-r--r--source/blender/blenkernel/intern/light.c7
-rw-r--r--source/blender/blenkernel/intern/linestyle.c46
-rw-r--r--source/blender/blenkernel/intern/mask.c16
-rw-r--r--source/blender/blenkernel/intern/movieclip.c24
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c11
-rw-r--r--source/blender/blenkernel/intern/object.c156
-rw-r--r--source/blender/blenkernel/intern/paint.c60
-rw-r--r--source/blender/blenkernel/intern/particle.c59
-rw-r--r--source/blender/blenkernel/intern/pbvh.c27
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h1
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c85
-rw-r--r--source/blender/blenkernel/intern/scene.c184
-rw-r--r--source/blender/blenkernel/intern/screen.c159
-rw-r--r--source/blender/blenkernel/intern/seqcache.c13
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c62
-rw-r--r--source/blender/blenkernel/intern/sequencer.c7
-rw-r--r--source/blender/blenkernel/intern/simulation.cc22
-rw-r--r--source/blender/blenkernel/intern/sound.c1
-rw-r--r--source/blender/blenkernel/intern/subdiv.c12
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c277
-rw-r--r--source/blender/blenkernel/intern/text.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c4
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c4
-rw-r--r--source/blender/blenkernel/intern/volume.cc71
-rw-r--r--source/blender/blenkernel/intern/workspace.c19
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c5
49 files changed, 1312 insertions, 3434 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index d76a4d8f859..98deddb4316 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -32,13 +32,6 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#ifdef WITH_OPENSUBDIV
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-# include "opensubdiv_evaluator_capi.h"
-# include "opensubdiv_topology_refiner_capi.h"
-#endif
-
#include "GPU_glew.h"
/***/
@@ -305,21 +298,6 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc,
ss->tempVerts = NULL;
ss->tempEdges = NULL;
-#ifdef WITH_OPENSUBDIV
- ss->osd_evaluator = NULL;
- ss->osd_mesh = NULL;
- ss->osd_topology_refiner = NULL;
- ss->osd_mesh_invalid = false;
- ss->osd_coarse_coords_invalid = false;
- ss->osd_vao = 0;
- ss->skip_grids = false;
- ss->osd_compute = 0;
- ss->osd_next_face_ptex_index = 0;
- ss->osd_coarse_coords = NULL;
- ss->osd_num_coarse_coords = 0;
- ss->osd_subdiv_uvs = false;
-#endif
-
return ss;
}
}
@@ -328,23 +306,6 @@ void ccgSubSurf_free(CCGSubSurf *ss)
{
CCGAllocatorIFC allocatorIFC = ss->allocatorIFC;
CCGAllocatorHDL allocator = ss->allocator;
-#ifdef WITH_OPENSUBDIV
- if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluator(ss->osd_evaluator);
- }
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- }
- if (ss->osd_vao != 0) {
- ccgSubSurf__delete_vertex_array(ss->osd_vao);
- }
- if (ss->osd_coarse_coords != NULL) {
- MEM_freeN(ss->osd_coarse_coords);
- }
- if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
- }
-#endif
if (ss->syncState) {
ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP)_face_free, ss);
@@ -529,9 +490,6 @@ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
ss->tempEdges = MEM_mallocN(sizeof(*ss->tempEdges) * ss->lenTempArrays, "CCGSubsurf tempEdges");
ss->syncState = eSyncState_Vert;
-#ifdef WITH_OPENSUBDIV
- ss->osd_next_face_ptex_index = 0;
-#endif
return eCCGError_None;
}
@@ -671,9 +629,6 @@ CCGError ccgSubSurf_syncVert(
ccg_ehash_insert(ss->vMap, (EHEntry *)v);
v->flags = 0;
}
-#ifdef WITH_OPENSUBDIV
- v->osd_index = ss->vMap->numEntries - 1;
-#endif
}
if (v_r) {
@@ -874,15 +829,6 @@ CCGError ccgSubSurf_syncFace(
}
}
}
-#ifdef WITH_OPENSUBDIV
- f->osd_index = ss->osd_next_face_ptex_index;
- if (numVerts == 4) {
- ss->osd_next_face_ptex_index++;
- }
- else {
- ss->osd_next_face_ptex_index += numVerts;
- }
-#endif
}
if (f_r) {
@@ -893,15 +839,7 @@ CCGError ccgSubSurf_syncFace(
static void ccgSubSurf__sync(CCGSubSurf *ss)
{
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- ccgSubSurf__sync_opensubdiv(ss);
- }
- else
-#endif
- {
- ccgSubSurf__sync_legacy(ss);
- }
+ ccgSubSurf__sync_legacy(ss);
}
CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
@@ -1615,12 +1553,6 @@ int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
ss->fMap->numEntries +
ss->numGrids * ((gridSize - 2) + ((gridSize - 2) * (gridSize - 2))));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
-
return numFinalVerts;
}
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
@@ -1629,22 +1561,12 @@ int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
int gridSize = ccg_gridsize(ss->subdivLevels);
int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) +
ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1))));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
return numFinalEdges;
}
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
{
int gridSize = ccg_gridsize(ss->subdivLevels);
int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
return numFinalFaces;
}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 83b59941ac7..2e5100db6de 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -211,57 +211,4 @@ CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);
-#ifdef WITH_OPENSUBDIV
-struct DerivedMesh;
-
-/* Check if topology changed and evaluators are to be re-created. */
-void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, struct DerivedMesh *dm);
-
-/* Create topology refiner from give derived mesh which then later will be
- * used for GL mesh creation.
- */
-void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, struct DerivedMesh *dm);
-
-/* Make sure GL mesh exists, up to date and ready to draw. */
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl, int active_uv_index);
-
-/* Draw given partitions of the GL mesh.
- *
- * TODO(sergey): fill_quads is actually an invariant and should be part
- * of the prepare routine.
- */
-void ccgSubSurf_drawGLMesh(CCGSubSurf *ss,
- bool fill_quads,
- int start_partition,
- int num_partitions);
-
-/* Get number of base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss);
-
-/* Get number of vertices in base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face);
-
-/* Controls whether CCG are needed (Cmeaning CPU evaluation) or fully GPU compute
- * and draw is allowed.
- */
-void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
-bool ccgSubSurf_needGrids(CCGSubSurf *ss);
-
-/* Set evaluator's face varying data from UV coordinates.
- * Used for CPU evaluation.
- */
-void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss, struct DerivedMesh *dm, int layer_index);
-
-/* TODO(sergey): Temporary call to test things. */
-void ccgSubSurf_evaluatorFVarUV(
- CCGSubSurf *ss, int face_index, int S, float grid_u, float grid_v, float uv[2]);
-
-void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss);
-
-void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3]);
-
-void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subsurf_uvs);
-
-#endif
-
#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 51486db1bdc..7c35d2ccfce 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -157,9 +157,6 @@ typedef enum {
eSyncState_Edge,
eSyncState_Face,
eSyncState_Partial,
-#ifdef WITH_OPENSUBDIV
- eSyncState_OpenSubdiv,
-#endif
} SyncState;
struct CCGSubSurf {
@@ -202,58 +199,6 @@ struct CCGSubSurf {
int lenTempArrays;
CCGVert **tempVerts;
CCGEdge **tempEdges;
-
-#ifdef WITH_OPENSUBDIV
- /* Skip grids means no CCG geometry is created and subsurf is possible
- * to be completely done on GPU.
- */
- bool skip_grids;
-
- /* ** GPU backend. ** */
-
- /* Compute device used by GL mesh. */
- short osd_compute;
- /* Coarse (base mesh) vertex coordinates.
- *
- * Filled in from the modifier stack and passed to OpenSubdiv compute
- * on mesh display.
- */
- float (*osd_coarse_coords)[3];
- int osd_num_coarse_coords;
- /* Denotes whether coarse positions in the GL mesh are invalid.
- * Used to avoid updating GL mesh coords on every redraw.
- */
- bool osd_coarse_coords_invalid;
-
- /* GL mesh descriptor, used for refinement and draw. */
- struct OpenSubdiv_GLMesh *osd_mesh;
- /* Refiner which is used to create GL mesh.
- *
- * Refiner is created from the modifier stack and used later from the main
- * thread to construct GL mesh to avoid threaded access to GL.
- */
- struct OpenSubdiv_TopologyRefiner
- *osd_topology_refiner; /* Only used at synchronization stage. */
- /* Denotes whether osd_mesh is invalid now due to topology changes and needs
- * to be reconstructed.
- *
- * Reconstruction happens from main thread due to OpenGL communication.
- */
- bool osd_mesh_invalid;
- /* Vertex array used for osd_mesh draw. */
- unsigned int osd_vao;
-
- /* ** CPU backend. ** */
-
- /* Limit evaluator, used to evaluate CCG. */
- struct OpenSubdiv_Evaluator *osd_evaluator;
- /* Next PTex face index, used while CCG synchronization
- * to fill in PTex index of CCGFace.
- */
- int osd_next_face_ptex_index;
-
- bool osd_subdiv_uvs;
-#endif
};
/* ** Utility macros ** */
@@ -322,16 +267,6 @@ void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss);
-/* Delayed free routines. Will do actual free if called from
- * main thread and schedule free for later free otherwise.
- */
-
-#ifdef WITH_OPENSUBDIV
-void ccgSubSurf__delete_osdGLMesh(struct OpenSubdiv_GLMesh *osd_mesh);
-void ccgSubSurf__delete_vertex_array(unsigned int vao);
-void ccgSubSurf__delete_pending(void);
-#endif
-
/* * CCGSubSurf_opensubdiv_converter.c * */
struct OpenSubdiv_Converter;
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
deleted file mode 100644
index 3257dd2334c..00000000000
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup bke
- */
-
-#ifdef WITH_OPENSUBDIV
-
-# include "BLI_sys_types.h" // for intptr_t support
-# include "MEM_guardedalloc.h"
-
-# include "BLI_listbase.h"
-# include "BLI_math.h"
-# include "BLI_threads.h"
-# include "BLI_utildefines.h" /* for BLI_assert */
-
-# include "CCGSubSurf.h"
-# include "CCGSubSurf_intern.h"
-
-# include "BKE_DerivedMesh.h"
-# include "BKE_subsurf.h"
-
-# include "DNA_userdef_types.h"
-
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-# include "opensubdiv_evaluator_capi.h"
-# include "opensubdiv_gl_mesh_capi.h"
-# include "opensubdiv_topology_refiner_capi.h"
-
-# include "GPU_extensions.h"
-# include "GPU_glew.h"
-
-# define OSD_LOG \
- if (false) \
- printf
-
-static bool compare_ccg_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
-{
- const int num_verts = dm->getNumVerts(dm);
- const int num_edges = dm->getNumEdges(dm);
- const int num_polys = dm->getNumPolys(dm);
- const MEdge *medge = dm->getEdgeArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
-
- /* Quick preliminary tests based on the number of verts and facces. */
- {
- if (num_verts != ss->vMap->numEntries || num_edges != ss->eMap->numEntries ||
- num_polys != ss->fMap->numEntries) {
- return false;
- }
- }
-
- /* Rather slow check for faces topology change. */
- {
- CCGFaceIterator ccg_face_iter;
- for (ccgSubSurf_initFaceIterator(ss, &ccg_face_iter);
- !ccgFaceIterator_isStopped(&ccg_face_iter);
- ccgFaceIterator_next(&ccg_face_iter)) {
- /*const*/ CCGFace *ccg_face = ccgFaceIterator_getCurrent(&ccg_face_iter);
- const int poly_index = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- const MPoly *mp = &mpoly[poly_index];
- int corner;
- if (ccg_face->numVerts != mp->totloop) {
- return false;
- }
- for (corner = 0; corner < ccg_face->numVerts; corner++) {
- /*const*/ CCGVert *ccg_vert = FACE_getVerts(ccg_face)[corner];
- const int vert_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert));
- if (vert_index != mloop[mp->loopstart + corner].v) {
- return false;
- }
- }
- }
- }
-
- /* Check for edge topology change. */
- {
- CCGEdgeIterator ccg_edge_iter;
- for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
- !ccgEdgeIterator_isStopped(&ccg_edge_iter);
- ccgEdgeIterator_next(&ccg_edge_iter)) {
- /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
- /* const */ CCGVert *ccg_vert1 = ccg_edge->v0;
- /* const */ CCGVert *ccg_vert2 = ccg_edge->v1;
- const int ccg_vert1_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert1));
- const int ccg_vert2_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert2));
- const int edge_index = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- const MEdge *me = &medge[edge_index];
- if (me->v1 != ccg_vert1_index || me->v2 != ccg_vert2_index) {
- return false;
- }
- }
- }
-
- /* TODO(sergey): Crease topology changes detection. */
- {
- CCGEdgeIterator ccg_edge_iter;
- for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
- !ccgEdgeIterator_isStopped(&ccg_edge_iter);
- ccgEdgeIterator_next(&ccg_edge_iter)) {
- /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
- const int edge_index = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- if (ccg_edge->crease != medge[edge_index].crease) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
-{
- OpenSubdiv_Converter converter;
- bool result;
- if (ss->osd_mesh == NULL && ss->osd_topology_refiner == NULL) {
- return true;
- }
- /* TODO(sergey): De-duplicate with topology counter at the bottom of
- * the file.
- */
- ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
- result = openSubdiv_topologyRefinerCompareWithConverter(ss->osd_topology_refiner, &converter);
- ccgSubSurf_converter_free(&converter);
- return result;
-}
-
-static bool opensubdiv_is_topology_changed(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (ss->osd_compute != U.opensubdiv_compute_type) {
- return true;
- }
- if (ss->osd_topology_refiner != NULL) {
- const int levels = ss->osd_topology_refiner->getSubdivisionLevel(ss->osd_topology_refiner);
- BLI_assert(ss->osd_mesh_invalid == true);
- if (levels != ss->subdivLevels) {
- return true;
- }
- }
- if (ss->skip_grids == false) {
- return compare_ccg_derivedmesh_topology(ss, dm) == false;
- }
- else {
- return compare_osd_derivedmesh_topology(ss, dm) == false;
- }
- return false;
-}
-
-void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (opensubdiv_is_topology_changed(ss, dm)) {
- /* ** Make sure both GPU and CPU backends are properly reset. ** */
-
- ss->osd_coarse_coords_invalid = true;
-
- /* Reset GPU part. */
- ss->osd_mesh_invalid = true;
- if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
- ss->osd_topology_refiner = NULL;
- }
-
- /* Reset CPU side. */
- if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluator(ss->osd_evaluator);
- ss->osd_evaluator = NULL;
- }
- }
-}
-
-static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
-{
- BLI_assert(ss->meshIFC.numLayers == 3);
- ss->osd_mesh->setCoarsePositions(
- ss->osd_mesh, (float *)ss->osd_coarse_coords, 0, ss->osd_num_coarse_coords);
-}
-
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl, int active_uv_index)
-{
- int compute_type;
-
- switch (U.opensubdiv_compute_type) {
-# define CHECK_COMPUTE_TYPE(type) \
- case USER_OPENSUBDIV_COMPUTE_##type: \
- compute_type = OPENSUBDIV_EVALUATOR_##type; \
- break;
- CHECK_COMPUTE_TYPE(CPU)
- CHECK_COMPUTE_TYPE(OPENMP)
- CHECK_COMPUTE_TYPE(OPENCL)
- CHECK_COMPUTE_TYPE(CUDA)
- CHECK_COMPUTE_TYPE(GLSL_TRANSFORM_FEEDBACK)
- CHECK_COMPUTE_TYPE(GLSL_COMPUTE)
- default:
- compute_type = OPENSUBDIV_EVALUATOR_CPU;
- break;
-# undef CHECK_COMPUTE_TYPE
- }
-
- if (ss->osd_vao == 0) {
- glGenVertexArrays(1, &ss->osd_vao);
- }
-
- if (ss->osd_mesh_invalid) {
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- ss->osd_mesh = NULL;
- }
- ss->osd_mesh_invalid = false;
- }
-
- if (ss->osd_mesh == NULL) {
- if (ss->osd_topology_refiner == NULL) {
- /* Happens with empty meshes. */
- /* TODO(sergey): Add assert that mesh is indeed empty. */
- return false;
- }
-
- ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner(ss->osd_topology_refiner,
- compute_type);
-
- if (UNLIKELY(ss->osd_mesh == NULL)) {
- /* Most likely compute device is not available. */
- return false;
- }
-
- ccgSubSurf__updateGLMeshCoords(ss);
- ss->osd_mesh->refine(ss->osd_mesh);
- ss->osd_mesh->synchronize(ss->osd_mesh);
- ss->osd_coarse_coords_invalid = false;
-
- glBindVertexArray(ss->osd_vao);
- ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
-
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (float *)12);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
- else if (ss->osd_coarse_coords_invalid) {
- ccgSubSurf__updateGLMeshCoords(ss);
- ss->osd_mesh->refine(ss->osd_mesh);
- ss->osd_mesh->synchronize(ss->osd_mesh);
- ss->osd_coarse_coords_invalid = false;
- }
-
- ss->osd_mesh->prepareDraw(ss->osd_mesh, use_osd_glsl, active_uv_index);
-
- return true;
-}
-
-void ccgSubSurf_drawGLMesh(CCGSubSurf *ss,
- bool fill_quads,
- int start_partition,
- int num_partitions)
-{
- if (LIKELY(ss->osd_mesh != NULL)) {
- glBindVertexArray(ss->osd_vao);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ss->osd_mesh->getPatchIndexBuffer(ss->osd_mesh));
-
- ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
- glBindVertexArray(ss->osd_vao);
- ss->osd_mesh->drawPatches(ss->osd_mesh, fill_quads, start_partition, num_partitions);
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
-}
-
-int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
-{
- if (ss->osd_topology_refiner != NULL) {
- return ss->osd_topology_refiner->getNumFaces(ss->osd_topology_refiner);
- }
- return 0;
-}
-
-/* Get number of vertices in base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
-{
- if (ss->osd_topology_refiner != NULL) {
- return ss->osd_topology_refiner->getNumFaceVertices(ss->osd_topology_refiner, face);
- }
- return 0;
-}
-
-void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
-{
- ss->skip_grids = skip_grids;
-}
-
-bool ccgSubSurf_needGrids(CCGSubSurf *ss)
-{
- return ss->skip_grids == false;
-}
-
-BLI_INLINE void ccgSubSurf__mapGridToFace(
- int S, float grid_u, float grid_v, float *face_u, float *face_v)
-{
- float u, v;
-
- /* - Each grid covers half of the face along the edges.
- * - Grid's (0, 0) starts from the middle of the face.
- */
- u = 0.5f - 0.5f * grid_u;
- v = 0.5f - 0.5f * grid_v;
-
- if (S == 0) {
- *face_u = v;
- *face_v = u;
- }
- else if (S == 1) {
- *face_u = 1.0f - u;
- *face_v = v;
- }
- else if (S == 2) {
- *face_u = 1.0f - v;
- *face_v = 1.0f - u;
- }
- else {
- *face_u = u;
- *face_v = 1.0f - v;
- }
-}
-
-BLI_INLINE void ccgSubSurf__mapEdgeToFace(
- int S, int edge_segment, bool inverse_edge, int edgeSize, float *face_u, float *face_v)
-{
- int t = inverse_edge ? edgeSize - edge_segment - 1 : edge_segment;
- if (S == 0) {
- *face_u = (float)t / (edgeSize - 1);
- *face_v = 0.0f;
- }
- else if (S == 1) {
- *face_u = 1.0f;
- *face_v = (float)t / (edgeSize - 1);
- }
- else if (S == 2) {
- *face_u = 1.0f - (float)t / (edgeSize - 1);
- *face_v = 1.0f;
- }
- else {
- *face_u = 0.0f;
- *face_v = 1.0f - (float)t / (edgeSize - 1);
- }
-}
-
-void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss, DerivedMesh *dm, int layer_index)
-{
- MPoly *mpoly = dm->getPolyArray(dm);
- MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
- int num_polys = dm->getNumPolys(dm);
- int index, poly;
- BLI_assert(ss->osd_evaluator != NULL);
- for (poly = 0, index = 0; poly < num_polys; poly++) {
- int loop;
- MPoly *mp = &mpoly[poly];
- for (loop = 0; loop < mp->totloop; loop++, index++) {
- MLoopUV *mluv = &mloopuv[loop + mp->loopstart];
- (void)mluv;
- /* TODO(sergey): Send mluv->uv to the evaluator's face varying
- * buffer.
- */
- }
- }
- (void)ss;
-}
-
-void ccgSubSurf_evaluatorFVarUV(
- CCGSubSurf *ss, int face_index, int S, float grid_u, float grid_v, float uv[2])
-{
- float face_u, face_v;
- ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
- (void)ss;
- (void)face_index;
- /* TODO(sergey): Evaluate face varying coordinate. */
- zero_v2(uv);
-}
-
-static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
-{
- OpenSubdiv_Converter converter;
- OpenSubdiv_TopologyRefiner *topology_refiner;
- if (ss->fMap->numEntries == 0) {
- /* OpenSubdiv doesn't support meshes without faces. */
- return false;
- }
- ccgSubSurf_converter_setup_from_ccg(ss, &converter);
- OpenSubdiv_TopologyRefinerSettings settings;
- settings.level = ss->subdivLevels;
- settings.is_adaptive = false;
- topology_refiner = openSubdiv_createTopologyRefinerFromConverter(&converter, &settings);
- ccgSubSurf_converter_free(&converter);
- ss->osd_evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(topology_refiner);
- if (ss->osd_evaluator == NULL) {
- BLI_assert(!"OpenSubdiv initialization failed, should not happen.");
- return false;
- }
- return true;
-}
-
-static bool opensubdiv_ensureEvaluator(CCGSubSurf *ss)
-{
- if (ss->osd_evaluator == NULL) {
- OSD_LOG("Allocating new evaluator, %d verts\n", ss->vMap->numEntries);
- opensubdiv_createEvaluator(ss);
- }
- return ss->osd_evaluator != NULL;
-}
-
-static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
-{
- float(*positions)[3];
- int vertDataSize = ss->meshIFC.vertDataSize;
- int num_basis_verts = ss->vMap->numEntries;
- int i;
-
- /* TODO(sergey): Avoid allocation on every update. We could either update
- * coordinates in chunks of 1K vertices (which will only use stack memory)
- * or do some callback magic for OSD evaluator can invoke it and fill in
- * buffer directly.
- */
- if (ss->meshIFC.numLayers == 3) {
- /* If all the components are to be initialized, no need to memset the
- * new memory block.
- */
- positions = MEM_mallocN(3 * sizeof(float) * num_basis_verts, "OpenSubdiv coarse points");
- }
- else {
- /* Calloc in order to have z component initialized to 0 for Uvs */
- positions = MEM_callocN(3 * sizeof(float) * num_basis_verts, "OpenSubdiv coarse points");
- }
-# pragma omp parallel for
- for (i = 0; i < ss->vMap->curSize; i++) {
- CCGVert *v = (CCGVert *)ss->vMap->buckets[i];
- for (; v; v = v->next) {
- float *co = VERT_getCo(v, 0);
- BLI_assert(v->osd_index < ss->vMap->numEntries);
- VertDataCopy(positions[v->osd_index], co, ss);
- OSD_LOG("Point %d has value %f %f %f\n",
- v->osd_index,
- positions[v->osd_index][0],
- positions[v->osd_index][1],
- positions[v->osd_index][2]);
- }
- }
-
- ss->osd_evaluator->setCoarsePositions(ss->osd_evaluator, (float *)positions, 0, num_basis_verts);
- ss->osd_evaluator->refine(ss->osd_evaluator);
-
- MEM_freeN(positions);
-}
-
-static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
- CCGFace *face,
- const int osd_face_index)
-{
- int normalDataOffset = ss->normalDataOffset;
- int subdivLevels = ss->subdivLevels;
- int gridSize = ccg_gridsize(subdivLevels);
- int edgeSize = ccg_edgesize(subdivLevels);
- int vertDataSize = ss->meshIFC.vertDataSize;
- int S;
- bool do_normals = ss->meshIFC.numLayers == 3;
-
-# pragma omp parallel for
- for (S = 0; S < face->numVerts; S++) {
- int x, y, k;
- CCGEdge *edge = NULL;
- bool inverse_edge = false;
-
- for (x = 0; x < gridSize; x++) {
- for (y = 0; y < gridSize; y++) {
- float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
- float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
- float grid_u = (float)x / (gridSize - 1), grid_v = (float)y / (gridSize - 1);
- float face_u, face_v;
- float P[3], dPdu[3], dPdv[3];
-
- ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
-
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(ss->osd_evaluator,
- osd_face_index,
- face_u,
- face_v,
- P,
- do_normals ? dPdu : NULL,
- do_normals ? dPdv : NULL);
-
- OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n",
- osd_face_index,
- S,
- grid_u,
- grid_v,
- face_u,
- face_v,
- P[0],
- P[1],
- P[2]);
-
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
-
- if (x == gridSize - 1 && y == gridSize - 1) {
- float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_co, co, ss);
- if (do_normals) {
- float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_no, no, ss);
- }
- }
- if (S == 0 && x == 0 && y == 0) {
- float *center_co = (float *)FACE_getCenterData(face);
- VertDataCopy(center_co, co, ss);
- if (do_normals) {
- float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
- VertDataCopy(center_no, no, ss);
- }
- }
- }
- }
-
- for (x = 0; x < gridSize; x++) {
- VertDataCopy(
- FACE_getIECo(face, subdivLevels, S, x), FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
- if (do_normals) {
- VertDataCopy(
- FACE_getIENo(face, subdivLevels, S, x), FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
- }
- }
-
- for (k = 0; k < face->numVerts; k++) {
- CCGEdge *current_edge = FACE_getEdges(face)[k];
- CCGVert **face_verts = FACE_getVerts(face);
- if (current_edge->v0 == face_verts[S] &&
- current_edge->v1 == face_verts[(S + 1) % face->numVerts]) {
- edge = current_edge;
- inverse_edge = false;
- break;
- }
- if (current_edge->v1 == face_verts[S] &&
- current_edge->v0 == face_verts[(S + 1) % face->numVerts]) {
- edge = current_edge;
- inverse_edge = true;
- break;
- }
- }
-
- BLI_assert(edge != NULL);
-
- for (x = 0; x < edgeSize; x++) {
- float u = 0, v = 0;
- float *co = EDGE_getCo(edge, subdivLevels, x);
- float *no = EDGE_getNo(edge, subdivLevels, x);
- float P[3], dPdu[3], dPdv[3];
- ccgSubSurf__mapEdgeToFace(S, x, inverse_edge, edgeSize, &u, &v);
-
- /* TODO(sergey): Ideally we will re-use grid here, but for now
- * let's just re-evaluate for simplicity.
- */
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv);
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
- }
- }
-}
-
-static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss,
- CCGFace *face,
- const int osd_face_index)
-{
- CCGVert **all_verts = FACE_getVerts(face);
- int normalDataOffset = ss->normalDataOffset;
- int subdivLevels = ss->subdivLevels;
- int gridSize = ccg_gridsize(subdivLevels);
- int edgeSize = ccg_edgesize(subdivLevels);
- int vertDataSize = ss->meshIFC.vertDataSize;
- int S;
- bool do_normals = ss->meshIFC.numLayers == 3;
-
- /* Note about handling non-quad faces.
- *
- * In order to deal with non-quad faces we need to split them
- * into a quads in the following way:
- *
- * |
- * (vert_next)
- * |
- * |
- * |
- * (face_center) ------------------- (v2)
- * | (o)--------------------> |
- * | | v |
- * | | |
- * | | |
- * | | |
- * | | y ^ |
- * | | | |
- * | v u x | |
- * | <---(o) |
- * ---- (vert_prev) ---- (v1) -------------------- (vert)
- *
- * This is how grids are expected to be stored and it's how
- * OpenSubdiv deals with non-quad faces using ptex face indices.
- * We only need to convert ptex (x, y) to grid (u, v) by some
- * simple flips and evaluate the ptex face.
- */
-
- /* Evaluate face grids. */
-# pragma omp parallel for
- for (S = 0; S < face->numVerts; S++) {
- int x, y;
- for (x = 0; x < gridSize; x++) {
- for (y = 0; y < gridSize; y++) {
- float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
- float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
- float u = 1.0f - (float)y / (gridSize - 1), v = 1.0f - (float)x / (gridSize - 1);
- float P[3], dPdu[3], dPdv[3];
-
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(
- ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv);
-
- OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n",
- osd_face_index + S,
- S,
- u,
- v,
- P[0],
- P[1],
- P[2]);
-
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
-
- /* TODO(sergey): De-dpuplicate with the quad case. */
- if (x == gridSize - 1 && y == gridSize - 1) {
- float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_co, co, ss);
- if (do_normals) {
- float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_no, no, ss);
- }
- }
- if (S == 0 && x == 0 && y == 0) {
- float *center_co = (float *)FACE_getCenterData(face);
- VertDataCopy(center_co, co, ss);
- if (do_normals) {
- float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
- VertDataCopy(center_no, no, ss);
- }
- }
- }
- }
- for (x = 0; x < gridSize; x++) {
- VertDataCopy(
- FACE_getIECo(face, subdivLevels, S, x), FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
- if (do_normals) {
- VertDataCopy(
- FACE_getIENo(face, subdivLevels, S, x), FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
- }
- }
- }
-
- /* Evaluate edges. */
- for (S = 0; S < face->numVerts; S++) {
- CCGEdge *edge = FACE_getEdges(face)[S];
- int x, S0 = 0, S1 = 0;
- bool flip;
-
- for (x = 0; x < face->numVerts; x++) {
- if (all_verts[x] == edge->v0) {
- S0 = x;
- }
- else if (all_verts[x] == edge->v1) {
- S1 = x;
- }
- }
- if (S == face->numVerts - 1) {
- flip = S0 > S1;
- }
- else {
- flip = S0 < S1;
- }
-
- for (x = 0; x <= edgeSize / 2; x++) {
- float *edge_co = EDGE_getCo(edge, subdivLevels, x);
- float *edge_no = EDGE_getNo(edge, subdivLevels, x);
- float *face_edge_co;
- float *face_edge_no;
- if (flip) {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
- }
- else {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
- }
- VertDataCopy(edge_co, face_edge_co, ss);
- if (do_normals) {
- VertDataCopy(edge_no, face_edge_no, ss);
- }
- }
- for (x = edgeSize / 2 + 1; x < edgeSize; x++) {
- float *edge_co = EDGE_getCo(edge, subdivLevels, x);
- float *edge_no = EDGE_getNo(edge, subdivLevels, x);
- float *face_edge_co;
- float *face_edge_no;
- if (flip) {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
- }
- else {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
- }
- VertDataCopy(edge_co, face_edge_co, ss);
- if (do_normals) {
- VertDataCopy(edge_no, face_edge_no, ss);
- }
- }
- }
-}
-
-static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
-{
- int i;
- for (i = 0; i < ss->fMap->curSize; i++) {
- CCGFace *face = (CCGFace *)ss->fMap->buckets[i];
- for (; face; face = face->next) {
- if (face->numVerts == 4) {
- /* For quads we do special magic with converting face coords
- * into corner coords and interpolating grids from it.
- */
- opensubdiv_evaluateQuadFaceGrids(ss, face, face->osd_index);
- }
- else {
- /* NGons and tris are split into separate osd faces which
- * evaluates onto grids directly.
- */
- opensubdiv_evaluateNGonFaceGrids(ss, face, face->osd_index);
- }
- }
- }
-}
-
-CCGError ccgSubSurf_initOpenSubdivSync(CCGSubSurf *ss)
-{
- if (ss->syncState != eSyncState_None) {
- return eCCGError_InvalidSyncState;
- }
- ss->syncState = eSyncState_OpenSubdiv;
- return eCCGError_None;
-}
-
-void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (ss->osd_mesh == NULL || ss->osd_mesh_invalid) {
- if (dm->getNumPolys(dm) != 0) {
- OpenSubdiv_Converter converter;
- ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
- /* TODO(sergey): Remove possibly previously allocated refiner. */
- OpenSubdiv_TopologyRefinerSettings settings;
- settings.level = ss->subdivLevels;
- settings.is_adaptive = false;
- ss->osd_topology_refiner = openSubdiv_createTopologyRefinerFromConverter(&converter,
- &settings);
- ccgSubSurf_converter_free(&converter);
- }
- }
-
- /* Update number of grids, needed for things like final faces
- * counter, used by display drawing.
- */
- {
- const int num_polys = dm->getNumPolys(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
- int poly;
- ss->numGrids = 0;
- for (poly = 0; poly < num_polys; poly++) {
- ss->numGrids += mpoly[poly].totloop;
- }
- }
-
- {
- const int num_verts = dm->getNumVerts(dm);
- const MVert *mvert = dm->getVertArray(dm);
- int vert;
- if (ss->osd_coarse_coords != NULL && num_verts != ss->osd_num_coarse_coords) {
- MEM_freeN(ss->osd_coarse_coords);
- ss->osd_coarse_coords = NULL;
- }
- if (ss->osd_coarse_coords == NULL) {
- ss->osd_coarse_coords = MEM_mallocN(sizeof(float) * 6 * num_verts, "osd coarse positions");
- }
- for (vert = 0; vert < num_verts; vert++) {
- copy_v3_v3(ss->osd_coarse_coords[vert * 2 + 0], mvert[vert].co);
- normal_short_to_float_v3(ss->osd_coarse_coords[vert * 2 + 1], mvert[vert].no);
- }
- ss->osd_num_coarse_coords = num_verts;
- ss->osd_coarse_coords_invalid = true;
- }
-}
-
-void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
-{
- BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
-
- /* Common synchronization steps */
- ss->osd_compute = U.opensubdiv_compute_type;
-
- if (ss->skip_grids == false) {
- /* Make sure OSD evaluator is up-to-date. */
- if (opensubdiv_ensureEvaluator(ss)) {
- /* Update coarse points in the OpenSubdiv evaluator. */
- opensubdiv_updateEvaluatorCoarsePositions(ss);
-
- /* Evaluate opensubdiv mesh into the CCG grids. */
- opensubdiv_evaluateGrids(ss);
- }
- }
- else {
- BLI_assert(ss->meshIFC.numLayers == 3);
- }
-
-# ifdef DUMP_RESULT_GRIDS
- ccgSubSurf__dumpCoords(ss);
-# endif
-}
-
-void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss)
-{
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- ss->osd_mesh = NULL;
- }
- if (ss->osd_vao != 0) {
- glDeleteVertexArrays(1, &ss->osd_vao);
- ss->osd_vao = 0;
- }
-}
-
-void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3])
-{
- int i;
- BLI_assert(ss->skip_grids == true);
- if (ss->osd_num_coarse_coords == 0) {
- zero_v3(r_min);
- zero_v3(r_max);
- }
- for (i = 0; i < ss->osd_num_coarse_coords; i++) {
- /* Coarse coordinates has normals interleaved into the array. */
- DO_MINMAX(ss->osd_coarse_coords[2 * i], r_min, r_max);
- }
-}
-
-/* ** Delayed delete routines ** */
-
-typedef struct OsdDeletePendingItem {
- struct OsdDeletePendingItem *next, *prev;
- OpenSubdiv_GLMesh *osd_mesh;
- unsigned int vao;
-} OsdDeletePendingItem;
-
-static SpinLock delete_spin;
-static ListBase delete_pool = {NULL, NULL};
-
-static void delete_pending_push(OpenSubdiv_GLMesh *osd_mesh, unsigned int vao)
-{
- OsdDeletePendingItem *new_entry = MEM_mallocN(sizeof(OsdDeletePendingItem),
- "opensubdiv delete entry");
- new_entry->osd_mesh = osd_mesh;
- new_entry->vao = vao;
- BLI_spin_lock(&delete_spin);
- BLI_addtail(&delete_pool, new_entry);
- BLI_spin_unlock(&delete_spin);
-}
-
-void ccgSubSurf__delete_osdGLMesh(OpenSubdiv_GLMesh *osd_mesh)
-{
- if (BLI_thread_is_main()) {
- openSubdiv_deleteOsdGLMesh(osd_mesh);
- }
- else {
- delete_pending_push(osd_mesh, 0);
- }
-}
-
-void ccgSubSurf__delete_vertex_array(unsigned int vao)
-{
- if (BLI_thread_is_main()) {
- glDeleteVertexArrays(1, &vao);
- }
- else {
- delete_pending_push(NULL, vao);
- }
-}
-
-void ccgSubSurf__delete_pending(void)
-{
- OsdDeletePendingItem *entry;
- BLI_assert(BLI_thread_is_main());
- BLI_spin_lock(&delete_spin);
- for (entry = delete_pool.first; entry != NULL; entry = entry->next) {
- if (entry->osd_mesh != NULL) {
- openSubdiv_deleteOsdGLMesh(entry->osd_mesh);
- }
- if (entry->vao != 0) {
- glDeleteVertexArrays(1, &entry->vao);
- }
- }
- BLI_freelistN(&delete_pool);
- BLI_spin_unlock(&delete_spin);
-}
-
-void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs)
-{
- ss->osd_subdiv_uvs = subdiv_uvs;
-}
-
-/* ** Public API ** */
-
-void BKE_subsurf_osd_init(void)
-{
- openSubdiv_init();
- BLI_spin_init(&delete_spin);
-}
-
-void BKE_subsurf_free_unused_buffers(void)
-{
- ccgSubSurf__delete_pending();
-}
-
-void BKE_subsurf_osd_cleanup(void)
-{
- openSubdiv_cleanup();
- ccgSubSurf__delete_pending();
- BLI_spin_end(&delete_spin);
-}
-
-#endif /* WITH_OPENSUBDIV */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
deleted file mode 100644
index 16766d52e57..00000000000
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup bke
- */
-
-#ifdef WITH_OPENSUBDIV
-
-# include <stdlib.h>
-
-# include "BLI_sys_types.h" // for intptr_t support
-# include "MEM_guardedalloc.h"
-
-# include "BLI_math.h"
-# include "BLI_utildefines.h" /* for BLI_assert */
-
-# include "CCGSubSurf.h"
-# include "CCGSubSurf_intern.h"
-
-# include "BKE_DerivedMesh.h"
-# include "BKE_mesh_mapping.h"
-
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-
-/* Use mesh element mapping structures during conversion.
- * Uses more memory but is much faster than naive algorithm.
- */
-# define USE_MESH_ELEMENT_MAPPING
-
-/**
- * Converter from DerivedMesh.
- */
-
-typedef struct ConvDMStorage {
- CCGSubSurf *ss;
- DerivedMesh *dm;
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- MeshElemMap *vert_edge_map, *vert_poly_map, *edge_poly_map;
- int *vert_edge_mem, *vert_poly_mem, *edge_poly_mem;
-# endif
-
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mpoly;
-
- MeshIslandStore island_store;
- int num_uvs;
- float *uvs;
- int *face_uvs;
-} ConvDMStorage;
-
-static OpenSubdiv_SchemeType conv_dm_get_type(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- if (storage->ss->meshIFC.simpleSubdiv) {
- return OSD_SCHEME_BILINEAR;
- }
- else {
- return OSD_SCHEME_CATMARK;
- }
-}
-
-static OpenSubdiv_VtxBoundaryInterpolation conv_dm_get_vtx_boundary_interpolation(
- const OpenSubdiv_Converter *UNUSED(converter))
-{
- return OSD_VTX_BOUNDARY_EDGE_ONLY;
-}
-
-static OpenSubdiv_FVarLinearInterpolation conv_dm_get_fvar_linear_interpolation(
- const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- if (storage->ss->osd_subdiv_uvs) {
- return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
- }
- return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
-}
-
-static bool conv_dm_specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return true;
-}
-
-static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumPolys(dm);
-}
-
-static int conv_dm_get_num_edges(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumEdges(dm);
-}
-
-static int conv_dm_get_num_verts(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumVerts(dm);
-}
-
-static int conv_dm_get_num_face_verts(const OpenSubdiv_Converter *converter, int face)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- return mpoly->totloop;
-}
-
-static void conv_dm_get_face_verts(const OpenSubdiv_Converter *converter,
- int face,
- int *face_verts)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- face_verts[loop] = storage->mloop[mpoly->loopstart + loop].v;
- }
-}
-
-static void conv_dm_get_face_edges(const OpenSubdiv_Converter *converter,
- int face,
- int *face_edges)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- face_edges[loop] = storage->mloop[mpoly->loopstart + loop].e;
- }
-}
-
-static void conv_dm_get_edge_verts(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_verts)
-{
- ConvDMStorage *storage = converter->user_data;
- const MEdge *medge = &storage->medge[edge];
- edge_verts[0] = medge->v1;
- edge_verts[1] = medge->v2;
-}
-
-static int conv_dm_get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->e == edge) {
- num++;
- break;
- }
- }
- }
- return num;
-# else
- return storage->edge_poly_map[edge].count;
-# endif
-}
-
-static void conv_dm_get_edge_faces(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_faces)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->e == edge) {
- edge_faces[num++] = poly;
- break;
- }
- }
- }
-# else
- memcpy(edge_faces,
- storage->edge_poly_map[edge].indices,
- sizeof(int) * storage->edge_poly_map[edge].count);
-# endif
-}
-
-static float conv_dm_get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge)
-{
- ConvDMStorage *storage = converter->user_data;
- CCGSubSurf *ss = storage->ss;
- const MEdge *medge = storage->medge;
- return (float)medge[edge].crease / 255.0f * ss->subdivLevels;
-}
-
-static int conv_dm_get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, edge;
- for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
- const MEdge *medge = &user_data->medge[edge];
- if (medge->v1 == vert || medge->v2 == vert) {
- num++;
- }
- }
- return num;
-# else
- return storage->vert_edge_map[vert].count;
-# endif
-}
-
-static void conv_dm_get_vert_edges(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_edges)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, edge;
- for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
- const MEdge *medge = &user_data->medge[edge];
- if (medge->v1 == vert || medge->v2 == vert) {
- vert_edges[num++] = edge;
- }
- }
-# else
- memcpy(vert_edges,
- storage->vert_edge_map[vert].indices,
- sizeof(int) * storage->vert_edge_map[vert].count);
-# endif
-}
-
-static int conv_dm_get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->v == vert) {
- num++;
- break;
- }
- }
- }
- return num;
-# else
- return storage->vert_poly_map[vert].count;
-# endif
-}
-
-static void conv_dm_get_vert_faces(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_faces)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &storage->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->v == vert) {
- vert_faces[num++] = poly;
- break;
- }
- }
- }
-# else
- memcpy(vert_faces,
- storage->vert_poly_map[vert].indices,
- sizeof(int) * storage->vert_poly_map[vert].count);
-# endif
-}
-
-static bool conv_dm_is_infinite_sharp_vertex(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return false;
-}
-
-static float conv_dm_get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return 0.0f;
-}
-
-static int conv_dm_get_num_uv_layers(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- int num_uv_layers = CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV);
- return num_uv_layers;
-}
-
-static void conv_dm_precalc_uv_layer(const OpenSubdiv_Converter *converter, int layer)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
-
- const MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer);
- const int num_loops = dm->getNumLoops(dm);
-
- /* Initialize memory required for the operations. */
- if (storage->uvs == NULL) {
- storage->uvs = MEM_mallocN(sizeof(float) * 2 * num_loops, "osd uvs");
- }
- if (storage->face_uvs == NULL) {
- storage->face_uvs = MEM_mallocN(sizeof(int) * num_loops, "osd face uvs");
- }
-
- /* Calculate islands connectivity of the UVs. */
- BKE_mesh_calc_islands_loop_poly_uvmap(storage->mvert,
- dm->getNumVerts(dm),
- storage->medge,
- dm->getNumEdges(dm),
- storage->mpoly,
- dm->getNumPolys(dm),
- storage->mloop,
- dm->getNumLoops(dm),
- mloopuv,
- &storage->island_store);
-
- /* Here we "weld" duplicated vertices from island to the same UV value.
- * The idea here is that we need to pass individual islands to OpenSubdiv.
- */
- storage->num_uvs = 0;
- for (int island = 0; island < storage->island_store.islands_num; island++) {
- MeshElemMap *island_poly_map = storage->island_store.islands[island];
- for (int poly = 0; poly < island_poly_map->count; poly++) {
- int poly_index = island_poly_map->indices[poly];
- /* Within the same UV island we should share UV points across
- * loops. Otherwise each poly will be subdivided individually
- * which we don't really want.
- */
- const MPoly *mpoly = &storage->mpoly[poly_index];
- for (int loop = 0; loop < mpoly->totloop; loop++) {
- const MLoopUV *luv = &mloopuv[mpoly->loopstart + loop];
- bool found = false;
- /* TODO(sergey): Quite bad loop, which gives us O(N^2)
- * complexity here. But how can we do it smarter, hopefully
- * without requiring lots of additional memory.
- */
- for (int i = 0; i < storage->num_uvs; i++) {
- if (equals_v2v2(luv->uv, &storage->uvs[2 * i])) {
- storage->face_uvs[mpoly->loopstart + loop] = i;
- found = true;
- break;
- }
- }
- if (!found) {
- copy_v2_v2(&storage->uvs[2 * storage->num_uvs], luv->uv);
- storage->face_uvs[mpoly->loopstart + loop] = storage->num_uvs;
- ++storage->num_uvs;
- }
- }
- }
- }
-}
-
-static void conv_dm_finish_uv_layer(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- BKE_mesh_loop_islands_free(&storage->island_store);
-}
-
-static int conv_dm_get_num_uvs(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- return storage->num_uvs;
-}
-
-static int conv_dm_get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
- int face,
- int corner)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- return storage->face_uvs[mpoly->loopstart + corner];
-}
-
-static void conv_dm_free_user_data(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *user_data = converter->user_data;
- if (user_data->uvs != NULL) {
- MEM_freeN(user_data->uvs);
- }
- if (user_data->face_uvs != NULL) {
- MEM_freeN(user_data->face_uvs);
- }
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- MEM_freeN(user_data->vert_edge_map);
- MEM_freeN(user_data->vert_edge_mem);
- MEM_freeN(user_data->vert_poly_map);
- MEM_freeN(user_data->vert_poly_mem);
- MEM_freeN(user_data->edge_poly_map);
- MEM_freeN(user_data->edge_poly_mem);
-# endif
- MEM_freeN(user_data);
-}
-
-void ccgSubSurf_converter_setup_from_derivedmesh(CCGSubSurf *ss,
- DerivedMesh *dm,
- OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *user_data;
-
- converter->getSchemeType = conv_dm_get_type;
-
- converter->getVtxBoundaryInterpolation = conv_dm_get_vtx_boundary_interpolation;
- converter->getFVarLinearInterpolation = conv_dm_get_fvar_linear_interpolation;
- converter->specifiesFullTopology = conv_dm_specifies_full_topology;
-
- converter->getNumFaces = conv_dm_get_num_faces;
- converter->getNumEdges = conv_dm_get_num_edges;
- converter->getNumVertices = conv_dm_get_num_verts;
-
- converter->getNumFaceVertices = conv_dm_get_num_face_verts;
- converter->getFaceVertices = conv_dm_get_face_verts;
- converter->getFaceEdges = conv_dm_get_face_edges;
-
- converter->getEdgeVertices = conv_dm_get_edge_verts;
- converter->getNumEdgeFaces = conv_dm_get_num_edge_faces;
- converter->getEdgeFaces = conv_dm_get_edge_faces;
- converter->getEdgeSharpness = conv_dm_get_edge_sharpness;
-
- converter->getNumVertexEdges = conv_dm_get_num_vert_edges;
- converter->getVertexEdges = conv_dm_get_vert_edges;
- converter->getNumVertexFaces = conv_dm_get_num_vert_faces;
- converter->getVertexFaces = conv_dm_get_vert_faces;
- converter->isInfiniteSharpVertex = conv_dm_is_infinite_sharp_vertex;
- converter->getVertexSharpness = conv_dm_get_vertex_sharpness;
-
- converter->getNumUVLayers = conv_dm_get_num_uv_layers;
- converter->precalcUVLayer = conv_dm_precalc_uv_layer;
- converter->finishUVLayer = conv_dm_finish_uv_layer;
- converter->getNumUVCoordinates = conv_dm_get_num_uvs;
- converter->getFaceCornerUVIndex = conv_dm_get_face_corner_uv_index;
-
- user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__);
- user_data->ss = ss;
- user_data->dm = dm;
-
- user_data->mvert = dm->getVertArray(dm);
- user_data->medge = dm->getEdgeArray(dm);
- user_data->mloop = dm->getLoopArray(dm);
- user_data->mpoly = dm->getPolyArray(dm);
-
- memset(&user_data->island_store, 0, sizeof(user_data->island_store));
-
- user_data->uvs = NULL;
- user_data->face_uvs = NULL;
-
- converter->freeUserData = conv_dm_free_user_data;
- converter->user_data = user_data;
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- {
- const MEdge *medge = dm->getEdgeArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
- const int num_vert = dm->getNumVerts(dm), num_edge = dm->getNumEdges(dm),
- num_loop = dm->getNumLoops(dm), num_poly = dm->getNumPolys(dm);
- BKE_mesh_vert_edge_map_create(
- &user_data->vert_edge_map, &user_data->vert_edge_mem, medge, num_vert, num_edge);
-
- BKE_mesh_vert_poly_map_create(&user_data->vert_poly_map,
- &user_data->vert_poly_mem,
- mpoly,
- mloop,
- num_vert,
- num_poly,
- num_loop);
-
- BKE_mesh_edge_poly_map_create(&user_data->edge_poly_map,
- &user_data->edge_poly_mem,
- medge,
- num_edge,
- mpoly,
- num_poly,
- mloop,
- num_loop);
- }
-# endif /* USE_MESH_ELEMENT_MAPPING */
-}
-
-/**
- * Converter from CCGSubSurf
- */
-
-static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- if (ss->meshIFC.simpleSubdiv) {
- return OSD_SCHEME_BILINEAR;
- }
- else {
- return OSD_SCHEME_CATMARK;
- }
-}
-
-static OpenSubdiv_VtxBoundaryInterpolation conv_ccg_get_vtx_boundary_interpolation(
- const OpenSubdiv_Converter *UNUSED(converter))
-{
- return OSD_VTX_BOUNDARY_EDGE_ONLY;
-}
-
-static OpenSubdiv_FVarLinearInterpolation conv_ccg_get_fvar_linear_interpolation(
- const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- if (ss->osd_subdiv_uvs) {
- return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
- }
- return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
-}
-
-static bool conv_ccg_specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return true;
-}
-
-static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->fMap->numEntries;
-}
-
-static int conv_ccg_get_num_edges(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->eMap->numEntries;
-}
-
-static int conv_ccg_get_num_verts(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->vMap->numEntries;
-}
-
-static int conv_ccg_get_num_face_verts(const OpenSubdiv_Converter *converter, int face)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- return ccgSubSurf_getFaceNumVerts(ccg_face);
-}
-
-static void conv_ccg_get_face_verts(const OpenSubdiv_Converter *converter,
- int face,
- int *face_verts)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
- int loop;
- for (loop = 0; loop < num_face_verts; loop++) {
- CCGVert *ccg_vert = ccgSubSurf_getFaceVert(ccg_face, loop);
- face_verts[loop] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert));
- }
-}
-
-static void conv_ccg_get_face_edges(const OpenSubdiv_Converter *converter,
- int face,
- int *face_edges)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
- int loop;
- for (loop = 0; loop < num_face_verts; loop++) {
- CCGEdge *ccg_edge = ccgSubSurf_getFaceEdge(ccg_face, loop);
- face_edges[loop] = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- }
-}
-
-static void conv_ccg_get_edge_verts(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_verts)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- CCGVert *ccg_vert0 = ccgSubSurf_getEdgeVert0(ccg_edge);
- CCGVert *ccg_vert1 = ccgSubSurf_getEdgeVert1(ccg_edge);
- edge_verts[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert0));
- edge_verts[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert1));
-}
-
-static int conv_ccg_get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- return ccgSubSurf_getEdgeNumFaces(ccg_edge);
-}
-
-static void conv_ccg_get_edge_faces(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_faces)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- int num_edge_faces = ccgSubSurf_getEdgeNumFaces(ccg_edge);
- int face;
- for (face = 0; face < num_edge_faces; face++) {
- CCGFace *ccg_face = ccgSubSurf_getEdgeFace(ccg_edge, face);
- edge_faces[face] = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- }
-}
-
-static float conv_ccg_get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- /* TODO(sergey): Multiply by subdivision level once CPU evaluator
- * is switched to uniform subdivision type.
- */
- return ccg_edge->crease;
-}
-
-static int conv_ccg_get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- return ccgSubSurf_getVertNumEdges(ccg_vert);
-}
-
-static void conv_ccg_get_vert_edges(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_edges)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- int num_vert_edges = ccgSubSurf_getVertNumEdges(ccg_vert);
- int edge;
- for (edge = 0; edge < num_vert_edges; edge++) {
- CCGEdge *ccg_edge = ccgSubSurf_getVertEdge(ccg_vert, edge);
- vert_edges[edge] = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- }
-}
-
-static int conv_ccg_get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- return ccgSubSurf_getVertNumFaces(ccg_vert);
-}
-
-static void conv_ccg_get_vert_faces(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_faces)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- int num_vert_faces = ccgSubSurf_getVertNumFaces(ccg_vert);
- int face;
- for (face = 0; face < num_vert_faces; face++) {
- CCGFace *ccg_face = ccgSubSurf_getVertFace(ccg_vert, face);
- vert_faces[face] = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- }
-}
-
-static bool conv_ccg_is_infinite_sharp_vertex(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return false;
-}
-
-static float conv_ccg_get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return 0.0f;
-}
-
-static int conv_ccg_get_num_uv_layers(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return 0;
-}
-
-static void conv_ccg_precalc_uv_layer(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(layer))
-{
-}
-
-static void conv_ccg_finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter))
-{
-}
-
-static int conv_ccg_get_num_uvs(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return 0;
-}
-
-static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(face),
- int UNUSED(corner_))
-{
- return 0;
-}
-
-void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, OpenSubdiv_Converter *converter)
-{
- converter->getSchemeType = conv_ccg_get_bilinear_type;
-
- converter->getVtxBoundaryInterpolation = conv_ccg_get_vtx_boundary_interpolation;
- converter->getFVarLinearInterpolation = conv_ccg_get_fvar_linear_interpolation;
- converter->specifiesFullTopology = conv_ccg_specifies_full_topology;
-
- converter->getNumFaces = conv_ccg_get_num_faces;
- converter->getNumEdges = conv_ccg_get_num_edges;
- converter->getNumVertices = conv_ccg_get_num_verts;
-
- converter->getNumFaceVertices = conv_ccg_get_num_face_verts;
- converter->getFaceVertices = conv_ccg_get_face_verts;
- converter->getFaceEdges = conv_ccg_get_face_edges;
-
- converter->getEdgeVertices = conv_ccg_get_edge_verts;
- converter->getNumEdgeFaces = conv_ccg_get_num_edge_faces;
- converter->getEdgeFaces = conv_ccg_get_edge_faces;
- converter->getEdgeSharpness = conv_ccg_get_edge_sharpness;
-
- converter->getNumVertexEdges = conv_ccg_get_num_vert_edges;
- converter->getVertexEdges = conv_ccg_get_vert_edges;
- converter->getNumVertexFaces = conv_ccg_get_num_vert_faces;
- converter->getVertexFaces = conv_ccg_get_vert_faces;
- converter->isInfiniteSharpVertex = conv_ccg_is_infinite_sharp_vertex;
- converter->getVertexSharpness = conv_ccg_get_vertex_sharpness;
-
- converter->getNumUVLayers = conv_ccg_get_num_uv_layers;
- converter->precalcUVLayer = conv_ccg_precalc_uv_layer;
- converter->finishUVLayer = conv_ccg_finish_uv_layer;
- converter->getNumUVCoordinates = conv_ccg_get_num_uvs;
- converter->getFaceCornerUVIndex = conv_ccg_get_face_corner_uv_index;
-
- converter->freeUserData = NULL;
- converter->user_data = ss;
-}
-
-void ccgSubSurf_converter_free(struct OpenSubdiv_Converter *converter)
-{
- if (converter->freeUserData) {
- converter->freeUserData(converter);
- }
-}
-
-#endif /* WITH_OPENSUBDIV */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b3893d8600f..52fe51afcb2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1798,9 +1798,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
}
}
- if (mesh_eval != NULL) {
- mesh_runtime_check_normals_valid(mesh_eval);
- }
+ mesh_runtime_check_normals_valid(mesh_eval);
mesh_build_extra_data(depsgraph, ob, mesh_eval);
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 4f51e23496c..bd39ffc65e7 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -52,6 +52,7 @@
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -154,6 +155,15 @@ static void action_free_data(struct ID *id)
BLI_freelistN(&action->markers);
}
+static void action_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ bAction *act = (bAction *)id;
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
+ BKE_LIB_FOREACHID_PROCESS(data, marker->camera, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_AC = {
.id_code = ID_AC,
.id_filter = FILTER_ID_AC,
@@ -168,6 +178,7 @@ IDTypeInfo IDType_ID_AC = {
.copy_data = action_copy_data,
.free_data = action_free_data,
.make_local = NULL,
+ .foreach_id = action_foreach_id,
};
/* ***************** Library data level operations on action ************** */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 06a97fc3826..36921bd2662 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -67,6 +67,7 @@
#include "BKE_scene.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "BIK_api.h"
@@ -500,14 +501,21 @@ static void armature_refresh_layer_used_recursive(bArmature *arm, ListBase *bone
}
}
-/* Update the layers_used variable after bones are moved between layer
- * NOTE: Used to be done in drawing code in 2.7, but that won't work with
- * Copy-on-Write, as drawing uses evaluated copies.
- */
-void BKE_armature_refresh_layer_used(bArmature *arm)
+void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm)
{
+ if (arm->edbo != NULL) {
+ /* Don't perform this update when the armature is in edit mode. In that case it should be
+ * handled by ED_armature_edit_refresh_layer_used(). */
+ return;
+ }
+
arm->layer_used = 0;
armature_refresh_layer_used_recursive(arm, &arm->bonebase);
+
+ if (depsgraph == NULL || DEG_is_active(depsgraph)) {
+ bArmature *arm_orig = (bArmature *)DEG_get_original_id(&arm->id);
+ arm_orig->layer_used = arm->layer_used;
+ }
}
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index c21dec16555..133917e441c 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1063,14 +1063,20 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
}
}
-static Brush *gpencil_brush_ensure(Main *bmain,
- ToolSettings *ts,
- const char *brush_name,
- eObjectMode mode)
+static Brush *gpencil_brush_ensure(
+ Main *bmain, ToolSettings *ts, const char *brush_name, eObjectMode mode, bool *r_new)
{
+ *r_new = false;
Brush *brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+
+ /* If the brush exist, but the type is not GPencil or the mode is wrong, create a new one. */
+ if ((brush != NULL) && ((brush->gpencil_settings == NULL) || (brush->ob_mode != mode))) {
+ brush = NULL;
+ }
+
if (brush == NULL) {
brush = BKE_brush_add_gpencil(bmain, ts, brush_name, mode);
+ *r_new = true;
}
if (brush->gpencil_settings == NULL) {
@@ -1081,164 +1087,235 @@ static Brush *gpencil_brush_ensure(Main *bmain,
}
/* Create a set of grease pencil Drawing presets. */
-void BKE_brush_gpencil_paint_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_paint_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
+ bool r_new = false;
Paint *paint = &ts->gp_paint->paint;
-
+ Brush *brush_prev = paint->brush;
Brush *brush, *deft_draw;
/* Airbrush brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Airbrush", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_AIRBRUSH);
+ brush = gpencil_brush_ensure(bmain, ts, "Airbrush", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_AIRBRUSH);
+ }
/* Ink Pen brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Ink Pen", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN);
+ brush = gpencil_brush_ensure(bmain, ts, "Ink Pen", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN);
+ }
/* Ink Pen Rough brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Ink Pen Rough", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN_ROUGH);
+ brush = gpencil_brush_ensure(bmain, ts, "Ink Pen Rough", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN_ROUGH);
+ }
/* Marker Bold brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Marker Bold", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_BOLD);
+ brush = gpencil_brush_ensure(bmain, ts, "Marker Bold", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_BOLD);
+ }
/* Marker Chisel brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Marker Chisel", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_CHISEL);
+ brush = gpencil_brush_ensure(bmain, ts, "Marker Chisel", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_CHISEL);
+ }
/* Pen brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pen", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PEN);
+ brush = gpencil_brush_ensure(bmain, ts, "Pen", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PEN);
+ }
/* Pencil Soft brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pencil Soft", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL_SOFT);
+ brush = gpencil_brush_ensure(bmain, ts, "Pencil Soft", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL_SOFT);
+ }
/* Pencil brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pencil", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL);
+ brush = gpencil_brush_ensure(bmain, ts, "Pencil", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL);
+ }
deft_draw = brush; /* save default brush. */
/* Fill brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Fill Area", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_FILL_AREA);
+ brush = gpencil_brush_ensure(bmain, ts, "Fill Area", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_FILL_AREA);
+ }
/* Soft Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Soft", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_SOFT);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Soft", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_SOFT);
+ }
/* Hard Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Hard", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_HARD);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Hard", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_HARD);
+ }
/* Point Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Point", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_POINT);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Point", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_POINT);
+ }
/* Stroke Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Stroke", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Stroke", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_STROKE);
+ }
/* Tint brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Tint", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TINT);
+ brush = gpencil_brush_ensure(bmain, ts, "Tint", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TINT);
+ }
/* Set default Draw brush. */
- BKE_paint_brush_set(paint, deft_draw);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(paint, deft_draw);
+ }
}
/* Create a set of grease pencil Vertex Paint presets. */
-void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
- Paint *vertexpaint = &ts->gp_vertexpaint->paint;
+ bool r_new = false;
+ Paint *vertexpaint = &ts->gp_vertexpaint->paint;
+ Brush *brush_prev = vertexpaint->brush;
Brush *brush, *deft_vertex;
/* Vertex Draw brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Draw", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_DRAW);
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Draw", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_DRAW);
+ }
deft_vertex = brush; /* save default brush. */
/* Vertex Blur brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Blur", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_BLUR);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Blur", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_BLUR);
+ }
/* Vertex Average brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Average", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_AVERAGE);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Average", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_AVERAGE);
+ }
/* Vertex Smear brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Smear", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_SMEAR);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Smear", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_SMEAR);
+ }
/* Vertex Replace brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Replace", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_REPLACE);
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Replace", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_REPLACE);
+ }
/* Set default Vertex brush. */
- BKE_paint_brush_set(vertexpaint, deft_vertex);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(vertexpaint, deft_vertex);
+ }
}
/* Create a set of grease pencil Sculpt Paint presets. */
-void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
+ bool r_new = false;
+
Paint *sculptpaint = &ts->gp_sculptpaint->paint;
+ Brush *brush_prev = sculptpaint->brush;
Brush *brush, *deft_sculpt;
/* Smooth brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Smooth Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_SMOOTH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Smooth Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_SMOOTH_STROKE);
+ }
deft_sculpt = brush;
/* Strength brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Strength Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_STRENGTH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Strength Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_STRENGTH_STROKE);
+ }
/* Thickness brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Thickness Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_THICKNESS_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Thickness Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_THICKNESS_STROKE);
+ }
/* Grab brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Grab Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_GRAB_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Grab Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_GRAB_STROKE);
+ }
/* Push brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Push Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PUSH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Push Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PUSH_STROKE);
+ }
/* Twist brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Twist Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TWIST_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Twist Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TWIST_STROKE);
+ }
/* Pinch brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pinch Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PINCH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Pinch Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PINCH_STROKE);
+ }
/* Randomize brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Randomize Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_RANDOMIZE_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Randomize Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_RANDOMIZE_STROKE);
+ }
/* Clone brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Clone Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_CLONE_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Clone Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_CLONE_STROKE);
+ }
/* Set default brush. */
- BKE_paint_brush_set(sculptpaint, deft_sculpt);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(sculptpaint, deft_sculpt);
+ }
}
/* Create a set of grease pencil Weight Paint presets. */
-void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
- Paint *weightpaint = &ts->gp_weightpaint->paint;
+ bool r_new = false;
+ Paint *weightpaint = &ts->gp_weightpaint->paint;
+ Brush *brush_prev = weightpaint->brush;
Brush *brush, *deft_weight;
/* Vertex Draw brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Draw Weight", OB_MODE_WEIGHT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_DRAW_WEIGHT);
+ brush = gpencil_brush_ensure(bmain, ts, "Draw Weight", OB_MODE_WEIGHT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_DRAW_WEIGHT);
+ }
deft_weight = brush; /* save default brush. */
/* Set default brush. */
- BKE_paint_brush_set(weightpaint, deft_weight);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(weightpaint, deft_weight);
+ }
}
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index d23b643ce70..da9dab36044 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -97,6 +97,7 @@ IDTypeInfo IDType_ID_CF = {
.copy_data = cache_file_copy_data,
.free_data = cache_file_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* TODO: make this per cache file to avoid global locks. */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 583bb39a851..c1d77fd5f9e 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -34,6 +34,7 @@
#include "BKE_idtype.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -128,6 +129,28 @@ static void collection_free_data(ID *id)
BKE_collection_object_cache_free(collection);
}
+static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Collection *collection = (Collection *)id;
+
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
+ BKE_LIB_FOREACHID_PROCESS(data, cob->ob, IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
+ BKE_LIB_FOREACHID_PROCESS(data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
+ /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
+ * anyway... */
+ const int cb_flag = ((parent->collection != NULL &&
+ (parent->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
+ IDWALK_CB_EMBEDDED :
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(
+ data, parent->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_LOOPBACK | cb_flag);
+ }
+}
+
IDTypeInfo IDType_ID_GR = {
.id_code = ID_GR,
.id_filter = FILTER_ID_GR,
@@ -142,6 +165,7 @@ IDTypeInfo IDType_ID_GR = {
.copy_data = collection_copy_data,
.free_data = collection_free_data,
.make_local = NULL,
+ .foreach_id = collection_foreach_id,
};
/***************************** Add Collection *******************************/
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 72197869f58..0798bc95797 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -4169,7 +4169,8 @@ void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
*/
void BKE_nurb_bezt_handle_test(BezTriple *bezt,
const eBezTriple_Flag__Alias sel_flag,
- const bool use_handle)
+ const bool use_handle,
+ const bool use_around_local)
{
short flag = 0;
@@ -4192,6 +4193,10 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
}
+ if (use_around_local) {
+ flag &= ~SEL_F2;
+ }
+
/* check for partial selection */
if (!ELEM(flag, 0, SEL_F1 | SEL_F2 | SEL_F3)) {
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
@@ -4218,7 +4223,7 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
#undef SEL_F3
}
-void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
+void BKE_nurb_handles_test(Nurb *nu, const bool use_handle, const bool use_around_local)
{
BezTriple *bezt;
int a;
@@ -4230,7 +4235,7 @@ void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle);
+ BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle, use_around_local);
bezt++;
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 8c47401cbc3..a022f3f5d14 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -699,6 +699,24 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int
return size;
}
+static void layerInterp_paint_mask(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ float mask = 0.0f;
+ const float *sub_weight = sub_weights;
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const float *src = sources[i];
+ if (sub_weights) {
+ mask += (*src) * (*sub_weight) * weight;
+ sub_weight++;
+ }
+ else {
+ mask += (*src) * weight;
+ }
+ }
+ *(float *)dest = mask;
+}
static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
{
@@ -1595,7 +1613,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* END BMESH ONLY */
/* 34: CD_PAINT_MASK */
- {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float), "", 0, NULL, NULL, NULL, layerInterp_paint_mask, NULL, NULL},
/* 35: CD_GRID_PAINT_MASK */
{sizeof(GridPaintMask),
"GridPaintMask",
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index d73f92b6073..a3e1eeb89c7 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1134,17 +1134,18 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
if (r_final) {
if (force_mesh_conversion && !modified) {
- /* XXX 2.8 : This is a workaround for by some deeper technical depts:
+ /* XXX 2.8 : This is a workaround for by some deeper technical debts:
* - DRW Batch cache is stored inside the ob->data.
* - Curve data is not COWed for instances that use different modifiers.
- * This can causes the modifiers to be applied on all user of the same datablock (see T71055)
+ * This can causes the modifiers to be applied on all user of the same data-block
+ * (see T71055)
*
* The easy workaround is to force to generate a Mesh that will be used for display data
* since a Mesh output is already used for generative modifiers.
* However it does not fix problems with actual edit data still being shared.
*
- * The right solution would be to COW the Curve data block at the input of the modifer stack
- * just like what the mesh modifier does.
+ * The right solution would be to COW the Curve data block at the input of the modifier
+ * stack just like what the mesh modifier does.
* */
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 79d9a40f06b..f3cc17f46f6 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -4646,9 +4646,6 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
return 1;
}
- /* begin thread safe malloc */
- BLI_threaded_malloc_begin();
-
/* only continue if particle bb is close enough to canvas bb */
if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) {
int c_index;
@@ -4684,7 +4681,6 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
&settings);
}
}
- BLI_threaded_malloc_end();
BLI_kdtree_3d_free(tree);
return 1;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 543d5c8b7c7..5d2207b5b80 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1147,7 +1147,7 @@ void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_ha
/* loop over beztriples */
for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
- BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle);
+ BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle, false);
}
/* recalculate handles */
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index fddc6b5e0ee..b75592836e0 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -3306,6 +3306,16 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *mds, Mesh *orgmesh, Obj
/* Biggest dimension will be used for upscaling. */
float max_size = MAX3(size[0], size[1], size[2]);
+ float co_scale[3];
+ co_scale[0] = max_size / ob->scale[0];
+ co_scale[1] = max_size / ob->scale[1];
+ co_scale[2] = max_size / ob->scale[2];
+
+ float co_offset[3];
+ co_offset[0] = (mds->p0[0] + mds->p1[0]) / 2.0f;
+ co_offset[1] = (mds->p0[1] + mds->p1[1]) / 2.0f;
+ co_offset[2] = (mds->p0[2] + mds->p1[2]) / 2.0f;
+
/* Normals. */
normals = MEM_callocN(sizeof(short) * num_normals * 3, "Fluidmesh_tmp_normals");
@@ -3329,9 +3339,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *mds, Mesh *orgmesh, Obj
mverts->co[2] *= mds->dx / mds->mesh_scale;
}
- mverts->co[0] *= max_size / fabsf(ob->scale[0]);
- mverts->co[1] *= max_size / fabsf(ob->scale[1]);
- mverts->co[2] *= max_size / fabsf(ob->scale[2]);
+ mul_v3_v3(mverts->co, co_scale);
+ add_v3_v3(mverts->co, co_offset);
+
# ifdef DEBUG_PRINT
/* Debugging: Print coordinates of vertices. */
printf("mverts->co[0]: %f, mverts->co[1]: %f, mverts->co[2]: %f\n",
@@ -3977,9 +3987,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
}
}
if (!baking_data && !baking_noise && next_data && next_noise) {
- /* TODO (sebbas): Confirm if this read call is really needed or not.
- * Currently only important to load the shadow grid. */
- has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame);
+ /* Nothing to do here since we already loaded noise grids. */
}
else {
has_data = manta_read_data(mds->fluid, mmd, data_frame);
@@ -4380,8 +4388,8 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *mds, ViewLayer *v
}
}
-/* get smoke velocity and density at given coordinates
- * returns fluid density or -1.0f if outside domain. */
+/* Get fluid velocity and density at given coordinates
+ * Returns fluid density or -1.0f if outside domain. */
float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3])
{
FluidModifierData *mmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
@@ -4390,16 +4398,15 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
if (mmd && (mmd->type & MOD_FLUID_TYPE_DOMAIN) && mmd->domain && mmd->domain->fluid) {
FluidDomainSettings *mds = mmd->domain;
float time_mult = 25.f * DT_DEFAULT;
+ float size_mult = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]) /
+ mds->maxres;
float vel_mag;
- float *velX = manta_get_velocity_x(mds->fluid);
- float *velY = manta_get_velocity_y(mds->fluid);
- float *velZ = manta_get_velocity_z(mds->fluid);
float density = 0.0f, fuel = 0.0f;
float pos[3];
copy_v3_v3(pos, position);
manta_pos_to_cell(mds, pos);
- /* check if point is outside domain max bounds */
+ /* Check if position is outside domain max bounds. */
if (pos[0] < mds->res_min[0] || pos[1] < mds->res_min[1] || pos[2] < mds->res_min[2]) {
return -1.0f;
}
@@ -4412,9 +4419,8 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
pos[1] = (pos[1] - mds->res_min[1]) / ((float)mds->res[1]);
pos[2] = (pos[2] - mds->res_min[2]) / ((float)mds->res[2]);
- /* check if point is outside active area */
- if (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS &&
- mmd->domain->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
+ /* Check if position is outside active area. */
+ if (mds->type == FLUID_DOMAIN_TYPE_GAS && mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) {
return 0.0f;
}
@@ -4423,21 +4429,22 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
}
}
- /* get interpolated velocity */
- velocity[0] = BLI_voxel_sample_trilinear(velX, mds->res, pos) * mds->global_size[0] *
- time_mult;
- velocity[1] = BLI_voxel_sample_trilinear(velY, mds->res, pos) * mds->global_size[1] *
- time_mult;
- velocity[2] = BLI_voxel_sample_trilinear(velZ, mds->res, pos) * mds->global_size[2] *
- time_mult;
+ /* Get interpolated velocity at given position. */
+ velocity[0] = BLI_voxel_sample_trilinear(manta_get_velocity_x(mds->fluid), mds->res, pos);
+ velocity[1] = BLI_voxel_sample_trilinear(manta_get_velocity_y(mds->fluid), mds->res, pos);
+ velocity[2] = BLI_voxel_sample_trilinear(manta_get_velocity_z(mds->fluid), mds->res, pos);
+
+ /* Convert simulation units to Blender units. */
+ mul_v3_fl(velocity, size_mult);
+ mul_v3_fl(velocity, time_mult);
- /* convert velocity direction to global space */
+ /* Convert velocity direction to global space. */
vel_mag = len_v3(velocity);
mul_mat3_m4_v3(mds->obmat, velocity);
normalize_v3(velocity);
mul_v3_fl(velocity, vel_mag);
- /* use max value of fuel or smoke density */
+ /* Use max value of fuel or smoke density. */
density = BLI_voxel_sample_trilinear(manta_smoke_get_density(mds->fluid), mds->res, pos);
if (manta_smoke_has_fuel(mds->fluid)) {
fuel = BLI_voxel_sample_trilinear(manta_smoke_get_fuel(mds->fluid), mds->res, pos);
@@ -4922,7 +4929,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *mmd)
/* cache options */
mmd->domain->cache_frame_start = 1;
- mmd->domain->cache_frame_end = 50;
+ mmd->domain->cache_frame_end = 250;
mmd->domain->cache_frame_pause_data = 0;
mmd->domain->cache_frame_pause_noise = 0;
mmd->domain->cache_frame_pause_mesh = 0;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 92eb6ea03e2..54f2492af93 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -134,6 +134,7 @@ IDTypeInfo IDType_ID_VF = {
.copy_data = vfont_copy_data,
.free_data = vfont_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/***************************** VFont *******************************/
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 041ef0503b9..4311e425abf 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -55,6 +55,7 @@
#include "BKE_idtype.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_paint.h"
@@ -97,6 +98,19 @@ static void greasepencil_free_data(ID *id)
BKE_gpencil_free((bGPdata *)id, true);
}
+static void greasepencil_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ bGPdata *gpencil = (bGPdata *)id;
+ /* materials */
+ for (int i = 0; i < gpencil->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, gpencil->mat[i], IDWALK_CB_USER);
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gplayer, &gpencil->layers) {
+ BKE_LIB_FOREACHID_PROCESS(data, gplayer->parent, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_GD = {
.id_code = ID_GD,
.id_filter = FILTER_ID_GD,
@@ -111,6 +125,7 @@ IDTypeInfo IDType_ID_GD = {
.copy_data = greasepencil_copy_data,
.free_data = greasepencil_free_data,
.make_local = NULL,
+ .foreach_id = greasepencil_foreach_id,
};
/* ************************************************** */
@@ -1748,7 +1763,18 @@ void BKE_gpencil_palette_ensure(Main *bmain, Scene *scene)
GpPaint *gp_paint = ts->gp_paint;
Paint *paint = &gp_paint->paint;
+ if (paint->palette != NULL) {
+ return;
+ }
+
paint->palette = BLI_findstring(&bmain->palettes, "Palette", offsetof(ID, name) + 2);
+ /* Try with first palette. */
+ if (bmain->palettes.first != NULL) {
+ paint->palette = bmain->palettes.first;
+ ts->gp_vertexpaint->paint.palette = paint->palette;
+ return;
+ }
+
if (paint->palette == NULL) {
paint->palette = BKE_palette_add(bmain, "Palette");
ts->gp_vertexpaint->paint.palette = paint->palette;
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 808c0347a37..90761d24b73 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -22,6 +22,7 @@
#include "DNA_defaults.h"
#include "DNA_hair_types.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "BLI_listbase.h"
@@ -48,50 +49,7 @@
/* Hair datablock */
-static void hair_random(Hair *hair)
-{
- const int numpoints = 8;
-
- hair->totcurve = 500;
- hair->totpoint = hair->totcurve * numpoints;
-
- CustomData_realloc(&hair->pdata, hair->totpoint);
- CustomData_realloc(&hair->cdata, hair->totcurve);
- BKE_hair_update_customdata_pointers(hair);
-
- RNG *rng = BLI_rng_new(0);
-
- for (int i = 0; i < hair->totcurve; i++) {
- HairCurve *curve = &hair->curves[i];
- curve->firstpoint = i * numpoints;
- curve->numpoints = numpoints;
-
- float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
- float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
-
- float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
- normalize_v3(no);
-
- float co[3];
- copy_v3_v3(co, no);
-
- float(*curve_co)[3] = hair->co + curve->firstpoint;
- float *curve_radius = hair->radius + curve->firstpoint;
- for (int key = 0; key < numpoints; key++) {
- float t = key / (float)(numpoints - 1);
- copy_v3_v3(curve_co[key], co);
- curve_radius[key] = 0.02f * (1.0f - t);
-
- float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f};
- add_v3_v3(offset, no);
- madd_v3_v3fl(co, offset, 1.0f / numpoints);
- }
- }
-
- BLI_rng_free(rng);
-}
+static void hair_random(Hair *hair);
static void hair_init_data(ID *id)
{
@@ -111,15 +69,6 @@ static void hair_init_data(ID *id)
hair_random(hair);
}
-void *BKE_hair_add(Main *bmain, const char *name)
-{
- Hair *hair = BKE_libblock_alloc(bmain, ID_HA, name, 0);
-
- hair_init_data(&hair->id);
-
- return hair;
-}
-
static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
Hair *hair_dst = (Hair *)id_dst;
@@ -134,18 +83,6 @@ static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, co
hair_dst->batch_cache = NULL;
}
-Hair *BKE_hair_copy(Main *bmain, const Hair *hair)
-{
- Hair *hair_copy;
- BKE_id_copy(bmain, &hair->id, (ID **)&hair_copy);
- return hair_copy;
-}
-
-static void hair_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void hair_free_data(ID *id)
{
Hair *hair = (Hair *)id;
@@ -159,6 +96,14 @@ static void hair_free_data(ID *id)
MEM_SAFE_FREE(hair->mat);
}
+static void hair_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Hair *hair = (Hair *)id;
+ for (int i = 0; i < hair->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, hair->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_HA = {
.id_code = ID_HA,
.id_filter = FILTER_ID_HA,
@@ -172,9 +117,71 @@ IDTypeInfo IDType_ID_HA = {
.init_data = hair_init_data,
.copy_data = hair_copy_data,
.free_data = hair_free_data,
- .make_local = hair_make_local,
+ .make_local = NULL,
+ .foreach_id = hair_foreach_id,
};
+static void hair_random(Hair *hair)
+{
+ const int numpoints = 8;
+
+ hair->totcurve = 500;
+ hair->totpoint = hair->totcurve * numpoints;
+
+ CustomData_realloc(&hair->pdata, hair->totpoint);
+ CustomData_realloc(&hair->cdata, hair->totcurve);
+ BKE_hair_update_customdata_pointers(hair);
+
+ RNG *rng = BLI_rng_new(0);
+
+ for (int i = 0; i < hair->totcurve; i++) {
+ HairCurve *curve = &hair->curves[i];
+ curve->firstpoint = i * numpoints;
+ curve->numpoints = numpoints;
+
+ float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
+ float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
+
+ float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
+ normalize_v3(no);
+
+ float co[3];
+ copy_v3_v3(co, no);
+
+ float(*curve_co)[3] = hair->co + curve->firstpoint;
+ float *curve_radius = hair->radius + curve->firstpoint;
+ for (int key = 0; key < numpoints; key++) {
+ float t = key / (float)(numpoints - 1);
+ copy_v3_v3(curve_co[key], co);
+ curve_radius[key] = 0.02f * (1.0f - t);
+
+ float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
+ 2.0f * BLI_rng_get_float(rng) - 1.0f,
+ 2.0f * BLI_rng_get_float(rng) - 1.0f};
+ add_v3_v3(offset, no);
+ madd_v3_v3fl(co, offset, 1.0f / numpoints);
+ }
+ }
+
+ BLI_rng_free(rng);
+}
+
+void *BKE_hair_add(Main *bmain, const char *name)
+{
+ Hair *hair = BKE_libblock_alloc(bmain, ID_HA, name, 0);
+
+ hair_init_data(&hair->id);
+
+ return hair;
+}
+
+Hair *BKE_hair_copy(Main *bmain, const Hair *hair)
+{
+ Hair *hair_copy;
+ BKE_id_copy(bmain, &hair->id, (ID **)&hair_copy);
+ return hair_copy;
+}
+
BoundBox *BKE_hair_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_HAIR);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 56cdce05d57..b4a3f249c63 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -199,6 +199,7 @@ IDTypeInfo IDType_ID_IM = {
.copy_data = image_copy_data,
.free_data = image_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* prototypes */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 12c1cf6bafa..780c3c2f14a 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -123,6 +123,7 @@ IDTypeInfo IDType_ID_IP = {
.copy_data = NULL,
.free_data = ipo_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* *************************************************** */
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index d922c5dd24c..015fa235a06 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -79,64 +79,12 @@
#include "BKE_node.h"
#include "BKE_particle.h"
#include "BKE_rigidbody.h"
+#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_texture.h"
#include "BKE_workspace.h"
-#define FOREACH_FINALIZE _finalize
-#define FOREACH_FINALIZE_VOID \
- if (0) { \
- goto FOREACH_FINALIZE; \
- } \
- FOREACH_FINALIZE: \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, _cb_flag) \
- CHECK_TYPE(id_pp, ID **); \
- if (!((_data)->status & IDWALK_STOP)) { \
- const int _flag = (_data)->flag; \
- ID *old_id = *(id_pp); \
- const int callback_return = (_data)->callback(&(struct LibraryIDLinkCallbackData){ \
- .user_data = (_data)->user_data, \
- .id_owner = (_data)->owner_id, \
- .id_self = (_data)->self_id, \
- .id_pointer = id_pp, \
- .cb_flag = ((_cb_flag | (_data)->cb_flag) & ~(_data)->cb_flag_clear)}); \
- if (_flag & IDWALK_READONLY) { \
- BLI_assert(*(id_pp) == old_id); \
- } \
- if (old_id && (_flag & IDWALK_RECURSE)) { \
- if (BLI_gset_add((_data)->ids_handled, old_id)) { \
- if (!(callback_return & IDWALK_RET_STOP_RECURSION)) { \
- BLI_LINKSTACK_PUSH((_data)->ids_todo, old_id); \
- } \
- } \
- } \
- if (callback_return & IDWALK_RET_STOP_ITER) { \
- (_data)->status |= IDWALK_STOP; \
- goto FOREACH_FINALIZE; \
- } \
- } \
- else { \
- goto FOREACH_FINALIZE; \
- } \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE_ID(_data, id, cb_flag) \
- { \
- CHECK_TYPE_ANY(id, ID *, void *); \
- FOREACH_CALLBACK_INVOKE_ID_PP(_data, (ID **)&(id), cb_flag); \
- } \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE(_data, id_super, cb_flag) \
- { \
- CHECK_TYPE(&((id_super)->id), ID *); \
- FOREACH_CALLBACK_INVOKE_ID_PP(_data, (ID **)&(id_super), cb_flag); \
- } \
- ((void)0)
-
/* status */
enum {
IDWALK_STOP = 1 << 0,
@@ -199,6 +147,25 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int
}
}
+int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
+{
+ return data->flag;
+}
+
+int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data,
+ const int cb_flag,
+ const bool do_replace)
+{
+ const int cb_flag_backup = data->cb_flag;
+ if (do_replace) {
+ data->cb_flag = cb_flag;
+ }
+ else {
+ data->cb_flag |= cb_flag;
+ }
+ return cb_flag_backup;
+}
+
static void library_foreach_ID_link(Main *bmain,
ID *id_owner,
ID *id,
@@ -215,82 +182,13 @@ void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void
BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
}
-static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
- ID **id_pointer,
- void *user_data,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_shaderfxForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
- ID **id_pointer,
- bool is_reference,
- void *user_data)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
- ID **id_pointer,
- void *user_data,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
static void library_foreach_nla_strip(LibraryForeachIDData *data, NlaStrip *strip)
{
- FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, strip->act, IDWALK_CB_USER);
LISTBASE_FOREACH (NlaStrip *, substrip, &strip->strips) {
library_foreach_nla_strip(data, substrip);
}
-
- FOREACH_FINALIZE_VOID;
}
static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
@@ -301,215 +199,20 @@ static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
/* only used targets */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- FOREACH_CALLBACK_INVOKE_ID(data, dtar->id, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, dtar->id, IDWALK_CB_NOP);
}
DRIVER_TARGETS_LOOPER_END;
}
}
- FOREACH_CALLBACK_INVOKE(data, adt->action, IDWALK_CB_USER);
- FOREACH_CALLBACK_INVOKE(data, adt->tmpact, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, adt->action, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, adt->tmpact, IDWALK_CB_USER);
LISTBASE_FOREACH (NlaTrack *, nla_track, &adt->nla_tracks) {
LISTBASE_FOREACH (NlaStrip *, nla_strip, &nla_track->strips) {
library_foreach_nla_strip(data, nla_strip);
}
}
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
-{
- FOREACH_CALLBACK_INVOKE(data, paint->brush, IDWALK_CB_USER);
- for (int i = 0; i < paint->tool_slots_len; i++) {
- FOREACH_CALLBACK_INVOKE(data, paint->tool_slots[i].brush, IDWALK_CB_USER);
- }
- FOREACH_CALLBACK_INVOKE(data, paint->palette, IDWALK_CB_USER);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
-{
- LISTBASE_FOREACH (LayerCollection *, lc, lb) {
- /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
- * anyway... */
- const int cb_flag = (lc->collection != NULL &&
- (lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
- IDWALK_CB_EMBEDDED :
- IDWALK_CB_NOP;
- FOREACH_CALLBACK_INVOKE(data, lc->collection, cb_flag);
- library_foreach_layer_collection(data, &lc->layer_collections);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-/* Used by both real Collection data-blocks, and the fake horror of master collection from Scene.
- */
-static void library_foreach_collection(LibraryForeachIDData *data, Collection *collection)
-{
- LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
- FOREACH_CALLBACK_INVOKE(data, cob->ob, IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- FOREACH_CALLBACK_INVOKE(data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
- /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
- * anyway... */
- const int cb_flag = ((parent->collection != NULL &&
- (parent->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
- IDWALK_CB_EMBEDDED :
- IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(
- data, parent->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_LOOPBACK | cb_flag);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
-{
- if (ads != NULL) {
- FOREACH_CALLBACK_INVOKE_ID(data, ads->source, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(data, ads->filter_grp, IDWALK_CB_NOP);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_screen_area(LibraryForeachIDData *data, ScrArea *area)
-{
- FOREACH_CALLBACK_INVOKE(data, area->full, IDWALK_CB_NOP);
-
- LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
- switch (sl->spacetype) {
- case SPACE_VIEW3D: {
- View3D *v3d = (View3D *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, v3d->camera, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(data, v3d->ob_center, IDWALK_CB_NOP);
-
- if (v3d->localvd) {
- FOREACH_CALLBACK_INVOKE(data, v3d->localvd->camera, IDWALK_CB_NOP);
- }
- break;
- }
- case SPACE_GRAPH: {
- SpaceGraph *sipo = (SpaceGraph *)sl;
-
- library_foreach_dopesheet(data, sipo->ads);
- break;
- }
- case SPACE_PROPERTIES: {
- SpaceProperties *sbuts = (SpaceProperties *)sl;
-
- FOREACH_CALLBACK_INVOKE_ID(data, sbuts->pinid, IDWALK_CB_NOP);
- break;
- }
- case SPACE_FILE:
- break;
- case SPACE_ACTION: {
- SpaceAction *saction = (SpaceAction *)sl;
-
- library_foreach_dopesheet(data, &saction->ads);
- FOREACH_CALLBACK_INVOKE(data, saction->action, IDWALK_CB_NOP);
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = (SpaceImage *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sima->image, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sima->gpd, IDWALK_CB_USER);
- break;
- }
- case SPACE_SEQ: {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sseq->gpd, IDWALK_CB_USER);
- break;
- }
- case SPACE_NLA: {
- SpaceNla *snla = (SpaceNla *)sl;
-
- library_foreach_dopesheet(data, snla->ads);
- break;
- }
- case SPACE_TEXT: {
- SpaceText *st = (SpaceText *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, st->text, IDWALK_CB_NOP);
- break;
- }
- case SPACE_SCRIPT: {
- SpaceScript *scpt = (SpaceScript *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, scpt->script, IDWALK_CB_NOP);
- break;
- }
- case SPACE_OUTLINER: {
- SpaceOutliner *so = (SpaceOutliner *)sl;
-
- FOREACH_CALLBACK_INVOKE_ID(data, so->search_tse.id, IDWALK_CB_NOP);
-
- if (so->treestore != NULL) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
-
- BLI_mempool_iternew(so->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- FOREACH_CALLBACK_INVOKE_ID(data, tselem->id, IDWALK_CB_NOP);
- }
- }
- break;
- }
- case SPACE_NODE: {
- SpaceNode *snode = (SpaceNode *)sl;
-
- const bool is_private_nodetree = snode->id != NULL &&
- ntreeFromID(snode->id) == snode->nodetree;
-
- FOREACH_CALLBACK_INVOKE_ID(data, snode->id, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE_ID(data, snode->from, IDWALK_CB_NOP);
-
- FOREACH_CALLBACK_INVOKE(
- data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
-
- LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
- if (path == snode->treepath.first) {
- /* first nodetree in path is same as snode->nodetree */
- FOREACH_CALLBACK_INVOKE(data,
- path->nodetree,
- is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
- }
- else {
- FOREACH_CALLBACK_INVOKE(data, path->nodetree, IDWALK_CB_USER_ONE);
- }
-
- if (path->nodetree == NULL) {
- break;
- }
- }
-
- FOREACH_CALLBACK_INVOKE(data, snode->edittree, IDWALK_CB_NOP);
- break;
- }
- case SPACE_CLIP: {
- SpaceClip *sclip = (SpaceClip *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sclip->clip, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
- break;
- }
- default:
- break;
- }
- }
-
- FOREACH_FINALIZE_VOID;
}
bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
@@ -556,7 +259,6 @@ static void library_foreach_ID_link(Main *bmain,
LibraryForeachIDData *inherit_data)
{
LibraryForeachIDData data = {.bmain = bmain};
- int i;
BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain);
@@ -577,10 +279,11 @@ static void library_foreach_ID_link(Main *bmain,
data.callback = callback;
data.user_data = user_data;
-#define CALLBACK_INVOKE_ID(check_id, cb_flag) FOREACH_CALLBACK_INVOKE_ID(&data, check_id, cb_flag)
+#define CALLBACK_INVOKE_ID(check_id, cb_flag) \
+ BKE_LIB_FOREACHID_PROCESS_ID(&data, check_id, cb_flag)
#define CALLBACK_INVOKE(check_id_super, cb_flag) \
- FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag)
+ BKE_LIB_FOREACHID_PROCESS(&data, check_id_super, cb_flag)
for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
data.self_id = id;
@@ -616,7 +319,7 @@ static void library_foreach_ID_link(Main *bmain,
* especially if/when it starts modifying Main database). */
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
for (; entry != NULL; entry = entry->next) {
- FOREACH_CALLBACK_INVOKE_ID_PP(&data, entry->id_pointer, entry->usage_flag);
+ BKE_lib_query_foreachid_process(&data, entry->id_pointer, entry->usage_flag);
}
continue;
}
@@ -642,569 +345,15 @@ static void library_foreach_ID_link(Main *bmain,
}
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
-
- /* Note: this is temp logic until all code has been ported to IDTypeInfo... */
if (id_type->foreach_id != NULL) {
id_type->foreach_id(id, &data);
if (data.status & IDWALK_STOP) {
break;
}
- else {
- continue;
- }
- }
-
- switch ((ID_Type)GS(id->name)) {
- case ID_LI: {
- BLI_assert(0);
- break;
- }
- case ID_SCE: {
- Scene *scene = (Scene *)id;
- ToolSettings *toolsett = scene->toolsettings;
-
- CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
- CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->set, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(scene->clip, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->r.bake.cage_object, IDWALK_CB_NOP);
- if (scene->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&scene->nodetree);
- }
- if (scene->ed) {
- Sequence *seq;
- SEQP_BEGIN (scene->ed, seq) {
- CALLBACK_INVOKE(seq->scene, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(seq->scene_camera, IDWALK_CB_NOP);
- CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER);
- CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER);
- CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER);
- IDP_foreach_property(seq->prop,
- IDP_TYPE_FILTER_ID,
- BKE_lib_query_idpropertiesForeachIDLink_callback,
- &data);
- LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
- CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
- }
-
- if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
- TextVars *text_data = seq->effectdata;
- CALLBACK_INVOKE(text_data->text_font, IDWALK_CB_USER);
- }
- }
- SEQ_END;
- }
-
- /* This pointer can be NULL during old files reading, better be safe than sorry. */
- if (scene->master_collection != NULL) {
- library_foreach_collection(&data, scene->master_collection);
- }
-
- LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- CALLBACK_INVOKE(view_layer->mat_override, IDWALK_CB_USER);
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
- CALLBACK_INVOKE(base->object, IDWALK_CB_NOP);
- }
-
- library_foreach_layer_collection(&data, &view_layer->layer_collections);
-
- LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
- if (fmc->script) {
- CALLBACK_INVOKE(fmc->script, IDWALK_CB_NOP);
- }
- }
-
- LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
- if (fls->group) {
- CALLBACK_INVOKE(fls->group, IDWALK_CB_USER);
- }
-
- if (fls->linestyle) {
- CALLBACK_INVOKE(fls->linestyle, IDWALK_CB_USER);
- }
- }
- }
-
- LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
- CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
- }
-
- if (toolsett) {
- CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_CB_NOP);
- CALLBACK_INVOKE(toolsett->particle.object, IDWALK_CB_NOP);
- CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_CB_NOP);
-
- library_foreach_paint(&data, &toolsett->imapaint.paint);
- CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_CB_USER);
- CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_CB_USER);
- CALLBACK_INVOKE(toolsett->imapaint.canvas, IDWALK_CB_USER);
-
- if (toolsett->vpaint) {
- library_foreach_paint(&data, &toolsett->vpaint->paint);
- }
- if (toolsett->wpaint) {
- library_foreach_paint(&data, &toolsett->wpaint->paint);
- }
- if (toolsett->sculpt) {
- library_foreach_paint(&data, &toolsett->sculpt->paint);
- CALLBACK_INVOKE(toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
- }
- if (toolsett->uvsculpt) {
- library_foreach_paint(&data, &toolsett->uvsculpt->paint);
- }
- if (toolsett->gp_paint) {
- library_foreach_paint(&data, &toolsett->gp_paint->paint);
- }
- if (toolsett->gp_vertexpaint) {
- library_foreach_paint(&data, &toolsett->gp_vertexpaint->paint);
- }
- if (toolsett->gp_sculptpaint) {
- library_foreach_paint(&data, &toolsett->gp_sculptpaint->paint);
- }
- if (toolsett->gp_weightpaint) {
- library_foreach_paint(&data, &toolsett->gp_weightpaint->paint);
- }
-
- CALLBACK_INVOKE(toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP);
- }
-
- if (scene->rigidbody_world) {
- BKE_rigidbody_world_id_loop(
- scene->rigidbody_world, library_foreach_rigidbodyworldSceneLooper, &data);
- }
-
- break;
- }
-
- case ID_OB: {
- Object *object = (Object *)id;
-
- /* Object is special, proxies make things hard... */
- const int data_cb_flag = data.cb_flag;
- const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
- (object->proxy || object->proxy_group)) ?
- IDWALK_CB_INDIRECT_USAGE :
- 0;
-
- /* object data special case */
- data.cb_flag |= proxy_cb_flag;
- if (object->type == OB_EMPTY) {
- /* empty can have NULL or Image */
- CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER);
- }
- else {
- /* when set, this can't be NULL */
- if (object->data) {
- CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
- }
- }
- data.cb_flag = data_cb_flag;
-
- CALLBACK_INVOKE(object->parent, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->track, IDWALK_CB_NEVER_SELF);
- /* object->proxy is refcounted, but not object->proxy_group... *sigh* */
- CALLBACK_INVOKE(object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->proxy_group, IDWALK_CB_NOP);
-
- /* Special case!
- * Since this field is set/owned by 'user' of this ID (and not ID itself),
- * it is only indirect usage if proxy object is linked... Twisted. */
- if (object->proxy_from) {
- data.cb_flag = ID_IS_LINKED(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0;
- }
- CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
- data.cb_flag = data_cb_flag;
-
- CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER);
-
- data.cb_flag |= proxy_cb_flag;
- for (i = 0; i < object->totcol; i++) {
- CALLBACK_INVOKE(object->mat[i], IDWALK_CB_USER);
- }
- data.cb_flag = data_cb_flag;
-
- /* Note that ob->gpd is deprecated, so no need to handle it here. */
- CALLBACK_INVOKE(object->instance_collection, IDWALK_CB_USER);
-
- if (object->pd) {
- CALLBACK_INVOKE(object->pd->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(object->pd->f_source, IDWALK_CB_NOP);
- }
- /* Note that ob->effect is deprecated, so no need to handle it here. */
-
- if (object->pose) {
- data.cb_flag |= proxy_cb_flag;
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- IDP_foreach_property(pchan->prop,
- IDP_TYPE_FILTER_ID,
- BKE_lib_query_idpropertiesForeachIDLink_callback,
- &data);
- CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
- BKE_constraints_id_loop(
- &pchan->constraints, library_foreach_constraintObjectLooper, &data);
- }
- data.cb_flag = data_cb_flag;
- }
-
- if (object->rigidbody_constraint) {
- CALLBACK_INVOKE(object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
- }
-
- if (object->lodlevels.first) {
- LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
- CALLBACK_INVOKE(level->source, IDWALK_CB_NEVER_SELF);
- }
- }
-
- BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, &data);
- BKE_gpencil_modifiers_foreach_ID_link(
- object, library_foreach_gpencil_modifiersForeachIDLink, &data);
- BKE_constraints_id_loop(
- &object->constraints, library_foreach_constraintObjectLooper, &data);
- BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, &data);
-
- LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
- BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
- }
-
- if (object->soft) {
- CALLBACK_INVOKE(object->soft->collision_group, IDWALK_CB_NOP);
-
- if (object->soft->effector_weights) {
- CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_CB_NOP);
- }
- }
- break;
- }
-
- case ID_AR: {
- BLI_assert(0);
- break;
- }
-
- case ID_ME: {
- BLI_assert(0);
- break;
- }
-
- case ID_CU: {
- BLI_assert(0);
- break;
- }
-
- case ID_MB: {
- BLI_assert(0);
- break;
- }
-
- case ID_MA: {
- BLI_assert(0);
- break;
- }
-
- case ID_TE: {
- BLI_assert(0);
- break;
- }
-
- case ID_LT: {
- BLI_assert(0);
- break;
- }
-
- case ID_LA: {
- break;
- }
-
- case ID_CA: {
- BLI_assert(0);
- break;
- }
-
- case ID_KE: {
- break;
- }
-
- case ID_WO: {
- BLI_assert(0);
- break;
- }
-
- case ID_SPK: {
- BLI_assert(0);
- break;
- }
-
- case ID_LP: {
- BLI_assert(0);
- break;
- }
-
- case ID_GR: {
- Collection *collection = (Collection *)id;
- library_foreach_collection(&data, collection);
- break;
- }
-
- case ID_NT: {
- BLI_assert(0);
- break;
- }
-
- case ID_BR: {
- BLI_assert(0);
- break;
- }
-
- case ID_PA: {
- ParticleSettings *psett = (ParticleSettings *)id;
- CALLBACK_INVOKE(psett->instance_collection, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->instance_object, IDWALK_CB_NOP);
- CALLBACK_INVOKE(psett->bb_ob, IDWALK_CB_NOP);
- CALLBACK_INVOKE(psett->collision_group, IDWALK_CB_NOP);
-
- for (i = 0; i < MAX_MTEX; i++) {
- if (psett->mtex[i]) {
- BKE_texture_mtex_foreach_id(&data, psett->mtex[i]);
- }
- }
-
- if (psett->effector_weights) {
- CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_CB_NOP);
- }
-
- if (psett->pd) {
- CALLBACK_INVOKE(psett->pd->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->pd->f_source, IDWALK_CB_NOP);
- }
- if (psett->pd2) {
- CALLBACK_INVOKE(psett->pd2->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_CB_NOP);
- }
-
- if (psett->boids) {
- LISTBASE_FOREACH (BoidState *, state, &psett->boids->states) {
- LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
- if (rule->type == eBoidRuleType_Avoid) {
- BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
- CALLBACK_INVOKE(gabr->ob, IDWALK_CB_NOP);
- }
- else if (rule->type == eBoidRuleType_FollowLeader) {
- BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
- CALLBACK_INVOKE(flbr->ob, IDWALK_CB_NOP);
- }
- }
- }
- }
-
- LISTBASE_FOREACH (ParticleDupliWeight *, dw, &psett->instance_weights) {
- CALLBACK_INVOKE(dw->ob, IDWALK_CB_NOP);
- }
- break;
- }
-
- case ID_MC: {
- MovieClip *clip = (MovieClip *)id;
- MovieTracking *tracking = &clip->tracking;
-
- CALLBACK_INVOKE(clip->gpd, IDWALK_CB_USER);
-
- LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) {
- CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
- LISTBASE_FOREACH (MovieTrackingTrack *, track, &object->tracks) {
- CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
- }
- }
-
- LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking->plane_tracks) {
- CALLBACK_INVOKE(plane_track->image, IDWALK_CB_USER);
- }
- break;
- }
-
- case ID_MSK: {
- Mask *mask = (Mask *)id;
-
- LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
- LISTBASE_FOREACH (MaskSpline *, mask_spline, &mask_layer->splines) {
- for (i = 0; i < mask_spline->tot_point; i++) {
- MaskSplinePoint *point = &mask_spline->points[i];
- CALLBACK_INVOKE_ID(point->parent.id, IDWALK_CB_USER);
- }
- }
- }
- break;
- }
-
- case ID_LS: {
- FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
-
- for (i = 0; i < MAX_MTEX; i++) {
- if (linestyle->mtex[i]) {
- BKE_texture_mtex_foreach_id(&data, linestyle->mtex[i]);
- }
- }
- if (linestyle->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&linestyle->nodetree);
- }
-
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleColorModifier_DistanceFromObject *p =
- (LineStyleColorModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->alpha_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleAlphaModifier_DistanceFromObject *p =
- (LineStyleAlphaModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->thickness_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleThicknessModifier_DistanceFromObject *p =
- (LineStyleThicknessModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- break;
- }
-
- case ID_AC: {
- bAction *act = (bAction *)id;
-
- LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
- CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
- }
- break;
- }
-
- case ID_WM: {
- wmWindowManager *wm = (wmWindowManager *)id;
-
- LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
- CALLBACK_INVOKE(win->scene, IDWALK_CB_USER_ONE);
-
- /* This pointer can be NULL during old files reading, better be safe than sorry. */
- if (win->workspace_hook != NULL) {
- ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
- CALLBACK_INVOKE_ID(workspace, IDWALK_CB_NOP);
- /* allow callback to set a different workspace */
- BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
- }
- if (data.flag & IDWALK_INCLUDE_UI) {
- LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
- library_foreach_screen_area(&data, area);
- }
- }
- }
- break;
- }
-
- case ID_WS: {
- WorkSpace *workspace = (WorkSpace *)id;
- ListBase *layouts = BKE_workspace_layouts_get(workspace);
-
- LISTBASE_FOREACH (WorkSpaceLayout *, layout, layouts) {
- bScreen *screen = BKE_workspace_layout_screen_get(layout);
-
- /* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
- * However we can't access layout->screen here
- * since we are outside the workspace project. */
- CALLBACK_INVOKE(screen, IDWALK_CB_USER);
- /* allow callback to set a different screen */
- BKE_workspace_layout_screen_set(layout, screen);
- }
- break;
- }
-
- case ID_GD: {
- bGPdata *gpencil = (bGPdata *)id;
- /* materials */
- for (i = 0; i < gpencil->totcol; i++) {
- CALLBACK_INVOKE(gpencil->mat[i], IDWALK_CB_USER);
- }
-
- LISTBASE_FOREACH (bGPDlayer *, gplayer, &gpencil->layers) {
- CALLBACK_INVOKE(gplayer->parent, IDWALK_CB_NOP);
- }
-
- break;
- }
- case ID_HA: {
- Hair *hair = (Hair *)id;
- for (i = 0; i < hair->totcol; i++) {
- CALLBACK_INVOKE(hair->mat[i], IDWALK_CB_USER);
- }
- break;
- }
- case ID_PT: {
- PointCloud *pointcloud = (PointCloud *)id;
- for (i = 0; i < pointcloud->totcol; i++) {
- CALLBACK_INVOKE(pointcloud->mat[i], IDWALK_CB_USER);
- }
- break;
- }
- case ID_VO: {
- Volume *volume = (Volume *)id;
- for (i = 0; i < volume->totcol; i++) {
- CALLBACK_INVOKE(volume->mat[i], IDWALK_CB_USER);
- }
- break;
- }
-
- case ID_SCR: {
- if (data.flag & IDWALK_INCLUDE_UI) {
- bScreen *screen = (bScreen *)id;
-
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- library_foreach_screen_area(&data, area);
- }
- }
- break;
- }
- case ID_SIM: {
- Simulation *simulation = (Simulation *)id;
- if (simulation->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&simulation->nodetree);
- }
- break;
- }
-
- /* Nothing needed for those... */
- case ID_IM:
- case ID_VF:
- case ID_TXT:
- case ID_SO:
- case ID_PAL:
- case ID_PC:
- case ID_CF:
- break;
-
- /* Deprecated. */
- case ID_IP:
- break;
}
}
-FOREACH_FINALIZE:
if (data.ids_handled) {
BLI_gset_free(data.ids_handled, NULL);
BLI_LINKSTACK_FREE(data.ids_todo);
@@ -1214,9 +363,6 @@ FOREACH_FINALIZE:
#undef CALLBACK_INVOKE
}
-#undef FOREACH_CALLBACK_INVOKE_ID
-#undef FOREACH_CALLBACK_INVOKE
-
/**
* Loop over all of the ID's this data-block links to.
*/
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index 9dc338ce580..aa1005c663f 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -48,6 +48,8 @@
#include "BLT_translation.h"
+#include "DEG_depsgraph.h"
+
static void light_init_data(ID *id)
{
Light *la = (Light *)id;
@@ -178,3 +180,8 @@ Light *BKE_light_localize(Light *la)
return lan;
}
+
+void BKE_light_eval(struct Depsgraph *depsgraph, Light *la)
+{
+ DEG_debug_print_eval(depsgraph, __func__, la->id.name, la);
+}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 0401ae48b5c..a389af5c47f 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -45,9 +45,11 @@
#include "BKE_freestyle.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_texture.h"
static void linestyle_init_data(ID *id)
{
@@ -144,6 +146,49 @@ static void linestyle_free_data(ID *id)
}
}
+static void linestyle_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
+
+ for (int i = 0; i < MAX_MTEX; i++) {
+ if (linestyle->mtex[i]) {
+ BKE_texture_mtex_foreach_id(data, linestyle->mtex[i]);
+ }
+ }
+ if (linestyle->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&linestyle->nodetree);
+ }
+
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)
+ lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->alpha_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleAlphaModifier_DistanceFromObject *p = (LineStyleAlphaModifier_DistanceFromObject *)
+ lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->thickness_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleThicknessModifier_DistanceFromObject *p =
+ (LineStyleThicknessModifier_DistanceFromObject *)lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_LS = {
.id_code = ID_LS,
.id_filter = FILTER_ID_LS,
@@ -158,6 +203,7 @@ IDTypeInfo IDType_ID_LS = {
.copy_data = linestyle_copy_data,
.free_data = linestyle_free_data,
.make_local = NULL,
+ .foreach_id = linestyle_foreach_id,
};
static const char *modifier_name[LS_MODIFIER_NUM] = {
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 6c835dc5fb2..49c909850de 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -45,6 +45,7 @@
#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_mask.h"
#include "BKE_movieclip.h"
@@ -79,6 +80,20 @@ static void mask_free_data(ID *id)
BKE_mask_layer_free_list(&mask->masklayers);
}
+static void mask_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Mask *mask = (Mask *)id;
+
+ LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
+ LISTBASE_FOREACH (MaskSpline *, mask_spline, &mask_layer->splines) {
+ for (int i = 0; i < mask_spline->tot_point; i++) {
+ MaskSplinePoint *point = &mask_spline->points[i];
+ BKE_LIB_FOREACHID_PROCESS_ID(data, point->parent.id, IDWALK_CB_USER);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_MSK = {
.id_code = ID_MSK,
.id_filter = FILTER_ID_MSK,
@@ -93,6 +108,7 @@ IDTypeInfo IDType_ID_MSK = {
.copy_data = mask_copy_data,
.free_data = mask_free_data,
.make_local = NULL,
+ .foreach_id = mask_foreach_id,
};
static struct {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4c7b791f103..fe7c2055aef 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -58,6 +59,7 @@
#include "BKE_idtype.h"
#include "BKE_image.h" /* openanim */
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
#include "BKE_node.h"
@@ -106,6 +108,27 @@ static void movie_clip_free_data(ID *id)
BKE_tracking_free(&movie_clip->tracking);
}
+static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ MovieClip *movie_clip = (MovieClip *)id;
+ MovieTracking *tracking = &movie_clip->tracking;
+
+ BKE_LIB_FOREACHID_PROCESS(data, movie_clip->gpd, IDWALK_CB_USER);
+
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, track->gpd, IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, &object->tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, track->gpd, IDWALK_CB_USER);
+ }
+ }
+
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking->plane_tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, plane_track->image, IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_MC = {
.id_code = ID_MC,
.id_filter = FILTER_ID_MC,
@@ -120,6 +143,7 @@ IDTypeInfo IDType_ID_MC = {
.copy_data = movie_clip_copy_data,
.free_data = movie_clip_free_data,
.make_local = NULL,
+ .foreach_id = movie_clip_foreach_id,
};
/*********************** movieclip buffer loaders *************************/
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index e59b19638f8..64cc9130e25 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -197,7 +197,16 @@ void multiresModifier_subdivide_to_level(struct Object *object,
if (!has_mdisps) {
CustomData_add_layer(&coarse_mesh->ldata, CD_MDISPS, CD_CALLOC, NULL, coarse_mesh->totloop);
}
- if (!has_mdisps || top_level == 1) {
+
+ /* NOTE: Subdivision happens from the top level of the existing multires modifier. If it is set
+ * to 0 and there is mdisps layer it would mean that the modifier went out of sync with the data.
+ * This happens when, for example, linking modifiers from one object to another.
+ *
+ * In such cases simply ensure grids to be the proper level.
+ *
+ * If something smarter is needed it is up to the operators which does data synchronization, so
+ * that the mdisps layer is also synchronized. */
+ if (!has_mdisps || top_level == 1 || mmd->totlvl == 0) {
multires_reshape_ensure_grids(coarse_mesh, top_level);
if (ELEM(mode, MULTIRES_SUBDIVIDE_LINEAR, MULTIRES_SUBDIVIDE_SIMPLE)) {
multires_subdivide_create_tangent_displacement_linear_grids(object, mmd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6bd841ca8e5..d17575195e3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -375,6 +375,153 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
}
}
+static void library_foreach_modifiersForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_shaderfxForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
+ ID **id_pointer,
+ bool is_reference,
+ void *user_data)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
+ ID **id_pointer,
+ void *user_data,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void object_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Object *object = (Object *)id;
+
+ /* Object is special, proxies make things hard... */
+ const int proxy_cb_flag = ((BKE_lib_query_foreachid_process_flags_get(data) &
+ IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
+ (object->proxy || object->proxy_group)) ?
+ IDWALK_CB_INDIRECT_USAGE :
+ 0;
+
+ /* object data special case */
+ if (object->type == OB_EMPTY) {
+ /* empty can have NULL or Image */
+ BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, proxy_cb_flag | IDWALK_CB_USER);
+ }
+ else {
+ /* when set, this can't be NULL */
+ if (object->data) {
+ BKE_LIB_FOREACHID_PROCESS_ID(
+ data, object->data, proxy_cb_flag | IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
+ }
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, object->parent, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->track, IDWALK_CB_NEVER_SELF);
+ /* object->proxy is refcounted, but not object->proxy_group... *sigh* */
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy_group, IDWALK_CB_NOP);
+
+ /* Special case!
+ * Since this field is set/owned by 'user' of this ID (and not ID itself),
+ * it is only indirect usage if proxy object is linked... Twisted. */
+ {
+ const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
+ data,
+ (object->proxy_from != NULL && ID_IS_LINKED(object->proxy_from)) ?
+ IDWALK_CB_INDIRECT_USAGE :
+ 0,
+ true);
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
+ BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, object->poselib, IDWALK_CB_USER);
+
+ for (int i = 0; i < object->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->mat[i], proxy_cb_flag | IDWALK_CB_USER);
+ }
+
+ /* Note that ob->gpd is deprecated, so no need to handle it here. */
+ BKE_LIB_FOREACHID_PROCESS(data, object->instance_collection, IDWALK_CB_USER);
+
+ if (object->pd) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->pd->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, object->pd->f_source, IDWALK_CB_NOP);
+ }
+ /* Note that ob->effect is deprecated, so no need to handle it here. */
+
+ if (object->pose) {
+ const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
+ data, proxy_cb_flag, false);
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ IDP_foreach_property(
+ pchan->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS(data, pchan->custom, IDWALK_CB_USER);
+ BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, data);
+ }
+ BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
+ }
+
+ if (object->rigidbody_constraint) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
+ }
+
+ if (object->lodlevels.first) {
+ LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
+ BKE_LIB_FOREACHID_PROCESS(data, level->source, IDWALK_CB_NEVER_SELF);
+ }
+ }
+
+ BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, data);
+ BKE_gpencil_modifiers_foreach_ID_link(
+ object, library_foreach_gpencil_modifiersForeachIDLink, data);
+ BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, data);
+ BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, data);
+
+ LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
+ BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, data);
+ }
+
+ if (object->soft) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->soft->collision_group, IDWALK_CB_NOP);
+
+ if (object->soft->effector_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->soft->effector_weights->group, IDWALK_CB_NOP);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_OB = {
.id_code = ID_OB,
.id_filter = FILTER_ID_OB,
@@ -389,6 +536,7 @@ IDTypeInfo IDType_ID_OB = {
.copy_data = object_copy_data,
.free_data = object_free_data,
.make_local = object_make_local,
+ .foreach_id = object_foreach_id,
};
void BKE_object_workob_clear(Object *workob)
@@ -3887,6 +4035,10 @@ bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_chi
* cases false positives are hard to avoid (shape keys for example) */
int BKE_object_is_modified(Scene *scene, Object *ob)
{
+ /* Always test on original object since evaluated object may no longer
+ * have shape keys or modifiers that were used to evaluate it. */
+ ob = DEG_get_original_object(ob);
+
int flag = 0;
if (BKE_key_from_object(ob)) {
@@ -4017,6 +4169,10 @@ static bool modifiers_has_animation_check(const Object *ob)
* and we can still if there was actual deformation afterwards */
int BKE_object_is_deform_modified(Scene *scene, Object *ob)
{
+ /* Always test on original object since evaluated object may no longer
+ * have shape keys or modifiers that were used to evaluate it. */
+ ob = DEG_get_original_object(ob);
+
ModifierData *md;
VirtualModifierData virtualModifierData;
int flag = 0;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 5b608d579e8..f26b478c680 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -116,6 +116,7 @@ IDTypeInfo IDType_ID_PAL = {
.copy_data = palette_copy_data,
.free_data = palette_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@@ -153,6 +154,7 @@ IDTypeInfo IDType_ID_PC = {
.copy_data = paint_curve_copy_data,
.free_data = paint_curve_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
@@ -547,35 +549,35 @@ void BKE_paint_runtime_init(const ToolSettings *ts, Paint *paint)
paint->runtime.tool_offset = offsetof(Brush, imagepaint_tool);
paint->runtime.ob_mode = OB_MODE_TEXTURE_PAINT;
}
- else if (paint == &ts->sculpt->paint) {
+ else if (ts->sculpt && paint == &ts->sculpt->paint) {
paint->runtime.tool_offset = offsetof(Brush, sculpt_tool);
paint->runtime.ob_mode = OB_MODE_SCULPT;
}
- else if (paint == &ts->vpaint->paint) {
+ else if (ts->vpaint && paint == &ts->vpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, vertexpaint_tool);
paint->runtime.ob_mode = OB_MODE_VERTEX_PAINT;
}
- else if (paint == &ts->wpaint->paint) {
+ else if (ts->wpaint && paint == &ts->wpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, weightpaint_tool);
paint->runtime.ob_mode = OB_MODE_WEIGHT_PAINT;
}
- else if (paint == &ts->uvsculpt->paint) {
+ else if (ts->uvsculpt && paint == &ts->uvsculpt->paint) {
paint->runtime.tool_offset = offsetof(Brush, uv_sculpt_tool);
paint->runtime.ob_mode = OB_MODE_EDIT;
}
- else if (paint == &ts->gp_paint->paint) {
+ else if (ts->gp_paint && paint == &ts->gp_paint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_tool);
paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL;
}
- else if (paint == &ts->gp_vertexpaint->paint) {
+ else if (ts->gp_vertexpaint && paint == &ts->gp_vertexpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_vertex_tool);
paint->runtime.ob_mode = OB_MODE_VERTEX_GPENCIL;
}
- else if (paint == &ts->gp_sculptpaint->paint) {
+ else if (ts->gp_sculptpaint && paint == &ts->gp_sculptpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_sculpt_tool);
paint->runtime.ob_mode = OB_MODE_SCULPT_GPENCIL;
}
- else if (paint == &ts->gp_weightpaint->paint) {
+ else if (ts->gp_weightpaint && paint == &ts->gp_weightpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_weight_tool);
paint->runtime.ob_mode = OB_MODE_WEIGHT_GPENCIL;
}
@@ -1480,6 +1482,7 @@ static void sculpt_update_object(
SculptSession *ss = ob->sculpt;
Mesh *me = BKE_object_get_original_mesh(ob);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+ const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
@@ -1535,17 +1538,22 @@ static void sculpt_update_object(
}
/* Sculpt Face Sets. */
- if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
- ss->face_sets = CustomData_add_layer(
- &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
- for (int i = 0; i < me->totpoly; i++) {
- ss->face_sets[i] = 1;
- }
+ if (use_face_sets) {
+ if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
+ ss->face_sets = CustomData_add_layer(
+ &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
+ for (int i = 0; i < me->totpoly; i++) {
+ ss->face_sets[i] = 1;
+ }
- /* Set the default face set color if the datalayer did not exist. */
- me->face_sets_color_default = 1;
+ /* Set the default face set color if the datalayer did not exist. */
+ me->face_sets_color_default = 1;
+ }
+ ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+ }
+ else {
+ ss->face_sets = NULL;
}
- ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
@@ -1805,11 +1813,12 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
return pbvh;
}
-static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
+static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool respect_hide)
{
Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
PBVH *pbvh = BKE_pbvh_new();
+ BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MLoopTri *looptri = MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__);
@@ -1841,11 +1850,12 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
return pbvh;
}
-static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
+static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect_hide)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
+ BKE_pbvh_respect_hide_set(pbvh, respect_hide);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,
@@ -1863,6 +1873,14 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
if (ob == NULL || ob->sculpt == NULL) {
return NULL;
}
+
+ bool respect_hide = true;
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ if (!(BKE_paint_select_vert_test(ob) || BKE_paint_select_face_test(ob))) {
+ respect_hide = false;
+ }
+ }
+
PBVH *pbvh = ob->sculpt->pbvh;
if (pbvh != NULL) {
/* NOTE: It is possible that grids were re-allocated due to modifier
@@ -1886,11 +1904,11 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = object_eval->data;
if (mesh_eval->runtime.subdiv_ccg != NULL) {
- pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg);
+ pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
- pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform);
+ pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 2f2d3aded31..015c67806c6 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -55,21 +55,22 @@
#include "BKE_cloth.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
-#include "BKE_effect.h"
-#include "BKE_idtype.h"
-#include "BKE_lattice.h"
-#include "BKE_main.h"
-
#include "BKE_deform.h"
#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_idtype.h"
#include "BKE_key.h"
+#include "BKE_lattice.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
+#include "BKE_texture.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -146,6 +147,53 @@ static void particle_settings_free_data(ID *id)
fluid_free_settings(particle_settings->fluid);
}
+static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ ParticleSettings *psett = (ParticleSettings *)id;
+ BKE_LIB_FOREACHID_PROCESS(data, psett->instance_collection, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->instance_object, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->bb_ob, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->collision_group, IDWALK_CB_NOP);
+
+ for (int i = 0; i < MAX_MTEX; i++) {
+ if (psett->mtex[i]) {
+ BKE_texture_mtex_foreach_id(data, psett->mtex[i]);
+ }
+ }
+
+ if (psett->effector_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->effector_weights->group, IDWALK_CB_NOP);
+ }
+
+ if (psett->pd) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd->f_source, IDWALK_CB_NOP);
+ }
+ if (psett->pd2) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->f_source, IDWALK_CB_NOP);
+ }
+
+ if (psett->boids) {
+ LISTBASE_FOREACH (BoidState *, state, &psett->boids->states) {
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ if (rule->type == eBoidRuleType_Avoid) {
+ BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
+ BKE_LIB_FOREACHID_PROCESS(data, gabr->ob, IDWALK_CB_NOP);
+ }
+ else if (rule->type == eBoidRuleType_FollowLeader) {
+ BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
+ BKE_LIB_FOREACHID_PROCESS(data, flbr->ob, IDWALK_CB_NOP);
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (ParticleDupliWeight *, dw, &psett->instance_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, dw->ob, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_PA = {
.id_code = ID_PA,
.id_filter = FILTER_ID_PA,
@@ -160,6 +208,7 @@ IDTypeInfo IDType_ID_PA = {
.copy_data = particle_settings_copy_data,
.free_data = particle_settings_free_data,
.make_local = NULL,
+ .foreach_id = particle_settings_foreach_id,
};
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 21bbdf46104..e31d2a8e005 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -295,6 +295,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
node->face_vert_indices = (const int(*)[3])face_vert_indices;
+ if (bvh->respect_hide == false) {
+ has_visible = true;
+ }
+
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &bvh->looptri[node->prim_indices[i]];
for (int j = 0; j < 3; j++) {
@@ -302,8 +306,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
bvh, map, &node->face_verts, &node->uniq_verts, bvh->mloop[lt->tri[j]].v);
}
- if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) {
- has_visible = true;
+ if (has_visible == false) {
+ if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) {
+ has_visible = true;
+ }
}
}
@@ -666,7 +672,7 @@ void BKE_pbvh_build_grids(PBVH *bvh,
PBVH *BKE_pbvh_new(void)
{
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
-
+ bvh->respect_hide = true;
return bvh;
}
@@ -2117,7 +2123,7 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
const MLoopTri *lt = &bvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (paint_is_face_hidden(lt, vert, mloop)) {
+ if (bvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
continue;
}
@@ -2426,7 +2432,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *bvh,
const MLoopTri *lt = &bvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (paint_is_face_hidden(lt, vert, mloop)) {
+ if (bvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
continue;
}
@@ -2900,6 +2906,12 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
vi->fno = NULL;
vi->mvert = NULL;
+ vi->respect_hide = bvh->respect_hide;
+ if (bvh->respect_hide == false) {
+ /* The same value for all vertices. */
+ vi->visible = true;
+ }
+
BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids);
BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
@@ -3014,3 +3026,8 @@ void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets)
{
bvh->face_sets = face_sets;
}
+
+void BKE_pbvh_respect_hide_set(PBVH *bvh, bool respect_hide)
+{
+ bvh->respect_hide = respect_hide;
+}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index d3e42ac7705..7397f939894 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -160,6 +160,7 @@ struct PBVH {
bool deformed;
bool show_mask;
bool show_face_sets;
+ bool respect_hide;
/* Dynamic topology */
BMesh *bm;
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index 79b16443122..e03888dcad7 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -21,6 +21,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
@@ -48,23 +49,7 @@
/* PointCloud datablock */
-static void pointcloud_random(PointCloud *pointcloud)
-{
- pointcloud->totpoint = 400;
- CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
-
- RNG *rng = BLI_rng_new(0);
-
- for (int i = 0; i < pointcloud->totpoint; i++) {
- pointcloud->co[i][0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->radius[i] = 0.05f * BLI_rng_get_float(rng);
- }
-
- BLI_rng_free(rng);
-}
+static void pointcloud_random(PointCloud *pointcloud);
static void pointcloud_init_data(ID *id)
{
@@ -81,15 +66,6 @@ static void pointcloud_init_data(ID *id)
pointcloud_random(pointcloud);
}
-void *BKE_pointcloud_add(Main *bmain, const char *name)
-{
- PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0);
-
- pointcloud_init_data(&pointcloud->id);
-
- return pointcloud;
-}
-
static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
@@ -105,18 +81,6 @@ static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_s
BKE_pointcloud_update_customdata_pointers(pointcloud_dst);
}
-PointCloud *BKE_pointcloud_copy(Main *bmain, const PointCloud *pointcloud)
-{
- PointCloud *pointcloud_copy;
- BKE_id_copy(bmain, &pointcloud->id, (ID **)&pointcloud_copy);
- return pointcloud_copy;
-}
-
-static void pointcloud_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void pointcloud_free_data(ID *id)
{
PointCloud *pointcloud = (PointCloud *)id;
@@ -126,6 +90,14 @@ static void pointcloud_free_data(ID *id)
MEM_SAFE_FREE(pointcloud->mat);
}
+static void pointcloud_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ for (int i = 0; i < pointcloud->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, pointcloud->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_PT = {
.id_code = ID_PT,
.id_filter = FILTER_ID_PT,
@@ -139,9 +111,44 @@ IDTypeInfo IDType_ID_PT = {
.init_data = pointcloud_init_data,
.copy_data = pointcloud_copy_data,
.free_data = pointcloud_free_data,
- .make_local = pointcloud_make_local,
+ .make_local = NULL,
+ .foreach_id = pointcloud_foreach_id,
};
+static void pointcloud_random(PointCloud *pointcloud)
+{
+ pointcloud->totpoint = 400;
+ CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
+ BKE_pointcloud_update_customdata_pointers(pointcloud);
+
+ RNG *rng = BLI_rng_new(0);
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ pointcloud->co[i][0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->co[i][1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->co[i][2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->radius[i] = 0.05f * BLI_rng_get_float(rng);
+ }
+
+ BLI_rng_free(rng);
+}
+
+void *BKE_pointcloud_add(Main *bmain, const char *name)
+{
+ PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0);
+
+ pointcloud_init_data(&pointcloud->id);
+
+ return pointcloud;
+}
+
+PointCloud *BKE_pointcloud_copy(Main *bmain, const PointCloud *pointcloud)
+{
+ PointCloud *pointcloud_copy;
+ BKE_id_copy(bmain, &pointcloud->id, (ID **)&pointcloud_copy);
+ return pointcloud_copy;
+}
+
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_POINTCLOUD);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index be6a4e4022b..34249e0a8f7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -33,6 +33,7 @@
#include "DNA_defaults.h"
#include "DNA_gpencil_types.h"
#include "DNA_linestyle_types.h"
+#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -42,6 +43,7 @@
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_space_types.h"
+#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
@@ -77,6 +79,7 @@
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
@@ -418,6 +421,155 @@ static void scene_free_data(ID *id)
BLI_assert(scene->layer_properties == NULL);
}
+static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
+ ID **id_pointer,
+ void *user_data,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
+{
+ BKE_LIB_FOREACHID_PROCESS(data, paint->brush, IDWALK_CB_USER);
+ for (int i = 0; i < paint->tool_slots_len; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, paint->tool_slots[i].brush, IDWALK_CB_USER);
+ }
+ BKE_LIB_FOREACHID_PROCESS(data, paint->palette, IDWALK_CB_USER);
+}
+
+static void library_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
+{
+ LISTBASE_FOREACH (LayerCollection *, lc, lb) {
+ /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
+ * anyway... */
+ const int cb_flag = (lc->collection != NULL &&
+ (lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
+ IDWALK_CB_EMBEDDED :
+ IDWALK_CB_NOP;
+ BKE_LIB_FOREACHID_PROCESS(data, lc->collection, cb_flag);
+ library_foreach_layer_collection(data, &lc->layer_collections);
+ }
+}
+
+static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Scene *scene = (Scene *)id;
+
+ BKE_LIB_FOREACHID_PROCESS(data, scene->camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->world, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->set, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->clip, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->gpd, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->r.bake.cage_object, IDWALK_CB_NOP);
+ if (scene->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree);
+ }
+ if (scene->ed) {
+ Sequence *seq;
+ SEQP_BEGIN (scene->ed, seq) {
+ BKE_LIB_FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER);
+ IDP_foreach_property(
+ seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
+ BKE_LIB_FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER);
+ }
+
+ if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
+ TextVars *text_data = seq->effectdata;
+ BKE_LIB_FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER);
+ }
+ }
+ SEQ_END;
+ }
+
+ /* This pointer can be NULL during old files reading, better be safe than sorry. */
+ if (scene->master_collection != NULL) {
+ BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection);
+ }
+
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_LIB_FOREACHID_PROCESS(data, view_layer->mat_override, IDWALK_CB_USER);
+
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_LIB_FOREACHID_PROCESS(data, base->object, IDWALK_CB_NOP);
+ }
+
+ library_foreach_layer_collection(data, &view_layer->layer_collections);
+
+ LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
+ if (fmc->script) {
+ BKE_LIB_FOREACHID_PROCESS(data, fmc->script, IDWALK_CB_NOP);
+ }
+ }
+
+ LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
+ if (fls->group) {
+ BKE_LIB_FOREACHID_PROCESS(data, fls->group, IDWALK_CB_USER);
+ }
+
+ if (fls->linestyle) {
+ BKE_LIB_FOREACHID_PROCESS(data, fls->linestyle, IDWALK_CB_USER);
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
+ BKE_LIB_FOREACHID_PROCESS(data, marker->camera, IDWALK_CB_NOP);
+ }
+
+ ToolSettings *toolsett = scene->toolsettings;
+ if (toolsett) {
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.scene, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.object, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.shape_object, IDWALK_CB_NOP);
+
+ library_foreach_paint(data, &toolsett->imapaint.paint);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.stencil, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.clone, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.canvas, IDWALK_CB_USER);
+
+ if (toolsett->vpaint) {
+ library_foreach_paint(data, &toolsett->vpaint->paint);
+ }
+ if (toolsett->wpaint) {
+ library_foreach_paint(data, &toolsett->wpaint->paint);
+ }
+ if (toolsett->sculpt) {
+ library_foreach_paint(data, &toolsett->sculpt->paint);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
+ }
+ if (toolsett->uvsculpt) {
+ library_foreach_paint(data, &toolsett->uvsculpt->paint);
+ }
+ if (toolsett->gp_paint) {
+ library_foreach_paint(data, &toolsett->gp_paint->paint);
+ }
+ if (toolsett->gp_vertexpaint) {
+ library_foreach_paint(data, &toolsett->gp_vertexpaint->paint);
+ }
+ if (toolsett->gp_sculptpaint) {
+ library_foreach_paint(data, &toolsett->gp_sculptpaint->paint);
+ }
+ if (toolsett->gp_weightpaint) {
+ library_foreach_paint(data, &toolsett->gp_weightpaint->paint);
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP);
+ }
+
+ if (scene->rigidbody_world) {
+ BKE_rigidbody_world_id_loop(
+ scene->rigidbody_world, library_foreach_rigidbodyworldSceneLooper, data);
+ }
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -434,6 +586,7 @@ IDTypeInfo IDType_ID_SCE = {
/* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
* support all possible corner cases. */
.make_local = NULL,
+ .foreach_id = scene_foreach_id,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
@@ -1175,34 +1328,6 @@ int BKE_scene_orientation_slot_get_index(const TransformOrientationSlot *orient_
/** \} */
-/* That's like really a bummer, because currently animation data for armatures
- * might want to use pose, and pose might be missing on the object.
- * This happens when changing visible layers, which leads to situations when
- * pose is missing or marked for recalc, animation will change it and then
- * object update will restore the pose.
- *
- * This could be solved by the new dependency graph, but for until then we'll
- * do an extra pass on the objects to ensure it's all fine.
- */
-#define POSE_ANIMATION_WORKAROUND
-
-#ifdef POSE_ANIMATION_WORKAROUND
-static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgraph)
-{
- Object *ob;
- if (BLI_listbase_is_empty(&bmain->armatures) || !DEG_id_type_updated(depsgraph, ID_OB)) {
- return;
- }
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- if (ob->type == OB_ARMATURE && ob->adt) {
- if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
- BKE_pose_rebuild(bmain, ob, ob->data, true);
- }
- }
- }
-}
-#endif
-
static bool check_rendered_viewport_visible(Main *bmain)
{
wmWindowManager *wm = bmain->wm.first;
@@ -1387,9 +1512,6 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
BKE_image_editors_update_frame(bmain, scene->r.cfra);
BKE_sound_set_cfra(scene->r.cfra);
DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
-#ifdef POSE_ANIMATION_WORKAROUND
- scene_armature_depsgraph_workaround(bmain, depsgraph);
-#endif
/* Update all objects: drivers, matrices, displists, etc. flags set
* by depgraph or manual, no layer check here, gets correct flushed.
*
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 997e807a253..bfc0d437994 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -32,14 +32,18 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_workspace_types.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
+#include "BLI_mempool.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -48,6 +52,8 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
+#include "BKE_lib_query.h"
+#include "BKE_node.h"
#include "BKE_screen.h"
#include "BKE_workspace.h"
@@ -72,6 +78,158 @@ static void screen_free_data(ID *id)
MEM_SAFE_FREE(screen->tool_tip);
}
+static void screen_foreach_id_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
+{
+ if (ads != NULL) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, ads->source, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, ads->filter_grp, IDWALK_CB_NOP);
+ }
+}
+
+void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area)
+{
+ BKE_LIB_FOREACHID_PROCESS(data, area->full, IDWALK_CB_NOP);
+
+ /* TODO this should be moved to a callback in `SpaceType`, defined in each editor's own code.
+ * Will be for a later round of cleanup though... */
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D: {
+ View3D *v3d = (View3D *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->ob_center, IDWALK_CB_NOP);
+
+ if (v3d->localvd) {
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->localvd->camera, IDWALK_CB_NOP);
+ }
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+
+ screen_foreach_id_dopesheet(data, sipo->ads);
+ break;
+ }
+ case SPACE_PROPERTIES: {
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_FILE:
+ break;
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
+
+ screen_foreach_id_dopesheet(data, &saction->ads);
+ BKE_LIB_FOREACHID_PROCESS(data, saction->action, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sima->image, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sima->gpd, IDWALK_CB_USER);
+ break;
+ }
+ case SPACE_SEQ: {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sseq->gpd, IDWALK_CB_USER);
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ screen_foreach_id_dopesheet(data, snla->ads);
+ break;
+ }
+ case SPACE_TEXT: {
+ SpaceText *st = (SpaceText *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, st->text, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_SCRIPT: {
+ SpaceScript *scpt = (SpaceScript *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, scpt->script, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_OUTLINER: {
+ SpaceOutliner *so = (SpaceOutliner *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, so->search_tse.id, IDWALK_CB_NOP);
+
+ if (so->treestore != NULL) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, IDWALK_CB_NOP);
+ }
+ }
+ break;
+ }
+ case SPACE_NODE: {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ const bool is_private_nodetree = snode->id != NULL &&
+ ntreeFromID(snode->id) == snode->nodetree;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
+
+ BKE_LIB_FOREACHID_PROCESS(
+ data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
+
+ LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ BKE_LIB_FOREACHID_PROCESS(data,
+ path->nodetree,
+ is_private_nodetree ? IDWALK_CB_EMBEDDED :
+ IDWALK_CB_USER_ONE);
+ }
+ else {
+ BKE_LIB_FOREACHID_PROCESS(data, path->nodetree, IDWALK_CB_USER_ONE);
+ }
+
+ if (path->nodetree == NULL) {
+ break;
+ }
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, snode->edittree, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_CLIP: {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sclip->clip, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+static void screen_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
+ bScreen *screen = (bScreen *)id;
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ BKE_screen_foreach_id_screen_area(data, area);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_SCR = {
.id_code = ID_SCR,
.id_filter = 0,
@@ -86,6 +244,7 @@ IDTypeInfo IDType_ID_SCR = {
.copy_data = NULL,
.free_data = screen_free_data,
.make_local = NULL,
+ .foreach_id = screen_foreach_id,
};
/* ************ Spacetype/regiontype handling ************** */
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index a08bbf182fa..5c2d5b0087f 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -1217,6 +1217,11 @@ void BKE_sequencer_cache_cleanup_sequence(Scene *scene,
struct ImBuf *BKE_sequencer_cache_get(
const SeqRenderData *context, Sequence *seq, float cfra, int type, bool skip_disk_cache)
{
+
+ if (context->skip_cache || context->is_proxy_render || !seq) {
+ return NULL;
+ }
+
Scene *scene = context->scene;
if (context->is_prefetch_render) {
@@ -1314,6 +1319,10 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
float cost,
bool skip_disk_cache)
{
+ if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
+ return;
+ }
+
Scene *scene = context->scene;
if (context->is_prefetch_render) {
@@ -1322,10 +1331,6 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
seq = BKE_sequencer_prefetch_get_original_sequence(seq, scene);
}
- if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
- return;
- }
-
/* Prevent reinserting, it breaks cache key linking. */
ImBuf *test = BKE_sequencer_cache_get(context, seq, cfra, type, true);
if (test) {
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index f00d517940a..dc75e2b9098 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -179,12 +179,17 @@ static bool seq_prefetch_is_cache_full(Scene *scene)
return BKE_sequencer_cache_recycle_item(pfjob->scene) == false;
}
+static float seq_prefetch_cfra(PrefetchJob *pfjob)
+{
+ return pfjob->cfra + pfjob->num_frames_prefetched;
+}
+
void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
{
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
*start = pfjob->cfra;
- *end = pfjob->cfra + pfjob->num_frames_prefetched;
+ *end = seq_prefetch_cfra(pfjob);
}
static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
@@ -198,8 +203,7 @@ static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
{
- DEG_evaluate_on_framechange(
- pfjob->bmain_eval, pfjob->depsgraph, pfjob->cfra + pfjob->num_frames_prefetched);
+ DEG_evaluate_on_framechange(pfjob->bmain_eval, pfjob->depsgraph, seq_prefetch_cfra(pfjob));
}
static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
@@ -347,7 +351,7 @@ static bool seq_prefetch_do_skip_frame(Scene *scene)
{
Editing *ed = scene->ed;
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
- float cfra = pfjob->cfra + pfjob->num_frames_prefetched;
+ float cfra = seq_prefetch_cfra(pfjob);
Sequence *seq_arr[MAXSEQ + 1];
int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
SeqRenderData *ctx = &pfjob->context_cpy;
@@ -403,18 +407,37 @@ static bool seq_prefetch_do_skip_frame(Scene *scene)
return false;
}
+static bool seq_prefetch_need_suspend(PrefetchJob *pfjob)
+{
+ return seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain) ||
+ (seq_prefetch_cfra(pfjob) >= pfjob->scene->r.efra);
+}
+
+static void seq_prefetch_do_suspend(PrefetchJob *pfjob)
+{
+ BLI_mutex_lock(&pfjob->prefetch_suspend_mutex);
+ while (seq_prefetch_need_suspend(pfjob) &&
+ (pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !pfjob->stop) {
+ pfjob->waiting = true;
+ BLI_condition_wait(&pfjob->prefetch_suspend_cond, &pfjob->prefetch_suspend_mutex);
+ seq_prefetch_update_area(pfjob);
+ }
+ pfjob->waiting = false;
+ BLI_mutex_unlock(&pfjob->prefetch_suspend_mutex);
+}
+
static void *seq_prefetch_frames(void *job)
{
PrefetchJob *pfjob = (PrefetchJob *)job;
- while (pfjob->cfra + pfjob->num_frames_prefetched <= pfjob->scene->r.efra) {
+ while (seq_prefetch_cfra(pfjob) <= pfjob->scene->r.efra) {
pfjob->scene_eval->ed->prefetch_job = NULL;
seq_prefetch_update_depsgraph(pfjob);
AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
BKE_animsys_evaluate_animdata(&pfjob->context_cpy.scene->id,
adt,
- pfjob->cfra + pfjob->num_frames_prefetched,
+ seq_prefetch_cfra(pfjob),
ADT_RECALC_ALL,
false);
@@ -431,26 +454,17 @@ static void *seq_prefetch_frames(void *job)
continue;
}
- ImBuf *ibuf = BKE_sequencer_give_ibuf(
- &pfjob->context_cpy, pfjob->cfra + pfjob->num_frames_prefetched, 0);
+ ImBuf *ibuf = BKE_sequencer_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0);
BKE_sequencer_cache_free_temp_cache(
- pfjob->scene, pfjob->context.task_id, pfjob->cfra + pfjob->num_frames_prefetched);
+ pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
IMB_freeImBuf(ibuf);
- /* suspend thread */
- BLI_mutex_lock(&pfjob->prefetch_suspend_mutex);
- while ((seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain)) &&
- pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE && !pfjob->stop) {
- pfjob->waiting = true;
- BLI_condition_wait(&pfjob->prefetch_suspend_cond, &pfjob->prefetch_suspend_mutex);
- seq_prefetch_update_area(pfjob);
- }
- pfjob->waiting = false;
- BLI_mutex_unlock(&pfjob->prefetch_suspend_mutex);
+ /* Suspend thread if there is nothing to be prefetched. */
+ seq_prefetch_do_suspend(pfjob);
/* Avoid "collision" with main thread, but make sure to fetch at least few frames */
if (pfjob->num_frames_prefetched > 5 &&
- (pfjob->cfra + pfjob->num_frames_prefetched - pfjob->scene->r.cfra) < 2) {
+ (seq_prefetch_cfra(pfjob) - pfjob->scene->r.cfra) < 2) {
break;
}
@@ -463,7 +477,7 @@ static void *seq_prefetch_frames(void *job)
}
BKE_sequencer_cache_free_temp_cache(
- pfjob->scene, pfjob->context.task_id, pfjob->cfra + pfjob->num_frames_prefetched);
+ pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
pfjob->running = false;
pfjob->scene_eval->ed->prefetch_job = NULL;
@@ -520,10 +534,12 @@ void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, floa
seq_prefetch_resume(scene);
/* conditions to start:
* prefetch enabled, prefetch not running, not scrubbing,
- * not playing and rendering-expensive footage, cache storage enabled, has strips to render
+ * not playing and rendering-expensive footage, cache storage enabled, has strips to render,
+ * not rendering, not doing modal transform - important, see D7820.
*/
if ((ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !running && !scrubbing &&
- !(playing && cost > 0.9) && ed->cache_flag & SEQ_CACHE_ALL_TYPES && has_strips) {
+ !(playing && cost > 0.9) && ed->cache_flag & SEQ_CACHE_ALL_TYPES && has_strips &&
+ !G.is_rendering && !G.moving) {
seq_prefetch_start(context, cfra);
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index a14db79ffc6..954dca0f679 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1910,9 +1910,10 @@ static bool seq_proxy_get_fname(Editing *ed,
static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra)
{
char name[PROXY_MAXFILE];
- IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
- int size_flags;
StripProxy *proxy = seq->strip->proxy;
+ const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size;
+ const IMB_Proxy_Size psize_flag = seq_rendersize_to_proxysize(psize);
+ int size_flags;
Editing *ed = context->scene->ed;
StripAnim *sanim;
@@ -1923,7 +1924,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
size_flags = proxy->build_size_flags;
/* only use proxies, if they are enabled (even if present!) */
- if (psize == IMB_PROXY_NONE || (size_flags & psize) == 0) {
+ if (psize_flag == IMB_PROXY_NONE || (size_flags & psize_flag) == 0) {
return NULL;
}
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index b4cfa7cf0ef..50770125a18 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -87,13 +87,13 @@ static void simulation_free_data(ID *id)
}
}
-void *BKE_simulation_add(Main *bmain, const char *name)
+static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
{
- Simulation *simulation = (Simulation *)BKE_libblock_alloc(bmain, ID_SIM, name, 0);
-
- simulation_init_data(&simulation->id);
-
- return simulation;
+ Simulation *simulation = (Simulation *)id;
+ if (simulation->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
+ }
}
IDTypeInfo IDType_ID_SIM = {
@@ -110,8 +110,18 @@ IDTypeInfo IDType_ID_SIM = {
/* copy_data */ simulation_copy_data,
/* free_data */ simulation_free_data,
/* make_local */ nullptr,
+ /* foreach_id */ simulation_foreach_id,
};
+void *BKE_simulation_add(Main *bmain, const char *name)
+{
+ Simulation *simulation = (Simulation *)BKE_libblock_alloc(bmain, ID_SIM, name, 0);
+
+ simulation_init_data(&simulation->id);
+
+ return simulation;
+}
+
void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene))
{
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 5500918428f..e8f31594cc0 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -127,6 +127,7 @@ IDTypeInfo IDType_ID_SO = {
.copy_data = sound_copy_data,
.free_data = sound_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
#ifdef WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 1f7cb225fc7..fe1dd3835fd 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -38,6 +38,18 @@
#include "opensubdiv_evaluator_capi.h"
#include "opensubdiv_topology_refiner_capi.h"
+/* =================----====--===== MODULE ==========================------== */
+
+void BKE_subdiv_init()
+{
+ openSubdiv_init();
+}
+
+void BKE_subdiv_exit()
+{
+ openSubdiv_cleanup();
+}
+
/* ========================== CONVERSION HELPERS ============================ */
eSubdivFVarLinearInterpolation BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth)
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index c21d640a4c1..7a0a5645b80 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -71,18 +71,13 @@
#include "CCGSubSurf.h"
-#ifdef WITH_OPENSUBDIV
-# include "opensubdiv_capi.h"
-#endif
-
/* assumes MLoop's are laid out 4 for each poly, in order */
#define USE_LOOP_LAYOUT_FAST
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
- DerivedMesh *dm,
- bool use_gpu_backend);
+ DerivedMesh *dm);
///
static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
@@ -404,82 +399,6 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
return 1;
}
-#ifdef WITH_OPENSUBDIV
-static void UNUSED_FUNCTION(set_subsurf_osd_ccg_uv)(CCGSubSurf *ss,
- DerivedMesh *dm,
- DerivedMesh *result,
- int layer_index)
-{
- CCGFace **faceMap;
- MTFace *tf;
- MLoopUV *mluv;
- CCGFaceIterator fi;
- int index, gridSize, gridFaces, totface, x, y, S;
- MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
- /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
- * just tface except applying the modifier then looses subsurf UV */
- MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
- MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
-
- if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
- return;
- }
-
- ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
-
- /* get some info from CCGSubSurf */
- totface = ccgSubSurf_getNumFaces(ss);
- gridSize = ccgSubSurf_getGridSize(ss);
- gridFaces = gridSize - 1;
-
- /* make a map from original faces to CCGFaces */
- faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
- ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
- }
-
- /* load coordinates from uvss into tface */
- tf = tface;
- mluv = mloopuv;
- for (index = 0; index < totface; index++) {
- CCGFace *f = faceMap[index];
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- const int delta[4][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
- float uv[4][2];
- int i;
- for (i = 0; i < 4; i++) {
- const int dx = delta[i][0], dy = delta[i][1];
- const float grid_u = ((float)(x + dx)) / (gridSize - 1),
- grid_v = ((float)(y + dy)) / (gridSize - 1);
- ccgSubSurf_evaluatorFVarUV(ss, index, S, grid_u, grid_v, uv[i]);
- }
- if (tf) {
- copy_v2_v2(tf->uv[0], uv[0]);
- copy_v2_v2(tf->uv[1], uv[1]);
- copy_v2_v2(tf->uv[2], uv[2]);
- copy_v2_v2(tf->uv[3], uv[3]);
- tf++;
- }
- if (mluv) {
- copy_v2_v2(mluv[0].uv, uv[0]);
- copy_v2_v2(mluv[1].uv, uv[1]);
- copy_v2_v2(mluv[2].uv, uv[2]);
- copy_v2_v2(mluv[3].uv, uv[3]);
- mluv += 4;
- }
- }
- }
- }
- }
- MEM_freeN(faceMap);
-}
-#endif /* WITH_OPENSUBDIV */
-
static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
{
CCGSubSurf *uvss;
@@ -564,16 +483,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
{
-#ifdef WITH_OPENSUBDIV
- if (!ccgSubSurf_needGrids(ss)) {
- /* GPU backend is used, no need to evaluate UVs on CPU. */
- /* TODO(sergey): Think of how to support edit mode of UVs. */
- }
- else
-#endif
- {
- set_subsurf_legacy_uv(ss, dm, result, layer_index);
- }
+ set_subsurf_legacy_uv(ss, dm, result, layer_index);
}
/* face weighting */
@@ -763,40 +673,13 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
#endif
}
-#ifdef WITH_OPENSUBDIV
-static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm)
-{
- ccgSubSurf_initFullSync(ss);
- ccgSubSurf_prepareTopologyRefiner(ss, dm);
- ccgSubSurf_processSync(ss);
-}
-#endif /* WITH_OPENSUBDIV */
-
static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
DerivedMesh *dm,
float (*vertexCos)[3],
int use_flat_subdiv,
- bool use_subdiv_uvs)
+ bool UNUSED(use_subdiv_uvs))
{
-#ifndef WITH_OPENSUBDIV
- UNUSED_VARS(use_subdiv_uvs);
-#endif
-
-#ifdef WITH_OPENSUBDIV
- /* Reset all related descriptors if actual mesh topology changed or if
- * other evaluation-related settings changed.
- */
- if (!ccgSubSurf_needGrids(ss)) {
- /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
- ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs);
- ccgSubSurf_checkTopologyChanged(ss, dm);
- ss_sync_osd_from_derivedmesh(ss, dm);
- }
- else
-#endif
- {
- ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
- }
+ ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
}
/***/
@@ -850,13 +733,6 @@ static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], fl
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max);
- return;
- }
-#endif
-
CCG_key_top_level(&key, ss);
if (!ccgSubSurf_getNumVerts(ss)) {
@@ -1642,11 +1518,9 @@ static void ccgDM_release(DerivedMesh *dm)
}
MEM_freeN(ccgdm->edgeFlags);
MEM_freeN(ccgdm->faceFlags);
- if (ccgdm->useGpuBackend == false) {
- MEM_freeN(ccgdm->vertMap);
- MEM_freeN(ccgdm->edgeMap);
- MEM_freeN(ccgdm->faceMap);
- }
+ MEM_freeN(ccgdm->vertMap);
+ MEM_freeN(ccgdm->edgeMap);
+ MEM_freeN(ccgdm->faceMap);
BLI_mutex_end(&ccgdm->loops_cache_lock);
BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
@@ -2417,76 +2291,44 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
}
-/* Fill in only geometry arrays needed for the GPU tessellation. */
-static void set_ccgdm_gpu_geometry(CCGDerivedMesh *ccgdm, DerivedMesh *dm)
-{
- const int totface = dm->getNumPolys(dm);
- MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
- int index;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
-
- for (index = 0; index < totface; index++) {
- faceFlags->flag = mpoly ? mpoly[index].flag : 0;
- faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0;
- faceFlags++;
- }
-
- /* TODO(sergey): Fill in edge flags. */
-}
-
-static CCGDerivedMesh *getCCGDerivedMesh(
- CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm, bool use_gpu_backend)
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
+ int drawInteriorEdges,
+ int useSubsurfUv,
+ DerivedMesh *dm)
{
-#ifdef WITH_OPENSUBDIV
- const int totedge = dm->getNumEdges(dm);
- const int totface = dm->getNumPolys(dm);
-#else
const int totedge = ccgSubSurf_getNumEdges(ss);
const int totface = ccgSubSurf_getNumFaces(ss);
-#endif
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
- if (use_gpu_backend == false) {
- BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
- BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
- DM_from_template(&ccgdm->dm,
- dm,
- DM_TYPE_CCGDM,
- ccgSubSurf_getNumFinalVerts(ss),
- ccgSubSurf_getNumFinalEdges(ss),
- 0,
- ccgSubSurf_getNumFinalFaces(ss) * 4,
- ccgSubSurf_getNumFinalFaces(ss));
+ BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
+ BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
+ DM_from_template(&ccgdm->dm,
+ dm,
+ DM_TYPE_CCGDM,
+ ccgSubSurf_getNumFinalVerts(ss),
+ ccgSubSurf_getNumFinalEdges(ss),
+ 0,
+ ccgSubSurf_getNumFinalFaces(ss) * 4,
+ ccgSubSurf_getNumFinalFaces(ss));
- CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
+ CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
- ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
- "reverseFaceMap");
+ ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
+ "reverseFaceMap");
- create_ccgdm_maps(ccgdm, ss);
- }
- else {
- DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, 0, 0, 0, 0, dm->getNumPolys(dm));
- CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, 0, 0, dm->getNumPolys(dm));
- }
+ create_ccgdm_maps(ccgdm, ss);
set_default_ccgdm_callbacks(ccgdm);
ccgdm->ss = ss;
ccgdm->drawInteriorEdges = drawInteriorEdges;
ccgdm->useSubsurfUv = useSubsurfUv;
- ccgdm->useGpuBackend = use_gpu_backend;
/* CDDM hack. */
ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
- if (use_gpu_backend == false) {
- set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
- }
- else {
- set_ccgdm_gpu_geometry(ccgdm, dm);
- }
+ set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
@@ -2502,21 +2344,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(
/***/
-static bool subsurf_use_gpu_backend(SubsurfFlags flags)
-{
-#ifdef WITH_OPENSUBDIV
- /* Use GPU backend if it's a last modifier in the stack
- * and user chose to use any of the OSD compute devices,
- * but also check if GPU has all needed features.
- */
- return (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
- (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
-#else
- (void)flags;
- return false;
-#endif
-}
-
struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
const struct Scene *scene,
@@ -2527,7 +2354,6 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
- const bool use_gpu_backend = subsurf_use_gpu_backend(flags);
const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
CCGDerivedMesh *result;
@@ -2546,11 +2372,8 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
-#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend);
-#endif
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm);
}
else if (flags & SUBSURF_USE_RENDER_PARAMS) {
/* Do not use cache in render mode. */
@@ -2567,7 +2390,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, false);
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
result->freeSS = 1;
}
@@ -2600,32 +2423,15 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm, false);
+ result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm);
}
else {
CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
CCGSubSurf *prevSS = NULL;
if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
-#ifdef WITH_OPENSUBDIV
- /* With OpenSubdiv enabled we always tries to re-use previous
- * subsurf structure in order to save computation time since
- * re-creation is rather a complicated business.
- *
- * TODO(sergey): There was a good reason why final calculation
- * used to free entirely cached subsurf structure. reason of
- * this is to be investigated still to be sure we don't have
- * regressions here.
- */
- if (use_gpu_backend) {
- prevSS = smd->mCache;
- }
- else
-#endif
- {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
- }
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
}
if (flags & SUBSURF_ALLOC_PAINT_MASK) {
@@ -2633,12 +2439,9 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
}
ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
-#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(ss, use_gpu_backend);
-#endif
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
if (flags & SUBSURF_IS_FINAL_CALC) {
smd->mCache = ss;
@@ -2710,26 +2513,10 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
bool subsurf_has_edges(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
-#else
- (void)ccgdm;
-#endif
return dm->getNumEdges(dm) != 0;
}
bool subsurf_has_faces(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
-#else
- (void)ccgdm;
-#endif
return dm->getNumPolys(dm) != 0;
}
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 3cdf3b40ce3..527b54a1aa2 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -206,6 +206,7 @@ IDTypeInfo IDType_ID_TXT = {
.copy_data = text_copy_data,
.free_data = text_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/***/
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index dffc703c943..e09e92588c6 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -42,6 +42,7 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "MEM_guardedalloc.h"
@@ -1399,7 +1400,7 @@ ImBuf *BKE_tracking_stabilize_frame(
return ibuf;
}
- /* Allocate frame for stabilization result. */
+ /* Allocate frame for stabilization result, copy alpha mode and colorspace. */
ibuf_flags = 0;
if (ibuf->rect) {
ibuf_flags |= IB_rect;
@@ -1409,6 +1410,7 @@ ImBuf *BKE_tracking_stabilize_frame(
}
tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ibuf_flags);
+ IMB_colormanagegent_copy_settings(ibuf, tmpibuf);
/* Calculate stabilization matrix. */
BKE_tracking_stabilization_data_get(clip, framenr, width, height, tloc, &tscale, &tangle);
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 629c01ec298..dcaa9082026 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -713,7 +713,7 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
*/
const size_t size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
grayscale->channels = 1;
- if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ if ((grayscale->rect_float = MEM_callocN(size, "tracking grayscale image")) != NULL) {
grayscale->mall |= IB_rectfloat;
grayscale->flags |= IB_rectfloat;
@@ -741,7 +741,7 @@ static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
size_t size = (size_t)ibuf->x * (size_t)ibuf->y * float_image->channels * sizeof(float);
ibuf->channels = float_image->channels;
- if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ if ((ibuf->rect_float = MEM_callocN(size, "tracking grayscale image")) != NULL) {
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 9e636c0ee8b..26c5810aefa 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -21,6 +21,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_volume_types.h"
@@ -442,26 +443,6 @@ static void volume_init_data(ID *id)
BKE_volume_init_grids(volume);
}
-void BKE_volume_init_grids(Volume *volume)
-{
-#ifdef WITH_OPENVDB
- if (volume->runtime.grids == NULL) {
- volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
- }
-#else
- UNUSED_VARS(volume);
-#endif
-}
-
-void *BKE_volume_add(Main *bmain, const char *name)
-{
- Volume *volume = (Volume *)BKE_libblock_alloc(bmain, ID_VO, name, 0);
-
- volume_init_data(&volume->id);
-
- return volume;
-}
-
static void volume_copy_data(Main *UNUSED(bmain),
ID *id_dst,
const ID *id_src,
@@ -483,18 +464,6 @@ static void volume_copy_data(Main *UNUSED(bmain),
#endif
}
-Volume *BKE_volume_copy(Main *bmain, const Volume *volume)
-{
- Volume *volume_copy;
- BKE_id_copy(bmain, &volume->id, (ID **)&volume_copy);
- return volume_copy;
-}
-
-static void volume_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void volume_free_data(ID *id)
{
Volume *volume = (Volume *)id;
@@ -506,6 +475,14 @@ static void volume_free_data(ID *id)
#endif
}
+static void volume_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Volume *volume = (Volume *)id;
+ for (int i = 0; i < volume->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, volume->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_VO = {
/* id_code */ ID_VO,
/* id_filter */ FILTER_ID_VO,
@@ -519,9 +496,37 @@ IDTypeInfo IDType_ID_VO = {
/* init_data */ volume_init_data,
/* copy_data */ volume_copy_data,
/* free_data */ volume_free_data,
- /* make_local */ volume_make_local,
+ /* make_local */ nullptr,
+ /* foreach_id */ volume_foreach_id,
};
+void BKE_volume_init_grids(Volume *volume)
+{
+#ifdef WITH_OPENVDB
+ if (volume->runtime.grids == NULL) {
+ volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
+ }
+#else
+ UNUSED_VARS(volume);
+#endif
+}
+
+void *BKE_volume_add(Main *bmain, const char *name)
+{
+ Volume *volume = (Volume *)BKE_libblock_alloc(bmain, ID_VO, name, 0);
+
+ volume_init_data(&volume->id);
+
+ return volume;
+}
+
+Volume *BKE_volume_copy(Main *bmain, const Volume *volume)
+{
+ Volume *volume_copy;
+ BKE_id_copy(bmain, &volume->id, (ID **)&volume_copy);
+ return volume_copy;
+}
+
/* Sequence */
static int volume_sequence_frame(const Depsgraph *depsgraph, const Volume *volume)
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index c65d55785c1..3a69b95c114 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -32,6 +32,7 @@
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -65,6 +66,23 @@ static void workspace_free_data(ID *id)
MEM_SAFE_FREE(workspace->status_text);
}
+static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ WorkSpace *workspace = (WorkSpace *)id;
+ ListBase *layouts = BKE_workspace_layouts_get(workspace);
+
+ LISTBASE_FOREACH (WorkSpaceLayout *, layout, layouts) {
+ bScreen *screen = BKE_workspace_layout_screen_get(layout);
+
+ /* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
+ * However we can't access layout->screen here
+ * since we are outside the workspace project. */
+ BKE_LIB_FOREACHID_PROCESS(data, screen, IDWALK_CB_USER);
+ /* allow callback to set a different screen */
+ BKE_workspace_layout_screen_set(layout, screen);
+ }
+}
+
IDTypeInfo IDType_ID_WS = {
.id_code = ID_WS,
.id_filter = FILTER_ID_WS,
@@ -79,6 +97,7 @@ IDTypeInfo IDType_ID_WS = {
.copy_data = NULL,
.free_data = workspace_free_data,
.make_local = NULL,
+ .foreach_id = workspace_foreach_id,
};
/** \name Internal Utils
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 16e56200131..724c4ab93b2 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -606,7 +606,10 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
c->gop_size = context->ffmpeg_gop_size;
c->max_b_frames = context->ffmpeg_max_b_frames;
- if (context->ffmpeg_crf >= 0) {
+ if (context->ffmpeg_type == FFMPEG_WEBM && context->ffmpeg_crf == 0) {
+ ffmpeg_dict_set_int(&opts, "lossless", 1);
+ }
+ else if (context->ffmpeg_crf >= 0) {
ffmpeg_dict_set_int(&opts, "crf", context->ffmpeg_crf);
}
else {