static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) { /* This group creates a vertex group to ob that has the * same name as bone (provided the bone is skinnable). * If such a vertex group already exist the routine exits. */ if (!(bone->flag & BONE_NO_DEFORM)) { if (!defgroup_find_name(ob, bone->name)) { BKE_object_defgroup_add_name(ob, bone->name); return 1; } } return 0; }
static int output_toggle_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); int output = RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; surface = get_activeSurface(pmd->canvas); /* if type is already enabled, toggle it off */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { int exists = dynamicPaint_outputLayerExists(surface, ob, output); const char *name; if (output == 0) name = surface->output_name; else name = surface->output_name2; /* Vertex Color Layer */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { if (!exists) ED_mesh_color_add(ob->data, name, true); else ED_mesh_color_remove_named(ob->data, name); } /* Vertex Weight Layer */ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { if (!exists) { BKE_object_defgroup_add_name(ob, name); } else { bDeformGroup *defgroup = defgroup_find_name(ob, name); if (defgroup) BKE_object_defgroup_remove(ob, defgroup); } } } return OPERATOR_FINISHED; }
bool data_transfer_layersmapping_vgroups( ListBase *r_map, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, Object *ob_src, Object *ob_dst, CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int fromlayers, const int tolayers) { int idx_src, idx_dst; MDeformVert *data_src, *data_dst = NULL; const size_t elem_size = sizeof(*((MDeformVert *)NULL)); /* Note: VGroups are a bit hairy, since their layout is defined on object level (ob->defbase), while their actual * data is a (mesh) CD layer. * This implies we may have to handle data layout itself while having NULL data itself, * and even have to support NULL data_src in transfer data code (we always create a data_dst, though). */ if (BLI_listbase_is_empty(&ob_src->defbase)) { if (use_delete) { BKE_object_defgroup_remove_all(ob_dst); } return true; } data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT); data_dst = CustomData_get_layer(cd_dst, CD_MDEFORMVERT); if (data_dst && use_dupref_dst && r_map) { /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */ data_dst = CustomData_duplicate_referenced_layer(cd_dst, CD_MDEFORMVERT, num_elem_dst); } if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) { /* Note: use_delete has not much meaning in this case, ignored. */ if (fromlayers >= 0) { idx_src = fromlayers; BLI_assert(idx_src < BLI_listbase_count(&ob_src->defbase)); } else if ((idx_src = ob_src->actdef - 1) == -1) { return false; } if (tolayers >= 0) { /* Note: in this case we assume layer exists! */ idx_dst = tolayers; BLI_assert(idx_dst < BLI_listbase_count(&ob_dst->defbase)); } else if (tolayers == DT_LAYERS_ACTIVE_DST) { if ((idx_dst = ob_dst->actdef - 1) == -1) { bDeformGroup *dg_src; if (!use_create) { return true; } dg_src = BLI_findlink(&ob_src->defbase, idx_src); BKE_object_defgroup_add_name(ob_dst, dg_src->name); idx_dst = ob_dst->actdef - 1; } } else if (tolayers == DT_LAYERS_INDEX_DST) { int num = BLI_listbase_count(&ob_src->defbase); idx_dst = idx_src; if (num <= idx_dst) { if (!use_create) { return true; } /* Create as much vgroups as necessary! */ for (; num <= idx_dst; num++) { BKE_object_defgroup_add(ob_dst); } } } else if (tolayers == DT_LAYERS_NAME_DST) { bDeformGroup *dg_src = BLI_findlink(&ob_src->defbase, idx_src); if ((idx_dst = defgroup_name_index(ob_dst, dg_src->name)) == -1) { if (!use_create) { return true; } BKE_object_defgroup_add_name(ob_dst, dg_src->name); idx_dst = ob_dst->actdef - 1; } } else { return false; } if (r_map) { /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * use_create is not relevant in this case */ if (!data_dst) { data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst); } data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_dst, elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } else { int num_src, num_sel_unused; bool *use_layers_src = NULL; bool ret = false; switch (fromlayers) { case DT_LAYERS_ALL_SRC: use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_ALL, &num_src, &num_sel_unused); break; case DT_LAYERS_VGROUP_SRC_BONE_SELECT: use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_BONE_SELECT, &num_src, &num_sel_unused); break; case DT_LAYERS_VGROUP_SRC_BONE_DEFORM: use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_BONE_DEFORM, &num_src, &num_sel_unused); break; } if (use_layers_src) { ret = data_transfer_layersmapping_vgroups_multisrc_to_dst( r_map, mix_mode, mix_factor, mix_weights, num_elem_dst, use_create, use_delete, ob_src, ob_dst, data_src, data_dst, cd_src, cd_dst, use_dupref_dst, tolayers, use_layers_src, num_src); } MEM_SAFE_FREE(use_layers_src); return ret; } return true; }
static bool data_transfer_layersmapping_vgroups_multisrc_to_dst( ListBase *r_map, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, Object *ob_src, Object *ob_dst, MDeformVert *data_src, MDeformVert *data_dst, CustomData *UNUSED(cd_src), CustomData *cd_dst, const bool UNUSED(use_dupref_dst), const int tolayers, bool *use_layers_src, const int num_layers_src) { int idx_src; int idx_dst; int tot_dst = BLI_listbase_count(&ob_dst->defbase); const size_t elem_size = sizeof(*((MDeformVert *)NULL)); switch (tolayers) { case DT_LAYERS_INDEX_DST: idx_dst = tot_dst; /* Find last source actually used! */ idx_src = num_layers_src; while (idx_src-- && !use_layers_src[idx_src]); idx_src++; if (idx_dst < idx_src) { if (!use_create) { return false; } /* Create as much vgroups as necessary! */ for (; idx_dst < idx_src; idx_dst++) { BKE_object_defgroup_add(ob_dst); } } else if (use_delete && idx_dst > idx_src) { while (idx_dst-- > idx_src) { BKE_object_defgroup_remove(ob_dst, ob_dst->defbase.last); } } if (r_map) { /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * Again, use_create is not relevant in this case */ if (!data_dst) { data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst); } while (idx_src--) { if (!use_layers_src[idx_src]) { continue; } data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_src, elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } break; case DT_LAYERS_NAME_DST: { bDeformGroup *dg_src, *dg_dst; if (use_delete) { /* Remove all unused dst vgroups first, simpler in this case. */ for (dg_dst = ob_dst->defbase.first; dg_dst;) { bDeformGroup *dg_dst_next = dg_dst->next; if (defgroup_name_index(ob_src, dg_dst->name) == -1) { BKE_object_defgroup_remove(ob_dst, dg_dst); } dg_dst = dg_dst_next; } } for (idx_src = 0, dg_src = ob_src->defbase.first; idx_src < num_layers_src; idx_src++, dg_src = dg_src->next) { if (!use_layers_src[idx_src]) { continue; } if ((idx_dst = defgroup_name_index(ob_dst, dg_src->name)) == -1) { if (!use_create) { if (r_map) { BLI_freelistN(r_map); } return false; } BKE_object_defgroup_add_name(ob_dst, dg_src->name); idx_dst = ob_dst->actdef - 1; } if (r_map) { /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * use_create is not relevant in this case */ if (!data_dst) { data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst); } data_transfer_layersmapping_add_item( r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights, data_src, data_dst, idx_src, idx_dst, elem_size, 0, 0, 0, vgroups_datatransfer_interp, NULL); } } break; } default: return false; } return true; }
static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) { /* Bones that are deforming * are regarded to be "skinnable" and are eligible for * auto-skinning. * * This function performs 2 functions: * * a) If the bone is skinnable, it creates * a vertex group for ob that has * the name of the skinnable bone * (if one doesn't exist already). * b) If the pointer data is non null, * it is treated like a handle to a * bDeformGroup pointer -- the * bDeformGroup pointer is set to point * to the deform group with the bone's * name, and the pointer the handle * points to is incremented to point to the * next member of an array of pointers * to bDeformGroups. This way we can loop using * this function to construct an array of * pointers to bDeformGroups, all with names * of skinnable bones. */ bDeformGroup ***hgroup, *defgroup = NULL; int a, segments; struct { Object *armob; void *list; int heat; } *data = datap; int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT); bArmature *arm = data->armob->data; if (!wpmode || !(bone->flag & BONE_HIDDEN_P)) { if (!(bone->flag & BONE_NO_DEFORM)) { if (data->heat && data->armob->pose && BKE_pose_channel_find_name(data->armob->pose, bone->name)) segments = bone->segments; else segments = 1; if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) { if (!(defgroup = defgroup_find_name(ob, bone->name))) { defgroup = BKE_object_defgroup_add_name(ob, bone->name); } else if (defgroup->flag & DG_LOCK_WEIGHT) { /* In case vgroup already exists and is locked, do not modify it here. See T43814. */ defgroup = NULL; } } if (data->list != NULL) { hgroup = (bDeformGroup ***) &data->list; for (a = 0; a < segments; a++) { **hgroup = defgroup; ++*hgroup; } } return segments; } } return 0; }