2017-11-30 16:49:32 +01:00
|
|
|
/*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2017 Blender Foundation.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup depsgraph
|
2017-11-30 16:49:32 +01:00
|
|
|
*
|
|
|
|
|
* Implementation of Querying and Filtering API's
|
|
|
|
|
*/
|
|
|
|
|
|
2018-04-28 16:20:19 +02:00
|
|
|
/* Silence warnings from copying deprecated fields. */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2020-04-03 11:35:04 +02:00
|
|
|
#include "BKE_duplilist.h"
|
2020-12-02 13:28:08 +01:00
|
|
|
#include "BKE_geometry_set.hh"
|
2017-12-01 11:24:21 -02:00
|
|
|
#include "BKE_idprop.h"
|
2017-11-30 16:49:32 +01:00
|
|
|
#include "BKE_layer.h"
|
2018-05-29 15:57:14 +02:00
|
|
|
#include "BKE_node.h"
|
2017-12-15 07:51:16 -02:00
|
|
|
#include "BKE_object.h"
|
2020-05-08 18:16:39 +02:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_math.h"
|
|
|
|
|
#include "BLI_utildefines.h"
|
2017-11-30 16:49:32 +01:00
|
|
|
|
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
|
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
#include "DEG_depsgraph_query.h"
|
|
|
|
|
|
2019-01-31 12:56:40 +01:00
|
|
|
#include "intern/depsgraph.h"
|
|
|
|
|
#include "intern/node/deg_node_id.h"
|
2017-12-20 16:40:49 +01:00
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
#ifndef NDEBUG
|
|
|
|
|
# include "intern/eval/deg_eval_copy_on_write.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-06-12 09:55:34 +02:00
|
|
|
// If defined, all working data will be set to an invalid state, helping
|
|
|
|
|
// to catch issues when areas accessing data which is considered to be no
|
|
|
|
|
// longer available.
|
|
|
|
|
#undef INVALIDATE_WORK_DATA
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
# define INVALIDATE_WORK_DATA
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-06-29 15:19:56 +02:00
|
|
|
namespace deg = blender::deg;
|
|
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
/* ************************ DEG ITERATORS ********************* */
|
|
|
|
|
|
2018-06-12 09:46:00 +02:00
|
|
|
namespace {
|
|
|
|
|
|
2018-06-12 09:55:34 +02:00
|
|
|
void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
|
|
|
|
|
{
|
|
|
|
|
#ifdef INVALIDATE_WORK_DATA
|
2020-01-28 14:50:13 +01:00
|
|
|
BLI_assert(data != nullptr);
|
2018-06-12 09:55:34 +02:00
|
|
|
memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
|
|
|
|
|
#else
|
|
|
|
|
(void)data;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-21 14:54:18 +12:00
|
|
|
void verify_id_properties_freed(DEGObjectIterData *data)
|
2018-01-24 15:46:34 +01:00
|
|
|
{
|
2020-01-28 14:50:13 +01:00
|
|
|
if (data->dupli_object_current == nullptr) {
|
2018-01-24 15:46:34 +01:00
|
|
|
// We didn't enter duplication yet, so we can't have any dangling
|
|
|
|
|
// pointers.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const Object *dupli_object = data->dupli_object_current->ob;
|
|
|
|
|
Object *temp_dupli_object = &data->temp_dupli_object;
|
2020-01-28 14:50:13 +01:00
|
|
|
if (temp_dupli_object->id.properties == nullptr) {
|
2018-09-24 18:46:51 +02:00
|
|
|
// No ID properties in temp datablock -- no leak is possible.
|
2018-01-24 15:46:34 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (temp_dupli_object->id.properties == dupli_object->id.properties) {
|
|
|
|
|
// Temp copy of object did not modify ID properties.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Free memory which is owned by temporary storage which is about to
|
|
|
|
|
// get overwritten.
|
|
|
|
|
IDP_FreeProperty(temp_dupli_object->id.properties);
|
2020-01-28 14:50:13 +01:00
|
|
|
temp_dupli_object->id.properties = nullptr;
|
2018-01-24 15:46:34 +01:00
|
|
|
}
|
|
|
|
|
|
2020-07-03 12:57:16 +02:00
|
|
|
bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
|
2018-12-18 18:18:00 +01:00
|
|
|
{
|
|
|
|
|
/* Automatic hiding if this object is being instanced on verts/faces/frames
|
|
|
|
|
* by its parent. Ideally this should not be needed, but due to the wrong
|
|
|
|
|
* dependency direction in the data design there is no way to keep the object
|
|
|
|
|
* visible otherwise. The better solution eventually would be for objects
|
2020-04-24 17:23:44 +02:00
|
|
|
* to specify which object they instance, instead of through parenting.
|
|
|
|
|
*
|
2020-08-17 12:34:05 +10:00
|
|
|
* This function should not be used for meta-balls. They have custom visibility rules, as hiding
|
|
|
|
|
* the base meta-ball will also hide all the other balls in the group. */
|
2018-12-18 18:18:00 +01:00
|
|
|
if (eval_mode == DAG_EVAL_RENDER || dob) {
|
2019-01-28 17:52:46 +01:00
|
|
|
const int hide_original_types = OB_DUPLIVERTS | OB_DUPLIFACES;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-18 18:18:00 +01:00
|
|
|
if (!dob || !(dob->type & hide_original_types)) {
|
|
|
|
|
if (ob->parent && (ob->parent->transflag & hide_original_types)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-18 18:18:00 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
void deg_iterator_components_init(DEGObjectIterData *data, Object *object)
|
|
|
|
|
{
|
|
|
|
|
data->geometry_component_owner = object;
|
|
|
|
|
data->geometry_component_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns false when iterator is exhausted. */
|
|
|
|
|
bool deg_iterator_components_step(BLI_Iterator *iter)
|
2017-11-30 16:49:32 +01:00
|
|
|
{
|
2017-12-15 08:11:19 -02:00
|
|
|
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
|
2020-12-02 13:28:08 +01:00
|
|
|
if (data->geometry_component_owner == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
if (data->geometry_component_owner->runtime.geometry_set_eval == nullptr) {
|
|
|
|
|
/* Return the object itself, if it does not have a geometry set yet. */
|
2020-12-02 13:28:08 +01:00
|
|
|
iter->current = data->geometry_component_owner;
|
|
|
|
|
data->geometry_component_owner = nullptr;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GeometrySet *geometry_set = data->geometry_component_owner->runtime.geometry_set_eval;
|
|
|
|
|
if (geometry_set == nullptr) {
|
|
|
|
|
data->geometry_component_owner = nullptr;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
/* The mesh component. */
|
2020-12-02 13:28:08 +01:00
|
|
|
if (data->geometry_component_id == 0) {
|
|
|
|
|
data->geometry_component_id++;
|
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
/* Don't use a temporary object for this component, when the owner is a mesh object. */
|
|
|
|
|
if (data->geometry_component_owner->type == OB_MESH) {
|
|
|
|
|
iter->current = data->geometry_component_owner;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
const Mesh *mesh = geometry_set->get_mesh_for_read();
|
|
|
|
|
if (mesh != nullptr) {
|
|
|
|
|
Object *temp_object = &data->temp_geometry_component_object;
|
|
|
|
|
*temp_object = *data->geometry_component_owner;
|
|
|
|
|
temp_object->type = OB_MESH;
|
|
|
|
|
temp_object->data = (void *)mesh;
|
|
|
|
|
temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
|
|
|
|
|
iter->current = temp_object;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-15 12:42:10 +01:00
|
|
|
|
|
|
|
|
/* The pointcloud component. */
|
2020-12-02 13:28:08 +01:00
|
|
|
if (data->geometry_component_id == 1) {
|
|
|
|
|
data->geometry_component_id++;
|
|
|
|
|
|
2020-12-15 12:42:10 +01:00
|
|
|
/* Don't use a temporary object for this component, when the owner is a point cloud object. */
|
|
|
|
|
if (data->geometry_component_owner->type == OB_POINTCLOUD) {
|
|
|
|
|
iter->current = data->geometry_component_owner;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
const PointCloud *pointcloud = geometry_set->get_pointcloud_for_read();
|
|
|
|
|
if (pointcloud != nullptr) {
|
|
|
|
|
Object *temp_object = &data->temp_geometry_component_object;
|
|
|
|
|
*temp_object = *data->geometry_component_owner;
|
|
|
|
|
temp_object->type = OB_POINTCLOUD;
|
|
|
|
|
temp_object->data = (void *)pointcloud;
|
|
|
|
|
temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
|
|
|
|
|
iter->current = temp_object;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-15 12:42:10 +01:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
data->geometry_component_owner = nullptr;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deg_iterator_duplis_init(DEGObjectIterData *data, Object *object)
|
|
|
|
|
{
|
|
|
|
|
if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
|
|
|
|
|
((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
|
|
|
|
|
data->dupli_parent = object;
|
|
|
|
|
data->dupli_list = object_duplilist(data->graph, data->scene, object);
|
|
|
|
|
data->dupli_object_next = (DupliObject *)data->dupli_list->first;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns false when iterator is exhausted. */
|
|
|
|
|
bool deg_iterator_duplis_step(DEGObjectIterData *data)
|
|
|
|
|
{
|
|
|
|
|
if (data->dupli_list == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 14:50:13 +01:00
|
|
|
while (data->dupli_object_next != nullptr) {
|
2017-11-30 16:49:32 +01:00
|
|
|
DupliObject *dob = data->dupli_object_next;
|
|
|
|
|
Object *obd = dob->ob;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
data->dupli_object_next = data->dupli_object_next->next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-18 18:18:00 +01:00
|
|
|
if (dob->no_draw) {
|
2017-11-30 16:49:32 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (obd->type == OB_MBALL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-12-18 18:18:00 +01:00
|
|
|
if (deg_object_hide_original(data->eval_mode, dob->ob, dob)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-21 14:54:18 +12:00
|
|
|
verify_id_properties_freed(data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
data->dupli_object_current = dob;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
/* Temporary object to evaluate. */
|
|
|
|
|
Object *dupli_parent = data->dupli_parent;
|
|
|
|
|
Object *temp_dupli_object = &data->temp_dupli_object;
|
|
|
|
|
*temp_dupli_object = *dob->ob;
|
2019-01-15 23:27:54 +11:00
|
|
|
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI;
|
2018-11-25 09:50:34 -02:00
|
|
|
temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits;
|
2019-09-24 10:32:00 -03:00
|
|
|
temp_dupli_object->runtime.local_collections_bits =
|
|
|
|
|
dupli_parent->runtime.local_collections_bits;
|
2019-03-12 13:21:54 +01:00
|
|
|
temp_dupli_object->dt = MIN2(temp_dupli_object->dt, dupli_parent->dt);
|
2019-03-12 12:28:01 +11:00
|
|
|
copy_v4_v4(temp_dupli_object->color, dupli_parent->color);
|
2020-11-24 17:32:40 +01:00
|
|
|
temp_dupli_object->runtime.select_id = dupli_parent->runtime.select_id;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-02-05 19:01:25 -02:00
|
|
|
/* Duplicated elements shouldn't care whether their original collection is visible or not. */
|
2019-10-03 19:22:36 -03:00
|
|
|
temp_dupli_object->base_flag |= BASE_VISIBLE_DEPSGRAPH;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-18 18:18:00 +01:00
|
|
|
int ob_visibility = BKE_object_visibility(temp_dupli_object, data->eval_mode);
|
2019-06-17 13:39:47 +02:00
|
|
|
if ((ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) == 0) {
|
2018-02-05 19:01:25 -02:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-10 14:46:01 +02:00
|
|
|
/* This could be avoided by refactoring make_dupli() in order to track all negative scaling
|
|
|
|
|
* recursively. */
|
|
|
|
|
bool is_neg_scale = is_negative_m4(dob->mat);
|
|
|
|
|
SET_FLAG_FROM_TEST(data->temp_dupli_object.transflag, is_neg_scale, OB_NEG_SCALE);
|
|
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
|
2019-05-10 14:46:01 +02:00
|
|
|
invert_m4_m4(data->temp_dupli_object.imat, data->temp_dupli_object.obmat);
|
2020-12-02 13:28:08 +01:00
|
|
|
deg_iterator_components_init(data, &data->temp_dupli_object);
|
2020-06-29 15:19:56 +02:00
|
|
|
BLI_assert(deg::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id));
|
2017-11-30 16:49:32 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
verify_id_properties_freed(data);
|
|
|
|
|
free_object_duplilist(data->dupli_list);
|
|
|
|
|
data->dupli_parent = nullptr;
|
|
|
|
|
data->dupli_list = nullptr;
|
|
|
|
|
data->dupli_object_next = nullptr;
|
|
|
|
|
data->dupli_object_current = nullptr;
|
|
|
|
|
deg_invalidate_iterator_work_data(data);
|
2017-11-30 16:49:32 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
/* Returns false when iterator is exhausted. */
|
|
|
|
|
bool deg_iterator_objects_step(DEGObjectIterData *data)
|
2017-11-30 16:49:32 +01:00
|
|
|
{
|
2020-12-02 13:28:08 +01:00
|
|
|
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(data->graph);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
for (; data->id_node_index < data->num_id_nodes; data->id_node_index++) {
|
|
|
|
|
deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
if (!id_node->is_directly_visible) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
const ID_Type id_type = GS(id_node->id_orig->name);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
if (id_type != ID_OB) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
switch (id_node->linked_state) {
|
|
|
|
|
case deg::DEG_ID_LINKED_DIRECTLY:
|
|
|
|
|
if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case deg::DEG_ID_LINKED_VIA_SET:
|
|
|
|
|
if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case deg::DEG_ID_LINKED_INDIRECTLY:
|
|
|
|
|
if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY) == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
Object *object = (Object *)id_node->id_cow;
|
|
|
|
|
BLI_assert(deg::deg_validate_copy_on_write_datablock(&object->id));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
int ob_visibility = OB_VISIBLE_ALL;
|
|
|
|
|
if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
|
|
|
|
|
ob_visibility = BKE_object_visibility(object, data->eval_mode);
|
|
|
|
|
|
|
|
|
|
if (object->type != OB_MBALL && deg_object_hide_original(data->eval_mode, object, nullptr)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-11-30 16:49:32 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
object->runtime.select_id = DEG_get_original_object(object)->runtime.select_id;
|
|
|
|
|
if (ob_visibility & OB_VISIBLE_INSTANCES) {
|
|
|
|
|
deg_iterator_duplis_init(data, object);
|
2018-12-18 18:18:00 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
|
|
|
|
|
deg_iterator_components_init(data, object);
|
|
|
|
|
}
|
|
|
|
|
data->id_node_index++;
|
|
|
|
|
return true;
|
2018-12-18 18:18:00 +01:00
|
|
|
}
|
2020-12-02 13:28:08 +01:00
|
|
|
return false;
|
2017-11-30 16:49:32 +01:00
|
|
|
}
|
|
|
|
|
|
2018-06-12 09:46:00 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
2017-12-15 08:11:19 -02:00
|
|
|
void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
|
2017-11-30 16:49:32 +01:00
|
|
|
{
|
|
|
|
|
Depsgraph *depsgraph = data->graph;
|
2020-06-29 15:19:56 +02:00
|
|
|
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
2017-11-30 16:49:32 +01:00
|
|
|
const size_t num_id_nodes = deg_graph->id_nodes.size();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
iter->data = data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-30 16:49:32 +01:00
|
|
|
if (num_id_nodes == 0) {
|
|
|
|
|
iter->valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-28 14:50:13 +01:00
|
|
|
data->dupli_parent = nullptr;
|
|
|
|
|
data->dupli_list = nullptr;
|
|
|
|
|
data->dupli_object_next = nullptr;
|
|
|
|
|
data->dupli_object_current = nullptr;
|
2017-11-30 16:49:32 +01:00
|
|
|
data->scene = DEG_get_evaluated_scene(depsgraph);
|
|
|
|
|
data->id_node_index = 0;
|
|
|
|
|
data->num_id_nodes = num_id_nodes;
|
2018-12-18 18:18:00 +01:00
|
|
|
data->eval_mode = DEG_get_mode(depsgraph);
|
2020-12-02 13:28:08 +01:00
|
|
|
data->geometry_component_id = 0;
|
|
|
|
|
data->geometry_component_owner = nullptr;
|
2018-06-12 09:55:34 +02:00
|
|
|
deg_invalidate_iterator_work_data(data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-02 13:28:08 +01:00
|
|
|
DEG_iterator_objects_next(iter);
|
2017-11-30 16:49:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DEG_iterator_objects_next(BLI_Iterator *iter)
|
|
|
|
|
{
|
2017-12-15 08:11:19 -02:00
|
|
|
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
|
2020-12-02 13:28:08 +01:00
|
|
|
while (true) {
|
|
|
|
|
if (deg_iterator_components_step(iter)) {
|
2017-11-30 16:49:32 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2020-12-02 13:28:08 +01:00
|
|
|
if (deg_iterator_duplis_step(data)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (deg_iterator_objects_step(data)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
iter->valid = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-11-30 16:49:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DEG_iterator_objects_end(BLI_Iterator *iter)
|
|
|
|
|
{
|
2017-12-15 08:11:19 -02:00
|
|
|
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
|
2020-01-28 14:50:13 +01:00
|
|
|
if (data != nullptr) {
|
2018-04-25 19:03:49 +02:00
|
|
|
/* Force crash in case the iterator data is referenced and accessed down
|
2019-01-31 12:56:40 +01:00
|
|
|
* the line. (T51718) */
|
2018-06-12 09:55:34 +02:00
|
|
|
deg_invalidate_iterator_work_data(data);
|
2018-04-25 19:03:49 +02:00
|
|
|
}
|
2017-11-30 16:49:32 +01:00
|
|
|
}
|
2018-05-29 15:57:14 +02:00
|
|
|
|
|
|
|
|
/* ************************ DEG ID ITERATOR ********************* */
|
|
|
|
|
|
2020-06-29 15:19:56 +02:00
|
|
|
static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool only_updated)
|
2018-05-29 15:57:14 +02:00
|
|
|
{
|
|
|
|
|
ID *id_cow = id_node->id_cow;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-09-19 15:21:51 +02:00
|
|
|
if (!id_node->is_directly_visible) {
|
2018-08-28 12:43:13 +02:00
|
|
|
iter->skip = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-08-07 12:38:42 +02:00
|
|
|
if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) {
|
2018-05-29 15:57:14 +02:00
|
|
|
bNodeTree *ntree = ntreeFromID(id_cow);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
/* Nodetree is considered part of the datablock. */
|
|
|
|
|
if (!(ntree && (ntree->id.recalc & ID_RECALC_ALL))) {
|
|
|
|
|
iter->skip = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
iter->current = id_cow;
|
|
|
|
|
iter->skip = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DEG_iterator_ids_begin(BLI_Iterator *iter, DEGIDIterData *data)
|
|
|
|
|
{
|
|
|
|
|
Depsgraph *depsgraph = data->graph;
|
2020-06-29 15:19:56 +02:00
|
|
|
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
2018-05-29 15:57:14 +02:00
|
|
|
const size_t num_id_nodes = deg_graph->id_nodes.size();
|
|
|
|
|
|
|
|
|
|
iter->data = data;
|
|
|
|
|
|
2018-05-30 19:45:03 +02:00
|
|
|
if ((num_id_nodes == 0) || (data->only_updated && !DEG_id_type_any_updated(depsgraph))) {
|
2018-05-29 15:57:14 +02:00
|
|
|
iter->valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data->id_node_index = 0;
|
|
|
|
|
data->num_id_nodes = num_id_nodes;
|
|
|
|
|
|
2020-06-29 15:19:56 +02:00
|
|
|
deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
|
2018-05-29 15:57:14 +02:00
|
|
|
DEG_iterator_ids_step(iter, id_node, data->only_updated);
|
|
|
|
|
|
|
|
|
|
if (iter->skip) {
|
|
|
|
|
DEG_iterator_ids_next(iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DEG_iterator_ids_next(BLI_Iterator *iter)
|
|
|
|
|
{
|
|
|
|
|
DEGIDIterData *data = (DEGIDIterData *)iter->data;
|
|
|
|
|
Depsgraph *depsgraph = data->graph;
|
2020-06-29 15:19:56 +02:00
|
|
|
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
do {
|
|
|
|
|
iter->skip = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-29 15:57:14 +02:00
|
|
|
++data->id_node_index;
|
|
|
|
|
if (data->id_node_index == data->num_id_nodes) {
|
|
|
|
|
iter->valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-29 15:19:56 +02:00
|
|
|
deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
|
2018-05-29 15:57:14 +02:00
|
|
|
DEG_iterator_ids_step(iter, id_node, data->only_updated);
|
|
|
|
|
} while (iter->skip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DEG_iterator_ids_end(BLI_Iterator *UNUSED(iter))
|
|
|
|
|
{
|
|
|
|
|
}
|