|
Blender
V2.59
|
00001 /* 00002 * $Id: MOD_smooth.c 38300 2011-07-11 09:15:20Z blendix $ 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) 2005 by the Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Daniel Dunbar 00024 * Ton Roosendaal, 00025 * Ben Batt, 00026 * Brecht Van Lommel, 00027 * Campbell Barton 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 * 00031 */ 00032 00038 #include "DNA_meshdata_types.h" 00039 00040 #include "BLI_math.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "BKE_cdderivedmesh.h" 00044 #include "BKE_particle.h" 00045 #include "BKE_deform.h" 00046 00047 00048 #include "MEM_guardedalloc.h" 00049 00050 #include "MOD_modifiertypes.h" 00051 #include "MOD_util.h" 00052 00053 00054 static void initData(ModifierData *md) 00055 { 00056 SmoothModifierData *smd = (SmoothModifierData*) md; 00057 00058 smd->fac = 0.5f; 00059 smd->repeat = 1; 00060 smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z; 00061 smd->defgrp_name[0] = '\0'; 00062 } 00063 00064 static void copyData(ModifierData *md, ModifierData *target) 00065 { 00066 SmoothModifierData *smd = (SmoothModifierData*) md; 00067 SmoothModifierData *tsmd = (SmoothModifierData*) target; 00068 00069 tsmd->fac = smd->fac; 00070 tsmd->repeat = smd->repeat; 00071 tsmd->flag = smd->flag; 00072 strncpy(tsmd->defgrp_name, smd->defgrp_name, 32); 00073 } 00074 00075 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) 00076 { 00077 SmoothModifierData *smd = (SmoothModifierData*) md; 00078 short flag; 00079 00080 flag = smd->flag & (MOD_SMOOTH_X|MOD_SMOOTH_Y|MOD_SMOOTH_Z); 00081 00082 /* disable if modifier is off for X, Y and Z or if factor is 0 */ 00083 if((smd->fac == 0.0f) || flag == 0) return 1; 00084 00085 return 0; 00086 } 00087 00088 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) 00089 { 00090 SmoothModifierData *smd = (SmoothModifierData *)md; 00091 CustomDataMask dataMask = 0; 00092 00093 /* ask for vertexgroups if we need them */ 00094 if(smd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT; 00095 00096 return dataMask; 00097 } 00098 00099 static void smoothModifier_do( 00100 SmoothModifierData *smd, Object *ob, DerivedMesh *dm, 00101 float (*vertexCos)[3], int numVerts) 00102 { 00103 MDeformVert *dvert = NULL; 00104 MEdge *medges = NULL; 00105 00106 int i, j, numDMEdges, defgrp_index; 00107 unsigned char *uctmp; 00108 float *ftmp, fac, facm; 00109 00110 ftmp = (float*)MEM_callocN(3*sizeof(float)*numVerts, 00111 "smoothmodifier_f"); 00112 if (!ftmp) return; 00113 uctmp = (unsigned char*)MEM_callocN(sizeof(unsigned char)*numVerts, 00114 "smoothmodifier_uc"); 00115 if (!uctmp) { 00116 if (ftmp) MEM_freeN(ftmp); 00117 return; 00118 } 00119 00120 fac = smd->fac; 00121 facm = 1 - fac; 00122 00123 medges = dm->getEdgeArray(dm); 00124 numDMEdges = dm->getNumEdges(dm); 00125 00126 modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); 00127 00128 /* NOTICE: this can be optimized a little bit by moving the 00129 * if (dvert) out of the loop, if needed */ 00130 for (j = 0; j < smd->repeat; j++) { 00131 for (i = 0; i < numDMEdges; i++) { 00132 float fvec[3]; 00133 float *v1, *v2; 00134 unsigned int idx1, idx2; 00135 00136 idx1 = medges[i].v1; 00137 idx2 = medges[i].v2; 00138 00139 v1 = vertexCos[idx1]; 00140 v2 = vertexCos[idx2]; 00141 00142 mid_v3_v3v3(fvec, v1, v2); 00143 00144 v1 = &ftmp[idx1*3]; 00145 v2 = &ftmp[idx2*3]; 00146 00147 if (uctmp[idx1] < 255) { 00148 uctmp[idx1]++; 00149 add_v3_v3(v1, fvec); 00150 } 00151 if (uctmp[idx2] < 255) { 00152 uctmp[idx2]++; 00153 add_v3_v3(v2, fvec); 00154 } 00155 } 00156 00157 if (dvert) { 00158 for (i = 0; i < numVerts; i++) { 00159 MDeformWeight *dw = NULL; 00160 float f, fm, facw, *fp, *v; 00161 int k; 00162 short flag = smd->flag; 00163 00164 v = vertexCos[i]; 00165 fp = &ftmp[i*3]; 00166 00167 for (k = 0; k < dvert[i].totweight; ++k) { 00168 if(dvert[i].dw[k].def_nr == defgrp_index) { 00169 dw = &dvert[i].dw[k]; 00170 break; 00171 } 00172 } 00173 if (!dw) continue; 00174 00175 f = fac * dw->weight; 00176 fm = 1.0f - f; 00177 00178 /* fp is the sum of uctmp[i] verts, so must be averaged */ 00179 facw = 0.0f; 00180 if (uctmp[i]) 00181 facw = f / (float)uctmp[i]; 00182 00183 if (flag & MOD_SMOOTH_X) 00184 v[0] = fm * v[0] + facw * fp[0]; 00185 if (flag & MOD_SMOOTH_Y) 00186 v[1] = fm * v[1] + facw * fp[1]; 00187 if (flag & MOD_SMOOTH_Z) 00188 v[2] = fm * v[2] + facw * fp[2]; 00189 } 00190 } 00191 else { /* no vertex group */ 00192 for (i = 0; i < numVerts; i++) { 00193 float facw, *fp, *v; 00194 short flag = smd->flag; 00195 00196 v = vertexCos[i]; 00197 fp = &ftmp[i*3]; 00198 00199 /* fp is the sum of uctmp[i] verts, so must be averaged */ 00200 facw = 0.0f; 00201 if (uctmp[i]) 00202 facw = fac / (float)uctmp[i]; 00203 00204 if (flag & MOD_SMOOTH_X) 00205 v[0] = facm * v[0] + facw * fp[0]; 00206 if (flag & MOD_SMOOTH_Y) 00207 v[1] = facm * v[1] + facw * fp[1]; 00208 if (flag & MOD_SMOOTH_Z) 00209 v[2] = facm * v[2] + facw * fp[2]; 00210 } 00211 00212 } 00213 00214 memset(ftmp, 0, 3*sizeof(float)*numVerts); 00215 memset(uctmp, 0, sizeof(unsigned char)*numVerts); 00216 } 00217 00218 MEM_freeN(ftmp); 00219 MEM_freeN(uctmp); 00220 } 00221 00222 static void deformVerts( 00223 ModifierData *md, Object *ob, DerivedMesh *derivedData, 00224 float (*vertexCos)[3], int numVerts, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) 00225 { 00226 DerivedMesh *dm= get_dm(ob, NULL, derivedData, NULL, 0); 00227 00228 smoothModifier_do((SmoothModifierData *)md, ob, dm, 00229 vertexCos, numVerts); 00230 00231 if(dm != derivedData) 00232 dm->release(dm); 00233 } 00234 00235 static void deformVertsEM( 00236 ModifierData *md, Object *ob, struct EditMesh *editData, 00237 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) 00238 { 00239 DerivedMesh *dm= get_dm(ob, editData, derivedData, NULL, 0); 00240 00241 smoothModifier_do((SmoothModifierData *)md, ob, dm, 00242 vertexCos, numVerts); 00243 00244 if(dm != derivedData) 00245 dm->release(dm); 00246 } 00247 00248 00249 ModifierTypeInfo modifierType_Smooth = { 00250 /* name */ "Smooth", 00251 /* structName */ "SmoothModifierData", 00252 /* structSize */ sizeof(SmoothModifierData), 00253 /* type */ eModifierTypeType_OnlyDeform, 00254 /* flags */ eModifierTypeFlag_AcceptsMesh 00255 | eModifierTypeFlag_SupportsEditmode, 00256 00257 /* copyData */ copyData, 00258 /* deformVerts */ deformVerts, 00259 /* deformMatrices */ NULL, 00260 /* deformVertsEM */ deformVertsEM, 00261 /* deformMatricesEM */ NULL, 00262 /* applyModifier */ NULL, 00263 /* applyModifierEM */ NULL, 00264 /* initData */ initData, 00265 /* requiredDataMask */ requiredDataMask, 00266 /* freeData */ NULL, 00267 /* isDisabled */ isDisabled, 00268 /* updateDepgraph */ NULL, 00269 /* dependsOnTime */ NULL, 00270 /* dependsOnNormals */ NULL, 00271 /* foreachObjectLink */ NULL, 00272 /* foreachIDLink */ NULL, 00273 };