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