diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 3 | ||||
-rw-r--r-- | source/blender/editors/include/ED_uvedit.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 19 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 2 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_draw.c | 4 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 7 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_common.c | 34 |
8 files changed, 63 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c81133a85fa..15e7efe7c6e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -585,6 +585,9 @@ void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpufu void node_type_internal_links(struct bNodeType *ntype, void (*update_internal_links)(struct bNodeTree *, struct bNode *)); void node_type_compatibility(struct bNodeType *ntype, short compatibility); +/* ************** GENERIC NODE FUNCTIONS *************** */ +bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node); + /* ************** COMMON NODES *************** */ #define NODE_UNDEFINED -2 /* node type is not registered */ diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 04eb829979f..4b82fa40c6a 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -54,7 +54,7 @@ void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Obje bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]); bool ED_object_get_active_image(struct Object *ob, int mat_nr, - struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node); + struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree); void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int mat_nr, struct Image *ima); bool ED_uvedit_test(struct Object *obedit); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index f26425943bd..b3f3a562998 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -51,6 +51,7 @@ #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_report.h" #include "BKE_modifier.h" #include "BKE_mesh.h" @@ -367,10 +368,22 @@ static bool bake_object_check(Object *ob, ReportList *reports) } for (i = 0; i < ob->totcol; i++) { - ED_object_get_active_image(ob, i + 1, &image, NULL, NULL); + bNodeTree *ntree = NULL; + bNode *node = NULL; + ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree); if (image) { - ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + ImBuf *ibuf; + + if (node) { + if (BKE_node_is_connected_to_output(ntree, node)) { + BKE_reportf(reports, RPT_ERROR, + "Circular dependency for image \"%s\" from object \"%s\"", + image->id.name + 2, ob->id.name + 2); + } + } + + ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); if (ibuf) { BKE_image_release_ibuf(image, ibuf, lock); @@ -477,7 +490,7 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images) for (i = 0; i < tot_mat; i++) { Image *image; - ED_object_get_active_image(ob, i + 1, &image, NULL, NULL); + ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); if ((image->id.flag & LIB_DOIT)) { for (j = 0; j < i; j++) { diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 348e6e526fe..89babf977e1 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -941,7 +941,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs) int texture_set = 0; /* draw image texture if we find one */ - if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) { + if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) { /* get openl texture */ int mipmap = 1; int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, false) : 0; diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 6eb8e525c96..0f605429187 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -424,7 +424,7 @@ static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage) /* if no materials, assume a default material with no image */ if (ob->totcol) - ED_object_get_active_image(ob, a + 1, &image, NULL, NULL); + ED_object_get_active_image(ob, a + 1, &image, NULL, NULL, NULL); else image = NULL; @@ -577,7 +577,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) if (new_shading_nodes) { if (efa_act) { - ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL); + ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL); } else { curimage = ima; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index ed88c72edc4..0d8b5a524b6 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -137,21 +137,24 @@ static bool is_image_texture_node(bNode *node) } bool ED_object_get_active_image(Object *ob, int mat_nr, - Image **r_ima, ImageUser **r_iuser, bNode **r_node) + Image **r_ima, ImageUser **r_iuser, bNode **r_node, bNodeTree **r_ntree) { Material *ma = give_current_material(ob, mat_nr); - bNode *node = (ma && ma->use_nodes) ? nodeGetActiveTexture(ma->nodetree) : NULL; + bNodeTree *ntree = (ma && ma->use_nodes) ? ma->nodetree : NULL; + bNode *node = (ntree) ? nodeGetActiveTexture(ntree) : NULL; if (node && is_image_texture_node(node)) { if (r_ima) *r_ima = (Image *)node->id; if (r_iuser) *r_iuser = NULL; if (r_node) *r_node = node; + if (r_ntree) *r_ntree = ntree; return true; } if (r_ima) *r_ima = NULL; if (r_iuser) *r_iuser = NULL; if (r_node) *r_node = node; + if (r_ntree) *r_ntree = ntree; return false; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7442e7b6411..335d8e6589e 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -201,7 +201,7 @@ void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, fl if (efa) { if (BKE_scene_use_new_shading_nodes(scene)) { - ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL); + ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); } else { MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index ae834f9e7cc..c58c9c902ec 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -336,6 +336,40 @@ void ntree_update_reroute_nodes(bNodeTree *ntree) node_reroute_inherit_type_recursive(ntree, node); } +static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node) +{ + bNodeLink *link; + + /* avoid redundant checks, and infinite loops in case of cyclic node links */ + if (node->done) + return false; + node->done = 1; + + /* main test, done before child loop so it catches output nodes themselves as well */ + if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) + return true; + + /* test all connected nodes, first positive find is sufficient to return true */ + for (link = ntree->links.first; link; link = link->next) { + if (link->fromnode == node) { + if (node_is_connected_to_output_recursive(ntree, link->tonode)) + return true; + } + } + return false; +} + +bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node) +{ + bNode *tnode; + + /* clear flags */ + for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) + tnode->done = 0; + + return node_is_connected_to_output_recursive(ntree, node); +} + void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree) { bNode *node; |