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 /* **************** Map UV ******************** */ 00036 00037 static bNodeSocketTemplate cmp_node_mapuv_in[]= { 00038 { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00039 { SOCK_VECTOR, 1, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, 00040 { -1, 0, "" } 00041 }; 00042 static bNodeSocketTemplate cmp_node_mapuv_out[]= { 00043 { SOCK_RGBA, 0, "Image"}, 00044 { -1, 0, "" } 00045 }; 00046 00047 /* foreach UV, use these values to read in cbuf and write to stackbuf */ 00048 /* stackbuf should be zeroed */ 00049 static void do_mapuv(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *uvbuf, float threshold) 00050 { 00051 ImBuf *ibuf; 00052 float *out= stackbuf->rect, *uv, *uvnext, *uvprev; 00053 float dx, dy, alpha; 00054 int x, y, sx, sy, row= 3*stackbuf->x; 00055 00056 /* ibuf needed for sampling */ 00057 ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); 00058 ibuf->rect_float= cbuf->rect; 00059 00060 /* vars for efficient looping */ 00061 uv= uvbuf->rect; 00062 uvnext= uv+row; 00063 uvprev= uv-row; 00064 sx= stackbuf->x; 00065 sy= stackbuf->y; 00066 00067 for(y=0; y<sy; y++) { 00068 for(x=0; x<sx; x++, out+=4, uv+=3, uvnext+=3, uvprev+=3) { 00069 if(x>0 && x<sx-1 && y>0 && y<sy-1) { 00070 if(uv[2]!=0.0f) { 00071 float uv_l, uv_r; 00072 00073 /* adaptive sampling, red (U) channel */ 00074 00075 /* prevent alpha zero UVs to be used */ 00076 uv_l= uv[-1]!=0.0f? fabsf(uv[0]-uv[-3]) : 0.0f; 00077 uv_r= uv[ 5]!=0.0f? fabsf(uv[0]-uv[ 3]) : 0.0f; 00078 00079 //dx= 0.5f*(fabs(uv[0]-uv[-3]) + fabs(uv[0]-uv[3])); 00080 dx= 0.5f*(uv_l + uv_r); 00081 00082 uv_l= uvprev[-1]!=0.0f? fabsf(uv[0]-uvprev[-3]) : 0.0f; 00083 uv_r= uvnext[-1]!=0.0f? fabsf(uv[0]-uvnext[-3]) : 0.0f; 00084 00085 //dx+= 0.25f*(fabs(uv[0]-uvprev[-3]) + fabs(uv[0]-uvnext[-3])); 00086 dx+= 0.25f*(uv_l + uv_r); 00087 00088 uv_l= uvprev[ 5]!=0.0f? fabsf(uv[0]-uvprev[+3]) : 0.0f; 00089 uv_r= uvnext[ 5]!=0.0f? fabsf(uv[0]-uvnext[+3]) : 0.0f; 00090 00091 //dx+= 0.25f*(fabs(uv[0]-uvprev[+3]) + fabs(uv[0]-uvnext[+3])); 00092 dx+= 0.25f*(uv_l + uv_r); 00093 00094 /* adaptive sampling, green (V) channel */ 00095 00096 uv_l= uv[-row+2]!=0.0f? fabsf(uv[1]-uv[-row+1]) : 0.0f; 00097 uv_r= uv[ row+2]!=0.0f? fabsf(uv[1]-uv[ row+1]) : 0.0f; 00098 00099 //dy= 0.5f*(fabs(uv[1]-uv[-row+1]) + fabs(uv[1]-uv[row+1])); 00100 dy= 0.5f*(uv_l + uv_r); 00101 00102 uv_l= uvprev[-1]!=0.0f? fabsf(uv[1]-uvprev[+1-3]) : 0.0f; 00103 uv_r= uvnext[-1]!=0.0f? fabsf(uv[1]-uvnext[+1-3]) : 0.0f; 00104 00105 //dy+= 0.25f*(fabs(uv[1]-uvprev[+1-3]) + fabs(uv[1]-uvnext[+1-3])); 00106 dy+= 0.25f*(uv_l + uv_r); 00107 00108 uv_l= uvprev[ 5]!=0.0f? fabsf(uv[1]-uvprev[+1+3]) : 0.0f; 00109 uv_r= uvnext[ 5]!=0.0f? fabsf(uv[1]-uvnext[+1+3]) : 0.0f; 00110 00111 //dy+= 0.25f*(fabs(uv[1]-uvprev[+1+3]) + fabs(uv[1]-uvnext[+1+3])); 00112 dy+= 0.25f*(uv_l + uv_r); 00113 00114 /* UV to alpha threshold */ 00115 alpha= 1.0f - threshold*(dx+dy); 00116 if(alpha<0.0f) alpha= 0.0f; 00117 else alpha*= uv[2]; 00118 00119 /* should use mipmap */ 00120 if(dx > 0.20f) dx= 0.20f; 00121 if(dy > 0.20f) dy= 0.20f; 00122 00123 ibuf_sample(ibuf, uv[0], uv[1], dx, dy, out); 00124 /* premul */ 00125 if(alpha<1.0f) { 00126 out[0]*= alpha; 00127 out[1]*= alpha; 00128 out[2]*= alpha; 00129 out[3]*= alpha; 00130 } 00131 } 00132 } 00133 } 00134 } 00135 00136 IMB_freeImBuf(ibuf); 00137 } 00138 00139 00140 static void node_composit_exec_mapuv(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00141 { 00142 if(out[0]->hasoutput==0) 00143 return; 00144 00145 if(in[0]->data && in[1]->data) { 00146 CompBuf *cbuf= in[0]->data; 00147 CompBuf *uvbuf= in[1]->data; 00148 CompBuf *stackbuf; 00149 00150 cbuf= typecheck_compbuf(cbuf, CB_RGBA); 00151 uvbuf= typecheck_compbuf(uvbuf, CB_VEC3); 00152 stackbuf= alloc_compbuf(uvbuf->x, uvbuf->y, CB_RGBA, 1); /* allocs */; 00153 00154 do_mapuv(stackbuf, cbuf, uvbuf, 0.05f*(float)node->custom1); 00155 00156 out[0]->data= stackbuf; 00157 00158 if(cbuf!=in[0]->data) 00159 free_compbuf(cbuf); 00160 if(uvbuf!=in[1]->data) 00161 free_compbuf(uvbuf); 00162 } 00163 } 00164 00165 void register_node_type_cmp_mapuv(bNodeTreeType *ttype) 00166 { 00167 static bNodeType ntype; 00168 00169 node_type_base(ttype, &ntype, CMP_NODE_MAP_UV, "Map UV", NODE_CLASS_DISTORT, NODE_OPTIONS); 00170 node_type_socket_templates(&ntype, cmp_node_mapuv_in, cmp_node_mapuv_out); 00171 node_type_size(&ntype, 140, 100, 320); 00172 node_type_exec(&ntype, node_composit_exec_mapuv); 00173 00174 nodeRegisterType(ttype, &ntype); 00175 }