Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r--source/blender/blenkernel/intern/deform.c2066
1 files changed, 1087 insertions, 979 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 3e6649085dd..7769f3aff86 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -21,7 +21,6 @@
* \ingroup bke
*/
-
#include <string.h>
#include <math.h>
#include <ctype.h>
@@ -45,7 +44,7 @@
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
-#include "BKE_deform.h" /* own include */
+#include "BKE_deform.h" /* own include */
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_object.h"
@@ -53,54 +52,53 @@
#include "data_transfer_intern.h"
-
bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
{
- bDeformGroup *defgroup;
+ bDeformGroup *defgroup;
- BLI_assert(OB_TYPE_SUPPORT_VGROUP(ob->type));
+ BLI_assert(OB_TYPE_SUPPORT_VGROUP(ob->type));
- defgroup = MEM_callocN(sizeof(bDeformGroup), __func__);
+ defgroup = MEM_callocN(sizeof(bDeformGroup), __func__);
- BLI_strncpy(defgroup->name, name, sizeof(defgroup->name));
+ BLI_strncpy(defgroup->name, name, sizeof(defgroup->name));
- BLI_addtail(&ob->defbase, defgroup);
- defgroup_unique_name(defgroup, ob);
+ BLI_addtail(&ob->defbase, defgroup);
+ defgroup_unique_name(defgroup, ob);
- BKE_object_batch_cache_dirty_tag(ob);
+ BKE_object_batch_cache_dirty_tag(ob);
- return defgroup;
+ return defgroup;
}
void defgroup_copy_list(ListBase *outbase, const ListBase *inbase)
{
- bDeformGroup *defgroup, *defgroupn;
+ bDeformGroup *defgroup, *defgroupn;
- BLI_listbase_clear(outbase);
+ BLI_listbase_clear(outbase);
- for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) {
- defgroupn = defgroup_duplicate(defgroup);
- BLI_addtail(outbase, defgroupn);
- }
+ for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) {
+ defgroupn = defgroup_duplicate(defgroup);
+ BLI_addtail(outbase, defgroupn);
+ }
}
bDeformGroup *defgroup_duplicate(const bDeformGroup *ingroup)
{
- bDeformGroup *outgroup;
+ bDeformGroup *outgroup;
- if (!ingroup) {
- BLI_assert(0);
- return NULL;
- }
+ if (!ingroup) {
+ BLI_assert(0);
+ return NULL;
+ }
- outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
+ outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
- /* For now, just copy everything over. */
- memcpy(outgroup, ingroup, sizeof(bDeformGroup));
+ /* For now, just copy everything over. */
+ memcpy(outgroup, ingroup, sizeof(bDeformGroup));
- outgroup->next = outgroup->prev = NULL;
+ outgroup->next = outgroup->prev = NULL;
- return outgroup;
+ return outgroup;
}
/**
@@ -108,16 +106,17 @@ bDeformGroup *defgroup_duplicate(const bDeformGroup *ingroup)
* - do nothing if neither are set.
* - add destination weight if needed
*/
-void defvert_copy_subset(
- MDeformVert *dvert_dst, const MDeformVert *dvert_src,
- const bool *vgroup_subset, const int vgroup_tot)
+void defvert_copy_subset(MDeformVert *dvert_dst,
+ const MDeformVert *dvert_src,
+ const bool *vgroup_subset,
+ const int vgroup_tot)
{
- int defgroup;
- for (defgroup = 0; defgroup < vgroup_tot; defgroup++) {
- if (vgroup_subset[defgroup]) {
- defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup);
- }
- }
+ int defgroup;
+ for (defgroup = 0; defgroup < vgroup_tot; defgroup++) {
+ if (vgroup_subset[defgroup]) {
+ defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup);
+ }
+ }
}
/**
@@ -125,36 +124,38 @@ void defvert_copy_subset(
* - do nothing if neither are set.
* - add destination weight if needed
*/
-void defvert_mirror_subset(
- MDeformVert *dvert_dst, const MDeformVert *dvert_src,
- const bool *vgroup_subset, const int vgroup_tot,
- const int *flip_map, const int flip_map_len)
+void defvert_mirror_subset(MDeformVert *dvert_dst,
+ const MDeformVert *dvert_src,
+ const bool *vgroup_subset,
+ const int vgroup_tot,
+ const int *flip_map,
+ const int flip_map_len)
{
- int defgroup;
- for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) {
- if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
- defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup);
- }
- }
+ int defgroup;
+ for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) {
+ if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
+ defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup);
+ }
+ }
}
void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
{
- if (dvert_dst->totweight == dvert_src->totweight) {
- if (dvert_src->totweight)
- memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
- }
- else {
- if (dvert_dst->dw)
- MEM_freeN(dvert_dst->dw);
-
- if (dvert_src->totweight)
- dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
- else
- dvert_dst->dw = NULL;
-
- dvert_dst->totweight = dvert_src->totweight;
- }
+ if (dvert_dst->totweight == dvert_src->totweight) {
+ if (dvert_src->totweight)
+ memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
+ }
+ else {
+ if (dvert_dst->dw)
+ MEM_freeN(dvert_dst->dw);
+
+ if (dvert_src->totweight)
+ dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+ else
+ dvert_dst->dw = NULL;
+
+ dvert_dst->totweight = dvert_src->totweight;
+ }
}
/**
@@ -162,27 +163,28 @@ void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
* - do nothing if neither are set.
* - add destination weight if needed.
*/
-void defvert_copy_index(
- MDeformVert *dvert_dst, const int defgroup_dst,
- const MDeformVert *dvert_src, const int defgroup_src)
+void defvert_copy_index(MDeformVert *dvert_dst,
+ const int defgroup_dst,
+ const MDeformVert *dvert_src,
+ const int defgroup_src)
{
- MDeformWeight *dw_src, *dw_dst;
-
- dw_src = defvert_find_index(dvert_src, defgroup_src);
-
- if (dw_src) {
- /* source is valid, verify destination */
- dw_dst = defvert_verify_index(dvert_dst, defgroup_dst);
- dw_dst->weight = dw_src->weight;
- }
- else {
- /* source was NULL, assign zero, could also remove */
- dw_dst = defvert_find_index(dvert_dst, defgroup_dst);
-
- if (dw_dst) {
- dw_dst->weight = 0.0f;
- }
- }
+ MDeformWeight *dw_src, *dw_dst;
+
+ dw_src = defvert_find_index(dvert_src, defgroup_src);
+
+ if (dw_src) {
+ /* source is valid, verify destination */
+ dw_dst = defvert_verify_index(dvert_dst, defgroup_dst);
+ dw_dst->weight = dw_src->weight;
+ }
+ else {
+ /* source was NULL, assign zero, could also remove */
+ dw_dst = defvert_find_index(dvert_dst, defgroup_dst);
+
+ if (dw_dst) {
+ dw_dst->weight = 0.0f;
+ }
+ }
}
/**
@@ -191,43 +193,49 @@ void defvert_copy_index(
*/
void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const bool use_verify)
{
- if (dvert_src->totweight && dvert_dst->totweight) {
- int i;
- MDeformWeight *dw_src;
- for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
- MDeformWeight *dw_dst;
- if (use_verify) dw_dst = defvert_verify_index(dvert_dst, dw_src->def_nr);
- else dw_dst = defvert_find_index(dvert_dst, dw_src->def_nr);
-
- if (dw_dst) {
- dw_dst->weight = dw_src->weight;
- }
- }
- }
+ if (dvert_src->totweight && dvert_dst->totweight) {
+ int i;
+ MDeformWeight *dw_src;
+ for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
+ MDeformWeight *dw_dst;
+ if (use_verify)
+ dw_dst = defvert_verify_index(dvert_dst, dw_src->def_nr);
+ else
+ dw_dst = defvert_find_index(dvert_dst, dw_src->def_nr);
+
+ if (dw_dst) {
+ dw_dst->weight = dw_src->weight;
+ }
+ }
+ }
}
/**
* be sure all flip_map values are valid
*/
-void defvert_sync_mapped(
- MDeformVert *dvert_dst, const MDeformVert *dvert_src,
- const int *flip_map, const int flip_map_len, const bool use_verify)
+void defvert_sync_mapped(MDeformVert *dvert_dst,
+ const MDeformVert *dvert_src,
+ const int *flip_map,
+ const int flip_map_len,
+ const bool use_verify)
{
- if (dvert_src->totweight && dvert_dst->totweight) {
- int i;
- MDeformWeight *dw_src;
- for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
- if (dw_src->def_nr < flip_map_len) {
- MDeformWeight *dw_dst;
- if (use_verify) dw_dst = defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]);
- else dw_dst = defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]);
-
- if (dw_dst) {
- dw_dst->weight = dw_src->weight;
- }
- }
- }
- }
+ if (dvert_src->totweight && dvert_dst->totweight) {
+ int i;
+ MDeformWeight *dw_src;
+ for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
+ if (dw_src->def_nr < flip_map_len) {
+ MDeformWeight *dw_dst;
+ if (use_verify)
+ dw_dst = defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]);
+ else
+ dw_dst = defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]);
+
+ if (dw_dst) {
+ dw_dst->weight = dw_src->weight;
+ }
+ }
+ }
+ }
}
/**
@@ -235,248 +243,252 @@ void defvert_sync_mapped(
*/
void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
{
- MDeformWeight *dw = dvert->dw;
- unsigned int i;
- for (i = dvert->totweight; i != 0; i--, dw++) {
- if (dw->def_nr < map_len) {
- dw->def_nr = map[dw->def_nr];
-
- /* just in case */
- BLI_assert(dw->def_nr >= 0);
- }
- }
+ MDeformWeight *dw = dvert->dw;
+ unsigned int i;
+ for (i = dvert->totweight; i != 0; i--, dw++) {
+ if (dw->def_nr < map_len) {
+ dw->def_nr = map[dw->def_nr];
+
+ /* just in case */
+ BLI_assert(dw->def_nr >= 0);
+ }
+ }
}
/**
* Same as #defvert_normalize but takes a bool array.
*/
-void defvert_normalize_subset(MDeformVert *dvert,
- const bool *vgroup_subset, const int vgroup_tot)
+void defvert_normalize_subset(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot)
{
- if (dvert->totweight == 0) {
- /* nothing */
- }
- else if (dvert->totweight == 1) {
- MDeformWeight *dw = dvert->dw;
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- dw->weight = 1.0f;
- }
- }
- else {
- MDeformWeight *dw;
- unsigned int i;
- float tot_weight = 0.0f;
-
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- tot_weight += dw->weight;
- }
- }
-
- if (tot_weight > 0.0f) {
- float scalar = 1.0f / tot_weight;
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- dw->weight *= scalar;
-
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
- }
- }
- }
- }
+ if (dvert->totweight == 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ MDeformWeight *dw = dvert->dw;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ dw->weight = 1.0f;
+ }
+ }
+ else {
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ tot_weight += dw->weight;
+ }
+ }
+
+ if (tot_weight > 0.0f) {
+ float scalar = 1.0f / tot_weight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+ }
}
void defvert_normalize(MDeformVert *dvert)
{
- if (dvert->totweight == 0) {
- /* nothing */
- }
- else if (dvert->totweight == 1) {
- dvert->dw[0].weight = 1.0f;
- }
- else {
- MDeformWeight *dw;
- unsigned int i;
- float tot_weight = 0.0f;
-
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- tot_weight += dw->weight;
- }
-
- if (tot_weight > 0.0f) {
- float scalar = 1.0f / tot_weight;
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- dw->weight *= scalar;
-
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
- }
- }
- }
+ if (dvert->totweight == 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ dvert->dw[0].weight = 1.0f;
+ }
+ else {
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ tot_weight += dw->weight;
+ }
+
+ if (tot_weight > 0.0f) {
+ float scalar = 1.0f / tot_weight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
}
/**
* Same as defvert_normalize() if the locked vgroup is not a member of the subset
*/
-void defvert_normalize_lock_single(
- MDeformVert *dvert,
- const bool *vgroup_subset, const int vgroup_tot,
- const int def_nr_lock)
+void defvert_normalize_lock_single(MDeformVert *dvert,
+ const bool *vgroup_subset,
+ const int vgroup_tot,
+ const int def_nr_lock)
{
- if (dvert->totweight == 0) {
- /* nothing */
- }
- else if (dvert->totweight == 1) {
- MDeformWeight *dw = dvert->dw;
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if (def_nr_lock != 0) {
- dw->weight = 1.0f;
- }
- }
- }
- else {
- MDeformWeight *dw_lock = NULL;
- MDeformWeight *dw;
- unsigned int i;
- float tot_weight = 0.0f;
- float lock_iweight = 1.0f;
-
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if (dw->def_nr != def_nr_lock) {
- tot_weight += dw->weight;
- }
- else {
- dw_lock = dw;
- lock_iweight = (1.0f - dw_lock->weight);
- CLAMP(lock_iweight, 0.0f, 1.0f);
- }
- }
- }
-
- if (tot_weight > 0.0f) {
- /* paranoid, should be 1.0 but in case of float error clamp anyway */
-
- float scalar = (1.0f / tot_weight) * lock_iweight;
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if (dw != dw_lock) {
- dw->weight *= scalar;
-
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
- }
- }
- }
- }
- }
+ if (dvert->totweight == 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ MDeformWeight *dw = dvert->dw;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (def_nr_lock != 0) {
+ dw->weight = 1.0f;
+ }
+ }
+ }
+ else {
+ MDeformWeight *dw_lock = NULL;
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+ float lock_iweight = 1.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (dw->def_nr != def_nr_lock) {
+ tot_weight += dw->weight;
+ }
+ else {
+ dw_lock = dw;
+ lock_iweight = (1.0f - dw_lock->weight);
+ CLAMP(lock_iweight, 0.0f, 1.0f);
+ }
+ }
+ }
+
+ if (tot_weight > 0.0f) {
+ /* paranoid, should be 1.0 but in case of float error clamp anyway */
+
+ float scalar = (1.0f / tot_weight) * lock_iweight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (dw != dw_lock) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+ }
+ }
}
/**
* Same as defvert_normalize() if no locked vgroup is a member of the subset
*/
-void defvert_normalize_lock_map(
- MDeformVert *dvert,
- const bool *vgroup_subset, const int vgroup_tot,
- const bool *lock_flags, const int defbase_tot)
+void defvert_normalize_lock_map(MDeformVert *dvert,
+ const bool *vgroup_subset,
+ const int vgroup_tot,
+ const bool *lock_flags,
+ const int defbase_tot)
{
- if (dvert->totweight == 0) {
- /* nothing */
- }
- else if (dvert->totweight == 1) {
- MDeformWeight *dw = dvert->dw;
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
- dw->weight = 1.0f;
- }
- }
- }
- else {
- MDeformWeight *dw;
- unsigned int i;
- float tot_weight = 0.0f;
- float lock_iweight = 0.0f;
-
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
- tot_weight += dw->weight;
- }
- else {
- /* invert after */
- lock_iweight += dw->weight;
- }
- }
- }
-
- lock_iweight = max_ff(0.0f, 1.0f - lock_iweight);
-
- if (tot_weight > 0.0f) {
- /* paranoid, should be 1.0 but in case of float error clamp anyway */
-
- float scalar = (1.0f / tot_weight) * lock_iweight;
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
- dw->weight *= scalar;
-
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
- }
- }
- }
- }
- }
+ if (dvert->totweight == 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ MDeformWeight *dw = dvert->dw;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
+ dw->weight = 1.0f;
+ }
+ }
+ }
+ else {
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+ float lock_iweight = 0.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
+ tot_weight += dw->weight;
+ }
+ else {
+ /* invert after */
+ lock_iweight += dw->weight;
+ }
+ }
+ }
+
+ lock_iweight = max_ff(0.0f, 1.0f - lock_iweight);
+
+ if (tot_weight > 0.0f) {
+ /* paranoid, should be 1.0 but in case of float error clamp anyway */
+
+ float scalar = (1.0f / tot_weight) * lock_iweight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+ }
+ }
}
void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
{
- MDeformWeight *dw;
- int i;
-
- for (dw = dvert->dw, i = 0; i < dvert->totweight; dw++, i++) {
- if (dw->def_nr < flip_map_len) {
- if (flip_map[dw->def_nr] >= 0) {
- dw->def_nr = flip_map[dw->def_nr];
- }
- }
- }
+ MDeformWeight *dw;
+ int i;
+
+ for (dw = dvert->dw, i = 0; i < dvert->totweight; dw++, i++) {
+ if (dw->def_nr < flip_map_len) {
+ if (flip_map[dw->def_nr] >= 0) {
+ dw->def_nr = flip_map[dw->def_nr];
+ }
+ }
+ }
}
void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
{
- MDeformWeight *dw, *dw_cpy;
- float weight;
- int i, totweight = dvert->totweight;
-
- /* copy weights */
- for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
- if (dw->def_nr < flip_map_len) {
- if (flip_map[dw->def_nr] >= 0) {
- /* error checkers complain of this but we'll never get NULL return */
- dw_cpy = defvert_verify_index(dvert, flip_map[dw->def_nr]);
- dw = &dvert->dw[i]; /* in case array got realloced */
-
- /* distribute weights: if only one of the vertex groups was
- * assigned this will halve the weights, otherwise it gets
- * evened out. this keeps it proportional to other groups */
- weight = 0.5f * (dw_cpy->weight + dw->weight);
- dw_cpy->weight = weight;
- dw->weight = weight;
- }
- }
- }
+ MDeformWeight *dw, *dw_cpy;
+ float weight;
+ int i, totweight = dvert->totweight;
+
+ /* copy weights */
+ for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
+ if (dw->def_nr < flip_map_len) {
+ if (flip_map[dw->def_nr] >= 0) {
+ /* error checkers complain of this but we'll never get NULL return */
+ dw_cpy = defvert_verify_index(dvert, flip_map[dw->def_nr]);
+ dw = &dvert->dw[i]; /* in case array got realloced */
+
+ /* distribute weights: if only one of the vertex groups was
+ * assigned this will halve the weights, otherwise it gets
+ * evened out. this keeps it proportional to other groups */
+ weight = 0.5f * (dw_cpy->weight + dw->weight);
+ dw_cpy->weight = weight;
+ dw->weight = weight;
+ }
+ }
+ }
}
bDeformGroup *defgroup_find_name(Object *ob, const char *name)
{
- return (name && name[0] != '\0') ? BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name)) : NULL;
+ return (name && name[0] != '\0') ?
+ BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name)) :
+ NULL;
}
int defgroup_name_index(Object *ob, const char *name)
{
- return (name && name[0] != '\0') ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1;
+ return (name && name[0] != '\0') ?
+ BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) :
+ -1;
}
/**
@@ -484,40 +496,40 @@ int defgroup_name_index(Object *ob, const char *name)
*/
int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
{
- int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
-
- if (defbase_tot == 0) {
- return NULL;
- }
- else {
- bDeformGroup *dg;
- char name_flip[sizeof(dg->name)];
- int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
-
- for (i = 0; i < defbase_tot; i++) {
- map[i] = -1;
- }
-
- for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
- if (map[i] == -1) { /* may be calculated previously */
-
- /* in case no valid value is found, use this */
- if (use_default)
- map[i] = i;
-
- BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
-
- if (!STREQ(name_flip, dg->name)) {
- flip_num = defgroup_name_index(ob, name_flip);
- if (flip_num >= 0) {
- map[i] = flip_num;
- map[flip_num] = i; /* save an extra lookup */
- }
- }
- }
- }
- return map;
- }
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
+
+ if (defbase_tot == 0) {
+ return NULL;
+ }
+ else {
+ bDeformGroup *dg;
+ char name_flip[sizeof(dg->name)];
+ int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
+
+ for (i = 0; i < defbase_tot; i++) {
+ map[i] = -1;
+ }
+
+ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
+ if (map[i] == -1) { /* may be calculated previously */
+
+ /* in case no valid value is found, use this */
+ if (use_default)
+ map[i] = i;
+
+ BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+
+ if (!STREQ(name_flip, dg->name)) {
+ flip_num = defgroup_name_index(ob, name_flip);
+ if (flip_num >= 0) {
+ map[i] = flip_num;
+ map[flip_num] = i; /* save an extra lookup */
+ }
+ }
+ }
+ }
+ return map;
+ }
}
/**
@@ -525,87 +537,93 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
*/
int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_default, int defgroup)
{
- int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
-
- if (defbase_tot == 0) {
- return NULL;
- }
- else {
- bDeformGroup *dg;
- char name_flip[sizeof(dg->name)];
- int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
-
- for (i = 0; i < defbase_tot; i++) {
- map[i] = use_default ? i : -1;
- }
-
- dg = BLI_findlink(&ob->defbase, defgroup);
-
- BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
- if (!STREQ(name_flip, dg->name)) {
- flip_num = defgroup_name_index(ob, name_flip);
-
- if (flip_num != -1) {
- map[defgroup] = flip_num;
- map[flip_num] = defgroup;
- }
- }
-
- return map;
- }
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
+
+ if (defbase_tot == 0) {
+ return NULL;
+ }
+ else {
+ bDeformGroup *dg;
+ char name_flip[sizeof(dg->name)];
+ int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
+
+ for (i = 0; i < defbase_tot; i++) {
+ map[i] = use_default ? i : -1;
+ }
+
+ dg = BLI_findlink(&ob->defbase, defgroup);
+
+ BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+ if (!STREQ(name_flip, dg->name)) {
+ flip_num = defgroup_name_index(ob, name_flip);
+
+ if (flip_num != -1) {
+ map[defgroup] = flip_num;
+ map[flip_num] = defgroup;
+ }
+ }
+
+ return map;
+ }
}
int defgroup_flip_index(Object *ob, int index, const bool use_default)
{
- bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
- int flip_index = -1;
+ bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
+ int flip_index = -1;
- if (dg) {
- char name_flip[sizeof(dg->name)];
- BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+ if (dg) {
+ char name_flip[sizeof(dg->name)];
+ BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
- if (!STREQ(name_flip, dg->name)) {
- flip_index = defgroup_name_index(ob, name_flip);
- }
- }
+ if (!STREQ(name_flip, dg->name)) {
+ flip_index = defgroup_name_index(ob, name_flip);
+ }
+ }
- return (flip_index == -1 && use_default) ? index : flip_index;
+ return (flip_index == -1 && use_default) ? index : flip_index;
}
static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
{
- bDeformGroup *curdef;
+ bDeformGroup *curdef;
- for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
- if (dg != curdef) {
- if (STREQ(curdef->name, name)) {
- return true;
- }
- }
- }
+ for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
+ if (dg != curdef) {
+ if (STREQ(curdef->name, name)) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
static bool defgroup_unique_check(void *arg, const char *name)
{
- struct {Object *ob; void *dg; } *data = arg;
- return defgroup_find_name_dupe(name, data->dg, data->ob);
+ struct {
+ Object *ob;
+ void *dg;
+ } *data = arg;
+ return defgroup_find_name_dupe(name, data->dg, data->ob);
}
void defgroup_unique_name(bDeformGroup *dg, Object *ob)
{
- struct {Object *ob; void *dg; } data;
- data.ob = ob;
- data.dg = dg;
-
- BLI_uniquename_cb(defgroup_unique_check, &data, DATA_("Group"), '.', dg->name, sizeof(dg->name));
+ struct {
+ Object *ob;
+ void *dg;
+ } data;
+ data.ob = ob;
+ data.dg = dg;
+
+ BLI_uniquename_cb(defgroup_unique_check, &data, DATA_("Group"), '.', dg->name, sizeof(dg->name));
}
float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
{
- MDeformWeight *dw = defvert_find_index(dvert, defgroup);
- return dw ? dw->weight : 0.0f;
+ MDeformWeight *dw = defvert_find_index(dvert, defgroup);
+ return dw ? dw->weight : 0.0f;
}
/**
@@ -615,41 +633,42 @@ float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
*
* This is a bit confusing, just saves some checks from the caller.
*/
-float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup)
+float defvert_array_find_weight_safe(const struct MDeformVert *dvert,
+ const int index,
+ const int defgroup)
{
- /* Invalid defgroup index means the vgroup selected is invalid, does not exist, in that case it is OK to return 1.0
- * (i.e. maximum weight, as if no vgroup was selected).
- * But in case of valid defgroup and NULL dvert data pointer, it means that vgroup **is** valid,
- * and just totally empty, so we shall return '0.0' value then!
- */
- if (defgroup == -1) {
- return 1.0f;
- }
- else if (dvert == NULL) {
- return 0.0f;
- }
-
- return defvert_find_weight(dvert + index, defgroup);
+ /* Invalid defgroup index means the vgroup selected is invalid, does not exist, in that case it is OK to return 1.0
+ * (i.e. maximum weight, as if no vgroup was selected).
+ * But in case of valid defgroup and NULL dvert data pointer, it means that vgroup **is** valid,
+ * and just totally empty, so we shall return '0.0' value then!
+ */
+ if (defgroup == -1) {
+ return 1.0f;
+ }
+ else if (dvert == NULL) {
+ return 0.0f;
+ }
+
+ return defvert_find_weight(dvert + index, defgroup);
}
-
MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
{
- if (dvert && defgroup >= 0) {
- MDeformWeight *dw = dvert->dw;
- unsigned int i;
-
- for (i = dvert->totweight; i != 0; i--, dw++) {
- if (dw->def_nr == defgroup) {
- return dw;
- }
- }
- }
- else {
- BLI_assert(0);
- }
-
- return NULL;
+ if (dvert && defgroup >= 0) {
+ MDeformWeight *dw = dvert->dw;
+ unsigned int i;
+
+ for (i = dvert->totweight; i != 0; i--, dw++) {
+ if (dw->def_nr == defgroup) {
+ return dw;
+ }
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ return NULL;
}
/**
@@ -659,32 +678,32 @@ MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
*/
MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup)
{
- MDeformWeight *dw_new;
-
- /* do this check always, this function is used to check for it */
- if (!dvert || defgroup < 0) {
- BLI_assert(0);
- return NULL;
- }
-
- dw_new = defvert_find_index(dvert, defgroup);
- if (dw_new)
- return dw_new;
-
- dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight");
- if (dvert->dw) {
- memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
- MEM_freeN(dvert->dw);
- }
- dvert->dw = dw_new;
- dw_new += dvert->totweight;
- dw_new->weight = 0.0f;
- dw_new->def_nr = defgroup;
- /* Group index */
-
- dvert->totweight++;
-
- return dw_new;
+ MDeformWeight *dw_new;
+
+ /* do this check always, this function is used to check for it */
+ if (!dvert || defgroup < 0) {
+ BLI_assert(0);
+ return NULL;
+ }
+
+ dw_new = defvert_find_index(dvert, defgroup);
+ if (dw_new)
+ return dw_new;
+
+ dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight");
+ if (dvert->dw) {
+ memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
+ MEM_freeN(dvert->dw);
+ }
+ dvert->dw = dw_new;
+ dw_new += dvert->totweight;
+ dw_new->weight = 0.0f;
+ dw_new->def_nr = defgroup;
+ /* Group index */
+
+ dvert->totweight++;
+
+ return dw_new;
}
/* TODO. merge with code above! */
@@ -696,27 +715,27 @@ MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup)
*/
void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
{
- MDeformWeight *dw_new;
-
- /* do this check always, this function is used to check for it */
- if (!dvert || defgroup < 0) {
- BLI_assert(0);
- return;
- }
-
- dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "defvert_add_to group, new deformWeight");
- if (dvert->dw) {
- memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
- MEM_freeN(dvert->dw);
- }
- dvert->dw = dw_new;
- dw_new += dvert->totweight;
- dw_new->weight = weight;
- dw_new->def_nr = defgroup;
- dvert->totweight++;
+ MDeformWeight *dw_new;
+
+ /* do this check always, this function is used to check for it */
+ if (!dvert || defgroup < 0) {
+ BLI_assert(0);
+ return;
+ }
+
+ dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1),
+ "defvert_add_to group, new deformWeight");
+ if (dvert->dw) {
+ memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
+ MEM_freeN(dvert->dw);
+ }
+ dvert->dw = dw_new;
+ dw_new += dvert->totweight;
+ dw_new->weight = weight;
+ dw_new->def_nr = defgroup;
+ dvert->totweight++;
}
-
/**
* Removes the given vertex from the vertex group.
*
@@ -724,43 +743,43 @@ void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weig
*/
void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
{
- if (dvert && dw) {
- int i = dw - dvert->dw;
-
- /* Security check! */
- if (i < 0 || i >= dvert->totweight) {
- return;
- }
-
- dvert->totweight--;
- /* If there are still other deform weights attached to this vert then remove
- * this deform weight, and reshuffle the others.
- */
- if (dvert->totweight) {
- BLI_assert(dvert->dw != NULL);
-
- if (i != dvert->totweight) {
- dvert->dw[i] = dvert->dw[dvert->totweight];
- }
-
- dvert->dw = MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
- }
- else {
- /* If there are no other deform weights left then just remove this one. */
- MEM_freeN(dvert->dw);
- dvert->dw = NULL;
- }
- }
+ if (dvert && dw) {
+ int i = dw - dvert->dw;
+
+ /* Security check! */
+ if (i < 0 || i >= dvert->totweight) {
+ return;
+ }
+
+ dvert->totweight--;
+ /* If there are still other deform weights attached to this vert then remove
+ * this deform weight, and reshuffle the others.
+ */
+ if (dvert->totweight) {
+ BLI_assert(dvert->dw != NULL);
+
+ if (i != dvert->totweight) {
+ dvert->dw[i] = dvert->dw[dvert->totweight];
+ }
+
+ dvert->dw = MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
+ }
+ else {
+ /* If there are no other deform weights left then just remove this one. */
+ MEM_freeN(dvert->dw);
+ dvert->dw = NULL;
+ }
+ }
}
void defvert_clear(MDeformVert *dvert)
{
- if (dvert->dw) {
- MEM_freeN(dvert->dw);
- dvert->dw = NULL;
- }
+ if (dvert->dw) {
+ MEM_freeN(dvert->dw);
+ dvert->dw = NULL;
+ }
- dvert->totweight = 0;
+ dvert->totweight = 0;
}
/**
@@ -769,18 +788,18 @@ void defvert_clear(MDeformVert *dvert)
*/
int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
{
- if (dvert_a->totweight && dvert_b->totweight) {
- MDeformWeight *dw = dvert_a->dw;
- unsigned int i;
-
- for (i = dvert_a->totweight; i != 0; i--, dw++) {
- if (dw->weight > 0.0f && defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) {
- return dw->def_nr;
- }
- }
- }
-
- return -1;
+ if (dvert_a->totweight && dvert_b->totweight) {
+ MDeformWeight *dw = dvert_a->dw;
+ unsigned int i;
+
+ for (i = dvert_a->totweight; i != 0; i--, dw++) {
+ if (dw->weight > 0.0f && defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) {
+ return dw->def_nr;
+ }
+ }
+ }
+
+ return -1;
}
/**
@@ -788,20 +807,19 @@ int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
*/
bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot)
{
- MDeformWeight *dw = dvert->dw;
- unsigned int i;
- for (i = dvert->totweight; i != 0; i--, dw++) {
- if (dw->weight != 0.0f) {
- /* check the group is in-range, happens on rare situations */
- if (LIKELY(dw->def_nr < defgroup_tot)) {
- return false;
- }
- }
- }
- return true;
+ MDeformWeight *dw = dvert->dw;
+ unsigned int i;
+ for (i = dvert->totweight; i != 0; i--, dw++) {
+ if (dw->weight != 0.0f) {
+ /* check the group is in-range, happens on rare situations */
+ if (LIKELY(dw->def_nr < defgroup_tot)) {
+ return false;
+ }
+ }
+ }
+ return true;
}
-
/**
* \return The representative weight of a multipaint group, used for
* viewport colors and actual painting.
@@ -810,480 +828,570 @@ bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_
* Value is not clamped, since painting relies on multiplication being always
* commutative with the collective weight function.
*/
-float BKE_defvert_multipaint_collective_weight(
- const struct MDeformVert *dv, int defbase_tot,
- const bool *defbase_sel, int defbase_tot_sel, bool do_autonormalize)
+float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
+ int defbase_tot,
+ const bool *defbase_sel,
+ int defbase_tot_sel,
+ bool do_autonormalize)
{
- int i;
- float total = 0.0f;
- const MDeformWeight *dw = dv->dw;
-
- for (i = dv->totweight; i != 0; i--, dw++) {
- /* in multipaint, get the average if auto normalize is inactive
- * get the sum if it is active */
- if (dw->def_nr < defbase_tot) {
- if (defbase_sel[dw->def_nr]) {
- total += dw->weight;
- }
- }
- }
-
- if (do_autonormalize == false) {
- total /= defbase_tot_sel;
- }
-
- return total;
+ int i;
+ float total = 0.0f;
+ const MDeformWeight *dw = dv->dw;
+
+ for (i = dv->totweight; i != 0; i--, dw++) {
+ /* in multipaint, get the average if auto normalize is inactive
+ * get the sum if it is active */
+ if (dw->def_nr < defbase_tot) {
+ if (defbase_sel[dw->def_nr]) {
+ total += dw->weight;
+ }
+ }
+ }
+
+ if (do_autonormalize == false) {
+ total /= defbase_tot_sel;
+ }
+
+ return total;
}
-
/* -------------------------------------------------------------------- */
/** \name Defvert Array functions
* \{ */
void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount)
{
- /* Assumes dst is already set up */
- int i;
+ /* Assumes dst is already set up */
+ int i;
- if (!src || !dst)
- return;
+ if (!src || !dst)
+ return;
- memcpy(dst, src, copycount * sizeof(MDeformVert));
-
- for (i = 0; i < copycount; i++) {
- if (src[i].dw) {
- dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
- memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
- }
- }
+ memcpy(dst, src, copycount * sizeof(MDeformVert));
+ for (i = 0; i < copycount; i++) {
+ if (src[i].dw) {
+ dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
+ memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
+ }
+ }
}
void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
{
- /* Instead of freeing the verts directly,
- * call this function to delete any special
- * vert data */
- int i;
-
- if (!dvert)
- return;
-
- /* Free any special data from the verts */
- for (i = 0; i < totvert; i++) {
- if (dvert[i].dw) MEM_freeN(dvert[i].dw);
- }
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ int i;
+
+ if (!dvert)
+ return;
+
+ /* Free any special data from the verts */
+ for (i = 0; i < totvert; i++) {
+ if (dvert[i].dw)
+ MEM_freeN(dvert[i].dw);
+ }
}
void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
{
- /* Instead of freeing the verts directly,
- * call this function to delete any special
- * vert data */
- if (!dvert)
- return;
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ if (!dvert)
+ return;
- /* Free any special data from the verts */
- BKE_defvert_array_free_elems(dvert, totvert);
+ /* Free any special data from the verts */
+ BKE_defvert_array_free_elems(dvert, totvert);
- MEM_freeN(dvert);
+ MEM_freeN(dvert);
}
-void BKE_defvert_extract_vgroup_to_vertweights(
- MDeformVert *dvert, const int defgroup, const int num_verts, float *r_weights, const bool invert_vgroup)
+void BKE_defvert_extract_vgroup_to_vertweights(MDeformVert *dvert,
+ const int defgroup,
+ const int num_verts,
+ float *r_weights,
+ const bool invert_vgroup)
{
- if (dvert && defgroup != -1) {
- int i = num_verts;
-
- while (i--) {
- const float w = defvert_find_weight(&dvert[i], defgroup);
- r_weights[i] = invert_vgroup ? (1.0f - w) : w;
- }
- }
- else {
- copy_vn_fl(r_weights, num_verts, invert_vgroup ? 1.0f : 0.0f);
- }
+ if (dvert && defgroup != -1) {
+ int i = num_verts;
+
+ while (i--) {
+ const float w = defvert_find_weight(&dvert[i], defgroup);
+ r_weights[i] = invert_vgroup ? (1.0f - w) : w;
+ }
+ }
+ else {
+ copy_vn_fl(r_weights, num_verts, invert_vgroup ? 1.0f : 0.0f);
+ }
}
/**
* The following three make basic interpolation,
* using temp vert_weights array to avoid looking up same weight several times.
*/
-void BKE_defvert_extract_vgroup_to_edgeweights(
- MDeformVert *dvert, const int defgroup, const int num_verts, MEdge *edges, const int num_edges,
- float *r_weights, const bool invert_vgroup)
+void BKE_defvert_extract_vgroup_to_edgeweights(MDeformVert *dvert,
+ const int defgroup,
+ const int num_verts,
+ MEdge *edges,
+ const int num_edges,
+ float *r_weights,
+ const bool invert_vgroup)
{
- if (dvert && defgroup != -1) {
- int i = num_edges;
- float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+ if (dvert && defgroup != -1) {
+ int i = num_edges;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
- BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+ BKE_defvert_extract_vgroup_to_vertweights(
+ dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
- while (i--) {
- MEdge *me = &edges[i];
+ while (i--) {
+ MEdge *me = &edges[i];
- r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
- }
+ r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
+ }
- MEM_freeN(tmp_weights);
- }
- else {
- copy_vn_fl(r_weights, num_edges, 0.0f);
- }
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ copy_vn_fl(r_weights, num_edges, 0.0f);
+ }
}
-void BKE_defvert_extract_vgroup_to_loopweights(
- MDeformVert *dvert, const int defgroup, const int num_verts, MLoop *loops, const int num_loops,
- float *r_weights, const bool invert_vgroup)
+void BKE_defvert_extract_vgroup_to_loopweights(MDeformVert *dvert,
+ const int defgroup,
+ const int num_verts,
+ MLoop *loops,
+ const int num_loops,
+ float *r_weights,
+ const bool invert_vgroup)
{
- if (dvert && defgroup != -1) {
- int i = num_loops;
- float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+ if (dvert && defgroup != -1) {
+ int i = num_loops;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
- BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+ BKE_defvert_extract_vgroup_to_vertweights(
+ dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
- while (i--) {
- MLoop *ml = &loops[i];
+ while (i--) {
+ MLoop *ml = &loops[i];
- r_weights[i] = tmp_weights[ml->v];
- }
+ r_weights[i] = tmp_weights[ml->v];
+ }
- MEM_freeN(tmp_weights);
- }
- else {
- copy_vn_fl(r_weights, num_loops, 0.0f);
- }
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ copy_vn_fl(r_weights, num_loops, 0.0f);
+ }
}
-void BKE_defvert_extract_vgroup_to_polyweights(
- MDeformVert *dvert, const int defgroup, const int num_verts, MLoop *loops, const int UNUSED(num_loops),
- MPoly *polys, const int num_polys, float *r_weights, const bool invert_vgroup)
+void BKE_defvert_extract_vgroup_to_polyweights(MDeformVert *dvert,
+ const int defgroup,
+ const int num_verts,
+ MLoop *loops,
+ const int UNUSED(num_loops),
+ MPoly *polys,
+ const int num_polys,
+ float *r_weights,
+ const bool invert_vgroup)
{
- if (dvert && defgroup != -1) {
- int i = num_polys;
- float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
-
- BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
-
- while (i--) {
- MPoly *mp = &polys[i];
- MLoop *ml = &loops[mp->loopstart];
- int j = mp->totloop;
- float w = 0.0f;
-
- for (; j--; ml++) {
- w += tmp_weights[ml->v];
- }
- r_weights[i] = w / (float)mp->totloop;
- }
-
- MEM_freeN(tmp_weights);
- }
- else {
- copy_vn_fl(r_weights, num_polys, 0.0f);
- }
+ if (dvert && defgroup != -1) {
+ int i = num_polys;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+
+ BKE_defvert_extract_vgroup_to_vertweights(
+ dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+
+ while (i--) {
+ MPoly *mp = &polys[i];
+ MLoop *ml = &loops[mp->loopstart];
+ int j = mp->totloop;
+ float w = 0.0f;
+
+ for (; j--; ml++) {
+ w += tmp_weights[ml->v];
+ }
+ r_weights[i] = w / (float)mp->totloop;
+ }
+
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ copy_vn_fl(r_weights, num_polys, 0.0f);
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Data Transfer
* \{ */
-static void vgroups_datatransfer_interp(
- const CustomDataTransferLayerMap *laymap, void *dest,
- const void **sources, const float *weights, const int count, const float mix_factor)
+static void vgroups_datatransfer_interp(const CustomDataTransferLayerMap *laymap,
+ void *dest,
+ const void **sources,
+ const float *weights,
+ const int count,
+ const float mix_factor)
{
- MDeformVert **data_src = (MDeformVert **)sources;
- MDeformVert *data_dst = (MDeformVert *)dest;
- const int idx_src = laymap->data_src_n;
- const int idx_dst = laymap->data_dst_n;
-
- const int mix_mode = laymap->mix_mode;
-
- int i, j;
-
- MDeformWeight *dw_src;
- MDeformWeight *dw_dst = defvert_find_index(data_dst, idx_dst);
- float weight_src = 0.0f, weight_dst = 0.0f;
-
- if (sources) {
- for (i = count; i--;) {
- for (j = data_src[i]->totweight; j--;) {
- if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) {
- weight_src += dw_src->weight * weights[i];
- break;
- }
- }
- }
- }
-
- if (dw_dst) {
- weight_dst = dw_dst->weight;
- }
- else if (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD) {
- return; /* Do not affect destination. */
- }
-
- weight_src = data_transfer_interp_float_do(mix_mode, weight_dst, weight_src, mix_factor);
-
- CLAMP(weight_src, 0.0f, 1.0f);
-
- if (!dw_dst) {
- defvert_add_index_notest(data_dst, idx_dst, weight_src);
- }
- else {
- dw_dst->weight = weight_src;
- }
+ MDeformVert **data_src = (MDeformVert **)sources;
+ MDeformVert *data_dst = (MDeformVert *)dest;
+ const int idx_src = laymap->data_src_n;
+ const int idx_dst = laymap->data_dst_n;
+
+ const int mix_mode = laymap->mix_mode;
+
+ int i, j;
+
+ MDeformWeight *dw_src;
+ MDeformWeight *dw_dst = defvert_find_index(data_dst, idx_dst);
+ float weight_src = 0.0f, weight_dst = 0.0f;
+
+ if (sources) {
+ for (i = count; i--;) {
+ for (j = data_src[i]->totweight; j--;) {
+ if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) {
+ weight_src += dw_src->weight * weights[i];
+ break;
+ }
+ }
+ }
+ }
+
+ if (dw_dst) {
+ weight_dst = dw_dst->weight;
+ }
+ else if (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD) {
+ return; /* Do not affect destination. */
+ }
+
+ weight_src = data_transfer_interp_float_do(mix_mode, weight_dst, weight_src, mix_factor);
+
+ CLAMP(weight_src, 0.0f, 1.0f);
+
+ if (!dw_dst) {
+ defvert_add_index_notest(data_dst, idx_dst, weight_src);
+ }
+ else {
+ dw_dst->weight = weight_src;
+ }
}
-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)
+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) {
- /* Create as much vgroups as necessary! */
- for (; idx_dst < idx_src; idx_dst++) {
- BKE_object_defgroup_add(ob_dst);
- }
- }
- else {
- /* Otherwise, just try to map what we can with existing dst vgroups. */
- idx_src = idx_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) {
- BKE_object_defgroup_add_name(ob_dst, dg_src->name);
- idx_dst = ob_dst->actdef - 1;
- }
- else {
- /* If we are not allowed to create missing dst vgroups, just skip matching src one. */
- continue;
- }
- }
- 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;
+ 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) {
+ /* Create as much vgroups as necessary! */
+ for (; idx_dst < idx_src; idx_dst++) {
+ BKE_object_defgroup_add(ob_dst);
+ }
+ }
+ else {
+ /* Otherwise, just try to map what we can with existing dst vgroups. */
+ idx_src = idx_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) {
+ BKE_object_defgroup_add_name(ob_dst, dg_src->name);
+ idx_dst = ob_dst->actdef - 1;
+ }
+ else {
+ /* If we are not allowed to create missing dst vgroups, just skip matching src one. */
+ continue;
+ }
+ }
+ 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;
}
-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)
+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;
- if (idx_src >= BLI_listbase_count(&ob_src->defbase)) {
- /* This can happen when vgroups are removed from source object...
- * Remapping would be really tricky here, we'd need to go over all objects in
- * Main every time we delete a vgroup... for now, simpler and safer to abort. */
- return false;
- }
- }
- 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;
+ 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;
+ if (idx_src >= BLI_listbase_count(&ob_src->defbase)) {
+ /* This can happen when vgroups are removed from source object...
+ * Remapping would be really tricky here, we'd need to go over all objects in
+ * Main every time we delete a vgroup... for now, simpler and safer to abort. */
+ return false;
+ }
+ }
+ 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;
}
/** \} */
@@ -1294,35 +1402,35 @@ bool data_transfer_layersmapping_vgroups(
void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight)
{
- const float blend = ((weight / 2.0f) + 0.5f);
-
- if (weight <= 0.25f) { /* blue->cyan */
- r_rgb[0] = 0.0f;
- r_rgb[1] = blend * weight * 4.0f;
- r_rgb[2] = blend;
- }
- else if (weight <= 0.50f) { /* cyan->green */
- r_rgb[0] = 0.0f;
- r_rgb[1] = blend;
- r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f));
- }
- else if (weight <= 0.75f) { /* green->yellow */
- r_rgb[0] = blend * ((weight - 0.50f) * 4.0f);
- r_rgb[1] = blend;
- r_rgb[2] = 0.0f;
- }
- else if (weight <= 1.0f) { /* yellow->red */
- r_rgb[0] = blend;
- r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f));
- r_rgb[2] = 0.0f;
- }
- else {
- /* exceptional value, unclamped or nan,
- * avoid uninitialized memory use */
- r_rgb[0] = 1.0f;
- r_rgb[1] = 0.0f;
- r_rgb[2] = 1.0f;
- }
+ const float blend = ((weight / 2.0f) + 0.5f);
+
+ if (weight <= 0.25f) { /* blue->cyan */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend * weight * 4.0f;
+ r_rgb[2] = blend;
+ }
+ else if (weight <= 0.50f) { /* cyan->green */
+ r_rgb[0] = 0.0f;
+ r_rgb[1] = blend;
+ r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f));
+ }
+ else if (weight <= 0.75f) { /* green->yellow */
+ r_rgb[0] = blend * ((weight - 0.50f) * 4.0f);
+ r_rgb[1] = blend;
+ r_rgb[2] = 0.0f;
+ }
+ else if (weight <= 1.0f) { /* yellow->red */
+ r_rgb[0] = blend;
+ r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f));
+ r_rgb[2] = 0.0f;
+ }
+ else {
+ /* exceptional value, unclamped or nan,
+ * avoid uninitialized memory use */
+ r_rgb[0] = 1.0f;
+ r_rgb[1] = 0.0f;
+ r_rgb[2] = 1.0f;
+ }
}
/** \} */