Current implementation more or less indiscriminately links physics objects to colliders and forces, ignoring precise details of layer checks and collider groups. The new depsgraph seemed to lack some such links at all. The relevant code in modifiers suffers from a lot of duplication. Different physics simulations use independent implementations of collision and similar things, which results in a lot of variance: * Cloth collides with objects on same or visible layer with dupli. * Softbody collides with objects on same layer without dupli. * Non-hair particles collide on same layer with dupli. * Smoke uses same code as cloth, but needs different modifier. * Dynamic paint "collides" with brushes on any layer without dupli. Force fields with absorption also imply dependency on colliders: * For most systems, colliders are selected from same layer as field. * For non-hair particles, it uses the same exact set as the particles. As a special quirk, smoke ignores smoke flow force fields; on the other hand dependency on such field implies dependency on the smoke domain. This introduces two utility functions each for old and new depsgraph that are flexible enough to handle all these variations, and uses them to handle particles, cloth, smoke, softbody and dynpaint. One thing to watch out for is that depsgraph code shouldn't rely on any properties that don't cause a graph rebuild when changed. This was violated in the original code that was building force field links, while taking zero field weights into account. This change may cause new dependency cycles in cases where necessary dependencies were missing, but may also remove cycles in situations where unnecessary links were previously created. It's also now possible to solve some cycles by switching to explicit groups, since they are now properly taken into account for dependencies. Differential Revision: https://developer.blender.org/D2141
170 lines
5.5 KiB
C++
170 lines
5.5 KiB
C++
/*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* 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) 2004 Blender Foundation.
|
|
* All rights reserved.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
/** \file blender/blenkernel/depsgraph_private.h
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#ifndef __DEPSGRAPH_PRIVATE_H__
|
|
#define __DEPSGRAPH_PRIVATE_H__
|
|
|
|
#include "BKE_depsgraph.h"
|
|
#include "DNA_constraint_types.h"
|
|
#include "BKE_constraint.h"
|
|
|
|
struct Scene;
|
|
struct Group;
|
|
struct EffectorWeights;
|
|
struct ModifierData;
|
|
|
|
/* **** DAG relation types *** */
|
|
|
|
/* scene link to object */
|
|
#define DAG_RL_SCENE (1 << 0)
|
|
/* object link to data */
|
|
#define DAG_RL_DATA (1 << 1)
|
|
|
|
/* object changes object (parent, track, constraints) */
|
|
#define DAG_RL_OB_OB (1 << 2)
|
|
/* object changes obdata (hooks, constraints) */
|
|
#define DAG_RL_OB_DATA (1 << 3)
|
|
/* data changes object (vertex parent) */
|
|
#define DAG_RL_DATA_OB (1 << 4)
|
|
/* data changes data (deformers) */
|
|
#define DAG_RL_DATA_DATA (1 << 5)
|
|
|
|
#define DAG_NO_RELATION (1 << 6)
|
|
|
|
#define DAG_RL_ALL_BUT_DATA (DAG_RL_SCENE | DAG_RL_OB_OB | DAG_RL_OB_DATA | DAG_RL_DATA_OB | DAG_RL_DATA_DATA)
|
|
#define DAG_RL_ALL (DAG_RL_ALL_BUT_DATA | DAG_RL_DATA)
|
|
|
|
|
|
#define DAGQUEUEALLOC 50
|
|
|
|
enum {
|
|
DAG_WHITE = 0,
|
|
DAG_GRAY = 1,
|
|
DAG_BLACK = 2
|
|
};
|
|
|
|
typedef struct DagAdjList {
|
|
struct DagNode *node;
|
|
short type;
|
|
int count; /* number of identical arcs */
|
|
unsigned int lay; // for flushing redraw/rebuild events
|
|
const char *name;
|
|
struct DagAdjList *next;
|
|
} DagAdjList;
|
|
|
|
|
|
typedef struct DagNode {
|
|
int color;
|
|
short type;
|
|
float x, y, k;
|
|
void *ob;
|
|
void *first_ancestor;
|
|
int ancestor_count;
|
|
unsigned int lay; /* accumulated layers of its relations + itself */
|
|
unsigned int scelay; /* layers due to being in scene */
|
|
uint64_t customdata_mask; /* customdata mask */
|
|
int lasttime; /* if lasttime != DagForest->time, this node was not evaluated yet for flushing */
|
|
int BFS_dist; /* BFS distance */
|
|
int DFS_dist; /* DFS distance */
|
|
int DFS_dvtm; /* DFS discovery time */
|
|
int DFS_fntm; /* DFS Finishing time */
|
|
struct DagAdjList *child;
|
|
struct DagAdjList *parent;
|
|
struct DagNode *next;
|
|
|
|
/* Threaded evaluation routines */
|
|
uint32_t num_pending_parents; /* number of parents which are not updated yet
|
|
* this node has got.
|
|
* Used by threaded update for faster detect whether node could be
|
|
* updated aready.
|
|
*/
|
|
bool scheduled;
|
|
|
|
/* Runtime flags mainly used to determine which extra data is to be evaluated
|
|
* during object_handle_update(). Such an extra data is what depends on the
|
|
* DAG topology, meaning this flags indicates the data evaluation of which
|
|
* depends on the node dependencies.
|
|
*/
|
|
short eval_flags;
|
|
} DagNode;
|
|
|
|
typedef struct DagNodeQueueElem {
|
|
struct DagNode *node;
|
|
struct DagNodeQueueElem *next;
|
|
} DagNodeQueueElem;
|
|
|
|
typedef struct DagNodeQueue {
|
|
DagNodeQueueElem *first;
|
|
DagNodeQueueElem *last;
|
|
int count;
|
|
int maxlevel;
|
|
struct DagNodeQueue *freenodes;
|
|
} DagNodeQueue;
|
|
|
|
/* forest as we may have more than one DAG unconnected */
|
|
typedef struct DagForest {
|
|
ListBase DagNode;
|
|
struct GHash *nodeHash;
|
|
int numNodes;
|
|
bool is_acyclic;
|
|
int time; /* for flushing/tagging, compare with node->lasttime */
|
|
bool ugly_hack_sorry; /* prevent type check */
|
|
bool need_update;
|
|
} DagForest;
|
|
|
|
// queue operations
|
|
DagNodeQueue *queue_create(int slots);
|
|
void queue_raz(DagNodeQueue *queue);
|
|
void push_queue(DagNodeQueue *queue, DagNode *node);
|
|
void push_stack(DagNodeQueue *queue, DagNode *node);
|
|
DagNode *pop_queue(DagNodeQueue *queue);
|
|
DagNode *get_top_node_queue(DagNodeQueue *queue);
|
|
void queue_delete(DagNodeQueue *queue);
|
|
|
|
// Dag management
|
|
DagForest *dag_init(void);
|
|
DagForest *build_dag(struct Main *bmain, struct Scene *sce, short mask);
|
|
void free_forest(struct DagForest *Dag);
|
|
DagNode *dag_find_node(DagForest *forest, void *fob);
|
|
DagNode *dag_add_node(DagForest *forest, void *fob);
|
|
DagNode *dag_get_node(DagForest *forest, void *fob);
|
|
DagNode *dag_get_sub_node(DagForest *forest, void *fob);
|
|
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name);
|
|
|
|
typedef bool (*DagCollobjFilterFunction)(struct Object *obj, struct ModifierData *md);
|
|
|
|
void dag_add_collision_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct Group *group, int layer, unsigned int modifier_type, DagCollobjFilterFunction fn, bool dupli, const char *name);
|
|
void dag_add_forcefield_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name);
|
|
|
|
void graph_print_queue(DagNodeQueue *nqueue);
|
|
void graph_print_queue_dist(DagNodeQueue *nqueue);
|
|
void graph_print_adj_list(DagForest *dag);
|
|
|
|
#endif /* __DEPSGRAPH_PRIVATE_H__ */
|