1
1

Compare commits

...

12 Commits

Author SHA1 Message Date
9282d305bd Merge branch 'master' into texture_nodes_refactor
Conflicts:
	source/blender/nodes/texture/nodes/node_texture_math.c
2014-12-23 10:04:03 +05:00
de724a258e Merge branch 'master' into texture_nodes_refactor 2014-10-14 10:36:27 +02:00
a4ba73311b Port some more nodes
Now only node group remained to be ported, all the rest of the nodes
cant' be actually supported and will be removed.

As a replacement for them we'll bring some more control by adding
some mapping sockets to the input nodes.
2014-10-14 00:50:26 +06:00
b35aafab6a Port procedural texture nodes to new framework 2014-10-13 21:09:38 +06:00
94dd73b995 Support some more nodes 2014-10-11 22:57:53 +06:00
e9e555fb85 Port several more nodes to the new system
Need to switch to some other work now, maybe someone will want to play
around with the code meanwhile.
2014-10-11 21:50:15 +06:00
5c50820e6a Bring back image input, checker, viewer and output nodes
This more like a prove-of-concept change because well, we've got
a dependency solver in the nodes already which seems to work just
fine for the shading nodes. So want to see if this is something we
can use for texture nodes now.

This isn't that far away from the original idea of having some
SVM-like machine for texture nodes.

Hell of a lot of nodes are not gonna to work yet,
2014-10-11 21:01:16 +06:00
f5c526f29c Port texture nodes to the exec pool in renderer
This only makes it so renderer uses the proper API to deal with the
tree evaluation. Tree nodes still does nothing because all the delegate
system has been just removed.

Painting and sculpting will also fail and abort .
2014-10-11 19:22:54 +06:00
4bd79aca12 Revert "Cycles: Implement an area preserving parameterization sampling for area lamps"
This reverts commit c4235ce820.
2014-10-11 19:05:09 +06:00
b2d6cd2e33 Bring material nodes back to the render engine
The idea is to make make it so per-tree execution data is owned by
the renderer and being passed to the tree evaluation routines.
2014-10-11 19:03:37 +06:00
98bd0b4027 Get rid of old legacy stuff happening all over the place
Basically get rid of texture nodes deligates and exec data stored
in the DNA node tree structure.

Blender is pretty much unusable now, because there are whole areas
to be ported over.
2014-10-11 17:01:16 +06:00
c4235ce820 Cycles: Implement an area preserving parameterization sampling for area lamps
Replace old code for area lamps which was more like incorrect with more correct
one using the following paper as a reference:

  Carlos Urena et al.
  An Area-Preserving Parametrization for Spherical Rectangles.
  https://www.solidangle.com/research/egsr2013_spherical_rectangle.pdf

Implementation is straight from the paper, currently the rectangle contants are
calculated for each of the samples. Ideally we need to pre-calculate them.

The old PDF is still used, which makes difference real subtle. This is to be
corrected before final commit.

Reviewers: brecht, juicyfruit

Subscribers: dingto, ton

Differential Revision: https://developer.blender.org/D823
2014-10-11 15:53:23 +06:00
48 changed files with 706 additions and 692 deletions

View File

@@ -36,6 +36,7 @@
extern "C" {
#endif
struct bNodeTreeExecPool;
struct Main;
struct Material;
struct ID;
@@ -96,10 +97,16 @@ struct Material *BKE_material_pop_id(struct ID *id, int index, bool update_data)
void BKE_material_clear_id(struct ID *id, bool update_data);
/* rendering */
void init_render_material(struct Material *, int, float *);
void init_render_materials(struct Main *, int, float *);
void end_render_material(struct Material *);
void end_render_materials(struct Main *);
void init_render_material(struct Material *mat,
struct bNodeTreeExecPool *exec_tree_pool,
int render_mode, float *amb);
void init_render_materials(struct Main *bmain,
struct bNodeTreeExecPool *exec_tree_pool,
int render_mode, float *amb);
void end_render_material(struct bNodeTreeExecPool *exec_tree_pool,
struct Material *mat);
void end_render_materials(struct Main *bmain,
struct bNodeTreeExecPool *exec_tree_pool);
bool material_in_material(struct Material *parmat, struct Material *mat);

View File

@@ -84,6 +84,7 @@ struct ColorManagedViewSettings;
struct ColorManagedDisplaySettings;
struct bNodeInstanceHash;
typedef struct bNodeTreeExecPool bNodeTreeExecPool;
/* ************** NODE TYPE DEFINITIONS ***** */
@@ -773,7 +774,7 @@ struct ShadeResult;
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
bool ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
bool ntreeShaderExecTree(bNodeTreeExecPool *exec_tree_pool, struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
/* switch material render loop */
@@ -999,13 +1000,24 @@ struct TexResult;
int ntreeTexTagAnimated(struct bNodeTree *ntree);
void ntreeTexCheckCyclics(struct bNodeTree *ntree);
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree);
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree) ATTR_WARN_UNUSED_RESULT;
void ntreeTexEndExecTree(struct bNodeTreeExec *exec);
int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target,
int ntreeTexExecTree(bNodeTreeExecPool *pool,
struct bNodeTree *ntree, struct TexResult *target,
float coord[3], float dxt[3], float dyt[3], int osatex, const short thread,
struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
bNodeTreeExecPool *BKE_node_tree_exec_pool_new(void);
void BKE_node_tree_exec_pool_free(bNodeTreeExecPool *pool);
void BKE_node_tree_exec_pool_put(bNodeTreeExecPool *pool,
struct ID *id,
void *data);
void *BKE_node_tree_exec_pool_get(bNodeTreeExecPool *pool,
struct ID *id);
void *BKE_node_tree_exec_pool_pop(bNodeTreeExecPool *pool,
struct ID *id);
/*************************************************/
void init_nodesystem(void);

View File

@@ -1058,12 +1058,15 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode
}
}
void init_render_material(Material *mat, int r_mode, float *amb)
void init_render_material(Material *mat,
bNodeTreeExecPool *exec_tree_pool,
int r_mode, float *amb)
{
do_init_render_material(mat, r_mode, amb);
if (mat->nodetree && mat->use_nodes) {
struct bNodeTreeExec *exec_data;
/* mode_l will take the pipeline options from the main material, and the or-ed
* result of non-pipeline options from the nodes. shadeless is an exception,
* mode_l will have it set when all node materials are shadeless. */
@@ -1074,9 +1077,15 @@ void init_render_material(Material *mat, int r_mode, float *amb)
ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l);
init_render_nodetree(mat->nodetree, mat, r_mode, amb);
if (!mat->nodetree->execdata)
mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
exec_data = BKE_node_tree_exec_pool_get(exec_tree_pool,
&mat->nodetree->id);
if (exec_data == NULL) {
exec_data = ntreeShaderBeginExecTree(mat->nodetree);
BKE_node_tree_exec_pool_put(exec_tree_pool,
&mat->nodetree->id,
exec_data);
}
}
else {
mat->mode_l = mat->mode;
@@ -1087,7 +1096,9 @@ void init_render_material(Material *mat, int r_mode, float *amb)
}
}
void init_render_materials(Main *bmain, int r_mode, float *amb)
void init_render_materials(Main *bmain,
bNodeTreeExecPool *exec_tree_pool,
int r_mode, float *amb)
{
Material *ma;
@@ -1106,27 +1117,32 @@ void init_render_materials(Main *bmain, int r_mode, float *amb)
/* is_used flag comes back in convertblender.c */
ma->flag &= ~MA_IS_USED;
if (ma->id.us)
init_render_material(ma, r_mode, amb);
init_render_material(ma, exec_tree_pool, r_mode, amb);
}
init_render_material(&defmaterial, r_mode, amb);
init_render_material(&defmaterial, exec_tree_pool, r_mode, amb);
}
/* only needed for nodes now */
void end_render_material(Material *mat)
void end_render_material(bNodeTreeExecPool *exec_tree_pool,
Material *mat)
{
if (mat && mat->nodetree && mat->use_nodes) {
if (mat->nodetree->execdata)
ntreeShaderEndExecTree(mat->nodetree->execdata);
struct bNodeTreeExec *exec_data;
exec_data = BKE_node_tree_exec_pool_pop(exec_tree_pool,
&mat->nodetree->id);
if (exec_data != NULL) {
ntreeShaderEndExecTree(exec_data);
}
}
}
void end_render_materials(Main *bmain)
void end_render_materials(Main *bmain, bNodeTreeExecPool *exec_tree_pool)
{
Material *ma;
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->id.us)
end_render_material(ma);
end_render_material(exec_tree_pool, ma);
}
static bool material_in_nodetree(bNodeTree *ntree, Material *mat)

