|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_mapUV.c 35237 2011-02-27 20:13:22Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 /* **************** Map UV ******************** */ 00038 00039 static bNodeSocketType cmp_node_mapuv_in[]= { 00040 { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00041 { SOCK_VECTOR, 1, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, 00042 { -1, 0, "" } 00043 }; 00044 static bNodeSocketType cmp_node_mapuv_out[]= { 00045 { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00046 { -1, 0, "" } 00047 }; 00048 00049 /* foreach UV, use these values to read in cbuf and write to stackbuf */ 00050 /* stackbuf should be zeroed */ 00051 static void do_mapuv(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *uvbuf, float threshold) 00052 { 00053 ImBuf *ibuf; 00054 float *out= stackbuf->rect, *uv, *uvnext, *uvprev; 00055 float dx, dy, alpha; 00056 int x, y, sx, sy, row= 3*stackbuf->x; 00057 00058 /* ibuf needed for sampling */ 00059 ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); 00060 ibuf->rect_float= cbuf->rect; 00061 00062 /* vars for efficient looping */ 00063 uv= uvbuf->rect; 00064 uvnext= uv+row; 00065 uvprev= uv-row; 00066 sx= stackbuf->x; 00067 sy= stackbuf->y; 00068 00069 for(y=0; y<sy; y++) { 00070 for(x=0; x<sx; x++, out+=4, uv+=3, uvnext+=3, uvprev+=3) { 00071 if(x>0 && x<sx-1 && y>0 && y<sy-1) { 00072 if(uv[2]!=0.0f) { 00073 float uv_l, uv_r; 00074 00075 /* adaptive sampling, red (U) channel */ 00076 00077 /* prevent alpha zero UVs to be used */ 00078 uv_l= uv[-1]!=0.0f? fabs(uv[0]-uv[-3]) : 0.0f; 00079 uv_r= uv[ 5]!=0.0f? fabs(uv[0]-uv[ 3]) : 0.0f; 00080 00081 //dx= 0.5f*(fabs(uv[0]-uv[-3]) + fabs(uv[0]-uv[3])); 00082 dx= 0.5f*(uv_l + uv_r); 00083 00084 uv_l= uvprev[-1]!=0.0f? fabs(uv[0]-uvprev[-3]) : 0.0f; 00085 uv_r= uvnext[-1]!=0.0f? fabs(uv[0]-uvnext[-3]) : 0.0f; 00086 00087 //dx+= 0.25f*(fabs(uv[0]-uvprev[-3]) + fabs(uv[0]-uvnext[-3])); 00088 dx+= 0.25f*(uv_l + uv_r); 00089 00090 uv_l= uvprev[ 5]!=0.0f? fabs(uv[0]-uvprev[+3]) : 0.0f; 00091 uv_r= uvnext[ 5]!=0.0f? fabs(uv[0]-uvnext[+3]) : 0.0f; 00092 00093 //dx+= 0.25f*(fabs(uv[0]-uvprev[+3]) + fabs(uv[0]-uvnext[+3])); 00094 dx+= 0.25f*(uv_l + uv_r); 00095 00096 /* adaptive sampling, green (V) channel */ 00097 00098 uv_l= uv[-row+2]!=0.0f? fabs(uv[1]-uv[-row+1]) : 0.0f; 00099 uv_r= uv[ row+2]!=0.0f? fabs(uv[1]-uv[ row+1]) : 0.0f; 00100 00101 //dy= 0.5f*(fabs(uv[1]-uv[-row+1]) + fabs(uv[1]-uv[row+1])); 00102 dy= 0.5f*(uv_l + uv_r); 00103 00104 uv_l= uvprev[-1]!=0.0f? fabs(uv[1]-uvprev[+1-3]) : 0.0f; 00105 uv_r= uvnext[-1]!=0.0f? fabs(uv[1]-uvnext[+1-3]) : 0.0f; 00106 00107 //dy+= 0.25f*(fabs(uv[1]-uvprev[+1-3]) + fabs(uv[1]-uvnext[+1-3])); 00108 dy+= 0.25f*(uv_l + uv_r); 00109 00110 uv_l= uvprev[ 5]!=0.0f? fabs(uv[1]-uvprev[+1+3]) : 0.0f; 00111 uv_r= uvnext[ 5]!=0.0f? fabs(uv[1]-uvnext[+1+3]) : 0.0f; 00112 00113 //dy+= 0.25f*(fabs(uv[1]-uvprev[+1+3]) + fabs(uv[1]-uvnext[+1+3])); 00114 dy+= 0.25f*(uv_l + uv_r); 00115 00116 /* UV to alpha threshold */ 00117 alpha= 1.0f - threshold*(dx+dy); 00118 if(alpha<0.0f) alpha= 0.0f; 00119 else alpha*= uv[2]; 00120 00121 /* should use mipmap */ 00122 if(dx > 0.20f) dx= 0.20f; 00123 if(dy > 0.20f) dy= 0.20f; 00124 00125 ibuf_sample(ibuf, uv[0], uv[1], dx, dy, out); 00126 /* premul */ 00127 if(alpha<1.0f) { 00128 out[0]*= alpha; 00129 out[1]*= alpha; 00130 out[2]*= alpha; 00131 out[3]*= alpha; 00132 } 00133 } 00134 } 00135 } 00136 } 00137 00138 IMB_freeImBuf(ibuf); 00139 } 00140 00141 00142 static void node_composit_exec_mapuv(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00143 { 00144 if(out[0]->hasoutput==0) 00145 return; 00146 00147 if(in[0]->data && in[1]->data) { 00148 CompBuf *cbuf= in[0]->data; 00149 CompBuf *uvbuf= in[1]->data; 00150 CompBuf *stackbuf; 00151 00152 cbuf= typecheck_compbuf(cbuf, CB_RGBA); 00153 uvbuf= typecheck_compbuf(uvbuf, CB_VEC3); 00154 stackbuf= alloc_compbuf(uvbuf->x, uvbuf->y, CB_RGBA, 1); /* allocs */; 00155 00156 do_mapuv(stackbuf, cbuf, uvbuf, 0.05f*(float)node->custom1); 00157 00158 out[0]->data= stackbuf; 00159 00160 if(cbuf!=in[0]->data) 00161 free_compbuf(cbuf); 00162 if(uvbuf!=in[1]->data) 00163 free_compbuf(uvbuf); 00164 } 00165 } 00166 00167 void register_node_type_cmp_mapuv(ListBase *lb) 00168 { 00169 static bNodeType ntype; 00170 00171 node_type_base(&ntype, CMP_NODE_MAP_UV, "Map UV", NODE_CLASS_DISTORT, NODE_OPTIONS, 00172 cmp_node_mapuv_in, cmp_node_mapuv_out); 00173 node_type_size(&ntype, 140, 100, 320); 00174 node_type_exec(&ntype, node_composit_exec_mapuv); 00175 00176 nodeRegisterType(lb, &ntype); 00177 } 00178 00179 00180