From 8ddc48d32f011b0c5af5c191a94188e3f29c3776 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 27 Dec 2007 14:19:11 +0000 Subject: Directional Blur Node Directional Blur node allows the users to do various blur operations on the input image. It essentially offers three different kind of ways of blurring in one node. It is possible to blur using a certain direction, spin and zoom. These three ways can be used in conjunction. The node contains following controls: *Iterations, Wrap *Center: X, Y *Distance, Angle *Spin *Zoom Iterations is used to determine the smoothness of the result. The more iterations, the smoother result. Low values are good for preview. Wrap means that the image is wrapped as if it was tiled on both x and y directions. To see better what this means, try it with spin for instance. Center values (X and Y) determine the location which is used as a pivot point for the operations. It is center (0.5) of the image by default. Distance and angle are used to adjust directional blur. The result can be described as a sweep that varies based on given distance (bigger distance, longer sweep) and angle. Angle is given in degrees. Spin produces rotating blur based on given angle. Yet again it is in degrees. Also negative values work. Zoom causes the image to be zoomed towards set center point (Center values). Thanks to Alfredo de Greef (eeshlo) for contribution. Possible development ideas: *Make an algorithm to extend image in case spin is used. Extend would temporarily change the size of the canvas of the input image. Canvas would be filled based on colors on the edges of the input image. After the blur operation has been done, the image would be cropped back to normal size. The advantage of this would be nicer result of spin (no problems with image size) on a computational cost. *Make values animatable. This is something that is better solved on more general level. ("everything is animatable" paradigm) *Provide an option to calculate automatic value for iterations. A good value that produces a smooth result could be calculated based on direction deltas. This would be useful in conjuction of animatable values. --- source/blender/nodes/CMP_node.h | 1 + .../nodes/intern/CMP_nodes/CMP_directionalblur.c | 143 +++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index 4b7e721ca57..d1e04065835 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -66,6 +66,7 @@ extern bNodeType cmp_node_normalize; extern bNodeType cmp_node_filter; extern bNodeType cmp_node_blur; +extern bNodeType cmp_node_dblur; extern bNodeType cmp_node_vecblur; extern bNodeType cmp_node_dilateerode; extern bNodeType cmp_node_defocus; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c new file mode 100644 index 00000000000..27f535186db --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c @@ -0,0 +1,143 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Alfredo de Greef (eeshlo) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + +static bNodeSocketType cmp_node_dblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f, 0.f, 1.f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_dblur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap, + float center_x, float center_y, float dist, float angle, float spin, float zoom) +{ + if ((dist != 0.f) || (spin != 0.f) || (zoom != 0.f)) { + void (*getpix)(CompBuf*, float, float, float*) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp; + const float a= angle * (float)M_PI / 180.f; + const float itsc= 1.f / pow(2.f, (float)iterations); + float D; + float center_x_pix, center_y_pix; + float tx, ty; + float sc, rot; + CompBuf *tmp; + int i, j; + + tmp= dupalloc_compbuf(img); + + D= dist * sqrtf(img->x * img->x + img->y * img->y); + center_x_pix= center_x * img->x; + center_y_pix= center_y * img->y; + + tx= itsc * D * cos(a); + ty= -itsc * D * sin(a); + sc= itsc * zoom; + rot= itsc * spin * (float)M_PI / 180.f; + + /* blur the image */ + for(i= 0; i < iterations; ++i) { + const float cs= cos(rot), ss= sin(rot); + const float isc= 1.f / (1.f + sc); + unsigned int x, y; + float col[4]= {0,0,0,0}; + + for(y= 0; y < img->y; ++y) { + const float v= isc * (y - center_y_pix) + ty; + + for(x= 0; x < img->x; ++x) { + const float u= isc * (x - center_x_pix) + tx; + unsigned int p= (x + y * img->x) * img->type; + + getpix(tmp, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, col); + + /* mix img and transformed tmp */ + for(j= 0; j < 4; ++j) + img->rect[p + j]= AVG2(img->rect[p + j], col[j]); + } + } + + /* copy img to tmp */ + if(i != (iterations - 1)) + memcpy(tmp->rect, img->rect, sizeof(float) * img->x * img->y * img->type); + + /* double transformations */ + tx *= 2.f, ty *= 2.f; + sc *= 2.f, rot *= 2.f; + + if(node->exec & NODE_BREAK) break; + } + + free_compbuf(tmp); + } + + return img; +} + +static void node_composit_exec_dblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + NodeDBlurData *ndbd= node->storage; + CompBuf *new, *img= in[0]->data; + + if((img == NULL) || (out[0]->hasoutput == 0)) return; + + if (img->type != CB_RGBA) + new = typecheck_compbuf(img, CB_RGBA); + else + new = dupalloc_compbuf(img); + + out[0]->data= dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom); +} + +static void node_composit_init_dblur(bNode* node) +{ + NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); + node->storage= ndbd; + ndbd->center_x= 0.5; + ndbd->center_y= 0.5; +} + +bNodeType cmp_node_dblur = { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_DBLUR, + /* name */ "Directional Blur", + /* width+range */ 150, 120, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_dblur_in, + /* output sock */ cmp_node_dblur_out, + /* storage */ "NodeDBlurData", + /* execfunc */ node_composit_exec_dblur, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_dblur, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL +}; -- cgit v1.2.3 From f4015d9fce21a4aa5991e3977a146183b1ea32ba Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 27 Dec 2007 20:36:17 +0000 Subject: Bilateral Blur Node Bilateral Blur node allows the user to blur images while retaining their sharp edges. Blurring can be controlled by following controls: *Iterations *Color Sigma *Space Sigma Also image input to blur and a determinator image is provided. The node produces a blurred image as its output. The more iterations are provided, the smoother the result. Use color and space sigmas to control the amount of blur. One way to use the determinator input is to feed a mix (add) of Z and normal passes to it. Examples of usage: Ambient Occlusion smoothing - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_01.blend Blurry Refraction - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_02.blend Smoothed shadows and smoothed Ambient Occlusion combined - http://wiki.blender.org/index.php/Image:Bilateral_blur_example_03.blend If you check out the examples, render the image and alter the values to see how they affect. More information about the algorithm can be found at http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html . Thanks to Vilem Novak for contributing the patch. --- source/blender/nodes/CMP_node.h | 1 + .../nodes/intern/CMP_nodes/CMP_bilateralblur.c | 273 +++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index d1e04065835..3e62ea9970f 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -67,6 +67,7 @@ extern bNodeType cmp_node_normalize; extern bNodeType cmp_node_filter; extern bNodeType cmp_node_blur; extern bNodeType cmp_node_dblur; +extern bNodeType cmp_node_bilateralblur; extern bNodeType cmp_node_vecblur; extern bNodeType cmp_node_dilateerode; extern bNodeType cmp_node_defocus; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c new file mode 100644 index 00000000000..81592becf4b --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c @@ -0,0 +1,273 @@ +/** + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Vilem Novak + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include "../CMP_util.h" + +/* **************** BILATERALBLUR ******************** */ +static bNodeSocketType cmp_node_bilateralblur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_bilateralblur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +#define INIT_C3\ + mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];mean1[3] = src[3]; + +/* finds color distances */ +#define COLOR_DISTANCE_C3(c1, c2)\ + ((c1[0] - c2[0])*(c1[0] - c2[0]) + \ + (c1[1] - c2[1])*(c1[1] - c2[1]) + \ + (c1[2] - c2[2])*(c1[2] - c2[2]) + \ + (c1[3] - c2[3])*(c1[3] - c2[3])) + +/* this is the main kernel function for comparing color distances + and adding them weighted to the final color */ +#define KERNEL_ELEMENT_C3(k)\ + temp_color = src + deltas[k];\ + ref_color = ref + deltas[k];\ + w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color;\ + w = 1./(w*w + 1); \ + mean0 += w;\ + mean1[0] += temp_color[0]*w; \ + mean1[1] += temp_color[1]*w; \ + mean1[2] += temp_color[2]*w; \ + mean1[3] += temp_color[3]*w; + +/* write blurred values to image */ +#define UPDATE_OUTPUT_C3\ + mean0 = 1./mean0;\ + dest[x*pix + 0] = mean1[0]*mean0; \ + dest[x*pix + 1] = mean1[1]*mean0; \ + dest[x*pix + 2] = mean1[2]*mean0; \ + dest[x*pix + 3] = mean1[3]*mean0; + +/* initializes deltas for fast access to neighbour pixels */ +#define INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)); + + +/* code of this node was heavily inspired by the smooth function of opencv library. +The main change is an optional image input */ +static void node_composit_exec_bilateralblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + NodeBilateralBlurData *nbbd= node->storage; + CompBuf *new, *source, *img= in[0]->data , *refimg= in[1]->data; + double mean0, w, i2sigma_color, i2sigma_space; + double mean1[4]; + double weight_tab[8]; + float *src, *dest, *ref, *temp_color, *ref_color; + float sigma_color, sigma_space; + int imgx, imgy, x, y, pix, i, step; + int deltas[8]; + short found_determinator= 0; + + if(img == NULL || out[0]->hasoutput == 0) + return; + + if(img->type != CB_RGBA) { + img= typecheck_compbuf(in[0]->data, CB_RGBA); + } + + imgx= img->x; + imgy= img->y; + pix= img->type; + step= pix * imgx; + + if(refimg) { + refimg= img; + if(refimg->x == imgx && refimg->y == imgy) { + if(refimg->type == CB_VEC2 || refimg->type == CB_VEC3) { + refimg= typecheck_compbuf(in[1]->data, CB_RGBA); + found_determinator= 1; + } + } + } + else { + refimg= img; + } + + /* allocs */ + source= dupalloc_compbuf(img); + new= alloc_compbuf(imgx, imgy, pix, 1); + + /* accept image offsets from other nodes */ + new->xof= img->xof; + new->yof= img->yof; + + /* bilateral code properties */ + sigma_color= nbbd->sigma_color; + sigma_space= nbbd->sigma_space; + + i2sigma_color= 1. / (sigma_color * sigma_color); + i2sigma_space= 1. / (sigma_space * sigma_space); + + INIT_3X3_DELTAS(deltas, step, pix); + + weight_tab[0] = weight_tab[2] = weight_tab[4] = weight_tab[6] = i2sigma_space; + weight_tab[1] = weight_tab[3] = weight_tab[5] = weight_tab[7] = i2sigma_space * 2; + + /* iterations */ + for(i= 0; i < nbbd->iter; i++) { + src= source->rect; + ref= refimg->rect; + dest= new->rect; + /*goes through image, there are more loops for 1st/last line and all other lines*/ + /*kernel element accumulates surrounding colors, which are then written with the update_output function*/ + for(x= 0; x < imgx; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(6); + + if(x > 0) { + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(4); + } + + if(x < imgx - 1) { + KERNEL_ELEMENT_C3(7); + KERNEL_ELEMENT_C3(0); + } + + UPDATE_OUTPUT_C3; + } + + dest+= step; + + for(y= 1; y < imgy - 1; y++, dest+= step, src+= pix, ref+= pix) { + x= 0; + + INIT_C3; + + KERNEL_ELEMENT_C3(0); + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(6); + KERNEL_ELEMENT_C3(7); + + UPDATE_OUTPUT_C3; + + src+= pix; + ref+= pix; + + for(x= 1; x < imgx - 1; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(0); + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(6); + KERNEL_ELEMENT_C3(7); + + UPDATE_OUTPUT_C3; + } + + INIT_C3; + + KERNEL_ELEMENT_C3(2); + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + KERNEL_ELEMENT_C3(5); + KERNEL_ELEMENT_C3(6); + + UPDATE_OUTPUT_C3; + } + + for(x= 0; x < imgx; x++, src+= pix, ref+= pix) { + INIT_C3; + + KERNEL_ELEMENT_C3(2); + + if(x > 0) { + KERNEL_ELEMENT_C3(3); + KERNEL_ELEMENT_C3(4); + } + if(x < imgx - 1) { + KERNEL_ELEMENT_C3(1); + KERNEL_ELEMENT_C3(0); + } + + UPDATE_OUTPUT_C3; + } + + if(node->exec & NODE_BREAK) break; + + SWAP(CompBuf, *source, *new); + } + + if(node->exec & NODE_BREAK) + free_compbuf(source); + + if(img != in[0]->data) + free_compbuf(img); + + if(found_determinator == 1) { + if(refimg != in[1]->data) + free_compbuf(refimg); + } + + out[0]->data= source; + + free_compbuf(new); +} + +static void node_composit_init_bilateralblur(bNode* node) +{ + NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); + node->storage= nbbd; + nbbd->sigma_color= 0.3; + nbbd->sigma_space= 5.0; +} + +bNodeType cmp_node_bilateralblur= { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_BILATERALBLUR, + /* name */ "Bilateral Blur", + /* width+range */ 150, 120, 200, + /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS, + /* input sock */ cmp_node_bilateralblur_in, + /* output sock */ cmp_node_bilateralblur_out, + /* storage */ "NodeBilateralBlurData", + /* execfunc */ node_composit_exec_bilateralblur, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_bilateralblur, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL + +}; -- cgit v1.2.3 From 011e0a93dde724650a6ec6315110c4d6bc615913 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Mon, 7 Jan 2008 13:55:48 +0000 Subject: Black and White level inputs to RGB Curves compositing node This commit adds possibility to define black and white level of the mapping curve of the RGB Curves node. This functionality is exactly the same found in the Curves tool of the UV/Image Editor. It can be used to extract wanted color ranges out of the input easily. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Björn C. Schaefer for contribution! --- source/blender/nodes/intern/CMP_nodes/CMP_curves.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c index 17d9821a5ef..01af0e1db1d 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Björn C. Schaefer * * ***** END GPL LICENSE BLOCK ***** */ @@ -123,6 +123,8 @@ bNodeType cmp_node_curve_vec= { static bNodeSocketType cmp_node_curve_rgb_in[]= { { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f}, { -1, 0, "" } }; @@ -157,7 +159,7 @@ static void do_curves_fac(bNode *node, float *out, float *in, float *fac) static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* stack order input: fac, image */ + /* stack order input: fac, image, black level, white level */ /* stack order output: image */ if(out[0]->hasoutput==0) @@ -172,6 +174,8 @@ static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **i CompBuf *cbuf= in[1]->data; CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */ + curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec); + if(in[0]->vec[0] == 1.0) composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA); else -- cgit v1.2.3 From adc68be1a87781112667005455e13f4f1514a7f2 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Mon, 7 Jan 2008 15:44:45 +0000 Subject: Blur Node to support Relative (percent) values This commit makes it possible to use relative values when using a Blur node. There is a new toggle in the node that can be used to enable the feature. Thanks to David Millan Escriva for contribution! --- source/blender/nodes/intern/CMP_nodes/CMP_blur.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c index 8ef4af4d219..3d6b3dd2955 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c @@ -22,7 +22,8 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva, + * Juho Vepsäläinen * * ***** END GPL LICENSE BLOCK ***** */ @@ -556,16 +557,20 @@ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { CompBuf *new, *img= in[0]->data; + NodeBlurData *nbd= node->storage; - if(img==NULL || out[0]->hasoutput==0) - return; + if(img==NULL) return; + + /* store image in size that is needed for absolute/relative conversions on ui level */ + nbd->image_in_width= img->x; + nbd->image_in_height= img->y; + + if(out[0]->hasoutput==0) return; if (((NodeBlurData *)node->storage)->filtertype == R_FILTER_FAST_GAUSS) { CompBuf *new, *img = in[0]->data; /*from eeshlo's original patch, removed to fit in with the existing blur node */ /*const float sx = in[1]->vec[0], sy = in[2]->vec[0];*/ - - NodeBlurData *nbd= node->storage; const float sx = ((float)nbd->sizex)/2.0f, sy = ((float)nbd->sizey)/2.0f; int c; -- cgit v1.2.3 From c8841a7f2f0e885335295b3cda34097e117d0edb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 19 Jan 2008 11:17:12 +0000 Subject: Added new render pass: "Mist". This is actually just the alpha value as currently being calculated by the mist code. It is in many cases not very useful to have this as alpha in shading result, also for postprocess and composite. Note: this pass also works with "Mist" not set in World, of course. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 20308e968d3..0984aa4bfe1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -48,6 +48,7 @@ static bNodeSocketType cmp_node_rlayers_out[]= { { SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 0, "Radio", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_VALUE, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { -1, 0, "" } }; @@ -149,6 +150,8 @@ void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, I out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO); if(out[RRES_OUT_INDEXOB]->hasoutput) out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB); + if(out[RRES_OUT_MIST]->hasoutput) + out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST); }; @@ -236,7 +239,7 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in CompBuf *buf; int buftype= CB_VEC3; - if(ELEM(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB)) + if(ELEM3(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST)) buftype= CB_VAL; else if(passcode==SCE_PASS_VECTOR) buftype= CB_VEC4; @@ -282,7 +285,9 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out if(out[RRES_OUT_RADIO]->hasoutput) out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO); if(out[RRES_OUT_INDEXOB]->hasoutput) - out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB); + out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB); + if(out[RRES_OUT_MIST]->hasoutput) + out[RRES_OUT_MIST]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_MIST); }; -- cgit v1.2.3 From d11cd3108b25ef0e205259539359da8759ef2819 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 22 Jan 2008 06:27:27 +0000 Subject: * Fix for bilateral blur node The 'Determinator' input didn't work at all - there was some quite weird code in there. I think the patch review process could have been quite a bit better on this one. --- source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c index 81592becf4b..b954e876ea1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c @@ -107,9 +107,8 @@ static void node_composit_exec_bilateralblur(void *data, bNode *node, bNodeStack step= pix * imgx; if(refimg) { - refimg= img; if(refimg->x == imgx && refimg->y == imgy) { - if(refimg->type == CB_VEC2 || refimg->type == CB_VEC3) { + if(ELEM3(refimg->type, CB_VAL, CB_VEC2, CB_VEC3)) { refimg= typecheck_compbuf(in[1]->data, CB_RGBA); found_determinator= 1; } -- cgit v1.2.3 From 703f248ab4bd918ba6a202a20b73dc6293851759 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 28 Jan 2008 16:33:59 +0000 Subject: New rendering option: FSA! This completes the pipeline make-over, as started in 2006. With this option, during rendering, each sample for every layer and pass is being saved on disk (looks like non-antialiased images). Then the composite and color correction happens, then a clip to 0-1 range, and only in end all samples get combined - using sampling filters such as gauss/mitch/catmul. This results in artefact-free antialiased images. Even Z-combine or ID masks now work perfect for it! This is an unfinished commit btw; Brecht will finish this for strands. Also Halo doesnt work yet. To activate FSA: press "Save Buffers" and the new button next to it. :) --- .../blender/nodes/intern/CMP_nodes/CMP_defocus.c | 6 ++++-- source/blender/nodes/intern/CMP_nodes/CMP_idMask.c | 22 +++++++++++++++++++++- .../blender/nodes/intern/CMP_nodes/CMP_zcombine.c | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c index 53d01ab1d12..a7db8c2d53d 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c @@ -376,8 +376,10 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, // some sort of visual feedback would be nice, or at least this text in the renderwin header // but for now just print some info in the console every 8 scanlines. if (((y & 7)==0) || (y==(img->y-1))) { - printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y); - fflush(stdout); + if(G.background==0) { + printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y); + fflush(stdout); + } } // esc set by main calling process if(node->exec & NODE_BREAK) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c b/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c index abb9fa98d97..a40579ac3b2 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c @@ -63,8 +63,25 @@ static void do_idmask(CompBuf *stackbuf, CompBuf *cbuf, float idnr) MEM_freeN(abuf); } +/* full sample version */ +static void do_idmask_fsa(CompBuf *stackbuf, CompBuf *cbuf, float idnr) +{ + float *rect, *rs; + int x; + + rect= cbuf->rect; + rs= stackbuf->rect; + for(x= cbuf->x*cbuf->y - 1; x>=0; x--) + if(rect[x]==idnr) + rs[x]= 1.0f; + +} + + static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + RenderData *rd= data; + if(out[0]->hasoutput==0) return; @@ -77,7 +94,10 @@ static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in, stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */; - do_idmask(stackbuf, cbuf, (float)node->custom1); + if(rd->scemode & R_FULL_SAMPLE) + do_idmask_fsa(stackbuf, cbuf, (float)node->custom1); + else + do_idmask(stackbuf, cbuf, (float)node->custom1); out[0]->data= stackbuf; } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c index 29cf8f34d54..eb939100644 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c @@ -45,6 +45,16 @@ static bNodeSocketType cmp_node_zcombine_out[]= { { -1, 0, "" } }; +static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2) +{ + if(*z1 <= *z2) { + QUATCOPY(out, src1); + } + else { + QUATCOPY(out, src2); + } +} + static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2) { if(*z1 > *z2) { @@ -67,6 +77,8 @@ static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, f static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + RenderData *rd= data; + /* stack order in: col z col z */ /* stack order out: col z */ if(out[0]->hasoutput==0) @@ -76,6 +88,16 @@ static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in if(in[0]->data==NULL) { return; } + else if(rd->scemode & R_FULL_SAMPLE) { + /* make output size of first input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, + in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); + + out[0]->data= stackbuf; + } else { /* make output size of first input image */ CompBuf *cbuf= in[0]->data; -- cgit v1.2.3 From b018f64a50f70f8f1ff5a2dd5d44d2d3d3c5eae0 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 4 Feb 2008 18:37:40 +0000 Subject: AlphaOver node feature: "Premul" slider allows to mix between the using alpha as premul or nonpremul. Quite useful for brightness tweaks. Todo: version-patch this so ConvertPremul button goes away Todo: make entire compositer accept non-premul by default... or both --- .../blender/nodes/intern/CMP_nodes/CMP_alphaOver.c | 50 +++++++++++++++++----- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c index f108098750c..8e8eb07c1cc 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c @@ -47,16 +47,16 @@ static void do_alphaover_premul(bNode *node, float *out, float *src, float *over if(over[3]<=0.0f) { QUATCOPY(out, src); } - else if(*fac==1.0f && over[3]>=1.0f) { + else if(fac[0]==1.0f && over[3]>=1.0f) { QUATCOPY(out, over); } else { - float mul= 1.0f - *fac*over[3]; + float mul= 1.0f - fac[0]*over[3]; - out[0]= (mul*src[0]) + *fac*over[0]; - out[1]= (mul*src[1]) + *fac*over[1]; - out[2]= (mul*src[2]) + *fac*over[2]; - out[3]= (mul*src[3]) + *fac*over[3]; + out[0]= (mul*src[0]) + fac[0]*over[0]; + out[1]= (mul*src[1]) + fac[0]*over[1]; + out[2]= (mul*src[2]) + fac[0]*over[2]; + out[3]= (mul*src[3]) + fac[0]*over[3]; } } @@ -67,7 +67,7 @@ static void do_alphaover_key(bNode *node, float *out, float *src, float *over, f if(over[3]<=0.0f) { QUATCOPY(out, src); } - else if(*fac==1.0f && over[3]>=1.0f) { + else if(fac[0]==1.0f && over[3]>=1.0f) { QUATCOPY(out, over); } else { @@ -81,6 +81,31 @@ static void do_alphaover_key(bNode *node, float *out, float *src, float *over, f } } +/* result will be still premul, but the over part is premulled */ +static void do_alphaover_mixed(bNode *node, float *out, float *src, float *over, float *fac) +{ + + if(over[3]<=0.0f) { + QUATCOPY(out, src); + } + else if(fac[0]==1.0f && over[3]>=1.0f) { + QUATCOPY(out, over); + } + else { + NodeTwoFloats *ntf= node->storage; + float addfac= 1.0f - ntf->x + over[3]*ntf->x; + float premul= fac[0]*addfac; + float mul= 1.0f - fac[0]*over[3]; + + out[0]= (mul*src[0]) + premul*over[0]; + out[1]= (mul*src[1]) + premul*over[1]; + out[2]= (mul*src[2]) + premul*over[2]; + out[3]= (mul*src[3]) + fac[0]*over[3]; + } +} + + + static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { @@ -97,8 +122,11 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i /* make output size of input image */ CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data; CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */ + NodeTwoFloats *ntf= node->storage; - if(node->custom1) + if(ntf->x != 0.0f) + composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_mixed, CB_RGBA, CB_RGBA, CB_VAL); + else if(node->custom1) composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL); else composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL); @@ -115,12 +143,12 @@ bNodeType cmp_node_alphaover= { /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS, /* input sock */ cmp_node_alphaover_in, /* output sock */ cmp_node_alphaover_out, - /* storage */ "", + /* storage */ "NodeTwoFloats", /* execfunc */ node_composit_exec_alphaover, /* butfunc */ NULL, /* initfunc */ NULL, - /* freestoragefunc */ NULL, - /* copystoragefunc */ NULL, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, /* id */ NULL }; -- cgit v1.2.3 From f11ea1eb8e51e9d2d236a4efb34e55b564eec7ba Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 4 Feb 2008 21:17:15 +0000 Subject: Bugfix for recent alphaover premul commit, crashed existing files and on adding a new node, maybe the commit was incomplete? --- source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c index 8e8eb07c1cc..4972ff4ae5a 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c @@ -135,6 +135,11 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i } } +static void node_alphaover_init(bNode* node) +{ + node->storage= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats"); +} + bNodeType cmp_node_alphaover= { /* *next,*prev */ NULL, NULL, /* type code */ CMP_NODE_ALPHAOVER, @@ -146,7 +151,7 @@ bNodeType cmp_node_alphaover= { /* storage */ "NodeTwoFloats", /* execfunc */ node_composit_exec_alphaover, /* butfunc */ NULL, - /* initfunc */ NULL, + /* initfunc */ node_alphaover_init, /* freestoragefunc */ node_free_standard_storage, /* copystoragefunc */ node_copy_standard_storage, /* id */ NULL -- cgit v1.2.3 From 16514e3ddb8500242931650c93f1397147442eba Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 9 Feb 2008 23:17:15 +0000 Subject: * Merge of PyNodes to trunk. Finally! See http://wiki.blender.org/index.php/BlenderDev/PyNodes and http://wiki.blender.org/index.php/BlenderDev/PyNodes/API For current documentation. Very very big thanks go to William Germano for fixing the memory issues left and for improving on the code. In the coming time documentation will be finalised and further stabilising of PyNodes is to be expected. --- source/blender/nodes/SConscript | 4 +- source/blender/nodes/SHD_node.h | 2 +- .../blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 645 ++++++++++++++++----- 3 files changed, 516 insertions(+), 135 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 0460848b4a5..cc7cde6fc26 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -13,7 +13,7 @@ incs += ' ../blenloader ../quicktime' incs += ' ../blenkernel ../renderconverter ' - +incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] incs += ' ' + env['BF_SDL_INC'] @@ -41,6 +41,6 @@ if env['WITH_BF_QUICKTIME'] == 1: defs += ' WITH_QUICKTIME' incs += ' ' + env['BF_QUICKTIME_INC'] -defs += ' WITH_CCGSUBSURF' +defs += ' WITH_CCGSUBSURF USE_PYNODES ' env.BlenderLib ( libname = 'nodes', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core','player'], priority = [65, 20] ) diff --git a/source/blender/nodes/SHD_node.h b/source/blender/nodes/SHD_node.h index 8064a543ca0..d75d7c9f568 100644 --- a/source/blender/nodes/SHD_node.h +++ b/source/blender/nodes/SHD_node.h @@ -56,13 +56,13 @@ extern bNodeType sh_node_curve_rgb; extern bNodeType sh_node_math; extern bNodeType sh_node_vect_math; extern bNodeType sh_node_squeeze; +extern bNodeType node_dynamic_typeinfo; extern bNodeType sh_node_material_ext; extern bNodeType sh_node_invert; extern bNodeType sh_node_seprgb; extern bNodeType sh_node_combrgb; extern bNodeType sh_node_hue_sat; - #endif diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 1ba777a0533..c198e73a3bf 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -34,6 +34,7 @@ #include "DNA_text_types.h" #include "BKE_text.h" +#include "BKE_utildefines.h" #include "api2_2x/Node.h" #include "api2_2x/gen_utils.h" @@ -41,6 +42,9 @@ #include "../SHD_util.h" +static void node_dynamic_setup(bNode *node); +static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out); + static PyObject *init_dynamicdict(void) { PyObject *newscriptdict= PyDict_New(); PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins()); @@ -48,198 +52,575 @@ static PyObject *init_dynamicdict(void) { return newscriptdict; } +/* unused for now static void free_dynamicdict(PyObject *dict) { - if(dict!=NULL) { + if (dict!=NULL) { Py_DECREF(dict); } } +*/ -static void node_dynamic_init(bNode *node) { - NodeScriptDict *nsd= MEM_callocN(sizeof(NodeScriptDict), "node script dictionary"); - int type= node->custom2; - node->custom2= 0; - node->storage= nsd; - if(type>=NODE_DYNAMIC_MENU) { - if(type==NODE_DYNAMIC_MENU) { - nodeMakeDynamicType(node); - node->custom1= SH_NODE_DYNAMIC_NEW; - } else { - node->custom1= SH_NODE_DYNAMIC_ADDEXIST; +static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id) +{ + bNodeType *ntype = list->first; + + while(ntype) { + if (ntype->type == NODE_DYNAMIC && ntype->id == id) + break; + ntype = ntype->next; + } + + return ntype; /* NULL if doesn't exist */ +} + +static void node_dynamic_free_typeinfo_sockets(bNodeType *tinfo) +{ + bNodeSocketType *sock; + + if (!tinfo) return; + + if (tinfo->inputs) { + sock = tinfo->inputs; + while (sock->type != -1) { + MEM_freeN(sock->name); + sock++; + } + MEM_freeN(tinfo->inputs); + tinfo->inputs = NULL; + } + if (tinfo->outputs) { + sock = tinfo->outputs; + while (sock->type != -1) { + MEM_freeN(sock->name); + sock++; + } + MEM_freeN(tinfo->outputs); + tinfo->outputs = NULL; + } +} + +static void node_dynamic_free_typeinfo(bNodeType *tinfo) +{ + if (!tinfo) return; + + node_dynamic_free_typeinfo_sockets(tinfo); + + if (tinfo->name) { MEM_freeN(tinfo->name); } + + MEM_freeN(tinfo); +} + +static void node_dynamic_free_sockets(bNode *node) +{ + BLI_freelistN(&node->inputs); + BLI_freelistN(&node->outputs); +} + +/* For now we just remove the socket links. It's the safest + * route, since an update in the script may change completely the + * inputs and outputs. Trying to recreate the node links would be + * nicer for pynode authors, though. */ +static void node_dynamic_update_socket_links(bNode *node, bNodeTree *ntree) +{ + if (ntree) { + nodeVerifyType(ntree, node); + } + else { + Material *ma; + + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd; + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if (nd == node) nodeVerifyType(ma->nodetree, node); + } + } } - node->id= node->typeinfo->id; - nodeDynamicParse(node); - } else { - if(node->custom1== SH_NODE_DYNAMIC_LOADED) { - nodeMakeDynamicType(node); - nodeDynamicParse(node); - } else if(node->custom1== SH_NODE_DYNAMIC_ADDEXIST) - nodeDynamicParse(node); } } -static void node_dynamic_free(bNode *node) +static void node_dynamic_free_storage_cb(bNode *node) { - NodeScriptDict *nsd= (NodeScriptDict *)(node->storage); - BPy_Node *pynode= nsd->node; - Py_XDECREF(pynode); - free_dynamicdict((PyObject *)(nsd->dict)); + NodeScriptDict *nsd; + PyObject *pydict; + BPy_Node *pynode; + + if (!node->storage) return; + + nsd = (NodeScriptDict *)(node->storage); + pydict = nsd->dict; + if (pydict) { + Py_DECREF(pydict); + } + pynode = nsd->node; + if (pynode) { + Py_DECREF(pynode); + } MEM_freeN(node->storage); + node->storage = NULL; } -static void node_dynamic_copy(bNode *orig_node, bNode *new_node) +/* Disable pynode when its script fails */ +static void node_dynamic_disable(bNode *node) { - NodeScriptDict *nsd= (NodeScriptDict *)(orig_node->storage); - new_node->storage= MEM_dupallocN(orig_node->storage); - if(nsd->node) - Py_INCREF((PyObject *)(nsd->node)); - if(nsd->dict) - Py_INCREF((PyObject *)(nsd->dict)); + node->custom1 = 0; + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR); } -static void node_dynamic_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - BPy_Node *mynode = NULL; - NodeScriptDict *nsd = NULL; - PyObject *pyresult = NULL; - PyObject *args = NULL; - ShadeInput *shi= ((ShaderCallData *)data)->shi; +/* Disable all pynodes using the given text (script) id */ +static void node_dynamic_disable_all_by_id(ID *id) +{ + Material *ma; /* XXX hardcoded for shaders */ - if(node->custom1==SH_NODE_DYNAMIC_NEW) { - nodeDynamicParse(node); - return; + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd; + bNodeTree *ntree = ma->nodetree; + for (nd= ntree->nodes.first; nd; nd= nd->next) { + if (nd->id == id) { + nd->custom1 = 0; + nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_ERROR); + } + } + } } +} - if(node->custom2<0) - return; +static void node_rem_socklist_links(bNodeTree *ntree, ListBase *lb) +{ + bNodeLink *link, *next; + bNodeSocket *sock; - if(node->custom1==SH_NODE_DYNAMIC_READY || node->custom1==SH_NODE_DYNAMIC_UPDATED) { - if(node->custom1== SH_NODE_DYNAMIC_UPDATED) - node->custom1= SH_NODE_DYNAMIC_READY; + if (!lb) return; - nsd = (NodeScriptDict *)node->storage; + for (sock= lb->first; sock; sock= sock->next) { + for (link= ntree->links.first; link; link= next) { + next= link->next; + if (link->fromsock==sock || link->tosock==sock) { + nodeRemLink(ntree, link); + } + } + } +} - mynode = (BPy_Node *)(nsd->node); - if(mynode && PyCallable_Check((PyObject *)mynode)) { - mynode->node= node; - Node_SetStack(mynode, in, NODE_INPUTSTACK); - Node_SetStack(mynode, out, NODE_OUTPUTSTACK); - Node_SetShi(mynode, shi); - args=Py_BuildValue("()"); - pyresult= PyObject_Call((PyObject *)mynode, args, NULL); - if(!pyresult) { - if(PyErr_Occurred()) { - PyErr_Print(); - node->custom2= -1; - } else { - printf("PyObject_Call __call__ failed\n"); +/* XXX hardcoded for shaders */ +static void node_dynamic_rem_all_links(bNodeType *tinfo) +{ + Material *ma; + int in, out; + + in = tinfo->inputs ? 1 : 0; + out = tinfo->outputs ? 1 : 0; + + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd; + bNodeTree *ntree = ma->nodetree; + for (nd= ntree->nodes.first; nd; nd= nd->next) { + if (nd->typeinfo == tinfo) { + if (in) + node_rem_socklist_links(ntree, &nd->inputs); + if (out) + node_rem_socklist_links(ntree, &nd->outputs); + } + } + } + } +} + +/* node_dynamic_reset: clean a pynode, getting rid of all + * data dynamically created for it. + * ntree is used only in a special case: for working pynodes + * that were saved on a .blend but fail for some reason when + * the file is opened. We need it because pynodes are initialized + * before G.main. */ +static void node_dynamic_reset(bNode *node, bNodeTree *ntree) +{ + bNodeType *tinfo, *tinfo_default; + Material *ma; + + tinfo = node->typeinfo; + tinfo_default = node_dynamic_find_typeinfo(&node_all_shaders, NULL); + + node_dynamic_rem_all_links(tinfo); + node_dynamic_free_typeinfo_sockets(tinfo); + + if (!ntree) { node_dynamic_free_sockets(node); } + + //wnode_dynamic_update_socket_links(node, ntree); + node_dynamic_free_storage_cb(node); + + /* XXX hardcoded for shaders: */ + if (node->typeinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } + + node->typeinfo = tinfo_default; + + /* reset all other XXX shader nodes sharing this typeinfo */ + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd; + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if (nd->typeinfo == tinfo) { + node_dynamic_free_storage_cb(nd); + node_dynamic_free_sockets(nd); + nd->typeinfo = tinfo_default; } } - Py_XDECREF(pyresult); - Py_DECREF(args); } } + + node_dynamic_free_typeinfo(tinfo); } -void nodeDynamicParse(struct bNode *node) +int nodeDynamicUnlinkText(ID *txtid) { + Material *ma; + int unlinked= 0; + + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd, *nd2 = NULL; + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if ((nd->type == NODE_DYNAMIC) && (nd->id == txtid)) { + nd->id = NULL; + nd->custom1 = 0; + nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); + BLI_strncpy(nd->name, "Dynamic", 8); + nd2 = nd; /* so we have a ptr to one of them */ + unlinked++; + } + } + /* clean uneeded dynamic data from all nodes that shared + * this text: */ + if (nd2) node_dynamic_reset(nd2, NULL); + } + } + + return unlinked; +} + +static void node_dynamic_pyerror_print(bNode *node) +{ + fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name); + if (PyErr_Occurred()) { PyErr_Print(); } + else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); } +} + +static int node_dynamic_parse(struct bNode *node) { - BPy_Node *pynode= NULL; PyObject *dict= NULL; PyObject *key= NULL; PyObject *value= NULL; - PyObject *testinst= NULL; + PyObject *pynode= NULL; PyObject *args= NULL; - int pos = 0; - NodeScriptDict *nsd= NULL; + NodeScriptDict *nsd = NULL; PyObject *pyresult = NULL; - PyObject *pycompiled = NULL; - Text *txt = NULL; - char *buf= NULL; + char *buf = NULL; + int pos = 0, is_valid_script = 0; + + if (!node->id || !node->storage) + return 0; - if(! node->id) { + /* READY, no need to be here */ + if (BTST(node->custom1, NODE_DYNAMIC_READY)) + return 0; + + nsd = (NodeScriptDict *)node->storage; + + dict = (PyObject *)(nsd->dict); + buf = txt_to_buf((Text *)node->id); + + pyresult = PyRun_String(buf, Py_file_input, dict, dict); + + MEM_freeN(buf); + + if (!pyresult) { + node_dynamic_disable(node); + node_dynamic_pyerror_print(node); + return -1; + } + + Py_DECREF(pyresult); + + while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) { + /* look for the node object */ + if (PyObject_TypeCheck(value, &PyType_Type)==1) { + BPy_NodeSockets *sockets = Node_CreateSockets(node); + + args = Py_BuildValue("(O)", sockets); + + /* init it to get the input and output sockets */ + pynode = PyObject_Call(value, args, NULL); + + Py_DECREF(sockets); + Py_DECREF(args); + + if (!PyErr_Occurred() && pynode && PyObject_TypeCheck(pynode, &Node_Type)==1) { + InitNode((BPy_Node *)(pynode), node); + nsd->node = pynode; + node->typeinfo->execfunc = node_dynamic_exec_cb; + is_valid_script = 1; + + /* for NEW, LOADED, REPARSE */ + if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) { + node->typeinfo->pydict = dict; + node->typeinfo->pynode = pynode; + node->typeinfo->id = node->id; + nodeAddSockets(node, node->typeinfo); + if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) { + nodeRegisterType(&node_all_shaders, node->typeinfo); + /* nodeRegisterType copied it to a new one, so we + * free the typeinfo itself, but not what it + * points to: */ + MEM_freeN(node->typeinfo); + node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id); + MEM_freeN(node->typeinfo->name); + node->typeinfo->name = BLI_strdup(node->name); + } + } + + node->custom1 = 0; + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); + break; + } + break; + } + } + + if (!is_valid_script) { /* not a valid pynode script */ + node_dynamic_disable(node); + node_dynamic_pyerror_print(node); + return -1; + } + + return 0; +} + +/* node_dynamic_setup: prepare for execution (state: NODE_DYNAMIC_READY) + * pynodes already linked to a script (node->id != NULL). */ +static void node_dynamic_setup(bNode *node) +{ + NodeScriptDict *nsd = NULL; + bNodeTree *nodetree = NULL; + bNodeType *ntype = NULL; + + /* Possible cases: + * NEW + * ADDEXIST + * LOADED + * REPARSE + * ERROR + * READY + */ + + /* NEW, but not linked to a script: link default (empty) typeinfo */ + if (!node->id) { + node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, + NULL); return; } - if(node->custom1!=SH_NODE_DYNAMIC_READY) { - txt = (Text *)node->id; - nsd = (NodeScriptDict *)node->storage; + /* READY, no need to be here */ + if (BTST(node->custom1, NODE_DYNAMIC_READY)) + return; - if(nsd->dict==NULL && (node->custom1==SH_NODE_DYNAMIC_NEW||node->custom1==SH_NODE_DYNAMIC_LOADED)) { - nsd->dict= init_dynamicdict(); - } else if(nsd->dict==NULL && node->custom1==SH_NODE_DYNAMIC_ADDEXIST) { - nsd->dict= node->typeinfo->pydict; - nsd->node= node->typeinfo->pynode; - Py_INCREF((PyObject *)(nsd->dict)); - Py_INCREF((PyObject *)(nsd->node)); - node->custom1= SH_NODE_DYNAMIC_READY; + /* ERROR, reset to (empty) defaults */ + if (BCLR(node->custom1, NODE_DYNAMIC_ERROR) == 0) { + node_dynamic_reset(node, NULL); + return; + } + + /* User asked to update this pynode, prepare it for reparsing */ + if (BTST(node->custom1, NODE_DYNAMIC_REPARSE)) { + int needs_parsing = 1; + + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW); + + if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { + node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_REPARSE); + ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id); + + if (ntype) { + node->typeinfo = ntype; + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); + node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR); + needs_parsing = 0; + } + else { nodeMakeDynamicType(node); } + + } else { + node_dynamic_free_typeinfo_sockets(node->typeinfo); + node_dynamic_update_socket_links(node, NULL); + node_dynamic_free_storage_cb(node); + } + + if (needs_parsing) { + nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary"); + nsd->dict = init_dynamicdict(); + node->storage = nsd; + /* prepared, now reparse: */ + node_dynamic_parse(node); return; } - dict= (PyObject *)(nsd->dict); + } + else if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) { + /* when loading from a .blend we don't have G.main yet, so we + * quickly abuse node->storage in ntreeInitTypes (node.c) to have + * our nodetree ptr (needed if a pynode script that worked before + * saving the .blend for some reason fails upon loading): */ + nodetree = (bNodeTree *)node->storage; + node->storage = NULL; + } - if(node->custom1!=SH_NODE_DYNAMIC_ADDEXIST) { - buf = txt_to_buf( txt ); - /*printf("Running script (%s, %d)...", node->name, node->custom1);*/ - pyresult = PyRun_String(buf, Py_file_input, dict, dict); - /*printf(" done\n");*/ + if (node->storage) + fprintf(stderr, "\nDEBUG: PYNODES ERROR: non NULL node->storage in node_dynamic_setup()\n"); - MEM_freeN(buf); + nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary"); + node->storage = nsd; + + /* NEW, LOADED or REPARSE */ + if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) { + /* check if there's already a bNodeType linked to this script */ + /* (XXX hardcoded for shader nodes for now) */ + ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id); - if(!pyresult) { - if(PyErr_Occurred()) { - PyErr_Print(); - } - Py_XDECREF(pyresult); - return; + if (ntype) { /* if so, reuse it */ + node->typeinfo = ntype; + /* so this is actually an ADDEXIST type */ + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); + } + else { /* create bNodeType for this pynode */ + nodeMakeDynamicType(node); + nsd->dict = init_dynamicdict(); + if ((node_dynamic_parse(node) == -1) && nodetree) { + node_dynamic_reset(node, nodetree); } + return; + } + } - Py_DECREF(pyresult); + /* ADDEXIST: new pynode linked to an already registered dynamic type, + * we just reuse existing py dict and pynode */ + nsd->dict = node->typeinfo->pydict; + nsd->node = node->typeinfo->pynode; + Py_INCREF((PyObject *)(nsd->dict)); + Py_INCREF((PyObject *)(nsd->node)); - while(PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value) ) { - if(PyObject_TypeCheck(value, &PyType_Type)==1) { - BPy_DefinitionMap *outputdef= Node_CreateOutputDefMap(node); - BPy_DefinitionMap *inputdef= Node_CreateInputDefMap(node); - - args= Py_BuildValue("(OO)", inputdef, outputdef); - testinst= PyObject_Call(value, args, NULL); - - Py_DECREF(outputdef); - Py_DECREF(inputdef); - if(testinst && PyObject_TypeCheck(testinst, &Node_Type)==1) { - Py_INCREF(testinst); - Py_INCREF(dict); - InitNode((BPy_Node *)(testinst), node); - nsd->node= testinst; - node->typeinfo->execfunc= node_dynamic_exec; - if(node->custom1== SH_NODE_DYNAMIC_NEW || node->custom1== SH_NODE_DYNAMIC_LOADED) { - node->typeinfo->pynode= testinst; - node->typeinfo->pydict= nsd->dict; - node->typeinfo->id= node->id; - nodeAddSockets(node, node->typeinfo); - nodeRegisterType(&node_all_shaders, node->typeinfo); - node->custom1= SH_NODE_DYNAMIC_READY; - } - break; - } - Py_DECREF(args); - } - } + if (BTST(node->custom1, NODE_DYNAMIC_NEW)) { + nodeAddSockets(node, node->typeinfo); + node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW); + } + + node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ADDEXIST); + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); + + return; +} + +/* node_dynamic_init_cb callback: called when a pynode is created. + * The pynode type is passed via node->custom2. It can be: + * 0: for loaded empty nodes + * NODE_DYNAMIC_MENU: for the default Dynamic node type + * > NODE_DYNAMIC_MENU: for the new types defined by scripts +*/ +static void node_dynamic_init_cb(bNode *node) { + int type = node->custom2; + + node->custom2 = 0; + + if (type >= NODE_DYNAMIC_MENU) { + node->custom1 = 0; + + if (type == NODE_DYNAMIC_MENU) { + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW); + return; } + + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); + node->id = node->typeinfo->id; } + + node_dynamic_setup(node); } +/* node_dynamic_copy_cb: pynode copy callback */ +static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node) +{ + NodeScriptDict *nsd; + + if (!orig_node->storage) return; + + nsd = (NodeScriptDict *)(orig_node->storage); + new_node->storage = MEM_dupallocN(orig_node->storage); + + if (nsd->node) + Py_INCREF((PyObject *)(nsd->node)); + if (nsd->dict) + Py_INCREF((PyObject *)(nsd->dict)); +} + +/* node_dynamic_exec_cb: the execution callback called per pixel + * during rendering. */ +static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + BPy_Node *mynode = NULL; + NodeScriptDict *nsd = NULL; + PyObject *pyresult = NULL; + PyObject *args = NULL; + ShadeInput *shi; + + if (!node->id) + return; + + if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_REPARSE)) { + node_dynamic_setup(node); + return; + } + + if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { + if (node->storage) node_dynamic_setup(node); + return; + } + + if (BTST(node->custom1, NODE_DYNAMIC_READY)) { + nsd = (NodeScriptDict *)node->storage; + + mynode = (BPy_Node *)(nsd->node); + if (mynode && PyCallable_Check((PyObject *)mynode)) { + mynode->node = node; + shi = ((ShaderCallData *)data)->shi; + + Node_SetStack(mynode, in, NODE_INPUTSTACK); + Node_SetStack(mynode, out, NODE_OUTPUTSTACK); + Node_SetShi(mynode, shi); + + args=Py_BuildValue("()"); + pyresult= PyObject_Call((PyObject *)mynode, args, NULL); + Py_DECREF(args); + + if (!pyresult) { + node_dynamic_disable_all_by_id(node->id); + node_dynamic_pyerror_print(node); + node_dynamic_setup(node); + return; + } + Py_DECREF(pyresult); + } + } +} -bNodeType sh_node_dynamic = { +bNodeType node_dynamic_typeinfo = { /* next, prev */ NULL, NULL, - /* type code */ SH_NODE_DYNAMIC, + /* type code */ NODE_DYNAMIC, /* name */ "Dynamic", /* width+range */ 150, 60, 300, /* class+opts */ NODE_CLASS_OP_DYNAMIC, NODE_OPTIONS, /* input sock */ NULL, /* output sock */ NULL, /* storage */ "NodeScriptDict", - /* execfunc */ node_dynamic_exec, + /* execfunc */ node_dynamic_exec_cb, /* butfunc */ NULL, - /* initfunc */ node_dynamic_init, - /* freefunc */ node_dynamic_free, - /* copyfunc */ node_dynamic_copy, + /* initfunc */ node_dynamic_init_cb, + /* freefunc */ node_dynamic_free_storage_cb, + /* copyfunc */ node_dynamic_copy_cb, /* id */ NULL }; -- cgit v1.2.3 From f46fcf7aab30fa2c905840e4ad0d4f1486994285 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Sun, 10 Feb 2008 03:40:24 +0000 Subject: == PyNodes == 1) Including the Add->Dynamic submenu in the Nodes window header. Previously pynodes could only be added via toolbox. 2) Disabling pynodes execution when using more than one thread for rendering. This prevents the crashes while a proper fix isn't implemented. --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index c198e73a3bf..9c15877e478 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -570,6 +570,9 @@ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNode if (!node->id) return; + if (G.scene->r.threads > 1) + return; + if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_REPARSE)) { node_dynamic_setup(node); return; -- cgit v1.2.3 From 9d7ef684e3ad699bd8aeb3324cfae2c98871e5e3 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 10 Feb 2008 18:48:29 +0000 Subject: * remove redundant define. --- source/blender/nodes/SConscript | 2 +- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index cc7cde6fc26..8682f626b80 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -41,6 +41,6 @@ if env['WITH_BF_QUICKTIME'] == 1: defs += ' WITH_QUICKTIME' incs += ' ' + env['BF_QUICKTIME_INC'] -defs += ' WITH_CCGSUBSURF USE_PYNODES ' +defs += ' WITH_CCGSUBSURF ' env.BlenderLib ( libname = 'nodes', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core','player'], priority = [65, 20] ) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 9c15877e478..3b9ef5ceb55 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -27,8 +27,6 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifdef USE_PYNODES /* note: won't work without patch */ - #include #include @@ -627,5 +625,3 @@ bNodeType node_dynamic_typeinfo = { /* id */ NULL }; -#endif /* USE_PYNODES */ - -- cgit v1.2.3 From a4e27a689ac197935dcd08d1917fb0f328ba3989 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 10 Feb 2008 20:16:35 +0000 Subject: added PyNode includes for Makefiles --- source/blender/nodes/intern/Makefile | 2 ++ source/blender/nodes/intern/SHD_nodes/Makefile | 2 ++ 2 files changed, 4 insertions(+) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 3b7783c5d1e..71290bf03cd 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -38,6 +38,8 @@ include nan_compile.mk CFLAGS += $(LEVEL_1_C_WARNINGS) +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +CPPFLAGS += -I../../python CPPFLAGS += -I../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../makesdna diff --git a/source/blender/nodes/intern/SHD_nodes/Makefile b/source/blender/nodes/intern/SHD_nodes/Makefile index 0ab6134ac93..04e042cee76 100644 --- a/source/blender/nodes/intern/SHD_nodes/Makefile +++ b/source/blender/nodes/intern/SHD_nodes/Makefile @@ -38,6 +38,8 @@ include nan_compile.mk CFLAGS += $(LEVEL_1_C_WARNINGS) +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +CPPFLAGS += -I../../../python CPPFLAGS += -I../../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../../makesdna -- cgit v1.2.3 From a7702e3d946db1c2f01e116a04710ecf3ba32847 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 10 Feb 2008 20:50:50 +0000 Subject: * make CMake compile again (after pynodes addition). Patch provided by skejoe. --- source/blender/nodes/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 6729d5099f0..eab47eaeb02 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -36,6 +36,7 @@ SET(INC ../blenkernel ${SDL_INC} ${ZLIB_INC} + ${PYTHON_INC} ) IF(WITH_VERSE) -- cgit v1.2.3 From 9615532ccb8290492bf076cdc7ad7a6ecb9d9311 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Sun, 10 Feb 2008 21:12:44 +0000 Subject: == Pynodes == 1) Trying to bring back compatibility with Python2.3. 2) Adding some stubs to compile blender player again on linux. Please tell me if Blender still doesn't compile with py 2.3 or if the player isn't compiling. There was a binreloc related stub I needed to add, so probably the player wasn't compiling before the pynodes commit. Thanks PanzerMKZ for reporting and testing part of the fix to py 2.3. --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 3b9ef5ceb55..4c4044f6bce 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -28,6 +28,7 @@ */ #include +#include #include #include "DNA_text_types.h" @@ -352,7 +353,7 @@ static int node_dynamic_parse(struct bNode *node) Py_DECREF(sockets); Py_DECREF(args); - if (!PyErr_Occurred() && pynode && PyObject_TypeCheck(pynode, &Node_Type)==1) { + if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) { InitNode((BPy_Node *)(pynode), node); nsd->node = pynode; node->typeinfo->execfunc = node_dynamic_exec_cb; -- cgit v1.2.3 From 66e69965b15fa03634fcc741a4ec67e1e865cc83 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 12 Feb 2008 15:34:26 +0000 Subject: Bugfix: when defocus node had nothing to do and just passed on the buffer, it didn't correctly deal with pointers, gave a crash in some circumstances. --- source/blender/nodes/intern/CMP_nodes/CMP_defocus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c index a7db8c2d53d..866bf406d1e 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c @@ -779,9 +779,7 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in, // if image not valid type or fstop==infinite (128), nothing to do, pass in to out if (((img->type!=CB_RGBA) && (img->type!=CB_VAL)) || ((nqd->no_zbuf==0) && (nqd->fstop==128.f))) { - new = alloc_compbuf(img->x, img->y, img->type, 0); - new->rect = img->rect; - out[0]->data = new; + out[0]->data = pass_on_compbuf(img); return; } -- cgit v1.2.3 From df0d81f3c7ae91cad0bc612cdf49753ea661299b Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 12 Feb 2008 18:56:32 +0000 Subject: * fix provided by Stefan Birgmeier (qwequ777): int pos may lead to crashes on 64-bit systems. PyDict_Next takes a Py_ssize_t, not an int (tsk tsk). --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 4c4044f6bce..1d1cf3d7e23 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -314,7 +314,8 @@ static int node_dynamic_parse(struct bNode *node) NodeScriptDict *nsd = NULL; PyObject *pyresult = NULL; char *buf = NULL; - int pos = 0, is_valid_script = 0; + Py_ssize_t pos = 0; + int is_valid_script = 0; if (!node->id || !node->storage) return 0; -- cgit v1.2.3 From e26b5aa9c47fbc604c23efe9100940ff68d8ddbe Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 13 Feb 2008 13:36:35 +0000 Subject: * fix for [#8085] Glare node crashes on inputs with < 4 colour channels I had this assigned to Alfredo for a while, but he hasn't replied to the tracker at all, so I suspect he's not around. I'll commit this now to prevent crashes. Some of the code in the glare node assumed that all buffers will be 4 channel RGBA, when in fact it was possible to give it a VEC3, such as a spec pass with no alpha, which would crash it. This fix just duplicates the input to a new temporary RGBA buffer to work on, if it's not already RGBA. --- source/blender/nodes/intern/CMP_nodes/CMP_glare.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_glare.c b/source/blender/nodes/intern/CMP_nodes/CMP_glare.c index e7b8fd00c93..9ab4038607f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_glare.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_glare.c @@ -424,15 +424,18 @@ static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src) static void node_composit_exec_glare(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - CompBuf *new, *img = in[0]->data; + CompBuf *new, *src, *img = in[0]->data; NodeGlare* ndg = node->storage; if ((img == NULL) || (out[0]->hasoutput == 0)) return; - if (img->type != CB_RGBA) + if (img->type != CB_RGBA) { new = typecheck_compbuf(img, CB_RGBA); - else + src = typecheck_compbuf(img, CB_RGBA); + } else { new = dupalloc_compbuf(img); + src = dupalloc_compbuf(img); + } { int x, y; @@ -448,19 +451,20 @@ static void node_composit_exec_glare(void *data, bNode *node, bNodeStack **in, b switch (ndg->type) { case 0: - star4(ndg, new, img); + star4(ndg, new, src); break; case 1: - fglow(ndg, new, img); + fglow(ndg, new, src); break; case 3: - ghosts(ndg, new, img); + ghosts(ndg, new, src); break; case 2: default: - streaks(ndg, new, img); + streaks(ndg, new, src); } + free_compbuf(src); out[0]->data = new; } -- cgit v1.2.3 From ac5d28a13c6db6837fd1f00cfecd9cef06e8d92a Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 14 Feb 2008 13:36:59 +0000 Subject: Added another 2 checks for if an image has the premul flag set, 1 in the image compositor node, another in render_realtime_texture. Note that multilayer images in the image compositor node do not respect the premul flag (though I did write commented out code for it). As far as I can tell, the premul option never worked for multilayer images in the image node, so I'm a little nervous about making it work properly there. ton, any comments? --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 0984aa4bfe1..659629457f8 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -79,6 +79,21 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i stackbuf->rect= ibuf->rect_float; } + /*code to respect the premul flag of images; I'm + not sure if this is a good idea for multilayer images, + since it never worked before for them. + if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + //premul the image + int i; + float *pixel = stackbuf->rect; + + for (i=0; ix*stackbuf->y; i++, pixel += 4) { + pixel[0] *= pixel[3]; + pixel[1] *= pixel[3]; + pixel[2] *= pixel[3]; + } + } + */ return stackbuf; }; @@ -186,7 +201,25 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b } else { stackbuf= node_composit_get_image(rd, ima, iuser); - + + /*respect image premul option*/ + if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + + /*first duplicate stackbuf->rect, since it's just a pointer + to the source imbuf, and we don't want to change that.*/ + stackbuf->rect = MEM_dupallocN(stackbuf->rect); + + /*premul the image*/ + int i; + float *pixel = stackbuf->rect; + + for (i=0; ix*stackbuf->y; i++, pixel += 4) { + pixel[0] *= pixel[3]; + pixel[1] *= pixel[3]; + pixel[2] *= pixel[3]; + } + } + /* put image on stack */ out[0]->data= stackbuf; -- cgit v1.2.3 From 09cb8a9f422cfa90201340a6735f8d9683f0bb42 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 14 Feb 2008 14:57:41 +0000 Subject: in my tiredness I didn't declare some vars at the top of the block. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 659629457f8..9a2f6fc3df8 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -204,14 +204,14 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b /*respect image premul option*/ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + int i; + float *pixel = stackbuf->rect; /*first duplicate stackbuf->rect, since it's just a pointer to the source imbuf, and we don't want to change that.*/ stackbuf->rect = MEM_dupallocN(stackbuf->rect); /*premul the image*/ - int i; - float *pixel = stackbuf->rect; for (i=0; ix*stackbuf->y; i++, pixel += 4) { pixel[0] *= pixel[3]; -- cgit v1.2.3 From 4b784f4311f724e983de32799e27d03ab199abb4 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 14 Feb 2008 15:14:01 +0000 Subject: stupid me! if you move var declarations sometimes you have to add assignments outside of the var declarations! --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 9a2f6fc3df8..6a82e8a9254 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -205,7 +205,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b /*respect image premul option*/ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { int i; - float *pixel = stackbuf->rect; + float *pixel; /*first duplicate stackbuf->rect, since it's just a pointer to the source imbuf, and we don't want to change that.*/ @@ -213,6 +213,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b /*premul the image*/ + pixel = stackbuf->rect; for (i=0; ix*stackbuf->y; i++, pixel += 4) { pixel[0] *= pixel[3]; pixel[1] *= pixel[3]; -- cgit v1.2.3 From 58046762f839edd132616bcc92610571ee592910 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 14 Feb 2008 18:56:14 +0000 Subject: 1) Revert previous commit, rendering negative won't work that simple... Needs much more attention. 2) Fix for zcombine node: - it skipped execution when no image rgba out was used - didnt work for FSA yet --- .../blender/nodes/intern/CMP_nodes/CMP_zcombine.c | 61 ++++++++++++---------- 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c index eb939100644..daf61609692 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c @@ -52,6 +52,9 @@ static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float * } else { QUATCOPY(out, src2); + + if(node->custom1) + *z1= *z2; } } @@ -78,54 +81,57 @@ static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, f static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { RenderData *rd= data; - + CompBuf *cbuf= in[0]->data; + CompBuf *zbuf; + /* stack order in: col z col z */ /* stack order out: col z */ - if(out[0]->hasoutput==0) + if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; /* no input image; do nothing now */ if(in[0]->data==NULL) { return; } - else if(rd->scemode & R_FULL_SAMPLE) { + + if(out[1]->hasoutput) { + /* copy or make a buffer for for the first z value, here we write result in */ + if(in[1]->data) + zbuf= dupalloc_compbuf(in[1]->data); + else { + float *zval; + int tot= cbuf->x*cbuf->y; + + zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); + for(zval= zbuf->rect; tot; tot--, zval++) + *zval= in[1]->vec[0]; + } + /* lazy coder hack */ + node->custom1= 1; + out[1]->data= zbuf; + } + else { + node->custom1= 0; + zbuf= in[1]->data; + } + + if(rd->scemode & R_FULL_SAMPLE) { /* make output size of first input image */ - CompBuf *cbuf= in[0]->data; CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, + composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, zbuf, in[1]->vec, in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); out[0]->data= stackbuf; } else { /* make output size of first input image */ - CompBuf *cbuf= in[0]->data; CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */ - CompBuf *zbuf, *mbuf; + CompBuf *mbuf; float *fp; int x; char *aabuf; - if(out[1]->hasoutput) { - /* copy or make a buffer for for the first z value, here we write result in */ - if(in[1]->data) - zbuf= dupalloc_compbuf(in[1]->data); - else { - float *zval; - int tot= cbuf->x*cbuf->y; - - zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); - for(zval= zbuf->rect; tot; tot--, zval++) - *zval= in[1]->vec[0]; - } - /* lazy coder hack */ - node->custom1= 1; - } - else { - node->custom1= 0; - zbuf= in[1]->data; - } /* make a mask based on comparison, optionally write zvalue */ mbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); @@ -153,9 +159,8 @@ static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in MEM_freeN(aabuf); out[0]->data= stackbuf; - if(node->custom1) - out[1]->data= zbuf; } + } bNodeType cmp_node_zcombine= { -- cgit v1.2.3 From 0ef89331e2a4a235bc17f82fe52a0e567c0e47c8 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 15 Feb 2008 09:42:25 +0000 Subject: Fix for theoretical memory leak. Oddly this leak didn't seem to be happening, but might as well fix it anyway. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 6a82e8a9254..06c3b90e828 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -211,8 +211,10 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b to the source imbuf, and we don't want to change that.*/ stackbuf->rect = MEM_dupallocN(stackbuf->rect); - /*premul the image*/ + /*flag that we can free the buffer.*/ + stackbuf->malloc = 1; + /*premul the image*/ pixel = stackbuf->rect; for (i=0; ix*stackbuf->y; i++, pixel += 4) { pixel[0] *= pixel[3]; -- cgit v1.2.3 From 331559d5859644d1ef0e7ce04a7aefd73ff47452 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 18 Feb 2008 15:21:59 +0000 Subject: Bugfix for defocus node gamma correct. It applied gamma correct to a premul image but that doesn't work correct. Now it depremuls and premuls again around the gamma correction. Better solution might be possible, but this gives compatible results. --- .../blender/nodes/intern/CMP_nodes/CMP_defocus.c | 8 +++++- source/blender/nodes/intern/CMP_util.c | 30 ++++++++++++++++++++++ source/blender/nodes/intern/CMP_util.h | 1 + 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c index 866bf406d1e..f8be69d8092 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c @@ -798,16 +798,22 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in, // ok, process old = img; if (nqd->gamco) { - // gamma correct, blender func is simplified, fixed value & RGBA only, should make user param + // gamma correct, blender func is simplified, fixed value & RGBA only, + // should make user param. also depremul and premul afterwards, gamma + // correction can't work with premul alpha old = dupalloc_compbuf(img); + premul_compbuf(old, 1); gamma_correct_compbuf(old, 0); + premul_compbuf(old, 0); } new = alloc_compbuf(old->x, old->y, old->type, 1); defocus_blur(node, new, old, zbuf_use, in[1]->vec[0]*nqd->scale); if (nqd->gamco) { + premul_compbuf(new, 1); gamma_correct_compbuf(new, 1); + premul_compbuf(new, 0); free_compbuf(old); } if(node->exec & NODE_BREAK) { diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c index eee33e33ff5..21e0f034a15 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/intern/CMP_util.c @@ -575,6 +575,36 @@ void gamma_correct_compbuf(CompBuf *img, int inversed) } } +void premul_compbuf(CompBuf *img, int inversed) +{ + float *drect; + int x; + + if(img->type!=CB_RGBA) return; + + drect= img->rect; + if(inversed) { + for(x=img->x*img->y; x>0; x--, drect+=4) { + if(fabs(drect[3]) < 1e-5f) { + drect[0]= 0.0f; + drect[1]= 0.0f; + drect[2]= 0.0f; + } + else { + drect[0] /= drect[3]; + drect[1] /= drect[3]; + drect[2] /= drect[3]; + } + } + } + else { + for(x=img->x*img->y; x>0; x--, drect+=4) { + drect[0] *= drect[3]; + drect[1] *= drect[3]; + drect[2] *= drect[3]; + } + } +} diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 7cb10b75f3a..6fa5251710a 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -176,6 +176,7 @@ void do_hsva_to_rgba(bNode *node, float *out, float *in); void do_ycca_to_rgba(bNode *node, float *out, float *in); void gamma_correct_compbuf(CompBuf *img, int inversed); +void premul_compbuf(CompBuf *img, int inversed); void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2); extern void node_ID_title_cb(void *node_v, void *unused_v); -- cgit v1.2.3 From ccac67d3eae4684e86b2a8a4858e9b173f520270 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 18 Feb 2008 23:50:12 +0000 Subject: Further work on the premul option for ton. This option (which basically tells the renderer and compositor to expect a key image) is now done at the image user level. This does have some caveats, as image users don't always work the way I thought they would/should (for example, the same image user structure is apparently used in the uv image editor for all images, which is kindof odd). The UV image editor also now smartly detects if the premul option is set and draws the image using key alpha, instead of premul The subversion level was upped to convert the old premul flag, which was at the image level, to the new one, which is at the image user level. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 34 +++++------------------ 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 06c3b90e828..5df649d6808 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -58,7 +58,7 @@ static bNodeSocketType cmp_node_rlayers_out[]= { static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser) { ImBuf *ibuf; - CompBuf *stackbuf; + CompBuf *stackbuf, *old; int type; ibuf= BKE_image_get_ibuf(ima, iuser); @@ -79,10 +79,11 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i stackbuf->rect= ibuf->rect_float; } - /*code to respect the premul flag of images; I'm - not sure if this is a good idea for multilayer images, - since it never worked before for them. - if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + old = stackbuf; + stackbuf = dupalloc_compbuf(stackbuf); + free_compbuf(old); + + if (type==CB_RGBA && iuser && (iuser->flag & IMA_DO_PREMUL)) { //premul the image int i; float *pixel = stackbuf->rect; @@ -93,7 +94,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i pixel[2] *= pixel[3]; } } - */ + return stackbuf; }; @@ -202,27 +203,6 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b else { stackbuf= node_composit_get_image(rd, ima, iuser); - /*respect image premul option*/ - if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { - int i; - float *pixel; - - /*first duplicate stackbuf->rect, since it's just a pointer - to the source imbuf, and we don't want to change that.*/ - stackbuf->rect = MEM_dupallocN(stackbuf->rect); - - /*flag that we can free the buffer.*/ - stackbuf->malloc = 1; - - /*premul the image*/ - pixel = stackbuf->rect; - for (i=0; ix*stackbuf->y; i++, pixel += 4) { - pixel[0] *= pixel[3]; - pixel[1] *= pixel[3]; - pixel[2] *= pixel[3]; - } - } - /* put image on stack */ out[0]->data= stackbuf; -- cgit v1.2.3 From 2283bdc09b48033c4de0e98e1bfd53b7fb382e25 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 19 Feb 2008 20:35:19 +0000 Subject: Possible fix for bug #6922: crash in displace compositor node, possibly because it didn't handle the vector input correct if it was translated. --- source/blender/nodes/intern/CMP_nodes/CMP_displace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c index 0ec15d9eb77..67b04750056 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c @@ -47,7 +47,7 @@ static bNodeSocketType cmp_node_displace_out[]= { static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *veccol, float *xscale, float *yscale) { ImBuf *ibuf; - int x, y, sx, sy; + int x, y, vx, vy, sx, sy; float dx=0.0, dy=0.0; float dspx, dspy; float uv[2]; @@ -72,16 +72,21 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float /* the x-xrad stuff is a bit weird, but i seem to need it otherwise * my returned pixels are offset weirdly */ vp = compbuf_get_pixel(vecbuf, veccol, x-vecbuf->xrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad); + + /* this happens in compbuf_get_pixel, need to make sure the following + * check takes them into account */ + vx= x-vecbuf->xof; + vy= y-vecbuf->yof; /* find the new displaced co-ords, also correcting for translate offset */ - dspx = x - (*xscale * vp[0]); - dspy = y - (*yscale * vp[1]); + dspx = vx - (*xscale * vp[0]); + dspy = vy - (*yscale * vp[1]); /* convert image space to 0.0-1.0 UV space for sampling, correcting for translate offset */ uv[0] = dspx / (float)sx; uv[1] = dspy / (float)sy; - - if(x>0 && x< vecbuf->x-1 && y>0 && y< vecbuf->y-1) { + + if(vx>0 && vx< vecbuf->x-1 && vy>0 && vy< vecbuf->y-1) { vpnext = vp+row; vpprev = vp-row; -- cgit v1.2.3 From 0e233b3213a21449399d91b9ee841c235fbba4d7 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 22 Feb 2008 22:23:58 +0000 Subject: =Reversion of premul bugfix= Reversion of premul bugfix, as it was apparently not working all that well. Note that this brings back the bug where the erase alpha paint tool won't display correctly, since the UV image editor just draws images in key alpha now. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 32 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 5df649d6808..6a82e8a9254 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -58,7 +58,7 @@ static bNodeSocketType cmp_node_rlayers_out[]= { static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser) { ImBuf *ibuf; - CompBuf *stackbuf, *old; + CompBuf *stackbuf; int type; ibuf= BKE_image_get_ibuf(ima, iuser); @@ -79,11 +79,10 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i stackbuf->rect= ibuf->rect_float; } - old = stackbuf; - stackbuf = dupalloc_compbuf(stackbuf); - free_compbuf(old); - - if (type==CB_RGBA && iuser && (iuser->flag & IMA_DO_PREMUL)) { + /*code to respect the premul flag of images; I'm + not sure if this is a good idea for multilayer images, + since it never worked before for them. + if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { //premul the image int i; float *pixel = stackbuf->rect; @@ -94,7 +93,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i pixel[2] *= pixel[3]; } } - + */ return stackbuf; }; @@ -203,6 +202,25 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b else { stackbuf= node_composit_get_image(rd, ima, iuser); + /*respect image premul option*/ + if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + int i; + float *pixel; + + /*first duplicate stackbuf->rect, since it's just a pointer + to the source imbuf, and we don't want to change that.*/ + stackbuf->rect = MEM_dupallocN(stackbuf->rect); + + /*premul the image*/ + + pixel = stackbuf->rect; + for (i=0; ix*stackbuf->y; i++, pixel += 4) { + pixel[0] *= pixel[3]; + pixel[1] *= pixel[3]; + pixel[2] *= pixel[3]; + } + } + /* put image on stack */ out[0]->data= stackbuf; -- cgit v1.2.3 From 012f0a336c84b22c3e20716e4820f3342afef5d3 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 23 Feb 2008 12:05:28 +0000 Subject: === PyNodes === * Make PyNodes work with threaded renderer. This patch is by Willian. He has worked hard on getting this sorted out - now you should be able to render with PyNodes AND multiple threads. --- .../blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 176 +++++++++++++++++---- 1 file changed, 142 insertions(+), 34 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 1d1cf3d7e23..ec3a9f3e5d6 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -43,11 +43,19 @@ static void node_dynamic_setup(bNode *node); static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out); +static void node_dynamic_free_storage_cb(bNode *node); static PyObject *init_dynamicdict(void) { - PyObject *newscriptdict= PyDict_New(); + PyObject *newscriptdict; + PyGILState_STATE gilstate = PyGILState_Ensure(); + + newscriptdict= PyDict_New(); + PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins()); EXPP_dict_set_item_str(newscriptdict, "__name__", PyString_FromString("__main__")); + + PyGILState_Release(gilstate); + return newscriptdict; } @@ -228,12 +236,8 @@ static void node_dynamic_rem_all_links(bNodeType *tinfo) } /* node_dynamic_reset: clean a pynode, getting rid of all - * data dynamically created for it. - * ntree is used only in a special case: for working pynodes - * that were saved on a .blend but fail for some reason when - * the file is opened. We need it because pynodes are initialized - * before G.main. */ -static void node_dynamic_reset(bNode *node, bNodeTree *ntree) + * data dynamically created for it. */ +static void node_dynamic_reset(bNode *node, int unlink_text) { bNodeType *tinfo, *tinfo_default; Material *ma; @@ -244,16 +248,6 @@ static void node_dynamic_reset(bNode *node, bNodeTree *ntree) node_dynamic_rem_all_links(tinfo); node_dynamic_free_typeinfo_sockets(tinfo); - if (!ntree) { node_dynamic_free_sockets(node); } - - //wnode_dynamic_update_socket_links(node, ntree); - node_dynamic_free_storage_cb(node); - - /* XXX hardcoded for shaders: */ - if (node->typeinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } - - node->typeinfo = tinfo_default; - /* reset all other XXX shader nodes sharing this typeinfo */ for (ma= G.main->mat.first; ma; ma= ma->id.next) { if (ma->nodetree) { @@ -263,45 +257,129 @@ static void node_dynamic_reset(bNode *node, bNodeTree *ntree) node_dynamic_free_storage_cb(nd); node_dynamic_free_sockets(nd); nd->typeinfo = tinfo_default; + if (unlink_text) { + nd->id = NULL; + nd->custom1 = 0; + nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); + BLI_strncpy(nd->name, "Dynamic", 8); + } } } } } + /* XXX hardcoded for shaders: */ + if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } + node_dynamic_free_typeinfo(tinfo); +} + +/* Special case of the above function: for working pynodes + * that were saved on a .blend but fail for some reason when + * the file is opened. We need this because pynodes are initialized + * before G.main. */ +static void node_dynamic_reset_loaded(bNode *node) +{ + bNodeType *tinfo = node->typeinfo; + + node_dynamic_rem_all_links(tinfo); + node_dynamic_free_typeinfo_sockets(tinfo); + node_dynamic_free_storage_cb(node); + /* XXX hardcoded for shaders: */ + if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } + node_dynamic_free_typeinfo(tinfo); + node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, NULL); } int nodeDynamicUnlinkText(ID *txtid) { Material *ma; - int unlinked= 0; + bNode *nd; + /* find one node that uses this text */ for (ma= G.main->mat.first; ma; ma= ma->id.next) { if (ma->nodetree) { - bNode *nd, *nd2 = NULL; for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { if ((nd->type == NODE_DYNAMIC) && (nd->id == txtid)) { - nd->id = NULL; + node_dynamic_reset(nd, 1); /* found, reset all */ + return 1; + } + } + } + } + return 0; /* no pynodes used this text */ +} + +/* +static void node_dynamic_free_all_typeinfos(ListBase *list) +{ + bNodeType *ntype, *ntnext; + + ntype = list->first; + + while (ntype) { + ntnext = ntype->next; + if (ntype->type == NODE_DYNAMIC && ntype->id) { + BLI_remlink(list, ntype); + node_dynamic_free_typeinfo_sockets(ntype); + node_dynamic_free_typeinfo(ntype); + } + ntype = ntnext; + } +} +*/ +/* Unload all pynodes: since the Game Engine restarts Python, we need + * to recreate pynodes dicts and objects. First we get rid of them here: */ +/* +void nodeDynamicUnloadAll(void) +{ + Material *ma; + bNode *nd; + PyGILState_STATE gilstate = PyGILState_Ensure(); + + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if ((nd->type == NODE_DYNAMIC) && nd->id) { + node_dynamic_free_storage_cb(nd); + nd->typeinfo = NULL; nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); - BLI_strncpy(nd->name, "Dynamic", 8); - nd2 = nd; /* so we have a ptr to one of them */ - unlinked++; + nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_LOADED); } } - /* clean uneeded dynamic data from all nodes that shared - * this text: */ - if (nd2) node_dynamic_reset(nd2, NULL); } } - return unlinked; + node_dynamic_free_all_typeinfos(&node_all_shaders); + + PyGILState_Release(gilstate); +} + +void nodeDynamicReloadAll(void) +{ + Material *ma; + bNode *nd; + + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if ((nd->type == NODE_DYNAMIC) && nd->id) { + node_dynamic_setup(nd); + } + } + } + } } +*/ static void node_dynamic_pyerror_print(bNode *node) { + PyGILState_STATE gilstate = PyGILState_Ensure(); + fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name); if (PyErr_Occurred()) { PyErr_Print(); } else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); } + + PyGILState_Release(gilstate); } static int node_dynamic_parse(struct bNode *node) @@ -316,6 +394,7 @@ static int node_dynamic_parse(struct bNode *node) char *buf = NULL; Py_ssize_t pos = 0; int is_valid_script = 0; + PyGILState_STATE gilstate; if (!node->id || !node->storage) return 0; @@ -324,6 +403,9 @@ static int node_dynamic_parse(struct bNode *node) if (BTST(node->custom1, NODE_DYNAMIC_READY)) return 0; + /* for threading */ + gilstate = PyGILState_Ensure(); + nsd = (NodeScriptDict *)node->storage; dict = (PyObject *)(nsd->dict); @@ -336,6 +418,7 @@ static int node_dynamic_parse(struct bNode *node) if (!pyresult) { node_dynamic_disable(node); node_dynamic_pyerror_print(node); + PyGILState_Release(gilstate); return -1; } @@ -365,7 +448,8 @@ static int node_dynamic_parse(struct bNode *node) node->typeinfo->pydict = dict; node->typeinfo->pynode = pynode; node->typeinfo->id = node->id; - nodeAddSockets(node, node->typeinfo); + if (BNTST(node->custom1, NODE_DYNAMIC_LOADED)) + nodeAddSockets(node, node->typeinfo); if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) { nodeRegisterType(&node_all_shaders, node->typeinfo); /* nodeRegisterType copied it to a new one, so we @@ -386,6 +470,8 @@ static int node_dynamic_parse(struct bNode *node) } } + PyGILState_Release(gilstate); + if (!is_valid_script) { /* not a valid pynode script */ node_dynamic_disable(node); node_dynamic_pyerror_print(node); @@ -402,6 +488,7 @@ static void node_dynamic_setup(bNode *node) NodeScriptDict *nsd = NULL; bNodeTree *nodetree = NULL; bNodeType *ntype = NULL; + PyGILState_STATE gilstate; /* Possible cases: * NEW @@ -423,9 +510,12 @@ static void node_dynamic_setup(bNode *node) if (BTST(node->custom1, NODE_DYNAMIC_READY)) return; + gilstate = PyGILState_Ensure(); + /* ERROR, reset to (empty) defaults */ if (BCLR(node->custom1, NODE_DYNAMIC_ERROR) == 0) { - node_dynamic_reset(node, NULL); + node_dynamic_reset(node, 0); + PyGILState_Release(gilstate); return; } @@ -459,6 +549,7 @@ static void node_dynamic_setup(bNode *node) node->storage = nsd; /* prepared, now reparse: */ node_dynamic_parse(node); + PyGILState_Release(gilstate); return; } } @@ -492,8 +583,9 @@ static void node_dynamic_setup(bNode *node) nodeMakeDynamicType(node); nsd->dict = init_dynamicdict(); if ((node_dynamic_parse(node) == -1) && nodetree) { - node_dynamic_reset(node, nodetree); + node_dynamic_reset_loaded(node); } + PyGILState_Release(gilstate); return; } } @@ -502,6 +594,7 @@ static void node_dynamic_setup(bNode *node) * we just reuse existing py dict and pynode */ nsd->dict = node->typeinfo->pydict; nsd->node = node->typeinfo->pynode; + Py_INCREF((PyObject *)(nsd->dict)); Py_INCREF((PyObject *)(nsd->node)); @@ -513,6 +606,8 @@ static void node_dynamic_setup(bNode *node) node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ADDEXIST); node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); + PyGILState_Release(gilstate); + return; } @@ -546,16 +641,21 @@ static void node_dynamic_init_cb(bNode *node) { static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node) { NodeScriptDict *nsd; + PyGILState_STATE gilstate; if (!orig_node->storage) return; nsd = (NodeScriptDict *)(orig_node->storage); new_node->storage = MEM_dupallocN(orig_node->storage); + gilstate = PyGILState_Ensure(); + if (nsd->node) Py_INCREF((PyObject *)(nsd->node)); if (nsd->dict) Py_INCREF((PyObject *)(nsd->dict)); + + PyGILState_Release(gilstate); } /* node_dynamic_exec_cb: the execution callback called per pixel @@ -566,12 +666,13 @@ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNode PyObject *pyresult = NULL; PyObject *args = NULL; ShadeInput *shi; + PyGILState_STATE gilstate; if (!node->id) return; - if (G.scene->r.threads > 1) - return; + /*if (G.scene->r.threads > 1) + return;*/ if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_REPARSE)) { node_dynamic_setup(node); @@ -585,9 +686,13 @@ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNode if (BTST(node->custom1, NODE_DYNAMIC_READY)) { nsd = (NodeScriptDict *)node->storage; - mynode = (BPy_Node *)(nsd->node); + + if (mynode && PyCallable_Check((PyObject *)mynode)) { + + gilstate = PyGILState_Ensure(); + mynode->node = node; shi = ((ShaderCallData *)data)->shi; @@ -600,12 +705,14 @@ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNode Py_DECREF(args); if (!pyresult) { + PyGILState_Release(gilstate); node_dynamic_disable_all_by_id(node->id); node_dynamic_pyerror_print(node); node_dynamic_setup(node); return; } Py_DECREF(pyresult); + PyGILState_Release(gilstate); } } } @@ -627,3 +734,4 @@ bNodeType node_dynamic_typeinfo = { /* id */ NULL }; + -- cgit v1.2.3 From 6f78c1371d82d492cc13602fbeb786cc53962b98 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 28 Feb 2008 15:23:44 +0000 Subject: Bugfix: compositor Blur node Bokeh option gave wrong results at the bottom pixels of the image. --- source/blender/nodes/intern/CMP_nodes/CMP_blur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c index 3d6b3dd2955..e7e799b6e76 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c @@ -398,7 +398,7 @@ static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fa int maxyr= y+rady>imgy-1?imgy-y-1:rady; float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr); - float *dgausd= gausstab + (minyr+rady)*2*radx + minxr+radx; + float *dgausd= gausstab + (minyr+rady)*(2*radx+1) + minxr+radx; if(x<=0) src= srcd; else if(x Date: Thu, 28 Feb 2008 20:26:00 +0000 Subject: Fix segfault with bad setting in the Image node. The limit in the UI tooltips to set the amount of images used in animation allow the zero value, that cause a segfault. This commit fix the UI, add a init value of 1 to the node and also check in case that node_composit_get_image return NULL. --- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 41 ++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 6a82e8a9254..be5a1d7241b 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -201,31 +201,33 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b } else { stackbuf= node_composit_get_image(rd, ima, iuser); + + if (stackbuf) { + /*respect image premul option*/ + if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { + int i; + float *pixel; - /*respect image premul option*/ - if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { - int i; - float *pixel; - - /*first duplicate stackbuf->rect, since it's just a pointer - to the source imbuf, and we don't want to change that.*/ - stackbuf->rect = MEM_dupallocN(stackbuf->rect); + /*first duplicate stackbuf->rect, since it's just a pointer + to the source imbuf, and we don't want to change that.*/ + stackbuf->rect = MEM_dupallocN(stackbuf->rect); - /*premul the image*/ + /*premul the image*/ - pixel = stackbuf->rect; - for (i=0; ix*stackbuf->y; i++, pixel += 4) { - pixel[0] *= pixel[3]; - pixel[1] *= pixel[3]; - pixel[2] *= pixel[3]; + pixel = stackbuf->rect; + for (i=0; ix*stackbuf->y; i++, pixel += 4) { + pixel[0] *= pixel[3]; + pixel[1] *= pixel[3]; + pixel[2] *= pixel[3]; + } } - } - /* put image on stack */ - out[0]->data= stackbuf; + /* put image on stack */ + out[0]->data= stackbuf; - if(out[2]->hasoutput) - out[2]->data= node_composit_get_zimage(node, rd); + if(out[2]->hasoutput) + out[2]->data= node_composit_get_zimage(node, rd); + } } /* alpha and preview for both types */ @@ -242,6 +244,7 @@ static void node_composit_init_image(bNode* node) { ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user"); node->storage= iuser; + iuser->frames= 1; iuser->sfra= 1; iuser->fie_ima= 2; iuser->ok= 1; -- cgit v1.2.3 From d7ef04a51939c49c32c0d82b0c53bd71788e760f Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 8 Mar 2008 19:02:08 +0000 Subject: Long on the wishlist, quite simple even, and there it finally is: Compositor: Muting option to temporary disable/enable nodes. Hotkey: press M on selection. It toggles. Note: no menu entry yet, and drawing style could be tweakered... --- source/blender/nodes/intern/CMP_util.c | 42 ++++++++++++++++++++++++++++++++++ source/blender/nodes/intern/CMP_util.h | 1 + 2 files changed, 43 insertions(+) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c index 21e0f034a15..a2629aa396e 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/intern/CMP_util.c @@ -122,6 +122,48 @@ void print_compbuf(char *str, CompBuf *cbuf) } +/* used for disabling node (similar code in drawnode.c for disable line) */ +void node_compo_pass_on(bNode *node, bNodeStack **nsin, bNodeStack **nsout) +{ + CompBuf *valbuf= NULL, *colbuf= NULL, *vecbuf= NULL; + bNodeSocket *sock; + int a; + + /* connect the first value buffer in with first value out */ + /* connect the first RGBA buffer in with first RGBA out */ + + /* test the inputs */ + for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { + if(nsin[a]->data) { + CompBuf *cbuf= nsin[a]->data; + if(cbuf->type==1 && valbuf==NULL) valbuf= cbuf; + if(cbuf->type==3 && vecbuf==NULL) vecbuf= cbuf; + if(cbuf->type==4 && colbuf==NULL) colbuf= cbuf; + } + } + + /* outputs */ + if(valbuf || colbuf || vecbuf) { + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->hasoutput) { + if(sock->type==SOCK_VALUE && valbuf) { + nsout[a]->data= pass_on_compbuf(valbuf); + valbuf= NULL; + } + if(sock->type==SOCK_VECTOR && vecbuf) { + nsout[a]->data= pass_on_compbuf(vecbuf); + vecbuf= NULL; + } + if(sock->type==SOCK_RGBA && colbuf) { + nsout[a]->data= pass_on_compbuf(colbuf); + colbuf= NULL; + } + } + } + } +} + + CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type) { CompBuf *cbuf; diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 6fa5251710a..a0e2f90f0da 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -132,6 +132,7 @@ CompBuf *dupalloc_compbuf(CompBuf *cbuf); CompBuf *pass_on_compbuf(CompBuf *cbuf); void free_compbuf(CompBuf *cbuf); void print_compbuf(char *str, CompBuf *cbuf); +void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNodeStack **nsout); CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type); CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy); -- cgit v1.2.3 From 3c561ec2165f201deaa910f981e0dd116f36e64e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Mar 2008 14:40:27 +0000 Subject: Added an Alpha Convert compositor node, to convert between premultiplied and key alpha. --- source/blender/nodes/CMP_node.h | 1 + .../blender/nodes/intern/CMP_nodes/CMP_premulkey.c | 77 ++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h index 3e62ea9970f..020bbdebfa2 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -85,6 +85,7 @@ extern bNodeType cmp_node_sepyuva; extern bNodeType cmp_node_combyuva; extern bNodeType cmp_node_sepycca; extern bNodeType cmp_node_combycca; +extern bNodeType cmp_node_premulkey; extern bNodeType cmp_node_diff_matte; extern bNodeType cmp_node_chroma; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c b/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c new file mode 100644 index 00000000000..4fde652c59d --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c @@ -0,0 +1,77 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) 2006 Blender Foundation. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** + +*/ + +#include "../CMP_util.h" + +/* **************** Premul and Key Alpha Convert ******************** */ + +static bNodeSocketType cmp_node_premulkey_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_premulkey_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_premulkey(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(out[0]->hasoutput==0) + return; + + if(in[0]->data) { + CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + + stackbuf= dupalloc_compbuf(cbuf); + premul_compbuf(stackbuf, node->custom1 == 1); + + out[0]->data = stackbuf; + if(cbuf != in[0]->data) + free_compbuf(cbuf); + } +} + +bNodeType cmp_node_premulkey= { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_PREMULKEY, + /* name */ "Alpha Convert", + /* width+range */ 140, 100, 320, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_premulkey_in, + /* output sock */ cmp_node_premulkey_out, + /* storage */ "", + /* execfunc */ node_composit_exec_premulkey, + /* butfunc */ NULL, + /* initfunc */ NULL, + /* freestoragefunc */ NULL, + /* copysotragefunc */ NULL, + /* id */ NULL +}; + -- cgit v1.2.3 From e6252661627407c8ed1004856ccfc67d32cf825d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 13 Mar 2008 11:26:18 +0000 Subject: Fix for bug #8385: vector inputs of texture node in the compositor did not work correct, it should use bNodeStack inputs like other nodes. --- source/blender/nodes/intern/CMP_nodes/CMP_texture.c | 15 ++++++++++----- source/blender/nodes/intern/CMP_util.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c index 31afe74bd11..c0845a582d3 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c @@ -45,16 +45,15 @@ static bNodeSocketType cmp_node_texture_out[]= { static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco) { bNode *node= cbuf->node; - bNodeSocket *sock= node->inputs.first; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}; int retval, type= cbuf->type; - size= sock->next->ns.vec; + size= cbuf->procedural_size; - vec[0]= size[0]*(xco + sock->ns.vec[0]); - vec[1]= size[1]*(yco + sock->ns.vec[1]); - vec[2]= size[2]*sock->ns.vec[2]; + vec[0]= size[0]*(xco + cbuf->procedural_offset[0]); + vec[1]= size[1]*(yco + cbuf->procedural_offset[1]); + vec[2]= size[2]*cbuf->procedural_offset[2]; retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres); @@ -106,6 +105,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, prevbuf->rect_procedural= texture_procedural; prevbuf->node= node; + VECCOPY(prevbuf->procedural_offset, in[0]->vec); + VECCOPY(prevbuf->procedural_size, in[1]->vec); composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); generate_preview(node, prevbuf); free_compbuf(prevbuf); @@ -115,6 +116,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->rect_procedural= texture_procedural; stackbuf->node= node; + VECCOPY(stackbuf->procedural_offset, in[0]->vec); + VECCOPY(stackbuf->procedural_size, in[1]->vec); out[0]->data= stackbuf; } @@ -123,6 +126,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->rect_procedural= texture_procedural; stackbuf->node= node; + VECCOPY(stackbuf->procedural_offset, in[0]->vec); + VECCOPY(stackbuf->procedural_size, in[1]->vec); out[1]->data= stackbuf; } diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index a0e2f90f0da..0d7bda0604c 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -107,6 +107,7 @@ typedef struct CompBuf { int xof, yof; /* relative to center of target image */ void (*rect_procedural)(struct CompBuf *, float *, float, float); + float procedural_size[3], procedural_offset[3]; bNode *node; /* only in use for procedural bufs */ struct CompBuf *next, *prev; /* for pass-on, works nicer than reference counting */ -- cgit v1.2.3 From bb48a75c37e85fd5cc77ebd1c585f575932fb305 Mon Sep 17 00:00:00 2001 From: Stephen Swaney Date: Sat, 15 Mar 2008 14:41:47 +0000 Subject: compiler warning cleanup --- source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c index 662d8e8dde9..5e1803a6774 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c @@ -63,7 +63,7 @@ static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav) } -void static tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src) +static void tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src) { int x, y; float dr, dg, db, al, igm = (ntm->gamma==0.f) ? 1 : (1.f / ntm->gamma); -- cgit v1.2.3 From dae503187c9c77a6f51bc4cb7bad81e78590b692 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Sun, 16 Mar 2008 17:24:29 +0000 Subject: == PyNodes == Ongoing updates to the Blender.Node Python API: - Changed Blender.Node.node to Blender.Node.Scripted to be more specific and conform to bpython API. - Added a Blender.Node.Socket type to be used to define node sockets in a PyNode script. Also, socket type is inferred from the value(s) passed in, instead of also being defined by the script author. - Added attr access to input and output sockets in the __call__ method. Ex: an input socket called 'color' can be accessed as self.input.color now. These changes break existing pynode scripts, which shouldn't be a problem yet, of course, since we're still finishing this feature for 2.46. The wiki page and sample .blends have already been updated: http://wiki.blender.org/index.php/BlenderDev/PyNodes http://wiki.blender.org/index.php/BlenderDev/PyNodes/API --- .../blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 80 ++-------------------- 1 file changed, 6 insertions(+), 74 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index ec3a9f3e5d6..36a3bd5b171 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -59,14 +59,6 @@ static PyObject *init_dynamicdict(void) { return newscriptdict; } -/* unused for now -static void free_dynamicdict(PyObject *dict) { - if (dict!=NULL) { - Py_DECREF(dict); - } -} -*/ - static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id) { bNodeType *ntype = list->first; @@ -309,68 +301,6 @@ int nodeDynamicUnlinkText(ID *txtid) { return 0; /* no pynodes used this text */ } -/* -static void node_dynamic_free_all_typeinfos(ListBase *list) -{ - bNodeType *ntype, *ntnext; - - ntype = list->first; - - while (ntype) { - ntnext = ntype->next; - if (ntype->type == NODE_DYNAMIC && ntype->id) { - BLI_remlink(list, ntype); - node_dynamic_free_typeinfo_sockets(ntype); - node_dynamic_free_typeinfo(ntype); - } - ntype = ntnext; - } -} -*/ -/* Unload all pynodes: since the Game Engine restarts Python, we need - * to recreate pynodes dicts and objects. First we get rid of them here: */ -/* -void nodeDynamicUnloadAll(void) -{ - Material *ma; - bNode *nd; - PyGILState_STATE gilstate = PyGILState_Ensure(); - - for (ma= G.main->mat.first; ma; ma= ma->id.next) { - if (ma->nodetree) { - for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { - if ((nd->type == NODE_DYNAMIC) && nd->id) { - node_dynamic_free_storage_cb(nd); - nd->typeinfo = NULL; - nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_LOADED); - } - } - } - } - - node_dynamic_free_all_typeinfos(&node_all_shaders); - - PyGILState_Release(gilstate); -} - -void nodeDynamicReloadAll(void) -{ - Material *ma; - bNode *nd; - - for (ma= G.main->mat.first; ma; ma= ma->id.next) { - if (ma->nodetree) { - for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { - if ((nd->type == NODE_DYNAMIC) && nd->id) { - node_dynamic_setup(nd); - } - } - } - } -} -*/ - static void node_dynamic_pyerror_print(bNode *node) { PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -426,15 +356,17 @@ static int node_dynamic_parse(struct bNode *node) while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) { /* look for the node object */ + if (strcmp("Socket", PyString_AsString(key)) == 0) + continue; /* XXX ugly, fix it */ if (PyObject_TypeCheck(value, &PyType_Type)==1) { - BPy_NodeSockets *sockets = Node_CreateSockets(node); + BPy_NodeSocketLists *socklists = Node_CreateSocketLists(node); - args = Py_BuildValue("(O)", sockets); + args = Py_BuildValue("(O)", socklists); /* init it to get the input and output sockets */ pynode = PyObject_Call(value, args, NULL); - Py_DECREF(sockets); + Py_DECREF(socklists); Py_DECREF(args); if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) { @@ -466,7 +398,7 @@ static int node_dynamic_parse(struct bNode *node) node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); break; } - break; + //break; } } -- cgit v1.2.3 From f48c8dea16cb5db9ada404b0bcc04e584a62a24f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 16 Mar 2008 20:04:41 +0000 Subject: Fix for bug #8582: compositor math node did not output any result without input connections. --- source/blender/nodes/intern/CMP_nodes/CMP_math.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c index cf2af9bbc11..e317998b5fc 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c @@ -142,7 +142,6 @@ static void node_composit_exec_math(void *data, bNode *node, bNodeStack **in, bN CompBuf *stackbuf; /* check for inputs and outputs for early out*/ - if(in[0]->hasinput==0 && in[1]->hasinput==0) return; if(out[0]->hasoutput==0) return; /* no image-color operation */ -- cgit v1.2.3 From 753a0e974627a84d365da42626fcaed6ea80326a Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 25 Mar 2008 06:10:03 +0000 Subject: Tweaks to labels on brightness/contrast node --- source/blender/nodes/intern/CMP_nodes/CMP_brightness.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c b/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c index c87307434b5..f6363cc7ffa 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_brightness.c @@ -35,8 +35,8 @@ static bNodeSocketType cmp_node_brightcontrast_in[]= { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, - { SOCK_VALUE, 1, "contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, + { SOCK_VALUE, 1, "Bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, + { SOCK_VALUE, 1, "Contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f}, { -1, 0, "" } }; static bNodeSocketType cmp_node_brightcontrast_out[]= { -- cgit v1.2.3 From 22149c95ba5e3f885b9609b0cf60f54a13c481d5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 1 Apr 2008 11:08:48 +0000 Subject: Bugfix: the defocus node "no zbuffer" settings was automatically set if there was no zbuffer input. However this means a user settings can be permanently changed without a user knowing. Now it just runs as if this option is set if there is no zbuffer, but doesn't change the setting. --- source/blender/nodes/intern/CMP_nodes/CMP_defocus.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c index f8be69d8092..6f175671296 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c @@ -235,7 +235,7 @@ static void IIR_gauss_single(CompBuf* buf, float sigma) #undef YVV } -static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, float inpval) +static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, float inpval, int no_zbuf) { NodeDefocus *nqd = node->storage; CompBuf *wts; // weights buffer @@ -283,7 +283,7 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, // if 'no_zbuf' flag set (which is always set if input is not an image), // values are instead interpreted directly as blur radius values - if (nqd->no_zbuf) { + if (no_zbuf) { // to prevent *reaaallly* big radius values and impossible calculation times, // limit the maximum to half the image width or height, whichever is smaller float maxr = 0.5f*(float)MIN2(img->x, img->y); @@ -700,7 +700,7 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf, // sampled, simple rejection sampling here, good enough unsigned int maxsam, s, ui = BLI_rand()*BLI_rand(); float wcor, cpr = BLI_frand(); - if (nqd->no_zbuf) + if (no_zbuf) maxsam = nqd->samples; // no zbuffer input, use sample value directly else { // depth adaptive sampling hack, the more out of focus, the more samples taken, 16 minimum. @@ -774,11 +774,12 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in, { CompBuf *new, *old, *zbuf_use = NULL, *img = in[0]->data, *zbuf = in[1]->data; NodeDefocus *nqd = node->storage; + int no_zbuf = nqd->no_zbuf; if ((img==NULL) || (out[0]->hasoutput==0)) return; // if image not valid type or fstop==infinite (128), nothing to do, pass in to out - if (((img->type!=CB_RGBA) && (img->type!=CB_VAL)) || ((nqd->no_zbuf==0) && (nqd->fstop==128.f))) { + if (((img->type!=CB_RGBA) && (img->type!=CB_VAL)) || ((no_zbuf==0) && (nqd->fstop==128.f))) { out[0]->data = pass_on_compbuf(img); return; } @@ -793,7 +794,7 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in, } zbuf_use = typecheck_compbuf(zbuf, CB_VAL); } - else nqd->no_zbuf = 1; // no zbuffer input + else no_zbuf = 1; // no zbuffer input // ok, process old = img; @@ -808,7 +809,7 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in, } new = alloc_compbuf(old->x, old->y, old->type, 1); - defocus_blur(node, new, old, zbuf_use, in[1]->vec[0]*nqd->scale); + defocus_blur(node, new, old, zbuf_use, in[1]->vec[0]*nqd->scale, no_zbuf); if (nqd->gamco) { premul_compbuf(new, 1); -- cgit v1.2.3 From 6dec5db1e6e050067ee58d6db7a476b8153a5d0d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Apr 2008 15:21:25 +0000 Subject: Fix for bug #8073: texture nodes connected to a viewer could crash. Also fixed a bug where procedural buffers did not convert correctly to different buffer types (e.g. value -> rgba would give red). --- .../blender/nodes/intern/CMP_nodes/CMP_texture.c | 11 +- source/blender/nodes/intern/CMP_util.c | 121 +++++++++++++++++++-- source/blender/nodes/intern/CMP_util.h | 2 + 3 files changed, 123 insertions(+), 11 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c index c0845a582d3..c1f1948dba1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c @@ -42,12 +42,12 @@ static bNodeSocketType cmp_node_texture_out[]= { }; /* called without rect allocated */ -static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco) +static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco) { bNode *node= cbuf->node; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}; - int retval, type= cbuf->type; + float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}, col[4]; + int retval, type= cbuf->procedural_type; size= cbuf->procedural_size; @@ -79,6 +79,8 @@ static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco) else { VECCOPY(col, nor); } + + typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type); } /* texture node outputs get a small rect, to make sure all other nodes accept it */ @@ -107,6 +109,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, prevbuf->node= node; VECCOPY(prevbuf->procedural_offset, in[0]->vec); VECCOPY(prevbuf->procedural_size, in[1]->vec); + prevbuf->procedural_type= CB_RGBA; composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); generate_preview(node, prevbuf); free_compbuf(prevbuf); @@ -118,6 +121,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->node= node; VECCOPY(stackbuf->procedural_offset, in[0]->vec); VECCOPY(stackbuf->procedural_size, in[1]->vec); + stackbuf->procedural_type= CB_VAL; out[0]->data= stackbuf; } @@ -128,6 +132,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->node= node; VECCOPY(stackbuf->procedural_offset, in[0]->vec); VECCOPY(stackbuf->procedural_size, in[1]->vec); + stackbuf->procedural_type= CB_RGBA; out[1]->data= stackbuf; } diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c index a2629aa396e..f9805645115 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/intern/CMP_util.c @@ -225,17 +225,100 @@ CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy) return outbuf; } +void typecheck_compbuf_color(float *out, float *in, int outtype, int intype) +{ + if(intype == outtype) { + memcpy(out, in, sizeof(float)*outtype); + } + else if(outtype==CB_VAL) { + if(intype==CB_VEC2) { + *out= 0.5f*(in[0]+in[1]); + } + else if(intype==CB_VEC3) { + *out= 0.333333f*(in[0]+in[1]+in[2]); + } + else if(intype==CB_RGBA) { + *out= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f; + } + } + else if(outtype==CB_VEC2) { + if(intype==CB_VAL) { + out[0]= in[0]; + out[1]= in[0]; + } + else if(intype==CB_VEC3) { + out[0]= in[0]; + out[1]= in[1]; + } + else if(intype==CB_RGBA) { + out[0]= in[0]; + out[1]= in[1]; + } + } + else if(outtype==CB_VEC3) { + if(intype==CB_VAL) { + out[0]= in[0]; + out[1]= in[0]; + out[2]= in[0]; + } + else if(intype==CB_VEC2) { + out[0]= in[0]; + out[1]= in[1]; + out[2]= 0.0f; + } + else if(intype==CB_RGBA) { + out[0]= in[0]; + out[1]= in[1]; + out[2]= in[2]; + } + } + else if(outtype==CB_RGBA) { + if(intype==CB_VAL) { + out[0]= in[0]; + out[1]= in[0]; + out[2]= in[0]; + out[3]= 1.0f; + } + else if(intype==CB_VEC2) { + out[0]= in[0]; + out[1]= in[1]; + out[2]= 0.0f; + out[3]= 1.0f; + } + else if(intype==CB_VEC3) { + out[0]= in[0]; + out[1]= in[1]; + out[2]= in[2]; + out[3]= 1.0f; + } + } +} + CompBuf *typecheck_compbuf(CompBuf *inbuf, int type) { - if(inbuf && inbuf->type!=type && inbuf->rect_procedural==NULL) { - CompBuf *outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); - float *inrf= inbuf->rect; - float *outrf= outbuf->rect; - int x= inbuf->x*inbuf->y; - + if(inbuf && inbuf->type!=type) { + CompBuf *outbuf; + float *inrf, *outrf; + int x; + + outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); + /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */ outbuf->xof= inbuf->xof; outbuf->yof= inbuf->yof; + + if(inbuf->rect_procedural) { + outbuf->rect_procedural= inbuf->rect_procedural; + VECCOPY(outbuf->procedural_size, inbuf->procedural_size); + VECCOPY(outbuf->procedural_offset, inbuf->procedural_offset); + outbuf->procedural_type= inbuf->procedural_type; + outbuf->node= inbuf->node; + return outbuf; + } + + inrf= inbuf->rect; + outrf= outbuf->rect; + x= inbuf->x*inbuf->y; if(type==CB_VAL) { if(inbuf->type==CB_VEC2) { @@ -502,6 +585,25 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel) return valbuf; } +static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy) +{ + CompBuf *outbuf; + float *outfp; + int xrad, yrad, x, y; + + outbuf= alloc_compbuf(newx, newy, CB_RGBA, 1); + + outfp= outbuf->rect; + xrad= outbuf->xrad; + yrad= outbuf->yrad; + + for(y= -yrad; y<-yrad+outbuf->y; y++) + for(x= -xrad; x<-xrad+outbuf->x; x++, outfp+=outbuf->type) + cbuf->rect_procedural(cbuf, outfp, (float)x/(float)xrad, (float)y/(float)yrad); + + return outbuf; +} + void generate_preview(bNode *node, CompBuf *stackbuf) { bNodePreview *preview= node->preview; @@ -509,7 +611,7 @@ void generate_preview(bNode *node, CompBuf *stackbuf) if(preview && stackbuf) { CompBuf *cbuf, *stackbuf_use; - if(stackbuf->rect==NULL) return; + if(stackbuf->rect==NULL && stackbuf->rect_procedural==NULL) return; stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA); @@ -522,7 +624,10 @@ void generate_preview(bNode *node, CompBuf *stackbuf) preview->xsize= (140*stackbuf->x)/stackbuf->y; } - cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize); + if(stackbuf_use->rect_procedural) + cbuf= generate_procedural_preview(stackbuf_use, preview->xsize, preview->ysize); + else + cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize); /* this ensures free-compbuf does the right stuff */ SWAP(float *, cbuf->rect, node->preview->rect); diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 0d7bda0604c..e111632a195 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -108,6 +108,7 @@ typedef struct CompBuf { void (*rect_procedural)(struct CompBuf *, float *, float, float); float procedural_size[3], procedural_offset[3]; + int procedural_type; bNode *node; /* only in use for procedural bufs */ struct CompBuf *next, *prev; /* for pass-on, works nicer than reference counting */ @@ -138,6 +139,7 @@ void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNo CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type); CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy); CompBuf *typecheck_compbuf(CompBuf *inbuf, int type); +void typecheck_compbuf_color(float *out, float *in, int outtype, int intype); float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad); /* **************************************************** */ -- cgit v1.2.3 From c92660b18c06866ca23c68506637bd487012dcd6 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 11 Apr 2008 18:07:27 +0000 Subject: This is patch [#8531] Change gamma node max value Submitted By: Stephane SOPPERA (soppera) It just increases the max value for gamma correction to 10f. Which as noted in the patch is the same as the Gimp's color level tool. Kent --- source/blender/nodes/intern/CMP_nodes/CMP_gamma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c index 5d0ab729e08..6cd1c5981a6 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c @@ -34,7 +34,7 @@ static bNodeSocketType cmp_node_gamma_in[]= { { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - { SOCK_VALUE, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 2.0f}, + { SOCK_VALUE, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f}, { -1, 0, "" } }; static bNodeSocketType cmp_node_gamma_out[]= { -- cgit v1.2.3 From 5d0a207ecb843c4c73be897cfccbf3a0d2db574b Mon Sep 17 00:00:00 2001 From: Chris Want Date: Wed, 16 Apr 2008 22:40:48 +0000 Subject: Patch from GSR that a) fixes a whole bunch of GPL/BL license blocks that were previously missed; and b) greatly increase my ohloh stats! --- source/blender/nodes/CMakeLists.txt | 9 +++------ source/blender/nodes/Makefile | 9 +++------ source/blender/nodes/intern/CMP_nodes/Makefile | 9 +++------ source/blender/nodes/intern/Makefile | 9 +++------ source/blender/nodes/intern/SHD_nodes/Makefile | 9 +++------ 5 files changed, 15 insertions(+), 30 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index eab47eaeb02..2cb855ed440 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -1,12 +1,9 @@ -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. +# 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 @@ -24,7 +21,7 @@ # # Contributor(s): Jacques Beaurain. # -# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# ***** END GPL LICENSE BLOCK ***** FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c) diff --git a/source/blender/nodes/Makefile b/source/blender/nodes/Makefile index 37edf74b3ea..ee0c82fad62 100644 --- a/source/blender/nodes/Makefile +++ b/source/blender/nodes/Makefile @@ -1,15 +1,12 @@ # # $Id$ # -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. +# 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 @@ -27,7 +24,7 @@ # # Contributor(s): none yet. # -# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# ***** END GPL LICENSE BLOCK ***** # # Bounces make to subdirectories. diff --git a/source/blender/nodes/intern/CMP_nodes/Makefile b/source/blender/nodes/intern/CMP_nodes/Makefile index 3564bf9034b..61b03f237db 100644 --- a/source/blender/nodes/intern/CMP_nodes/Makefile +++ b/source/blender/nodes/intern/CMP_nodes/Makefile @@ -1,15 +1,12 @@ # # $Id$ # -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. +# 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 @@ -27,7 +24,7 @@ # # Contributor(s): none yet. # -# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# ***** END GPL LICENSE BLOCK ***** # # diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 71290bf03cd..12b3616df25 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -1,15 +1,12 @@ # # $Id$ # -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. +# 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 @@ -27,7 +24,7 @@ # # Contributor(s): none yet. # -# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# ***** END GPL LICENSE BLOCK ***** # # diff --git a/source/blender/nodes/intern/SHD_nodes/Makefile b/source/blender/nodes/intern/SHD_nodes/Makefile index 04e042cee76..1917e9ba15c 100644 --- a/source/blender/nodes/intern/SHD_nodes/Makefile +++ b/source/blender/nodes/intern/SHD_nodes/Makefile @@ -1,15 +1,12 @@ # # $Id$ # -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. +# 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 @@ -27,7 +24,7 @@ # # Contributor(s): none yet. # -# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# ***** END GPL LICENSE BLOCK ***** # # -- cgit v1.2.3 From 3a4f23aa78b5152c1adc253f48b6a591da0cf8f9 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Fri, 25 Apr 2008 16:35:52 +0000 Subject: == PyNodes == 1) Added support for a var called "__node__" in pynode scripts, that can be used to point to the desired pynode object, to make sure it is chosen. 2) Fixed a semi-obscure crash that could happen when reparsing a pynode script that was used by multiple nodes in different scenes. Memory corruption would happen if the reparsing failed during the recreation of the pynode object, not when executing it. --- .../blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 136 ++++++++++++++------- 1 file changed, 90 insertions(+), 46 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 36a3bd5b171..37bbb68ba03 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -160,11 +160,11 @@ static void node_dynamic_free_storage_cb(bNode *node) } /* Disable pynode when its script fails */ -static void node_dynamic_disable(bNode *node) +/*static void node_dynamic_disable(bNode *node) { node->custom1 = 0; node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR); -} +}*/ /* Disable all pynodes using the given text (script) id */ static void node_dynamic_disable_all_by_id(ID *id) @@ -211,6 +211,8 @@ static void node_dynamic_rem_all_links(bNodeType *tinfo) in = tinfo->inputs ? 1 : 0; out = tinfo->outputs ? 1 : 0; + if (!in && !out) return; + for (ma= G.main->mat.first; ma; ma= ma->id.next) { if (ma->nodetree) { bNode *nd; @@ -248,6 +250,7 @@ static void node_dynamic_reset(bNode *node, int unlink_text) if (nd->typeinfo == tinfo) { node_dynamic_free_storage_cb(nd); node_dynamic_free_sockets(nd); + //node_dynamic_update_socket_links(nd, ma->nodetree); nd->typeinfo = tinfo_default; if (unlink_text) { nd->id = NULL; @@ -312,17 +315,69 @@ static void node_dynamic_pyerror_print(bNode *node) PyGILState_Release(gilstate); } +static void node_dynamic_register_type(bNode *node) +{ + nodeRegisterType(&node_all_shaders, node->typeinfo); + /* nodeRegisterType copied it to a new one, so we + * free the typeinfo itself, but not what it + * points to: */ + MEM_freeN(node->typeinfo); + node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id); + MEM_freeN(node->typeinfo->name); + node->typeinfo->name = BLI_strdup(node->name); +} + +/* node_dynamic_get_pynode: + * Find the pynode definition from the script */ +static PyObject *node_dynamic_get_pynode(PyObject *dict) +{ + PyObject *key= NULL; + Py_ssize_t pos = 0; + PyObject *value = NULL; + + /* script writer specified a node? */ + value = PyDict_GetItemString(dict, "__node__"); + + if (value) { + if (PyObject_TypeCheck(value, &PyType_Type)) { + Py_INCREF(value); + return value; + } + else { + PyErr_SetString(PyExc_TypeError, + "expected class object derived from Scripted node"); + return NULL; + } + } + + /* case not, search for it in the script's global dictionary */ + while (PyDict_Next(dict, &pos, &key, &value)) { + /* skip names we know belong to other available objects */ + if (strcmp("Socket", PyString_AsString(key)) == 0) + continue; + else if (strcmp("Scripted", PyString_AsString(key)) == 0) + continue; + /* naive: we grab the first ob of type 'type': */ + else if (PyObject_TypeCheck(value, &PyType_Type)) { + Py_INCREF(value); + return value; + } + } + + PyErr_SetString(PyExc_TypeError, + "no PyNode definition found in the script!"); + return NULL; +} + static int node_dynamic_parse(struct bNode *node) { PyObject *dict= NULL; - PyObject *key= NULL; - PyObject *value= NULL; + PyObject *pynode_data= NULL; PyObject *pynode= NULL; PyObject *args= NULL; NodeScriptDict *nsd = NULL; PyObject *pyresult = NULL; char *buf = NULL; - Py_ssize_t pos = 0; int is_valid_script = 0; PyGILState_STATE gilstate; @@ -346,7 +401,7 @@ static int node_dynamic_parse(struct bNode *node) MEM_freeN(buf); if (!pyresult) { - node_dynamic_disable(node); + node_dynamic_disable_all_by_id(node->id); node_dynamic_pyerror_print(node); PyGILState_Release(gilstate); return -1; @@ -354,58 +409,46 @@ static int node_dynamic_parse(struct bNode *node) Py_DECREF(pyresult); - while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) { - /* look for the node object */ - if (strcmp("Socket", PyString_AsString(key)) == 0) - continue; /* XXX ugly, fix it */ - if (PyObject_TypeCheck(value, &PyType_Type)==1) { - BPy_NodeSocketLists *socklists = Node_CreateSocketLists(node); + pynode_data = node_dynamic_get_pynode(dict); - args = Py_BuildValue("(O)", socklists); + if (pynode_data) { + BPy_NodeSocketLists *socklists = Node_CreateSocketLists(node); - /* init it to get the input and output sockets */ - pynode = PyObject_Call(value, args, NULL); + args = Py_BuildValue("(O)", socklists); - Py_DECREF(socklists); - Py_DECREF(args); + /* init it to get the input and output sockets */ + pynode = PyObject_Call(pynode_data, args, NULL); - if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) { - InitNode((BPy_Node *)(pynode), node); - nsd->node = pynode; - node->typeinfo->execfunc = node_dynamic_exec_cb; - is_valid_script = 1; - - /* for NEW, LOADED, REPARSE */ - if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) { - node->typeinfo->pydict = dict; - node->typeinfo->pynode = pynode; - node->typeinfo->id = node->id; - if (BNTST(node->custom1, NODE_DYNAMIC_LOADED)) - nodeAddSockets(node, node->typeinfo); - if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) { - nodeRegisterType(&node_all_shaders, node->typeinfo); - /* nodeRegisterType copied it to a new one, so we - * free the typeinfo itself, but not what it - * points to: */ - MEM_freeN(node->typeinfo); - node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id); - MEM_freeN(node->typeinfo->name); - node->typeinfo->name = BLI_strdup(node->name); - } - } + Py_DECREF(pynode_data); + Py_DECREF(socklists); + Py_DECREF(args); + + if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) { + InitNode((BPy_Node *)(pynode), node); + nsd->node = pynode; + node->typeinfo->execfunc = node_dynamic_exec_cb; + is_valid_script = 1; - node->custom1 = 0; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); - break; + /* for NEW, LOADED, REPARSE */ + if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) { + node->typeinfo->pydict = dict; + node->typeinfo->pynode = pynode; + node->typeinfo->id = node->id; + if (BNTST(node->custom1, NODE_DYNAMIC_LOADED)) + nodeAddSockets(node, node->typeinfo); + if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) + node_dynamic_register_type(node); } - //break; + + node->custom1 = 0; + node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); } } PyGILState_Release(gilstate); if (!is_valid_script) { /* not a valid pynode script */ - node_dynamic_disable(node); + node_dynamic_disable_all_by_id(node->id); node_dynamic_pyerror_print(node); return -1; } @@ -470,6 +513,7 @@ static void node_dynamic_setup(bNode *node) else { nodeMakeDynamicType(node); } } else { + node_dynamic_rem_all_links(node->typeinfo); node_dynamic_free_typeinfo_sockets(node->typeinfo); node_dynamic_update_socket_links(node, NULL); node_dynamic_free_storage_cb(node); -- cgit v1.2.3 From 5ad6b3f8dda50f86a5441b48539643a00a8914b8 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Fri, 2 May 2008 20:41:33 +0000 Subject: == PyNodes == More bug fixing, reports by Juho (bebraw) Vepsalainen (thanks!) #10340: a recent fix I made broke handling of pynodes with buggy scripts when loaded from a .blend. (This may have been the reason for #10341, too, caused by saving buggy typeinfo.) http://projects.blender.org/tracker/?func=detail&atid=125&aid=10340&group_id=9 --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 37bbb68ba03..78f780c43b1 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -160,11 +160,11 @@ static void node_dynamic_free_storage_cb(bNode *node) } /* Disable pynode when its script fails */ -/*static void node_dynamic_disable(bNode *node) +static void node_dynamic_disable(bNode *node) { node->custom1 = 0; node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR); -}*/ +} /* Disable all pynodes using the given text (script) id */ static void node_dynamic_disable_all_by_id(ID *id) @@ -401,7 +401,11 @@ static int node_dynamic_parse(struct bNode *node) MEM_freeN(buf); if (!pyresult) { + if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) { + node_dynamic_disable(node); + } else { node_dynamic_disable_all_by_id(node->id); + } node_dynamic_pyerror_print(node); PyGILState_Release(gilstate); return -1; -- cgit v1.2.3 From ad38297a08b3f6901bfdefdca56b1f0e4f8ac58d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 8 May 2008 19:57:10 +0000 Subject: Fix for bug #11005: hue-sat-value node was doing unnecessary clamping, which not only is suboptimal for working with hdr images, it was also doing the clamping incorrect. --- source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c | 2 -- source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c b/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c index eeddb4ce756..92614d1cc6a 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c @@ -52,9 +52,7 @@ static void do_hue_sat_fac(bNode *node, float *out, float *in, float *fac) hsv[0]+= (nhs->hue - 0.5f); if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; hsv[1]*= nhs->sat; - if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; hsv[2]*= nhs->val; - if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0; hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); out[0]= mfac*in[0] + *fac*col[0]; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c index 8c07a2d1dc8..67dfc619080 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c @@ -54,9 +54,7 @@ static void do_hue_sat_fac(bNode *node, float *out, float *hue, float *sat, floa hsv[0]+= (*hue - 0.5f); if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; hsv[1]*= *sat; - if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; hsv[2]*= *val; - if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0; hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); out[0]= mfac*in[0] + *fac*col[0]; -- cgit v1.2.3 From 90420a15efb3117ce6a770c94207816531b2777b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 May 2008 15:32:55 +0000 Subject: Fix for bug #7068: displace node crashes with procedural texture input as vectors. --- .../blender/nodes/intern/CMP_nodes/CMP_displace.c | 58 +++++++++++++--------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c index 67b04750056..f5b6edcea80 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c @@ -44,18 +44,22 @@ static bNodeSocketType cmp_node_displace_out[]= { { -1, 0, "" } }; +static float *vecbuf_get_pixel(CompBuf *vecbuf, float *veccol, int x, int y) +{ + /* the x-xrad stuff is a bit weird, but i seem to need it otherwise + * my returned pixels are offset weirdly */ + return compbuf_get_pixel(vecbuf, veccol, x-vecbuf->xrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad); +} + static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *veccol, float *xscale, float *yscale) { ImBuf *ibuf; - int x, y, vx, vy, sx, sy; float dx=0.0, dy=0.0; float dspx, dspy; - float uv[2]; - - float *out= stackbuf->rect, *vec=vecbuf->rect, *in= cbuf->rect; + float uv[2], col[4], colnext[4], colprev[4]; float *vp, *vpnext, *vpprev; - - int row = 3*vecbuf->x; + float *out= stackbuf->rect, *vec=vecbuf->rect, *in= cbuf->rect; + int x, y, vx, vy, sx, sy; /* ibuf needed for sampling */ ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0, 0); @@ -65,13 +69,15 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float sx= stackbuf->x; sy= stackbuf->y; + + QUATCOPY(col, veccol); + QUATCOPY(colnext, veccol); + QUATCOPY(colprev, veccol); for(y=0; yxrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad); + vp = vecbuf_get_pixel(vecbuf, col, x, y); /* this happens in compbuf_get_pixel, need to make sure the following * check takes them into account */ @@ -87,20 +93,26 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float uv[1] = dspy / (float)sy; if(vx>0 && vx< vecbuf->x-1 && vy>0 && vy< vecbuf->y-1) { - vpnext = vp+row; - vpprev = vp-row; - - /* adaptive sampling, X channel */ - dx= 0.5f*(fabs(vp[0]-vp[-3]) + fabs(vp[0]-vp[3])); - - dx+= 0.25f*(fabs(vp[0]-vpprev[-3]) + fabs(vp[0]-vpnext[-3])); - dx+= 0.25f*(fabs(vp[0]-vpprev[+3]) + fabs(vp[0]-vpnext[+3])); - - /* adaptive sampling, Y channel */ - dy= 0.5f*(fabs(vp[1]-vp[-row+1]) + fabs(vp[1]-vp[row+1])); - - dy+= 0.25f*(fabs(vp[1]-vpprev[+1-3]) + fabs(vp[1]-vpnext[+1-3])); - dy+= 0.25f*(fabs(vp[1]-vpprev[+1+3]) + fabs(vp[1]-vpnext[+1+3])); + /* adaptive sampling, X and Y channel. + * we call vecbuf_get_pixel for every pixel since the input + * might be a procedural, and then we can't use offsets */ + vpprev = vecbuf_get_pixel(vecbuf, colprev, x-1, y); + vpnext = vecbuf_get_pixel(vecbuf, colnext, x+1, y); + dx= 0.5f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0])); + + vpprev = vecbuf_get_pixel(vecbuf, colprev, x, y-1); + vpnext = vecbuf_get_pixel(vecbuf, colnext, x, y+1); + dy= 0.5f*(fabs(vp[1]-vpnext[1]) + fabs(vp[1]-vpprev[1])); + + vpprev = vecbuf_get_pixel(vecbuf, colprev, x-1, y-1); + vpnext = vecbuf_get_pixel(vecbuf, colnext, x-1, y+1); + dx+= 0.25f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0])); + dy+= 0.25f*(fabs(vp[1]-vpprev[1]) + fabs(vp[1]-vpnext[1])); + + vpprev = vecbuf_get_pixel(vecbuf, colprev, x+1, y-1); + vpnext = vecbuf_get_pixel(vecbuf, colnext, x+1, y+1); + dx+= 0.25f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0])); + dy+= 0.25f*(fabs(vp[1]-vpprev[1]) + fabs(vp[1]-vpnext[1])); /* scaled down to prevent blurriness */ /* 8: magic number, provides a good level of sharpness without getting too aliased */ -- cgit v1.2.3 From 5463828bd2f62b10640e91637942b8784a7eee5c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 22 May 2008 14:56:32 +0000 Subject: Fix for part of bug #12075: gamma node generated nan's on negative input. --- source/blender/nodes/intern/CMP_nodes/CMP_gamma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c index 6cd1c5981a6..ff9e2b716ce 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c @@ -46,7 +46,8 @@ static void do_gamma(bNode *node, float *out, float *in, float *fac) { int i=0; for(i=0; i<3; i++) { - out[i] = pow(in[i],fac[0]); + /* check for negative to avoid nan's */ + out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0]; } out[3] = in[3]; } -- cgit v1.2.3 From 5f70682f6a622b2832e50860cc2699c67d9b7e65 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Fri, 23 May 2008 16:31:02 +0000 Subject: == PyNodes == Fixing bug #11737 reported by Daniel Salazar (Zanqdo, thanks!): assigning as pynode a text that failed to parse as a pynode script, then deleting that text would crash Blender. http://projects.blender.org/tracker/?func=detail&atid=125&aid=11737&group_id=9 --- source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 78f780c43b1..49473b213ce 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -239,6 +239,27 @@ static void node_dynamic_reset(bNode *node, int unlink_text) tinfo = node->typeinfo; tinfo_default = node_dynamic_find_typeinfo(&node_all_shaders, NULL); + if ((tinfo == tinfo_default) && unlink_text) { + ID *textID = node->id; + /* already at default (empty) state, which happens if this node's + * script failed to parse at the first stage: definition. We're here + * because its text was removed from Blender. */ + for (ma= G.main->mat.first; ma; ma= ma->id.next) { + if (ma->nodetree) { + bNode *nd; + for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { + if (nd->id == textID) { + nd->id = NULL; + nd->custom1 = 0; + nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); + BLI_strncpy(nd->name, "Dynamic", 8); + return; + } + } + } + } + } + node_dynamic_rem_all_links(tinfo); node_dynamic_free_typeinfo_sockets(tinfo); -- cgit v1.2.3 From 5263021aa8608252a6db44208f2bee89bdc7e4de Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Sun, 25 May 2008 21:11:34 +0000 Subject: Commit patch #9059 by gsrb3d Unnecesary include path in Makefile. --- source/blender/nodes/intern/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 12b3616df25..7cf2411ed84 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -35,8 +35,6 @@ include nan_compile.mk CFLAGS += $(LEVEL_1_C_WARNINGS) -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I../../python CPPFLAGS += -I../../blenkernel CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../makesdna -- cgit v1.2.3 From 4c391a0c30018917f6173d1200efcb93c02211f5 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 17 Jun 2008 04:18:34 +0000 Subject: * Simple addition to math node (comp and shading): Greater Than and Less Than modes. --- source/blender/nodes/intern/CMP_nodes/CMP_math.c | 18 +++++++++++++++++- source/blender/nodes/intern/SHD_nodes/SHD_math.c | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c index e317998b5fc..d00ce18a44f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c @@ -131,7 +131,23 @@ static void do_math(bNode *node, float *out, float *in, float *in2) { out[0]= (int)(in[0] + 0.5f); } - break; + break; + case 15: /* Less Than */ + { + if( in[0] < in2[0] ) + out[0]= 1.0f; + else + out[0]= 0.0f; + } + break; + case 16: /* Greater Than */ + { + if( in[0] > in2[0] ) + out[0]= 1.0f; + else + out[0]= 0.0f; + } + break; } } diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c index 95162e508d5..2e156cf12bf 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c @@ -174,7 +174,23 @@ bNodeStack **out) else out[0]->vec[0]= (int)(in[1]->vec[0] + 0.5f); } - break; + break; + case 15: /* Less Than */ + { + if( in[0]->vec[0] < in[1]->vec[0] ) + out[0]->vec[0]= 1.0f; + else + out[0]->vec[0]= 0.0f; + } + break; + case 16: /* Greater Than */ + { + if( in[0]->vec[0] > in[1]->vec[0] ) + out[0]->vec[0]= 1.0f; + else + out[0]->vec[0]= 0.0f; + } + break; } } -- cgit v1.2.3 From a8f00246bae68a08562832fbb010ff674e293599 Mon Sep 17 00:00:00 2001 From: Juho Vepsalainen Date: Thu, 26 Jun 2008 17:08:07 +0000 Subject: Fix for bug [#13651] Convertor->Math->Divide broken Changed the if statement to catch zero case properly. --- source/blender/nodes/intern/CMP_nodes/CMP_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c index d00ce18a44f..421c1343df7 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c @@ -57,7 +57,7 @@ static void do_math(bNode *node, float *out, float *in, float *in2) break; case 3: /* Divide */ { - if(in[1]==0) /* We don't want to divide by zero. */ + if(in2[0]==0) /* We don't want to divide by zero. */ out[0]= 0.0; else out[0]= in[0] / in2[0]; -- cgit v1.2.3 From 838886daf35b791d24e18e3f039a7f9c3c8332e4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Jul 2008 10:13:09 +0000 Subject: Fix for bugfix #12075: gamma node check for nan was always checking red channel. --- source/blender/nodes/intern/CMP_nodes/CMP_gamma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c index ff9e2b716ce..e77de3726cb 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c @@ -47,7 +47,7 @@ static void do_gamma(bNode *node, float *out, float *in, float *fac) int i=0; for(i=0; i<3; i++) { /* check for negative to avoid nan's */ - out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0]; + out[i] = (in[i] > 0.0f)? pow(in[i],fac[0]): in[i]; } out[3] = in[3]; } -- cgit v1.2.3 From 846ae7a187a630e0fc413a272917c08cd9fde8af Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 25 Jul 2008 01:17:37 +0000 Subject: * Fix for bug #9450 'Problems with Extended Material node with AmbCol socket' It turns out the material AmbCol property was never working properly, or even supported in the renderer, so I've removed it. Also included is a fix to make the 'Amb' input work properly too. --- source/blender/nodes/intern/SHD_nodes/SHD_material.c | 3 --- source/blender/nodes/intern/SHD_util.c | 4 ++-- source/blender/nodes/intern/SHD_util.h | 13 ++++++------- 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c index bdceb134c0d..9396410f850 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c @@ -54,7 +54,6 @@ static bNodeSocketType sh_node_material_ext_in[]= { { SOCK_VALUE, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, { SOCK_RGBA, 1, "Mirror", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, - { SOCK_RGBA, 1, "AmbCol", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { SOCK_VALUE, 1, "Ambient", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { SOCK_VALUE, 1, "Emit", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, { SOCK_VALUE, 1, "SpecTra", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, @@ -117,8 +116,6 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, if (node->type == SH_NODE_MATERIAL_EXT) { if(in[MAT_IN_MIR]->hasinput) nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]); - if(in[MAT_IN_AMBCOL]->hasinput) - nodestack_get_vec(&shi->ambr, SOCK_VECTOR, in[MAT_IN_AMBCOL]); if(in[MAT_IN_AMB]->hasinput) nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]); if(in[MAT_IN_EMIT]->hasinput) diff --git a/source/blender/nodes/intern/SHD_util.c b/source/blender/nodes/intern/SHD_util.c index c9f58fbce49..f673834d2b7 100644 --- a/source/blender/nodes/intern/SHD_util.c +++ b/source/blender/nodes/intern/SHD_util.c @@ -164,7 +164,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto) case MAT_IN_MIR: VECCOPY(&ma->mirr, sock->ns.vec); break; case MAT_IN_AMB: - VECCOPY(&ma->ambr, sock->ns.vec); break; + ma->amb= sock->ns.vec[0]; break; case MAT_IN_EMIT: ma->emit= sock->ns.vec[0]; break; case MAT_IN_SPECTRA: @@ -188,7 +188,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto) case MAT_IN_MIR: VECCOPY(sock->ns.vec, &ma->mirr); break; case MAT_IN_AMB: - VECCOPY(sock->ns.vec, &ma->ambr); break; + sock->ns.vec[0]= ma->amb; break; case MAT_IN_EMIT: sock->ns.vec[0]= ma->emit; break; case MAT_IN_SPECTRA: diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/intern/SHD_util.h index f75802b7c15..bdb2bb3707d 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/intern/SHD_util.h @@ -117,13 +117,12 @@ typedef struct ShaderCallData { #define MAT_IN_REFL 2 #define MAT_IN_NORMAL 3 #define MAT_IN_MIR 4 -#define MAT_IN_AMBCOL 5 -#define MAT_IN_AMB 6 -#define MAT_IN_EMIT 7 -#define MAT_IN_SPECTRA 8 -#define MAT_IN_RAY_MIRROR 9 -#define MAT_IN_ALPHA 10 -#define MAT_IN_TRANSLUCENCY 11 +#define MAT_IN_AMB 5 +#define MAT_IN_EMIT 6 +#define MAT_IN_SPECTRA 7 +#define MAT_IN_RAY_MIRROR 8 +#define MAT_IN_ALPHA 9 +#define MAT_IN_TRANSLUCENCY 10 /* output socket defines */ #define MAT_OUT_COLOR 0 -- cgit v1.2.3 From cb89decfdcf5e6b2f26376d416633f4ccf0c532d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 4 Sep 2008 20:51:28 +0000 Subject: Merge of first part of changes from the apricot branch, especially the features that are needed to run the game. Compile tested with scons, make, but not cmake, that seems to have an issue not related to these changes. The changes include: * GLSL support in the viewport and game engine, enable in the game menu in textured draw mode. * Synced and merged part of the duplicated blender and gameengine/ gameplayer drawing code. * Further refactoring of game engine drawing code, especially mesh storage changed a lot. * Optimizations in game engine armatures to avoid recomputations. * A python function to get the framerate estimate in game. * An option take object color into account in materials. * An option to restrict shadow casters to a lamp's layers. * Increase from 10 to 18 texture slots for materials, lamps, word. An extra texture slot shows up once the last slot is used. * Memory limit for undo, not enabled by default yet because it needs the .B.blend to be changed. * Multiple undo for image painting. * An offset for dupligroups, so not all objects in a group have to be at the origin. --- source/blender/nodes/CMakeLists.txt | 2 +- source/blender/nodes/SConscript | 1 + source/blender/nodes/intern/CMP_nodes/Makefile | 1 + source/blender/nodes/intern/Makefile | 2 + source/blender/nodes/intern/SHD_nodes/Makefile | 2 + source/blender/nodes/intern/SHD_nodes/SHD_camera.c | 10 ++- source/blender/nodes/intern/SHD_nodes/SHD_curves.c | 24 ++++++- source/blender/nodes/intern/SHD_nodes/SHD_geom.c | 16 ++++- .../blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c | 9 ++- source/blender/nodes/intern/SHD_nodes/SHD_invert.c | 8 ++- .../blender/nodes/intern/SHD_nodes/SHD_mapping.c | 17 ++++- .../blender/nodes/intern/SHD_nodes/SHD_material.c | 79 ++++++++++++++++++++-- source/blender/nodes/intern/SHD_nodes/SHD_math.c | 43 +++++++++++- source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c | 14 +++- source/blender/nodes/intern/SHD_nodes/SHD_normal.c | 11 ++- source/blender/nodes/intern/SHD_nodes/SHD_output.c | 16 ++++- source/blender/nodes/intern/SHD_nodes/SHD_rgb.c | 11 ++- .../nodes/intern/SHD_nodes/SHD_sepcombRGB.c | 16 ++++- .../blender/nodes/intern/SHD_nodes/SHD_squeeze.c | 8 ++- .../blender/nodes/intern/SHD_nodes/SHD_texture.c | 17 ++++- .../blender/nodes/intern/SHD_nodes/SHD_valToRgb.c | 20 +++++- source/blender/nodes/intern/SHD_nodes/SHD_value.c | 9 ++- .../blender/nodes/intern/SHD_nodes/SHD_vectMath.c | 31 ++++++++- source/blender/nodes/intern/SHD_util.h | 2 + 24 files changed, 343 insertions(+), 26 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 2cb855ed440..cf83804b999 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -30,7 +30,7 @@ SET(INC ../python ../render/extern/include ../../../intern/decimation/extern ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/iksolver/extern ../blenloader ../quicktime - ../blenkernel + ../blenkernel ../../../extern/glew/include ../gpu ${SDL_INC} ${ZLIB_INC} ${PYTHON_INC} diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 8682f626b80..8af7b67520e 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -11,6 +11,7 @@ incs += ' ../python ../render/extern/include ' incs += ' ../imbuf ../avi ' incs += ' ../blenloader ../quicktime' incs += ' ../blenkernel ../renderconverter ' +incs += ' ../gpu #/extern/glew/include ' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/blender/nodes/intern/CMP_nodes/Makefile b/source/blender/nodes/intern/CMP_nodes/Makefile index 61b03f237db..8a8d323ac5b 100644 --- a/source/blender/nodes/intern/CMP_nodes/Makefile +++ b/source/blender/nodes/intern/CMP_nodes/Makefile @@ -42,4 +42,5 @@ CPPFLAGS += -I../../../blenlib CPPFLAGS += -I../../../include CPPFLAGS += -I../../../imbuf CPPFLAGS += -I../../../render/extern/include +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile index 7cf2411ed84..6167cf6bc72 100644 --- a/source/blender/nodes/intern/Makefile +++ b/source/blender/nodes/intern/Makefile @@ -42,4 +42,6 @@ CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../include CPPFLAGS += -I../../imbuf CPPFLAGS += -I../../render/extern/include +CPPFLAGS += -I../../gpu +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) diff --git a/source/blender/nodes/intern/SHD_nodes/Makefile b/source/blender/nodes/intern/SHD_nodes/Makefile index 1917e9ba15c..ae3cae029d2 100644 --- a/source/blender/nodes/intern/SHD_nodes/Makefile +++ b/source/blender/nodes/intern/SHD_nodes/Makefile @@ -44,4 +44,6 @@ CPPFLAGS += -I../../../blenlib CPPFLAGS += -I../../../include CPPFLAGS += -I../../../imbuf CPPFLAGS += -I../../../render/extern/include +CPPFLAGS += -I../../../gpu +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_camera.c b/source/blender/nodes/intern/SHD_nodes/SHD_camera.c index 63260ff91ed..20136d75540 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_camera.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_camera.c @@ -46,8 +46,13 @@ static void node_shader_exec_camera(void *data, bNode *node, bNodeStack **in, bN VECCOPY(out[0]->vec, shi->co); /* get view vector */ out[1]->vec[0]= fabs(shi->co[2]); /* get view z-depth */ out[2]->vec[0]= Normalize(out[0]->vec); /* get view distance */ - } } +} + +static int gpu_shader_camera(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "camera", in, out, GPU_builtin(GPU_VIEW_POSITION)); +} bNodeType sh_node_camera= { /* *next,*prev */ NULL, NULL, @@ -63,6 +68,7 @@ bNodeType sh_node_camera= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_camera }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_curves.c b/source/blender/nodes/intern/SHD_nodes/SHD_curves.c index b6f1f8d52cd..d277547b636 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_curves.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_curves.c @@ -56,6 +56,15 @@ static void node_shader_init_curve_vec(bNode* node) node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); } +static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + float *array; + int size; + + curvemapping_table_RGBA(node->storage, &array, &size); + return GPU_stack_link(mat, "curves_vec", in, out, GPU_texture(size, array)); +} + bNodeType sh_node_curve_vec= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_CURVE_VEC, @@ -70,7 +79,8 @@ bNodeType sh_node_curve_vec= { /* initfunc */ node_shader_init_curve_vec, /* freestoragefunc */ node_free_curves, /* copystoragefunc */ node_copy_curves, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_curve_vec }; @@ -100,6 +110,15 @@ static void node_shader_init_curve_rgb(bNode *node) node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } +static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + float *array; + int size; + + curvemapping_table_RGBA(node->storage, &array, &size); + return GPU_stack_link(mat, "curves_rgb", in, out, GPU_texture(size, array)); +} + bNodeType sh_node_curve_rgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_CURVE_RGB, @@ -114,6 +133,7 @@ bNodeType sh_node_curve_rgb= { /* initfunc */ node_shader_init_curve_rgb, /* freestoragefunc */ node_free_curves, /* copystoragefunc */ node_copy_curves, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_curve_rgb }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c b/source/blender/nodes/intern/SHD_nodes/SHD_geom.c index 24395059c60..bc345759b98 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_geom.c @@ -29,6 +29,7 @@ #include "../SHD_util.h" +#include "DNA_customdata_types.h" /* **************** GEOMETRY ******************** */ @@ -124,6 +125,18 @@ static void node_shader_init_geometry(bNode *node) node->storage= MEM_callocN(sizeof(NodeGeometry), "NodeGeometry"); } +static int gpu_shader_geom(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + NodeGeometry *ngeo= (NodeGeometry*)node->storage; + GPUNodeLink *orco = GPU_attribute(CD_ORCO, ""); + GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ngeo->uvname); + GPUNodeLink *mcol = GPU_attribute(CD_MCOL, ngeo->colname); + + return GPU_stack_link(mat, "geom", in, out, + GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface, mcol); +} + /* node type definition */ bNodeType sh_node_geom= { /* *next,*prev */ NULL, NULL, @@ -139,6 +152,7 @@ bNodeType sh_node_geom= { /* initfunc */ node_shader_init_geometry, /* freestoragefunc */ node_free_standard_storage, /* copystoragefunc */ node_copy_standard_storage, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_geom }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c index 67dfc619080..1b7b2dfb8e7 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c @@ -71,6 +71,12 @@ static void node_shader_exec_hue_sat(void *data, bNode *node, bNodeStack **in, b do_hue_sat_fac(node, out[0]->vec, in[0]->vec, in[1]->vec, in[2]->vec, in[4]->vec, in[3]->vec); } + +static int gpu_shader_hue_sat(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "hue_sat", in, out); +} + bNodeType sh_node_hue_sat= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_HUE_SAT, @@ -85,7 +91,8 @@ bNodeType sh_node_hue_sat= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_hue_sat }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c b/source/blender/nodes/intern/SHD_nodes/SHD_invert.c index 4d1ce282fce..72ee1483ecf 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_invert.c @@ -64,6 +64,11 @@ bNodeStack **out) VECCOPY(out[0]->vec, col); } +static int gpu_shader_invert(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "invert", in, out); +} + bNodeType sh_node_invert= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_INVERT, @@ -78,6 +83,7 @@ bNodeType sh_node_invert= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_invert }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c b/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c index 589954c8f7b..c081929a2fc 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_mapping.c @@ -69,6 +69,20 @@ static void node_shader_init_mapping(bNode *node) node->storage= add_mapping(); } +static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + TexMapping *texmap= node->storage; + float domin= (texmap->flag & TEXMAP_CLIP_MIN) != 0; + float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0; + GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat); + GPUNodeLink *tmin = GPU_uniform(texmap->min); + GPUNodeLink *tmax = GPU_uniform(texmap->max); + GPUNodeLink *tdomin = GPU_uniform(&domin); + GPUNodeLink *tdomax = GPU_uniform(&domax); + + return GPU_stack_link(mat, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax); +} + bNodeType sh_node_mapping= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_MAPPING, @@ -83,7 +97,8 @@ bNodeType sh_node_mapping= { /* initfunc */ node_shader_init_mapping, /* freestoragefunc */ node_free_standard_storage, /* copystoragefunc */ node_copy_standard_storage, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_mapping }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c index 9396410f850..c0a2534ac4a 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c @@ -182,6 +182,77 @@ static void node_shader_init_material(bNode* node) node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC; } +static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + if(node->id) { + GPUShadeInput shi; + GPUShadeResult shr; + + GPU_shadeinput_set(mat, (Material*)node->id, &shi); + + /* write values */ + if(in[MAT_IN_COLOR].hasinput) + shi.rgb = in[MAT_IN_COLOR].link; + + if(in[MAT_IN_SPEC].hasinput) + shi.specrgb = in[MAT_IN_SPEC].link; + + if(in[MAT_IN_REFL].hasinput) + shi.refl = in[MAT_IN_REFL].link; + + /* retrieve normal */ + if(in[MAT_IN_NORMAL].hasinput) { + GPUNodeLink *tmp; + shi.vn = in[MAT_IN_NORMAL].link; + GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp); + } + + /* custom option to flip normal */ + if(node->custom1 & SH_NODE_MAT_NEG) + GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); + + if (node->type == SH_NODE_MATERIAL_EXT) { + if(in[MAT_IN_AMB].hasinput) + shi.amb= in[MAT_IN_AMB].link; + if(in[MAT_IN_EMIT].hasinput) + shi.emit= in[MAT_IN_EMIT].link; + if(in[MAT_IN_ALPHA].hasinput) + shi.alpha= in[MAT_IN_ALPHA].link; + } + + GPU_shaderesult_set(&shi, &shr); /* clears shr */ + + /* write to outputs */ + if(node->custom1 & SH_NODE_MAT_DIFF) { + if(node->custom1 & SH_NODE_MAT_SPEC) + out[MAT_OUT_COLOR].link= shr.combined; + else + out[MAT_OUT_COLOR].link= shr.diff; + } + else if(node->custom1 & SH_NODE_MAT_SPEC) { + out[MAT_OUT_COLOR].link= shr.spec; + } + else + GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link); + + GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link); + + out[MAT_OUT_ALPHA].link = shr.alpha; // + + if(node->custom1 & SH_NODE_MAT_NEG) + GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); + out[MAT_OUT_NORMAL].link = shi.vn; + + if (node->type == SH_NODE_MATERIAL_EXT) { + out[MAT_OUT_DIFFUSE].link = shr.diff; + out[MAT_OUT_SPEC].link = shr.spec; + } + + return 1; + } + + return 0; +} bNodeType sh_node_material= { /* *next,*prev */ NULL, NULL, @@ -197,8 +268,8 @@ bNodeType sh_node_material= { /* initfunc */ node_shader_init_material, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL - + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_material }; bNodeType sh_node_material_ext= { @@ -215,7 +286,7 @@ bNodeType sh_node_material_ext= { /* initfunc */ node_shader_init_material, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL - + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_material }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c index 2e156cf12bf..050c2cdcc95 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c @@ -194,6 +194,46 @@ bNodeStack **out) } } +static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + static char *names[] = {"math_add", "math_subtract", "math_multiply", + "math_divide", "math_sine", "math_cosine", "math_tangnet", "math_asin", + "math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max", + "math_round", "math_less_than", "math_greater_than"}; + + switch (node->custom1) { + case 0: + case 1: + case 2: + case 3: + case 10: + case 11: + case 12: + case 13: + case 15: + case 16: + GPU_stack_link(mat, names[node->custom1], NULL, out, + GPU_socket(&in[0]), GPU_socket(&in[1])); + break; + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 14: + if(in[0].hasinput || !in[1].hasinput) + GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0])); + else + GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1])); + break; + default: + return 0; + } + + return 1; +} + bNodeType sh_node_math= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_MATH, @@ -208,6 +248,7 @@ bNodeType sh_node_math= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_math }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c b/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c index dba70253fda..2da1dee5623 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_mixRgb.c @@ -60,6 +60,17 @@ static void node_shader_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, b VECCOPY(out[0]->vec, col); } +static int gpu_shader_mix_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + static char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub", + "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light", + "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat", + "mix_val", "mix_color"}; + + return GPU_stack_link(mat, names[node->custom1], in, out); +} + + bNodeType sh_node_mix_rgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_MIX_RGB, @@ -74,6 +85,7 @@ bNodeType sh_node_mix_rgb= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_mix_rgb }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_normal.c b/source/blender/nodes/intern/SHD_nodes/SHD_normal.c index f1ffd3446af..9d4ea1ccf67 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_normal.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_normal.c @@ -57,6 +57,14 @@ static void node_shader_exec_normal(void *data, bNode *node, bNodeStack **in, bN out[1]->vec[0]= -INPR(out[0]->vec, vec); } +static int gpu_shader_normal(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + bNodeSocket *sock= node->outputs.first; + GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + + return GPU_stack_link(mat, "normal", in, out, vec); +} + bNodeType sh_node_normal= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_NORMAL, @@ -71,6 +79,7 @@ bNodeType sh_node_normal= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_normal }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_output.c b/source/blender/nodes/intern/SHD_nodes/SHD_output.c index 0a9a30c452b..76856cfd2e8 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_output.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_output.c @@ -62,6 +62,19 @@ static void node_shader_exec_output(void *data, bNode *node, bNodeStack **in, bN } } +static int gpu_shader_output(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + GPUNodeLink *outlink; + + /*if(in[1].hasinput) + GPU_material_enable_alpha(mat);*/ + + GPU_stack_link(mat, "output_node", in, out, &outlink); + GPU_material_output_link(mat, outlink); + + return 1; +} + bNodeType sh_node_output= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_OUTPUT, @@ -76,7 +89,8 @@ bNodeType sh_node_output= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_output }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c b/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c index 4e56e26d3ad..1aa1a2ffc33 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_rgb.c @@ -42,6 +42,14 @@ static void node_shader_exec_rgb(void *data, bNode *node, bNodeStack **in, bNode VECCOPY(out[0]->vec, sock->ns.vec); } +static int gpu_shader_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + bNodeSocket *sock= node->outputs.first; + GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + + return GPU_stack_link(mat, "set_rgba", in, out, vec); +} + bNodeType sh_node_rgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_RGB, @@ -56,6 +64,7 @@ bNodeType sh_node_rgb= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_rgb }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c b/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c index 2b52a8e2229..6d5df2a1321 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c @@ -48,6 +48,11 @@ static void node_shader_exec_seprgb(void *data, bNode *node, bNodeStack **in, bN out[2]->vec[0] = in[0]->vec[2]; } +static int gpu_shader_seprgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "separate_rgb", in, out); +} + bNodeType sh_node_seprgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_SEPRGB, @@ -62,7 +67,8 @@ bNodeType sh_node_seprgb= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_seprgb }; @@ -86,6 +92,11 @@ static void node_shader_exec_combrgb(void *data, bNode *node, bNodeStack **in, b out[0]->vec[2] = in[2]->vec[0]; } +static int gpu_shader_combrgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "combine_rgb", in, out); +} + bNodeType sh_node_combrgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_COMBRGB, @@ -100,6 +111,7 @@ bNodeType sh_node_combrgb= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_combrgb }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c b/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c index 30abad666c4..d3480a6ae9d 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_squeeze.c @@ -54,6 +54,11 @@ bNodeStack **out) out[0]->vec[0] = 1.0f / (1.0f + pow(2.71828183,-((vec[0]-vec[2])*vec[1]))) ; } +static int gpu_shader_squeeze(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "squeeze", in, out); +} + bNodeType sh_node_squeeze= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_SQUEEZE, @@ -68,6 +73,7 @@ bNodeType sh_node_squeeze= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_squeeze }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c index ace11a20d42..31dbde940fd 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c @@ -27,6 +27,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "DNA_texture_types.h" + #include "../SHD_util.h" /* **************** TEXTURE ******************** */ @@ -110,6 +112,18 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b } } +static int gpu_shader_texture(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + Tex *tex = (Tex*)node->id; + + if(tex && tex->type == TEX_IMAGE && tex->ima) { + GPUNodeLink *texlink = GPU_image(tex->ima, NULL); + return GPU_stack_link(mat, "texture_image", in, out, texlink); + } + else + return 0; +} + bNodeType sh_node_texture= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_TEXTURE, @@ -124,7 +138,8 @@ bNodeType sh_node_texture= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_texture }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c b/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c index cf7e33d9dca..301c0cb7031 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_valToRgb.c @@ -59,6 +59,15 @@ static void node_shader_init_valtorgb(bNode *node) node->storage= add_colorband(1); } +static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + float *array; + int size; + + colorband_table_RGBA(node->storage, &array, &size); + return GPU_stack_link(mat, "valtorgb", in, out, GPU_texture(size, array)); +} + bNodeType sh_node_valtorgb= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_VALTORGB, @@ -73,7 +82,8 @@ bNodeType sh_node_valtorgb= { /* initfunc */ node_shader_init_valtorgb, /* freestoragefunc */ node_free_standard_storage, /* copystoragefunc */ node_copy_standard_storage, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_valtorgb }; @@ -96,6 +106,11 @@ static void node_shader_exec_rgbtobw(void *data, bNode *node, bNodeStack **in, b out[0]->vec[0]= in[0]->vec[0]*0.35f + in[0]->vec[1]*0.45f + in[0]->vec[2]*0.2f; } +static int gpu_shader_rgbtobw(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "rgbtobw", in, out); +} + bNodeType sh_node_rgbtobw= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_RGBTOBW, @@ -110,7 +125,8 @@ bNodeType sh_node_rgbtobw= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_rgbtobw }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_value.c b/source/blender/nodes/intern/SHD_nodes/SHD_value.c index 57ef7226066..768ef3cda3d 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_value.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_value.c @@ -42,7 +42,13 @@ static void node_shader_exec_value(void *data, bNode *node, bNodeStack **in, bNo out[0]->vec[0]= sock->ns.vec[0]; } +static int gpu_shader_value(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + bNodeSocket *sock= node->outputs.first; + GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + return GPU_stack_link(mat, "set_value", in, out, vec); +} bNodeType sh_node_value= { /* *next,*prev */ NULL, NULL, @@ -58,7 +64,8 @@ bNodeType sh_node_value= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_value }; diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c index 8d0a4b3abe3..96db8db18a6 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_vectMath.c @@ -99,6 +99,34 @@ static void node_shader_exec_vect_math(void *data, bNode *node, bNodeStack **in, } +static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + static char *names[] = {"vec_math_add", "vec_math_subtract", + "vec_math_average", "vec_math_dot", "vec_math_cross", + "vec_math_normalize"}; + + switch (node->custom1) { + case 0: + case 1: + case 2: + case 3: + case 4: + GPU_stack_link(mat, names[node->custom1], NULL, out, + GPU_socket(&in[0]), GPU_socket(&in[1])); + break; + case 5: + if(in[0].hasinput || !in[1].hasinput) + GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0])); + else + GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1])); + break; + default: + return 0; + } + + return 1; +} + bNodeType sh_node_vect_math= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_VECT_MATH, @@ -113,6 +141,7 @@ bNodeType sh_node_vect_math= { /* initfunc */ NULL, /* freestoragefunc */ NULL, /* copystoragefunc */ NULL, - /* id */ NULL + /* id */ NULL, NULL, NULL, + /* gpufunc */ gpu_shader_vect_math }; diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/intern/SHD_util.h index bdb2bb3707d..eda985529c1 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/intern/SHD_util.h @@ -88,6 +88,8 @@ #include "RE_pipeline.h" #include "RE_shader_ext.h" +#include "GPU_material.h" + #include "butspace.h" #include "blendef.h" #include "mydevice.h" -- cgit v1.2.3 From 70be839859852f9fcf3ab234093c390d5b2c9c05 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 9 Sep 2008 10:16:09 +0000 Subject: Bugfix #13837 Tonemap didn't correctly accept any buffer type. The coder who added this should check this fix! Any node coder maybe... --- source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c index 5e1803a6774..950ad97a397 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c @@ -130,13 +130,16 @@ static void node_composit_exec_tonemap(void *data, bNode *node, bNodeStack **in, if ((img==NULL) || (out[0]->hasoutput==0)) return; if (img->type != CB_RGBA) - new = typecheck_compbuf(img, CB_RGBA); - else - new = dupalloc_compbuf(img); + img = typecheck_compbuf(img, CB_RGBA); + + new = dupalloc_compbuf(img); tonemap(node->storage, new, img); out[0]->data = new; + + if(img!=in[0]->data) + free_compbuf(img); } static void node_composit_init_tonemap(bNode* node) -- cgit v1.2.3 From 2ecf987dc665eff477fb03a0cef0b2972e4b78d2 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 22 Oct 2008 11:28:10 +0000 Subject: * Minor cleanup of SCons files - cleanup of boolean usage - use True and False now instead of 'true'/'false' or 0/1 - changed SConscripts accordingly --- source/blender/nodes/SConscript | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 8af7b67520e..f80f4b521db 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -31,14 +31,14 @@ if env['WITH_BF_VERSE']: if env['WITH_BF_VERSE']: defs += ' WITH_VERSE' -if env['WITH_BF_OPENEXR'] == 1: +if env['WITH_BF_OPENEXR']: defs += ' WITH_OPENEXR' -if env['WITH_BF_FFMPEG'] == 1: +if env['WITH_BF_FFMPEG']: defs += ' WITH_FFMPEG' incs += ' ' + env['BF_FFMPEG_INC'] -if env['WITH_BF_QUICKTIME'] == 1: +if env['WITH_BF_QUICKTIME']: defs += ' WITH_QUICKTIME' incs += ' ' + env['BF_QUICKTIME_INC'] -- cgit v1.2.3 From ac4ff83ca6b5795f4451a7e743d3975aeb17ae3b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 28 Oct 2008 18:47:13 +0000 Subject: added scons option BF_WITH_PYTHON (defined as DISABLE_PYTHON) --- source/blender/nodes/SConscript | 5 +++- .../blender/nodes/intern/SHD_nodes/SHD_dynamic.c | 30 ++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index f80f4b521db..038ce4b749e 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -21,8 +21,11 @@ incs += ' ' + env['BF_SDL_INC'] defs = '' +if not env['WITH_BF_PYTHON']: + defs += 'DISABLE_PYTHON' + if env['WITH_BF_INTERNATIONAL']: - defs += 'WITH_FREETYPE2' + defs += ' WITH_FREETYPE2' if env['WITH_BF_VERSE']: defs += ' WITH_VERSE' diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 49473b213ce..2065ac2ed33 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -27,17 +27,21 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef DISABLE_PYTHON #include #include #include +#endif #include "DNA_text_types.h" #include "BKE_text.h" #include "BKE_utildefines.h" +#ifndef DISABLE_PYTHON #include "api2_2x/Node.h" #include "api2_2x/gen_utils.h" #include "BPY_extern.h" +#endif #include "../SHD_util.h" @@ -45,6 +49,7 @@ static void node_dynamic_setup(bNode *node); static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out); static void node_dynamic_free_storage_cb(bNode *node); +#ifndef DISABLE_PYTHON static PyObject *init_dynamicdict(void) { PyObject *newscriptdict; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -58,6 +63,7 @@ static PyObject *init_dynamicdict(void) { return newscriptdict; } +#endif static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id) { @@ -140,12 +146,12 @@ static void node_dynamic_update_socket_links(bNode *node, bNodeTree *ntree) static void node_dynamic_free_storage_cb(bNode *node) { +#ifndef DISABLE_PYTHON NodeScriptDict *nsd; PyObject *pydict; BPy_Node *pynode; if (!node->storage) return; - nsd = (NodeScriptDict *)(node->storage); pydict = nsd->dict; if (pydict) { @@ -155,6 +161,7 @@ static void node_dynamic_free_storage_cb(bNode *node) if (pynode) { Py_DECREF(pynode); } +#endif MEM_freeN(node->storage); node->storage = NULL; } @@ -169,6 +176,7 @@ static void node_dynamic_disable(bNode *node) /* Disable all pynodes using the given text (script) id */ static void node_dynamic_disable_all_by_id(ID *id) { +#ifndef DISABLE_PYTHON Material *ma; /* XXX hardcoded for shaders */ for (ma= G.main->mat.first; ma; ma= ma->id.next) { @@ -183,6 +191,7 @@ static void node_dynamic_disable_all_by_id(ID *id) } } } +#endif } static void node_rem_socklist_links(bNodeTree *ntree, ListBase *lb) @@ -327,6 +336,7 @@ int nodeDynamicUnlinkText(ID *txtid) { static void node_dynamic_pyerror_print(bNode *node) { +#ifndef DISABLE_PYTHON PyGILState_STATE gilstate = PyGILState_Ensure(); fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name); @@ -334,6 +344,7 @@ static void node_dynamic_pyerror_print(bNode *node) else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); } PyGILState_Release(gilstate); +#endif } static void node_dynamic_register_type(bNode *node) @@ -348,6 +359,7 @@ static void node_dynamic_register_type(bNode *node) node->typeinfo->name = BLI_strdup(node->name); } +#ifndef DISABLE_PYTHON /* node_dynamic_get_pynode: * Find the pynode definition from the script */ static PyObject *node_dynamic_get_pynode(PyObject *dict) @@ -389,9 +401,13 @@ static PyObject *node_dynamic_get_pynode(PyObject *dict) "no PyNode definition found in the script!"); return NULL; } +#endif /* DISABLE_PYTHON */ static int node_dynamic_parse(struct bNode *node) { +#ifdef DISABLE_PYTHON + return -1; +#else PyObject *dict= NULL; PyObject *pynode_data= NULL; PyObject *pynode= NULL; @@ -479,12 +495,14 @@ static int node_dynamic_parse(struct bNode *node) } return 0; +#endif } /* node_dynamic_setup: prepare for execution (state: NODE_DYNAMIC_READY) * pynodes already linked to a script (node->id != NULL). */ static void node_dynamic_setup(bNode *node) { +#ifndef DISABLE_PYTHON NodeScriptDict *nsd = NULL; bNodeTree *nodetree = NULL; bNodeType *ntype = NULL; @@ -608,7 +626,7 @@ static void node_dynamic_setup(bNode *node) node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); PyGILState_Release(gilstate); - +#endif /* DISABLE_PYTHON */ return; } @@ -641,6 +659,9 @@ static void node_dynamic_init_cb(bNode *node) { /* node_dynamic_copy_cb: pynode copy callback */ static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node) { +#ifdef DISABLE_PYTHON + return; +#else NodeScriptDict *nsd; PyGILState_STATE gilstate; @@ -657,11 +678,15 @@ static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node) Py_INCREF((PyObject *)(nsd->dict)); PyGILState_Release(gilstate); +#endif } /* node_dynamic_exec_cb: the execution callback called per pixel * during rendering. */ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { +#ifdef DISABLE_PYTHON + return; +#else BPy_Node *mynode = NULL; NodeScriptDict *nsd = NULL; PyObject *pyresult = NULL; @@ -716,6 +741,7 @@ static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNode PyGILState_Release(gilstate); } } +#endif } bNodeType node_dynamic_typeinfo = { -- cgit v1.2.3 From 483136c8e4d73fafe2b3e0953a6325107558d896 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Nov 2008 14:14:22 +0000 Subject: Adjusted scons files so disabling quicktime, python and sdl also removes their includes when building. writefile.c had usless include. --- source/blender/nodes/SConscript | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 038ce4b749e..0cfef20dae7 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -7,21 +7,21 @@ sources += env.Glob('intern/SHD_nodes/*.c') incs = '. ./intern ' incs += '#/intern/guardedalloc ../include ../blenlib ../makesdna' -incs += ' ../python ../render/extern/include ' +incs += ' ../render/extern/include ' incs += ' ../imbuf ../avi ' -incs += ' ../blenloader ../quicktime' +incs += ' ../blenloader' incs += ' ../blenkernel ../renderconverter ' incs += ' ../gpu #/extern/glew/include ' - -incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] -incs += ' ' + env['BF_SDL_INC'] defs = '' -if not env['WITH_BF_PYTHON']: +if env['WITH_BF_PYTHON']: + incs += ' ' + env['BF_PYTHON_INC'] + incs += ' ../python' +else: defs += 'DISABLE_PYTHON' if env['WITH_BF_INTERNATIONAL']: -- cgit v1.2.3