Fix T49993: Indirectly used taper/bevel crashes new dependency graph
New dependency graph expects strict separation between nodes and relations builder, meaning, if we try to create relation with an object which is not in the graph yet we'll have an error in depsgraph. Now, so far object nodes were created from bases of the current scene, which caused missing objects in graph in certain cases. Didn't find better approach than to simply ensure object nodes exists when we know they'll be used by relation builder.
This commit is contained in:
parent
b1743cda5a
commit
7dda3cf830
Notes:
blender-bot
2023-02-14 07:25:46 +01:00
Referenced by commit d1d359b792
, Depsgraph: Fix missing relations for objects which are indirectly linked
Referenced by issue #49993, Indirectly used taper/bevel crashes new dependency graph
|
@ -108,6 +108,40 @@ extern "C" {
|
|||
|
||||
namespace DEG {
|
||||
|
||||
namespace {
|
||||
|
||||
struct BuilderWalkUserData {
|
||||
DepsgraphNodeBuilder *builder;
|
||||
Scene *scene;
|
||||
};
|
||||
|
||||
static void modifier_walk(void *user_data,
|
||||
struct Object * /*ob*/,
|
||||
struct Object **obpoin,
|
||||
int /*cd_flag*/)
|
||||
{
|
||||
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
|
||||
if (*obpoin) {
|
||||
data->builder->build_object(data->scene, NULL, *obpoin);
|
||||
}
|
||||
}
|
||||
|
||||
void constraint_walk(bConstraint * /*con*/,
|
||||
ID **idpoin,
|
||||
bool /*is_reference*/,
|
||||
void *user_data)
|
||||
{
|
||||
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
|
||||
if (*idpoin) {
|
||||
ID *id = *idpoin;
|
||||
if (GS(id) == ID_OB) {
|
||||
data->builder->build_object(data->scene, NULL, (Object *)id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
/* ************ */
|
||||
/* Node Builder */
|
||||
|
||||
|
@ -405,19 +439,22 @@ SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
|
|||
{
|
||||
/*Object *ob = go->ob;*/
|
||||
|
||||
/* Each "group object" is effectively a separate instance of the underlying
|
||||
* object data. When the group is evaluated, the transform results and/or
|
||||
* some other attributes end up getting overridden by the group
|
||||
/* Each "group object" is effectively a separate instance of the
|
||||
* underlying object data. When the group is evaluated, the transform
|
||||
* results and/or some other attributes end up getting overridden by
|
||||
* the group.
|
||||
*/
|
||||
}
|
||||
|
||||
/* create a node for representing subgraph */
|
||||
/* Create a node for representing subgraph. */
|
||||
SubgraphDepsNode *subgraph_node = m_graph->add_subgraph_node(&group->id);
|
||||
subgraph_node->graph = subgraph;
|
||||
|
||||
/* make a copy of the data this node will need? */
|
||||
// XXX: do we do this now, or later?
|
||||
// TODO: need API function which queries graph's ID's hash, and duplicates those blocks thoroughly with all outside links removed...
|
||||
/* Make a copy of the data this node will need? */
|
||||
/* XXX: do we do this now, or later? */
|
||||
/* TODO: need API function which queries graph's ID's hash, and duplicates
|
||||
* those blocks thoroughly with all outside links removed.
|
||||
*/
|
||||
|
||||
return subgraph_node;
|
||||
}
|
||||
|
@ -432,13 +469,32 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
|
|||
ob->id.tag |= LIB_TAG_DOIT;
|
||||
|
||||
IDDepsNode *id_node = add_id_node(&ob->id);
|
||||
id_node->layers |= base->lay;
|
||||
if (base != NULL) {
|
||||
id_node->layers |= base->lay;
|
||||
}
|
||||
ob->customdata_mask = 0;
|
||||
|
||||
/* standard components */
|
||||
/* Standard components. */
|
||||
build_object_transform(scene, ob);
|
||||
|
||||
/* object data */
|
||||
if (ob->parent != NULL) {
|
||||
build_object(scene, NULL, ob->parent);
|
||||
}
|
||||
if (ob->modifiers.first != NULL) {
|
||||
BuilderWalkUserData data;
|
||||
data.builder = this;
|
||||
data.scene = scene;
|
||||
modifiers_foreachObjectLink(ob, modifier_walk, &data);
|
||||
}
|
||||
if (ob->constraints.first != NULL) {
|
||||
BuilderWalkUserData data;
|
||||
data.builder = this;
|
||||
data.scene = scene;
|
||||
modifiers_foreachObjectLink(ob, modifier_walk, &data);
|
||||
BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data);
|
||||
}
|
||||
|
||||
/* Object data. */
|
||||
if (ob->data) {
|
||||
/* type-specific data... */
|
||||
switch (ob->type) {
|
||||
|
@ -1110,9 +1166,10 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
|
|||
}
|
||||
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
case OB_FONT:
|
||||
{
|
||||
/* Curve evaluation operations. */
|
||||
/* Curve/nurms evaluation operations. */
|
||||
/* - calculate curve geometry (including path) */
|
||||
add_operation_node(obdata,
|
||||
DEPSNODE_TYPE_GEOMETRY,
|
||||
|
@ -1124,28 +1181,30 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
|
|||
"Geometry Eval");
|
||||
|
||||
/* Calculate curve path - this is used by constraints, etc. */
|
||||
add_operation_node(obdata,
|
||||
DEPSNODE_TYPE_GEOMETRY,
|
||||
DEPSOP_TYPE_EXEC,
|
||||
function_bind(BKE_curve_eval_path,
|
||||
_1,
|
||||
(Curve *)obdata),
|
||||
DEG_OPCODE_GEOMETRY_PATH,
|
||||
"Path");
|
||||
break;
|
||||
}
|
||||
if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
|
||||
add_operation_node(obdata,
|
||||
DEPSNODE_TYPE_GEOMETRY,
|
||||
DEPSOP_TYPE_EXEC,
|
||||
function_bind(BKE_curve_eval_path,
|
||||
_1,
|
||||
(Curve *)obdata),
|
||||
DEG_OPCODE_GEOMETRY_PATH,
|
||||
"Path");
|
||||
}
|
||||
|
||||
case OB_SURF:
|
||||
{
|
||||
/* Nurbs evaluation operations. */
|
||||
add_operation_node(obdata,
|
||||
DEPSNODE_TYPE_GEOMETRY,
|
||||
DEPSOP_TYPE_INIT,
|
||||
function_bind(BKE_curve_eval_geometry,
|
||||
_1,
|
||||
(Curve *)obdata),
|
||||
DEG_OPCODE_PLACEHOLDER,
|
||||
"Geometry Eval");
|
||||
/* Make sure objects used for bevel.taper are in the graph.
|
||||
* NOTE: This objects might be not linked to the scene.
|
||||
*/
|
||||
Curve *cu = (Curve *)obdata;
|
||||
if (cu->bevobj != NULL) {
|
||||
build_object(scene, NULL, cu->bevobj);
|
||||
}
|
||||
if (cu->taperobj != NULL) {
|
||||
build_object(scene, NULL, cu->bevobj);
|
||||
}
|
||||
if (ob->type == OB_FONT && cu->textoncurve != NULL) {
|
||||
build_object(scene, NULL, cu->textoncurve);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1908,15 +1908,18 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
|
|||
// XXX: these needs geom data, but where is geom stored?
|
||||
if (cu->bevobj) {
|
||||
ComponentKey bevob_key(&cu->bevobj->id, DEPSNODE_TYPE_GEOMETRY);
|
||||
build_object(bmain, scene, cu->bevobj);
|
||||
add_relation(bevob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Bevel");
|
||||
}
|
||||
if (cu->taperobj) {
|
||||
ComponentKey taperob_key(&cu->taperobj->id, DEPSNODE_TYPE_GEOMETRY);
|
||||
build_object(bmain, scene, cu->taperobj);
|
||||
add_relation(taperob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Taper");
|
||||
}
|
||||
if (ob->type == OB_FONT) {
|
||||
if (cu->textoncurve) {
|
||||
ComponentKey textoncurve_key(&cu->textoncurve->id, DEPSNODE_TYPE_GEOMETRY);
|
||||
build_object(bmain, scene, cu->textoncurve);
|
||||
add_relation(textoncurve_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Text on Curve");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue