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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}