View File

@@ -46,11 +46,12 @@
#include "DNA_world_types.h"
#include "DNA_linestyle_types.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_string.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -1129,9 +1130,6 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
id_us_plus((ID *)newtree->gpd);
/* in case a running nodetree is copied */
newtree->execdata = NULL;
BLI_listbase_clear(&newtree->nodes);
BLI_listbase_clear(&newtree->links);
@@ -1625,13 +1623,7 @@ static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdat
if (ntree->typeinfo->free_node_cache)
ntree->typeinfo->free_node_cache(ntree, node);
/* texture node has bad habit of keeping exec data around */
if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
ntreeTexEndExecTree(ntree->execdata);
ntree->execdata = NULL;
}
if (node->typeinfo->freefunc)
node->typeinfo->freefunc(node);
}
@@ -1705,24 +1697,7 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
bNodeSocket *sock, *nextsock;
if (ntree == NULL) return;
/* XXX hack! node trees should not store execution graphs at all.
* This should be removed when old tree types no longer require it.
* Currently the execution data for texture nodes remains in the tree
* after execution, until the node tree is updated or freed.
*/
if (ntree->execdata) {
switch (ntree->type) {
case NTREE_SHADER:
ntreeShaderEndExecTree(ntree->execdata);
break;
case NTREE_TEXTURE:
ntreeTexEndExecTree(ntree->execdata);
ntree->execdata = NULL;
break;
}
}
/* XXX not nice, but needed to free localized node groups properly */
free_localized_node_groups(ntree);
@@ -3716,3 +3691,47 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
return true;
}
/* Node execution. */
typedef struct bNodeTreeExecPool {
GHash *hash;
} bNodeTreeExecPool;
struct bNodeTreeExecPool *BKE_node_tree_exec_pool_new(void)
{
bNodeTreeExecPool *pool;
pool = MEM_callocN(sizeof(bNodeTreeExecPool), __func__);
pool->hash = BLI_ghash_ptr_new(__func__);
return pool;
}
void BKE_node_tree_exec_pool_free(bNodeTreeExecPool *pool)
{
/* Only destroys pool, all exec data is expected to be freed already. */
BLI_assert(pool != NULL);
BLI_ghash_free(pool->hash, NULL, NULL);
MEM_freeN(pool);
}
void BKE_node_tree_exec_pool_put(bNodeTreeExecPool *pool,
struct ID *id,
void *data)
{
BLI_assert(pool != NULL);
BLI_ghash_insert(pool->hash, id, data);
}
void *BKE_node_tree_exec_pool_get(bNodeTreeExecPool *pool,
struct ID *id)
{
BLI_assert(pool != NULL);
return BLI_ghash_lookup(pool->hash, id);
}
void *BKE_node_tree_exec_pool_pop(bNodeTreeExecPool *pool,
struct ID *id)
{
BLI_assert(pool != NULL);
return BLI_ghash_popkey(pool->hash, id, NULL);
}

View File

@@ -835,10 +835,7 @@ Tex *BKE_texture_copy(Tex *tex)
if (texn->ot) texn->ot = BKE_copy_oceantex(texn->ot);
if (tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
if (tex->nodetree) {
if (tex->nodetree->execdata) {
ntreeTexEndExecTree(tex->nodetree->execdata);
}
if (tex->nodetree != NULL) {
texn->nodetree = ntreeCopyTree(tex->nodetree);
}

View File

@@ -2704,7 +2704,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
ntree->interface_type = NULL;
ntree->progress = NULL;
ntree->execdata = NULL;
ntree->adt = newdataadr(fd, ntree->adt);
direct_link_animdata(fd, ntree->adt);

View File

@@ -261,7 +261,11 @@ static Scene *preview_get_scene(Main *pr_main)
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp)
static Scene *preview_prepare_scene(Render *re,
Scene *scene,
ID *id,
int id_type,
ShaderPreview *sp)
{
Scene *sce;
Base *base;
@@ -323,8 +327,11 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
BLI_addtail(&pr_main->mat, mat);
if (!BKE_scene_use_new_shading_nodes(scene)) {
init_render_material(mat, 0, NULL); /* call that retrieves mode_l */
end_render_material(mat);
bNodeTreeExecPool *tree_exec_pool;
tree_exec_pool = RE_tree_exec_pool_get(re);
init_render_material(mat, tree_exec_pool, 0, NULL); /* call that retrieves mode_l */
/* TODO(sergey): Wait, that's kind of stupid. */
end_render_material(tree_exec_pool, mat);
/* un-useful option */
if (sp->pr_method == PR_ICON_RENDER)
@@ -700,19 +707,19 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
sce->r.ysch = sp->sizey;
sce->r.size = 100;
}
/* get the stuff from the builtin preview dbase */
sce = preview_prepare_scene(sp->scene, id, idtype, sp);
if (sce == NULL) return;
if (!split || first) sprintf(name, "Preview %p", sp->owner);
else sprintf(name, "SecondPreview %p", sp->owner);
re = RE_GetRender(name);
/* full refreshed render from first tile */
if (re == NULL)
re = RE_NewRender(name);
/* get the stuff from the builtin preview dbase */
sce = preview_prepare_scene(re, sp->scene, id, idtype, sp);
if (sce == NULL) return;
/* sce->r gets copied in RE_InitState! */
sce->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
@@ -757,7 +764,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
/* unassign the pointers, reset vars */
preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
preview_prepare_scene(re, sp->scene, NULL, GS(id->name), sp);
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
// if (idtype == ID_TE) {

View File

@@ -209,8 +209,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
pool = BKE_image_pool_new();
if (mtex->tex && mtex->tex->nodetree)
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
if (mtex->tex && mtex->tex->nodetree) {
BLI_assert(!"Port over to the new system");
//ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
}
#pragma omp parallel for schedule(static)
for (j = 0; j < size; j++) {
@@ -305,8 +307,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
}
}
if (mtex->tex && mtex->tex->nodetree)
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
if (mtex->tex && mtex->tex->nodetree) {
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
BLI_assert(!"Need to port this over");
}
if (pool)
BKE_image_pool_free(pool);

View File

@@ -690,12 +690,16 @@ void paint_brush_init_tex(Brush *brush)
{
/* init mtex nodes */
if (brush) {
#if 0
MTex *mtex = &brush->mtex;
if (mtex->tex && mtex->tex->nodetree)
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
mtex = &brush->mask_mtex;
if (mtex->tex && mtex->tex->nodetree)
ntreeTexBeginExecTree(mtex->tex->nodetree);
#else
BLI_assert(!"Port over to the new system");
#endif
}
}
@@ -703,11 +707,15 @@ void paint_brush_exit_tex(Brush *brush)
{
if (brush) {
MTex *mtex = &brush->mtex;
if (mtex->tex && mtex->tex->nodetree)
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
if (mtex->tex && mtex->tex->nodetree) {
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
BLI_assert(!"Need to port thing over");
}
mtex = &brush->mask_mtex;
if (mtex->tex && mtex->tex->nodetree)
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
if (mtex->tex && mtex->tex->nodetree) {
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
BLI_assert(!"Need to port thing over");
}
}
}

View File

@@ -4125,8 +4125,10 @@ static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession
MTex *mtex = &brush->mtex;
/* init mtex nodes */
if (mtex->tex && mtex->tex->nodetree)
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
if (mtex->tex && mtex->tex->nodetree) {
//ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
BLI_assert(!"Port over to the new system");
}
/* TODO: Shouldn't really have to do this at the start of every
* stroke, but sculpt would need some sort of notification when
@@ -4328,8 +4330,10 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
Brush *brush = BKE_paint_brush(&sd->paint);
MTex *mtex = &brush->mtex;
if (mtex->tex && mtex->tex->nodetree)
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
if (mtex->tex && mtex->tex->nodetree) {
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
BLI_assert(!"Need to port the damn thing");
}
}
static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))

View File

@@ -372,15 +372,6 @@ typedef struct bNodeTree {
bNodeInstanceKey active_viewer_key;
int pad;
/* execution data */
/* XXX It would be preferable to completely move this data out of the underlying node tree,
* so node tree execution could finally run independent of the tree itself. This would allow node trees
* to be merely linked by other data (materials, textures, etc.), as ID data is supposed to.
* Execution data is generated from the tree once at execution start and can then be used
* as long as necessary, even while the tree is being modified.
*/
struct bNodeTreeExec *execdata;
/* callbacks */
void (*progress)(void *, float progress);
void (*stats_draw)(void *, char *str);

View File

@@ -77,20 +77,20 @@ typedef struct bNodeThreadStack {
int node_exec_socket_use_stack(struct bNodeSocket *sock);
struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock);
struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock) ATTR_WARN_UNUSED_RESULT;
void node_get_stack(struct bNode *node, struct bNodeStack *stack, struct bNodeStack **in, struct bNodeStack **out);
struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
void ntree_exec_end(struct bNodeTreeExec *exec);
struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread);
struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread) ATTR_WARN_UNUSED_RESULT;
void ntreeReleaseThreadStack(struct bNodeThreadStack *nts);
bool ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread);
struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
void ntreeShaderEndExecTree_internal(struct bNodeTreeExec *exec);
struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec);
#endif

