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/scene.c')
-rw-r--r--source/blender/blenkernel/intern/scene.c240
1 files changed, 185 insertions, 55 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b12402d74fc..aa2a1b14841 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"
@@ -59,13 +61,14 @@
#include "BLT_translation.h"
#include "BKE_action.h"
-#include "BKE_anim.h"
+#include "BKE_anim_data.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_cachefile.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_curveprofile.h"
+#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
#include "BKE_fcurve.h"
#include "BKE_freestyle.h"
@@ -76,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"
@@ -154,6 +158,9 @@ static void scene_init_data(ID *id)
scene->unit.mass_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_MASS);
scene->unit.time_unit = (uchar)bUnit_GetBaseUnitOfType(USER_UNIT_METRIC, B_UNIT_TIME);
+ /* Anti-Aliasing threshold. */
+ scene->grease_pencil_settings.smaa_threshold = 1.0f;
+
{
ParticleEditSettings *pset;
pset = &scene->toolsettings->particle;
@@ -339,12 +346,17 @@ static void scene_free_data(ID *id)
/* is no lib link block, but scene extension */
if (scene->nodetree) {
- ntreeFreeNestedTree(scene->nodetree);
+ ntreeFreeEmbeddedTree(scene->nodetree);
MEM_freeN(scene->nodetree);
scene->nodetree = NULL;
}
if (scene->rigidbody_world) {
+ /* Prevent rigidbody freeing code to follow other IDs pointers, this should never be allowed
+ * nor necessary from here, and with new undo code, those pointers may be fully invalid or
+ * worse, pointing to data actually belonging to new BMain! */
+ scene->rigidbody_world->constraints = NULL;
+ scene->rigidbody_world->group = NULL;
BKE_rigidbody_free_world(scene);
}
@@ -409,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,
@@ -425,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";
@@ -459,7 +621,7 @@ static void remove_sequencer_fcurves(Scene *sce)
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
action_groups_remove_channel(adt->action, fcu);
- free_fcurve(fcu);
+ BKE_fcurve_free(fcu);
}
}
}
@@ -506,7 +668,6 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
}
BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag);
- ts->imapaint.paintcursor = NULL;
ts->particle.paintcursor = NULL;
ts->particle.scene = NULL;
ts->particle.object = NULL;
@@ -668,10 +829,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
if (type == SCE_COPY_FULL) {
/* Copy Freestyle LineStyle datablocks. */
- for (ViewLayer *view_layer_dst = sce_copy->view_layers.first; view_layer_dst;
- view_layer_dst = view_layer_dst->next) {
- for (FreestyleLineSet *lineset = view_layer_dst->freestyle_config.linesets.first; lineset;
- lineset = lineset->next) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
+ LISTBASE_FOREACH (
+ FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
if (lineset->linestyle) {
id_us_min(&lineset->linestyle->id);
BKE_id_copy_ex(
@@ -731,8 +891,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
*/
bool BKE_scene_object_find(Scene *scene, Object *ob)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
- view_layer = view_layer->next) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
if (BLI_findptr(&view_layer->object_bases, ob, offsetof(Base, object))) {
return true;
}
@@ -742,9 +901,8 @@ bool BKE_scene_object_find(Scene *scene, Object *ob)
Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
- view_layer = view_layer->next) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (STREQ(base->object->id.name + 2, name)) {
return base->object;
}
@@ -772,9 +930,8 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
}
/* copy layers and flags from bases to objects */
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer;
- view_layer = view_layer->next) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
ob = base->object;
/* collection patch... */
BKE_scene_object_base_flag_sync_from_base(base);
@@ -928,7 +1085,7 @@ int BKE_scene_base_iter_next(
Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
{
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
- for (ViewLayer *layer = scene->view_layers.first; layer; layer = layer->next) {
+ LISTBASE_FOREACH (ViewLayer *, layer, &scene->view_layers) {
if (BKE_view_layer_has_collection(layer, collection)) {
return scene;
}
@@ -954,7 +1111,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene)
Object *camera = NULL;
Object *first_camera = NULL;
- for (TimeMarker *m = scene->markers.first; m; m = m->next) {
+ LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) {
if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0) {
if ((m->frame <= cfra) && (m->frame > frame)) {
camera = m->camera;
@@ -1091,9 +1248,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
}
/**
- * This function is needed to cope with fractional frames - including two Blender rendering
- * features mblur (motion blur that renders 'subframes' and blurs them together),
- * and fields rendering.
+ * This function is needed to cope with fractional frames, needed for motion blur & physics.
*/
float BKE_scene_frame_get(const Scene *scene)
{
@@ -1170,34 +1325,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;
@@ -1281,6 +1408,14 @@ void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain)
BKE_sound_update_scene(depsgraph, scene);
}
+void BKE_scene_update_tag_audio_volume(Depsgraph *UNUSED(depsgraph), Scene *scene)
+{
+ BLI_assert(DEG_is_evaluated_id(&scene->id));
+ /* The volume is actually updated in BKE_scene_update_sound(), from either
+ * scene_graph_update_tagged() or from BKE_scene_graph_update_for_newframe(). */
+ scene->id.recalc |= ID_RECALC_AUDIO_VOLUME;
+}
+
/* TODO(sergey): This actually should become view_layer_graph or so.
* Same applies to update_for_newframe.
*
@@ -1374,9 +1509,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.
*
@@ -2097,7 +2229,7 @@ static Depsgraph **scene_get_depsgraph_p(Main *bmain,
if (allocate_depsgraph) {
*depsgraph_ptr = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
/* TODO(sergey): Would be cool to avoid string format print,
- * but is a bit tricky because we can't know in advance whether
+ * but is a bit tricky because we can't know in advance whether
* we will ever enable debug messages for this depsgraph.
*/
char name[1024];
@@ -2170,8 +2302,6 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain)
void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
{
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
- BLI_assert(scene->depsgraph_hash == NULL);
-
for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
view_layer = view_layer->next) {
char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0};