Copying scripts from 2.4x without 2.5x changes
[blender.git] / source / blender / nodes / intern / CMP_nodes / CMP_diffMatte.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2006 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Bob Holcomb
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "../CMP_util.h"
31
32 /* ******************* channel Difference Matte ********************************* */
33 static bNodeSocketType cmp_node_diff_matte_in[]={
34         {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
35         {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
36         {-1,0,""}
37 };
38
39 static bNodeSocketType cmp_node_diff_matte_out[]={
40         {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
41         {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
42         {-1,0,""}
43 };
44
45 /* note, keyvals is passed on from caller as stack array */
46 /* might have been nicer as temp struct though... */
47 static void do_diff_matte(bNode *node, float *colorbuf, float *imbuf1, float *imbuf2)
48 {
49         NodeChroma *c= (NodeChroma *)node->storage;
50         float tolerence=c->t1;
51    float falloff=c->t2;
52         float difference;
53    float alpha;
54         
55    difference=fabs(imbuf2[0]-imbuf1[0])+
56                fabs(imbuf2[1]-imbuf1[1])+
57                fabs(imbuf2[2]-imbuf1[2]);
58
59    /*average together the distances*/
60    difference=difference/3.0;
61
62    VECCOPY(colorbuf, imbuf1);
63
64    /*make 100% transparent*/
65         if(difference < tolerence){
66       colorbuf[3]=0.0;
67         }
68    /*in the falloff region, make partially transparent */
69    else if(difference < falloff+tolerence){
70       difference=difference-tolerence;
71       alpha=difference/falloff;
72       /*only change if more transparent than before */
73       if(alpha < imbuf1[3]) {      
74          colorbuf[3]=alpha;
75       }
76       else { /* leave as before */
77          colorbuf[3]=imbuf1[3];
78       }
79    }
80         else {
81                 /*foreground object*/
82                 colorbuf[3]= imbuf1[3];
83         }
84 }
85
86 static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
87 {
88         CompBuf *outbuf;
89         CompBuf *imbuf1;
90    CompBuf *imbuf2;
91         NodeChroma *c;
92         
93         /*is anything connected?*/
94         if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
95         /*must have an image imput*/
96         if(in[0]->data==NULL) return;
97    if(in[1]->data==NULL) return;
98         
99         imbuf1=typecheck_compbuf(in[0]->data, CB_RGBA);
100    imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA);
101         
102         c=node->storage;
103         outbuf=dupalloc_compbuf(imbuf1);
104         
105         /* note, processor gets a keyvals array passed on as buffer constant */
106         composit2_pixel_processor(node, outbuf, imbuf1, in[0]->vec, imbuf2, in[1]->vec, do_diff_matte, CB_RGBA, CB_RGBA);
107         
108         out[0]->data=outbuf;
109         if(out[1]->hasoutput)
110                 out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
111         generate_preview(node, outbuf);
112
113         if(imbuf1!=in[0]->data)
114                 free_compbuf(imbuf1);
115
116         if(imbuf2!=in[1]->data)
117                 free_compbuf(imbuf2);
118 }
119
120 static void node_composit_init_diff_matte(bNode *node)
121 {
122    NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma");
123    node->storage= c;
124    c->t1= 0.1f;
125    c->t2= 0.1f;
126 }
127
128 bNodeType cmp_node_diff_matte={
129         /* *next,*prev */       NULL, NULL,
130         /* type code   */       CMP_NODE_DIFF_MATTE,
131         /* name        */       "Difference Key",
132         /* width+range */       200, 80, 250,
133         /* class+opts  */       NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS,
134         /* input sock  */       cmp_node_diff_matte_in,
135         /* output sock */       cmp_node_diff_matte_out,
136         /* storage     */       "NodeChroma",
137         /* execfunc    */       node_composit_exec_diff_matte,
138         /* butfunc     */       NULL,
139         /* initfunc    */       node_composit_init_diff_matte,
140         /* freestoragefunc    */        node_free_standard_storage,
141         /* copystoragefunc    */        node_copy_standard_storage,
142         /* id          */       NULL
143 };
144
145