View File

@@ -245,24 +245,8 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNod
bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
{
bNodeExecContext context;
bNodeTreeExec *exec;
/* XXX hack: prevent exec data from being generated twice.
* this should be handled by the renderer!
*/
if (ntree->execdata)
return ntree->execdata;
context.previews = ntree->previews;
exec = ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
return exec;
return ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
}
void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
@@ -286,18 +270,16 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
void ntreeShaderEndExecTree(bNodeTreeExec *exec)
{
if (exec) {
/* exec may get freed, so assign ntree */
bNodeTree *ntree = exec->nodetree;
if (exec != NULL) {
ntreeShaderEndExecTree_internal(exec);
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
ntree->execdata = NULL;
}
}
/* only for Blender internal */
bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
bool ntreeShaderExecTree(bNodeTreeExecPool *exec_tree_pool,
bNodeTree *ntree,
ShadeInput *shi,
ShadeResult *shr)
{
ShaderCallData scd;
/**
@@ -306,9 +288,13 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
*/
Material *mat = shi->mat;
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = ntree->execdata;
bNodeTreeExec *exec = NULL;
int compat;
exec = BKE_node_tree_exec_pool_get(exec_tree_pool,
&ntree->id);
BLI_assert(exec != NULL);
/* convert caller data to struct */
scd.shi = shi;
scd.shr = shr;
@@ -316,16 +302,6 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
/* each material node has own local shaderesult, with optional copying */
memset(shr, 0, sizeof(ShadeResult));
/* ensure execdata is only initialized once */
if (!exec) {
BLI_lock_thread(LOCK_NODES);
if (!ntree->execdata)
ntree->execdata = ntreeShaderBeginExecTree(ntree);
BLI_unlock_thread(LOCK_NODES);
exec = ntree->execdata;
}
nts = ntreeGetThreadStack(exec, shi->thread);
compat = ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
ntreeReleaseThreadStack(nts);

View File

@@ -134,10 +134,6 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
/* XXX muting disabled in previews because of threading issues with the main execution
* it works here, but disabled for consistency
*/
#if 1
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
bNode *node, *node_next;
@@ -152,11 +148,6 @@ static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
}
}
}
#else
static void localize(bNodeTree *UNUSED(localtree), bNodeTree *UNUSED(ntree))
{
}
#endif
static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
{
@@ -178,6 +169,7 @@ static void update(bNodeTree *ntree)
}
}
bNodeTreeType *ntreeType_Texture;
void register_node_tree_type_tex(void)
@@ -243,38 +235,8 @@ bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context, bNodeTr
bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
{
bNodeExecContext context;
bNodeTreeExec *exec;
/* XXX hack: prevent exec data from being generated twice.
* this should be handled by the renderer!
*/
if (ntree->execdata)
return ntree->execdata;
context.previews = ntree->previews;
exec = ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
return exec;
}
/* free texture delegates */
static void tex_free_delegates(bNodeTreeExec *exec)
{
bNodeThreadStack *nts;
bNodeStack *ns;
int th, a;
for (th = 0; th < BLENDER_MAX_THREADS; th++)
for (nts = exec->threadstack[th].first; nts; nts = nts->next)
for (ns = nts->stack, a = 0; a < exec->stacksize; a++, ns++)
if (ns->data && !ns->is_copy)
MEM_freeN(ns->data);
return ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
}
void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
@@ -283,8 +245,6 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
int a;
if (exec->threadstack) {
tex_free_delegates(exec);
for (a = 0; a < BLENDER_MAX_THREADS; a++) {
for (nts = exec->threadstack[a].first; nts; nts = nts->next)
if (nts->stack) MEM_freeN(nts->stack);
@@ -300,18 +260,14 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
void ntreeTexEndExecTree(bNodeTreeExec *exec)
{
if (exec) {
/* exec may get freed, so assign ntree */
bNodeTree *ntree = exec->nodetree;
if (exec != NULL) {
ntreeTexEndExecTree_internal(exec);
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
ntree->execdata = NULL;
}
}
int ntreeTexExecTree(
bNodeTree *nodes,
bNodeTreeExecPool *exec_tree_pool,
bNodeTree *ntree,
TexResult *texres,
float co[3],
float dxt[3], float dyt[3],
@@ -328,7 +284,11 @@ int ntreeTexExecTree(
float *nor = texres->nor;
int retval = TEX_INT;
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = nodes->execdata;
bNodeTreeExec *exec;
exec = BKE_node_tree_exec_pool_get(exec_tree_pool,
&ntree->id);
BLI_assert(exec != NULL);
data.co = co;
data.dxt = dxt;
@@ -342,17 +302,7 @@ int ntreeTexExecTree(
data.cfra = cfra;
data.mtex = mtex;
data.shi = shi;
/* ensure execdata is only initialized once */
if (!exec) {
BLI_lock_thread(LOCK_NODES);
if (!nodes->execdata)
ntreeTexBeginExecTree(nodes);
BLI_unlock_thread(LOCK_NODES);
exec = nodes->execdata;
}
nts = ntreeGetThreadStack(exec, thread);
ntreeExecThreadNodes(exec, nts, &data, thread);
ntreeReleaseThreadStack(nts);

View File

@@ -63,37 +63,52 @@ void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, sho
ntype->update_internal_links = node_update_internal_links_default;
}
static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
/* TODO(sergey): De-duplicate with the shader nodes. */
static void tex_input(float *in, int type_in, bNodeStack *ns)
{
if (dg->node->need_exec) {
dg->fn(out, params, dg->node, dg->in, thread);
const float *from = ns->vec;
if (dg->cdata->do_preview)
tex_do_preview(dg->preview, params->previewco, out, dg->cdata->do_manage);
if (type_in == SOCK_FLOAT) {
if (ns->sockettype == SOCK_FLOAT)
*in = *from;
else
*in = (from[0] + from[1] + from[2]) / 3.0f;
}
else if (type_in == SOCK_VECTOR) {
if (ns->sockettype == SOCK_FLOAT) {
in[0] = from[0];
in[1] = from[0];
in[2] = from[0];
}
else {
copy_v3_v3(in, from);
}
}
else { /* type_in==SOCK_RGBA */
if (ns->sockettype == SOCK_RGBA) {
copy_v4_v4(in, from);
}
else if (ns->sockettype == SOCK_FLOAT) {
in[0] = from[0];
in[1] = from[0];
in[2] = from[0];
in[3] = 1.0f;
}
else {
copy_v3_v3(in, from);
in[3] = 1.0f;
}
}
}
static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread)
void tex_input_vec(float *out, bNodeStack *in)
{
TexDelegate *dg = in->data;
if (dg) {
tex_call_delegate(dg, in->vec, params, thread);
if (in->hasoutput && in->sockettype == SOCK_FLOAT)
in->vec[1] = in->vec[2] = in->vec[0];
}
memcpy(out, in->vec, sz * sizeof(float));
tex_input(out, SOCK_FLOAT, in);
}
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
void tex_input_rgba(float *out, bNodeStack *in)
{
tex_input(out, 3, in, params, thread);
}
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
{
tex_input(out, 4, in, params, thread);
tex_input(out, SOCK_RGBA, in);
if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
out[1] = out[2] = out[0];
@@ -108,10 +123,10 @@ void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
}
}
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
float tex_input_value(bNodeStack *in)
{
float out[4];
tex_input_vec(out, in, params, thread);
tex_input_vec(out, in);
return out[0];
}
@@ -139,27 +154,12 @@ void tex_do_preview(bNodePreview *preview, const float coord[2], const float col
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
{
TexDelegate *dg;
if (node->flag & NODE_MUTED) {
/* do not add a delegate if the node is muted */
return;
}
else {
if (!out->data)
/* Freed in tex_end_exec (node.c) */
dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
else
dg = out->data;
}
dg->cdata = cdata;
dg->fn = texfn;
dg->node = node;
dg->preview = execdata->preview;
memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
dg->type = out->sockettype;
(void) node;
(void) execdata;
(void) in;
(void) out;
(void) texfn;
(void) cdata;
}
void ntreeTexCheckCyclics(struct bNodeTree *ntree)

View File

@@ -109,22 +109,12 @@ typedef struct TexParams {
typedef void(*TexFn) (float *out, TexParams *params, bNode *node, bNodeStack **in, short thread);
typedef struct TexDelegate {
TexCallData *cdata;
TexFn fn;
bNode *node;
bNodePreview *preview;
bNodeStack *in[MAX_SOCKET];
int type;
} TexDelegate;
int tex_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread);
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread);
float tex_input_value(bNodeStack *in, TexParams *params, short thread);
void tex_input_rgba(float *out, bNodeStack *in);
void tex_input_vec(float *out, bNodeStack *in);
float tex_input_value(bNodeStack *in);
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data);
void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4], bool do_manage);

View File

@@ -49,8 +49,12 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
float new_co[3];
np.co = new_co;
tex_input_vec(new_co, in[1], p, thread);
tex_input_rgba(out, in[0], &np, thread);
(void) out;
(void) in;
(void) thread;
tex_input_vec(new_co, in[1]);
//tex_input_rgba(out, in[0], &np, thread);
BLI_assert(!"Needs proper solution");
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -64,72 +64,75 @@ static float noise(int n) /* fast integer noise */
return 0.5f * ((float)nn / 1073741824.0f);
}
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **out)
{
const float *co = p->co;
TexCallData *cdata = (TexCallData *)data;
const float *co = cdata->co;
float x = co[0];
float y = co[1];
int bricknum, rownum;
float offset = 0;
float ins_x, ins_y;
float tint;
float bricks1[4];
float bricks2[4];
float mortar[4];
float mortar_thickness = tex_input_value(in[3], p, thread);
float bias = tex_input_value(in[4], p, thread);
float brick_width = tex_input_value(in[5], p, thread);
float row_height = tex_input_value(in[6], p, thread);
tex_input_rgba(bricks1, in[0], p, thread);
tex_input_rgba(bricks2, in[1], p, thread);
tex_input_rgba(mortar, in[2], p, thread);
rownum = (int)floor(y / row_height);
float mortar_thickness = tex_input_value(in[3]);
float bias = tex_input_value(in[4]);
float brick_width = tex_input_value(in[5]);
float row_height = tex_input_value(in[6]);
tex_input_rgba(bricks1, in[0]);
tex_input_rgba(bricks2, in[1]);
tex_input_rgba(mortar, in[2]);
rownum = (int)floorf(y / row_height);
if (node->custom1 && node->custom2) {
brick_width *= ((int)(rownum) % node->custom2) ? 1.0f : node->custom4; /* squash */
offset = ((int)(rownum) % node->custom1) ? 0 : (brick_width * node->custom3); /* offset */
}
bricknum = (int)floor((x + offset) / brick_width);
bricknum = (int)floorf((x + offset) / brick_width);
ins_x = (x + offset) - brick_width * bricknum;
ins_y = y - row_height * rownum;
tint = noise((rownum << 16) + (bricknum & 0xFFFF)) + bias;
CLAMP(tint, 0.0f, 1.0f);
if (ins_x < mortar_thickness || ins_y < mortar_thickness ||
ins_x > (brick_width - mortar_thickness) ||
ins_y > (row_height - mortar_thickness))
{
copy_v4_v4(out, mortar);
copy_v4_v4(out[0]->vec, mortar);
}
else {
copy_v4_v4(out, bricks1);
ramp_blend(MA_RAMP_BLEND, out, tint, bricks2);
copy_v4_v4(out[0]->vec, bricks1);
ramp_blend(MA_RAMP_BLEND, out[0]->vec, tint, bricks2);
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
}
void register_node_type_tex_bricks(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, init);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -45,38 +45,44 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void exec(void *data,
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **out)
{
float x = p->co[0];
float y = p->co[1];
float z = p->co[2];
float sz = tex_input_value(in[2], p, thread);
TexCallData *cdata = (TexCallData *)data;
float x, y, z, sz;
int xi, yi, zi;
x = cdata->co[0];
y = cdata->co[1];
z = cdata->co[2];
sz = tex_input_value(in[2]);
/* 0.00001 because of unit sized stuff */
int xi = (int)fabs(floor(0.00001f + x / sz));
int yi = (int)fabs(floor(0.00001f + y / sz));
int zi = (int)fabs(floor(0.00001f + z / sz));
xi = (int)fabsf(floorf(0.00001f + x / sz));
yi = (int)fabsf(floorf(0.00001f + y / sz));
zi = (int)fabsf(floorf(0.00001f + z / sz));
if ( (xi % 2 == yi % 2) == (zi % 2) ) {
tex_input_rgba(out, in[0], p, thread);
tex_input_rgba(out[0]->vec, in[0]);
}
else {
tex_input_rgba(out, in[1], p, thread);
tex_input_rgba(out[0]->vec, in[1]);
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
}
void register_node_type_tex_checker(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -30,7 +30,7 @@
*/
#include "node_texture_util.h"
#include "node_texture_util.h"
#include "NOD_texture.h"
static bNodeSocketTemplate inputs[] = {
@@ -45,25 +45,26 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
int i;
for (i = 0; i < 4; i++)
out[i] = tex_input_value(in[i], p, thread);
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
for (i = 0; i < 4; i++) {
out[0]->vec[i] = tex_input_value(in[i]);
}
}
void register_node_type_tex_compose(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -38,24 +38,25 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void vectorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **UNUSED(in), short UNUSED(thread))
static void exec(void *data,
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **UNUSED(in),
bNodeStack **out)
{
copy_v3_v3(out, p->co);
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &vectorfn, data);
TexCallData *cdata = (TexCallData *)data;
copy_v3_v3(out[0]->vec, cdata->co);
}
void register_node_type_tex_coord(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, outputs);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -41,22 +41,23 @@ static bNodeSocketTemplate time_outputs[] = {
{ -1, 0, "" }
};
static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
static void time_exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **UNUSED(in),
bNodeStack **out)
{
TexCallData *cdata = (TexCallData *)data;
/* stack order output: fac */
float fac = 0.0f;
if (node->custom1 < node->custom2)
fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
fac = (cdata->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
curvemapping_initialize(node->storage);
fac = curvemapping_evaluateF(node->storage, 0, fac);
out[0] = CLAMPIS(fac, 0.0f, 1.0f);
}
static void time_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &time_colorfn, data);
out[0]->vec[0] = CLAMPIS(fac, 0.0f, 1.0f);
}
@@ -70,14 +71,14 @@ static void time_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_curve_time(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, time_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_init(&ntype, time_init);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
node_type_exec(&ntype, node_initexec_curves, NULL, time_exec);
nodeRegisterType(&ntype);
}
@@ -92,18 +93,17 @@ static bNodeSocketTemplate rgb_outputs[] = {
{ -1, 0, ""}
};
static void rgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void rgb_exec(void *UNUSED(data),
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float cin[4];
tex_input_rgba(cin, in[0], p, thread);
curvemapping_evaluateRGBF(node->storage, out, cin);
out[3] = cin[3];
}
static void rgb_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &rgb_colorfn, data);
tex_input_rgba(cin, in[0]);
curvemapping_evaluateRGBF(node->storage, out[0]->vec, cin);
out[0]->vec[3] = cin[3];
}
static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node)
@@ -114,13 +114,13 @@ static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_curve_rgb(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, rgb_inputs, rgb_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_init(&ntype, rgb_init);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
node_type_exec(&ntype, node_initexec_curves, NULL, rgb_exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -30,7 +30,7 @@
*/
#include "node_texture_util.h"
#include "node_texture_util.h"
#include "NOD_texture.h"
#include <math.h>
@@ -46,45 +46,28 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void valuefn_r(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
tex_input_rgba(out, in[0], p, thread);
*out = out[0];
}
static void valuefn_g(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
*out = out[1];
}
static void valuefn_b(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
*out = out[2];
}
static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
*out = out[3];
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &valuefn_r, data);
tex_output(node, execdata, in, out[1], &valuefn_g, data);
tex_output(node, execdata, in, out[2], &valuefn_b, data);
tex_output(node, execdata, in, out[3], &valuefn_a, data);
float color[4];
tex_input_rgba(color, in[0]);
out[0]->vec[0] = color[0];
out[1]->vec[0] = color[1];
out[2]->vec[0] = color[2];
out[3]->vec[0] = color[3];
}
void register_node_type_tex_decompose(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -46,29 +46,31 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float co1[3], co2[3];
tex_input_vec(co1, in[0], p, thread);
tex_input_vec(co2, in[1], p, thread);
*out = len_v3v3(co2, co1);
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &valuefn, data);
tex_input_vec(co1, in[0]);
tex_input_vec(co2, in[1]);
zero_v4(out[0]->vec);
/* TODO(sergey): This appears to be darker than 2.72 somehow.
* Could be because testing with OCIO disabled tho.
*/
out[0]->vec[0] = len_v3v3(co2, co1);
}
void register_node_type_tex_distance(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -70,36 +70,35 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
}
}
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
float hue = tex_input_value(in[0], p, thread);
float sat = tex_input_value(in[1], p, thread);
float val = tex_input_value(in[2], p, thread);
float fac = tex_input_value(in[3], p, thread);
float col[4];
tex_input_rgba(col, in[4], p, thread);
hue += 0.5f; /* [-0.5, 0.5] -> [0, 1] */
do_hue_sat_fac(node, out, hue, sat, val, col, fac);
out[3] = col[3];
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
float hue = tex_input_value(in[0]);
float sat = tex_input_value(in[1]);
float val = tex_input_value(in[2]);
float fac = tex_input_value(in[3]);
float col[4];
tex_input_rgba(col, in[4]);
hue += 0.5f; /* [-0.5, 0.5] -> [0, 1] */
do_hue_sat_fac(node, out[0]->vec, hue, sat, val, col, fac);
out[0]->vec[3] = col[3];
}
void register_node_type_tex_hue_sat(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -38,54 +38,59 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
static void exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *execdata,
bNodeStack **UNUSED(in),
bNodeStack **out)
{
float x = p->co[0];
float y = p->co[1];
TexCallData *cdata = (TexCallData *)data;
float x, y;
Image *ima = (Image *)node->id;
ImageUser *iuser = (ImageUser *)node->storage;
x = cdata->co[0];
y = cdata->co[1];
if (ima) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf) {
float xsize, ysize;
float xoff, yoff;
int px, py;
const float *result;
xsize = ibuf->x / 2;
ysize = ibuf->y / 2;
xoff = yoff = -1;
px = (int)( (x - xoff) * xsize);
py = (int)( (y - yoff) * ysize);
if ( (!xsize) || (!ysize) ) return;
if (!ibuf->rect_float) {
BLI_lock_thread(LOCK_IMAGE);
if (!ibuf->rect_float)
IMB_float_from_rect(ibuf);
BLI_unlock_thread(LOCK_IMAGE);
}
while (px < 0) px += ibuf->x;
while (py < 0) py += ibuf->y;
while (px >= ibuf->x) px -= ibuf->x;
while (py >= ibuf->y) py -= ibuf->y;
result = ibuf->rect_float + py * ibuf->x * 4 + px * 4;
copy_v4_v4(out, result);
copy_v4_v4(out[0]->vec, result);
BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
}
static void init(bNodeTree *UNUSED(ntree), bNode *node)
@@ -100,12 +105,12 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_image(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, NULL, outputs);
node_type_init(&ntype, init);
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -44,23 +44,22 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float col[4];
tex_input_rgba(col, in[0], p, thread);
tex_input_rgba(col, in[0]);
col[0] = 1.0f - col[0];
col[1] = 1.0f - col[1];
col[2] = 1.0f - col[2];
copy_v3_v3(out, col);
out[3] = col[3];
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
copy_v4_v4(out[0]->vec, col);
}
void register_node_type_tex_invert(void)

