/** * Maps distances to weights, with an optional "smoothing" mapping. */ static void do_map(Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode) { const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */ unsigned int i = nidx; if (max_d == min_d) { while (i-- > 0) { weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */ } } else if (max_d > min_d) { while (i-- > 0) { if (weights[i] >= max_d) weights[i] = 1.0f; /* most likely case first */ else if (weights[i] <= min_d) weights[i] = 0.0f; else weights[i] = (weights[i] - min_d) * range_inv; } } else { while (i-- > 0) { if (weights[i] <= max_d) weights[i] = 1.0f; /* most likely case first */ else if (weights[i] >= min_d) weights[i] = 0.0f; else weights[i] = (weights[i] - min_d) * range_inv; } } if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) { RNG *rng = NULL; if (mode == MOD_WVG_MAPPING_RANDOM) rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); weightvg_do_map(nidx, weights, mode, NULL, rng); if (rng) BLI_rng_free(rng); } }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md; DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw = NULL; float *org_w; /* Array original weights. */ float *new_w; /* Array new weights. */ int numVerts; int defgrp_index; int i; /* Flags. */ int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; /* Only do weight-preview in Object, Sculpt and Pose modes! */ #if 0 int do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview); #endif /* Get number of verts. */ numVerts = dm->getNumVerts(dm); /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ if ((numVerts == 0) || (ob->defbase.first == NULL)) return dm; /* Get vgroup idx from its name. */ defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); if (defgrp_index == -1) return dm; dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ if (!dvert) { /* If this modifier is not allowed to add vertices, just return. */ if (!do_add) return dm; /* Else, add a valid data layer! */ dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts, wmd->defgrp_name); /* Ultimate security check. */ if (!dvert) return dm; } /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w"); new_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, new_w"); dw = MEM_mallocN(sizeof(MDeformWeight *) * numVerts, "WeightVGEdit Modifier, dw"); for (i = 0; i < numVerts; i++) { dw[i] = defvert_find_index(&dvert[i], defgrp_index); if (dw[i]) { org_w[i] = new_w[i] = dw[i]->weight; } else { org_w[i] = new_w[i] = wmd->default_weight; } } /* Do mapping. */ if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng); if (rng) BLI_rng_free(rng); } /* Do masking. */ weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->modifier.scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); /* Update/add/remove from vgroup. */ weightvg_update_vg(dvert, defgrp_index, dw, numVerts, NULL, org_w, do_add, wmd->add_threshold, do_rem, wmd->rem_threshold); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ if (do_prev) DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL); #endif /* Freeing stuff. */ MEM_freeN(org_w); MEM_freeN(new_w); MEM_freeN(dw); /* Return the vgroup-modified mesh. */ return dm; }
static unsigned int _ghashutil_keyhash(const void *ptr) { const GHashKey *key = ptr; unsigned int hash = BLI_ghashutil_strhash(key->msgctxt); return hash ^ BLI_ghashutil_strhash(key->msgid); }