Blender V2.61 - r43446

MOD_weightvgedit.c

Go to the documentation of this file.
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 };