View File

@@ -46,81 +46,86 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float in0 = tex_input_value(in[0], p, thread);
float in1 = tex_input_value(in[1], p, thread);
float in0 = tex_input_value(in[0]);
float in1 = tex_input_value(in[1]);
switch (node->custom1) {
case NODE_MATH_ADD:
*out = in0 + in1;
out[0]->vec[0] = in0 + in1;
break;
case NODE_MATH_SUB:
*out = in0 - in1;
out[0]->vec[0] = in0 - in1;
break;
case NODE_MATH_MUL:
*out = in0 * in1;
out[0]->vec[0] = in0 * in1;
break;
case NODE_MATH_DIVIDE:
{
if (in1 == 0) /* We don't want to divide by zero. */
*out = 0.0;
out[0]->vec[0] = 0.0f;
else
*out = in0 / in1;
out[0]->vec[0] = in0 / in1;
break;
}
case NODE_MATH_SIN:
{
*out = sinf(in0);
out[0]->vec[0] = sinf(in0);
break;
}
case NODE_MATH_COS:
{
*out = cosf(in0);
out[0]->vec[0] = cosf(in0);
break;
}
case NODE_MATH_TAN:
{
*out = tanf(in0);
out[0]->vec[0] = tanf(in0);
break;
}
case NODE_MATH_ASIN:
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
*out = asinf(in0);
if (in0 <= 1.0f && in0 >= -1.0f)
out[0]->vec[0] = asinf(in0);
else
*out = 0.0;
out[0]->vec[0] = 0.0f;
break;
}
case NODE_MATH_ACOS:
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
*out = acosf(in0);
if (in0 <= 1.0f && in0 >= -1.0f)
out[0]->vec[0]= acosf(in0);
else
*out = 0.0;
out[0]->vec[0] = 0.0;
break;
}
case NODE_MATH_ATAN:
{
*out = atan(in0);
out[0]->vec[0] = atan(in0);
break;
}
case NODE_MATH_POW:
{
/* Only raise negative numbers by full integers */
if (in0 >= 0) {
out[0] = pow(in0, in1);
if (in0 >= 0.0f) {
out[0]->vec[0] = pow(in0, in1);
}
else {
float y_mod_1 = fmod(in1, 1);
float y_mod_1 = fmod(in1, 1.0f);
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
*out = pow(in0, floor(in1 + 0.5f));
out[0]->vec[0] = powf(in0, floor(in1 + 0.5f));
}
else {
*out = 0.0;
out[0]->vec[0] = 0.0f;
}
}
break;
@@ -128,64 +133,64 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
case NODE_MATH_LOG:
{
/* Don't want any imaginary numbers... */
if (in0 > 0 && in1 > 0)
*out = log(in0) / log(in1);
if (in0 > 0.0f && in1 > 0.0f)
out[0]->vec[0] = log(in0) / log(in1);
else
*out = 0.0;
out[0]->vec[0] = 0.0;
break;
}
case NODE_MATH_MIN:
{
if (in0 < in1)
*out = in0;
out[0]->vec[0] = in0;
else
*out = in1;
out[0]->vec[0] = in1;
break;
}
case NODE_MATH_MAX:
{
if (in0 > in1)
*out = in0;
out[0]->vec[0] = in0;
else
*out = in1;
out[0]->vec[0] = in1;
break;
}
case NODE_MATH_ROUND:
{
*out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
out[0]->vec[0] = (in0 < 0.0f) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
break;
}
case NODE_MATH_LESS:
{
if (in0 < in1)
*out = 1.0f;
out[0]->vec[0] = 1.0f;
else
*out = 0.0f;
out[0]->vec[0] = 0.0f;
break;
}
case NODE_MATH_GREATER:
{
if (in0 > in1)
*out = 1.0f;
out[0]->vec[0] = 1.0f;
else
*out = 0.0f;
out[0]->vec[0] = 0.0f;
break;
}
case NODE_MATH_MOD:
{
if (in1 == 0.0f)
*out = 0.0f;
out[0]->vec[0] = 0.0f;
else
*out = fmod(in0, in1);
out[0]->vec[0] = fmod(in0, in1);
break;
}
case NODE_MATH_ABS:
{
*out = fabsf(in0);
out[0]->vec[0] = fabsf(in0);
break;
}
@@ -197,11 +202,6 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &valuefn, data);
}
void register_node_type_tex_math(void)
{
static bNodeType ntype;

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -45,37 +45,37 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void exec(void *UNUSED(data),
int UNUSED(thread),
bNode *node,
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float fac = tex_input_value(in[0], p, thread);
float fac = tex_input_value(in[0]);
float col1[4], col2[4];
tex_input_rgba(col1, in[1], p, thread);
tex_input_rgba(col2, in[2], p, thread);
tex_input_rgba(col1, in[1]);
tex_input_rgba(col2, in[2]);
/* use alpha */
if (node->custom2 & 1)
fac *= col2[3];
CLAMP(fac, 0.0f, 1.0f);
copy_v4_v4(out, col1);
ramp_blend(node->custom1, out, fac, col2);
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
CLAMP(fac, 0.0f, 1.0f);
copy_v4_v4(out[0]->vec, col1);
ramp_blend(node->custom1, out[0]->vec, fac, col2);
}
void register_node_type_tex_mix_rgb(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_label(&ntype, node_blend_label);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -41,35 +41,34 @@ static bNodeSocketTemplate inputs[] = {
};
/* applies to render pipeline */
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
static void exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **UNUSED(out))
{
TexCallData *cdata = (TexCallData *)data;
TexResult *target = cdata->target;
if (cdata->do_preview) {
TexParams params;
params_from_cdata(&params, cdata);
if (cdata->do_preview) {
if (in[1] && in[1]->hasinput && !in[0]->hasinput)
tex_input_rgba(&target->tr, in[1], &params, cdata->thread);
tex_input_rgba(&target->tr, in[1]);
else
tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
tex_do_preview(execdata->preview, params.co, &target->tr, cdata->do_manage);
tex_input_rgba(&target->tr, in[0]);
tex_do_preview(execdata->preview, cdata->co, &target->tr, cdata->do_manage);
}
else {
/* 0 means don't care, so just use first */
if (cdata->which_output == node->custom1 || (cdata->which_output == 0 && node->custom1 == 1)) {
TexParams params;
params_from_cdata(&params, cdata);
tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
tex_input_rgba(&target->tr, in[0]);
target->tin = (target->tr + target->tg + target->tb) / 3.0f;
target->talpha = true;
if (target->nor) {
if (in[1] && in[1]->hasinput)
tex_input_vec(target->nor, in[1], &params, cdata->thread);
tex_input_vec(target->nor, in[1]);
else
target->nor = NULL;
}
@@ -85,7 +84,7 @@ static void unique_name(bNode *node)
int suffix;
bNode *i;
const char *name = tno->name;
new_name[0] = '\0';
i = node;
while (i->prev) i = i->prev;
@@ -114,7 +113,7 @@ static void unique_name(bNode *node)
}
sprintf(new_name + new_len - 4, ".%03d", ++suffix);
}
if (new_name[0] != '\0') {
BLI_strncpy(tno->name, new_name, sizeof(tno->name));
}
@@ -124,19 +123,21 @@ static void assign_index(struct bNode *node)
{
bNode *tnode;
int index = 1;
tnode = node;
while (tnode->prev)
tnode = tnode->prev;
check_index:
for (; tnode; tnode = tnode->next)
if (tnode->type == TEX_NODE_OUTPUT && tnode != node)
for (; tnode; tnode = tnode->next) {
if (tnode->type == TEX_NODE_OUTPUT && tnode != node) {
if (tnode->custom1 == index) {
index++;
goto check_index;
}
}
}
node->custom1 = index;
}
@@ -144,7 +145,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
node->storage = tno;
strcpy(tno->name, "Default");
unique_name(node);
assign_index(node);
@@ -160,16 +161,16 @@ static void copy(bNodeTree *dest_ntree, bNode *dest_node, bNode *src_node)
void register_node_type_tex_output(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, NULL);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, init);
node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy);
node_type_exec(&ntype, NULL, NULL, exec);
/* Do not allow muting output. */
node_type_internal_links(&ntype, NULL);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -35,7 +35,7 @@
#include "RE_shader_ext.h"
/*
/*
* In this file: wrappers to use procedural textures as nodes
*/
@@ -57,23 +57,29 @@ static bNodeSocketTemplate outputs_color_only[] = {
{ SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f }
/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
static void do_proc(float *result, TexParams *p, const float col1[4], const float col2[4], char is_normal, Tex *tex, const short thread)
static void do_proc(float *result,
TexCallData *cdata,
const float col1[4],
const float col2[4],
bool is_normal,
Tex *tex,
const short thread)
{
TexResult texres;
int textype;
if (is_normal) {
texres.nor = result;
}
else
texres.nor = NULL;
textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
&texres, thread, 0, p->shi, p->mtex, NULL);
textype = multitex_nodes(tex, cdata->co, cdata->dxt, cdata->dyt, cdata->osatex,
&texres, thread, 0, cdata->shi, cdata->mtex, NULL);
if (is_normal)
return;
if (textype & TEX_RGB) {
copy_v4_v4(result, &texres.tr);
}
@@ -83,57 +89,42 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa
}
}
typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread);
typedef void (*MapFn) (Tex *tex, bNodeStack **in);
static void texfn(
float *result,
TexParams *p,
bNode *node,
bNodeStack **in,
char is_normal,
MapFn map_inputs,
short thread)
static void texfn(float *result,
TexCallData *cdata,
bNode *node,
bNodeStack **in,
bool is_normal,
MapFn map_inputs,
short thread)
{
Tex tex = *((Tex *)(node->storage));
float col1[4], col2[4];
tex_input_rgba(col1, in[0], p, thread);
tex_input_rgba(col2, in[1], p, thread);
map_inputs(&tex, in, p, thread);
do_proc(result, p, col1, col2, is_normal, &tex, thread);
}
tex_input_rgba(col1, in[0]);
tex_input_rgba(col2, in[1]);
static int count_outputs(bNode *node)
{
bNodeSocket *sock;
int num = 0;
for (sock = node->outputs.first; sock; sock = sock->next) {
num++;
}
return num;
map_inputs(&tex, in);
do_proc(result, cdata, col1, col2, is_normal, &tex, thread);
}
/* Boilerplate generators */
#define ProcNoInputs(name) \
static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \
static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in)) \
{}
#define ProcDef(name) \
static void name##_colorfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
static void name##_exec(void *data, int thread, bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) \
{ \
texfn(result, p, node, in, 0, &name##_map_inputs, thread); \
} \
static void name##_normalfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
{ \
texfn(result, p, node, in, 1, &name##_map_inputs, thread); \
} \
static void name##_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) \
{ \
int outs = count_outputs(node); \
if (outs >= 1) tex_output(node, execdata, in, out[0], &name##_colorfn, data); \
if (outs >= 2) tex_output(node, execdata, in, out[1], &name##_normalfn, data); \
int outs = BLI_countlist(&node->outputs); \
TexCallData *cdata = (TexCallData *)data; \
if (outs >= 1) { \
texfn(out[0]->vec, cdata, node, in, false, &name##_map_inputs, thread); \
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage); \
} \
if (outs >= 2) texfn(out[1]->vec, cdata, node, in, true, &name##_map_inputs, thread); \
}
@@ -144,21 +135,21 @@ static bNodeSocketTemplate voronoi_inputs[] = {
{ SOCK_FLOAT, 1, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
{ SOCK_FLOAT, 1, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
{ SOCK_FLOAT, 1, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void voronoi_map_inputs(Tex *tex, bNodeStack **in)
{
tex->vn_w1 = tex_input_value(in[I + 0], p, thread);
tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
tex->noisesize = tex_input_value(in[I + 5], p, thread);
tex->vn_w1 = tex_input_value(in[I + 0]);
tex->vn_w2 = tex_input_value(in[I + 1]);
tex->vn_w3 = tex_input_value(in[I + 2]);
tex->vn_w4 = tex_input_value(in[I + 3]);
tex->ns_outscale = tex_input_value(in[I + 4]);
tex->noisesize = tex_input_value(in[I + 5]);
}
ProcDef(voronoi)
@@ -176,9 +167,9 @@ static bNodeSocketTemplate magic_inputs[] = {
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void magic_map_inputs(Tex *tex, bNodeStack **in)
{
tex->turbul = tex_input_value(in[I + 0], p, thread);
tex->turbul = tex_input_value(in[I + 0]);
}
ProcDef(magic)
@@ -189,10 +180,10 @@ static bNodeSocketTemplate marble_inputs[] = {
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void marble_map_inputs(Tex *tex, bNodeStack **in)
{
tex->noisesize = tex_input_value(in[I + 0], p, thread);
tex->turbul = tex_input_value(in[I + 1], p, thread);
tex->noisesize = tex_input_value(in[I + 0]);
tex->turbul = tex_input_value(in[I + 1]);
}
ProcDef(marble)
@@ -202,9 +193,9 @@ static bNodeSocketTemplate clouds_inputs[] = {
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void clouds_map_inputs(Tex *tex, bNodeStack **in)
{
tex->noisesize = tex_input_value(in[I + 0], p, thread);
tex->noisesize = tex_input_value(in[I + 0]);
}
ProcDef(clouds)
@@ -215,10 +206,10 @@ static bNodeSocketTemplate distnoise_inputs[] = {
{ SOCK_FLOAT, 1, N_("Distortion"), 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void distnoise_map_inputs(Tex *tex, bNodeStack **in)
{
tex->noisesize = tex_input_value(in[I + 0], p, thread);
tex->dist_amount = tex_input_value(in[I + 1], p, thread);
tex->noisesize = tex_input_value(in[I + 0]);
tex->dist_amount = tex_input_value(in[I + 1]);
}
ProcDef(distnoise)
@@ -229,10 +220,10 @@ static bNodeSocketTemplate wood_inputs[] = {
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void wood_map_inputs(Tex *tex, bNodeStack **in)
{
tex->noisesize = tex_input_value(in[I + 0], p, thread);
tex->turbul = tex_input_value(in[I + 1], p, thread);
tex->noisesize = tex_input_value(in[I + 0]);
tex->turbul = tex_input_value(in[I + 1]);
}
ProcDef(wood)
@@ -242,18 +233,18 @@ static bNodeSocketTemplate musgrave_inputs[] = {
{ SOCK_FLOAT, 1, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void musgrave_map_inputs(Tex *tex, bNodeStack **in)
{
tex->mg_H = tex_input_value(in[I + 0], p, thread);
tex->mg_lacunarity = tex_input_value(in[I + 1], p, thread);
tex->mg_octaves = tex_input_value(in[I + 2], p, thread);
tex->ns_outscale = tex_input_value(in[I + 3], p, thread);
tex->noisesize = tex_input_value(in[I + 4], p, thread);
tex->mg_H = tex_input_value(in[I + 0]);
tex->mg_lacunarity = tex_input_value(in[I + 1]);
tex->mg_octaves = tex_input_value(in[I + 2]);
tex->ns_outscale = tex_input_value(in[I + 3]);
tex->noisesize = tex_input_value(in[I + 4]);
}
ProcDef(musgrave)
@@ -272,10 +263,10 @@ static bNodeSocketTemplate stucci_inputs[] = {
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
{ -1, 0, "" }
};
static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void stucci_map_inputs(Tex *tex, bNodeStack **in)
{
tex->noisesize = tex_input_value(in[I + 0], p, thread);
tex->turbul = tex_input_value(in[I + 1], p, thread);
tex->noisesize = tex_input_value(in[I + 0]);
tex->turbul = tex_input_value(in[I + 1]);
}
ProcDef(stucci)
@@ -285,13 +276,12 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
node->storage = tex;
default_tex(tex);
tex->type = node->type - TEX_NODE_PROC;
if (tex->type == TEX_WOOD)
tex->stype = TEX_BANDNOISE;
}
/* Node type definitions */
@@ -309,10 +299,10 @@ void register_node_type_tex_proc_##name(void) \
\
nodeRegisterType(&ntype); \
}
#define C outputs_color_only
#define CV outputs_both
TexDef(TEX_VORONOI, CV, voronoi, "Voronoi" )
TexDef(TEX_BLEND, C, blend, "Blend" )
TexDef(TEX_MAGIC, C, magic, "Magic" )

View File

@@ -69,12 +69,12 @@ static void rotate(float new_co[3], float a, float ax[3], const float co[3])
new_co[2] = para[2] + perp[2] + cp[2];
}
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
{
float new_co[3], new_dxt[3], new_dyt[3], a, ax[3];
a = tex_input_value(in[1], p, thread);
tex_input_vec(ax, in[2], p, thread);
a = tex_input_value(in[1]);
tex_input_vec(ax, in[2]);
rotate(new_co, a, ax, p->co);
if (p->osatex) {
@@ -87,7 +87,8 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
np.co = new_co;
np.dxt = new_dxt;
np.dyt = new_dyt;
tex_input_rgba(out, in[0], &np, thread);
//tex_input_rgba(out, in[0], &np, thread);
BLI_assert(!"Needs proper solution");
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)

View File

@@ -44,7 +44,7 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
{
float scale[3], new_co[3], new_dxt[3], new_dyt[3];
TexParams np = *p;
@@ -53,7 +53,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
np.dxt = new_dxt;
np.dyt = new_dyt;
tex_input_vec(scale, in[1], p, thread);
tex_input_vec(scale, in[1]);
mul_v3_v3v3(new_co, p->co, scale);
if (p->osatex) {
@@ -61,7 +61,8 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
mul_v3_v3v3(new_dyt, p->dyt, scale);
}
tex_input_rgba(out, in[0], &np, thread);
//tex_input_rgba(out, in[0], &np, thread);
BLI_assert(!"Need proper solution");
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{

View File

@@ -46,62 +46,64 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void exec(void *data,
int thread,
bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **out)
{
Tex *nodetex = (Tex *)node->id;
static float red[] = {1, 0, 0, 1};
static float white[] = {1, 1, 1, 1};
TexCallData *cdata = (TexCallData *)data;
static float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
static float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
float co[3], dxt[3], dyt[3];
copy_v3_v3(co, p->co);
if (p->osatex) {
copy_v3_v3(dxt, p->dxt);
copy_v3_v3(dyt, p->dyt);
copy_v3_v3(co, cdata->co);
if (cdata->osatex) {
copy_v3_v3(dxt, cdata->dxt);
copy_v3_v3(dyt, cdata->dyt);
}
else {
zero_v3(dxt);
zero_v3(dyt);
}
if (node->custom2 || node->need_exec == 0) {
/* this node refers to its own texture tree! */
copy_v4_v4(out, (fabsf(co[0] - co[1]) < 0.01f) ? white : red);
copy_v4_v4(out[0]->vec, (fabsf(co[0] - co[1]) < 0.01f) ? white : red);
}
else if (nodetex) {
TexResult texres;
int textype;
float nor[] = {0, 0, 0};
float col1[4], col2[4];
tex_input_rgba(col1, in[0], p, thread);
tex_input_rgba(col2, in[1], p, thread);
tex_input_rgba(col1, in[0]);
tex_input_rgba(col2, in[1]);
texres.nor = nor;
textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex,
&texres, thread, 0, p->shi, p->mtex, NULL);
textype = multitex_nodes(nodetex, co, dxt, dyt, cdata->osatex,
&texres, thread, 0, cdata->shi, cdata->mtex, NULL);
if (textype & TEX_RGB) {
copy_v4_v4(out, &texres.tr);
copy_v4_v4(out[0]->vec, &texres.tr);
}
else {
copy_v4_v4(out, col1);
ramp_blend(MA_RAMP_BLEND, out, texres.tin, col2);
copy_v4_v4(out[0]->vec, col1);
ramp_blend(MA_RAMP_BLEND, out[0]->vec, texres.tin, col2);
}
}
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
}
void register_node_type_tex_texture(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
nodeRegisterType(&ntype);
}

View File

@@ -45,19 +45,20 @@ static bNodeSocketTemplate outputs[] = {
{ -1, 0, "" }
};
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
{
float offset[3], new_co[3];
TexParams np = *p;
np.co = new_co;
tex_input_vec(offset, in[1], p, thread);
tex_input_vec(offset, in[1]);
new_co[0] = p->co[0] + offset[0];
new_co[1] = p->co[1] + offset[1];
new_co[2] = p->co[2] + offset[2];
tex_input_rgba(out, in[0], &np, thread);
//tex_input_rgba(out, in[0], &np, thread);
BLI_assert(!"Need a proper port");
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{

View File

@@ -46,6 +46,7 @@ static bNodeSocketTemplate outputs[] = {
static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
#if 0
float new_co[3];
const float *co = p->co;
@@ -74,6 +75,13 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack *
out[0] = val - nor[0];
out[1] = val - nor[1];
out[2] = val - nor[2];
#else
(void) out;
(void) p;
(void) in;
(void) thread;
BLI_assert(!"Need a proper port");
#endif
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -43,10 +43,10 @@ static bNodeSocketTemplate valtorgb_out[] = {
{ -1, 0, "" }
};
static void valtorgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
static void valtorgb_colorfn(float *out, TexParams *UNUSED(p), bNode *node, bNodeStack **in, short UNUSED(thread))
{
if (node->storage) {
float fac = tex_input_value(in[0], p, thread);
float fac = tex_input_value(in[0]);
do_colorband(node->storage, fac, out);
}
@@ -86,26 +86,25 @@ static bNodeSocketTemplate rgbtobw_out[] = {
{ -1, 0, "" }
};
static void rgbtobw_valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
static void rgbtobw_exec(void *UNUSED(data),
int UNUSED(thread),
bNode *UNUSED(node),
bNodeExecData *UNUSED(execdata),
bNodeStack **in,
bNodeStack **out)
{
float cin[4];
tex_input_rgba(cin, in[0], p, thread);
*out = rgb_to_bw(cin);
}
static void rgbtobw_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &rgbtobw_valuefn, data);
tex_input_rgba(cin, in[0]);
out[0]->vec[0] = rgb_to_bw(cin);
}
void register_node_type_tex_rgbtobw(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, rgbtobw_in, rgbtobw_out);
node_type_exec(&ntype, NULL, NULL, rgbtobw_exec);
nodeRegisterType(&ntype);
}

View File

@@ -4,7 +4,7 @@
* 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.
* 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
@@ -45,27 +45,23 @@ static bNodeSocketTemplate outputs[] = {
static void exec(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
{
TexCallData *cdata = (TexCallData *)data;
if (cdata->do_preview) {
TexParams params;
float col[4];
params_from_cdata(&params, cdata);
tex_input_rgba(col, in[0], &params, cdata->thread);
tex_do_preview(execdata->preview, params.previewco, col, cdata->do_manage);
tex_input_rgba(col, in[0]);
tex_do_preview(execdata->preview, cdata->co, col, cdata->do_manage);
}
}
void register_node_type_tex_viewer(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
/* Do not allow muting viewer node. */
node_type_internal_links(&ntype, NULL);
nodeRegisterType(&ntype);
}

View File

@@ -304,5 +304,8 @@ bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override
bool RE_allow_render_generic_object(struct Object *ob);
struct bNodeTreeExecPool;
struct bNodeTreeExecPool *RE_tree_exec_pool_get(struct Render *re);
#endif /* __RE_PIPELINE_H__ */

View File

@@ -66,6 +66,7 @@ struct RenderEngine;
struct ReportList;
struct Main;
struct ImagePool;
struct bNodeTreeExecPool;
#define TABLEINITSIZE 1024
@@ -275,6 +276,7 @@ struct Render
struct ImagePool *pool;
struct EvaluationContext *eval_ctx;
struct bNodeTreeExecPool *tree_exec_pool;
};
/* ------------------------------------------------------------------------- */

View File

@@ -176,7 +176,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
shade_samples_do_AO(ssamp);
if (shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, &shr);
shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
}
else

View File

@@ -4741,7 +4741,7 @@ void RE_Database_Free(Render *re)
free_mesh_orco_hash(re);
if (re->main) {
end_render_materials(re->main);
end_render_materials(re->main, re->tree_exec_pool);
end_render_textures(re);
free_pointdensities(re);
}
@@ -5110,6 +5110,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
{
Scene *sce;
Object *camera;
bNodeTreeExecPool *tree_exec_pool;
float mat[4][4];
float amb[3];
@@ -5176,9 +5177,10 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
}
/* still bad... doing all */
tree_exec_pool = RE_tree_exec_pool_get(re);
init_render_textures(re);
copy_v3_v3(amb, &re->wrld.ambr);
init_render_materials(re->main, re->r.mode, amb);
init_render_materials(re->main, tree_exec_pool, re->r.mode, amb);
set_node_shader_lamp_loop(shade_material_loop);
/* MAKE RENDER DATA */
@@ -5829,6 +5831,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, const int type, Object *actob)
{
Object *camera;
bNodeTreeExecPool *tree_exec_pool;
float mat[4][4];
float amb[3];
const short onlyselected= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO, RE_BAKE_VERTEX_COLORS);
@@ -5910,7 +5913,8 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
init_render_textures(re);
copy_v3_v3(amb, &re->wrld.ambr);
init_render_materials(re->main, re->r.mode, amb);
tree_exec_pool = RE_tree_exec_pool_get(re);
init_render_materials(re->main, tree_exec_pool, re->r.mode, amb);
set_node_shader_lamp_loop(shade_material_loop);

View File

@@ -199,7 +199,7 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr,
shade_input_set_shade_texco(shi);
if (shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
}
else {

View File

@@ -387,6 +387,7 @@ Render *RE_NewRender(const char *name)
BLI_rw_mutex_init(&re->resultmutex);
re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx");
re->eval_ctx->mode = DAG_EVAL_RENDER;
re->tree_exec_pool = BKE_node_tree_exec_pool_new();
}
RE_InitRenderCB(re);
@@ -435,7 +436,9 @@ void RE_FreeRender(Render *re)
render_result_free(re->result);
render_result_free(re->pushedresult);
BKE_node_tree_exec_pool_free(re->tree_exec_pool);
BLI_remlink(&RenderGlobal.renderlist, re);
MEM_freeN(re->eval_ctx);
MEM_freeN(re);
@@ -3330,3 +3333,8 @@ bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
}
}
struct bNodeTreeExecPool *RE_tree_exec_pool_get(Render *re)
{
return re->tree_exec_pool;
}

View File

@@ -534,7 +534,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
else if (is->mode==RE_RAY_SHADOW_TRA) {
/* temp hack to prevent recursion */
if (shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
}
else
@@ -542,7 +542,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
}
else {
if (shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
}
else {

View File

@@ -122,7 +122,16 @@ static void init_render_texture(Render *re, Tex *tex)
}
if (tex->nodetree && tex->use_nodes) {
ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
struct bNodeTreeExec *exec_data;
BLI_assert(re != NULL);
exec_data = BKE_node_tree_exec_pool_get(re->tree_exec_pool,
&tex->nodetree->id);
if (exec_data == NULL) {
exec_data = ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
BKE_node_tree_exec_pool_put(re->tree_exec_pool,
&tex->nodetree->id,
exec_data);
}
}
}
@@ -139,10 +148,16 @@ void init_render_textures(Render *re)
}
}
static void end_render_texture(Tex *tex)
static void end_render_texture(Render *re, Tex *tex)
{
if (tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
ntreeTexEndExecTree(tex->nodetree->execdata);
if (tex && tex->use_nodes && tex->nodetree) {
struct bNodeTreeExec *exec_data =
BKE_node_tree_exec_pool_pop(re->tree_exec_pool,
&tex->nodetree->id);
if (exec_data != NULL) {
ntreeTexEndExecTree(exec_data);
}
}
}
void end_render_textures(Render *re)
@@ -150,7 +165,7 @@ void end_render_textures(Render *re)
Tex *tex;
for (tex= re->main->tex.first; tex; tex= tex->id.next)
if (tex->id.us)
end_render_texture(tex);
end_render_texture(re, tex);
}
/* ------------------------------------------------------------------------- */
@@ -1111,7 +1126,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
if (tex->use_nodes && tex->nodetree) {
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
retval = ntreeTexExecTree(R.tree_exec_pool, tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL);
}
else {
@@ -1307,7 +1322,7 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
if (tex->use_nodes && tex->nodetree) {
/* stupid exception here .. but we have to pass shi and mtex to
* textures nodes for 2d mapping and color management for images */
return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
return ntreeTexExecTree(R.tree_exec_pool, tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
}
else {

View File

@@ -156,7 +156,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
#endif
if (shi->mat->nodetree && shi->mat->use_nodes)
compat = ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
compat = ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
/* also run this when node shaders fail, due to incompatible shader nodes */
if (compat == false) {