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) 2011 by Bastien Montagne. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): None yet. 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 * 00025 */ 00026 00031 #include "BLI_utildefines.h" 00032 #include "BLI_math.h" 00033 #include "BLI_string.h" 00034 00035 #include "DNA_color_types.h" /* CurveMapping. */ 00036 #include "DNA_mesh_types.h" 00037 #include "DNA_meshdata_types.h" 00038 #include "DNA_modifier_types.h" 00039 #include "DNA_object_types.h" 00040 00041 #include "BKE_cdderivedmesh.h" 00042 #include "BKE_colortools.h" /* CurveMapping. */ 00043 #include "BKE_deform.h" 00044 #include "BKE_mesh.h" 00045 #include "BKE_modifier.h" 00046 #include "BKE_texture.h" /* Texture masking. */ 00047 00048 #include "depsgraph_private.h" 00049 #include "MEM_guardedalloc.h" 00050 #include "MOD_util.h" 00051 #include "MOD_weightvg_util.h" 00052 00053 /************************************** 00054 * Modifiers functions. * 00055 **************************************/ 00056 static void initData(ModifierData *md) 00057 { 00058 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00059 wmd->edit_flags = 0; 00060 wmd->falloff_type = MOD_WVG_MAPPING_NONE; 00061 wmd->default_weight = 0.0f; 00062 00063 wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0); 00064 curvemapping_initialize(wmd->cmap_curve); 00065 00066 wmd->rem_threshold = 0.01f; 00067 wmd->add_threshold = 0.01f; 00068 00069 wmd->mask_constant = 1.0f; 00070 wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */ 00071 wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL; 00072 } 00073 00074 static void freeData(ModifierData *md) 00075 { 00076 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00077 curvemapping_free(wmd->cmap_curve); 00078 } 00079 00080 static void copyData(ModifierData *md, ModifierData *target) 00081 { 00082 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00083 WeightVGEditModifierData *twmd = (WeightVGEditModifierData*) target; 00084 00085 BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name)); 00086 00087 twmd->edit_flags = wmd->edit_flags; 00088 twmd->falloff_type = wmd->falloff_type; 00089 twmd->default_weight = wmd->default_weight; 00090 00091 twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve); 00092 00093 twmd->add_threshold = wmd->add_threshold; 00094 twmd->rem_threshold = wmd->rem_threshold; 00095 00096 twmd->mask_constant = wmd->mask_constant; 00097 BLI_strncpy(twmd->mask_defgrp_name, wmd->mask_defgrp_name, sizeof(twmd->mask_defgrp_name)); 00098 twmd->mask_texture = wmd->mask_texture; 00099 twmd->mask_tex_use_channel = wmd->mask_tex_use_channel; 00100 twmd->mask_tex_mapping = wmd->mask_tex_mapping; 00101 twmd->mask_tex_map_obj = wmd->mask_tex_map_obj; 00102 BLI_strncpy(twmd->mask_tex_uvlayer_name, wmd->mask_tex_uvlayer_name, sizeof(twmd->mask_tex_uvlayer_name)); 00103 } 00104 00105 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) 00106 { 00107 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00108 CustomDataMask dataMask = 0; 00109 00110 /* We need vertex groups! */ 00111 dataMask |= CD_MASK_MDEFORMVERT; 00112 00113 /* Ask for UV coordinates if we need them. */ 00114 if(wmd->mask_tex_mapping == MOD_DISP_MAP_UV) 00115 dataMask |= CD_MASK_MTFACE; 00116 00117 return dataMask; 00118 } 00119 00120 static int dependsOnTime(ModifierData *md) 00121 { 00122 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00123 00124 if(wmd->mask_texture) 00125 return BKE_texture_dependsOnTime(wmd->mask_texture); 00126 return 0; 00127 } 00128 00129 static void foreachObjectLink(ModifierData *md, Object *ob, 00130 void (*walk)(void *userData, Object *ob, Object **obpoin), 00131 void *userData) 00132 { 00133 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00134 walk(userData, ob, &wmd->mask_tex_map_obj); 00135 } 00136 00137 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) 00138 { 00139 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00140 00141 walk(userData, ob, (ID **)&wmd->mask_texture); 00142 00143 foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); 00144 } 00145 00146 static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData) 00147 { 00148 walk(userData, ob, md, "mask_texture"); 00149 } 00150 00151 static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), 00152 Object *UNUSED(ob), DagNode *obNode) 00153 { 00154 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00155 DagNode *curNode; 00156 00157 if(wmd->mask_tex_map_obj && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) { 00158 curNode = dag_get_node(forest, wmd->mask_tex_map_obj); 00159 00160 dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, 00161 "WeightVGEdit Modifier"); 00162 } 00163 00164 if(wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) 00165 dag_add_relation(forest, obNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, 00166 "WeightVGEdit Modifier"); 00167 } 00168 00169 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) 00170 { 00171 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00172 /* If no vertex group, bypass. */ 00173 return (wmd->defgrp_name[0] == '\0'); 00174 } 00175 00176 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, 00177 int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) 00178 { 00179 WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; 00180 DerivedMesh *dm = derivedData; 00181 MDeformVert *dvert = NULL; 00182 MDeformWeight **dw = NULL; 00183 float *org_w; /* Array original weights. */ 00184 float *new_w; /* Array new weights. */ 00185 int numVerts; 00186 int defgrp_idx; 00187 int i; 00188 /* Flags. */ 00189 int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; 00190 int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; 00191 00192 /* Get number of verts. */ 00193 numVerts = dm->getNumVerts(dm); 00194 00195 /* Check if we can just return the original mesh. 00196 * Must have verts and therefore verts assigned to vgroups to do anything useful! 00197 */ 00198 if ((numVerts == 0) || (ob->defbase.first == NULL)) 00199 return dm; 00200 00201 /* Get vgroup idx from its name. */ 00202 defgrp_idx = defgroup_name_index(ob, wmd->defgrp_name); 00203 if (defgrp_idx < 0) 00204 return dm; 00205 00206 dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); 00207 00208 /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ 00209 org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w"); 00210 new_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, new_w"); 00211 dw = MEM_mallocN(sizeof(MDeformWeight*) * numVerts, "WeightVGEdit Modifier, dw"); 00212 for (i = 0; i < numVerts; i++) { 00213 dw[i] = defvert_find_index(&dvert[i], defgrp_idx); 00214 if(dw[i]) { 00215 org_w[i] = new_w[i] = dw[i]->weight; 00216 } 00217 else { 00218 org_w[i] = new_w[i] = wmd->default_weight; 00219 } 00220 } 00221 00222 /* Do mapping. */ 00223 if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) { 00224 weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve); 00225 } 00226 00227 /* Do masking. */ 00228 weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant, 00229 wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, 00230 wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); 00231 00232 /* Update/add/remove from vgroup. */ 00233 weightvg_update_vg(dvert, defgrp_idx, dw, numVerts, NULL, org_w, do_add, wmd->add_threshold, 00234 do_rem, wmd->rem_threshold); 00235 00236 /* Freeing stuff. */ 00237 MEM_freeN(org_w); 00238 MEM_freeN(new_w); 00239 MEM_freeN(dw); 00240 00241 /* Return the vgroup-modified mesh. */ 00242 return dm; 00243 } 00244 00245 static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, 00246 struct EditMesh *UNUSED(editData), 00247 DerivedMesh *derivedData) 00248 { 00249 return applyModifier(md, ob, derivedData, 0, 1); 00250 } 00251 00252 00253 ModifierTypeInfo modifierType_WeightVGEdit = { 00254 /* name */ "VertexWeightEdit", 00255 /* structName */ "WeightVGEditModifierData", 00256 /* structSize */ sizeof(WeightVGEditModifierData), 00257 /* type */ eModifierTypeType_NonGeometrical, 00258 /* flags */ eModifierTypeFlag_AcceptsMesh 00259 /* |eModifierTypeFlag_SupportsMapping*/ 00260 |eModifierTypeFlag_SupportsEditmode, 00261 00262 /* copyData */ copyData, 00263 /* deformVerts */ NULL, 00264 /* deformMatrices */ NULL, 00265 /* deformVertsEM */ NULL, 00266 /* deformMatricesEM */ NULL, 00267 /* applyModifier */ applyModifier, 00268 /* applyModifierEM */ applyModifierEM, 00269 /* initData */ initData, 00270 /* requiredDataMask */ requiredDataMask, 00271 /* freeData */ freeData, 00272 /* isDisabled */ isDisabled, 00273 /* updateDepgraph */ updateDepgraph, 00274 /* dependsOnTime */ dependsOnTime, 00275 /* dependsOnNormals */ NULL, 00276 /* foreachObjectLink */ foreachObjectLink, 00277 /* foreachIDLink */ foreachIDLink, 00278 /* foreachTexLink */ foreachTexLink, 00279 };