Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "node_composite_util.h" 00034 00035 /* **************** FILTER ******************** */ 00036 static bNodeSocketTemplate cmp_node_filter_in[]= { 00037 { SOCK_FLOAT, 1, "Fac", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, 00038 { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00039 { -1, 0, "" } 00040 }; 00041 static bNodeSocketTemplate cmp_node_filter_out[]= { 00042 { SOCK_RGBA, 0, "Image"}, 00043 { -1, 0, "" } 00044 }; 00045 00046 static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac) 00047 { 00048 float *row1, *row2, *row3; 00049 float *fp, f1, f2, mfac= 1.0f-fac; 00050 int rowlen, x, y, c, pix= in->type; 00051 00052 rowlen= in->x; 00053 00054 for(y=0; y<in->y; y++) { 00055 /* setup rows */ 00056 if(y==0) row1= in->rect; 00057 else row1= in->rect + pix*(y-1)*rowlen; 00058 00059 row2= in->rect + y*pix*rowlen; 00060 00061 if(y==in->y-1) row3= row2; 00062 else row3= row2 + pix*rowlen; 00063 00064 fp= out->rect + pix*y*rowlen; 00065 00066 if(pix==CB_RGBA) { 00067 copy_v4_v4(fp, row2); 00068 fp+= pix; 00069 00070 for(x=2; x<rowlen; x++) { 00071 for(c=0; c<3; c++) { 00072 f1= filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]; 00073 f2= filter[0]*row1[0] + filter[3]*row1[4] + filter[6]*row1[8] + filter[1]*row2[0] + filter[4]*row2[4] + filter[7]*row2[8] + filter[2]*row3[0] + filter[5]*row3[4] + filter[8]*row3[8]; 00074 fp[0]= mfac*row2[4] + fac*sqrt(f1*f1 + f2*f2); 00075 fp++; row1++; row2++; row3++; 00076 } 00077 fp[0]= row2[4]; 00078 /* no alpha... will clear it completely */ 00079 fp++; row1++; row2++; row3++; 00080 } 00081 copy_v4_v4(fp, row2+4); 00082 } 00083 else if(pix==CB_VAL) { 00084 fp+= pix; 00085 for(x=2; x<rowlen; x++) { 00086 f1= filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2]; 00087 f2= filter[0]*row1[0] + filter[3]*row1[1] + filter[6]*row1[2] + filter[1]*row2[0] + filter[4]*row2[1] + filter[7]*row2[2] + filter[2]*row3[0] + filter[5]*row3[1] + filter[8]*row3[2]; 00088 fp[0]= mfac*row2[1] + fac*sqrt(f1*f1 + f2*f2); 00089 fp++; row1++; row2++; row3++; 00090 } 00091 } 00092 } 00093 } 00094 00095 static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac) 00096 { 00097 float *row1, *row2, *row3; 00098 float *fp, mfac= 1.0f-fac; 00099 int rowlen, x, y, c; 00100 int pixlen= in->type; 00101 00102 rowlen= in->x; 00103 00104 for(y=0; y<in->y; y++) { 00105 /* setup rows */ 00106 if(y==0) row1= in->rect; 00107 else row1= in->rect + pixlen*(y-1)*rowlen; 00108 00109 row2= in->rect + y*pixlen*rowlen; 00110 00111 if(y==in->y-1) row3= row2; 00112 else row3= row2 + pixlen*rowlen; 00113 00114 fp= out->rect + pixlen*(y)*rowlen; 00115 00116 if(pixlen==1) { 00117 fp[0]= row2[0]; 00118 fp+= 1; 00119 00120 for(x=2; x<rowlen; x++) { 00121 fp[0]= mfac*row2[1] + fac*(filter[0]*row1[0] + filter[1]*row1[1] + filter[2]*row1[2] + filter[3]*row2[0] + filter[4]*row2[1] + filter[5]*row2[2] + filter[6]*row3[0] + filter[7]*row3[1] + filter[8]*row3[2]); 00122 fp++; row1++; row2++; row3++; 00123 } 00124 fp[0]= row2[1]; 00125 } 00126 else if(pixlen==2) { 00127 fp[0]= row2[0]; 00128 fp[1]= row2[1]; 00129 fp+= 2; 00130 00131 for(x=2; x<rowlen; x++) { 00132 for(c=0; c<2; c++) { 00133 fp[0]= mfac*row2[2] + fac*(filter[0]*row1[0] + filter[1]*row1[2] + filter[2]*row1[4] + filter[3]*row2[0] + filter[4]*row2[2] + filter[5]*row2[4] + filter[6]*row3[0] + filter[7]*row3[2] + filter[8]*row3[4]); 00134 fp++; row1++; row2++; row3++; 00135 } 00136 } 00137 fp[0]= row2[2]; 00138 fp[1]= row2[3]; 00139 } 00140 else if(pixlen==3) { 00141 copy_v3_v3(fp, row2); 00142 fp+= 3; 00143 00144 for(x=2; x<rowlen; x++) { 00145 for(c=0; c<3; c++) { 00146 fp[0]= mfac*row2[3] + fac*(filter[0]*row1[0] + filter[1]*row1[3] + filter[2]*row1[6] + filter[3]*row2[0] + filter[4]*row2[3] + filter[5]*row2[6] + filter[6]*row3[0] + filter[7]*row3[3] + filter[8]*row3[6]); 00147 fp++; row1++; row2++; row3++; 00148 } 00149 } 00150 copy_v3_v3(fp, row2+3); 00151 } 00152 else { 00153 copy_v4_v4(fp, row2); 00154 fp+= 4; 00155 00156 for(x=2; x<rowlen; x++) { 00157 for(c=0; c<4; c++) { 00158 fp[0]= mfac*row2[4] + fac*(filter[0]*row1[0] + filter[1]*row1[4] + filter[2]*row1[8] + filter[3]*row2[0] + filter[4]*row2[4] + filter[5]*row2[8] + filter[6]*row3[0] + filter[7]*row3[4] + filter[8]*row3[8]); 00159 fp++; row1++; row2++; row3++; 00160 } 00161 } 00162 copy_v4_v4(fp, row2+4); 00163 } 00164 } 00165 } 00166 00167 00168 static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00169 { 00170 static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f}; 00171 float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1}; 00172 float laplace[9]= {-1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f, 1.0f, -1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f}; 00173 float sobel[9]= {1,2,1,0,0,0,-1,-2,-1}; 00174 float prewitt[9]= {1,1,1,0,0,0,-1,-1,-1}; 00175 float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2}; 00176 float shadow[9]= {1,2,1,0,1,0,-1,-2,-1}; 00177 00178 if(out[0]->hasoutput==0) return; 00179 00180 /* stack order in: Image */ 00181 /* stack order out: Image */ 00182 00183 if(in[1]->data) { 00184 /* make output size of first available input image */ 00185 CompBuf *cbuf= in[1]->data; 00186 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* allocs */ 00187 00188 /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */ 00189 stackbuf->xof= cbuf->xof; 00190 stackbuf->yof= cbuf->yof; 00191 00192 switch(node->custom1) { 00193 case CMP_FILT_SOFT: 00194 do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]); 00195 break; 00196 case CMP_FILT_SHARP: 00197 do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]); 00198 break; 00199 case CMP_FILT_LAPLACE: 00200 do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]); 00201 break; 00202 case CMP_FILT_SOBEL: 00203 do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]); 00204 break; 00205 case CMP_FILT_PREWITT: 00206 do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]); 00207 break; 00208 case CMP_FILT_KIRSCH: 00209 do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]); 00210 break; 00211 case CMP_FILT_SHADOW: 00212 do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]); 00213 break; 00214 } 00215 00216 out[0]->data= stackbuf; 00217 00218 generate_preview(data, node, out[0]->data); 00219 } 00220 } 00221 00222 00223 void register_node_type_cmp_filter(bNodeTreeType *ttype) 00224 { 00225 static bNodeType ntype; 00226 00227 node_type_base(ttype, &ntype, CMP_NODE_FILTER, "Filter", NODE_CLASS_OP_FILTER, NODE_PREVIEW|NODE_OPTIONS); 00228 node_type_socket_templates(&ntype, cmp_node_filter_in, cmp_node_filter_out); 00229 node_type_size(&ntype, 80, 40, 120); 00230 node_type_label(&ntype, node_filter_label); 00231 node_type_exec(&ntype, node_composit_exec_filter); 00232 00233 nodeRegisterType(ttype, &ntype); 00234 }